-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Closed
Copy link
Description
Environment
- Qiskit version: 1.3.2
- Python version: 3.12
- Operating system: MacOS 15.2
What is happening?
When executing the example, an error is caused under Qiskit v1.3.2 while it works under v1.3.1:
---------------------------------------------------------------------------
PanicException Traceback (most recent call last)
Cell In[1], line 7
5 new_qc = qpy.load(fd)[0]
6 pm = PassManager(CommutativeInverseCancellation())
----> 7 altered_qc = pm.run(new_qc)
File ~/.venv/lib/python3.12/site-packages/qiskit/transpiler/passmanager.py:464, in _replace_error.<locals>.wrapper(*meth_args, **meth_kwargs)
461 @wraps(meth)
462 def wrapper(*meth_args, **meth_kwargs):
463 try:
--> 464 return meth(*meth_args, **meth_kwargs)
465 except PassManagerError as ex:
466 raise TranspilerError(ex.message) from ex
File ~/.venv/lib/python3.12/site-packages/qiskit/transpiler/passmanager.py:226, in PassManager.run(self, circuits, output_name, callback, num_processes)
223 if callback is not None:
224 callback = _legacy_style_callback(callback)
--> 226 return super().run(
227 in_programs=circuits,
228 callback=callback,
229 output_name=output_name,
230 num_processes=num_processes,
231 )
File ~/.venv/lib/python3.12/site-packages/qiskit/passmanager/passmanager.py:232, in BasePassManager.run(self, in_programs, callback, num_processes, **kwargs)
228 # If we're not going to run in parallel, we want to avoid spending time `dill` serializing
229 # ourselves, since that can be quite expensive.
230 if len(in_programs) == 1 or not should_run_in_parallel(num_processes):
231 out = [
--> 232 _run_workflow(program=program, pass_manager=self, callback=callback, **kwargs)
233 for program in in_programs
234 ]
235 if len(in_programs) == 1 and not is_list:
236 return out[0]
File ~/.venv/lib/python3.12/site-packages/qiskit/passmanager/passmanager.py:292, in _run_workflow(program, pass_manager, **kwargs)
286 initial_status = WorkflowStatus()
288 passmanager_ir = pass_manager._passmanager_frontend(
289 input_program=program,
290 **kwargs,
291 )
--> 292 passmanager_ir, final_state = flow_controller.execute(
293 passmanager_ir=passmanager_ir,
294 state=PassManagerState(
295 workflow_status=initial_status,
296 property_set=PropertySet(),
297 ),
298 callback=kwargs.get("callback", None),
299 )
300 # The `property_set` has historically been returned as a mutable attribute on `PassManager`
301 # This makes us non-reentrant (though `PassManager` would be dependent on its internal tasks to
302 # be re-entrant if that was required), but is consistent with previous interfaces. We're still
303 # safe to be called in a serial loop, again assuming internal tasks are re-runnable. The
304 # conversion to the backend language is also allowed to use the property set, so it must be set
305 # before calling it.
306 pass_manager.property_set = final_state.property_set
File ~/.venv/lib/python3.12/site-packages/qiskit/passmanager/base_tasks.py:218, in BaseController.execute(self, passmanager_ir, state, callback)
216 return passmanager_ir, state
217 while True:
--> 218 passmanager_ir, state = next_task.execute(
219 passmanager_ir=passmanager_ir,
220 state=state,
221 callback=callback,
222 )
223 try:
224 # Sending the object through the generator implies the custom controllers
225 # can always rely on the latest data to choose the next task to run.
226 next_task = task_generator.send(state)
File ~/.venv/lib/python3.12/site-packages/qiskit/transpiler/basepasses.py:195, in TransformationPass.execute(self, passmanager_ir, state, callback)
189 def execute(
190 self,
191 passmanager_ir: PassManagerIR,
192 state: PassManagerState,
193 callback: Callable = None,
194 ) -> tuple[PassManagerIR, PassManagerState]:
--> 195 new_dag, state = super().execute(
196 passmanager_ir=passmanager_ir,
197 state=state,
198 callback=callback,
199 )
201 if state.workflow_status.previous_run == RunState.SUCCESS:
202 if isinstance(new_dag, DAGCircuit):
203 # Copy calibration data from the original program
File ~/.venv/lib/python3.12/site-packages/qiskit/passmanager/base_tasks.py:98, in GenericPass.execute(self, passmanager_ir, state, callback)
96 try:
97 if self not in state.workflow_status.completed_passes:
---> 98 ret = self.run(passmanager_ir)
99 run_state = RunState.SUCCESS
100 else:
File ~/.venv/lib/python3.12/site-packages/qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py:122, in CommutativeInverseCancellation.run(self, dag)
119 matched_idx2 = idx2
120 break
--> 122 if not self.comm_checker.commute_nodes(
123 topo_sorted_nodes[idx1],
124 topo_sorted_nodes[idx2],
125 max_num_qubits=self._max_qubits,
126 ):
127 break
129 if matched_idx2 != -1:
File ~/.venv/lib/python3.12/site-packages/qiskit/circuit/commutation_checker.py:45, in CommutationChecker.commute_nodes(self, op1, op2, max_num_qubits)
38 def commute_nodes(
39 self,
40 op1,
41 op2,
42 max_num_qubits: int = 3,
43 ) -> bool:
44 """Checks if two DAGOpNodes commute."""
---> 45 return self.cc.commute_nodes(op1, op2, max_num_qubits)
PanicException: index out of bounds: the len is 0 but the index is 0
How can we reproduce the issue?
Unfortunately, I cannot upload the qpy
file directly, but I could upload it as a zip
.
from qiskit import qpy
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import CommutativeInverseCancellation
with open('errorcircuit.qpy', 'rb') as fd:
qc = qpy.load(fd)[0]
pm = PassManager(CommutativeInverseCancellation())
altered_qc = pm.run(qc)
What should happen?
There should be no error.
Any suggestions?
Probably the issue is related to the CommuteChecker
(
return self.cc.commute_nodes(op1, op2, max_num_qubits) |
CommutativeInverseCancellation
pass.Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working