|
43 | 43 | from datetime import datetime
|
44 | 44 | from typing import List, Dict, Any
|
45 | 45 |
|
| 46 | +from qiskit import QuantumCircuit |
| 47 | +from qiskit.circuit import Instruction |
46 | 48 | from qiskit.pulse import ScheduleBlock
|
47 | 49 |
|
48 | 50 | from .calibrations import Calibrations
|
@@ -118,6 +120,14 @@ class CalibrationModelV1:
|
118 | 120 | parameters: List[ParameterModelV1] = field(default_factory=list)
|
119 | 121 | """List of calibrated pulse parameters."""
|
120 | 122 |
|
| 123 | + schedule_free_parameters: QuantumCircuit = field(default_factory=lambda: QuantumCircuit(1)) |
| 124 | + """Placeholder circuit for parameters not associated with a schedule |
| 125 | +
|
| 126 | + The circuit contains placeholder instructions which have the Parameter |
| 127 | + objects attached and operate on the qubits that the parameter is associated |
| 128 | + with in the calibrations. |
| 129 | + """ |
| 130 | + |
121 | 131 | schema_version: str = "1.0"
|
122 | 132 | """Version of this data model. This must be static."""
|
123 | 133 |
|
@@ -177,13 +187,26 @@ def calibrations_to_dict(
|
177 | 187 | sched_obj.metadata.update(qubit_metadata)
|
178 | 188 | sched_entries.append(sched_obj)
|
179 | 189 |
|
| 190 | + max_qubit = max( |
| 191 | + (max(k.qubits or (0,)) for k in cals._parameter_map if k.schedule is None), |
| 192 | + default=0, |
| 193 | + ) |
| 194 | + schedule_free_parameters = QuantumCircuit(max_qubit + 1) |
| 195 | + for sched_key, param in cals._parameter_map.items(): |
| 196 | + if sched_key.schedule is None: |
| 197 | + schedule_free_parameters.append( |
| 198 | + Instruction("parameter_container", len(sched_key.qubits), 0, [param]), |
| 199 | + sched_key.qubits, |
| 200 | + ) |
| 201 | + |
180 | 202 | model = CalibrationModelV1(
|
181 | 203 | backend_name=cals.backend_name,
|
182 | 204 | backend_version=cals.backend_version,
|
183 | 205 | device_coupling_graph=getattr(cals, "_coupling_map"),
|
184 | 206 | control_channel_map=ControlChannelMap(getattr(cals, "_control_channel_map")),
|
185 | 207 | schedules=sched_entries,
|
186 | 208 | parameters=data_entries,
|
| 209 | + schedule_free_parameters=schedule_free_parameters, |
187 | 210 | )
|
188 | 211 |
|
189 | 212 | return asdict(model)
|
@@ -257,6 +280,15 @@ def calibrations_from_dict(
|
257 | 280 | schedule=param.schedule,
|
258 | 281 | update_inst_map=False,
|
259 | 282 | )
|
| 283 | + |
| 284 | + for instruction in model.schedule_free_parameters.data: |
| 285 | + # For some reason, pylint thinks the items in data are tuples instead |
| 286 | + # of CircuitInstruction. Remove the following line if it ever stops |
| 287 | + # thinking that: |
| 288 | + # pylint: disable=no-member |
| 289 | + for param in instruction.operation.params: |
| 290 | + cals._register_parameter(param, instruction.qubits) |
| 291 | + |
260 | 292 | cals.update_inst_map()
|
261 | 293 |
|
262 | 294 | return cals
|
0 commit comments