-
Notifications
You must be signed in to change notification settings - Fork 171
/
Copy pathplugin.py
138 lines (114 loc) · 5.72 KB
/
plugin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# This code is part of Qiskit.
#
# (C) Copyright IBM 2022.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""Plugin for IBM provider backend transpiler stages."""
from typing import Optional
from qiskit.transpiler.passmanager import PassManager
from qiskit.transpiler.passmanager_config import PassManagerConfig
from qiskit.transpiler.preset_passmanagers.plugin import PassManagerStagePlugin
from qiskit.transpiler.preset_passmanagers import common
from qiskit.transpiler.passes import ConvertConditionsToIfOps
from qiskit_ibm_runtime.transpiler.passes.basis import (
ConvertIdToDelay,
FoldRzzAngle,
)
class IBMTranslationPlugin(PassManagerStagePlugin):
"""A translation stage plugin for targeting Qiskit circuits
to IBM Quantum systems."""
def pass_manager(
self,
pass_manager_config: PassManagerConfig,
optimization_level: Optional[int] = None,
) -> PassManager:
"""Build IBMTranslationPlugin PassManager."""
translator_pm = common.generate_translation_passmanager(
target=pass_manager_config.target,
basis_gates=pass_manager_config.basis_gates,
approximation_degree=pass_manager_config.approximation_degree,
coupling_map=pass_manager_config.coupling_map,
backend_props=pass_manager_config.backend_properties,
unitary_synthesis_method=pass_manager_config.unitary_synthesis_method,
unitary_synthesis_plugin_config=pass_manager_config.unitary_synthesis_plugin_config,
hls_config=pass_manager_config.hls_config,
qubits_initially_zero=pass_manager_config.qubits_initially_zero,
)
plugin_passes = []
instruction_durations = pass_manager_config.instruction_durations
if instruction_durations:
plugin_passes.append(ConvertIdToDelay(instruction_durations))
return PassManager(plugin_passes) + translator_pm
class IBMDynamicTranslationPlugin(PassManagerStagePlugin):
"""A translation stage plugin for targeting Qiskit circuits
to IBM Quantum systems."""
def pass_manager(
self,
pass_manager_config: PassManagerConfig,
optimization_level: Optional[int] = None,
) -> PassManager:
"""Build IBMTranslationPlugin PassManager."""
translator_pm = common.generate_translation_passmanager(
target=pass_manager_config.target,
basis_gates=pass_manager_config.basis_gates,
approximation_degree=pass_manager_config.approximation_degree,
coupling_map=pass_manager_config.coupling_map,
backend_props=pass_manager_config.backend_properties,
unitary_synthesis_method=pass_manager_config.unitary_synthesis_method,
unitary_synthesis_plugin_config=pass_manager_config.unitary_synthesis_plugin_config,
hls_config=pass_manager_config.hls_config,
)
instruction_durations = pass_manager_config.instruction_durations
plugin_passes = []
if pass_manager_config.target is not None:
id_supported = "id" in pass_manager_config.target
else:
id_supported = "id" in pass_manager_config.basis_gates
if instruction_durations and not id_supported:
plugin_passes.append(ConvertIdToDelay(instruction_durations))
# Only inject control-flow conversion pass at level 0 and level 1. As of
# qiskit 0.22.x transpile() with level 2 and 3 does not support
# control flow instructions (including if_else). This can be
# removed when higher optimization levels support control flow
# instructions.
if optimization_level in {0, 1}:
plugin_passes += [ConvertConditionsToIfOps()]
return PassManager(plugin_passes) + translator_pm
class IBMFractionalTranslationPlugin(PassManagerStagePlugin):
"""A translation stage plugin for targeting Qiskit circuits
to IBM Quantum systems with fractional gate support.
Currently coexistence of fractional gate operations and
dynamic circuits is not assumed.
"""
def pass_manager(
self,
pass_manager_config: PassManagerConfig,
optimization_level: Optional[int] = None,
) -> PassManager:
"""Build IBMTranslationPlugin PassManager."""
translator_pm = common.generate_translation_passmanager(
target=pass_manager_config.target,
basis_gates=pass_manager_config.basis_gates,
approximation_degree=pass_manager_config.approximation_degree,
coupling_map=pass_manager_config.coupling_map,
backend_props=pass_manager_config.backend_properties,
unitary_synthesis_method=pass_manager_config.unitary_synthesis_method,
unitary_synthesis_plugin_config=pass_manager_config.unitary_synthesis_plugin_config,
hls_config=pass_manager_config.hls_config,
)
instruction_durations = pass_manager_config.instruction_durations
pre_passes = []
post_passes = []
target = pass_manager_config.target or pass_manager_config.basis_gates
if instruction_durations and not "id" in target:
pre_passes.append(ConvertIdToDelay(instruction_durations))
if "rzz" in target:
# Apply this pass after SU4 is translated.
post_passes.append(FoldRzzAngle(target))
return PassManager(pre_passes) + translator_pm + PassManager(post_passes)