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
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
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
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
def set_simulator(self, **kwargs: KwargTypes) -> CliffordSimulator: return CliffordSimulator(seed=kwargs.get("seed"))
def set_simulator(self, **kwargs: KwargTypes) -> DensityMatrixSimulator: return DensityMatrixSimulator(seed=kwargs.get("seed"))