Example #1
0
def test_idempotent_del():
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=rec, engine_list=[])
    q = eng.allocate_qubit()[0]
    rec.received_commands = []
    assert len(rec.received_commands) == 0
    q.__del__()
    assert len(rec.received_commands) == 1
    q.__del__()
    assert len(rec.received_commands) == 1
def check_phase_circuit(register_sizes,
                        expected_turns,
                        engine_list,
                        actions):
    """
    Args:
        register_sizes (list[int]):
        expected_turns (function(register_sizes: tuple[int],
                                 register_vals: tuple[int])):
        engine_list (list[projectq.cengines.BasicEngine]):
        actions (function(eng: MainEngine, registers: list[Qureg])):
    """

    sim = Simulator()
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=sim, engine_list=list(engine_list) + [rec])
    registers = [eng.allocate_qureg(size) for size in register_sizes]

    # Simulate all.
    for reg in registers:
        for q in reg:
            H | q
    rec.received_commands = []
    actions(eng, registers)

    state = np.array(sim.cheat()[1])
    magnitude_factor = math.sqrt(len(state))
    actions = list(rec.received_commands)
    for reg in registers:
        for q in reg:
            Measure | q

    # Compare.
    for i in range(len(state)):
        vals = []
        t = 0
        for r in register_sizes:
            vals.append((i >> t) & ((1 << r) - 1))
            t += r
        vals = tuple(vals)

        actual_factor = state[i]
        expected_turn = expected_turns(register_sizes, vals)
        actual_turn = cmath.phase(state[i]) / (2 * math.pi)
        delta_turn = abs((actual_turn - expected_turn + 0.5) % 1 - 0.5)
        if not (delta_turn < 0.00001):
            print(commands_to_ascii_circuit(actions))
            print("Register Sizes", register_sizes)
            print("Conflicting state: {}".format(vals))
            print("Expected phase: {} deg".format(float(expected_turn)*360))
            print("Actual phase: {} deg".format(actual_turn*360))
        assert abs(abs(actual_factor * magnitude_factor) - 1) < 0.00001
        assert delta_turn < 0.00001
def fuzz_permutation_circuit(register_sizes,
                             permutation,
                             actions,
                             engine_list=(),
                             register_limits=None):
    """
    Args:
        register_sizes (list[int]):
        permutation (function(register_vals: tuple[int],
                                        register_sizes: tuple[int])
                                        : tuple[int]):
        actions (function(eng: MainEngine, registers: list[Qureg])):
        engine_list (list[projectq.cengines.BasicEngine]):
        register_limits (list[int]):
    """

    n = len(register_sizes)
    if register_limits is None:
        register_limits = [1 << size for size in register_sizes]
    assert len(register_limits) == n
    inputs = tuple(random.randint(0, limit - 1) for limit in register_limits)
    outputs = [e % (1 << d)
               for e, d in zip(permutation(register_sizes, inputs),
                               register_sizes)]

    sim = ClassicalSimulator()
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=sim, engine_list=list(engine_list) + [rec])
    registers = tuple(eng.allocate_qureg(size) for size in register_sizes)

    # Encode inputs.
    for i in range(n):
        for b in range(register_sizes[i]):
            if inputs[i] & (1 << b):
                X | registers[i][b]

    # Simulate.
    rec.received_commands = []
    actions(eng, registers)

    # Compare outputs.
    actual_outputs = [sim.read_register(registers[i]) for i in range(n)]
    if outputs != actual_outputs:
        print(commands_to_ascii_circuit(rec.received_commands))
        print("Register Sizes", register_sizes)
        print("Register Limits", register_limits)
        print("Inputs", inputs)
        print("Expected Outputs", outputs)
        print("Actual Outputs", actual_outputs)
    assert outputs == actual_outputs
def check_quantum_permutation_circuit(register_size,
                                      permutation_func,
                                      actions,
                                      engine_list=()):
    """
    Args:
        register_size (int):
        permutation_func (function(register_sizes: tuple[int],
                                   register_vals: tuple[int]) : tuple[int]):
        actions (function(eng: MainEngine, registers: list[Qureg])):
        engine_list (list[projectq.cengines.BasicEngine]):
    """
    sim = Simulator()
    rec = DummyEngine(save_commands=True)
    eng = MainEngine(backend=sim, engine_list=list(engine_list) + [rec])

    reg = eng.allocate_qureg(register_size)

    All(H) | reg
    for i in range(len(reg)):
        Rz(math.pi / 2**i) | reg[i]
    pre_state = np.array(sim.cheat()[1])

    # Simulate.
    rec.received_commands = []
    actions(eng, [reg])
    actions = list(rec.received_commands)

    post_state = np.array(sim.cheat()[1])
    for q in reg:
        Measure | q

    denom = math.sqrt(len(pre_state))
    pre_state *= denom
    post_state *= denom
    for i in range(len(pre_state)):
        j = permutation_func([register_size], [i]) & ((1 << len(reg)) - 1)
        if not (abs(post_state[j] - pre_state[i]) < 0.000000001):
            print(commands_to_ascii_circuit(actions))
            print("Input", i)
            print("Expected Output", j)
            print("Input Amp at " + str(i), pre_state[i])
            print("Actual Amp at " + str(j), post_state[j])
        assert abs(post_state[j] - pre_state[i]) < 0.000000001
def test_ibm5qubitmapper_optimizeifpossible():
    backend = DummyEngine(save_commands=True)
    connectivity = {(2, 1), (4, 2), (2, 0), (3, 2), (3, 4), (1, 0)}
    eng = MainEngine(
        backend=backend,
        engine_list=[
            _ibm5qubitmapper.IBM5QubitMapper(connections=connectivity),
            SwapAndCNOTFlipper(connectivity),
        ],
    )
    qb0 = eng.allocate_qubit()  # noqa: F841
    qb1 = eng.allocate_qubit()
    qb2 = eng.allocate_qubit()
    qb3 = eng.allocate_qubit()  # noqa: F841
    CNOT | (qb1, qb2)
    CNOT | (qb2, qb1)
    CNOT | (qb1, qb2)

    eng.flush()

    hadamard_count = 0
    for cmd in backend.received_commands:
        if cmd.gate == H:
            hadamard_count += 1

    assert hadamard_count == 4
    backend.received_commands = []

    CNOT | (qb2, qb1)
    CNOT | (qb1, qb2)
    CNOT | (qb2, qb1)

    eng.flush()

    hadamard_count = 0
    for cmd in backend.received_commands:
        if cmd.gate == H:
            hadamard_count += 1

    assert hadamard_count == 4
Example #6
0
def test_ibmcnotmapper_optimizeifpossible():
    backend = DummyEngine(save_commands=True)
    eng = MainEngine(backend=backend,
                     engine_list=[_ibmcnotmapper.IBMCNOTMapper()])
    qb0 = eng.allocate_qubit()
    qb1 = eng.allocate_qubit()
    qb2 = eng.allocate_qubit()
    qb3 = eng.allocate_qubit()
    CNOT | (qb1, qb2)
    CNOT | (qb2, qb1)
    CNOT | (qb1, qb2)

    eng.flush()

    hadamard_count = 0
    for cmd in backend.received_commands:
        if cmd.gate == H:
            hadamard_count += 1
        if cmd.gate == X:
            assert cmd.qubits[0][0].id == qb2[0].id

    assert hadamard_count == 4
    backend.received_commands = []

    CNOT | (qb2, qb1)
    CNOT | (qb1, qb2)
    CNOT | (qb2, qb1)

    eng.flush()

    hadamard_count = 0
    for cmd in backend.received_commands:
        if cmd.gate == H:
            hadamard_count += 1
        if cmd.gate == X:
            assert cmd.qubits[0][0].id == qb1[0].id

    assert hadamard_count == 4
    def _recursive_decompose(self, cmd):
        if self.is_available(cmd):
            return [cmd]

        canonical_cmd, id_map, key, used, avail = self._canonicalize(cmd)
        if key in self._cached_results:
            if self._cached_results == 'IN PROGRESS':
                raise NoGateDecompositionError(
                    'Cyclic decomposition for {}.'.format(cmd))
            return self._translate(cmd, self._cached_results[key], id_map)
        self._cached_results[key] = 'IN PROGRESS'

        rec = DummyEngine(save_commands=True)
        eng = MainEngine(backend=rec,
                         engine_list=[
                             LocalOptimizer(),
                             SimpleAdjacentCombiner(self.merge_rules),
                         ])
        involved = eng.allocate_qureg(used)
        workspace = eng.allocate_qureg(avail)
        eng.flush()
        rec.received_commands = []
        canonical_cmd.engine = eng

        self._pick_decomp_for(cmd).decompose(canonical_cmd)
        eng.flush()
        intermediate_result = rec.received_commands[:-1]

        assert involved is not None
        assert workspace is not None

        flattened_result = [
            leaf for child in intermediate_result
            for leaf in self._recursive_decompose(child)
        ]

        self._cached_results[key] = flattened_result
        return self._translate(cmd, flattened_result, id_map)