示例#1
0
def test_wrong_init_mapped_ids_to_backend_ids():
    with pytest.raises(RuntimeError):
        test = {0: 1, 1: 0, 2: 2, 3: 3, 4: 4}
        two_d.GridMapper(num_rows=2, num_columns=3, mapped_ids_to_backend_ids=test)
    with pytest.raises(RuntimeError):
        test = {0: 1, 1: 0, 2: 2, 3: 3, 4: 4, 5: 2}
        two_d.GridMapper(num_rows=2, num_columns=3, mapped_ids_to_backend_ids=test)
示例#2
0
def test_send_possible_commands_deallocate(different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 4, 4: 5, 5: 6}
    else:
        map_to_backend_ids = None
    mapper = two_d.GridMapper(num_rows=3, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    cmd0 = Command(engine=None, gate=Deallocate, qubits=([qb0],), controls=[], tags=[])
    mapper._stored_commands = [cmd0]
    mapper.current_mapping = {}
    mapper._currently_allocated_ids = {10}
    # not yet allocated:
    mapper._send_possible_commands()
    assert len(backend.received_commands) == 0
    assert mapper._stored_commands == [cmd0]
    # allocated:
    mapper.current_mapping = {0: 3}
    mapper._currently_allocated_ids.add(0)
    mapper._send_possible_commands()
    assert len(backend.received_commands) == 1
    assert len(mapper._stored_commands) == 0
    assert mapper.current_mapping == {}
    assert mapper._currently_allocated_ids == {10}
示例#3
0
def test_send_possible_commands_allocate(different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 4, 4: 5, 5: 6}
    else:
        map_to_backend_ids = None
    mapper = two_d.GridMapper(num_rows=3, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],), controls=[], tags=[])
    mapper._stored_commands = [cmd0]
    mapper._currently_allocated_ids = {10}
    # not in mapping:
    mapper.current_mapping = {}
    assert len(backend.received_commands) == 0
    mapper._send_possible_commands()
    assert len(backend.received_commands) == 0
    assert mapper._stored_commands == [cmd0]
    # in mapping:
    mapper.current_mapping = {0: 3}
    mapper._send_possible_commands()
    assert len(mapper._stored_commands) == 0
    # Only self._run() sends Allocate gates
    mapped0 = WeakQubitRef(engine=None, idx=3)
    received_cmd = Command(
        engine=mapper,
        gate=Allocate,
        qubits=([mapped0],),
        controls=[],
        tags=[LogicalQubitIDTag(0)],
    )
    assert backend.received_commands[0] == received_cmd
    assert mapper._currently_allocated_ids == {10, 0}
示例#4
0
def test_is_available():
    mapper = two_d.GridMapper(num_rows=2, num_columns=2)
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb2 = WeakQubitRef(engine=None, idx=2)
    cmd0 = Command(None, BasicGate(), qubits=([qb0],))
    assert mapper.is_available(cmd0)
    cmd1 = Command(None, BasicGate(), qubits=([qb0],), controls=[qb1])
    assert mapper.is_available(cmd1)
    cmd2 = Command(None, BasicGate(), qubits=([qb0], [qb1, qb2]))
    assert not mapper.is_available(cmd2)
    cmd3 = Command(None, BasicGate(), qubits=([qb0], [qb1]), controls=[qb2])
    assert not mapper.is_available(cmd3)
def test_send_possible_cmds_before_new_mapping():
    mapper = two_d.GridMapper(num_rows=3, num_columns=1)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend

    def dont_call_mapping(): raise Exception

    mapper._return_new_mapping = dont_call_mapping
    mapper.current_mapping = {0: 1}
    qb0 = WeakQubitRef(engine=None, idx=0)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    qb2 = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb2],))
    mapper.receive([cmd0, cmd_flush])
示例#6
0
def test_send_possible_commands_one_inactive_qubit(different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 0, 4: 5, 5: 6}
    else:
        map_to_backend_ids = None
    mapper = two_d.GridMapper(num_rows=3, num_columns=2, mapped_ids_to_backend_ids=map_to_backend_ids)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],), controls=[], tags=[])
    cmd1 = Command(engine=None, gate=X, qubits=([qb0],), controls=[qb1])
    mapper._stored_commands = [cmd0, cmd1]
    mapper.current_mapping = {0: 0}
    mapper._send_possible_commands()
    assert mapper._stored_commands == [cmd1]
def test_return_swaps_random(num_rows, num_columns, seed, none_old, none_new):
    random.seed(seed)
    num_qubits = num_rows * num_columns
    old_chain = random.sample(range(num_qubits), num_qubits)
    new_chain = random.sample(range(num_qubits), num_qubits)
    old_mapping = dict()
    new_mapping = dict()
    for i in range(num_qubits):
        old_mapping[old_chain[i]] = i
        new_mapping[new_chain[i]] = i
    # Remove certain elements from mappings:
    old_none_ids = set(random.sample(range(num_qubits), none_old))
    if none_old != 0:
        for logical_id in old_none_ids:
            old_mapping.pop(logical_id)
    new_none_ids = set(random.sample(range(num_qubits), none_new))
    if none_new != 0:
        for logical_id in new_none_ids:
            new_mapping.pop(logical_id)

    mapper = two_d.GridMapper(num_rows=num_rows,
                              num_columns=num_columns)
    swaps = mapper.return_swaps(old_mapping, new_mapping)
    # Check that Swaps are allowed
    all_allowed_swaps = set()
    for row in range(num_rows):
        for column in range(num_columns-1):
            qb_id = row * num_columns + column
            all_allowed_swaps.add((qb_id, qb_id + 1))
    for row in range(num_rows-1):
        for column in range(num_columns):
            qb_id = row * num_columns + column
            all_allowed_swaps.add((qb_id, qb_id + num_columns))

    for swap in swaps:
        assert swap in all_allowed_swaps
    test_chain = deepcopy(old_chain)
    for pos0, pos1 in swaps:
        tmp = test_chain[pos0]
        test_chain[pos0] = test_chain[pos1]
        test_chain[pos1] = tmp
    assert len(test_chain) == len(new_chain)
    for i in range(len(new_chain)):
        if new_chain[i] in old_mapping and new_chain[i] in new_mapping:
            assert test_chain[i] == new_chain[i]
示例#8
0
def test_send_possible_commands(different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 1, 3: 4, 4: 5, 5: 6, 6: 10, 7: 7}
    else:
        map_to_backend_ids = None
    mapper = two_d.GridMapper(num_rows=2, num_columns=4, mapped_ids_to_backend_ids=map_to_backend_ids)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    # mapping is identical except 5 <-> 0
    if different_backend_ids:
        mapper.current_mapping = {0: 6, 1: 32, 2: 1, 3: 4, 4: 5, 5: 21, 6: 10, 7: 7}
    else:
        mapper.current_mapping = {5: 0, 1: 1, 2: 2, 3: 3, 4: 4, 0: 5, 6: 6, 7: 7}
    neighbours = [
        (5, 1),
        (1, 2),
        (2, 3),
        (4, 0),
        (0, 6),
        (6, 7),
        (5, 4),
        (1, 0),
        (2, 6),
        (3, 7),
    ]
    for qb0_id, qb1_id in neighbours:
        qb0 = WeakQubitRef(engine=None, idx=qb0_id)
        qb1 = WeakQubitRef(engine=None, idx=qb1_id)
        cmd1 = Command(None, X, qubits=([qb0],), controls=[qb1])
        cmd2 = Command(None, X, qubits=([qb1],), controls=[qb0])
        mapper._stored_commands = [cmd1, cmd2]
        mapper._send_possible_commands()
        assert len(mapper._stored_commands) == 0
    for qb0_id, qb1_id in itertools.permutations(range(8), 2):
        if (qb0_id, qb1_id) not in neighbours and (qb1_id, qb0_id) not in neighbours:
            qb0 = WeakQubitRef(engine=None, idx=qb0_id)
            qb1 = WeakQubitRef(engine=None, idx=qb1_id)
            cmd = Command(None, X, qubits=([qb0],), controls=[qb1])
            mapper._stored_commands = [cmd]
            mapper._send_possible_commands()
            assert len(mapper._stored_commands) == 1
示例#9
0
def test_run_infinite_loop_detection():
    mapper = two_d.GridMapper(num_rows=2, num_columns=2)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb2 = WeakQubitRef(engine=None, idx=2)
    qb3 = WeakQubitRef(engine=None, idx=3)
    qb4 = WeakQubitRef(engine=None, idx=4)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],))
    cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],))
    cmd3 = Command(engine=None, gate=Allocate, qubits=([qb3],))
    cmd4 = Command(engine=None, gate=Allocate, qubits=([qb4],))
    cmd5 = Command(None, X, qubits=([qb0],), controls=[qb1])
    qb2 = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb2],))
    with pytest.raises(RuntimeError):
        mapper.receive([cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd_flush])
def test_return_new_mapping(different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 1, 3: 4, 4: 5, 5: 6, 6: 10,
                              7: 7, 8: 0, 9: 56, 10: 55, 11: 9}
    else:
        map_to_backend_ids = None
    mapper = two_d.GridMapper(num_rows=4, num_columns=3,
                              mapped_ids_to_backend_ids=map_to_backend_ids)
    eng = projectq.MainEngine(DummyEngine(), [mapper])
    linear_chain_ids = [33, 22, 11, 2, 3, 0, 6, 7, 9, 12, 4, 88]
    mapper._stored_commands = []
    for i in range(12):
        qb = WeakQubitRef(engine=None, idx=linear_chain_ids[i])
        cmd = Command(None, Allocate, ([qb],))
        mapper._stored_commands.append(cmd)
    for i in range(11):
        qb0 = WeakQubitRef(engine=None, idx=linear_chain_ids[i])
        qb1 = WeakQubitRef(engine=None, idx=linear_chain_ids[i+1])
        cmd = Command(None, X, qubits=([qb0],), controls=[qb1])
        mapper._stored_commands.append(cmd)
    new_mapping = mapper._return_new_mapping()
    possible_solution_1 = {33: 0, 22: 1, 11: 2, 2: 5, 3: 4, 0: 3, 6: 6, 7: 7,
                           9: 8, 12: 11, 4: 10, 88: 9}
    possible_solution_2 = {88: 0, 4: 1, 12: 2, 9: 5, 7: 4, 6: 3, 0: 6, 3: 7,
                           2: 8, 11: 11, 22: 10, 33: 9}
    assert (new_mapping == possible_solution_1 or
            new_mapping == possible_solution_2)
    eng.flush()
    if different_backend_ids:
        transformed_sol1 = dict()
        for logical_id, mapped_id in possible_solution_1.items():
            transformed_sol1[logical_id] = map_to_backend_ids[mapped_id]
        transformed_sol2 = dict()
        for logical_id, mapped_id in possible_solution_2.items():
            transformed_sol2[logical_id] = map_to_backend_ids[mapped_id]
        assert (mapper.current_mapping == transformed_sol1 or
                mapper.current_mapping == transformed_sol2)
    else:
        assert (mapper.current_mapping == possible_solution_1 or
                mapper.current_mapping == possible_solution_2)
示例#11
0
def test_correct_stats():
    # Should test stats for twice same mapping but depends on heuristic
    mapper = two_d.GridMapper(num_rows=3, num_columns=1)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb2 = WeakQubitRef(engine=None, idx=2)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],))
    cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],))
    cmd3 = Command(None, X, qubits=([qb0],), controls=[qb1])
    cmd4 = Command(None, X, qubits=([qb1],), controls=[qb2])
    cmd5 = Command(None, X, qubits=([qb0],), controls=[qb2])
    cmd6 = Command(None, X, qubits=([qb2],), controls=[qb1])
    cmd7 = Command(None, X, qubits=([qb0],), controls=[qb1])
    cmd8 = Command(None, X, qubits=([qb1],), controls=[qb2])
    qb_flush = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],))
    mapper.receive([cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8, cmd_flush])
    assert mapper.num_mappings == 2
示例#12
0
def test_check_that_local_optimizer_doesnt_merge():
    mapper = two_d.GridMapper(num_rows=2, num_columns=2)
    optimizer = LocalOptimizer(10)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = optimizer
    optimizer.next_engine = backend
    mapper.current_mapping = {0: 0}
    mapper.storage = 1
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb_flush = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],))
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    cmd1 = Command(None, X, qubits=([qb0],))
    cmd2 = Command(engine=None, gate=Deallocate, qubits=([qb0],))
    mapper.receive([cmd0, cmd1, cmd2])
    assert len(mapper._stored_commands) == 0
    mapper.current_mapping = {1: 0}
    cmd3 = Command(engine=None, gate=Allocate, qubits=([qb1],))
    cmd4 = Command(None, X, qubits=([qb1],))
    cmd5 = Command(engine=None, gate=Deallocate, qubits=([qb1],))
    mapper.receive([cmd3, cmd4, cmd5, cmd_flush])
    assert len(backend.received_commands) == 7
示例#13
0
def test_logical_id_tags_allocate_and_deallocate():
    mapper = two_d.GridMapper(num_rows=2, num_columns=2)
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],))
    cmd2 = Command(None, X, qubits=([qb0],), controls=[qb1])
    cmd3 = Command(engine=None, gate=Deallocate, qubits=([qb0],))
    cmd4 = Command(engine=None, gate=Deallocate, qubits=([qb1],))
    mapper.current_mapping = {0: 0, 1: 3}
    qb_flush = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb_flush],))
    mapper.receive([cmd0, cmd1, cmd2, cmd_flush])
    assert backend.received_commands[0].gate == Allocate
    assert backend.received_commands[0].qubits[0][0].id == 0
    assert backend.received_commands[0].tags == [LogicalQubitIDTag(0)]
    assert backend.received_commands[1].gate == Allocate
    assert backend.received_commands[1].qubits[0][0].id == 3
    assert backend.received_commands[1].tags == [LogicalQubitIDTag(1)]
    for cmd in backend.received_commands[2:]:
        if cmd.gate == Allocate:
            assert cmd.tags == []
        elif cmd.gate == Deallocate:
            assert cmd.tags == []
    mapped_id_for_0 = mapper.current_mapping[0]
    mapped_id_for_1 = mapper.current_mapping[1]
    mapper.receive([cmd3, cmd4, cmd_flush])
    assert backend.received_commands[-3].gate == Deallocate
    assert backend.received_commands[-3].qubits[0][0].id == mapped_id_for_0
    assert backend.received_commands[-3].tags == [LogicalQubitIDTag(0)]
    assert backend.received_commands[-2].gate == Deallocate
    assert backend.received_commands[-2].qubits[0][0].id == mapped_id_for_1
    assert backend.received_commands[-2].tags == [LogicalQubitIDTag(1)]
示例#14
0
def test_resetting_mapping_to_none():
    mapper = two_d.GridMapper(num_rows=2, num_columns=3)
    mapper.current_mapping = {0: 1}
    assert mapper._current_row_major_mapping == {0: 1}
    mapper.current_mapping = None
    assert mapper._current_row_major_mapping is None
示例#15
0
def test_run_and_receive(num_optimization_steps, different_backend_ids):
    if different_backend_ids:
        map_to_backend_ids = {0: 21, 1: 32, 2: 3, 3: 0}
    else:
        map_to_backend_ids = None

    def choose_last_permutation(swaps):
        choose_last_permutation.counter -= 1
        return choose_last_permutation.counter

    choose_last_permutation.counter = 100
    mapper = two_d.GridMapper(
        num_rows=2,
        num_columns=2,
        mapped_ids_to_backend_ids=map_to_backend_ids,
        optimization_function=choose_last_permutation,
        num_optimization_steps=num_optimization_steps,
    )
    backend = DummyEngine(save_commands=True)
    backend.is_last_engine = True
    mapper.next_engine = backend
    qb0 = WeakQubitRef(engine=None, idx=0)
    qb1 = WeakQubitRef(engine=None, idx=1)
    qb2 = WeakQubitRef(engine=None, idx=2)
    qb3 = WeakQubitRef(engine=None, idx=3)
    cmd0 = Command(engine=None, gate=Allocate, qubits=([qb0],))
    cmd1 = Command(engine=None, gate=Allocate, qubits=([qb1],))
    cmd2 = Command(engine=None, gate=Allocate, qubits=([qb2],))
    cmd3 = Command(engine=None, gate=Allocate, qubits=([qb3],))
    cmd4 = Command(None, X, qubits=([qb0],), controls=[qb1])
    cmd5 = Command(None, X, qubits=([qb1],), controls=[qb3])
    cmd6 = Command(None, X, qubits=([qb3],), controls=[qb2])
    cmd7 = Command(None, X, qubits=([qb0],), controls=[qb2])
    cmd8 = Command(engine=None, gate=Deallocate, qubits=([qb1],))
    all_cmd = [cmd0, cmd1, cmd2, cmd3, cmd4, cmd5, cmd6, cmd7, cmd8]
    mapper.receive(all_cmd)
    assert mapper._stored_commands == all_cmd
    qb4 = WeakQubitRef(engine=None, idx=-1)
    cmd_flush = Command(engine=None, gate=FlushGate(), qubits=([qb4],))
    mapper.receive([cmd_flush])
    assert mapper._stored_commands == []
    assert len(backend.received_commands) == 10
    assert mapper._currently_allocated_ids == {0, 2, 3}
    if different_backend_ids:
        assert (
            mapper.current_mapping == {0: 21, 2: 3, 3: 0}
            or mapper.current_mapping == {0: 32, 2: 0, 3: 21}
            or mapper.current_mapping == {0: 3, 2: 21, 3: 32}
            or mapper.current_mapping == {0: 0, 2: 32, 3: 3}
        )
    else:
        assert (
            mapper.current_mapping == {0: 0, 2: 2, 3: 3}
            or mapper.current_mapping == {0: 1, 2: 3, 3: 0}
            or mapper.current_mapping == {0: 2, 2: 0, 3: 1}
            or mapper.current_mapping == {0: 3, 2: 1, 3: 2}
        )
    cmd9 = Command(None, X, qubits=([qb0],), controls=[qb3])
    mapper.storage = 1
    mapper.receive([cmd9])
    assert mapper._currently_allocated_ids == {0, 2, 3}
    assert mapper._stored_commands == []
    assert len(mapper.current_mapping) == 3
    assert 0 in mapper.current_mapping
    assert 2 in mapper.current_mapping
    assert 3 in mapper.current_mapping
    assert mapper.num_mappings == 1