def test_ibm_backend_is_available_control_not(num_ctrl_qubits, is_available): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit1 = eng.allocate_qubit() qureg = eng.allocate_qureg(num_ctrl_qubits) ibm_backend = _ibm.IBMBackend() cmd = Command(eng, NOT, (qubit1,), controls=qureg) assert ibm_backend.is_available(cmd) == is_available
def test_qubit_management_error(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) with _compute.Compute(eng): ancilla = eng.allocate_qubit() eng.active_qubits = weakref.WeakSet() with pytest.raises(_compute.QubitManagementError): _compute.Uncompute(eng)
def test_compute_uncompute_no_additional_qubits(): # No ancilla qubit created in compute section backend0 = DummyEngine(save_commands=True) compare_engine0 = CompareEngine() eng0 = MainEngine(backend=backend0, engine_list=[compare_engine0]) qubit = eng0.allocate_qubit() with _compute.Compute(eng0): Rx(0.5) | qubit H | qubit _compute.Uncompute(eng0) eng0.flush(deallocate_qubits=True) assert backend0.received_commands[0].gate == Allocate assert backend0.received_commands[1].gate == Rx(0.5) assert backend0.received_commands[2].gate == H assert backend0.received_commands[3].gate == Rx(-0.5) assert backend0.received_commands[4].gate == Deallocate assert backend0.received_commands[0].tags == [] assert backend0.received_commands[1].tags == [_compute.ComputeTag()] assert backend0.received_commands[2].tags == [] assert backend0.received_commands[3].tags == [_compute.UncomputeTag()] assert backend0.received_commands[4].tags == [] # Same using CustomUncompute and test using CompareEngine backend1 = DummyEngine(save_commands = True) compare_engine1 = CompareEngine() eng1 = MainEngine(backend=backend1, engine_list=[compare_engine1]) qubit = eng1.allocate_qubit() with _compute.Compute(eng1): Rx(0.5) | qubit H | qubit with _compute.CustomUncompute(eng1): Rx(-0.5) | qubit eng1.flush(deallocate_qubits=True) assert compare_engine0 == compare_engine1
def test_qureg(qubit_ids, expected): eng = MainEngine(backend = DummyEngine(), engine_list = [DummyEngine()]) qureg = _qubit.Qureg() for qubit_id in qubit_ids: qubit = _qubit.Qubit(eng, qubit_id) qureg.append(qubit) assert str(qureg) == expected
def test_loop_unrolling_with_ancillas(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() qubit_id = deepcopy(qubit[0].id) with _loop.Loop(eng, 3): ancilla = eng.allocate_qubit() H | ancilla CNOT | (ancilla, qubit) del ancilla eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 15 assert backend.received_commands[0].gate == Allocate for ii in range(3): assert backend.received_commands[ii * 4 + 1].gate == Allocate assert backend.received_commands[ii * 4 + 2].gate == H assert backend.received_commands[ii * 4 + 3].gate == X assert backend.received_commands[ii * 4 + 4].gate == Deallocate # Check qubit ids assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 2].qubits[0][0].id) assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 3].control_qubits[0].id) assert backend.received_commands[ii * 4 + 3].qubits[0][0].id == qubit_id assert (backend.received_commands[ii * 4 + 1].qubits[0][0].id == backend.received_commands[ii * 4 + 4].qubits[0][0].id) assert backend.received_commands[13].gate == Deallocate assert backend.received_commands[14].gate == FlushGate() assert backend.received_commands[1].qubits[0][ 0].id != backend.received_commands[5].qubits[0][0].id assert backend.received_commands[1].qubits[0][ 0].id != backend.received_commands[9].qubits[0][0].id assert backend.received_commands[5].qubits[0][ 0].id != backend.received_commands[9].qubits[0][0].id
def test_control(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qureg = eng.allocate_qureg(2) with _control.Control(eng, qureg): qubit = eng.allocate_qubit() with Compute(eng): Rx(0.5) | qubit H | qubit Uncompute(eng) with _control.Control(eng, qureg[0]): H | qubit eng.flush() assert len(backend.received_commands) == 8 assert len(backend.received_commands[0].control_qubits) == 0 assert len(backend.received_commands[1].control_qubits) == 0 assert len(backend.received_commands[2].control_qubits) == 0 assert len(backend.received_commands[3].control_qubits) == 0 assert len(backend.received_commands[4].control_qubits) == 2 assert len(backend.received_commands[5].control_qubits) == 0 assert len(backend.received_commands[6].control_qubits) == 1 assert len(backend.received_commands[7].control_qubits) == 0 assert backend.received_commands[4].control_qubits[0].id == qureg[0].id assert backend.received_commands[4].control_qubits[1].id == qureg[1].id assert backend.received_commands[6].control_qubits[0].id == qureg[0].id
def test_basic_gate_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) qubit3 = Qubit(main_engine, 3) qureg = Qureg([qubit2, qubit3]) basic_gate = _basics.BasicGate() command1 = basic_gate.generate_command(qubit0) basic_gate | qubit0 command2 = basic_gate.generate_command([qubit0, qubit1]) basic_gate | [qubit0, qubit1] command3 = basic_gate.generate_command(qureg) basic_gate | qureg command4 = basic_gate.generate_command((qubit0, )) basic_gate | (qubit0, ) command5 = basic_gate.generate_command((qureg, qubit0)) basic_gate | (qureg, qubit0) received_commands = [] # Remove Deallocate gates for cmd in saving_backend.received_commands: if not isinstance(cmd.gate, _basics.FastForwardingGate): received_commands.append(cmd) assert received_commands == ([ command1, command2, command3, command4, command5 ])
def test_insert_then_drop(): d1 = DummyEngine() d2 = DummyEngine() d3 = DummyEngine() eng = MainEngine(backend=d3, engine_list=[d1]) assert d1.next_engine is d3 assert d2.next_engine is None assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is None assert d3.main_engine is eng assert eng.n_engines == 2 _util.insert_engine(d1, d2) assert d1.next_engine is d2 assert d2.next_engine is d3 assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is eng assert d3.main_engine is eng assert eng.n_engines == 3 _util.drop_engine_after(d1) assert d1.next_engine is d3 assert d2.next_engine is None assert d3.next_engine is None assert d1.main_engine is eng assert d2.main_engine is None assert d3.main_engine is eng assert eng.n_engines == 2
def test_tensor_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) gate = Rx(0.6) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) # Option 1: _metagates.Tensor(gate) | ([qubit0, qubit1, qubit2], ) # Option 2: _metagates.Tensor(gate) | [qubit0, qubit1, qubit2] received_commands = [] # Remove Allocate and Deallocate gates for cmd in saving_backend.received_commands: if not (isinstance(cmd.gate, FastForwardingGate) or isinstance(cmd.gate, ClassicalInstructionGate)): received_commands.append(cmd) # Check results assert len(received_commands) == 6 qubit_ids = [] for cmd in received_commands: assert len(cmd.qubits) == 1 assert cmd.gate == gate qubit_ids.append(cmd.qubits[0][0].id) assert sorted(qubit_ids) == [0, 0, 1, 1, 2, 2]
def test_decomposition(angle): for basis_state in ([1, 0], [0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[ry2rz]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(ry_decomp_gates), test_dummy_eng ]) correct_qb = correct_eng.allocate_qubit() Ry(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Ry(angle) | test_qb test_eng.flush() assert correct_dummy_eng.received_commands[1].gate == Ry(angle) assert test_dummy_eng.received_commands[1].gate != Ry(angle) for fstate in ['0', '1']: test = test_eng.backend.get_amplitude(fstate, test_qb) correct = correct_eng.backend.get_amplitude(fstate, correct_qb) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def test_controlled_gate_or(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) gate = Rx(0.6) qubit0 = Qubit(main_engine, 0) qubit1 = Qubit(main_engine, 1) qubit2 = Qubit(main_engine, 2) qubit3 = Qubit(main_engine, 3) expected_cmd = Command(main_engine, gate, ([qubit3], ), controls=[qubit0, qubit1, qubit2]) received_commands = [] # Option 1: _metagates.ControlledGate(gate, 3) | ([qubit1], [qubit0], [qubit2 ], [qubit3]) # Option 2: _metagates.ControlledGate(gate, 3) | (qubit1, qubit0, qubit2, qubit3) # Option 3: _metagates.ControlledGate(gate, 3) | ([qubit1, qubit0], qubit2, qubit3) # Option 4: _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2], qubit3) # Wrong option 5: with pytest.raises(_metagates.ControlQubitError): _metagates.ControlledGate(gate, 3) | (qubit1, [qubit0, qubit2, qubit3]) # Remove Allocate and Deallocate gates for cmd in saving_backend.received_commands: if not (isinstance(cmd.gate, FastForwardingGate) or isinstance(cmd.gate, ClassicalInstructionGate)): received_commands.append(cmd) assert len(received_commands) == 4 for cmd in received_commands: assert cmd == expected_cmd
def test_qureg_engine(): eng1 = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) eng2 = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qureg = _qubit.Qureg([_qubit.Qubit(eng1, 0), _qubit.Qubit(eng1, 1)]) assert eng1 == qureg.engine qureg.engine = eng2 assert qureg[0].engine == eng2 and qureg[1].engine == eng2
def test_qubit_not_copyable(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit = _qubit.Qubit(eng, 10) qubit_copy = copy(qubit) assert id(qubit) == id(qubit_copy) qubit_deepcopy = deepcopy(qubit) assert id(qubit) == id(qubit_deepcopy)
def test_swapandcnotflipper_is_available(): flipper = _swapandcnotflipper.SwapAndCNOTFlipper(set()) dummy = DummyEngine() dummy.is_available = lambda x: False flipper.next_engine = dummy eng = MainEngine(DummyEngine(save_commands=True), []) qubit1, qubit2 = eng.allocate_qureg(2) Swap | (qubit1, qubit2) swap_count = 0 for cmd in eng.backend.received_commands: if cmd.gate == Swap: swap_count += 1 assert flipper.is_available(cmd) assert swap_count == 1 eng = MainEngine(DummyEngine(save_commands=True), []) qubit1, qubit2, qubit3 = eng.allocate_qureg(3) with Control(eng, qubit3): Swap | (qubit1, qubit2) swap_count = 0 for cmd in eng.backend.received_commands: if cmd.gate == Swap: swap_count += 1 assert not flipper.is_available(cmd) assert swap_count == 1
def test_swapandcnotflipper_optimize_swaps(): backend = DummyEngine(save_commands=True) connectivity = set([(1, 0)]) flipper = _swapandcnotflipper.SwapAndCNOTFlipper(connectivity) eng = MainEngine(backend=backend, engine_list=[flipper]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() Swap | (qb0, qb1) hgates = 0 for cmd in backend.received_commands: if cmd.gate == H: hgates += 1 if cmd.gate == X: assert cmd.qubits[0][0].id == 0 assert cmd.control_qubits[0].id == 1 assert hgates == 4 backend = DummyEngine(save_commands=True) connectivity = set([(0, 1)]) flipper = _swapandcnotflipper.SwapAndCNOTFlipper(connectivity) eng = MainEngine(backend=backend, engine_list=[flipper]) qb0 = eng.allocate_qubit() qb1 = eng.allocate_qubit() Swap | (qb0, qb1) hgates = 0 for cmd in backend.received_commands: if cmd.gate == H: hgates += 1 if cmd.gate == X: assert cmd.qubits[0][0].id == 1 assert cmd.control_qubits[0].id == 0 assert hgates == 4
def test_loop_unrolling(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() with _loop.Loop(eng, 3): H | qubit eng.flush(deallocate_qubits=True) assert len(backend.received_commands) == 6
def test_outside_qubit_deallocated_in_compute(): # Test that there is an error if a qubit is deallocated which has # not been allocated within the with Compute(eng) context eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() with pytest.raises(_compute.QubitManagementError): with _compute.Compute(eng): qubit[0].__del__()
def test_decomposition(): for basis_state_index in range(0, 16): basis_state = [0] * 16 basis_state[basis_state_index] = 1.0 correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[cnu2toffoliandcu]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(_decomp_gates), test_dummy_eng, ], ) test_sim = test_eng.backend correct_sim = correct_eng.backend correct_qb = correct_eng.allocate_qubit() correct_ctrl_qureg = correct_eng.allocate_qureg(3) correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qureg = test_eng.allocate_qureg(3) test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qureg) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qureg) with Control(test_eng, test_ctrl_qureg[:2]): Rx(0.4) | test_qb with Control(test_eng, test_ctrl_qureg): Ry(0.6) | test_qb with Control(test_eng, test_ctrl_qureg): X | test_qb with Control(correct_eng, correct_ctrl_qureg[:2]): Rx(0.4) | correct_qb with Control(correct_eng, correct_ctrl_qureg): Ry(0.6) | correct_qb with Control(correct_eng, correct_ctrl_qureg): X | correct_qb test_eng.flush() correct_eng.flush() assert len(correct_dummy_eng.received_commands) == 9 assert len(test_dummy_eng.received_commands) == 25 for fstate in range(16): binary_state = format(fstate, '04b') test = test_sim.get_amplitude(binary_state, test_qb + test_ctrl_qureg) correct = correct_sim.get_amplitude(binary_state, correct_qb + correct_ctrl_qureg) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qureg All(Measure) | correct_qb + correct_ctrl_qureg test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def test_deallocation_using_custom_uncompute3(): # Test not allowed version: eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) with _compute.Compute(eng): pass with pytest.raises(_compute.QubitManagementError): with _compute.CustomUncompute(eng): ancilla = eng.allocate_qubit() H | ancilla
def test_empty_loop(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qubit = eng.allocate_qubit() assert len(backend.received_commands) == 1 with _loop.Loop(eng, 0): H | qubit assert len(backend.received_commands) == 1
def test_aqt_backend_is_available_control_not(num_ctrl_qubits, is_available): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qubit1 = eng.allocate_qubit() qureg = eng.allocate_qureg(num_ctrl_qubits) aqt_backend = _aqt.AQTBackend() cmd = Command(eng, Rx(0.5), (qubit1, ), controls=qureg) assert aqt_backend.is_available(cmd) == is_available cmd = Command(eng, Rxx(0.5), (qubit1, ), controls=qureg) assert aqt_backend.is_available(cmd) == is_available
def test_basic_permutation(): saving_backend = DummyEngine(save_commands=True) main_engine = MainEngine(backend=saving_backend, engine_list=[DummyEngine()]) qubit0 = main_engine.allocate_qubit() qubit1 = main_engine.allocate_qubit() PermutationOracle([0, 2, 1, 3]) | (qubit0, qubit1) assert len(saving_backend.received_commands) == 5
def test_main_engine_init_failure(): with pytest.raises(_main.UnsupportedEngineError): eng = _main.MainEngine(backend=DummyEngine) with pytest.raises(_main.UnsupportedEngineError): eng = _main.MainEngine(engine_list=DummyEngine) with pytest.raises(_main.UnsupportedEngineError): eng = _main.MainEngine(engine_list=[DummyEngine(), DummyEngine]) with pytest.raises(_main.UnsupportedEngineError): engine = DummyEngine() eng = _main.MainEngine(backend=engine, engine_list=[engine])
def test_qureg_measure_exception(): eng = MainEngine(backend=DummyEngine(), engine_list=[DummyEngine()]) qureg = _qubit.Qureg() for qubit_id in [0, 1]: qubit = _qubit.Qubit(eng, qubit_id) qureg.append(qubit) with pytest.raises(Exception): qureg.__bool__() with pytest.raises(Exception): qureg.__int__()
def test_control_state_contradiction(): backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) qureg = eng.allocate_qureg(1) with pytest.raises(IncompatibleControlState): with _control.Control(eng, qureg[0], '0'): qubit = eng.allocate_qubit() with _control.Control(eng, qureg[0], '1'): H | qubit eng.flush()
def test_decomposition(gate_matrix): # Create single qubit gate with gate_matrix test_gate = MatrixGate() test_gate.matrix = np.matrix(gate_matrix) for basis_state in ([1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(modules=[carb1q]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine( backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(_decomp_gates), test_dummy_eng, ], ) test_sim = test_eng.backend correct_sim = correct_eng.backend correct_qb = correct_eng.allocate_qubit() correct_ctrl_qb = correct_eng.allocate_qubit() correct_eng.flush() test_qb = test_eng.allocate_qubit() test_ctrl_qb = test_eng.allocate_qubit() test_eng.flush() correct_sim.set_wavefunction(basis_state, correct_qb + correct_ctrl_qb) test_sim.set_wavefunction(basis_state, test_qb + test_ctrl_qb) with Control(test_eng, test_ctrl_qb): test_gate | test_qb with Control(correct_eng, correct_ctrl_qb): test_gate | correct_qb test_eng.flush() correct_eng.flush() assert correct_dummy_eng.received_commands[3].gate == test_gate assert test_dummy_eng.received_commands[3].gate != test_gate for fstate in ['00', '01', '10', '11']: test = test_sim.get_amplitude(fstate, test_qb + test_ctrl_qb) correct = correct_sim.get_amplitude(fstate, correct_qb + correct_ctrl_qb) assert correct == pytest.approx(test, rel=1e-12, abs=1e-12) All(Measure) | test_qb + test_ctrl_qb All(Measure) | correct_qb + correct_ctrl_qb test_eng.flush(deallocate_qubits=True) correct_eng.flush(deallocate_qubits=True)
def test_decomposition(angle): """ Test that this decomposition of Rz produces correct amplitudes Note that this function tests each DecompositionRule in rz2rx.all_defined_decomposition_rules """ decomposition_rule_list = rz2rx.all_defined_decomposition_rules for rule in decomposition_rule_list: for basis_state in ([1, 0], [0, 1]): correct_dummy_eng = DummyEngine(save_commands=True) correct_eng = MainEngine(backend=Simulator(), engine_list=[correct_dummy_eng]) rule_set = DecompositionRuleSet(rules=[rule]) test_dummy_eng = DummyEngine(save_commands=True) test_eng = MainEngine(backend=Simulator(), engine_list=[ AutoReplacer(rule_set), InstructionFilter(rz_decomp_gates), test_dummy_eng ]) correct_qb = correct_eng.allocate_qubit() Rz(angle) | correct_qb correct_eng.flush() test_qb = test_eng.allocate_qubit() Rz(angle) | test_qb test_eng.flush() # Create empty vectors for the wave vectors for the correct and # test qubits correct_vector = np.zeros((2, 1), dtype=np.complex_) test_vector = np.zeros((2, 1), dtype=np.complex_) i = 0 for fstate in ['0', '1']: test = test_eng.backend.get_amplitude(fstate, test_qb) correct = correct_eng.backend.get_amplitude(fstate, correct_qb) correct_vector[i] = correct test_vector[i] = test i += 1 # Necessary to transpose vector to use matrix dot product test_vector = test_vector.transpose() # Remember that transposed vector should come first in product vector_dot_product = np.dot(test_vector, correct_vector) assert np.absolute(vector_dot_product) == pytest.approx(1, rel=1e-12, abs=1e-12) Measure | test_qb Measure | correct_qb
def test_too_many_engines(): N = 10 eng = MainEngine(backend=DummyEngine(), engine_list=[]) eng.n_engines_max = N for _ in range(N - 1): _util.insert_engine(eng, DummyEngine()) with pytest.raises(RuntimeError): _util.insert_engine(eng, DummyEngine())
def test_qubit_management_error_when_loop_tag_supported(): backend = DummyEngine(save_commands=True) def allow_loop_tags(self, meta_tag): return meta_tag == _loop.LoopTag backend.is_meta_tag_handler = types.MethodType(allow_loop_tags, backend) eng = MainEngine(backend=backend, engine_list=[DummyEngine()]) with pytest.raises(_loop.QubitManagementError): with _loop.Loop(eng, 3): qb = eng.allocate_qubit()
def test_compare_engine(): compare_engine0 = _testengine.CompareEngine() compare_engine1 = _testengine.CompareEngine() compare_engine2 = _testengine.CompareEngine() compare_engine3 = _testengine.CompareEngine() eng0 = MainEngine(backend=compare_engine0, engine_list=[DummyEngine()]) eng1 = MainEngine(backend=compare_engine1, engine_list=[DummyEngine()]) eng2 = MainEngine(backend=compare_engine2, engine_list=[DummyEngine()]) eng3 = MainEngine(backend=compare_engine3, engine_list=[DummyEngine()]) # reference circuit qb00 = eng0.allocate_qubit() qb01 = eng0.allocate_qubit() qb02 = eng0.allocate_qubit() H | qb00 CNOT | (qb00, qb01) CNOT | (qb01, qb00) H | qb00 Rx(0.5) | qb01 CNOT | (qb00, qb01) Rx(0.6) | qb02 eng0.flush() # identical circuit: qb10 = eng1.allocate_qubit() qb11 = eng1.allocate_qubit() qb12 = eng1.allocate_qubit() H | qb10 Rx(0.6) | qb12 CNOT | (qb10, qb11) CNOT | (qb11, qb10) Rx(0.5) | qb11 H | qb10 CNOT | (qb10, qb11) eng1.flush() # mistake in CNOT circuit: qb20 = eng2.allocate_qubit() qb21 = eng2.allocate_qubit() qb22 = eng2.allocate_qubit() H | qb20 Rx(0.6) | qb22 CNOT | (qb21, qb20) CNOT | (qb20, qb21) Rx(0.5) | qb21 H | qb20 CNOT | (qb20, qb21) eng2.flush() # test other branch to fail qb30 = eng3.allocate_qubit() # noqa: F841 qb31 = eng3.allocate_qubit() # noqa: F841 qb32 = eng3.allocate_qubit() # noqa: F841 eng3.flush() assert compare_engine0 == compare_engine1 assert compare_engine1 != compare_engine2 assert compare_engine1 != compare_engine3 assert not compare_engine0 == DummyEngine()