예제 #1
0
 def assemble(self):
     """Assemble a QasmQobjInstruction"""
     instruction = QasmQobjInstruction(name=self.name)
     # Evaluate parameters
     if self.params:
         params = [x.evalf(x) if hasattr(x, "evalf") else x for x in self.params]
         instruction.params = params
     # Add placeholder for qarg and carg params
     if self.num_qubits:
         instruction.qubits = list(range(self.num_qubits))
     if self.num_clbits:
         instruction.memory = list(range(self.num_clbits))
     # Add label if defined
     if self.label:
         instruction.label = self.label
     # Add condition parameters for assembler. This is needed to convert
     # to a qobj conditional instruction at assemble time and after
     # conversion will be deleted by the assembler.
     if self.condition:
         instruction._condition = self.condition
     return instruction
예제 #2
0
    def run_experiment(self, experiment, **options):
        """Run an experiment (circuit) and return a single experiment result.
        Args:
            experiment (QobjExperiment): experiment from qobj experiments list
        Returns:
            dict: A dictionary of results.
            dict: A result dictionary
        Raises:
            QrackError: If the number of qubits is too large, or another
                error occurs during execution.
        """
        start = time.time()

        instructions = []
        if isinstance(experiment, QasmQobjExperiment):
            self._number_of_qubits = experiment.header.n_qubits
            self._number_of_clbits = experiment.header.memory_slots
            instructions = experiment.instructions
        elif isinstance(experiment, QuantumCircuit):
            self._number_of_qubits = len(experiment.qubits)
            self._number_of_clbits = len(experiment.clbits)
            for datum in experiment._data:
                qubits = []
                for qubit in datum[1]:
                    qubits.append(experiment.qubits.index(qubit))

                clbits = []
                for clbit in datum[2]:
                    clbits.append(experiment.clbits.index(clbit))

                conditional = None
                condition = datum[0].condition
                if condition is not None:
                    if isinstance(condition[0], Clbit):
                        conditional = experiment.clbits.index(condition[0])
                    else:
                        creg_index = experiment.cregs.index(condition[0])
                        size = experiment.cregs[creg_index].size
                        offset = 0
                        for i in range(creg_index):
                            offset += len(experiment.cregs[i])
                        mask = ((1 << offset) - 1) ^ ((1 <<
                                                       (offset + size)) - 1)
                        val = condition[1]
                        conditional = offset if (
                            size
                            == 1) else QrackQasmQobjInstructionConditional(
                                mask, val)

                instructions.append(
                    QasmQobjInstruction(datum[0].name,
                                        qubits=qubits,
                                        memory=clbits,
                                        condition=condition,
                                        conditional=conditional,
                                        params=datum[0].params))
        else:
            raise QrackError(
                'Unrecognized "run_input" argument specified for run().')

        self._sample_qubits = []
        self._sample_clbits = []
        self._sample_cregbits = []
        self._data = []

        self._sample_measure = True
        shotsPerLoop = self._shots
        shotLoopMax = 1

        is_initializing = True
        boundary_start = -1

        for opcount in range(len(instructions)):
            operation = instructions[opcount]

            if operation.name == 'id' or operation.name == 'barrier':
                continue

            if is_initializing and ((operation.name == 'measure') or
                                    (operation.name == 'reset')):
                continue

            is_initializing = False

            if (operation.name == 'measure') or (operation.name == 'reset'):
                if boundary_start == -1:
                    boundary_start = opcount

            if (boundary_start != -1) and (operation.name != 'measure'):
                shotsPerLoop = 1
                shotLoopMax = self._shots
                self._sample_measure = False
                break

        preamble_memory = 0
        preamble_register = 0
        preamble_sim = None

        if self._sample_measure or boundary_start <= 0:
            boundary_start = 0
            self._sample_measure = True
            shotsPerLoop = self._shots
            shotLoopMax = 1
        else:
            boundary_start -= 1
            if boundary_start > 0:
                self._sim = QrackSimulator(qubitCount=self._number_of_qubits,
                                           **options)
                self._classical_memory = 0
                self._classical_register = 0

                for operation in instructions[:boundary_start]:
                    self._apply_op(operation)

                preamble_memory = self._classical_memory
                preamble_register = self._classical_register
                preamble_sim = self._sim

        for shot in range(shotLoopMax):
            if preamble_sim is None:
                self._sim = QrackSimulator(qubitCount=self._number_of_qubits,
                                           **options)
                self._classical_memory = 0
                self._classical_register = 0
            else:
                self._sim = QrackSimulator(cloneSid=preamble_sim.sid)
                self._classical_memory = preamble_memory
                self._classical_register = preamble_register

            for operation in instructions[boundary_start:]:
                self._apply_op(operation)

            if not self._sample_measure and (len(self._sample_qubits) > 0):
                self._data += [hex(int(bin(self._classical_memory)[2:], 2))]
                self._sample_qubits = []
                self._sample_clbits = []
                self._sample_cregbits = []

        if self._sample_measure and (len(self._sample_qubits) > 0):
            self._data = self._add_sample_measure(self._sample_qubits,
                                                  self._sample_clbits,
                                                  self._shots)

        data = {'counts': dict(Counter(self._data))}
        if isinstance(experiment, QasmQobjExperiment):
            data['memory'] = self._data
            data = QrackExperimentResultData(**data)
        else:
            data = pd.DataFrame(data=data)

        metadata = {}
        if isinstance(experiment,
                      QuantumCircuit) and experiment.metadata is not None:
            metadata = experiment.metadata

        metadata['measure_sampling'] = self._sample_measure

        return QrackExperimentResult(
            shots=self._shots,
            data=data,
            status='DONE',
            success=True,
            header=experiment.header
            if isinstance(experiment, QasmQobjExperiment) else
            QrackExperimentResultHeader(name=experiment.name),
            meta_data=metadata,
            time_taken=(time.time() - start))