def test_snapshot_instruction_from_dict(self): """Test snapshot instruction from dict.""" expected_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), QasmQobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2]), QasmQobjInstruction(name='snapshot', qubits=[1], snapshot_type='statevector', label='my_snap') ]) ] ) qobj_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.1.0', 'header': {}, 'config': {'max_credits': 10, 'memory_slots': 2, 'shots': 1024}, 'experiments': [ {'instructions': [ {'name': 'u1', 'params': [0.4], 'qubits': [1]}, {'name': 'u2', 'params': [0.4, 0.2], 'qubits': [1]}, {'name': 'snapshot', 'qubits': [1], 'snapshot_type': 'statevector', 'label': 'my_snap'} ]} ], } self.assertEqual(expected_qobj, QasmQobj.from_dict(qobj_dict))
def setUp(self): self.valid_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), QasmQobjInstruction(name='u2', qubits=[1], params=[0.4, 0.2]) ]) ] ) self.valid_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.1.0', 'header': {}, 'config': {'max_credits': 10, 'memory_slots': 2, 'shots': 1024}, 'experiments': [ {'instructions': [ {'name': 'u1', 'params': [0.4], 'qubits': [1]}, {'name': 'u2', 'params': [0.4, 0.2], 'qubits': [1]} ]} ], } self.bad_qobj = copy.deepcopy(self.valid_qobj) self.bad_qobj.experiments = []
def run_histogram_test(self, single_experiment, mock_result1, mock_result2, expected_histogram, expected_histogram_prob, expected_memory): self.mock_api.set(mock_result1, mock_result2) jobs = self._basic_job_dictionary measurements = QuantumInspireBackend._collect_measurements( QasmQobjExperiment.from_dict(single_experiment)) user_data = { 'name': 'name', 'memory_slots': 2, 'creg_sizes': [['c1', 2]], 'measurements': measurements } jobs['user_data'] = json.dumps(user_data) self.mock_api.get_jobs_from_project.return_value = [jobs] job = QIJob('backend', '42', self.mock_api) result = self.simulator.get_experiment_results_from_all_jobs(job) number_of_shots = jobs['number_of_shots'] self.assertEqual(1, len(result)) first_experiment = first_item(result) actual = first_experiment.data.counts self.assertDictEqual(expected_histogram, actual) probabilities = first_experiment.data.probabilities self.assertTrue( len(expected_histogram_prob.keys() - probabilities.keys()) == 0) for key in set(probabilities.keys()) & set( expected_histogram_prob.keys()): self.assertTrue( np.isclose(expected_histogram_prob[key], probabilities[key])) self.assertTrue(len(first_experiment.data.memory) == number_of_shots) self.assertListEqual(expected_memory, first_experiment.data.memory)
def test_from_dict_per_class(self): """Test Qobj and its subclass representations given a dictionary.""" test_parameters = { QasmQobj: (self.valid_qobj, self.valid_dict), QasmQobjConfig: (QasmQobjConfig(shots=1, memory_slots=2), { 'shots': 1, 'memory_slots': 2 }), QasmQobjExperiment: (QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]) ]), { 'instructions': [{ 'name': 'u1', 'qubits': [1], 'params': [0.4] }] }), QasmQobjInstruction: (QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]), { 'name': 'u1', 'qubits': [1], 'params': [0.4] }) } for qobj_class, (qobj_item, expected_dict) in test_parameters.items(): with self.subTest(msg=str(qobj_class)): self.assertEqual(qobj_item, qobj_class.from_dict(expected_dict))
def _configure_experiment_los( experiments: List[QasmQobjExperiment], lo_converter: converters.LoConfigConverter, run_config: RunConfig, ): # get per experiment los freq_configs = [lo_converter(lo_dict) for lo_dict in getattr(run_config, "schedule_los", [])] if len(experiments) > 1 and len(freq_configs) not in [0, 1, len(experiments)]: raise QiskitError( "Invalid 'schedule_los' setting specified. If specified, it should be " "either have a single entry to apply the same LOs for each experiment or " "have length equal to the number of experiments." ) if len(freq_configs) > 1: if len(experiments) > 1: for idx, expt in enumerate(experiments): freq_config = freq_configs[idx] expt.config.qubit_lo_freq = freq_config.qubit_lo_freq expt.config.meas_lo_freq = freq_config.meas_lo_freq elif len(experiments) == 1: expt = experiments[0] experiments = [] for freq_config in freq_configs: expt_config = copy.deepcopy(expt.config) expt_config.qubit_lo_freq = freq_config.qubit_lo_freq expt_config.meas_lo_freq = freq_config.meas_lo_freq experiments.append( QasmQobjExperiment( header=expt.header, instructions=expt.instructions, config=expt_config ) ) return experiments
def test_snapshot_instruction_to_dict(self): """Test snapshot instruction to dict.""" valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), QasmQobjInstruction( name="u2", qubits=[1], params=[0.4, 0.2]), QasmQobjInstruction( name="snapshot", qubits=[1], snapshot_type="statevector", label="my_snap", ), ]) ], ) res = valid_qobj.to_dict() expected_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.3.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024 }, "experiments": [{ "instructions": [ { "name": "u1", "params": [0.4], "qubits": [1] }, { "name": "u2", "params": [0.4, 0.2], "qubits": [1] }, { "name": "snapshot", "qubits": [1], "snapshot_type": "statevector", "label": "my_snap", }, ], "config": {}, "header": {}, }], } self.assertEqual(expected_dict, res)
def __init__(self): qobj_id = "test_id" config = QasmQobjConfig(shots=1024, memory_slots=1) header = QobjHeader(backend_name=FakeQasmSimulator().name()) experiments = [ QasmQobjExperiment( instructions=[QasmQobjInstruction(name="barrier", qubits=[1])], header=QobjExperimentHeader(), config=QasmQobjExperimentConfig(seed=123456), ) ] super().__init__(qobj_id=qobj_id, config=config, experiments=experiments, header=header)
def new_fake_qobj(): """Create fake `Qobj` and backend instances.""" backend = FakeQasmSimulator() return QasmQobj( qobj_id='test-id', config=QasmQobjConfig(shots=1024, memory_slots=1, max_credits=100), header=QobjHeader(backend_name=backend.name()), experiments=[ QasmQobjExperiment( instructions=[QasmQobjInstruction(name='barrier', qubits=[1])], header=QobjExperimentHeader(), config=QasmQobjExperimentConfig(seed_simulator=123456)) ])
def setUp(self): super().setUp() self.valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10), experiments=[ QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), QasmQobjInstruction( name="u2", qubits=[1], params=[0.4, 0.2]), ]) ], ) self.valid_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.2.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024 }, "experiments": [{ "instructions": [ { "name": "u1", "params": [0.4], "qubits": [1] }, { "name": "u2", "params": [0.4, 0.2], "qubits": [1] }, ] }], } self.bad_qobj = copy.deepcopy(self.valid_qobj) self.bad_qobj.experiments = []
def test_map_measurements(self): counts = Counter() counts.update({'0000': 10}) counts.update({'0101': 3}) counts.update({'1111': 7}) counts.update({'0101': 5}) counts.update({'1110': 1}) counts.update({'1000': 2}) # move to 01 -> 10 qasm_experiment = QasmQobjExperiment(instructions=[ QasmQobjInstruction(name='measure', qubits=[0], memory=[1]), QasmQobjInstruction(name='measure', qubits=[2], memory=[0]) ]) new_counts = map_measurements(counts, qasm_experiment) self.assertIn('00', new_counts) self.assertIn('10', new_counts) self.assertIn('11', new_counts) self.assertEqual(new_counts['00'], 10 + 3 + 5) self.assertEqual(new_counts['11'], 7 + 1) self.assertEqual(new_counts['10'], 2)
def test_from_dict_per_class(self): """Test Qobj and its subclass representations given a dictionary.""" test_parameters = { QasmQobj: (self.valid_qobj, self.valid_dict), QasmQobjConfig: ( QasmQobjConfig(shots=1, memory_slots=2), { "shots": 1, "memory_slots": 2 }, ), QasmQobjExperiment: ( QasmQobjExperiment(instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]) ]), { "instructions": [{ "name": "u1", "qubits": [1], "params": [0.4] }] }, ), QasmQobjInstruction: ( QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]), { "name": "u1", "qubits": [1], "params": [0.4] }, ), } for qobj_class, (qobj_item, expected_dict) in test_parameters.items(): with self.subTest(msg=str(qobj_class)): self.assertEqual(qobj_item, qobj_class.from_dict(expected_dict))
def assemble_circuits(circuits, qobj_id=None, qobj_header=None, run_config=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits]): circuit(s) to assemble qobj_id (int): identifier for the generated qobj qobj_header (QobjHeader): header to pass to the results run_config (RunConfig): configuration of the runtime environment Returns: QasmQobj: the Qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) # Pack everything into the Qobj experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.control for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: qubit_indices = [ qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs ] instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs ] instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = clbit_indices # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, '_control'): ctrl_reg, ctrl_val = instruction._control mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == ctrl_reg.name: mask |= (1 << clbit_labels.index(clbit)) val |= (((ctrl_val >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete control attribute now that we have replaced it with # the conditional and bfuc del instruction._control instructions.append(instruction) experiments.append( QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots qobj_config.memory_slots = max_memory_slots qobj_config.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
def assemble_circuits(circuits, run_config=None, qobj_header=None, qobj_id=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits] or QuantumCircuit): circuits to assemble run_config (RunConfig): RunConfig object qobj_header (QobjHeader): header to pass to the results qobj_id (int): identifier for the generated qobj Returns: QasmQobj: the Qobj to be run on the backends """ qobj_header = qobj_header or QobjHeader() run_config = run_config or RunConfig() if isinstance(circuits, QuantumCircuit): circuits = [circuits] userconfig = QasmQobjConfig(**run_config.to_dict()) experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) instructions = [] for op_context in circuit.data: op = op_context[0] qargs = op_context[1] cargs = op_context[2] current_instruction = QasmQobjInstruction(name=op.name) if qargs: qubit_indices = [qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs] current_instruction.qubits = qubit_indices if cargs: clbit_indices = [clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs] current_instruction.memory = clbit_indices if op.params: params = list(map(lambda x: x.evalf(), op.params)) params = [sympy.matrix2numpy(x, dtype=complex) if isinstance(x, sympy.Matrix) else x for x in params] if len(params) == 1 and isinstance(params[0], numpy.ndarray): # TODO: Aer expects list of rows for unitary instruction params; # change to matrix in Aer. params = params[0] current_instruction.params = params # TODO: I really dont like this for snapshot. I also think we should change # type to snap_type if op.name == "snapshot": current_instruction.label = str(op.params[0]) current_instruction.type = str(op.params[1]) if op.name == 'unitary': if op._label: current_instruction.label = op._label if op.control: mask = 0 for clbit in clbit_labels: if clbit[0] == op.control[0].name: mask |= (1 << clbit_labels.index(clbit)) current_instruction.conditional = QobjConditional(mask="0x%X" % mask, type='equals', val="0x%X" % op.control[1]) instructions.append(current_instruction) experiments.append(QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots userconfig.memory_slots = max_memory_slots userconfig.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id or str(uuid.uuid4()), config=userconfig, experiments=experiments, header=qobj_header)
def test_gate_calibrations_to_dict(self): """Test gate calibrations to dict.""" pulse_library = [PulseLibraryItem(name='test', samples=[1j, 1j])] valid_qobj = QasmQobj( qobj_id='12345', header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10, pulse_library=pulse_library), experiments=[ QasmQobjExperiment( instructions=[ QasmQobjInstruction(name='u1', qubits=[1], params=[0.4]) ], config=QasmQobjConfig( calibrations=QasmExperimentCalibrations(gates=[ GateCalibration(name='u1', qubits=[1], params=[0.4], instructions=[]) ]))) ]) res = valid_qobj.to_dict(validate=True) expected_dict = { 'qobj_id': '12345', 'type': 'QASM', 'schema_version': '1.3.0', 'header': {}, 'config': { 'max_credits': 10, 'memory_slots': 2, 'shots': 1024, 'pulse_library': [{ 'name': 'test', 'samples': [1j, 1j] }] }, 'experiments': [{ 'instructions': [{ 'name': 'u1', 'params': [0.4], 'qubits': [1] }], 'config': { 'calibrations': { 'gates': [{ 'name': 'u1', 'qubits': [1], 'params': [0.4], 'instructions': [] }] } }, 'header': {} }], } self.assertEqual(expected_dict, res)
def _assemble_circuit( circuit: QuantumCircuit, run_config: RunConfig ) -> Tuple[QasmQobjExperiment, Optional[PulseLibrary]]: """Assemble one circuit. Args: circuit: circuit to assemble run_config: configuration of the runtime environment Returns: One experiment for the QasmQobj, and pulse library for pulse gates (which could be None) Raises: QiskitError: when the circuit has unit other than 'dt'. """ if circuit.unit != "dt": raise QiskitError( "Unable to assemble circuit with unit '{}', which must be 'dt'.". format(circuit.unit)) # header data num_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) num_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size qubit_indices = {qubit: idx for idx, qubit in enumerate(circuit.qubits)} clbit_indices = {clbit: idx for idx, clbit in enumerate(circuit.clbits)} # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit metadata = circuit.metadata if metadata is None: metadata = {} header = QobjExperimentHeader( qubit_labels=qubit_labels, n_qubits=num_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name, global_phase=float(circuit.global_phase), metadata=metadata, ) # TODO: why do we need n_qubits and memory_slots in both the header and the config config = QasmQobjExperimentConfig(n_qubits=num_qubits, memory_slots=memory_slots) calibrations, pulse_library = _assemble_pulse_gates(circuit, run_config) if calibrations: config.calibrations = calibrations # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.condition for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: instruction.qubits = [qubit_indices[qubit] for qubit in qargs] if cargs: instruction.memory = [clbit_indices[clbit] for clbit in cargs] # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = [ clbit_indices[clbit] for clbit in cargs ] # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, "_condition"): ctrl_reg, ctrl_val = instruction._condition mask = 0 val = 0 if isinstance(ctrl_reg, Clbit): mask = 1 << clbit_indices[ctrl_reg] val = (ctrl_val & 1) << clbit_indices[ctrl_reg] else: for clbit in clbit_indices: if clbit in ctrl_reg: mask |= 1 << clbit_indices[clbit] val |= ((ctrl_val >> list(ctrl_reg).index(clbit)) & 1) << clbit_indices[clbit] conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name="bfunc", mask="0x%X" % mask, relation="==", val="0x%X" % val, register=conditional_reg_idx, ) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete condition attribute now that we have replaced it with # the conditional and bfunc del instruction._condition instructions.append(instruction) return ( QasmQobjExperiment(instructions=instructions, header=header, config=config), pulse_library, )
def _assemble_circuit(circuit): # header stuff num_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) num_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit header = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=num_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name, global_phase=circuit.global_phase) # TODO: why do we need n_qubits and memory_slots in both the header and the config config = QasmQobjExperimentConfig(n_qubits=num_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.condition for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: instruction = op_context[0].assemble() # Add register attributes to the instruction qargs = op_context[1] cargs = op_context[2] if qargs: qubit_indices = [ qubit_labels.index([qubit.register.name, qubit.index]) for qubit in qargs ] instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit.register.name, clbit.index]) for clbit in cargs ] instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if instruction.name == "measure" and is_conditional_experiment: instruction.register = clbit_indices # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. if hasattr(instruction, '_condition'): ctrl_reg, ctrl_val = instruction._condition mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == ctrl_reg.name: mask |= (1 << clbit_labels.index(clbit)) val |= (((ctrl_val >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) instruction.conditional = conditional_reg_idx max_conditional_idx += 1 # Delete condition attribute now that we have replaced it with # the conditional and bfuc del instruction._condition instructions.append(instruction) return QasmQobjExperiment(instructions=instructions, header=header, config=config)
def test_gate_calibrations_to_dict(self): """Test gate calibrations to dict.""" pulse_library = [PulseLibraryItem(name="test", samples=[1j, 1j])] valid_qobj = QasmQobj( qobj_id="12345", header=QobjHeader(), config=QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10, pulse_library=pulse_library), experiments=[ QasmQobjExperiment( instructions=[ QasmQobjInstruction(name="u1", qubits=[1], params=[0.4]) ], config=QasmQobjConfig( calibrations=QasmExperimentCalibrations(gates=[ GateCalibration(name="u1", qubits=[1], params=[0.4], instructions=[]) ])), ) ], ) res = valid_qobj.to_dict() expected_dict = { "qobj_id": "12345", "type": "QASM", "schema_version": "1.3.0", "header": {}, "config": { "max_credits": 10, "memory_slots": 2, "shots": 1024, "pulse_library": [{ "name": "test", "samples": [1j, 1j] }], }, "experiments": [{ "instructions": [{ "name": "u1", "params": [0.4], "qubits": [1] }], "config": { "calibrations": { "gates": [{ "name": "u1", "qubits": [1], "params": [0.4], "instructions": [] }] } }, "header": {}, }], } self.assertEqual(expected_dict, res)
def execute_one_qasm(self, buffer, program): qobjStr = self.qobj_compiler.translate(program) import json from qiskit import Aer from qiskit.qobj import (QasmQobj, QobjHeader, QasmQobjInstruction, QasmQobjExperiment, QasmQobjExperimentConfig, QobjExperimentHeader, QasmQobjConfig) qobj_json = json.loads(qobjStr) # Create the Experiments using qiskit data structures exps = [ QasmQobjExperiment( config=QasmQobjExperimentConfig( memory_slots=e['config']['memory_slots'], n_qubits=e['config']['n_qubits']), header=QobjExperimentHeader( clbit_labels=e['header']['clbit_labels'], creg_sizes=e['header']['creg_sizes'], memory_slots=e['header']['memory_slots'], n_qubits=e['header']['n_qubits'], name=e['header']['name'], qreg_sizes=e['header']['qreg_sizes'], qubit_labels=e['header']['qubit_labels']), instructions=[ QasmQobjInstruction( name=i['name'], qubits=i['qubits'], params=(i['params'] if 'params' in i else [])) if i['name'] != 'measure' else QasmQobjInstruction( name=i['name'], qubits=i['qubits'], memory=i['memory']) for i in e['instructions'] ]) for e in qobj_json['qObject']['experiments'] ] qobj = QasmQobj( qobj_id=qobj_json['qObject']['qobj_id'], header=QobjHeader(), config=QasmQobjConfig( shots=self.shots, memory_slots=qobj_json['qObject']['config']['memory_slots']), experiments=exps, shots=self.shots) measures = {} for i in exps[0].instructions: if i.name == "measure": measures[i.memory[0]] = i.qubits[0] backend = Aer.get_backend('qasm_simulator') if self.noise_model is not None: job_sim = backend.run(qobj, noise_model=self.noise_model) else: job_sim = backend.run(qobj) sim_result = job_sim.result() for b, c in sim_result.get_counts().items(): bitstring = b if len(b) < buffer.size(): tmp = ['0' for i in range(buffer.size())] for bit_loc, qubit in measures.items(): tmp[len(tmp) - 1 - qubit] = list(b)[bit_loc] bitstring = ''.join(tmp) buffer.appendMeasurement(bitstring, c)
def assemble_circuits(circuits, qobj_id=None, qobj_header=None, run_config=None): """Assembles a list of circuits into a qobj which can be run on the backend. Args: circuits (list[QuantumCircuits]): circuit(s) to assemble qobj_id (int): identifier for the generated qobj qobj_header (QobjHeader): header to pass to the results run_config (RunConfig): configuration of the runtime environment Returns: QasmQobj: the Qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) # Pack everything into the Qobj experiments = [] max_n_qubits = 0 max_memory_slots = 0 for circuit in circuits: # header stuff n_qubits = 0 memory_slots = 0 qubit_labels = [] clbit_labels = [] qreg_sizes = [] creg_sizes = [] for qreg in circuit.qregs: qreg_sizes.append([qreg.name, qreg.size]) for j in range(qreg.size): qubit_labels.append([qreg.name, j]) n_qubits += qreg.size for creg in circuit.cregs: creg_sizes.append([creg.name, creg.size]) for j in range(creg.size): clbit_labels.append([creg.name, j]) memory_slots += creg.size # TODO: why do we need creq_sizes and qreg_sizes in header # TODO: we need to rethink memory_slots as they are tied to classical bit experimentheader = QobjExperimentHeader(qubit_labels=qubit_labels, n_qubits=n_qubits, qreg_sizes=qreg_sizes, clbit_labels=clbit_labels, memory_slots=memory_slots, creg_sizes=creg_sizes, name=circuit.name) # TODO: why do we need n_qubits and memory_slots in both the header and the config experimentconfig = QasmQobjExperimentConfig(n_qubits=n_qubits, memory_slots=memory_slots) # Convert conditionals from QASM-style (creg ?= int) to qobj-style # (register_bit ?= 1), by assuming device has unlimited register slots # (supported only for simulators). Map all measures to a register matching # their clbit_index, create a new register slot for every conditional gate # and add a bfunc to map the creg=val mask onto the gating register bit. is_conditional_experiment = any(op.control for (op, qargs, cargs) in circuit.data) max_conditional_idx = 0 instructions = [] for op_context in circuit.data: op = op_context[0] qargs = op_context[1] cargs = op_context[2] current_instruction = QasmQobjInstruction(name=op.name) if qargs: qubit_indices = [ qubit_labels.index([qubit[0].name, qubit[1]]) for qubit in qargs ] current_instruction.qubits = qubit_indices if cargs: clbit_indices = [ clbit_labels.index([clbit[0].name, clbit[1]]) for clbit in cargs ] current_instruction.memory = clbit_indices # If the experiment has conditional instructions, assume every # measurement result may be needed for a conditional gate. if op.name == "measure" and is_conditional_experiment: current_instruction.register = clbit_indices if op.params: # Evalute Sympy parameters params = [ x.evalf() if hasattr(x, 'evalf') else x for x in op.params ] params = [ sympy.matrix2numpy(x, dtype=complex) if isinstance( x, sympy.Matrix) else x for x in params ] current_instruction.params = params # TODO: I really dont like this for snapshot. I also think we should change # type to snap_type if op.name == 'snapshot': current_instruction.label = str(op.params[0]) current_instruction.snapshot_type = str(op.params[1]) if op.name == 'unitary': if op._label: current_instruction.label = op._label if op.control: # To convert to a qobj-style conditional, insert a bfunc prior # to the conditional instruction to map the creg ?= val condition # onto a gating register bit. mask = 0 val = 0 for clbit in clbit_labels: if clbit[0] == op.control[0].name: mask |= (1 << clbit_labels.index(clbit)) val |= (((op.control[1] >> clbit[1]) & 1) << clbit_labels.index(clbit)) conditional_reg_idx = memory_slots + max_conditional_idx conversion_bfunc = QasmQobjInstruction( name='bfunc', mask="0x%X" % mask, relation='==', val="0x%X" % val, register=conditional_reg_idx) instructions.append(conversion_bfunc) current_instruction.conditional = conditional_reg_idx max_conditional_idx += 1 instructions.append(current_instruction) experiments.append( QasmQobjExperiment(instructions=instructions, header=experimentheader, config=experimentconfig)) if n_qubits > max_n_qubits: max_n_qubits = n_qubits if memory_slots > max_memory_slots: max_memory_slots = memory_slots qobj_config.memory_slots = max_memory_slots qobj_config.n_qubits = max_n_qubits return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)