示例#1
0
def test_pec_decorator_pyquil():
    """Performs the same test as test_mitigate_executor_pyquil(), but using
    pec_decorator() instead of mitigate_executor().
    """
    circuit = pyquil.Program(pyquil.gates.H(0))

    unmitigated = serial_executor(circuit)

    mitigated = decorated_serial_executor(circuit)

    assert np.isclose(unmitigated, mitigated)
def optimize_toffoli(a, b, c):
    program = pq.Program()
    program += pq.gates.H(c)
    program += pq.gates.T(c).dagger()
    program += pq.gates.CNOT(a, c)
    program += pq.gates.T(c)
    program += pq.gates.CNOT(b, c)
    program += pq.gates.T(c).dagger()
    program += pq.gates.CNOT(a, c)
    program += pq.gates.T(c)
    program += pq.gates.H(c)
    return program
示例#3
0
 def QFT(self, qubits):
     # NOTE: This method will reverse the order of the list of qubits,
     # rather than implementing a bunch of swaps at the end
     # Handle with care!
     program = pq.Program()
     for i, tq in enumerate(qubits):
         program += pq.gates.H(tq)
         for j, cq in list(enumerate(qubits))[i + 1:]:
             program += pq.gates.RZ(2**(-(j - i)) * np.pi,
                                    tq).controlled(cq)
             program += pq.gates.RZ(2**(-(j - i + 1)) * np.pi, cq)
     return program
示例#4
0
    def __init__(self, path: list, test_type: BellTestType, add_measurements, num_shots):
        super().__init__()

        assert len(path) >= 2, "qubit path has to have length at least 2"

        qubit_a = path[0]
        qubit_b = path[-1]

        self.qubit_a = qubit_a
        self.qubit_b = qubit_b
        self.path = path
        self.test_type = test_type
        self.add_measurements = add_measurements
        self.num_shots = num_shots

        # Build the circuit
        program = pq.Program()
        program += Pragma("INITIAL_REWIRING", ['"NAIVE"'])

        program += pq.gates.X(qubit_a)
        program += pq.gates.X(qubit_b)
        program += pq.gates.H(qubit_a)

        # CNOT along path
        for (x, y) in zip(path[:-2], path[1:-1]):
            program += pq.gates.CNOT(x, y)

        # CNOT the last pair
        program += pq.gates.CNOT(path[-2], qubit_b)

        # undo CNOT along path
        for (x, y) in reversed(list(zip(path[:-2], path[1:-1]))):
            program += pq.gates.CNOT(x, y)

        # measurement directions
        angle_a, angle_b = test_type.value
        if angle_a != 0:
            program += pq.gates.RZ(angle_a, qubit_a)
        if angle_b != 0:
            program += pq.gates.RZ(angle_b, qubit_b)

        # final hadamards
        program += pq.gates.H(qubit_a)
        program += pq.gates.H(qubit_b)

        # store the resulting circuit
        self.program = program
示例#5
0
    def test_convert_simple_program_with_parameters_mixed_keys(self):
        """Test that a parametrized program is properly converted when
        the variable map contains mixed key types."""
        program = pyquil.Program()

        alpha = program.declare("alpha", "REAL")
        beta = program.declare("beta", "REAL")
        gamma = program.declare("gamma", "REAL")
        delta = program.declare("delta", "REAL")

        program += g.H(0)
        program += g.CNOT(0, 1)
        program += g.RX(alpha, 1)
        program += g.RZ(beta, 1)
        program += g.RX(gamma, 1)
        program += g.CNOT(0, 1)
        program += g.RZ(delta, 0)
        program += g.H(0)

        a, b, c, d = 0.1, 0.2, 0.3, 0.4

        parameter_map = {
            "alpha": a,
            beta: b,
            gamma: c,
            "delta": d,
        }

        with OperationRecorder() as rec:
            load_program(program)(wires=range(2), parameter_map=parameter_map)

        expected_queue = [
            qml.Hadamard(0),
            qml.CNOT(wires=[0, 1]),
            qml.RX(0.1, wires=[1]),
            qml.RZ(0.2, wires=[1]),
            qml.RX(0.3, wires=[1]),
            qml.CNOT(wires=[0, 1]),
            qml.RZ(0.4, wires=[0]),
            qml.Hadamard(0),
        ]

        for converted, expected in zip(rec.queue, expected_queue):
            assert converted.name == expected.name
            assert converted.wires == expected.wires
            assert converted.params == expected.params
示例#6
0
def test_mitigate_executor_pyquil():
    """Performs the same test as
    test_execute_with_pec_pyquil_trivial_decomposition(), but using
    mitigate_executor() instead of execute_with_pec().
    """
    circuit = pyquil.Program(pyquil.gates.H(0))
    rep = OperationRepresentation(
        circuit, basis_expansion={NoisyOperation(circuit): 1.0}
    )
    unmitigated = serial_executor(circuit)

    mitigated_executor = mitigate_executor(
        serial_executor, representations=[rep], num_samples=10, random_state=1,
    )
    mitigated = mitigated_executor(circuit)

    assert np.isclose(unmitigated, mitigated)
示例#7
0
    def _run_and_measure(
        self,
        program: pq.Program,
        num_shots: int,
        measure_qubits: list,
        optimize,
        active_reset=False,
    ):
        program = program.copy()
        qubits = measure_qubits if measure_qubits is not None else program.get_qubits(
        )

        # actively reset qubits at start
        if active_reset:
            program = pq.Program(pq.gates.RESET()) + program

        # add measurements everywhere
        ro = program.declare("ro", "BIT", len(qubits))
        for i, q in enumerate(qubits):
            program.inst(pq.gates.MEASURE(q, ro[i]))

        program.wrap_in_numshots_loop(shots=num_shots)

        try:
            executable = self.device.compile(program, optimize=optimize)
            bitstring_array = self.device.run(executable=executable)
        except Exception as e:
            print_stderr(e)  # we want to log, but not interrupt
            return {
                "result": ThinPromise(lambda: None),
                "transpiled_circuit": None
            }

        print_hl(program, color="grey")
        print_hl(executable.program, color="grey")

        bitstring_dict = {}
        for i, q in enumerate(qubits):
            bitstring_dict[q] = bitstring_array[:, i]

        return {
            "result": ThinPromise(lambda: bitstring_dict),
            "transpiled_circuit": executable.asdict(),
        }
def load_quil(quil_str: str):
    """Load a quil string as a PennyLane template.

    During loading, gates are converted to PennyLane gates as far as possible. If
    the gates are not supported they are replaced with QubitUnitary instances. The
    import ignores all statements that are not declarations or gates (e.g. pragmas,
    classical control flow and measurements).

    Every variable that is present in the Program and that is not used as the target
    register of a measurement has to be provided in the ``parameter_map`` of the template. 
    
    Args:
        quil_str (str): The program that should be loaded
    
    Returns:
        ProgramLoader: a ProgramLoader instance that can be called like a template
    """

    return load_program(pyquil.Program(quil_str))