QPY: Correctly load ParameterExpression with empty replay#15876
QPY: Correctly load ParameterExpression with empty replay#15876gadial wants to merge 7 commits intoQiskit:mainfrom
ParameterExpression with empty replay#15876Conversation
|
One or more of the following people are relevant to this code:
|
…meter expresssions
jakelishman
left a comment
There was a problem hiding this comment.
I tried this locally, and while it fixes all the instances listed in the test, I'm not convinced it's solving the true underlying issue, because you can have an expression with cancelled-out parameters that isn't 0 too:
import io
from qiskit import qpy, QuantumCircuit
from qiskit.circuit import Parameter
x = Parameter("x")
# Using either of these triggers the same bug.
bad = [0 * x + 2]
qc = QuantumCircuit(1)
qc.rz(bad[0], 0)
with io.BytesIO() as fptr:
qpy.dump(qc, fptr)
fptr.seek(0)
x = qpy.load(fptr)[0]This should satisfy x[0].params[0] == 2, but it's still coming out as 0 after this PR. Without this PR it fails with the same "empty replay" bug.
This feels like it might be a problem with the dump rather than the load?
Also: I'm getting a panic in qiskit_circuit::parameter::parameter_expression::ParameterExpression::from_qpy with these (without this PR) which we could do with turning into a safer exception too (but can be a follow-up).
This actually makes a lot of sense. The replay doesn't have EDIT: after playing with this a little, the problem is more serious than I thought, and it's present even in the Python implementation. The workaround I suggest is saving the constant value |
* Enable missing argument in docstring lint In the recently merged Qiskit#15603 we migrated from pylint to use ruff. During the development of that PR the rule group "D" for rules derived from pydocstyle was investigated but the full rule group was overly pedantic and even with disabling the most egregious rules also changed the docs for the worse (at least by autofixing many rules) so that sphinx would not succesfully build after applying the fixes. So during Qiskit#15603 the changes for this rule group were reverted. However, one of the useful rules from that group D417 which checks that all arguments are documented. This rule found real issues in the documentation and it is worthwhile to enable it. This commit enables the rule in our ruff checks and fixes the issues associated with. During this process ruff flagged one place in the `__call__` method docstring for the `TwoQubitControlledUDecomposer` class has not documented several arguments on the method. However, these arguments are unused currently. It is apparently trying to match the `__call__` signature of the other two qubit decomposers but is not using most of the arguments. Most could be conceivably supported by `TwoQubitControlledUDecomposer` and it's not clear why they were added. But, for this PR I didn't want to look into adding the support as it was out of scope. For the time being this PR suppresses the ruff rule and adds a TODO comment to start using the unused arguments. * Update filename docstring * Revise wording on state visualization filename arg
…t#15881) In the recently merged Qiskit#15871 we updated the consolidate blocks pass to use Matrix4 in the common path of a 2q block being consolidated. This is like > 90% of what the pass does when run in the preset pass manager. However, there were uncommon cases in the pass around the handling of blocks of a single gate that are outside of the target which were not updated to use nalgebra arrays if it's a fixed size 1q or 2q gate. This commit updates these uncommon paths so that we're always returning an nalgebra matrix in the output UnitaryGate if the block being consolidated is a single qubit or two qubits.
|
Done in #15900 |
Summary
Fixes a bug where
ParameterExpressiondid not load correctly when the expression was "empty" (e.g.0*x).Fixes #15355
Details and comments
ParameterExpressionsare stored using a "replay" which enables to reconstruct them step by step. An expression like0*xreduces to an empty expression (considered as the value 0) with an empty replay - this crashes when trying to reconstruct the expression with theParameterExpression::from_qpymethod.To solve this, explicit handling of the empty replay case was added. The subtle point is that the symbol table should be preserved, so the parameter list of the circuit will be as before even if those parameters were not used in practice. This was also simple to implement as the QPY file already has this data.