Example #1
0
    def load(self, executable):
        """
        Initialize a QAM and load a program to be executed with a call to :py:func:`run`.

        If ``QVM.requires_executable`` is set to ``True``, this function will only load
        :py:class:`PyQuilExecutableResponse` executables. This more closely follows the behavior
        of :py:class:`QPU`. However, the quantum simulator doesn't *actually* need a compiled
        binary executable, so if this flag is set to ``False`` we also accept :py:class:`Program`
        objects.

        :param executable: An executable. See the above note for acceptable types.
        """
        if self.requires_executable:
            if isinstance(executable, PyQuilExecutableResponse):
                executable = _extract_program_from_pyquil_executable_response(executable)
            else:
                raise TypeError("`executable` argument must be a `PyQuilExecutableResponse`. Make "
                                "sure you have explicitly compiled your program via `qc.compile` "
                                "or `qc.compiler.native_quil_to_executable(...)` for more "
                                "fine-grained control. This explicit step is required for running "
                                "on a QPU.")
        else:
            if isinstance(executable, PyQuilExecutableResponse):
                executable = _extract_program_from_pyquil_executable_response(executable)
            elif isinstance(executable, Program):
                pass
            else:
                raise TypeError("`executable` argument must be a `PyQuilExecutableResponse` or a "
                                "`Program`. You provided {}".format(type(executable)))

        return super().load(executable)
Example #2
0
    def run(self):
        """
        Run a Quil program on the QVM multiple times and return the values stored in the
        classical registers designated by the classical_addresses parameter.

        :return: An array of bitstrings of shape ``(trials, len(classical_addresses))``
        """

        super().run()

        if isinstance(self._executable, PyQuilExecutableResponse):
            quil_program = _extract_program_from_pyquil_executable_response(self._executable)
        elif isinstance(self._executable, Program):
            quil_program = self._executable
        else:
            raise TypeError("quil_binary argument must be a PyQuilExecutableResponse or a Program."
                            "This error is typically triggered by forgetting to pass (nativized)"
                            "Quil to native_quil_to_executable or by using a compiler meant to be"
                            "used for jobs bound for a QPU.")

        trials = quil_program.num_shots
        classical_addresses = get_classical_addresses_from_program(quil_program)

        if self.noise_model is not None:
            quil_program = apply_noise_model(quil_program, self.noise_model)

        quil_program = self.augment_program_with_memory_values(quil_program)
        self._bitstrings = self.connection._qvm_run(quil_program=quil_program,
                                                    classical_addresses=classical_addresses,
                                                    trials=trials,
                                                    measurement_noise=self.measurement_noise,
                                                    gate_noise=self.gate_noise,
                                                    random_seed=self.random_seed)['ro']

        return self
Example #3
0
def test_roundtrip_pyquilexecutableresponse():
    p = Program(H(10), CNOT(10, 11))
    lcqvm = LocalQVMCompiler(endpoint=None, device=NxDevice(nx.complete_graph(3)))
    pqer = lcqvm.native_quil_to_executable(p)
    p2 = _extract_program_from_pyquil_executable_response(pqer)
    for i1, i2 in zip(p, p2):
        assert i1 == i2
Example #4
0
    def load(self, executable):
        if isinstance(executable, PyQuilExecutableResponse):
            program = _extract_program_from_pyquil_executable_response(
                executable)
        else:
            program = executable

        try:
            program, self._qubit_to_ram, self._ro_size = _make_ram_program(
                program)
        except NotRunAndMeasureProgramError as e:
            raise ValueError(
                "PyQVM can only run run-and-measure style programs: {}".format(
                    e))

        # initialize program counter
        self.program = program
        self.program_counter = 0
        self._bitstrings = None

        # clear RAM, although it's not strictly clear if this should happen here
        self.ram = {}

        self.status = 'loaded'
        return self
Example #5
0
    def load(self, executable):
        if isinstance(executable, PyQuilExecutableResponse):
            program = _extract_program_from_pyquil_executable_response(executable)
        else:
            program = executable

        # initialize program counter
        self.program = program
        self.program_counter = 0
        self._memory_results = None

        # clear RAM, although it's not strictly clear if this should happen here
        self.ram = {}
        # if we're clearing RAM, we ought to clear the WF too
        self.wf_simulator.reset()

        # grab the gate definitions for future use
        self.defined_gates = dict()
        for dg in self.program.defined_gates:
            if dg.parameters is not None and len(dg.parameters) > 0:
                raise NotImplementedError("PyQVM does not support parameterized DEFGATEs")
            self.defined_gates[dg.name] = dg.matrix

        self.status = 'loaded'
        return self
Example #6
0
    def load(self, executable):
        if isinstance(executable, PyQuilExecutableResponse):
            program = _extract_program_from_pyquil_executable_response(executable)
        else:
            program = executable

        # initialize program counter
        self.program = program
        self.program_counter = 0
        self._memory_results = None

        # clear RAM, although it's not strictly clear if this should happen here
        self.ram = {}
        # if we're clearing RAM, we ought to clear the WF too
        self.wf_simulator.reset()

        # grab the gate definitions for future use
        self._extract_defined_gates()

        self.status = "loaded"
        return self
Example #7
0
def test_roundtrip_pyquilexecutableresponse(compiler):
    p = Program(H(10), CNOT(10, 11))
    pqer = compiler.native_quil_to_executable(p)
    p2 = _extract_program_from_pyquil_executable_response(pqer)
    for i1, i2 in zip(p, p2):
        assert i1 == i2