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 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
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))