Exemple #1
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
    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
Exemple #3
0
 def run_circuit(self, circuit: Circuit,
                 **kwargs: KwargTypes) -> BackendResult:
     cirq_circ = tk_to_cirq(circuit)
     bit_to_qubit_map = {b: q for q, b in circuit.qubit_to_bit_map.items()}
     if not cirq_circ.has_measurements():  # type: ignore
         n_shots = cast(int, kwargs.get("n_shots"))
         return self.empty_result(circuit, n_shots=n_shots)
     else:
         run = self._simulator.run(cirq_circ,
                                   repetitions=cast(int,
                                                    kwargs.get("n_shots")))
         run_dict = run.data.to_dict()
         c_bits = [
             bit for key in run_dict.keys()
             for bit in bit_to_qubit_map.keys() if str(bit) == key
         ]
         individual_readouts = [
             list(readout.values()) for readout in run_dict.values()
         ]
         shots = OutcomeArray.from_readouts(
             [list(r) for r in zip(*individual_readouts)])
         return BackendResult(shots=shots, c_bits=c_bits)
    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
Exemple #5
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
Exemple #6
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
Exemple #7
0
 def set_simulator(self, **kwargs: KwargTypes) -> CliffordSimulator:
     return CliffordSimulator(seed=kwargs.get("seed"))
Exemple #8
0
 def set_simulator(self, **kwargs: KwargTypes) -> DensityMatrixSimulator:
     return DensityMatrixSimulator(seed=kwargs.get("seed"))