示例#1
0
 def circuit_status(self, handle: ResultHandle) -> CircuitStatus:
     self._check_handle_type(handle)
     jobid = handle[0]
     message = ""
     measure_permutations = json.loads(handle[1])  # type: ignore
     if self._MACHINE_DEBUG:
         n_qubits, n_shots = literal_eval(
             jobid[len(_DEBUG_HANDLE_PREFIX):])  # type: ignore
         empty_ar = OutcomeArray.from_ints([0] * n_shots,
                                           n_qubits,
                                           big_endian=True)
         self._cache[handle].update(
             {"result": BackendResult(shots=empty_ar)})
         statenum = StatusEnum.COMPLETED
     else:
         data = put(self._url, data={
             "id": jobid
         }, headers=self._header).json()
         status = data["status"]
         if "ERROR" in data:
             message = data["ERROR"]
         statenum = _STATUS_MAP.get(status, StatusEnum.ERROR)
         if statenum is StatusEnum.COMPLETED:
             shots = OutcomeArray.from_ints(data["samples"],
                                            data["no_qubits"],
                                            big_endian=True)
             shots = shots.choose_indices(measure_permutations)
             self._cache[handle].update(
                 {"result": BackendResult(shots=shots)})
     return CircuitStatus(statenum, message)
def backendresult_to_qiskit_resultdata(
    res: BackendResult,
    header: "QobjExperimentHeader",
    final_map: Optional[Dict[UnitID, UnitID]],
) -> ExperimentResultData:
    data: Dict[str, Any] = dict()
    if res.contains_state_results:
        qbits = (
            _gen_uids(header.qreg_sizes, Qubit) if hasattr(header, "qreg_sizes") else []
        )
        if final_map:
            qbits = [final_map[q] for q in qbits]
        stored_res = res.get_result(qbits)
        if stored_res.state is not None:
            data["statevector"] = stored_res.state
        if stored_res.unitary is not None:
            data["unitary"] = stored_res.unitary
    if res.contains_measured_results:
        cbits = (
            _gen_uids(header.creg_sizes, Bit) if hasattr(header, "creg_sizes") else []
        )
        if final_map:
            cbits = [final_map[c] for c in cbits]
        stored_res = res.get_result(cbits)
        if stored_res.shots is not None:
            data["memory"] = [hex(i) for i in stored_res.shots.to_intlist()]
            data["counts"] = dict(Counter(data["memory"]))
        elif stored_res.counts is not None:
            data["counts"] = {
                hex(i.to_intlist()[0]): f for i, f in stored_res.counts.items()
            }
    return ExperimentResultData(**data)
示例#3
0
 def circuit_status(self, handle: ResultHandle) -> CircuitStatus:
     self._check_handle_type(handle)
     jobid = str(handle[0])
     n_shots = cast(int, handle[1])
     if self._MACHINE_DEBUG:
         n_qubits: int = literal_eval(jobid[len(_DEBUG_HANDLE_PREFIX):])
         zero_counts: Counter = Counter()
         zero_array = OutcomeArray.from_ints(
             ints=[0],
             width=n_qubits,
             big_endian=False,
         )
         zero_counts[zero_array] = n_shots
         if handle in self._cache:
             self._cache[handle].update(
                 {"result": BackendResult(counts=zero_counts)})
         else:
             self._cache[handle] = {
                 "result": BackendResult(counts=zero_counts)
             }
         statenum = StatusEnum.COMPLETED
     else:
         measure_permutations = json.loads(str(handle[2]))
         url = self._url + str(jobid)
         resp = get(url, headers=self._header).json()
         status = resp["status"]
         statenum = _STATUS_MAP.get(status)  # type: ignore
         if statenum is StatusEnum.COMPLETED:
             ionq_counts = resp["data"]["histogram"]
             tket_counts: Counter = Counter()
             # reverse engineer counts. Imprecise, due to rounding.
             max_counts = 0
             max_array = None
             for outcome_key, prob in ionq_counts.items():
                 array = OutcomeArray.from_ints(
                     ints=[int(outcome_key)],
                     width=int(resp["qubits"]),
                     big_endian=False,
                 )
                 array = array.choose_indices(measure_permutations)
                 array_counts = round(n_shots * float(prob))
                 tket_counts[array] = array_counts
                 if array_counts > max_counts:
                     max_counts = array_counts
                     max_array = array
             # account for rounding error
             sum_counts = sum(tket_counts.values())
             diff = n_shots - sum_counts
             tket_counts[max_array] += diff
             if handle in self._cache:
                 self._cache[handle].update(
                     {"result": BackendResult(counts=tket_counts)})
             else:
                 self._cache[handle] = {
                     "result": BackendResult(counts=tket_counts)
                 }
     return CircuitStatus(statenum)
    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
示例#5
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
示例#6
0
    def package_results(
        self, circuit: CirqCircuit, q_bits: Sequence[Qubit]
    ) -> List[BackendResult]:
        moments = self._simulator.simulate_moment_steps(circuit)
        all_backres = [
            BackendResult(density_matrix=run.density_matrix(copy=True), q_bits=q_bits)
            for run in moments
        ]

        return all_backres
示例#7
0
def _get_result(completed_task: Union[AwsQuantumTask, LocalQuantumTask],
                want_state: bool) -> Dict[str, BackendResult]:
    result = completed_task.result()
    kwargs = {}
    if want_state:
        kwargs["state"] = result.get_value_by_result_type(
            ResultType.StateVector())
    else:
        kwargs["shots"] = OutcomeArray.from_readouts(result.measurements)
    return {"result": BackendResult(**kwargs)}
示例#8
0
 def package_result(self, circuit: CirqCircuit,
                    q_bits: Sequence[Qubit]) -> BackendResult:
     run = cast(
         StateVectorTrialResult,
         self._simulator.simulate(
             circuit,
             qubit_order=ops.QubitOrder.as_qubit_order(
                 ops.QubitOrder.DEFAULT).order_for(circuit.all_qubits()),
         ),
     )
     return BackendResult(state=run.final_state_vector, q_bits=q_bits)
示例#9
0
 def package_results(
     self, circuit: CirqCircuit, q_bits: Sequence[Qubit]
 ) -> List[BackendResult]:
     moments = self._simulator.simulate_moment_steps(
         circuit,
         qubit_order=ops.QubitOrder.as_qubit_order(ops.QubitOrder.DEFAULT).order_for(
             circuit.all_qubits()
         ),
     )
     all_backres = [
         BackendResult(state=run.state.state_vector(), q_bits=q_bits)
         for run in moments
     ]
     return all_backres
    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
示例#11
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
def qiskit_result_to_backendresult(res: Result) -> Iterator[BackendResult]:
    for result in res.results:
        header = result.header
        width = header.memory_slots

        c_bits = (
            _gen_uids(header.creg_sizes, Bit) if hasattr(header, "creg_sizes") else None
        )
        q_bits = (
            _gen_uids(header.qreg_sizes, Qubit)
            if hasattr(header, "qreg_sizes")
            else None
        )
        shots, counts, state, unitary = (None,) * 4
        datadict = result.data.to_dict()
        if len(datadict) == 0 and result.shots > 0:
            n_bits = len(c_bits) if c_bits else 0
            shots = OutcomeArray.from_readouts(
                np.zeros((result.shots, n_bits), dtype=np.uint8)  #  type: ignore
            )
        else:
            if "memory" in datadict:
                memory = datadict["memory"]
                shots = _hex_to_outar(memory, width)
            elif "counts" in datadict:
                qis_counts = datadict["counts"]
                counts = Counter(
                    dict(
                        (_hex_to_outar([hexst], width), count)
                        for hexst, count in qis_counts.items()
                    )
                )

            if "statevector" in datadict:
                state = datadict["statevector"]

            if "unitary" in datadict:
                unitary = datadict["unitary"]

        yield BackendResult(
            c_bits=c_bits,
            q_bits=q_bits,
            shots=shots,
            counts=counts,
            state=state,
            unitary=unitary,
        )
示例#13
0
def _convert_result(resultdict: Dict[str, List[str]]) -> BackendResult:
    array_dict = {
        creg: np.array([list(a) for a in reslist]).astype(np.uint8)
        for creg, reslist in resultdict.items()
    }
    reversed_creg_names = sorted(array_dict.keys(), reverse=True)
    c_bits = [
        Bit(name, ind) for name in reversed_creg_names
        for ind in range(array_dict[name].shape[-1] - 1, -1, -1)
    ]

    stacked_array = np.hstack(
        [array_dict[name] for name in reversed_creg_names])
    return BackendResult(
        c_bits=c_bits,
        shots=OutcomeArray.from_readouts(
            cast(Sequence[Sequence[int]], stacked_array)),
    )
示例#14
0
    def get_result(self, handle: ResultHandle,
                   **kwargs: KwargTypes) -> BackendResult:
        """
        See :py:meth:`pytket.backends.Backend.get_result`.
        Supported kwargs: none.
        """
        try:
            return super().get_result(handle)
        except CircuitNotRunError:
            if handle not in self._cache:
                raise CircuitNotRunError(handle)

            qam = self._cache[handle]["qam"]
            shots = qam.wait().read_memory(region_name="ro")
            shots = OutcomeArray.from_readouts(shots)
            res = BackendResult(shots=shots,
                                c_bits=self._cache[handle]["c_bits"])
            self._cache[handle].update({"result": res})
            return res
示例#15
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)
示例#16
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
示例#17
0
 def package_result(
     self, circuit: CirqCircuit, q_bits: Sequence[Qubit]
 ) -> BackendResult:
     run = cast(DensityMatrixTrialResult, self._simulator.simulate(circuit))
     return BackendResult(density_matrix=run.final_density_matrix, q_bits=q_bits)