Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.28k stars 2.37k forks source link

scheduling methods don't match with documentation #10195

Open kevinsung opened 1 year ago

kevinsung commented 1 year ago

Environment

What is happening?

As documented at https://qiskit.org/documentation/stubs/qiskit.compiler.transpile.html, "as_soon_as_possible" and "as_late_as_possible" are options, but they don't work. "asap" and "alap" work though.

How can we reproduce the issue?

from qiskit import transpile, QuantumCircuit
from qiskit.providers.fake_provider import FakeBelemV2

circuit = QuantumCircuit()
transpiled = transpile(circuit, FakeBelemV2(), scheduling_method='as_late_as_possible')
---------------------------------------------------------------------------
TranspilerError                           Traceback (most recent call last)
Cell In[14], line 5
      2 from qiskit.providers.fake_provider import FakeBelemV2
      4 circuit = QuantumCircuit()
----> 5 transpiled = transpile(circuit, FakeBelemV2(), scheduling_method='as_late_as_possible')

File ~/projects/qiskit-terra/qiskit/compiler/transpiler.py:374, in transpile(circuits, backend, basis_gates, inst_map, coupling_map, backend_properties, initial_layout, layout_method, routing_method, translation_method, scheduling_method, instruction_durations, dt, approximation_degree, timing_constraints, 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)
    372 output_circuits = []
    373 for circuit, unique_args in zip(circuits, unique_transpile_args):
--> 374     transpile_config, pass_manager = _combine_args(shared_args, unique_args)
    375     output_circuits.append(
    376         _serial_transpile_circuit(
    377             circuit,
   (...)
    381         )
    382     )
    383 circuits = output_circuits

File ~/projects/qiskit-terra/qiskit/compiler/transpiler.py:442, in _combine_args(shared_transpiler_args, unique_config)
    440     pass_manager = level_0_pass_manager(pass_manager_config)
    441 elif level == 1:
--> 442     pass_manager = level_1_pass_manager(pass_manager_config)
    443 elif level == 2:
    444     pass_manager = level_2_pass_manager(pass_manager_config)

File ~/projects/qiskit-terra/qiskit/transpiler/preset_passmanagers/level1.py:295, in level_1_pass_manager(pass_manager_config)
    291     sched = common.generate_scheduling(
    292         instruction_durations, scheduling_method, timing_constraints, inst_map, target=target
    293     )
    294 else:
--> 295     sched = plugin_manager.get_passmanager_stage(
    296         "scheduling", scheduling_method, pass_manager_config, optimization_level=1
    297     )
    298 init = common.generate_control_flow_options_check(
    299     layout_method=layout_method,
    300     routing_method=routing_method,
   (...)
    305     target=target,
    306 )
    307 if init_method is not None:

File ~/projects/qiskit-terra/qiskit/transpiler/preset_passmanagers/plugin.py:258, in PassManagerStagePluginManager.get_passmanager_stage(self, stage_name, plugin_name, pm_config, optimization_level)
    254     return self._build_pm(
    255         self.optimization_plugins, stage_name, plugin_name, pm_config, optimization_level
    256     )
    257 elif stage_name == "scheduling":
--> 258     return self._build_pm(
    259         self.scheduling_plugins, stage_name, plugin_name, pm_config, optimization_level
    260     )
    261 else:
    262     raise TranspilerError(f"Invalid stage name: {stage_name}")

File ~/projects/qiskit-terra/qiskit/transpiler/preset_passmanagers/plugin.py:273, in PassManagerStagePluginManager._build_pm(self, stage_obj, stage_name, plugin_name, pm_config, optimization_level)
    264 def _build_pm(
    265     self,
    266     stage_obj: stevedore.ExtensionManager,
   (...)
    270     optimization_level: Optional[int] = None,
    271 ):
    272     if plugin_name not in stage_obj:
--> 273         raise TranspilerError(f"Invalid plugin name {plugin_name} for stage {stage_name}")
    274     plugin_obj = stage_obj[plugin_name]
    275     return plugin_obj.obj.pass_manager(pm_config, optimization_level)

TranspilerError: 'Invalid plugin name as_late_as_possible for stage scheduling'

What should happen?

Should work. Or, documentation should not give incorrect information.

Any suggestions?

No response

mtreinish commented 1 year ago

Ah, yeah this is a bug. It should be supported, we need to add the fully spelled out versions to the list of non-plugins:

So the transpiler knows to not treat those methods like a plugin and build the pass manager correctly.

aeddins-ibm commented 5 months ago

Just updating that this is still a bug, I ran into it today.