Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
1ucian0 committed Aug 24, 2021
1 parent a34b2ab commit c267ebe
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 6 deletions.
4 changes: 2 additions & 2 deletions qiskit/transpiler/passmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ def _normalize_passes(
if isinstance(passes, BasePass):
passes = [passes]
for pass_ in passes:
if not isinstance(pass_, BasePass):
raise TranspilerError("%s is not a pass instance" % pass_.__class__)
if not isinstance(pass_, (BasePass, PassManager)):
raise TranspilerError("%s is not a pass instance or manager" % pass_.__class__)
return passes

def run(
Expand Down
16 changes: 12 additions & 4 deletions qiskit/transpiler/runningpassmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

from qiskit.dagcircuit import DAGCircuit
from qiskit.converters import circuit_to_dag, dag_to_circuit
from .basepasses import BasePass
from .propertyset import PropertySet
from .fencedobjs import FencedPropertySet, FencedDAGCircuit
from .exceptions import TranspilerError
Expand Down Expand Up @@ -90,7 +91,6 @@ def append(self, passes, **flow_controller_conditions):
passes, self.passmanager_options, **flow_controller_conditions
)
)
pass

def _normalize_flow_controller(self, flow_controller):
for name, param in flow_controller.items():
Expand All @@ -100,6 +100,16 @@ def _normalize_flow_controller(self, flow_controller):
raise TranspilerError("The flow controller parameter %s is not callable" % name)
return flow_controller

def _run_on_dag(self, dag, callback):
for passset in self.working_list:
for pass_ in passset:
if isinstance(pass_, BasePass):
dag = self._do_pass(pass_, dag, passset.options)
else:
running_passmanager = pass_._create_running_passmanager()
dag = running_passmanager._run_on_dag(dag, callback)
return dag

def run(self, circuit, output_name=None, callback=None):
"""Run all the passes on a QuantumCircuit
Expand All @@ -118,9 +128,7 @@ def run(self, circuit, output_name=None, callback=None):
if callback:
self.callback = callback

for passset in self.working_list:
for pass_ in passset:
dag = self._do_pass(pass_, dag, passset.options)
dag = self._run_on_dag(dag, callback)

circuit = dag_to_circuit(dag)
if output_name:
Expand Down
85 changes: 85 additions & 0 deletions test/python/transpiler/test_pass_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def assertScheduler(self, circuit, passmanager, expected):
with self.assertLogs(logger, level="INFO") as cm:
out = passmanager.run(circuit)
self.assertIsInstance(out, QuantumCircuit)
print([record.message for record in cm.records])
self.assertEqual([record.message for record in cm.records], expected)

def assertSchedulerRaises(self, circuit, passmanager, expected, exception_type):
Expand Down Expand Up @@ -550,6 +551,90 @@ def test_fresh_initial_state(self):
],
)

def test_conditional_inside_loop(self):
"""Nestead flow control
See https://github.com/Qiskit/qiskit-terra/issues/6830"""
conditional_part = PassManager()
conditional_part.append(PassE_AP_NR_NP(True))
conditional_part.append(
PassA_TP_NR_NP(), condition=lambda property_set: property_set["property"]
)
self.passmanager.append(
[
PassK_check_fixed_point_property(),
PassA_TP_NR_NP(),
PassF_reduce_dag_property(),
conditional_part,
],
do_while=lambda property_set: not property_set["property_fixed_point"],
)
expected = [
"run analysis pass PassG_calculates_dag_property",
"set property as 8 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 6",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 6 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 5",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 5 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 4",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 4 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 3",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 3 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 2",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 2 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 2",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
"run analysis pass PassG_calculates_dag_property",
"set property as 2 (from dag.property)",
"run analysis pass PassK_check_fixed_point_property",
"run transformation pass PassA_TP_NR_NP",
"run transformation pass PassF_reduce_dag_property",
"dag property = 2",
"run analysis pass PassE_AP_NR_NP",
"set property as True",
"run transformation pass PassA_TP_NR_NP",
]
self.assertScheduler(self.circuit, self.passmanager, expected)


class DoXTimesController(FlowController):
"""A control-flow plugin for running a set of passes an X amount of times."""
Expand Down

0 comments on commit c267ebe

Please sign in to comment.