def _assemble_pulse_gates( circuit: QuantumCircuit, run_config: RunConfig ) -> Tuple[Optional[QasmExperimentCalibrations], Optional[PulseLibrary]]: """Assemble and return the circuit calibrations and associated pulse library, if there are any. The calibrations themselves may reference the pulse library which is returned as a dict. Args: circuit: circuit which may have pulse calibrations run_config: configuration of the runtime environment Returns: The calibrations and pulse library, if there are any """ if not circuit.calibrations: return None, None if not hasattr(run_config, "parametric_pulses"): run_config.parametric_pulses = [] calibrations = [] pulse_library = {} for gate, cals in circuit.calibrations.items(): for (qubits, params), schedule in cals.items(): qobj_instructions, _ = _assemble_schedule( schedule, converters.InstructionToQobjConverter(PulseQobjInstruction), run_config, pulse_library, ) calibrations.append( GateCalibration(str(gate), list(qubits), list(params), qobj_instructions)) return QasmExperimentCalibrations(gates=calibrations), pulse_library
def _extract_common_calibrations( experiments: List[QasmQobjExperiment], ) -> Tuple[List[QasmQobjExperiment], Optional[QasmExperimentCalibrations]]: """Given a list of ``QasmQobjExperiment``s, each of which may have calibrations in their ``config``, collect common calibrations into a global ``QasmExperimentCalibrations`` and delete them from their local experiments. Args: experiments: The list of Qasm experiments that are being assembled into one qobj Returns: The input experiments with modified calibrations, and common calibrations, if there are any """ def index_calibrations() -> Dict[int, List[Tuple[int, GateCalibration]]]: """Map each calibration to all experiments that contain it.""" exp_indices = defaultdict(list) for exp_idx, exp in enumerate(experiments): for gate_cal in exp.config.calibrations.gates: # They must be keyed on the hash or identical cals will be indexed separately exp_indices[hash(gate_cal)].append((exp_idx, gate_cal)) return exp_indices def collect_common_calibrations() -> List[GateCalibration]: """If a gate calibration appears in all experiments, collect it.""" common_calibrations = [] for _, exps_w_cal in exp_indices.items(): if len(exps_w_cal) == len(experiments): _, gate_cal = exps_w_cal[0] common_calibrations.append(gate_cal) return common_calibrations def remove_common_gate_calibrations( exps: List[QasmQobjExperiment]) -> None: """For calibrations that appear in all experiments, remove them from the individual experiment's ``config.calibrations``.""" for _, exps_w_cal in exp_indices.items(): if len(exps_w_cal) == len(exps): for exp_idx, gate_cal in exps_w_cal: exps[exp_idx].config.calibrations.gates.remove(gate_cal) if not (experiments and all( hasattr(exp.config, "calibrations") for exp in experiments)): # No common calibrations return experiments, None exp_indices = index_calibrations() common_calibrations = collect_common_calibrations() remove_common_gate_calibrations(experiments) # Remove the ``calibrations`` attribute if it's now empty for exp in experiments: if not exp.config.calibrations.gates: del exp.config.calibrations return experiments, QasmExperimentCalibrations(gates=common_calibrations)
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 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)