Skip to content

Commit

Permalink
make sure stochastic swap child instances get new seeds
Browse files Browse the repository at this point in the history
  • Loading branch information
ewinston committed Oct 4, 2022
1 parent dc5b23c commit 9d16884
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 35 deletions.
21 changes: 9 additions & 12 deletions qiskit/transpiler/passes/routing/stochastic_swap.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class StochasticSwap(TransformationPass):
the circuit.
"""

_count = 0 # track number of instances of this class
_instance_num = 0 # track number of instances of this class

def __init__(
self, coupling_map, trials=20, seed=None, fake_run=False, initial_layout=None, _depth=0
Expand Down Expand Up @@ -79,8 +79,7 @@ def __init__(
self.initial_layout = initial_layout
self._qubit_indices = None
self._depth = _depth
self._count += 1
self._instance_num = self._count
self._instance_num += 1

def run(self, dag):
"""Run the StochasticSwap pass on `dag`.
Expand Down Expand Up @@ -303,7 +302,7 @@ def _mapper(self, circuit_graph, coupling_graph, trials=20):
cf_layout = None
for node in subdag.op_nodes(op=ControlFlowOp):
updated_ctrl_op, cf_layout, idle_qubits = self._transpile_controlflow_op(
node, layout, circuit_graph
node, layout, circuit_graph, _seed=self.seed
)
cf_subdag = DAGCircuit()
cf_qubits = [qubit for qubit in circuit_graph.qubits if qubit not in idle_qubits]
Expand Down Expand Up @@ -386,19 +385,17 @@ def _mapper(self, circuit_graph, coupling_graph, trials=20):
return circuit_graph
return dagcircuit_output

def _transpile_controlflow_op(self, cf_opnode, current_layout, dag, _depth=0):
def _transpile_controlflow_op(self, cf_opnode, current_layout, dag, _depth=0, _seed=None):
"""handle controlflow ops by type"""
# seed = None
# if self.seed is not None:
# seed = self.seed + self._instance_num
seed = self.seed

seed = _seed if _seed is None else _seed + self._instance_num
_pass = self.__class__(
self.coupling_map, initial_layout=current_layout, seed=seed, _depth=self._depth + 1
)
if isinstance(cf_opnode.op, IfElseOp):
return route_cf_multiblock(_pass, cf_opnode, current_layout, self.qregs, dag, seed=seed)
return route_cf_multiblock(
_pass, cf_opnode, current_layout, self.qregs, dag, seed=self.seed
)
elif isinstance(cf_opnode.op, (ForLoopOp, WhileLoopOp)):
return route_cf_looping(_pass, cf_opnode, current_layout, dag, seed=seed)
return route_cf_looping(_pass, cf_opnode, current_layout, dag, seed=self.seed)
else:
raise TranspilerError(f"unsupported control flow operation: {cf_opnode}")
43 changes: 20 additions & 23 deletions test/python/transpiler/test_stochastic_swap.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,9 +980,9 @@ def test_controlflow_for_loop(self, nloops):
expected.h(0)
expected.x(1)
efor_body = QuantumCircuit(qreg, creg)
efor_body.swap(1, 2)
efor_body.cx(0, 1)
efor_body.swap(1, 2)
efor_body.swap(0, 1)
efor_body.cx(1, 2)
efor_body.swap(0, 1)
loop_parameter = None
expected.for_loop(range(nloops), loop_parameter, efor_body, qreg, creg)
expected.measure(qreg, creg)
Expand Down Expand Up @@ -1069,15 +1069,16 @@ def test_controlflow_nested_inner_cnot(self):
efor_body = QuantumCircuit(qreg, creg)
efor_body.delay(10, 0)
efor_body.barrier(qreg)
efor_body.swap(0, 1)
efor_body.cx(1, 2)
efor_body.swap(0, 1)
efor_body.swap(1, 2)
efor_body.cx(0, 1)
efor_body.swap(1, 2)
etrue_body.for_loop(range(3), loop_parameter, efor_body, qreg, creg)

efalse_body = QuantumCircuit(qreg, creg)
efalse_body.y(0)
expected.if_else((creg[0], 0), etrue_body, efalse_body, qreg, creg)
expected.measure(qreg, creg)

self.assertEqual(cqc, expected)
check_map_pass = CheckMap(coupling)
check_map_pass.run(circuit_to_dag(expected))
Expand Down Expand Up @@ -1120,25 +1121,21 @@ def test_controlflow_nested_outer_cnot(self):
expected.x(1)
expected.measure(0, 0)
etrue_body = QuantumCircuit(qreg, creg)
etrue_body.swap(0, 1)
etrue_body.cx(1, 2)
etrue_body.x(1)
etrue_body.swap(1, 2)
etrue_body.cx(0, 1)
etrue_body.x(0)

efor_body = QuantumCircuit(qreg, creg)
efor_body.delay(10, 0)
efor_body.barrier(qreg)
efor_body.swap(1, 0)
efor_body.swap(2, 3)
efor_body.cx(0, 2)
efor_body.swap(1, 0)
efor_body.swap(2, 3)
etrue_body.for_loop(range(3), loop_parameter, efor_body, qreg[[1, 0, 2, 3, 4]], creg)
efor_body.cx(1, 3)
etrue_body.for_loop(range(3), loop_parameter, efor_body, qreg[[0, 2, 1, 3, 4]], creg)

efalse_body = QuantumCircuit(qreg, creg)
efalse_body.y(0)
efalse_body.swap(1, 0)
efalse_body.swap(1, 2)
expected.if_else((creg[0], 0), etrue_body, efalse_body, qreg, creg)
expected.measure(qreg, creg[[1, 0, 2, 3, 4]])
expected.measure(qreg, creg[[0, 2, 1, 3, 4]])

check_map_pass.run(circuit_to_dag(expected))
self.assertTrue(check_map_pass.property_set["is_swap_mapped"])
Expand All @@ -1157,9 +1154,9 @@ def test_controlflow_disjoint_looping(self):

expected = QuantumCircuit(qr)
efor_body = QuantumCircuit(3)
efor_body.swap(1, 0)
efor_body.cx(1, 2)
efor_body.swap(1, 0)
efor_body.swap(1, 2)
efor_body.cx(0, 1)
efor_body.swap(1, 2)
expected.for_loop((0,), None, efor_body, [0, 1, 2], [])
self.assertEqual(cqc, expected)

Expand All @@ -1180,10 +1177,10 @@ def test_controlflow_disjoint_multiblock(self):
expected = QuantumCircuit(qr, cr)
etrue_body = QuantumCircuit(true_body.qregs[0], cr)
etrue_body.cx(0, 1)
etrue_body.swap(1, 2)
etrue_body.swap(0, 1)
efalse_body = QuantumCircuit(false_body.qregs[0], cr)
efalse_body.swap(1, 2)
efalse_body.cx(0, 1)
efalse_body.swap(0, 1)
efalse_body.cx(1, 2)
expected.if_else((cr[0], 1), etrue_body, efalse_body, [0, 1, 2], [])
self.assertEqual(cqc, expected)

Expand Down

0 comments on commit 9d16884

Please sign in to comment.