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
4.85k stars 2.29k forks source link

generate_preset_pass_manager compatibility issue in 'scheduling_method' options with runtime FakebakcendV2 and Aersimulator #12362

Open 0sophy1 opened 2 months ago

0sophy1 commented 2 months ago

Environment

What is happening?

if add scheduling_method option inside of generate_preset_pass_manager with FakebackendV2 of qiskit-ibm-runtim and Aersimulator of qiskit-aer, granularity relate error comes

below is whole error block:

AttributeError                            Traceback (most recent call last)
Cell In[26], line 2
      1 #but ok with Aersimulator, which bring confuration from backends
----> 2 pm = generate_preset_pass_manager(backend=noisy_backend, optimization_level=1, scheduling_method='alap')

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/__init__.py:255, in generate_preset_pass_manager(optimization_level, backend, target, basis_gates, inst_map, coupling_map, instruction_durations, backend_properties, timing_constraints, initial_layout, layout_method, routing_method, translation_method, scheduling_method, approximation_degree, seed_transpiler, unitary_synthesis_method, unitary_synthesis_plugin_config, hls_config, init_method, optimization_method, _skip_target)
    253     pm = level_0_pass_manager(pm_config)
    254 elif optimization_level == 1:
--> 255     pm = level_1_pass_manager(pm_config)
    256 elif optimization_level == 2:
    257     pm = level_2_pass_manager(pm_config)

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/level1.py:94, in level_1_pass_manager(pass_manager_config)
     88     pre_optimization = common.generate_pre_op_passmanager(remove_reset_in_zero=False)
     90 optimization = plugin_manager.get_passmanager_stage(
     91     "optimization", optimization_method, pass_manager_config, optimization_level=1
     92 )
---> 94 sched = plugin_manager.get_passmanager_stage(
     95     "scheduling", scheduling_method, pass_manager_config, optimization_level=1
     96 )
     98 pre_init = common.generate_control_flow_options_check(
     99     layout_method=layout_method,
    100     routing_method=routing_method,
   (...)
    105     target=target,
    106 )
    107 init = plugin_manager.get_passmanager_stage(
    108     "init", init_method, pass_manager_config, optimization_level=1
    109 )

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py:255, in PassManagerStagePluginManager.get_passmanager_stage(self, stage_name, plugin_name, pm_config, optimization_level)
    251     return self._build_pm(
    252         self.optimization_plugins, stage_name, plugin_name, pm_config, optimization_level
    253     )
    254 elif stage_name == "scheduling":
--> 255     return self._build_pm(
    256         self.scheduling_plugins, stage_name, plugin_name, pm_config, optimization_level
    257     )
    258 else:
    259     raise TranspilerError(f"Invalid stage name: {stage_name}")

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py:272, in PassManagerStagePluginManager._build_pm(self, stage_obj, stage_name, plugin_name, pm_config, optimization_level)
    270     raise TranspilerError(f"Invalid plugin name {plugin_name} for stage {stage_name}")
    271 plugin_obj = stage_obj[plugin_name]
--> 272 return plugin_obj.obj.pass_manager(pm_config, optimization_level)

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/builtin_plugins.py:623, in AlapSchedulingPassManager.pass_manager(self, pass_manager_config, optimization_level)
    620 inst_map = pass_manager_config.inst_map
    621 target = pass_manager_config.target
--> 623 return common.generate_scheduling(
    624     instruction_durations, scheduling_method, timing_constraints, inst_map, target
    625 )

File ~/opt/anaconda3/envs/qiskit10/lib/python3.10/site-packages/qiskit/transpiler/preset_passmanagers/common.py:573, in generate_scheduling(instruction_durations, scheduling_method, timing_constraints, inst_map, target)
    566     scheduling.append(ContainsInstruction("delay"))
    567     scheduling.append(
    568         ConditionalController(
    569             TimeUnitConversion(instruction_durations, target=target), condition=_contains_delay
    570         )
    571     )
    572 if (
--> 573     timing_constraints.granularity != 1
    574     or timing_constraints.min_length != 1
    575     or timing_constraints.acquire_alignment != 1
    576     or timing_constraints.pulse_alignment != 1
    577 ):
    578     # Run alignment analysis regardless of scheduling.
    580     def _require_alignment(property_set):
    581         return property_set["reschedule_required"]

AttributeError: 'NoneType' object has no attribute 'granularity'

there will be no error if we use this option inside of transpile() function.

How can we reproduce the issue?

  1. with FakebackendV2
    
    from qiskit_ibm_runtime.fake_provider import FakeOsaka
    fakeosaka = FakeOsaka()

pm = generate_preset_pass_manager(backend=fakeosaka, optimization_level=1, scheduling_method='alap')

-->  this returns "AttributeError: 'NoneType' object has no attribute 'granularity'"

2. with Aersimulator with noise model

from qiskit_aer import AerSimulator from qiskit_ibm_runtime import QiskitRuntimeService service = QiskitRuntimeService(channel="ibm_quantum")

sim = AerSimulator() backend_device = service.get_backend('ibm_osaka') noisy_backend = AerSimulator.from_backend(backend_device)

pm = generate_preset_pass_manager(backend=noisy_backend, optimization_level=1, scheduling_method='alap')


--> this also returns "AttributeError: 'NoneType' object has no attribute 'granularity'"

### What should happen?

add delays according to the option as expected. 
except this, other options and plugins of generate_preset_pass_manager works well

### Any suggestions?

_No response_
ashsaki commented 1 month ago

Same issue with real backends.

Minimal example:

from qiskit.circuit import QuantumCircuit
from qiskit import transpile
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_torino")

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.x(1)
circuit.cx(0,1)

pm_sched = generate_preset_pass_manager(
    backend=backend,
    optimization_level=3,
    scheduling_method="alap"
)
isa_circuit_sched_pm = pm_sched.run(circuit)

Note that, this error does not occur if we use:

Software versions:

Error trace

14 pm_sched = generate_preset_pass_manager(
     15     backend=backend,
     16     optimization_level=3,
     17     scheduling_method="alap"
     18 )
     19 isa_circuit_sched_pm = pm_sched.run(circuit)

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/__init__.py:259](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/__init__.py#line=258), in generate_preset_pass_manager(optimization_level, backend, target, basis_gates, inst_map, coupling_map, instruction_durations, backend_properties, timing_constraints, initial_layout, layout_method, routing_method, translation_method, scheduling_method, approximation_degree, seed_transpiler, unitary_synthesis_method, unitary_synthesis_plugin_config, hls_config, init_method, optimization_method, _skip_target)
    257     pm = level_2_pass_manager(pm_config)
    258 elif optimization_level == 3:
--> 259     pm = level_3_pass_manager(pm_config)
    260 else:
    261     raise ValueError(f"Invalid optimization level {optimization_level}")

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/level3.py:106](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/level3.py#line=105), in level_3_pass_manager(pass_manager_config)
    103 else:
    104     pre_optimization = common.generate_pre_op_passmanager(remove_reset_in_zero=False)
--> 106 sched = plugin_manager.get_passmanager_stage(
    107     "scheduling", scheduling_method, pass_manager_config, optimization_level=3
    108 )
    110 return StagedPassManager(
    111     pre_init=pre_init,
    112     init=init,
   (...)
    118     scheduling=sched,
    119 )

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py:255](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py#line=254), in PassManagerStagePluginManager.get_passmanager_stage(self, stage_name, plugin_name, pm_config, optimization_level)
    251     return self._build_pm(
    252         self.optimization_plugins, stage_name, plugin_name, pm_config, optimization_level
    253     )
    254 elif stage_name == "scheduling":
--> 255     return self._build_pm(
    256         self.scheduling_plugins, stage_name, plugin_name, pm_config, optimization_level
    257     )
    258 else:
    259     raise TranspilerError(f"Invalid stage name: {stage_name}")

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py:272](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/plugin.py#line=271), in PassManagerStagePluginManager._build_pm(self, stage_obj, stage_name, plugin_name, pm_config, optimization_level)
    270     raise TranspilerError(f"Invalid plugin name {plugin_name} for stage {stage_name}")
    271 plugin_obj = stage_obj[plugin_name]
--> 272 return plugin_obj.obj.pass_manager(pm_config, optimization_level)

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/builtin_plugins.py:623](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/builtin_plugins.py#line=622), in AlapSchedulingPassManager.pass_manager(self, pass_manager_config, optimization_level)
    620 inst_map = pass_manager_config.inst_map
    621 target = pass_manager_config.target
--> 623 return common.generate_scheduling(
    624     instruction_durations, scheduling_method, timing_constraints, inst_map, target
    625 )

File [python3.11/site-packages/qiskit/transpiler/preset_passmanagers/common.py:573](python3.11/site-packages/qiskit/transpiler/preset_passmanagers/common.py#line=572), in generate_scheduling(instruction_durations, scheduling_method, timing_constraints, inst_map, target)
    566     scheduling.append(ContainsInstruction("delay"))
    567     scheduling.append(
    568         ConditionalController(
    569             TimeUnitConversion(instruction_durations, target=target), condition=_contains_delay
    570         )
    571     )
    572 if (
--> 573     timing_constraints.granularity != 1
    574     or timing_constraints.min_length != 1
    575     or timing_constraints.acquire_alignment != 1
    576     or timing_constraints.pulse_alignment != 1
    577 ):
    578     # Run alignment analysis regardless of scheduling.
    580     def _require_alignment(property_set):
    581         return property_set["reschedule_required"]

AttributeError: 'NoneType' object has no attribute 'granularity'