Correctly handle non-UnitaryGate gates named "unitary" (backport #14109) #14112
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Normally creating a custom gate class that overloads the name of a Qiskit defined operation is not valid and not allowed. The names have meaning and are often used as identifiers and this overloading the name will prevent Qiskit from correctly identifying an operation. However as was discovered in #14103 there are some paths available around serialization and I/O where Qiskit does this itself. For example, qasm (both 2 and 3) is a lossy serialization format and qasm2 doesn't have a representation of a UnitaryGate. So when the qasm2 exporter encounteres a
UnitaryGate
it is serialized as a custom gate definition with the name "unitary" in the output qasm2 and the definition is a decomposition of the unitary from theUnitaryGate
. When that qasm2 program is subsequently deserialized by qiskit parser the custom gate named "unitary" is added as a_DefinedGate
subclass which includes an__array__
implementation which computes the unitary from the definition using the quantum info Operator class. This makes the custom gate parsed from qasm2 look like aUnitaryGate
despite not actually one so this is typically fine for most use cases. However, since #13759 trying to add that notUnitaryGate
object named "unitary" would cause the Python -> Rust translation to panic (which happens as part of qasm2 desierailzation). because the conversion was expecting a gate namedunitary
to be aUnitaryGate
as is prescribed by the data model.This commit fixes this by gracefully handling the lack of a matrix parameter as it not actually being a
UnitaryGate
and instead the object gets treated as aPyGate
in rust which is the expected behavior.Details and comments
Related to #14103
This is an automatic backport of pull request #14109 done by Mergify.