Description
Environment
- Qiskit version: Qiskit 1.3.0 and
main
- Python version: 3.11.9
- Operating system: macOS
What is happening?
This is the problem underlying Qiskit/qiskit-addon-cutting#714.
Running basis translation in parallel (see snippet below) causes the following failure
[...]
File "/Users/jul/Qiskit/qiskit/qiskit/transpiler/passes/basis/basis_translator.py", line 129, in run
return base_run(
^^^^^^^^^
ValueError: An invalid parameter was provided.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/jul/IBM/snippets/repro.py", line 25, in <module>
pm.run([qc_a, qc_b]) # This fails with the error
^^^^^^^^^^^^^^^^^^^^
[...]
File "/opt/homebrew/Cellar/python@3.11/3.11.9/Frameworks/Python.framework/Versions/3.11/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
ValueError: An invalid parameter was provided.
This seems to be due to the recent port of the basis translator to Rust (see #12246 for an overview). Dissecting the code, the error seems to be triggered by compose_transforms
, so it might be worth checking if this already existed after #13137 and before the rest of the basis translator was moved to Rust.
How can we reproduce the issue?
From @mtreinish:
I just came up with a minimal reproduce:
from qiskit.circuit import QuantumCircuit, Parameter from qiskit import generate_preset_pass_manager from qiskit.providers.fake_provider import GenericBackendV2 from qiskit.circuit.library import RXGate backend = GenericBackendV2(5) pm = generate_preset_pass_manager(1, backend) param = Parameter('a') gate = RXGate(param) qc_a = QuantumCircuit(1) qc_a.append(gate, [0]) qc_b = QuantumCircuit(1) qc_b.append(gate, [0]) pm.run(qc_a) pm.run(qc_b) pm.run([qc_a, qc_b]) # This fails with the error
Note that this only happens with multiprocessing turned on. On Mac this is turned off per default but can be enabled with export QISKIT_PARALLEL=TRUE
.
What should happen?
The above should run, as it did in 1.2.4.
Any suggestions?
One possible solution is to delete the cached py_op
upon parameter assignment, i.e. replace
qiskit/crates/circuit/src/circuit_data.rs
Lines 1385 to 1389 in 6979d91
previous.py_op = OnceLock::new(); // or OnceCell on Qiskit 1.3.0
But this comes at a ~5% performance overhead on my machine, benchmarked on some utility scale circuits. Maybe there's another way to avoid this overhead?