|
19 | 19 | from inspect import signature |
20 | 20 |
|
21 | 21 | from qiskit.circuit import QuantumCircuit |
22 | | -from qiskit.converters import circuit_to_dag, dag_to_circuit |
23 | 22 | from qiskit.dagcircuit import DAGCircuit |
24 | 23 | from qiskit.passmanager.base_tasks import GenericPass, PassManagerIR |
25 | 24 | from qiskit.passmanager.compilation_status import PropertySet, RunState, PassManagerState |
26 | 25 |
|
27 | 26 | from .exceptions import TranspilerError |
28 | | -from .layout import TranspileLayout |
29 | 27 |
|
30 | 28 |
|
31 | 29 | class MetaPass(abc.ABCMeta): |
@@ -126,57 +124,31 @@ def __call__( |
126 | 124 |
|
127 | 125 | Args: |
128 | 126 | circuit: The dag on which the pass is run. |
129 | | - property_set: Input/output property set. An analysis pass |
130 | | - might change the property set in-place. |
| 127 | + property_set: Input/output property set. An analysis pass might change the property set |
| 128 | + in-place. If not given, the existing ``property_set`` attribute of the pass will |
| 129 | + be used (if set). |
131 | 130 |
|
132 | 131 | Returns: |
133 | 132 | If on transformation pass, the resulting QuantumCircuit. |
134 | 133 | If analysis pass, the input circuit. |
135 | 134 | """ |
136 | | - property_set_ = None |
137 | | - if isinstance(property_set, dict): # this includes (dict, PropertySet) |
138 | | - property_set_ = PropertySet(property_set) |
139 | | - |
140 | | - if isinstance(property_set_, PropertySet): |
141 | | - # pylint: disable=attribute-defined-outside-init |
142 | | - self.property_set = property_set_ |
143 | | - |
144 | | - result = self.run(circuit_to_dag(circuit)) |
145 | | - |
146 | | - result_circuit = circuit |
147 | | - |
148 | | - if isinstance(property_set, dict): # this includes (dict, PropertySet) |
| 135 | + from qiskit.transpiler import PassManager # pylint: disable=cyclic-import |
| 136 | + |
| 137 | + pm = PassManager([self]) |
| 138 | + # Previous versions of the `__call__` function would not construct a `PassManager`, but just |
| 139 | + # call `self.run` directly (this caused issues with `requires`). It only overrode |
| 140 | + # `self.property_set` if the input was not `None`, which some users might have been relying |
| 141 | + # on (as our test suite was). |
| 142 | + if property_set is None: |
| 143 | + property_set = self.property_set |
| 144 | + out = pm.run(circuit, property_set=property_set) |
| 145 | + if property_set is not None and property_set is not pm.property_set: |
| 146 | + # When this `__call__` was first added, it contained this behaviour of mutating the |
| 147 | + # input `property_set` in-place, but didn't use the `PassManager` infrastructure. This |
| 148 | + # preserves the output-variable nature of the `property_set` parameter. |
149 | 149 | property_set.clear() |
150 | | - property_set.update(self.property_set) |
151 | | - |
152 | | - if isinstance(result, DAGCircuit): |
153 | | - result_circuit = dag_to_circuit(result, copy_operations=False) |
154 | | - elif result is None: |
155 | | - result_circuit = circuit.copy() |
156 | | - |
157 | | - if self.property_set["layout"]: |
158 | | - result_circuit._layout = TranspileLayout( |
159 | | - initial_layout=self.property_set["layout"], |
160 | | - input_qubit_mapping=self.property_set["original_qubit_indices"], |
161 | | - final_layout=self.property_set["final_layout"], |
162 | | - _input_qubit_count=len(circuit.qubits), |
163 | | - _output_qubit_list=result_circuit.qubits, |
164 | | - ) |
165 | | - if self.property_set["clbit_write_latency"] is not None: |
166 | | - result_circuit._clbit_write_latency = self.property_set["clbit_write_latency"] |
167 | | - if self.property_set["conditional_latency"] is not None: |
168 | | - result_circuit._conditional_latency = self.property_set["conditional_latency"] |
169 | | - if self.property_set["node_start_time"]: |
170 | | - # This is dictionary keyed on the DAGOpNode, which is invalidated once |
171 | | - # dag is converted into circuit. So this schedule information is |
172 | | - # also converted into list with the same ordering with circuit.data. |
173 | | - topological_start_times = [] |
174 | | - start_times = self.property_set["node_start_time"] |
175 | | - for dag_node in result.topological_op_nodes(): |
176 | | - topological_start_times.append(start_times[dag_node]) |
177 | | - result_circuit._op_start_times = topological_start_times |
178 | | - |
179 | | - return result_circuit |
| 150 | + property_set.update(pm.property_set) |
| 151 | + return out |
180 | 152 |
|
181 | 153 |
|
182 | 154 | class AnalysisPass(BasePass): # pylint: disable=abstract-method |
|
0 commit comments