예제 #1
0
def test_aer_result_handle() -> None:
    c = Circuit(2, 2).H(0).CX(0, 1).measure_all()

    b = AerBackend()

    handles = b.process_circuits([c, c.copy()], n_shots=2)

    ids, indices = zip(*(han for han in handles))

    assert all(isinstance(idval, str) for idval in ids)
    assert indices == (0, 1)

    assert len(b.get_result(handles[0]).get_shots()) == 2

    with pytest.raises(TypeError) as errorinfo:
        _ = b.get_result(ResultHandle("43"))
    assert "ResultHandle('43',) does not match expected identifier types" in str(
        errorinfo.value)

    wronghandle = ResultHandle("asdf", 3)

    with pytest.raises(CircuitNotRunError) as errorinfoCirc:
        _ = b.get_result(wronghandle)
    assert "Circuit corresponding to {0!r} ".format(
        wronghandle) + "has not been run by this backend instance." in str(
            errorinfoCirc.value)
예제 #2
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        See :py:meth:`pytket.backends.Backend.process_circuits`.
        Supported kwargs: none.
        """
        if n_shots is None or n_shots < 1:
            raise ValueError("Parameter n_shots is required for this backend")

        if valid_check:
            self._check_all_circuits(circuits)
        basebody = {
            "lang": "json",
            "body": None,
            "target": self._device_name,
            "shots": n_shots,
        }
        handles = []
        for i, circ in enumerate(circuits):
            result = dict()
            bodycopy = basebody.copy()
            (bodycopy["body"], meas) = tk_to_ionq(circ)  # type: ignore
            if len(meas) == 0:
                result["result"] = self.empty_result(circ, n_shots=n_shots)
            measures = json.dumps(meas)
            bodycopy["name"] = circ.name if circ.name else f"{self._label}_{i}"
            if self._MACHINE_DEBUG:
                handle = ResultHandle(
                    _DEBUG_HANDLE_PREFIX + str(circ.n_qubits),
                    n_shots,
                    measures,
                )
                handles.append(handle)
            else:
                header = self._header.copy()
                header["Content-Type"] = "application/json"
                try:
                    # post job
                    resp = post(self._url, json.dumps(bodycopy), headers=header).json()
                    if "error" in resp:
                        raise RuntimeError(resp["error"])
                    if resp["status"] == "failed":
                        raise RuntimeError("Unknown error while submitting job.")
                except ConnectionError:
                    raise ConnectionError(
                        f"{self._label} Connection Error: Error during submit..."
                    )

                # extract job ID from response
                job_id = resp["id"]
                handle = ResultHandle(job_id, n_shots, measures)
                handles.append(handle)
        for handle in handles:
            self._cache[handle] = result
        return handles
예제 #3
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        See :py:meth:`pytket.backends.Backend.process_circuits`.
        Supported kwargs: none.
        """
        if n_shots is None or n_shots < 1:
            raise ValueError("Parameter n_shots is required for this backend")

        if valid_check:
            self._check_all_circuits(circuits)
        basebody = {
            "machine": self._device_name,
            "language": "OPENQASM 2.0",
            "priority": "normal",
            "count": n_shots,
            "options": None,
        }
        handle_list = []
        for i, circ in enumerate(circuits):
            honeywell_circ = circuit_to_qasm_str(circ, header="hqslib1")
            body = basebody.copy()
            body["name"] = circ.name if circ.name else f"{self._label}_{i}"
            body["program"] = honeywell_circ
            if self._api_handler is None:
                handle_list.append(
                    ResultHandle(_DEBUG_HANDLE_PREFIX +
                                 str((circ.n_qubits, n_shots))))
            else:
                try:
                    res = _submit_job(self._api_handler, body)
                    if res.status_code != HTTPStatus.OK:
                        self.relogin()
                        res = _submit_job(self._api_handler, body)

                    jobdict = res.json()
                    if res.status_code != HTTPStatus.OK:
                        raise HQSAPIError(
                            f'HTTP error submitting job, {jobdict["error"]["text"]}'
                        )
                except ConnectionError:
                    raise ConnectionError(
                        f"{self._label} Connection Error: Error during submit..."
                    )

                # extract job ID from response
                handle = ResultHandle(jobdict["job"])
                handle_list.append(handle)
                self._cache[handle] = dict()

        return handle_list
예제 #4
0
 def process_circuits(
     self,
     circuits: Iterable[Circuit],
     n_shots: Optional[int] = None,
     valid_check: bool = True,
     **kwargs: KwargTypes,
 ) -> List[ResultHandle]:
     """
     Supported `kwargs`: none
     """
     if not self.supports_shots and not self.supports_state:
         raise RuntimeError("Backend does not support shots or state")
     if n_shots is None:
         n_shots = 0
     want_state = n_shots == 0
     if (not want_state) and (n_shots < self._sample_min_shots
                              or n_shots > self._sample_max_shots):
         raise ValueError(
             "For sampling, n_shots must be between "
             f"{self._sample_min_shots} and {self._sample_max_shots}. "
             "For statevector simulation, omit this parameter.")
     if valid_check:
         self._check_all_circuits(circuits, nomeasure_warn=False)
     handles = []
     for circ in circuits:
         bkcirc = self._to_bkcirc(circ)
         if want_state:
             bkcirc.add_result_type(ResultType.StateVector())
         if not bkcirc.instructions and len(circ.bits) == 0:
             task = None
         else:
             task = self._run(bkcirc, n_shots=n_shots)
         if self._device_type == _DeviceType.LOCAL:
             # Results are available now. Put them in the cache.
             if task is not None:
                 assert task.state() == "COMPLETED"
                 results = _get_result(task, want_state)
             else:
                 results = {
                     "result": self.empty_result(circ, n_shots=n_shots)
                 }
         else:
             # Task is asynchronous. Must wait for results.
             results = {}
         if task is not None:
             handle = ResultHandle(task.id, want_state)
         else:
             handle = ResultHandle(str(uuid4()), False)
         self._cache[handle] = results
         handles.append(handle)
     return handles
예제 #5
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        circuit_list = list(circuits)

        if valid_check:
            self._check_all_circuits(circuit_list)

        qcs = [tk_to_qiskit(tkc) for tkc in circuit_list]
        seed = cast(Optional[int], kwargs.get("seed"))
        qobj = assemble(qcs,
                        shots=n_shots,
                        memory=self._memory,
                        seed_simulator=seed)
        job = self._backend.run(qobj, noise_model=self._noise_model)
        jobid = job.job_id()
        handle_list = [
            ResultHandle(jobid, i) for i in range(len(circuit_list))
        ]
        for handle in handle_list:
            self._cache[handle] = {"job": job}
        return handle_list
예제 #6
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list,
                                     nomeasure_warn=(n_shots is not None))

        handle_list = []
        for circuit in circuit_list:
            qulacs_state = self._sim(circuit.n_qubits)
            qulacs_state.set_zero_state()
            qulacs_circ = tk_to_qulacs(circuit)
            qulacs_circ.update_quantum_state(qulacs_state)
            state = qulacs_state.get_vector()
            qubits = sorted(circuit.qubits, reverse=True)
            shots = None
            bits = None
            if n_shots:

                bits2index = list((com.bits[0], qubits.index(com.qubits[0]))
                                  for com in circuit
                                  if com.op.type == OpType.Measure)
                if len(bits2index) == 0:
                    bits = circuit.bits
                    shots = OutcomeArray.from_ints([0] * n_shots, len(bits))
                else:
                    bits, choose_indices = zip(*bits2index)

                    samples = qulacs_state.sampling(n_shots)
                    shots = OutcomeArray.from_ints(samples, circuit.n_qubits)
                    shots = shots.choose_indices(choose_indices)
            try:
                phase = float(circuit.phase)
                coeff = np.exp(phase * np.pi * 1j)
                state *= coeff
            except TypeError:
                warning(
                    "Global phase is dependent on a symbolic parameter, so cannot "
                    "adjust for phase")
            implicit_perm = circuit.implicit_qubit_permutation()
            qubits = [implicit_perm[qb] for qb in qubits]
            handle = ResultHandle(str(uuid4()))
            self._cache[handle] = {
                "result":
                BackendResult(state=state,
                              shots=shots,
                              c_bits=bits,
                              q_bits=qubits)
            }
            handle_list.append(handle)
            del qulacs_state
            del qulacs_circ
        return handle_list
예제 #7
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        Submit circuits to the backend for running. The results will be stored
        in the backend's result cache to be retrieved by the corresponding
        get_<data> method.

        Use keyword arguments to specify parameters to be used in submitting circuits
        See specific Backend derived class for available parameters, from the following
        list:

        * `seed`: RNG seed for simulators

        :param circuits: Circuits to process on the backend.
        :type circuits: Iterable[Circuit]
        :param n_shots: Number of shots to run per circuit. None is to be used
            for state/unitary simulators. Defaults to None.
        :type n_shots: Optional[int], optional
        :param valid_check: Explicitly check that all circuits satisfy all required
            predicates to run on the backend. Defaults to True
        :type valid_check: bool, optional
        :return: Handles to results for each input circuit, as an interable in
            the same order as the circuits.
        :rtype: List[ResultHandle]
        """

        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list)

        handle_list = []
        for circuit in circuit_list:
            handle = ResultHandle(str(uuid4()))
            mycirc, measure_map = tk_to_mymeasures(circuit)
            qubit_list, bit_list = zip(*measure_map.items())
            qubit_shots = sample_mycircuit(mycirc, set(qubit_list), n_shots,
                                           kwargs.get("seed"))
            # Pad shot table with 0 columns for unused bits
            all_shots = np.zeros((n_shots, len(circuit.bits)), dtype=int)
            all_shots[:, :len(qubit_list)] = qubit_shots
            res_bits = [
                measure_map[q] for q in sorted(qubit_list, reverse=True)
            ]
            for b in circuit.bits:
                if b not in bit_list:
                    res_bits.append(b)
            res = BackendResult(c_bits=res_bits,
                                shots=OutcomeArray.from_readouts(all_shots))
            self._cache[handle] = {"result": res}
            handle_list.append(handle)
        return handle_list
예제 #8
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        See :py:meth:`pytket.backends.Backend.process_circuits`.
        Supported kwargs: none.
        """
        if n_shots is None or n_shots < 1:
            raise ValueError("Parameter n_shots is required for this backend")

        if valid_check:
            self._check_all_circuits(circuits)
        handles = []
        for i, c in enumerate(circuits):
            (aqt_circ, measures) = _translate_aqt(c)
            if self._MACHINE_DEBUG:
                handles.append(
                    ResultHandle(
                        _DEBUG_HANDLE_PREFIX + str((c.n_qubits, n_shots)),
                        measures))
            else:
                resp = put(
                    self._url,
                    data={
                        "data": json.dumps(aqt_circ),
                        "repetitions": n_shots,
                        "no_qubits": c.n_qubits,
                        "label": c.name if c.name else f"{self._label}_{i}",
                    },
                    headers=self._header,
                ).json()
                if "status" not in resp:
                    raise RuntimeError(resp["message"])
                if resp["status"] == "error":
                    raise RuntimeError(resp["ERROR"])
                handles.append(ResultHandle(resp["id"], measures))
        for handle in handles:
            self._cache[handle] = dict()
        return handles
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        """
        See :py:meth:`pytket.backends.Backend.process_circuits`.
        Supported kwargs: `seed`.
        """
        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list)

        handle_list = []
        for circuit in circuit_list:
            sim = Simulator(rnd_seed=kwargs.get("seed"))
            fwd = ForwarderEngine(sim)
            eng = MainEngine(backend=sim, engine_list=[fwd])
            qureg = eng.allocate_qureg(circuit.n_qubits)
            tk_to_projectq(eng, qureg, circuit, True)
            eng.flush()
            state = np.array(
                eng.backend.cheat()[1], dtype=complex
            )  # `cheat()` returns tuple:(a dictionary of qubit indices, statevector)
            handle = ResultHandle(str(uuid4()))
            try:
                phase = float(circuit.phase)
                coeff = np.exp(phase * np.pi * 1j)
                state *= coeff
            except ValueError:
                warning(
                    "Global phase is dependent on a symbolic parameter, so cannot "
                    "adjust for phase")
            implicit_perm = circuit.implicit_qubit_permutation()
            # reverse qubits as projectq state is dlo
            res_qubits = [
                implicit_perm[qb]
                for qb in sorted(circuit.qubits, reverse=True)
            ]
            measures = circuit.n_gates_of_type(OpType.Measure)
            if measures == 0 and n_shots is not None:
                backres = self.empty_result(circuit, n_shots=n_shots)
            else:
                backres = BackendResult(q_bits=res_qubits, state=state)
            self._cache[handle] = {"result": backres}
            handle_list.append(handle)
        return handle_list
예제 #10
0
def process_circuits(
    self,
    circuits: Iterable[Circuit],
    n_shots: Optional[int] = None,
    valid_check: bool = True,
    **kwargs: KwargTypes,
) -> List[ResultHandle]:
    """
    Submit circuits to the backend for running. The results will be stored
    in the backend's result cache to be retrieved by the corresponding
    get_<data> method.

    Use keyword arguments to specify parameters to be used in submitting circuits
    See specific Backend derived class for available parameters, from the following
    list:

    * `seed`: RNG seed for simulators

    :param circuits: Circuits to process on the backend.
    :type circuits: Iterable[Circuit]
    :param n_shots: Number of shots to run per circuit. None is to be used
        for state/unitary simulators. Defaults to None.
    :type n_shots: Optional[int], optional
    :param valid_check: Explicitly check that all circuits satisfy all required
        predicates to run on the backend. Defaults to True
    :type valid_check: bool, optional
    :return: Handles to results for each input circuit, as an interable in
        the same order as the circuits.
    :rtype: List[ResultHandle]
    """

    circuit_list = list(circuits)
    if valid_check:
        self._check_all_circuits(circuit_list)

    handle_list = []
    for circuit in circuit_list:
        handle = ResultHandle(str(uuid4()))
        mycirc = tk_to_mycircuit(circuit)
        state = run_mycircuit(mycirc)
        state *= np.exp(1j * np.pi * circuit.phase)
        implicit_perm = circuit.implicit_qubit_permutation()
        res_qubits = [
            implicit_perm[qb] for qb in sorted(circuit.qubits, reverse=True)
        ]
        res = BackendResult(q_bits=res_qubits, state=state)
        self._cache[handle] = {"result": res}
        handle_list.append(handle)
    return handle_list
예제 #11
0
 def process_circuits(
     self,
     circuits: Iterable[Circuit],
     n_shots: Optional[int] = None,
     valid_check: bool = True,
     **kwargs: KwargTypes,
 ) -> List[ResultHandle]:
     """
     See :py:meth:`pytket.backends.Backend.process_circuits`.
     Supported kwargs: none.
     """
     if n_shots is None or n_shots < 1:
         raise ValueError("Parameter n_shots is required for this backend")
     handle_list = []
     for chunk in itertools.zip_longest(*([iter(circuits)] *
                                          self._max_per_job)):
         filtchunk = list(filter(lambda x: x is not None, chunk))
         if valid_check:
             self._check_all_circuits(filtchunk)
         qcs = [tk_to_qiskit(tkc) for tkc in filtchunk]
         qobj = assemble(qcs, shots=n_shots, memory=self._config.memory)
         if self._MACHINE_DEBUG:
             handle_list += [
                 ResultHandle(
                     _DEBUG_HANDLE_PREFIX + str((c.n_qubits, n_shots)), i)
                 for i, c in enumerate(filtchunk)
             ]
         else:
             job = self._backend.run(qobj)
             jobid = job.job_id()
             handle_list += [
                 ResultHandle(jobid, i) for i in range(len(filtchunk))
             ]
     for handle in handle_list:
         self._cache[handle] = dict()
     return handle_list
예제 #12
0
    def get_result(self, handle: ResultHandle,
                   **kwargs: KwargTypes) -> BackendResult:
        try:
            return super().get_result(handle)
        except CircuitNotRunError:
            jobid, _ = handle
            try:
                job: "AerJob" = self._cache[handle]["job"]
            except KeyError:
                raise CircuitNotRunError(handle)

            res = job.result()
            backresults = qiskit_result_to_backendresult(res)
            for circ_index, backres in enumerate(backresults):
                self._cache[ResultHandle(jobid,
                                         circ_index)]["result"] = backres

            return cast(BackendResult, self._cache[handle]["result"])
예제 #13
0
    def get_result(self, handle: ResultHandle,
                   **kwargs: KwargTypes) -> BackendResult:
        if handle in self._cache:
            if "result" in self._cache[handle]:
                return cast(BackendResult, self._cache[handle]["result"])

        self._check_handle_type(handle)
        try:
            job: "AerJob" = self._cache[handle]["job"]
        except KeyError:
            raise CircuitNotRunError(handle)

        res = job.result()
        backresults = qiskit_result_to_backendresult(res)
        for circ_index, backres in enumerate(backresults):
            newhandle = ResultHandle(handle[0], circ_index)
            if "implicit_perm_qubits" in self._cache[newhandle]:
                permed_qbit_map: Dict[
                    Qubit,
                    Qubit] = self._cache[newhandle]["implicit_perm_qubits"]
                original_indexmap = backres.q_bits.copy()
                assert original_indexmap
                # Simultaneous permutation of inputs and outputs of process
                # Handles implicit permutation of outputs for statevector
                backres.q_bits = {
                    permed_qbit_map[qb]: index
                    for qb, index in original_indexmap.items()
                }

                if backres._unitary is not None:
                    # For unitaries, the implicit permutation
                    #  should only be applied to inputs
                    # The above relabelling will permute both inputs and outputs
                    # Correct by applying the inverse
                    # permutation on the inputs (i.e. a column permutation)
                    permutation = [0] * len(original_indexmap)
                    for qb, index in original_indexmap.items():
                        permutation[index] = original_indexmap[
                            permed_qbit_map[qb]]
                    backres._unitary = permute_basis_indexing(
                        backres._unitary.T, tuple(permutation)).T
            self._cache[newhandle]["result"] = backres

        return cast(BackendResult, self._cache[handle]["result"])
예제 #14
0
    def process_circuits(
        self,
        circuits: Iterable[Circuit],
        n_shots: Optional[int] = None,
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:
        self._simulator = self.set_simulator(seed=kwargs.get("seed"))
        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list)

        handle_list = []
        for i, circuit in enumerate(circuit_list):
            handle = ResultHandle(str(uuid4()), i)
            handle_list.append(handle)
            backres = self.run_circuit(circuit, n_shots=n_shots)
            self._cache[handle] = {"result": backres}

        return handle_list
예제 #15
0
    def process_circuits_moments(
        self,
        circuits: Iterable[Circuit],
        valid_check: bool = True,
        **kwargs: KwargTypes,
    ) -> List[ResultHandle]:

        """
        Submit circuits to the backend for running. The results will be stored
        in the backend's result cache to be retrieved by the corresponding
        get_<data> method. The get_<data> method will return List[BackendResult]
        corresponding to each moment.

        Use keyword arguments to specify parameters to be used in submitting circuits:

        * `seed`: RNG seed for simulators

        :param circuits: Circuits to process on the backend.
        :type circuits: Iterable[Circuit]
        :param valid_check: Explicitly check that all circuits satisfy all required
            predicates to run on the backend. Defaults to True
        :type valid_check: bool, optional
        :return: Handles to results for each input circuit, as an interable in
            the same order as the circuits.
        :rtype: List[ResultHandle]
        """

        self._simulator = self.set_simulator(seed=kwargs.get("seed"))
        circuit_list = list(circuits)
        if valid_check:
            self._check_all_circuits(circuit_list)

        handle_list = []
        for i, circuit in enumerate(circuit_list):
            circuit.remove_blank_wires()
            handle = ResultHandle(str(uuid4()), i)
            handle_list.append(handle)
            backres = self.run_circuit_moments(circuit)
            self._cache[handle] = {"result": backres}  # type: ignore

        return handle_list
예제 #16
0
 def process_circuits(
     self,
     circuits: Iterable[Circuit],
     n_shots: Optional[int] = None,
     valid_check: bool = True,
     **kwargs: KwargTypes,
 ) -> List[ResultHandle]:
     """
     See :py:meth:`pytket.backends.Backend.process_circuits`.
     Supported kwargs: `seed`.
     """
     if n_shots is None or n_shots < 1:
         raise ValueError(
             "Parameter n_shots is required for this backend for ForestBackend"
         )
     if valid_check:
         self._check_all_circuits(circuits)
     handle_list = []
     for circuit in circuits:
         p, bits = tk_to_pyquil(circuit, return_used_bits=True)
         p.wrap_in_numshots_loop(n_shots)
         ex = self._qc.compiler.native_quil_to_executable(p)
         qam = copy(self._qc.qam)
         qam.load(ex)
         qam.random_seed = kwargs.get("seed")  # type: ignore
         qam.run()
         handle = ResultHandle(uuid4().int)
         measures = circuit.n_gates_of_type(OpType.Measure)
         if measures == 0:
             self._cache[handle] = {
                 "qam": qam,
                 "c_bits": sorted(bits),
                 "result": self.empty_result(circuit, n_shots=n_shots),
             }
         else:
             self._cache[handle] = {"qam": qam, "c_bits": sorted(bits)}
         handle_list.append(handle)
     return handle_list
예제 #17
0
    def get_result(self, handle: ResultHandle,
                   **kwargs: KwargTypes) -> BackendResult:
        """
        See :py:meth:`pytket.backends.Backend.get_result`.
        Supported kwargs: `timeout`, `wait`.
        """
        try:
            return super().get_result(handle)
        except CircuitNotRunError:
            jobid = cast(str, handle[0])
            index = cast(int, handle[1])
            if self._MACHINE_DEBUG or jobid.startswith(_DEBUG_HANDLE_PREFIX):
                shots: int
                n_qubits: int
                n_qubits, shots = literal_eval(
                    jobid[len(_DEBUG_HANDLE_PREFIX):])
                res = _gen_debug_results(n_qubits, shots, index)
            else:
                try:
                    job = self._retrieve_job(jobid)
                except IBMQBackendApiError:
                    raise CircuitNotRunError(handle)

                if self._monitor and job:
                    job_monitor(job)
                newkwargs = {
                    key: kwargs[key]
                    for key in ("wait", "timeout") if key in kwargs
                }
                res = job.result(**newkwargs)
            backresults = list(qiskit_result_to_backendresult(res))
            self._cache.update((ResultHandle(jobid, circ_index), {
                "result": backres
            }) for circ_index, backres in enumerate(backresults))

            return cast(BackendResult, self._cache[handle]["result"])
예제 #18
0
 def process_circuits(
     self,
     circuits: Iterable[Circuit],
     n_shots: Optional[int] = None,
     valid_check: bool = True,
     **kwargs: KwargTypes,
 ) -> List[ResultHandle]:
     handle_list = []
     if valid_check:
         self._check_all_circuits(circuits)
     for circuit in circuits:
         p = tk_to_pyquil(circuit)
         for qb in circuit.qubits:
             # Qubits with no gates will not be included in the Program
             # Add identities to ensure all qubits are present and dimension
             # is as expected
             p += I(Qubit_(qb.index[0]))
         handle = ResultHandle(uuid4().int)
         state = np.array(self._sim.wavefunction(p).amplitudes)
         try:
             phase = float(circuit.phase)
             coeff = np.exp(phase * np.pi * 1j)
             state *= coeff
         except ValueError:
             warning(
                 "Global phase is dependent on a symbolic parameter, so cannot "
                 "adjust for phase")
         implicit_perm = circuit.implicit_qubit_permutation()
         res_qubits = [
             implicit_perm[qb]
             for qb in sorted(circuit.qubits, reverse=True)
         ]
         res = BackendResult(q_bits=res_qubits, state=state)
         self._cache[handle] = {"result": res}
         handle_list.append(handle)
     return handle_list
예제 #19
0
 def process_circuits(
     self,
     circuits: Iterable[Circuit],
     n_shots: Optional[int] = None,
     valid_check: bool = True,
     **kwargs: KwargTypes,
 ) -> List[ResultHandle]:
     """
     See :py:meth:`pytket.backends.Backend.process_circuits`.
     Supported kwargs: none.
     """
     if valid_check:
         self._check_all_circuits(circuits, nomeasure_warn=False)
     handles = []
     for c in circuits:
         qs = tk_to_qsharp(c)
         qc = qscompile(qs)
         results = self._calculate_results(qc, n_shots)
         handle = ResultHandle(str(uuid4()))
         key = "result" if isinstance(results,
                                      BackendResult) else "resource"
         self._cache.update({handle: {key: results}})
         handles.append(handle)
     return handles