예제 #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)
예제 #2
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
예제 #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)
예제 #4
0
def _convert_result(output: Dict[str, float], n_shots: int) -> BackendResult:
    counts = Counter({
        OutcomeArray.from_readouts([json.loads(state)]): int(prob * n_shots)
        for state, prob in output.items()
    })

    return BackendResult(counts=counts)
예제 #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 _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)}
예제 #7
0
 def _calculate_results(self,
                        qscall: "QSharpCallable",
                        n_shots: Optional[int] = None) -> BackendResult:
     if n_shots:
         shots_ar = np.array([qscall.simulate() for _ in range(n_shots)],
                             dtype=np.uint8)
         shots = OutcomeArray.from_readouts(shots_ar)  # type: ignore
         # ^ type ignore as array is ok for Sequence[Sequence[int]]
         # outputs should correspond to default register,
         # as mapped by FlattenRegisters()
         return BackendResult(shots=shots)
     raise ValueError("Parameter n_shots is required for this backend")
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,
        )
예제 #9
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)),
    )
예제 #10
0
 def circuit_status(self, handle: ResultHandle) -> CircuitStatus:
     self._check_handle_type(handle)
     jobid = cast(str, handle[0])
     message = ""
     n_shots = cast(int, handle[1])
     if self._MACHINE_DEBUG:
         n_bits = literal_eval(jobid[len(_DEBUG_HANDLE_PREFIX) :])
         empty_ar = OutcomeArray.from_ints([0] * n_shots, n_bits, big_endian=True)
         self._cache[handle].update({"result": BackendResult(shots=empty_ar)})
         statenum = StatusEnum.COMPLETED
     else:
         job = qsharp.azure.status(jobid)
         status = job.status.lower()
         statenum = _STATUS_MAP.get(status, StatusEnum.ERROR)
         message = repr(job)
         if statenum is StatusEnum.COMPLETED:
             output = qsharp.azure.output(jobid)
             self._cache[handle].update({"result": _convert_result(output, n_shots)})
     return CircuitStatus(statenum, message)
예제 #11
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
예제 #12
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)
예제 #13
0
def _hex_to_outar(hexes: Sequence[str], width: int) -> OutcomeArray:
    ints = [int(hexst, 16) for hexst in hexes]
    return OutcomeArray.from_ints(ints, width)