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_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 _maybe_split_qobj_by_gates(qobjs, qobj): if MAX_GATES_PER_JOB is not None: max_gates_per_job = int(MAX_GATES_PER_JOB) total_num_gates = 0 for j in range(len(qobj.experiments)): total_num_gates += len(qobj.experiments[j].instructions) # split by gates if total number of gates in a qobj exceed MAX_GATES_PER_JOB if total_num_gates > max_gates_per_job: qobj_template = QasmQobj(qobj_id=qobj.qobj_id, config=qobj.config, experiments=[], header=qobj.header) temp_qobj = copy.deepcopy(qobj_template) temp_qobj.qobj_id = str(uuid.uuid4()) temp_qobj.experiments = [] num_gates = 0 for i in range(len(qobj.experiments)): num_gates += len(qobj.experiments[i].instructions) if num_gates <= max_gates_per_job: temp_qobj.experiments.append(qobj.experiments[i]) else: qobjs.append(temp_qobj) # Initialize for next temp_qobj temp_qobj = copy.deepcopy(qobj_template) temp_qobj.qobj_id = str(uuid.uuid4()) temp_qobj.experiments.append(qobj.experiments[i]) num_gates = len(qobj.experiments[i].instructions) qobjs.append(temp_qobj) else: qobjs.append(qobj) else: qobjs.append(qobj) return qobjs
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 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 _copy_qobj_for_noise(qobj, max_shot_size, qobj_id): num_shot_jobs, shot_mod = divmod(qobj.config.shots, max_shot_size) qobj_list = [] if shot_mod == 0 and num_shot_jobs == 1: return qobj if shot_mod > 0: qobj.config.shots = shot_mod for experiment in qobj.experiments: _id = str(uuid.uuid4()) experiment.header.metadata["id"] = _id qobj_list.append(qobj) if num_shot_jobs > 1: _qid = qobj_id or str(uuid.uuid4()) _config = copy.copy(qobj.config) setattr(_config, "shots", max_shot_size) experiment_list = [] for experiment in qobj.experiments: _id = str(uuid.uuid4()) for _ in range(num_shot_jobs): cpy_exp = copy.copy(experiment) cpy_exp.header = copy.copy(experiment.header) cpy_exp.header.metadata["id"] = _id experiment_list.append(cpy_exp) qobj_list.append(QasmQobj(_qid, _config, experiment_list, qobj.header)) return qobj_list
def test_measurement_2_qubits_to_1_classical_bit(self): with patch.object(QuantumInspireBackend, "_submit_experiment", return_value=Mock()): api = Mock() project = {'id': 42} api.create_project.return_value = project api.get_jobs_from_project.return_value = [] api.execute_qasm_async.return_value = 42 simulator = QuantumInspireBackend(api, Mock()) instructions = [{ 'name': 'cx', 'qubits': [0, 1] }, { 'memory': [0], 'name': 'measure', 'qubits': [0] }, { 'name': 'x', 'qubits': [0] }, { 'memory': [0], 'name': 'measure', 'qubits': [1] }] experiment = self._basic_experiment_dictionary experiment['instructions'] = instructions qjob_dict = self._basic_qobj_dictionary qjob_dict['experiments'][0] = experiment qobj = QasmQobj.from_dict(qjob_dict) self.assertRaisesRegex( QisKitBackendError, 'Measurement of different qubits to the same classical ' 'register 0 is not supported', simulator.run, 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_for_fsp_no_measurements(self): with patch.object(QuantumInspireBackend, "_submit_experiment", return_value=Mock()) as result_experiment: api = Mock() project = {'id': 42} api.create_project.return_value = project api.get_jobs_from_project.return_value = [] api.execute_qasm_async.return_value = 42 simulator = QuantumInspireBackend(api, Mock()) instructions = [{ 'name': 'cx', 'qubits': [0, 1] }, { 'name': 'x', 'qubits': [0] }] experiment = self._basic_experiment_dictionary experiment['instructions'] = instructions qjob_dict = self._basic_qobj_dictionary qjob_dict['experiments'][0] = experiment qobj = QasmQobj.from_dict(qjob_dict) experiment = qobj.experiments[0] simulator.run(qobj) result_experiment.assert_called_once_with(experiment, 25, project=project, full_state_projection=True)
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 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 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 dict_to_qobj(qobj_dict: Dict) -> Union[QasmQobj, PulseQobj]: """Convert a Qobj in dictionary format to an instance. Args: qobj_dict: Qobj in dictionary format. Returns: The corresponding QasmQobj or PulseQobj instance. """ if qobj_dict['type'] == 'PULSE': _decode_pulse_qobj(qobj_dict) # Convert to proper types. return PulseQobj.from_dict(qobj_dict) return QasmQobj.from_dict(qobj_dict)
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_run_returns_correct_result(self): api = Mock() api.create_project.return_value = {'id': 42} api.get_jobs_from_project.return_value = [] api.execute_qasm_async.return_value = 42 api.get_backend_type_by_name.return_value = {'max_number_of_shots': 4096} simulator = QuantumInspireBackend(api, Mock()) instructions = [{'name': 'cx', 'qubits': [0, 1], 'memory': [0, 1]}, {'name': 'measure', 'qubits': [0], 'memory': [1]}] qobj_dict = self._basic_qobj_dictionary qobj_dict['experiments'][0]['instructions'] = instructions qobj = QasmQobj.from_dict(qobj_dict) job = simulator.run(qobj) self.assertEqual('42', job.job_id())
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 _save_job_data_s3(self, qobj: QasmQobj, s3_bucket: Optional[str] = None, extra_data: Optional[dict] = None) -> AwsSession.S3DestinationFolder: used_s3_bucket: str = s3_bucket or self._provider.get_default_bucket() s3_client = self._provider.get_s3_client() file = f'{self._get_job_data_s3_folder(job_id=qobj.qobj_id)}/qiskit_qobj_data.json' if AWSBackend._exists_file(s3_client, used_s3_bucket, file): raise ValueError(f"An object '{file}' already exists at the bucket {used_s3_bucket}") body = { 'qobj_id': qobj.qobj_id, 'qobj': qobj.to_dict() } if extra_data: body['extra_data'] = extra_data result = s3_client.put_object(Body=json.dumps(body).encode(), Bucket=used_s3_bucket, Key=file) # TODO: error handling return used_s3_bucket, self._get_job_data_s3_folder(job_id=qobj.qobj_id)
def _split_qobj_to_qobjs(qobj, chunk_size): qobjs = [] num_chunks = int(np.ceil(len(qobj.experiments) / chunk_size)) if num_chunks == 1: qobjs = [qobj] else: if isinstance(qobj, QasmQobj): qobj_template = QasmQobj(qobj_id=qobj.qobj_id, config=qobj.config, experiments=[], header=qobj.header) for i in range(num_chunks): temp_qobj = copy.deepcopy(qobj_template) temp_qobj.qobj_id = str(uuid.uuid4()) temp_qobj.experiments = qobj.experiments[i * chunk_size:(i + 1) * chunk_size] qobjs.append(temp_qobj) else: raise AquaError("Only support QasmQobj now.") return qobjs
def test_valid_non_fsp_measurement_qubit_to_classical(self): api = Mock() api.create_project.return_value = {'id': 42} api.get_jobs_from_project.return_value = [] api.execute_qasm_async.return_value = 42 simulator = QuantumInspireBackend(api, Mock()) instructions = [{ 'name': 'h', 'qubits': [0] }, { 'name': 'h', 'qubits': [2] }, { 'memory': [0], 'name': 'measure', 'qubits': [1] }, { 'memory': [1], 'name': 'measure', 'qubits': [0] }, { 'mask': '0x2', 'name': 'bfunc', 'register': 7, 'relation': '==', 'val': '0x2' }, { 'conditional': 7, 'name': 'h', 'qubits': [1] }, { 'memory': [1], 'name': 'measure', 'qubits': [0] }, { 'memory': [0], 'name': 'measure', 'qubits': [1] }] qobj_dict = self._basic_qobj_dictionary qobj_dict['experiments'][0]['instructions'] = instructions qobj = QasmQobj.from_dict(qobj_dict) job = simulator.run(qobj) self.assertEqual('42', job.job_id())
def _load_job_data_s3(self, job_id: str, s3_bucket: Optional[str] = None) -> Tuple[QasmQobj, dict]: used_s3_bucket = s3_bucket or self._provider.get_default_bucket() s3_client = self._provider.get_s3_client() file = f'{self._get_job_data_s3_folder(job_id=job_id)}/qiskit_qobj_data.json' if not AWSBackend._exists_file(s3_client, used_s3_bucket, file): raise ValueError(f"An object '{file}' does not exist in the bucket {used_s3_bucket}") result: dict = s3_client.get_object(Bucket=used_s3_bucket, Key=file) # TODO: error handling streaming_body: StreamingBody = result['Body'] data: bytes = streaming_body.read() stored_experiment_data = json.loads(data.decode()) assert 'qobj' in stored_experiment_data qobj_raw = stored_experiment_data['qobj'] qobj = QasmQobj.from_dict(qobj_raw) extra_data = stored_experiment_data.get('extra_data', {}) return qobj, extra_data
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 dict_to_circuit(dict_: dict) -> QuantumCircuit: qobj = QasmQobj.from_dict(dict_) return disassemble(qobj)[0][0]
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 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: 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, 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 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)