Ejemplo n.º 1
0
def test_dagger_with_dirty_qubits():
    backend = DummyEngine(save_commands=True)

    def allow_dirty_qubits(self, meta_tag):
        return meta_tag == DirtyQubitTag

    backend.is_meta_tag_handler = types.MethodType(allow_dirty_qubits, backend)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])
    qubit = eng.allocate_qubit()
    with _dagger.Dagger(eng):
        ancilla = eng.allocate_qubit(dirty=True)
        Rx(0.6) | ancilla
        CNOT | (ancilla, qubit)
        H | qubit
        Rx(-0.6) | ancilla
        del ancilla[0]
    eng.flush(deallocate_qubits=True)
    assert len(backend.received_commands) == 9
    assert backend.received_commands[0].gate == Allocate
    assert backend.received_commands[1].gate == Allocate
    assert backend.received_commands[2].gate == Rx(0.6)
    assert backend.received_commands[3].gate == H
    assert backend.received_commands[4].gate == X
    assert backend.received_commands[5].gate == Rx(-0.6)
    assert backend.received_commands[6].gate == Deallocate
    assert backend.received_commands[7].gate == Deallocate
    assert backend.received_commands[1].tags == [DirtyQubitTag()]
    assert backend.received_commands[6].tags == [DirtyQubitTag()]
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
def test_empty_loop_when_loop_tag_supported_by_backend():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])

    def allow_loop_tags(self, meta_tag):
        return meta_tag == _loop.LoopTag

    backend.is_meta_tag_handler = types.MethodType(allow_loop_tags, backend)
    qubit = eng.allocate_qubit()

    assert len(backend.received_commands) == 1
    with _loop.Loop(eng, 0):
        H | qubit
    assert len(backend.received_commands) == 1
Ejemplo n.º 4
0
def test_loop_with_supported_loop_tag_depending_on_num():
    # Test that if loop has only one iteration, there is no loop tag
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])

    def allow_loop_tags(self, meta_tag):
        return meta_tag == _loop.LoopTag

    backend.is_meta_tag_handler = types.MethodType(allow_loop_tags, backend)
    qubit = eng.allocate_qubit()
    with _loop.Loop(eng, 1):
        H | qubit
    with _loop.Loop(eng, 2):
        H | qubit
    assert len(backend.received_commands[1].tags) == 0
    assert len(backend.received_commands[2].tags) == 1
Ejemplo n.º 5
0
def test_nested_loop():
    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()])
    qubit = eng.allocate_qubit()
    with _loop.Loop(eng, 3):
        with _loop.Loop(eng, 4):
            H | qubit
    eng.flush(deallocate_qubits=True)
    assert len(backend.received_commands) == 4
    assert backend.received_commands[1].gate == H
    assert len(backend.received_commands[1].tags) == 2
    assert backend.received_commands[1].tags[0].num == 4
    assert backend.received_commands[1].tags[1].num == 3
    assert (backend.received_commands[1].tags[0].id !=
            backend.received_commands[1].tags[1].id)
Ejemplo n.º 6
0
def test_basic_engine_is_meta_tag_supported():
    eng = _basics.BasicEngine()
    # BasicEngine needs receive function to function so let's add it:

    def receive(self, cmd_list): self.send(cmd_list)

    eng.receive = types.MethodType(receive, eng)
    backend = DummyEngine()
    engine0 = DummyEngine()
    engine1 = DummyEngine()
    engine2 = DummyEngine()

    def allow_dirty_qubits(self, meta_tag):
        if meta_tag == DirtyQubitTag:
            return True
        return False

    engine2.is_meta_tag_handler = types.MethodType(allow_dirty_qubits,
                                                   engine2)
    main_engine = MainEngine(backend=backend,
                             engine_list=[engine0, engine1, engine2])
    assert not main_engine.is_meta_tag_supported("NotSupported")
    assert main_engine.is_meta_tag_supported(DirtyQubitTag)
Ejemplo n.º 7
0
def test_basic_engine_allocate_and_deallocate_qubit_and_qureg():
    eng = _basics.BasicEngine()
    # custom receive function which checks that main_engine does not send
    # any allocate or deallocate gates
    cmd_sent_by_main_engine = []

    def receive(self, cmd_list):
        cmd_sent_by_main_engine.append(cmd_list)

    eng.receive = types.MethodType(receive, eng)
    # Create test engines:
    saving_backend = DummyEngine(save_commands=True)
    main_engine = MainEngine(backend=saving_backend,
                             engine_list=[eng, DummyEngine()])
    # Allocate and deallocate qubits
    qubit = eng.allocate_qubit()
    # Try to allocate dirty qubit but it should give a non dirty qubit
    not_dirty_qubit = eng.allocate_qubit(dirty=True)

    # Allocate an actual dirty qubit
    def allow_dirty_qubits(self, meta_tag):
        if meta_tag == DirtyQubitTag:
            return True
        return False

    saving_backend.is_meta_tag_handler = types.MethodType(allow_dirty_qubits,
                                                          saving_backend)
    dirty_qubit = eng.allocate_qubit(dirty=True)
    qureg = eng.allocate_qureg(2)
    # Test qubit allocation
    assert isinstance(qubit, list)
    assert len(qubit) == 1 and isinstance(qubit[0], Qubit)
    assert qubit[0] in main_engine.active_qubits
    assert id(qubit[0].engine) == id(eng)
    # Test non dirty qubit allocation
    assert isinstance(not_dirty_qubit, list)
    assert len(not_dirty_qubit) == 1 and isinstance(not_dirty_qubit[0], Qubit)
    assert not_dirty_qubit[0] in main_engine.active_qubits
    assert id(not_dirty_qubit[0].engine) == id(eng)
    # Test dirty_qubit allocation
    assert isinstance(dirty_qubit, list)
    assert len(dirty_qubit) == 1 and isinstance(dirty_qubit[0], Qubit)
    assert dirty_qubit[0] in main_engine.active_qubits
    assert dirty_qubit[0].id in main_engine.dirty_qubits
    assert id(dirty_qubit[0].engine) == id(eng)
    # Test qureg allocation
    assert isinstance(qureg, list)
    assert len(qureg) == 2
    for tmp_qubit in qureg:
        assert tmp_qubit in main_engine.active_qubits
        assert id(tmp_qubit.engine) == id(eng)
    # Test uniqueness of ids
    assert len(set([qubit[0].id, not_dirty_qubit[0].id, dirty_qubit[0].id,
                    qureg[0].id, qureg[1].id])) == 5
    # Test allocate gates were sent
    assert len(cmd_sent_by_main_engine) == 0
    assert len(saving_backend.received_commands) == 5
    for cmd in saving_backend.received_commands:
        assert cmd.gate == AllocateQubitGate()
    assert saving_backend.received_commands[2].tags == [DirtyQubitTag()]
    # Test deallocate gates were sent
    eng.deallocate_qubit(qubit[0])
    eng.deallocate_qubit(not_dirty_qubit[0])
    eng.deallocate_qubit(dirty_qubit[0])
    eng.deallocate_qubit(qureg[0])
    eng.deallocate_qubit(qureg[1])
    assert len(cmd_sent_by_main_engine) == 0
    assert len(saving_backend.received_commands) == 10
    for cmd in saving_backend.received_commands[5:]:
        assert cmd.gate == DeallocateQubitGate()
    assert saving_backend.received_commands[7].tags == [DirtyQubitTag()]
Ejemplo n.º 8
0
def test_compute_uncompute_with_statement():
    # Allocating and deallocating qubit within Compute
    backend = DummyEngine(save_commands=True)
    compare_engine0 = CompareEngine()
    # Allow dirty qubits
    dummy_cengine = DummyEngine()

    def allow_dirty_qubits(self, meta_tag):
        return meta_tag == DirtyQubitTag

    dummy_cengine.is_meta_tag_handler = types.MethodType(
        allow_dirty_qubits, dummy_cengine)
    eng = MainEngine(backend=backend,
                     engine_list=[compare_engine0, dummy_cengine])
    qubit = eng.allocate_qubit()
    with _compute.Compute(eng):
        Rx(0.9) | qubit
        ancilla = eng.allocate_qubit(dirty=True)
        # ancilla2 will be deallocated in Uncompute section:
        ancilla2 = eng.allocate_qubit()
        # Test that ancilla is registered in MainEngine.active_qubits:
        assert ancilla[0] in eng.active_qubits
        H | qubit
        Rx(0.5) | ancilla
        CNOT | (ancilla, qubit)
        Rx(0.7) | qubit
        Rx(-0.5) | ancilla
        ancilla[0].__del__()
    H | qubit
    _compute.Uncompute(eng)
    eng.flush(deallocate_qubits=True)
    assert len(backend.received_commands) == 22
    # Test each Command has correct gate
    assert backend.received_commands[0].gate == Allocate
    assert backend.received_commands[1].gate == Rx(0.9)
    assert backend.received_commands[2].gate == Allocate
    assert backend.received_commands[3].gate == Allocate
    assert backend.received_commands[4].gate == H
    assert backend.received_commands[5].gate == Rx(0.5)
    assert backend.received_commands[6].gate == NOT
    assert backend.received_commands[7].gate == Rx(0.7)
    assert backend.received_commands[8].gate == Rx(-0.5)
    assert backend.received_commands[9].gate == Deallocate
    assert backend.received_commands[10].gate == H
    assert backend.received_commands[11].gate == Allocate
    assert backend.received_commands[12].gate == Rx(0.5)
    assert backend.received_commands[13].gate == Rx(-0.7)
    assert backend.received_commands[14].gate == NOT
    assert backend.received_commands[15].gate == Rx(-0.5)
    assert backend.received_commands[16].gate == H
    assert backend.received_commands[17].gate == Deallocate
    assert backend.received_commands[18].gate == Deallocate
    assert backend.received_commands[19].gate == Rx(-0.9)
    assert backend.received_commands[20].gate == Deallocate
    assert backend.received_commands[21].gate == FlushGate()
    # Test that each command has correct tags
    assert backend.received_commands[0].tags == []
    assert backend.received_commands[1].tags == [_compute.ComputeTag()]
    assert backend.received_commands[2].tags == [
        DirtyQubitTag(), _compute.ComputeTag()
    ]
    for cmd in backend.received_commands[3:9]:
        assert cmd.tags == [_compute.ComputeTag()]
    assert backend.received_commands[9].tags == [
        DirtyQubitTag(), _compute.ComputeTag()
    ]
    assert backend.received_commands[10].tags == []
    assert backend.received_commands[11].tags == [
        DirtyQubitTag(), _compute.UncomputeTag()
    ]
    for cmd in backend.received_commands[12:18]:
        assert cmd.tags == [_compute.UncomputeTag()]
    assert backend.received_commands[18].tags == [
        DirtyQubitTag(), _compute.UncomputeTag()
    ]
    assert backend.received_commands[19].tags == [_compute.UncomputeTag()]
    assert backend.received_commands[20].tags == []
    assert backend.received_commands[21].tags == []
    # Test that each command has correct qubits
    # Note that ancilla qubit in compute should be
    # different from ancilla qubit in uncompute section
    qubit_id = backend.received_commands[0].qubits[0][0].id
    ancilla_compt_id = backend.received_commands[2].qubits[0][0].id
    ancilla_uncompt_id = backend.received_commands[11].qubits[0][0].id
    ancilla2_id = backend.received_commands[3].qubits[0][0].id
    assert backend.received_commands[1].qubits[0][0].id == qubit_id
    assert backend.received_commands[4].qubits[0][0].id == qubit_id
    assert backend.received_commands[5].qubits[0][0].id == ancilla_compt_id
    assert backend.received_commands[6].qubits[0][0].id == qubit_id
    assert (
        backend.received_commands[6].control_qubits[0].id == ancilla_compt_id)
    assert backend.received_commands[7].qubits[0][0].id == qubit_id
    assert backend.received_commands[8].qubits[0][0].id == ancilla_compt_id
    assert backend.received_commands[9].qubits[0][0].id == ancilla_compt_id
    assert backend.received_commands[10].qubits[0][0].id == qubit_id
    assert backend.received_commands[12].qubits[0][0].id == ancilla_uncompt_id
    assert backend.received_commands[13].qubits[0][0].id == qubit_id
    assert backend.received_commands[14].qubits[0][0].id == qubit_id
    assert (backend.received_commands[14].control_qubits[0].id ==
            ancilla_uncompt_id)
    assert backend.received_commands[15].qubits[0][0].id == ancilla_uncompt_id
    assert backend.received_commands[16].qubits[0][0].id == qubit_id
    assert backend.received_commands[17].qubits[0][0].id == ancilla2_id
    assert backend.received_commands[18].qubits[0][0].id == ancilla_uncompt_id
    assert backend.received_commands[19].qubits[0][0].id == qubit_id
    assert backend.received_commands[20].qubits[0][0].id == qubit_id
    # Test that ancilla qubits should have seperate ids
    assert ancilla_uncompt_id != ancilla_compt_id

    # Do the same thing with CustomUncompute and compare using the
    # CompareEngine:
    backend1 = DummyEngine(save_commands=True)
    compare_engine1 = CompareEngine()
    # Allow dirty qubits
    dummy_cengine1 = DummyEngine()

    def allow_dirty_qubits(self, meta_tag):
        return meta_tag == DirtyQubitTag

    dummy_cengine1.is_meta_tag_handler = types.MethodType(
        allow_dirty_qubits, dummy_cengine1)
    eng1 = MainEngine(backend=backend1,
                      engine_list=[compare_engine1, dummy_cengine1])
    qubit = eng1.allocate_qubit()
    with _compute.Compute(eng1):
        Rx(0.9) | qubit
        ancilla = eng1.allocate_qubit(dirty=True)
        # ancilla2 will be deallocated in Uncompute section:
        ancilla2 = eng1.allocate_qubit()
        # Test that ancilla is registered in MainEngine.active_qubits:
        assert ancilla[0] in eng1.active_qubits
        H | qubit
        Rx(0.5) | ancilla
        CNOT | (ancilla, qubit)
        Rx(0.7) | qubit
        Rx(-0.5) | ancilla
        ancilla[0].__del__()
    H | qubit
    with _compute.CustomUncompute(eng1):
        ancilla = eng1.allocate_qubit(dirty=True)
        Rx(0.5) | ancilla
        Rx(-0.7) | qubit
        CNOT | (ancilla, qubit)
        Rx(-0.5) | ancilla
        H | qubit
        assert ancilla[0] in eng1.active_qubits
        ancilla2[0].__del__()
        ancilla[0].__del__()
        Rx(-0.9) | qubit
    eng1.flush(deallocate_qubits=True)
    assert compare_engine0 == compare_engine1
Ejemplo n.º 9
0
def test_loop_with_supported_loop_tag_and_local_qubits():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend, engine_list=[DummyEngine()])

    def allow_loop_tags(self, meta_tag):
        return meta_tag == _loop.LoopTag

    backend.is_meta_tag_handler = types.MethodType(allow_loop_tags, backend)
    qubit = eng.allocate_qubit()
    H | qubit
    with _loop.Loop(eng, 6):
        ancilla = eng.allocate_qubit()
        ancilla2 = eng.allocate_qubit()
        H | ancilla2
        H | ancilla
        CNOT | (ancilla, qubit)
        H | ancilla
        H | ancilla2
        del ancilla2
        del ancilla
    H | qubit
    eng.flush(deallocate_qubits=True)
    assert len(backend.received_commands) == 14
    assert backend.received_commands[0].gate == Allocate
    assert backend.received_commands[1].gate == H
    assert backend.received_commands[2].gate == Allocate
    assert backend.received_commands[3].gate == Allocate
    assert backend.received_commands[4].gate == H
    assert backend.received_commands[5].gate == H
    assert backend.received_commands[6].gate == X
    assert backend.received_commands[7].gate == H
    assert backend.received_commands[8].gate == H
    assert backend.received_commands[9].gate == Deallocate
    assert backend.received_commands[10].gate == Deallocate
    assert backend.received_commands[11].gate == H
    assert backend.received_commands[12].gate == Deallocate
    assert backend.received_commands[13].gate == FlushGate()
    # Test qubit ids
    qubit_id = backend.received_commands[0].qubits[0][0].id
    ancilla_id = backend.received_commands[2].qubits[0][0].id
    ancilla2_id = backend.received_commands[3].qubits[0][0].id
    assert qubit_id != ancilla_id
    assert qubit_id != ancilla2_id
    assert ancilla_id != ancilla2_id
    assert backend.received_commands[1].qubits[0][0].id == qubit_id
    assert backend.received_commands[4].qubits[0][0].id == ancilla2_id
    assert backend.received_commands[5].qubits[0][0].id == ancilla_id
    assert backend.received_commands[6].qubits[0][0].id == qubit_id
    assert backend.received_commands[6].control_qubits[0].id == ancilla_id
    assert backend.received_commands[7].qubits[0][0].id == ancilla_id
    assert backend.received_commands[8].qubits[0][0].id == ancilla2_id
    assert backend.received_commands[9].qubits[0][0].id == ancilla2_id
    assert backend.received_commands[10].qubits[0][0].id == ancilla_id
    assert backend.received_commands[11].qubits[0][0].id == qubit_id
    assert backend.received_commands[12].qubits[0][0].id == qubit_id
    # Tags
    assert len(backend.received_commands[3].tags) == 1
    loop_tag = backend.received_commands[3].tags[0]
    assert isinstance(loop_tag, _loop.LoopTag)
    assert loop_tag.num == 6
    for ii in [0, 1, 11, 12, 13]:
        assert backend.received_commands[ii].tags == []
    for ii in range(2, 9):
        assert backend.received_commands[ii].tags == [loop_tag]