def _format_qobj_str(self, qobj, backend_options, noise_model): """Format qobj string for qiskit aer controller""" # Save original qobj config so we can revert our modification # after execution original_config = qobj.config # Convert to dictionary and add new parameters # from noise model and backend options config = original_config.as_dict() if backend_options is not None: for key, val in backend_options.items(): config[key] = val if "max_memory_mb" not in config: max_memory_mb = int(local_hardware_info()['memory'] * 1024 / 2) config['max_memory_mb'] = max_memory_mb # Add noise model if noise_model is not None: config["noise_model"] = noise_model # Add runtime config config['library_dir'] = self.configuration().library_dir qobj.config = QasmQobjConfig.from_dict(config) # Get the JSON serialized string output = json.dumps(qobj, cls=AerJSONEncoder).encode('UTF-8') # Revert original qobj qobj.config = original_config # Return output return output
def test_qobj_to_circuits_with_nothing(self): """Verify that qobj_to_circuits returns None without any data.""" qobj = QasmQobj(qobj_id='abc123', config=QasmQobjConfig(), header=QobjHeader(), experiments=[]) self.assertIsNone(qobj_to_circuits(qobj))
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 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 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 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 test_submit(self): backend = Mock() backend.run.return_value = '25' api = Mock() job_id = '42' qobj = QasmQobj(qobj_id='id', config=QasmQobjConfig(), experiments=[], header=QobjHeader()) job = QIJob(backend, job_id, api, qobj) job.submit() self.assertEqual('25', job.job_id())
def assemble_circuits(circuits: List[QuantumCircuit], run_config: RunConfig, qobj_id: int, qobj_header: QobjHeader) -> QasmQobj: """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits: circuit(s) to assemble run_config: configuration of the runtime environment qobj_id: identifier for the generated qobj qobj_header: header to pass to the results Returns: The qobj to be run on the backends """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) experiments_and_pulse_libs = parallel_map(_assemble_circuit, circuits, [run_config]) experiments = [] pulse_library = {} for exp, lib in experiments_and_pulse_libs: experiments.append(exp) if lib: pulse_library.update(lib) if pulse_library: qobj_config.pulse_library = [ PulseLibraryItem(name=name, samples=samples) for name, samples in pulse_library.items() ] experiments, calibrations = _extract_common_calibrations(experiments) if calibrations and calibrations.gates: qobj_config.calibrations = calibrations return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
def test_constructor_with_qobj(self): api = Mock() job_id = '42' backend = 'test_backend' qobj = QasmQobj(qobj_id='id', config=QasmQobjConfig(), experiments=[], header=QobjHeader()) job = QIJob(backend, job_id, api, qobj) self.assertIs(qobj, job._qobj) self.assertEqual(job.job_id(), '') self.assertEqual(api, job._api) self.assertIsNone(job.experiments) self.assertEqual(JobStatus.INITIALIZING, job._status)
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 assemble_circuits(circuits, run_config, qobj_id, qobj_header): """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits (list[QuantumCircuit]): 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()) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) experiments = parallel_map(_assemble_circuit, circuits) return QasmQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_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 load_qobj_from_cache(self, circuits, chunk, run_config=None): self.try_loading_cache_from_file() if self.try_reusing_qobjs and self.qobjs is not None and len(self.qobjs) > 0 and len(self.qobjs) <= chunk: self.mappings.insert(chunk, self.mappings[0]) self.qobjs.insert(chunk, copy.deepcopy(self.qobjs[0])) for circ_num, input_circuit in enumerate(circuits): # If there are too few experiments in the cache, try reusing the first experiment. # Only do this for the first chunk. Subsequent chunks should rely on these copies # through the deepcopy above. if self.try_reusing_qobjs and chunk == 0 and circ_num > 0 and len(self.qobjs[chunk].experiments) <= \ circ_num: self.qobjs[0].experiments.insert(circ_num, copy.deepcopy(self.qobjs[0].experiments[0])) self.mappings[0].insert(circ_num, self.mappings[0][0]) # Unroll circuit in case of composite gates raw_gates = [] for gate in input_circuit.data: if isinstance(gate, CompositeGate): raw_gates += gate.instruction_list() else: raw_gates += [gate] self.qobjs[chunk].experiments[circ_num].header.name = input_circuit.name for gate_num, compiled_gate in enumerate(self.qobjs[chunk].experiments[circ_num].instructions): if not hasattr(compiled_gate, 'params') or len(compiled_gate.params) < 1: continue if compiled_gate.name == 'snapshot': continue cache_index = self.mappings[chunk][circ_num][gate_num] (uncompiled_gate, regs, _) = raw_gates[cache_index] # Need the 'getattr' wrapper because measure has no 'params' field and breaks this. if not len(getattr(compiled_gate, 'params', [])) == len(getattr(uncompiled_gate, 'params', [])) or \ not compiled_gate.name == uncompiled_gate.name: raise AquaError('Gate mismatch at gate {0} ({1}, {2} params) of circuit against gate {3} ({4}, ' '{5} params) of cached qobj'.format(cache_index, uncompiled_gate.name, len(uncompiled_gate.params), gate_num, compiled_gate.name, len(compiled_gate.params))) compiled_gate.params = np.array(uncompiled_gate.params, dtype=float).tolist() exec_qobj = copy.copy(self.qobjs[chunk]) if self.skip_qobj_deepcopy: exec_qobj.experiments = self.qobjs[chunk].experiments[0:len(circuits)] else: exec_qobj.experiments = copy.deepcopy(self.qobjs[chunk].experiments[0:len(circuits)]) if run_config is None: run_config = RunConfig(shots=1024, max_credits=10, memory=False) exec_qobj.config = QasmQobjConfig(**run_config.to_dict()) exec_qobj.config.memory_slots = max(experiment.config.memory_slots for experiment in exec_qobj.experiments) exec_qobj.config.n_qubits = max(experiment.config.n_qubits for experiment in exec_qobj.experiments) return exec_qobj
def run_on_backend(backend, qobj, backend_options=None, noise_config=None, skip_qobj_validation=False): """ run on backend """ if skip_qobj_validation: job_id = str(uuid.uuid4()) if is_aer_provider(backend): # pylint: disable=import-outside-toplevel try: from qiskit.providers.aer.aerjob import AerJob except ImportError as ex: raise MissingOptionalLibraryError( libname='qiskit-aer', name='run_on_backend', pip_install='pip install qiskit-aer') from ex temp_backend_options = \ backend_options['backend_options'] if backend_options != {} else None temp_noise_config = noise_config[ 'noise_model'] if noise_config != {} else None # Add new options if temp_backend_options is not None or temp_noise_config is not None: config = qobj.config.to_dict() if temp_backend_options is not None: for key, val in temp_backend_options.items(): config[key] = val if not hasattr( val, 'to_dict') else val.to_dict() if temp_noise_config is not None: config['noise_model'] = temp_noise_config qobj.config = QasmQobjConfig.from_dict(config) job = AerJob(backend, job_id, backend._run, qobj) job.submit() elif is_basicaer_provider(backend): backend._set_options(qobj_config=qobj.config, **backend_options) job = BasicAerJob(backend, job_id, backend._run_job, qobj) job._future = job._executor.submit(job._fn, job._job_id, job._qobj) else: logger.info("Can't skip qobj validation for the %s provider.", backend.provider().__class__.__name__) job = backend.run(qobj, **backend_options, **noise_config) return job else: job = backend.run(qobj, **backend_options, **noise_config) return job
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_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_schedules(schedules, qobj_id=None, qobj_header=None, run_config=None): """Assembles a list of schedules into a qobj which can be run on the backend. Args: schedules (list[Schedule]): schedules 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: PulseQobj: the Qobj to be run on the backends Raises: QiskitError: when invalid schedules or configs are provided """ qobj_config = QasmQobjConfig() if run_config: qobj_config = QasmQobjConfig(**run_config.to_dict()) # Get appropriate convertors instruction_converter = PulseQobjConverter instruction_converter = instruction_converter(PulseQobjInstruction, **run_config.to_dict()) lo_converter = LoConfigConverter(PulseQobjExperimentConfig, run_config.qubit_lo_freq, run_config.meas_lo_freq, **run_config.to_dict()) # Pack everything into the Qobj qobj_schedules = [] user_pulselib = set() for idx, schedule in enumerate(schedules): # instructions qobj_instructions = [] # Instructions are returned as tuple of shifted time and instruction for shift, instruction in list(schedule.flatten()): # TODO: support conditional gate qobj_instructions.append(instruction_converter(shift, instruction)) if isinstance(instruction, PulseInstruction): # add samples to pulse library user_pulselib.add(instruction.command) # experiment header qobj_experiment_header = QobjExperimentHeader( name=schedule.name or 'Experiment-%d' % idx) qobj_schedules.append({ 'header': qobj_experiment_header, 'instructions': qobj_instructions }) # setup pulse_library run_config.pulse_library = [ QobjPulseLibrary(name=pulse.name, samples=pulse.samples) for pulse in user_pulselib ] # create qob experiment field experiments = [] if len(run_config.schedule_los) == 1: lo_dict = run_config.schedule_los.pop() # update global config q_los = lo_converter.get_qubit_los(lo_dict) if q_los: run_config.qubit_lo_freq = q_los m_los = lo_converter.get_meas_los(lo_dict) if m_los: run_config.meas_lo_freq = m_los if run_config.schedule_los: # multiple frequency setups if len(qobj_schedules) == 1: # frequency sweep for lo_dict in run_config.schedule_los: experiments.append( PulseQobjExperiment( instructions=qobj_schedules[0]['instructions'], experimentheader=qobj_schedules[0]['header'], experimentconfig=lo_converter(lo_dict))) elif len(qobj_schedules) == len(run_config.schedule_los): # n:n setup for lo_dict, schedule in zip(run_config.schedule_los, qobj_schedules): experiments.append( PulseQobjExperiment( instructions=schedule['instructions'], experimentheader=schedule['header'], experimentconfig=lo_converter(lo_dict))) else: raise QiskitError( 'Invalid LO setting is specified. ' 'The LO should be configured for each schedule, or ' 'single setup for all schedules (unique), or ' 'multiple setups for a single schedule (frequency sweep),' 'or no LO configured at all.') else: # unique frequency setup for schedule in qobj_schedules: experiments.append( PulseQobjExperiment( instructions=schedule['instructions'], experimentheader=schedule['header'], )) qobj_config = PulseQobjConfig(**run_config.to_dict()) return PulseQobj(qobj_id=qobj_id, config=qobj_config, experiments=experiments, header=qobj_header)
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 test_qasm_obj_config_warns(self): """Test that QasmQobjConfig constructor displays a deprecation warning if max_credits is used""" with self.assertWarns(DeprecationWarning): QasmQobjConfig(shots=1024, memory_slots=2, max_credits=10)
def assemble_circuits(circuits: List[QuantumCircuit], run_config: RunConfig, qobj_id: int, qobj_header: QobjHeader) -> QasmQobj: """Assembles a list of circuits into a qobj that can be run on the backend. Args: circuits: circuit(s) to assemble run_config: configuration of the runtime environment qobj_id: identifier for the generated qobj qobj_header: header to pass to the results Returns: The qobj to be run on the backends """ # assemble the circuit experiments experiments_and_pulse_libs = parallel_map(_assemble_circuit, circuits, [run_config]) experiments = [] pulse_library = {} for exp, lib in experiments_and_pulse_libs: experiments.append(exp) if lib: pulse_library.update(lib) # extract common calibrations experiments, calibrations = _extract_common_calibrations(experiments) # configure LO freqs per circuit lo_converter = converters.LoConfigConverter(QasmQobjExperimentConfig, **run_config.to_dict()) experiments = _configure_experiment_los(experiments, lo_converter, run_config) qobj_config = QasmQobjConfig() if run_config: qobj_config_dict = run_config.to_dict() # remove LO ranges, not needed in qobj qobj_config_dict.pop("qubit_lo_range", None) qobj_config_dict.pop("meas_lo_range", None) # convert LO frequencies to GHz, if they exist if "qubit_lo_freq" in qobj_config_dict: qobj_config_dict["qubit_lo_freq"] = [ freq / 1e9 for freq in qobj_config_dict["qubit_lo_freq"] ] if "meas_lo_freq" in qobj_config_dict: qobj_config_dict["meas_lo_freq"] = [ freq / 1e9 for freq in qobj_config_dict["meas_lo_freq"] ] # override default los if single ``schedule_los`` entry set schedule_los = qobj_config_dict.pop("schedule_los", []) if len(schedule_los) == 1: lo_dict = schedule_los[0] q_los = lo_converter.get_qubit_los(lo_dict) # Hz -> GHz if q_los: qobj_config_dict["qubit_lo_freq"] = [ freq / 1e9 for freq in q_los ] m_los = lo_converter.get_meas_los(lo_dict) if m_los: qobj_config_dict["meas_lo_freq"] = [ freq / 1e9 for freq in m_los ] qobj_config = QasmQobjConfig(**qobj_config_dict) qubit_sizes = [] memory_slot_sizes = [] for circ in circuits: num_qubits = 0 memory_slots = 0 for qreg in circ.qregs: num_qubits += qreg.size for creg in circ.cregs: memory_slots += creg.size qubit_sizes.append(num_qubits) memory_slot_sizes.append(memory_slots) qobj_config.memory_slots = max(memory_slot_sizes) qobj_config.n_qubits = max(qubit_sizes) if pulse_library: qobj_config.pulse_library = [ PulseLibraryItem(name=name, samples=samples) for name, samples in pulse_library.items() ] if calibrations and calibrations.gates: qobj_config.calibrations = calibrations return QasmQobj(qobj_id=qobj_id, config=qobj_config, 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_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 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)
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)