qiskit 1.2.0rc1__cp38-abi3-macosx_10_9_universal2.whl → 1.2.2__cp38-abi3-macosx_10_9_universal2.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +15 -2
- qiskit/circuit/library/basis_change/qft.py +3 -1
- qiskit/circuit/library/data_preparation/initializer.py +5 -2
- qiskit/circuit/library/data_preparation/state_preparation.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +1 -0
- qiskit/circuit/library/standard_gates/__init__.py +32 -25
- qiskit/circuit/quantumcircuit.py +43 -18
- qiskit/compiler/transpiler.py +1 -1
- qiskit/dagcircuit/dagcircuit.py +1 -1
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +9 -1
- qiskit/providers/basic_provider/basic_simulator.py +1 -1
- qiskit/providers/fake_provider/fake_openpulse_2q.py +3 -3
- qiskit/providers/fake_provider/fake_openpulse_3q.py +2 -3
- qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
- qiskit/providers/fake_provider/fake_qasm_backend.py +2 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +434 -18
- qiskit/providers/models/__init__.py +47 -21
- qiskit/pulse/builder.py +16 -7
- qiskit/pulse/instructions/directives.py +5 -0
- qiskit/pulse/library/symbolic_pulses.py +4 -3
- qiskit/pulse/schedule.py +5 -9
- qiskit/pulse/transforms/alignments.py +3 -1
- qiskit/pulse/transforms/dag.py +7 -0
- qiskit/qasm2/parse.py +29 -0
- qiskit/qasm3/exporter.py +20 -7
- qiskit/qpy/__init__.py +1 -1
- qiskit/quantum_info/operators/operator.py +24 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +6 -1
- qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +1 -1
- qiskit/synthesis/linear/cnot_synth.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +2 -1
- qiskit/synthesis/permutation/permutation_full.py +2 -2
- qiskit/synthesis/permutation/permutation_lnn.py +3 -1
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +2 -2
- qiskit/transpiler/__init__.py +6 -1
- qiskit/transpiler/instruction_durations.py +4 -0
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +2 -1
- qiskit/transpiler/passes/calibration/rx_builder.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +7 -1
- qiskit/transpiler/passes/optimization/elide_permutations.py +2 -2
- qiskit/transpiler/passes/optimization/hoare_opt.py +12 -8
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +16 -20
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +9 -3
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +3 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +16 -6
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +1 -1
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +12 -55
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +9 -0
- qiskit/utils/optionals.py +173 -150
- qiskit/visualization/bloch.py +44 -1
- qiskit/visualization/dag_visualization.py +10 -3
- qiskit/visualization/gate_map.py +28 -6
- qiskit/visualization/pass_manager_visualization.py +3 -14
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/METADATA +20 -20
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/RECORD +67 -67
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/WHEEL +1 -1
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/entry_points.txt +0 -0
- {qiskit-1.2.0rc1.dist-info → qiskit-1.2.2.dist-info}/top_level.txt +0 -0
@@ -16,6 +16,7 @@ from __future__ import annotations
|
|
16
16
|
import warnings
|
17
17
|
|
18
18
|
from collections.abc import Iterable
|
19
|
+
from typing import List, Dict, Any, Union
|
19
20
|
import numpy as np
|
20
21
|
|
21
22
|
from qiskit import pulse
|
@@ -35,12 +36,12 @@ from qiskit.transpiler import CouplingMap, Target, InstructionProperties, QubitP
|
|
35
36
|
from qiskit.providers import Options
|
36
37
|
from qiskit.providers.basic_provider import BasicSimulator
|
37
38
|
from qiskit.providers.backend import BackendV2
|
38
|
-
from qiskit.providers.models import (
|
39
|
-
PulseDefaults,
|
40
|
-
Command,
|
41
|
-
)
|
42
|
-
from qiskit.qobj import PulseQobjInstruction, PulseLibraryItem
|
43
39
|
from qiskit.utils import optionals as _optionals
|
40
|
+
from qiskit.providers.models.pulsedefaults import Command
|
41
|
+
from qiskit.qobj.converters.pulse_instruction import QobjToInstructionConverter
|
42
|
+
from qiskit.pulse.calibration_entries import PulseQobjDef
|
43
|
+
from qiskit.providers.models.pulsedefaults import MeasurementKernel, Discriminator
|
44
|
+
from qiskit.qobj.pulse_qobj import QobjMeasurementOption
|
44
45
|
|
45
46
|
# Noise default values/ranges for duration and error of supported
|
46
47
|
# instructions. There are two possible formats:
|
@@ -74,17 +75,432 @@ _QUBIT_PROPERTIES = {
|
|
74
75
|
"frequency": (5e9, 5.5e9),
|
75
76
|
}
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
78
|
+
|
79
|
+
class PulseDefaults:
|
80
|
+
"""Internal - Description of default settings for Pulse systems. These are instructions
|
81
|
+
or settings that
|
82
|
+
may be good starting points for the Pulse user. The user may modify these defaults for custom
|
83
|
+
scheduling.
|
84
|
+
"""
|
85
|
+
|
86
|
+
# Copy from the deprecated from qiskit.providers.models.pulsedefaults.PulseDefaults
|
87
|
+
|
88
|
+
_data = {}
|
89
|
+
|
90
|
+
def __init__(
|
91
|
+
self,
|
92
|
+
qubit_freq_est: List[float],
|
93
|
+
meas_freq_est: List[float],
|
94
|
+
buffer: int,
|
95
|
+
pulse_library: List[PulseLibraryItem],
|
96
|
+
cmd_def: List[Command],
|
97
|
+
meas_kernel: MeasurementKernel = None,
|
98
|
+
discriminator: Discriminator = None,
|
99
|
+
**kwargs: Dict[str, Any],
|
100
|
+
):
|
101
|
+
"""
|
102
|
+
Validate and reformat transport layer inputs to initialize.
|
103
|
+
Args:
|
104
|
+
qubit_freq_est: Estimated qubit frequencies in GHz.
|
105
|
+
meas_freq_est: Estimated measurement cavity frequencies in GHz.
|
106
|
+
buffer: Default buffer time (in units of dt) between pulses.
|
107
|
+
pulse_library: Pulse name and sample definitions.
|
108
|
+
cmd_def: Operation name and definition in terms of Commands.
|
109
|
+
meas_kernel: The measurement kernels
|
110
|
+
discriminator: The discriminators
|
111
|
+
**kwargs: Other attributes for the super class.
|
112
|
+
"""
|
113
|
+
self._data = {}
|
114
|
+
self.buffer = buffer
|
115
|
+
self.qubit_freq_est = [freq * 1e9 for freq in qubit_freq_est]
|
116
|
+
"""Qubit frequencies in Hertz."""
|
117
|
+
self.meas_freq_est = [freq * 1e9 for freq in meas_freq_est]
|
118
|
+
"""Measurement frequencies in Hertz."""
|
119
|
+
self.pulse_library = pulse_library
|
120
|
+
self.cmd_def = cmd_def
|
121
|
+
self.instruction_schedule_map = InstructionScheduleMap()
|
122
|
+
self.converter = QobjToInstructionConverter(pulse_library)
|
123
|
+
|
124
|
+
for inst in cmd_def:
|
125
|
+
entry = PulseQobjDef(converter=self.converter, name=inst.name)
|
126
|
+
entry.define(inst.sequence, user_provided=False)
|
127
|
+
self.instruction_schedule_map._add(
|
128
|
+
instruction_name=inst.name,
|
129
|
+
qubits=tuple(inst.qubits),
|
130
|
+
entry=entry,
|
131
|
+
)
|
132
|
+
|
133
|
+
if meas_kernel is not None:
|
134
|
+
self.meas_kernel = meas_kernel
|
135
|
+
if discriminator is not None:
|
136
|
+
self.discriminator = discriminator
|
137
|
+
|
138
|
+
self._data.update(kwargs)
|
139
|
+
|
140
|
+
def __getattr__(self, name):
|
141
|
+
try:
|
142
|
+
return self._data[name]
|
143
|
+
except KeyError as ex:
|
144
|
+
raise AttributeError(f"Attribute {name} is not defined") from ex
|
145
|
+
|
146
|
+
def to_dict(self):
|
147
|
+
"""Return a dictionary format representation of the PulseDefaults.
|
148
|
+
Returns:
|
149
|
+
dict: The dictionary form of the PulseDefaults.
|
150
|
+
"""
|
151
|
+
out_dict = {
|
152
|
+
"qubit_freq_est": self.qubit_freq_est,
|
153
|
+
"meas_freq_est": self.qubit_freq_est,
|
154
|
+
"buffer": self.buffer,
|
155
|
+
"pulse_library": [x.to_dict() for x in self.pulse_library],
|
156
|
+
"cmd_def": [x.to_dict() for x in self.cmd_def],
|
157
|
+
}
|
158
|
+
if hasattr(self, "meas_kernel"):
|
159
|
+
out_dict["meas_kernel"] = self.meas_kernel.to_dict()
|
160
|
+
if hasattr(self, "discriminator"):
|
161
|
+
out_dict["discriminator"] = self.discriminator.to_dict()
|
162
|
+
for key, value in self.__dict__.items():
|
163
|
+
if key not in [
|
164
|
+
"qubit_freq_est",
|
165
|
+
"meas_freq_est",
|
166
|
+
"buffer",
|
167
|
+
"pulse_library",
|
168
|
+
"cmd_def",
|
169
|
+
"meas_kernel",
|
170
|
+
"discriminator",
|
171
|
+
"converter",
|
172
|
+
"instruction_schedule_map",
|
173
|
+
]:
|
174
|
+
out_dict[key] = value
|
175
|
+
out_dict.update(self._data)
|
176
|
+
|
177
|
+
out_dict["qubit_freq_est"] = [freq * 1e-9 for freq in self.qubit_freq_est]
|
178
|
+
out_dict["meas_freq_est"] = [freq * 1e-9 for freq in self.meas_freq_est]
|
179
|
+
return out_dict
|
180
|
+
|
181
|
+
@classmethod
|
182
|
+
def from_dict(cls, data):
|
183
|
+
"""Create a new PulseDefaults object from a dictionary.
|
184
|
+
|
185
|
+
Args:
|
186
|
+
data (dict): A dictionary representing the PulseDefaults
|
187
|
+
to create. It will be in the same format as output by
|
188
|
+
:meth:`to_dict`.
|
189
|
+
Returns:
|
190
|
+
PulseDefaults: The PulseDefaults from the input dictionary.
|
191
|
+
"""
|
192
|
+
schema = {
|
193
|
+
"pulse_library": PulseLibraryItem, # The class PulseLibraryItem is deprecated
|
194
|
+
"cmd_def": Command,
|
195
|
+
"meas_kernel": MeasurementKernel,
|
196
|
+
"discriminator": Discriminator,
|
197
|
+
}
|
198
|
+
|
199
|
+
# Pulse defaults data is nested dictionary.
|
200
|
+
# To avoid deepcopy and avoid mutating the source object, create new dict here.
|
201
|
+
in_data = {}
|
202
|
+
for key, value in data.items():
|
203
|
+
if key in schema:
|
204
|
+
with warnings.catch_warnings():
|
205
|
+
# The class PulseLibraryItem is deprecated
|
206
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning, module="qiskit")
|
207
|
+
if isinstance(value, list):
|
208
|
+
in_data[key] = list(map(schema[key].from_dict, value))
|
209
|
+
else:
|
210
|
+
in_data[key] = schema[key].from_dict(value)
|
211
|
+
else:
|
212
|
+
in_data[key] = value
|
213
|
+
|
214
|
+
return cls(**in_data)
|
215
|
+
|
216
|
+
def __str__(self):
|
217
|
+
qubit_freqs = [freq / 1e9 for freq in self.qubit_freq_est]
|
218
|
+
meas_freqs = [freq / 1e9 for freq in self.meas_freq_est]
|
219
|
+
qfreq = f"Qubit Frequencies [GHz]\n{qubit_freqs}"
|
220
|
+
mfreq = f"Measurement Frequencies [GHz]\n{meas_freqs} "
|
221
|
+
return f"<{self.__class__.__name__}({str(self.instruction_schedule_map)}{qfreq}\n{mfreq})>"
|
222
|
+
|
223
|
+
|
224
|
+
def _to_complex(value: Union[List[float], complex]) -> complex:
|
225
|
+
"""Convert the input value to type ``complex``.
|
226
|
+
Args:
|
227
|
+
value: Value to be converted.
|
228
|
+
Returns:
|
229
|
+
Input value in ``complex``.
|
230
|
+
Raises:
|
231
|
+
TypeError: If the input value is not in the expected format.
|
232
|
+
"""
|
233
|
+
if isinstance(value, list) and len(value) == 2:
|
234
|
+
return complex(value[0], value[1])
|
235
|
+
elif isinstance(value, complex):
|
236
|
+
return value
|
237
|
+
|
238
|
+
raise TypeError(f"{value} is not in a valid complex number format.")
|
239
|
+
|
240
|
+
|
241
|
+
class PulseLibraryItem:
|
242
|
+
"""INTERNAL - An item in a pulse library."""
|
243
|
+
|
244
|
+
# Copy from the deprecated from qiskit.qobj.PulseLibraryItem
|
245
|
+
def __init__(self, name, samples):
|
246
|
+
"""Instantiate a pulse library item.
|
247
|
+
|
248
|
+
Args:
|
249
|
+
name (str): A name for the pulse.
|
250
|
+
samples (list[complex]): A list of complex values defining pulse
|
251
|
+
shape.
|
252
|
+
"""
|
253
|
+
self.name = name
|
254
|
+
if isinstance(samples[0], list):
|
255
|
+
self.samples = np.array([complex(sample[0], sample[1]) for sample in samples])
|
256
|
+
else:
|
257
|
+
self.samples = samples
|
258
|
+
|
259
|
+
def to_dict(self):
|
260
|
+
"""Return a dictionary format representation of the pulse library item.
|
261
|
+
|
262
|
+
Returns:
|
263
|
+
dict: The dictionary form of the PulseLibraryItem.
|
264
|
+
"""
|
265
|
+
return {"name": self.name, "samples": self.samples}
|
266
|
+
|
267
|
+
@classmethod
|
268
|
+
def from_dict(cls, data):
|
269
|
+
"""Create a new PulseLibraryItem object from a dictionary.
|
270
|
+
|
271
|
+
Args:
|
272
|
+
data (dict): A dictionary for the experiment config
|
273
|
+
|
274
|
+
Returns:
|
275
|
+
PulseLibraryItem: The object from the input dictionary.
|
276
|
+
"""
|
277
|
+
return cls(**data)
|
278
|
+
|
279
|
+
def __repr__(self):
|
280
|
+
return f"PulseLibraryItem({self.name}, {repr(self.samples)})"
|
281
|
+
|
282
|
+
def __str__(self):
|
283
|
+
return f"Pulse Library Item:\n\tname: {self.name}\n\tsamples: {self.samples}"
|
284
|
+
|
285
|
+
def __eq__(self, other):
|
286
|
+
if isinstance(other, PulseLibraryItem):
|
287
|
+
if self.to_dict() == other.to_dict():
|
288
|
+
return True
|
289
|
+
return False
|
290
|
+
|
291
|
+
|
292
|
+
class PulseQobjInstruction:
|
293
|
+
"""Internal - A class representing a single instruction in a PulseQobj Experiment."""
|
294
|
+
|
295
|
+
# Copy from the deprecated from qiskit.qobj.PulseQobjInstruction
|
296
|
+
|
297
|
+
_COMMON_ATTRS = [
|
298
|
+
"ch",
|
299
|
+
"conditional",
|
300
|
+
"val",
|
301
|
+
"phase",
|
302
|
+
"frequency",
|
303
|
+
"duration",
|
304
|
+
"qubits",
|
305
|
+
"memory_slot",
|
306
|
+
"register_slot",
|
307
|
+
"label",
|
308
|
+
"type",
|
309
|
+
"pulse_shape",
|
310
|
+
"parameters",
|
311
|
+
]
|
312
|
+
|
313
|
+
def __init__(
|
314
|
+
self,
|
315
|
+
name,
|
316
|
+
t0,
|
317
|
+
ch=None,
|
318
|
+
conditional=None,
|
319
|
+
val=None,
|
320
|
+
phase=None,
|
321
|
+
duration=None,
|
322
|
+
qubits=None,
|
323
|
+
memory_slot=None,
|
324
|
+
register_slot=None,
|
325
|
+
kernels=None,
|
326
|
+
discriminators=None,
|
327
|
+
label=None,
|
328
|
+
type=None, # pylint: disable=invalid-name,redefined-builtin
|
329
|
+
pulse_shape=None,
|
330
|
+
parameters=None,
|
331
|
+
frequency=None,
|
332
|
+
):
|
333
|
+
"""Instantiate a new PulseQobjInstruction object.
|
334
|
+
|
335
|
+
Args:
|
336
|
+
name (str): The name of the instruction
|
337
|
+
t0 (int): Pulse start time in integer **dt** units.
|
338
|
+
ch (str): The channel to apply the pulse instruction.
|
339
|
+
conditional (int): The register to use for a conditional for this
|
340
|
+
instruction
|
341
|
+
val (complex): Complex value to apply, bounded by an absolute value
|
342
|
+
of 1.
|
343
|
+
phase (float): if a ``fc`` instruction, the frame change phase in
|
344
|
+
radians.
|
345
|
+
frequency (float): if a ``sf`` instruction, the frequency in Hz.
|
346
|
+
duration (int): The duration of the pulse in **dt** units.
|
347
|
+
qubits (list): A list of ``int`` representing the qubits the
|
348
|
+
instruction operates on
|
349
|
+
memory_slot (list): If a ``measure`` instruction this is a list
|
350
|
+
of ``int`` containing the list of memory slots to store the
|
351
|
+
measurement results in (must be the same length as qubits).
|
352
|
+
If a ``bfunc`` instruction this is a single ``int`` of the
|
353
|
+
memory slot to store the boolean function result in.
|
354
|
+
register_slot (list): If a ``measure`` instruction this is a list
|
355
|
+
of ``int`` containing the list of register slots in which to
|
356
|
+
store the measurement results (must be the same length as
|
357
|
+
qubits). If a ``bfunc`` instruction this is a single ``int``
|
358
|
+
of the register slot in which to store the result.
|
359
|
+
kernels (list): List of :class:`QobjMeasurementOption` objects
|
360
|
+
defining the measurement kernels and set of parameters if the
|
361
|
+
measurement level is 1 or 2. Only used for ``acquire``
|
362
|
+
instructions.
|
363
|
+
discriminators (list): A list of :class:`QobjMeasurementOption`
|
364
|
+
used to set the discriminators to be used if the measurement
|
365
|
+
level is 2. Only used for ``acquire`` instructions.
|
366
|
+
label (str): Label of instruction
|
367
|
+
type (str): Type of instruction
|
368
|
+
pulse_shape (str): The shape of the parametric pulse
|
369
|
+
parameters (dict): The parameters for a parametric pulse
|
370
|
+
"""
|
371
|
+
self.name = name
|
372
|
+
self.t0 = t0
|
373
|
+
if ch is not None:
|
374
|
+
self.ch = ch
|
375
|
+
if conditional is not None:
|
376
|
+
self.conditional = conditional
|
377
|
+
if val is not None:
|
378
|
+
self.val = val
|
379
|
+
if phase is not None:
|
380
|
+
self.phase = phase
|
381
|
+
if frequency is not None:
|
382
|
+
self.frequency = frequency
|
383
|
+
if duration is not None:
|
384
|
+
self.duration = duration
|
385
|
+
if qubits is not None:
|
386
|
+
self.qubits = qubits
|
387
|
+
if memory_slot is not None:
|
388
|
+
self.memory_slot = memory_slot
|
389
|
+
if register_slot is not None:
|
390
|
+
self.register_slot = register_slot
|
391
|
+
if kernels is not None:
|
392
|
+
self.kernels = kernels
|
393
|
+
if discriminators is not None:
|
394
|
+
self.discriminators = discriminators
|
395
|
+
if label is not None:
|
396
|
+
self.label = label
|
397
|
+
if type is not None:
|
398
|
+
self.type = type
|
399
|
+
if pulse_shape is not None:
|
400
|
+
self.pulse_shape = pulse_shape
|
401
|
+
if parameters is not None:
|
402
|
+
self.parameters = parameters
|
403
|
+
|
404
|
+
def to_dict(self):
|
405
|
+
"""Return a dictionary format representation of the Instruction.
|
406
|
+
|
407
|
+
Returns:
|
408
|
+
dict: The dictionary form of the PulseQobjInstruction.
|
409
|
+
"""
|
410
|
+
out_dict = {"name": self.name, "t0": self.t0}
|
411
|
+
for attr in self._COMMON_ATTRS:
|
412
|
+
if hasattr(self, attr):
|
413
|
+
out_dict[attr] = getattr(self, attr)
|
414
|
+
if hasattr(self, "kernels"):
|
415
|
+
out_dict["kernels"] = [x.to_dict() for x in self.kernels]
|
416
|
+
if hasattr(self, "discriminators"):
|
417
|
+
out_dict["discriminators"] = [x.to_dict() for x in self.discriminators]
|
418
|
+
return out_dict
|
419
|
+
|
420
|
+
def __repr__(self):
|
421
|
+
out = f'PulseQobjInstruction(name="{self.name}", t0={self.t0}'
|
422
|
+
for attr in self._COMMON_ATTRS:
|
423
|
+
attr_val = getattr(self, attr, None)
|
424
|
+
if attr_val is not None:
|
425
|
+
if isinstance(attr_val, str):
|
426
|
+
out += f', {attr}="{attr_val}"'
|
427
|
+
else:
|
428
|
+
out += f", {attr}={attr_val}"
|
429
|
+
out += ")"
|
430
|
+
return out
|
431
|
+
|
432
|
+
def __str__(self):
|
433
|
+
out = f"Instruction: {self.name}\n"
|
434
|
+
out += f"\t\tt0: {self.t0}\n"
|
435
|
+
for attr in self._COMMON_ATTRS:
|
436
|
+
if hasattr(self, attr):
|
437
|
+
out += f"\t\t{attr}: {getattr(self, attr)}\n"
|
438
|
+
return out
|
439
|
+
|
440
|
+
@classmethod
|
441
|
+
def from_dict(cls, data):
|
442
|
+
"""Create a new PulseQobjExperimentConfig object from a dictionary.
|
443
|
+
|
444
|
+
Args:
|
445
|
+
data (dict): A dictionary for the experiment config
|
446
|
+
|
447
|
+
Returns:
|
448
|
+
PulseQobjInstruction: The object from the input dictionary.
|
449
|
+
"""
|
450
|
+
schema = {
|
451
|
+
"discriminators": QobjMeasurementOption,
|
452
|
+
"kernels": QobjMeasurementOption,
|
453
|
+
}
|
454
|
+
skip = ["t0", "name"]
|
455
|
+
|
456
|
+
# Pulse instruction data is nested dictionary.
|
457
|
+
# To avoid deepcopy and avoid mutating the source object, create new dict here.
|
458
|
+
in_data = {}
|
459
|
+
for key, value in data.items():
|
460
|
+
if key in skip:
|
461
|
+
continue
|
462
|
+
if key == "parameters":
|
463
|
+
# This is flat dictionary of parametric pulse parameters
|
464
|
+
formatted_value = value.copy()
|
465
|
+
if "amp" in formatted_value:
|
466
|
+
formatted_value["amp"] = _to_complex(formatted_value["amp"])
|
467
|
+
in_data[key] = formatted_value
|
468
|
+
continue
|
469
|
+
if key in schema:
|
470
|
+
if isinstance(value, list):
|
471
|
+
in_data[key] = list(map(schema[key].from_dict, value))
|
472
|
+
else:
|
473
|
+
in_data[key] = schema[key].from_dict(value)
|
474
|
+
else:
|
475
|
+
in_data[key] = value
|
476
|
+
|
477
|
+
return cls(data["name"], data["t0"], **in_data)
|
478
|
+
|
479
|
+
def __eq__(self, other):
|
480
|
+
if isinstance(other, PulseQobjInstruction):
|
481
|
+
if self.to_dict() == other.to_dict():
|
482
|
+
return True
|
483
|
+
return False
|
484
|
+
|
485
|
+
|
486
|
+
def _pulse_library():
|
487
|
+
# The number of samples determines the pulse durations of the corresponding
|
488
|
+
# instructions. This default defines pulses with durations in multiples of
|
489
|
+
# 16 dt for consistency with the pulse granularity of real IBM devices, but
|
490
|
+
# keeps the number smaller than what would be realistic for
|
491
|
+
# manageability. If needed, more realistic durations could be added in the
|
492
|
+
# future (order of 160dt for 1q gates, 1760dt for 2q gates and measure).
|
493
|
+
return [
|
494
|
+
PulseLibraryItem(
|
495
|
+
name="pulse_1", samples=np.linspace(0, 1.0, 16, dtype=np.complex128)
|
496
|
+
), # 16dt
|
497
|
+
PulseLibraryItem(
|
498
|
+
name="pulse_2", samples=np.linspace(0, 1.0, 32, dtype=np.complex128)
|
499
|
+
), # 32dt
|
500
|
+
PulseLibraryItem(
|
501
|
+
name="pulse_3", samples=np.linspace(0, 1.0, 64, dtype=np.complex128)
|
502
|
+
), # 64dt
|
503
|
+
]
|
88
504
|
|
89
505
|
|
90
506
|
class GenericBackendV2(BackendV2):
|
@@ -262,7 +678,7 @@ class GenericBackendV2(BackendV2):
|
|
262
678
|
acting on qargs.
|
263
679
|
"""
|
264
680
|
|
265
|
-
pulse_library =
|
681
|
+
pulse_library = _pulse_library()
|
266
682
|
# Note that the calibration pulses are different for
|
267
683
|
# 1q gates vs 2q gates vs measurement instructions.
|
268
684
|
if inst == "measure":
|
@@ -352,7 +768,7 @@ class GenericBackendV2(BackendV2):
|
|
352
768
|
qubit_freq_est=qubit_freq_est,
|
353
769
|
meas_freq_est=meas_freq_est,
|
354
770
|
buffer=0,
|
355
|
-
pulse_library=
|
771
|
+
pulse_library=_pulse_library(),
|
356
772
|
cmd_def=cmd_def,
|
357
773
|
)
|
358
774
|
|
@@ -38,26 +38,52 @@ Classes
|
|
38
38
|
GateProperties
|
39
39
|
Nduv
|
40
40
|
"""
|
41
|
+
# pylint: disable=undefined-all-variable
|
42
|
+
__all__ = [
|
43
|
+
"BackendConfiguration",
|
44
|
+
"PulseBackendConfiguration",
|
45
|
+
"QasmBackendConfiguration",
|
46
|
+
"UchannelLO",
|
47
|
+
"GateConfig",
|
48
|
+
"BackendProperties",
|
49
|
+
"GateProperties",
|
50
|
+
"Nduv",
|
51
|
+
"BackendStatus",
|
52
|
+
"JobStatus",
|
53
|
+
"PulseDefaults",
|
54
|
+
"Command",
|
55
|
+
]
|
56
|
+
|
57
|
+
import importlib
|
41
58
|
import warnings
|
42
59
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
"qiskit.providers.models
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
|
61
|
+
_NAME_MAP = {
|
62
|
+
# public object name mapped to containing module
|
63
|
+
"BackendConfiguration": "qiskit.providers.models.backendconfiguration",
|
64
|
+
"PulseBackendConfiguration": "qiskit.providers.models.backendconfiguration",
|
65
|
+
"QasmBackendConfiguration": "qiskit.providers.models.backendconfiguration",
|
66
|
+
"UchannelLO": "qiskit.providers.models.backendconfiguration",
|
67
|
+
"GateConfig": "qiskit.providers.models.backendconfiguration",
|
68
|
+
"BackendProperties": "qiskit.providers.models.backendproperties",
|
69
|
+
"GateProperties": "qiskit.providers.models.backendproperties",
|
70
|
+
"Nduv": "qiskit.providers.models.backendproperties",
|
71
|
+
"BackendStatus": "qiskit.providers.models.backendstatus",
|
72
|
+
"JobStatus": "qiskit.providers.models.jobstatus",
|
73
|
+
"PulseDefaults": "qiskit.providers.models.pulsedefaults",
|
74
|
+
"Command": "qiskit.providers.models.pulsedefaults",
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
def __getattr__(name):
|
79
|
+
if (module_name := _NAME_MAP.get(name)) is not None:
|
80
|
+
warnings.warn(
|
81
|
+
"qiskit.providers.models is deprecated since Qiskit 1.2 and will be "
|
82
|
+
"removed in Qiskit 2.0. With the removal of Qobj, there is no need for these "
|
83
|
+
"schema-conformant objects. If you still need to use them, it could be because "
|
84
|
+
"you are using a BackendV1, which is also deprecated in favor of BackendV2.",
|
85
|
+
DeprecationWarning,
|
86
|
+
stacklevel=2,
|
87
|
+
)
|
88
|
+
return getattr(importlib.import_module(module_name), name)
|
89
|
+
raise AttributeError(f"module 'qiskit.providers.models' has no attribute '{name}'")
|
qiskit/pulse/builder.py
CHANGED
@@ -137,7 +137,6 @@ In the example below we demonstrate some more features of the pulse builder:
|
|
137
137
|
from qiskit.compiler import schedule
|
138
138
|
|
139
139
|
from qiskit import pulse, QuantumCircuit
|
140
|
-
from qiskit.pulse import library
|
141
140
|
from qiskit.providers.fake_provider import FakeOpenPulse2Q
|
142
141
|
|
143
142
|
backend = FakeOpenPulse2Q()
|
@@ -147,7 +146,7 @@ In the example below we demonstrate some more features of the pulse builder:
|
|
147
146
|
|
148
147
|
with pulse.build(backend) as pulse_prog:
|
149
148
|
# Create a pulse.
|
150
|
-
gaussian_pulse =
|
149
|
+
gaussian_pulse = pulse.Gaussian(10, 1.0, 2)
|
151
150
|
# Get the qubit's corresponding drive channel from the backend.
|
152
151
|
d0 = pulse.drive_channel(0)
|
153
152
|
d1 = pulse.drive_channel(1)
|
@@ -285,7 +284,7 @@ Pulse instructions are available within the builder interface. Here's an example
|
|
285
284
|
d0 = pulse.drive_channel(0)
|
286
285
|
a0 = pulse.acquire_channel(0)
|
287
286
|
|
288
|
-
pulse.play(pulse.
|
287
|
+
pulse.play(pulse.Constant(10, 1.0), d0)
|
289
288
|
pulse.delay(20, d0)
|
290
289
|
pulse.shift_phase(3.14/2, d0)
|
291
290
|
pulse.set_phase(3.14, d0)
|
@@ -293,8 +292,8 @@ Pulse instructions are available within the builder interface. Here's an example
|
|
293
292
|
pulse.set_frequency(5e9, d0)
|
294
293
|
|
295
294
|
with pulse.build() as temp_sched:
|
296
|
-
pulse.play(pulse.
|
297
|
-
pulse.play(pulse.
|
295
|
+
pulse.play(pulse.Gaussian(20, 1.0, 3.0), d0)
|
296
|
+
pulse.play(pulse.Gaussian(20, -1.0, 3.0), d0)
|
298
297
|
|
299
298
|
pulse.call(temp_sched)
|
300
299
|
pulse.acquire(30, a0, pulse.MemorySlot(0))
|
@@ -1327,7 +1326,9 @@ def frequency_offset(
|
|
1327
1326
|
:emphasize-lines: 7, 16
|
1328
1327
|
|
1329
1328
|
from qiskit import pulse
|
1329
|
+
from qiskit.providers.fake_provider import FakeOpenPulse2Q
|
1330
1330
|
|
1331
|
+
backend = FakeOpenPulse2Q()
|
1331
1332
|
d0 = pulse.DriveChannel(0)
|
1332
1333
|
|
1333
1334
|
with pulse.build(backend) as pulse_prog:
|
@@ -1969,19 +1970,23 @@ def barrier(*channels_or_qubits: chans.Channel | int, name: str | None = None):
|
|
1969
1970
|
.. code-block::
|
1970
1971
|
|
1971
1972
|
import math
|
1973
|
+
from qiskit import pulse
|
1974
|
+
from qiskit.providers.fake_provider import FakeOpenPulse2Q
|
1975
|
+
|
1976
|
+
backend = FakeOpenPulse2Q()
|
1972
1977
|
|
1973
1978
|
d0 = pulse.DriveChannel(0)
|
1974
1979
|
|
1975
1980
|
with pulse.build(backend) as pulse_prog:
|
1976
1981
|
with pulse.align_right():
|
1977
|
-
pulse.call(backend.defaults.instruction_schedule_map.get('
|
1982
|
+
pulse.call(backend.defaults().instruction_schedule_map.get('u1', (1,)))
|
1978
1983
|
# Barrier qubit 1 and d0.
|
1979
1984
|
pulse.barrier(1, d0)
|
1980
1985
|
# Due to barrier this will play before the gate on qubit 1.
|
1981
1986
|
pulse.play(pulse.Constant(10, 1.0), d0)
|
1982
1987
|
# This will end at the same time as the pulse above due to
|
1983
1988
|
# the barrier.
|
1984
|
-
pulse.call(backend.defaults.instruction_schedule_map.get('
|
1989
|
+
pulse.call(backend.defaults().instruction_schedule_map.get('u1', (1,)))
|
1985
1990
|
|
1986
1991
|
.. note:: Requires the active builder context to have a backend set if
|
1987
1992
|
qubits are barriered on.
|
@@ -2012,6 +2017,7 @@ def macro(func: Callable):
|
|
2012
2017
|
:include-source:
|
2013
2018
|
|
2014
2019
|
from qiskit import pulse
|
2020
|
+
from qiskit.providers.fake_provider import FakeOpenPulse2Q
|
2015
2021
|
|
2016
2022
|
@pulse.macro
|
2017
2023
|
def measure(qubit: int):
|
@@ -2021,6 +2027,9 @@ def macro(func: Callable):
|
|
2021
2027
|
|
2022
2028
|
return mem_slot
|
2023
2029
|
|
2030
|
+
|
2031
|
+
backend = FakeOpenPulse2Q()
|
2032
|
+
|
2024
2033
|
with pulse.build(backend=backend) as sched:
|
2025
2034
|
mem_slot = measure(0)
|
2026
2035
|
print(f"Qubit measured into {mem_slot}")
|
@@ -72,6 +72,8 @@ class TimeBlockade(Directive):
|
|
72
72
|
|
73
73
|
.. code-block:: python
|
74
74
|
|
75
|
+
from qiskit.pulse import Schedule, Play, Constant, DriveChannel
|
76
|
+
|
75
77
|
schedule = Schedule()
|
76
78
|
schedule.insert(120, Play(Constant(10, 0.1), DriveChannel(0)))
|
77
79
|
|
@@ -79,6 +81,9 @@ class TimeBlockade(Directive):
|
|
79
81
|
|
80
82
|
.. code-block:: python
|
81
83
|
|
84
|
+
from qiskit.pulse import ScheduleBlock, Play, Constant, DriveChannel
|
85
|
+
from qiskit.pulse.instructions import TimeBlockade
|
86
|
+
|
82
87
|
block = ScheduleBlock()
|
83
88
|
block.append(TimeBlockade(120, DriveChannel(0)))
|
84
89
|
block.append(Play(Constant(10, 0.1), DriveChannel(0)))
|
@@ -1773,12 +1773,13 @@ def Square(
|
|
1773
1773
|
is the sign function with the convention :math:`\\text{sign}\\left(0\\right)=1`.
|
1774
1774
|
|
1775
1775
|
Args:
|
1776
|
-
duration: Pulse length in terms of the sampling period
|
1777
|
-
amp: The magnitude of the amplitude of the square wave. Wave range is
|
1776
|
+
duration: Pulse length in terms of the sampling period ``dt``.
|
1777
|
+
amp: The magnitude of the amplitude of the square wave. Wave range is
|
1778
|
+
:math:`\\left[-\\texttt{amp},\\texttt{amp}\\right]`.
|
1778
1779
|
phase: The phase of the square wave (note that this is not equivalent to the angle of
|
1779
1780
|
the complex amplitude).
|
1780
1781
|
freq: The frequency of the square wave, in terms of 1 over sampling period.
|
1781
|
-
If not provided defaults to a single cycle (i.e :math
|
1782
|
+
If not provided defaults to a single cycle (i.e :math:`\\frac{1}{\\text{duration}}`).
|
1782
1783
|
The frequency is limited to the range :math:`\\left(0,0.5\\right]` (the Nyquist frequency).
|
1783
1784
|
angle: The angle in radians of the complex phase factor uniformly
|
1784
1785
|
scaling the pulse. Default value 0.
|