-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Environment
- Qiskit version: 2.2.3
- Python version: 3.12.3
- Operating system: Ubuntu 24.04.3 LTS
What is happening?
I'm getting an internal error from the Rust part of the Qiskit transpiler when trying to compile a single-qubit permutation (which should be a no-op) to a device.
How can we reproduce the issue?
Run this code:
from qiskit_ibm_runtime.fake_provider import FakeTorino
from qiskit.circuit.library import PermutationGate
from qiskit import QuantumCircuit, transpile
c = QuantumCircuit(1)
c.append(PermutationGate([0]), [0])
transpile(c, backend=FakeTorino())
What should happen?
Instead of compiling to an empty circuit, I get this error message:
---------------------------------------------------------------------------
PanicException Traceback (most recent call last)
Cell In[8], line 7
5 c = QuantumCircuit(1)
6 c.append(PermutationGate([0]), [0])
----> 7 transpile(c, backend=FakeTorino())
File path/to/venv/lib/python3.12/site-packages/qiskit/compiler/transpiler.py:291, in transpile(circuits, backend, basis_gates, coupling_map, initial_layout, layout_method, routing_method, translation_method, scheduling_method, dt, approximation_degree, seed_transpiler, optimization_level, callback, output_name, unitary_synthesis_method, unitary_synthesis_plugin_config, target, hls_config, init_method, optimization_method, ignore_backend_supplied_default_methods, num_processes, qubits_initially_zero)
266 # Edge cases require using the old model (loose constraints) instead of building a target,
267 # but we don't populate the passmanager config with loose constraints unless it's one of
268 # the known edge cases to control the execution path.
269 pm = generate_preset_pass_manager(
270 optimization_level,
271 target=target,
(...)
288 qubits_initially_zero=qubits_initially_zero,
289 )
--> 291 out_circuits = pm.run(circuits, callback=callback, num_processes=num_processes)
293 for name, circ in zip(output_name, out_circuits):
294 circ.name = name
File path/to/venv/lib/python3.12/site-packages/qiskit/transpiler/passmanager.py:415, in StagedPassManager.run(self, circuits, output_name, callback, num_processes, property_set)
405 def run(
406 self,
407 circuits: _CircuitsT,
(...)
412 property_set: dict[str, object] | None = None,
413 ) -> _CircuitsT:
414 self._update_passmanager()
--> 415 return super().run(circuits, output_name, callback, num_processes=num_processes)
File path/to/venv/lib/python3.12/site-packages/qiskit/transpiler/passmanager.py:438, in _replace_error.<locals>.wrapper(*meth_args, **meth_kwargs)
435 @wraps(meth)
436 def wrapper(*meth_args, **meth_kwargs):
437 try:
--> 438 return meth(*meth_args, **meth_kwargs)
439 except TranspilerError:
440 # If it's already a `TranspilerError` subclass, don't erase the extra information.
441 raise
File path/to/venv/lib/python3.12/site-packages/qiskit/transpiler/passmanager.py:197, in PassManager.run(self, circuits, output_name, callback, num_processes, property_set)
194 if callback is not None:
195 callback = _legacy_style_callback(callback)
--> 197 return super().run(
198 in_programs=circuits,
199 callback=callback,
200 output_name=output_name,
201 num_processes=num_processes,
202 property_set=property_set,
203 )
File path/to/venv/lib/python3.12/site-packages/qiskit/passmanager/passmanager.py:238, in BasePassManager.run(self, in_programs, callback, num_processes, property_set, **kwargs)
234 # If we're not going to run in parallel, we want to avoid spending time `dill` serializing
235 # ourselves, since that can be quite expensive.
236 if len(in_programs) == 1 or not should_run_in_parallel(num_processes):
237 out = [
--> 238 _run_workflow(
239 program=program,
240 pass_manager=self,
241 callback=callback,
242 initial_property_set=property_set,
243 **kwargs,
244 )
245 for program in in_programs
246 ]
247 if len(in_programs) == 1 and not is_list:
248 return out[0]
File path/to/venv/lib/python3.12/site-packages/qiskit/passmanager/passmanager.py:311, in _run_workflow(program, pass_manager, initial_property_set, **kwargs)
306 pass_manager.property_set = property_set
307 passmanager_ir = pass_manager._passmanager_frontend(
308 input_program=program,
309 **kwargs,
310 )
--> 311 passmanager_ir, final_state = flow_controller.execute(
312 passmanager_ir=passmanager_ir,
313 state=PassManagerState(
314 workflow_status=initial_status, property_set=pass_manager.property_set
315 ),
316 callback=kwargs.get("callback", None),
317 )
318 # The `property_set` has historically been returned as a mutable attribute on `PassManager`
319 # This makes us non-reentrant (though `PassManager` would be dependent on its internal tasks to
320 # be re-entrant if that was required), but is consistent with previous interfaces. We're still
321 # safe to be called in a serial loop, again assuming internal tasks are re-runnable. The
322 # conversion to the backend language is also allowed to use the property set, so it must be set
323 # before calling it.
324 pass_manager.property_set = final_state.property_set
File path/to/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 path/to/venv/lib/python3.12/site-packages/qiskit/transpiler/basepasses.py:167, in TransformationPass.execute(self, passmanager_ir, state, callback)
161 def execute(
162 self,
163 passmanager_ir: PassManagerIR,
164 state: PassManagerState,
165 callback: Callable = None,
166 ) -> tuple[PassManagerIR, PassManagerState]:
--> 167 new_dag, state = super().execute(
168 passmanager_ir=passmanager_ir,
169 state=state,
170 callback=callback,
171 )
173 if state.workflow_status.previous_run == RunState.SUCCESS:
174 if not isinstance(new_dag, DAGCircuit):
File path/to/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 path/to/venv/lib/python3.12/site-packages/qiskit/transpiler/passes/optimization/elide_permutations.py:69, in ElidePermutations.run(self, dag)
63 logger.warning(
64 "ElidePermutations is not valid after a layout has been set. This indicates "
65 "an invalid pass manager construction."
66 )
67 return dag
---> 69 result = elide_permutations_rs.run(dag)
71 # If the pass did not do anything, the result is None
72 if result is None:
PanicException: internal error: entered unreachable code
Any suggestions?
It seems like the problem is probably in elide_permutations_rs, but I haven't looked further.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working