qiskit 2.0.3__cp39-abi3-macosx_11_0_arm64.whl → 2.1.0__cp39-abi3-macosx_11_0_arm64.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/__init__.py +19 -1
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +104 -20
- qiskit/circuit/_add_control.py +57 -31
- qiskit/circuit/_classical_resource_map.py +4 -0
- qiskit/circuit/annotation.py +504 -0
- qiskit/circuit/classical/expr/__init__.py +1 -1
- qiskit/circuit/classical/expr/expr.py +104 -446
- qiskit/circuit/classical/expr/visitors.py +6 -0
- qiskit/circuit/classical/types/types.py +7 -130
- qiskit/circuit/controlflow/box.py +32 -7
- qiskit/circuit/delay.py +11 -9
- qiskit/circuit/library/arithmetic/adders/adder.py +4 -4
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +2 -2
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +8 -4
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
- qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
- qiskit/circuit/library/basis_change/qft.py +2 -2
- qiskit/circuit/library/blueprintcircuit.py +6 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
- qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
- qiskit/circuit/library/fourier_checking.py +2 -2
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
- qiskit/circuit/library/generalized_gates/gms.py +5 -1
- qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +5 -1
- qiskit/circuit/library/generalized_gates/uc.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +21 -2
- qiskit/circuit/library/graph_state.py +2 -2
- qiskit/circuit/library/grover_operator.py +2 -2
- qiskit/circuit/library/hidden_linear_function.py +2 -2
- qiskit/circuit/library/iqp.py +2 -2
- qiskit/circuit/library/n_local/efficient_su2.py +2 -2
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
- qiskit/circuit/library/n_local/n_local.py +4 -3
- qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
- qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
- qiskit/circuit/library/n_local/two_local.py +2 -2
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +3 -2
- qiskit/circuit/library/phase_estimation.py +2 -2
- qiskit/circuit/library/standard_gates/dcx.py +11 -12
- qiskit/circuit/library/standard_gates/ecr.py +21 -24
- qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +22 -45
- qiskit/circuit/library/standard_gates/i.py +1 -1
- qiskit/circuit/library/standard_gates/iswap.py +13 -31
- qiskit/circuit/library/standard_gates/p.py +19 -26
- qiskit/circuit/library/standard_gates/r.py +11 -17
- qiskit/circuit/library/standard_gates/rx.py +21 -45
- qiskit/circuit/library/standard_gates/rxx.py +7 -22
- qiskit/circuit/library/standard_gates/ry.py +21 -39
- qiskit/circuit/library/standard_gates/ryy.py +13 -28
- qiskit/circuit/library/standard_gates/rz.py +18 -35
- qiskit/circuit/library/standard_gates/rzx.py +7 -22
- qiskit/circuit/library/standard_gates/rzz.py +7 -19
- qiskit/circuit/library/standard_gates/s.py +44 -39
- qiskit/circuit/library/standard_gates/swap.py +25 -38
- qiskit/circuit/library/standard_gates/sx.py +34 -41
- qiskit/circuit/library/standard_gates/t.py +18 -27
- qiskit/circuit/library/standard_gates/u.py +8 -24
- qiskit/circuit/library/standard_gates/u1.py +28 -52
- qiskit/circuit/library/standard_gates/u2.py +9 -9
- qiskit/circuit/library/standard_gates/u3.py +24 -40
- qiskit/circuit/library/standard_gates/x.py +190 -336
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
- qiskit/circuit/library/standard_gates/y.py +19 -23
- qiskit/circuit/library/standard_gates/z.py +31 -38
- qiskit/circuit/parameter.py +14 -5
- qiskit/circuit/parameterexpression.py +109 -75
- qiskit/circuit/quantumcircuit.py +172 -99
- qiskit/circuit/quantumcircuitdata.py +1 -0
- qiskit/circuit/random/__init__.py +37 -2
- qiskit/circuit/random/utils.py +445 -56
- qiskit/circuit/tools/pi_check.py +5 -13
- qiskit/compiler/transpiler.py +1 -1
- qiskit/converters/circuit_to_instruction.py +2 -2
- qiskit/dagcircuit/dagnode.py +8 -3
- qiskit/primitives/__init__.py +2 -2
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +0 -3
- qiskit/primitives/containers/observables_array.py +192 -108
- qiskit/primitives/primitive_job.py +29 -10
- qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
- qiskit/qasm3/__init__.py +106 -12
- qiskit/qasm3/ast.py +15 -1
- qiskit/qasm3/exporter.py +59 -36
- qiskit/qasm3/printer.py +12 -0
- qiskit/qpy/__init__.py +182 -6
- qiskit/qpy/binary_io/circuits.py +256 -24
- qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
- qiskit/qpy/binary_io/schedules.py +12 -32
- qiskit/qpy/binary_io/value.py +36 -18
- qiskit/qpy/common.py +11 -3
- qiskit/qpy/formats.py +17 -1
- qiskit/qpy/interface.py +52 -12
- qiskit/qpy/type_keys.py +7 -1
- qiskit/quantum_info/__init__.py +10 -0
- qiskit/quantum_info/operators/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
- qiskit/result/sampled_expval.py +3 -1
- qiskit/synthesis/__init__.py +10 -0
- qiskit/synthesis/arithmetic/__init__.py +1 -1
- qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
- qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +10 -7
- qiskit/synthesis/evolution/qdrift.py +10 -7
- qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
- qiskit/synthesis/multi_controlled/__init__.py +4 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
- qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
- qiskit/synthesis/unitary/qsd.py +80 -9
- qiskit/transpiler/__init__.py +10 -3
- qiskit/transpiler/instruction_durations.py +2 -20
- qiskit/transpiler/passes/__init__.py +5 -2
- qiskit/transpiler/passes/layout/dense_layout.py +26 -6
- qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
- qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
- qiskit/transpiler/passes/layout/vf2_utils.py +10 -0
- qiskit/transpiler/passes/optimization/__init__.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
- qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
- qiskit/transpiler/passes/routing/sabre_swap.py +4 -2
- qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
- qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
- qiskit/transpiler/passes/synthesis/__init__.py +1 -0
- qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +494 -93
- qiskit/transpiler/passes/synthesis/plugin.py +4 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
- qiskit/transpiler/passmanager_config.py +3 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
- qiskit/transpiler/preset_passmanagers/common.py +101 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
- qiskit/transpiler/preset_passmanagers/level3.py +2 -2
- qiskit/transpiler/target.py +15 -2
- qiskit/utils/optionals.py +6 -5
- qiskit/visualization/circuit/_utils.py +5 -3
- qiskit/visualization/circuit/latex.py +9 -2
- qiskit/visualization/circuit/matplotlib.py +26 -4
- qiskit/visualization/circuit/qcstyle.py +9 -157
- qiskit/visualization/dag/__init__.py +13 -0
- qiskit/visualization/dag/dagstyle.py +103 -0
- qiskit/visualization/dag/styles/__init__.py +13 -0
- qiskit/visualization/dag/styles/color.json +10 -0
- qiskit/visualization/dag/styles/plain.json +5 -0
- qiskit/visualization/dag_visualization.py +169 -98
- qiskit/visualization/style.py +223 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/METADATA +7 -6
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/RECORD +178 -169
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/entry_points.txt +6 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
- qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/WHEEL +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/top_level.txt +0 -0
@@ -18,12 +18,10 @@ The purpose of the `_read` and `_load` methods below is just to advance
|
|
18
18
|
the file handle while consuming pulse data."""
|
19
19
|
import json
|
20
20
|
import struct
|
21
|
-
import zlib
|
22
21
|
|
23
22
|
from io import BytesIO
|
24
23
|
|
25
24
|
import numpy as np
|
26
|
-
import symengine as sym
|
27
25
|
|
28
26
|
from qiskit.exceptions import QiskitError
|
29
27
|
from qiskit.qpy import formats, common, type_keys
|
@@ -87,20 +85,6 @@ def _read_discriminator(file_obj, version) -> None:
|
|
87
85
|
value.read_value(file_obj, version, {}) # read name
|
88
86
|
|
89
87
|
|
90
|
-
def _loads_symbolic_expr(expr_bytes, use_symengine=False):
|
91
|
-
if expr_bytes == b"":
|
92
|
-
return None
|
93
|
-
expr_bytes = zlib.decompress(expr_bytes)
|
94
|
-
if use_symengine:
|
95
|
-
return common.load_symengine_payload(expr_bytes)
|
96
|
-
else:
|
97
|
-
from sympy import parse_expr
|
98
|
-
|
99
|
-
expr_txt = expr_bytes.decode(common.ENCODE)
|
100
|
-
expr = parse_expr(expr_txt)
|
101
|
-
return sym.sympify(expr)
|
102
|
-
|
103
|
-
|
104
88
|
def _read_symbolic_pulse(file_obj, version) -> None:
|
105
89
|
make = formats.SYMBOLIC_PULSE._make
|
106
90
|
pack = formats.SYMBOLIC_PULSE_PACK
|
@@ -113,11 +97,9 @@ def _read_symbolic_pulse(file_obj, version) -> None:
|
|
113
97
|
)
|
114
98
|
)
|
115
99
|
pulse_type = file_obj.read(header.type_size).decode(common.ENCODE)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
file_obj.read(header.valid_amp_conditions_size)
|
120
|
-
) # read valid amp conditions
|
100
|
+
file_obj.read(header.envelope_size) # read envelope
|
101
|
+
file_obj.read(header.constraints_size) # read constraints
|
102
|
+
file_obj.read(header.valid_amp_conditions_size) # read valid amp conditions
|
121
103
|
# read parameters
|
122
104
|
common.read_mapping(
|
123
105
|
file_obj,
|
@@ -146,7 +128,7 @@ def _read_symbolic_pulse(file_obj, version) -> None:
|
|
146
128
|
raise NotImplementedError(f"Unknown class '{class_name}'")
|
147
129
|
|
148
130
|
|
149
|
-
def _read_symbolic_pulse_v6(file_obj, version
|
131
|
+
def _read_symbolic_pulse_v6(file_obj, version) -> None:
|
150
132
|
make = formats.SYMBOLIC_PULSE_V2._make
|
151
133
|
pack = formats.SYMBOLIC_PULSE_PACK_V2
|
152
134
|
size = formats.SYMBOLIC_PULSE_SIZE_V2
|
@@ -159,11 +141,9 @@ def _read_symbolic_pulse_v6(file_obj, version, use_symengine) -> None:
|
|
159
141
|
)
|
160
142
|
class_name = file_obj.read(header.class_name_size).decode(common.ENCODE)
|
161
143
|
file_obj.read(header.type_size).decode(common.ENCODE) # read pulse type
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
file_obj.read(header.valid_amp_conditions_size), use_symengine
|
166
|
-
) # read valid_amp_conditions
|
144
|
+
file_obj.read(header.envelope_size) # read envelope
|
145
|
+
file_obj.read(header.constraints_size) # read constraints
|
146
|
+
file_obj.read(header.valid_amp_conditions_size) # read valid_amp_conditions
|
167
147
|
# read parameters
|
168
148
|
common.read_mapping(
|
169
149
|
file_obj,
|
@@ -191,16 +171,14 @@ def _read_alignment_context(file_obj, version) -> None:
|
|
191
171
|
|
192
172
|
|
193
173
|
# pylint: disable=too-many-return-statements
|
194
|
-
def _loads_operand(type_key, data_bytes, version
|
174
|
+
def _loads_operand(type_key, data_bytes, version):
|
195
175
|
if type_key == type_keys.ScheduleOperand.WAVEFORM:
|
196
176
|
return common.data_from_binary(data_bytes, _read_waveform, version=version)
|
197
177
|
if type_key == type_keys.ScheduleOperand.SYMBOLIC_PULSE:
|
198
178
|
if version < 6:
|
199
179
|
return common.data_from_binary(data_bytes, _read_symbolic_pulse, version=version)
|
200
180
|
else:
|
201
|
-
return common.data_from_binary(
|
202
|
-
data_bytes, _read_symbolic_pulse_v6, version=version, use_symengine=use_symengine
|
203
|
-
)
|
181
|
+
return common.data_from_binary(data_bytes, _read_symbolic_pulse_v6, version=version)
|
204
182
|
if type_key == type_keys.ScheduleOperand.CHANNEL:
|
205
183
|
return common.data_from_binary(data_bytes, _read_channel, version=version)
|
206
184
|
if type_key == type_keys.ScheduleOperand.OPERAND_STR:
|
@@ -229,7 +207,9 @@ def _read_element(file_obj, version, metadata_deserializer, use_symengine) -> No
|
|
229
207
|
|
230
208
|
# read operands
|
231
209
|
common.read_sequence(
|
232
|
-
file_obj,
|
210
|
+
file_obj,
|
211
|
+
deserializer=_loads_operand,
|
212
|
+
version=version,
|
233
213
|
)
|
234
214
|
# read name
|
235
215
|
value.read_value(file_obj, version, {})
|
qiskit/qpy/binary_io/value.py
CHANGED
@@ -20,8 +20,6 @@ import struct
|
|
20
20
|
import uuid
|
21
21
|
|
22
22
|
import numpy as np
|
23
|
-
import symengine
|
24
|
-
|
25
23
|
|
26
24
|
from qiskit.circuit import CASE_DEFAULT, Clbit, ClassicalRegister, Duration
|
27
25
|
from qiskit.circuit.classical import expr, types
|
@@ -124,7 +122,10 @@ def _encode_replay_entry(inst, file_obj, version, r_side=False):
|
|
124
122
|
|
125
123
|
def _encode_replay_subs(subs, file_obj, version):
|
126
124
|
with io.BytesIO() as mapping_buf:
|
127
|
-
|
125
|
+
if version < 15:
|
126
|
+
subs_dict = {k.name: v for k, v in subs.binds.items()}
|
127
|
+
else:
|
128
|
+
subs_dict = {k.uuid.bytes: v for k, v in subs.binds.items()}
|
128
129
|
common.write_mapping(
|
129
130
|
mapping_buf, mapping=subs_dict, serializer=dumps_value, version=version
|
130
131
|
)
|
@@ -459,14 +460,21 @@ def _read_parameter_vec(file_obj, vectors):
|
|
459
460
|
file_obj.read(formats.PARAMETER_VECTOR_ELEMENT_SIZE),
|
460
461
|
),
|
461
462
|
)
|
462
|
-
|
463
|
+
# Starting in version 15, the parameter vector root uuid
|
464
|
+
# is used as a key instead of the parameter name.
|
465
|
+
root_uuid_int = uuid.UUID(bytes=data.uuid).int - data.index
|
466
|
+
root_uuid = uuid.UUID(int=root_uuid_int)
|
463
467
|
name = file_obj.read(data.vector_name_size).decode(common.ENCODE)
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
468
|
+
|
469
|
+
if root_uuid not in vectors:
|
470
|
+
vectors[root_uuid] = (ParameterVector(name, data.vector_size), set())
|
471
|
+
vector = vectors[root_uuid][0]
|
472
|
+
|
473
|
+
if vector[data.index].uuid != root_uuid:
|
474
|
+
vectors[root_uuid][1].add(data.index)
|
475
|
+
vector._params[data.index] = ParameterVectorElement(
|
476
|
+
vector, data.index, uuid=uuid.UUID(int=root_uuid_int + data.index)
|
477
|
+
)
|
470
478
|
return vector[data.index]
|
471
479
|
|
472
480
|
|
@@ -476,7 +484,7 @@ def _read_parameter_expression(file_obj):
|
|
476
484
|
)
|
477
485
|
|
478
486
|
sympy_str = file_obj.read(data.expr_size).decode(common.ENCODE)
|
479
|
-
expr_ =
|
487
|
+
expr_ = parse_sympy_repr(sympy_str)
|
480
488
|
symbol_map = {}
|
481
489
|
for _ in range(data.map_elements):
|
482
490
|
elem_data = formats.PARAM_EXPR_MAP_ELEM(
|
@@ -503,7 +511,7 @@ def _read_parameter_expression(file_obj):
|
|
503
511
|
raise exceptions.QpyError(f"Invalid parameter expression map type: {elem_key}")
|
504
512
|
symbol_map[symbol] = value
|
505
513
|
|
506
|
-
return ParameterExpression(symbol_map, expr_)
|
514
|
+
return ParameterExpression(symbol_map, str(expr_))
|
507
515
|
|
508
516
|
|
509
517
|
def _read_parameter_expression_v3(file_obj, vectors, use_symengine):
|
@@ -516,7 +524,7 @@ def _read_parameter_expression_v3(file_obj, vectors, use_symengine):
|
|
516
524
|
expr_ = common.load_symengine_payload(payload)
|
517
525
|
else:
|
518
526
|
sympy_str = payload.decode(common.ENCODE)
|
519
|
-
expr_ =
|
527
|
+
expr_ = parse_sympy_repr(sympy_str)
|
520
528
|
|
521
529
|
symbol_map = {}
|
522
530
|
for _ in range(data.map_elements):
|
@@ -556,7 +564,7 @@ def _read_parameter_expression_v3(file_obj, vectors, use_symengine):
|
|
556
564
|
raise exceptions.QpyError(f"Invalid parameter expression map type: {elem_key}")
|
557
565
|
symbol_map[symbol] = value
|
558
566
|
|
559
|
-
return ParameterExpression(symbol_map, expr_)
|
567
|
+
return ParameterExpression(symbol_map, str(expr_))
|
560
568
|
|
561
569
|
|
562
570
|
def _read_parameter_expression_v13(file_obj, vectors, version):
|
@@ -641,9 +649,16 @@ def _read_parameter_expr_v13(buf, symbol_map, version, vectors):
|
|
641
649
|
subs_map_data = buf.read(size)
|
642
650
|
with io.BytesIO(subs_map_data) as mapping_buf:
|
643
651
|
mapping = common.read_mapping(
|
644
|
-
mapping_buf,
|
652
|
+
mapping_buf,
|
653
|
+
deserializer=loads_value,
|
654
|
+
version=version,
|
655
|
+
vectors=vectors,
|
645
656
|
)
|
646
|
-
|
657
|
+
# Starting in version 15, the uuid is used instead of the name
|
658
|
+
if version < 15:
|
659
|
+
stack.append({name_map[k]: v for k, v in mapping.items()})
|
660
|
+
else:
|
661
|
+
stack.append({param_uuid_map[k]: v for k, v in mapping.items()})
|
647
662
|
else:
|
648
663
|
raise exceptions.QpyError(
|
649
664
|
"Unknown ParameterExpression operation type {expression_data.LHS_TYPE}"
|
@@ -1067,7 +1082,6 @@ def loads_value(
|
|
1067
1082
|
before setting this option, as it will be required by qpy to deserialize the payload.
|
1068
1083
|
standalone_vars (Sequence[Var]): standalone :class:`.expr.Var` nodes in the order that they
|
1069
1084
|
were declared by the circuit header.
|
1070
|
-
|
1071
1085
|
Returns:
|
1072
1086
|
any: Deserialized value object.
|
1073
1087
|
|
@@ -1094,7 +1108,11 @@ def loads_value(
|
|
1094
1108
|
if type_key == type_keys.Value.CASE_DEFAULT:
|
1095
1109
|
return CASE_DEFAULT
|
1096
1110
|
if type_key == type_keys.Value.PARAMETER_VECTOR:
|
1097
|
-
return common.data_from_binary(
|
1111
|
+
return common.data_from_binary(
|
1112
|
+
binary_data,
|
1113
|
+
_read_parameter_vec,
|
1114
|
+
vectors=vectors,
|
1115
|
+
)
|
1098
1116
|
if type_key == type_keys.Value.PARAMETER:
|
1099
1117
|
return common.data_from_binary(binary_data, _read_parameter)
|
1100
1118
|
if type_key == type_keys.Value.PARAMETER_EXPRESSION:
|
qiskit/qpy/common.py
CHANGED
@@ -17,12 +17,13 @@ Common functions across several serialization and deserialization modules.
|
|
17
17
|
|
18
18
|
import io
|
19
19
|
import struct
|
20
|
+
import uuid
|
20
21
|
|
21
22
|
from qiskit.utils.optionals import HAS_SYMENGINE
|
22
23
|
|
23
24
|
from qiskit.qpy import formats, exceptions
|
24
25
|
|
25
|
-
QPY_VERSION =
|
26
|
+
QPY_VERSION = 15
|
26
27
|
QPY_COMPATIBILITY_VERSION = 13
|
27
28
|
ENCODE = "utf8"
|
28
29
|
|
@@ -95,7 +96,11 @@ def read_mapping(file_obj, deserializer, **kwargs):
|
|
95
96
|
map_header = formats.MAP_ITEM._make(
|
96
97
|
struct.unpack(formats.MAP_ITEM_PACK, file_obj.read(formats.MAP_ITEM_SIZE))
|
97
98
|
)
|
98
|
-
|
99
|
+
if kwargs.get("version", 15) < 15:
|
100
|
+
key = file_obj.read(map_header.key_size).decode(ENCODE)
|
101
|
+
else:
|
102
|
+
key = uuid.UUID(bytes=file_obj.read(map_header.key_size))
|
103
|
+
|
99
104
|
datum = deserializer(map_header.type, file_obj.read(map_header.size), **kwargs)
|
100
105
|
mapping[key] = datum
|
101
106
|
|
@@ -167,7 +172,10 @@ def write_mapping(file_obj, mapping, serializer, **kwargs):
|
|
167
172
|
|
168
173
|
file_obj.write(struct.pack(formats.SEQUENCE_PACK, num_elements))
|
169
174
|
for key, datum in mapping.items():
|
170
|
-
|
175
|
+
if kwargs.get("version", 15) < 15:
|
176
|
+
key_bytes = key.encode(ENCODE)
|
177
|
+
else:
|
178
|
+
key_bytes = key
|
171
179
|
type_key, datum_bytes = serializer(datum, **kwargs)
|
172
180
|
item_header = struct.pack(formats.MAP_ITEM_PACK, len(key_bytes), type_key, len(datum_bytes))
|
173
181
|
file_obj.write(item_header)
|
qiskit/qpy/formats.py
CHANGED
@@ -128,7 +128,7 @@ CIRCUIT_INSTRUCTION_V2 = namedtuple(
|
|
128
128
|
"num_parameters",
|
129
129
|
"num_qargs",
|
130
130
|
"num_cargs",
|
131
|
-
"
|
131
|
+
"extras_key",
|
132
132
|
"condition_register_size",
|
133
133
|
"condition_value",
|
134
134
|
"num_ctrl_qubits",
|
@@ -144,6 +144,22 @@ CIRCUIT_INSTRUCTION_ARG = namedtuple("CIRCUIT_INSTRUCTION_ARG", ["type", "size"]
|
|
144
144
|
CIRCUIT_INSTRUCTION_ARG_PACK = "!1cI"
|
145
145
|
CIRCUIT_INSTRUCTION_ARG_SIZE = struct.calcsize(CIRCUIT_INSTRUCTION_ARG_PACK)
|
146
146
|
|
147
|
+
ANNOTATION_HEADER_STATIC = namedtuple("ANNOTATION_HEADER_STATIC", ["num_namespaces"])
|
148
|
+
ANNOTATION_HEADER_STATIC_PACK = "!I"
|
149
|
+
ANNOTATION_HEADER_STATIC_SIZE = struct.calcsize(ANNOTATION_HEADER_STATIC_PACK)
|
150
|
+
|
151
|
+
ANNOTATION_STATE_HEADER = namedtuple("ANNOTATION_STATE_HEADER", ["namespace_size", "state_size"])
|
152
|
+
ANNOTATION_STATE_HEADER_PACK = "!IQ"
|
153
|
+
ANNOTATION_STATE_HEADER_SIZE = struct.calcsize(ANNOTATION_STATE_HEADER_PACK)
|
154
|
+
|
155
|
+
INSTRUCTION_ANNOTATIONS_HEADER = namedtuple("INSTRUCTION_ANNOTATIONS_HEADER", ["num_annotations"])
|
156
|
+
INSTRUCTION_ANNOTATIONS_HEADER_PACK = "!I"
|
157
|
+
INSTRUCTION_ANNOTATIONS_HEADER_SIZE = struct.calcsize(INSTRUCTION_ANNOTATIONS_HEADER_PACK)
|
158
|
+
|
159
|
+
INSTRUCTION_ANNOTATION = namedtuple("INSTRUCTION_ANNOTATION", ["namespace_index", "payload_size"])
|
160
|
+
INSTRUCTION_ANNOTATION_PACK = "!IQ"
|
161
|
+
INSTRUCTION_ANNOTATION_SIZE = struct.calcsize(INSTRUCTION_ANNOTATION_PACK)
|
162
|
+
|
147
163
|
# SparsePauliOp List
|
148
164
|
SPARSE_PAULI_OP_LIST_ELEM = namedtuple("SPARSE_PAULI_OP_LIST_ELEMENT", ["size"])
|
149
165
|
SPARSE_PAULI_OP_LIST_ELEM_PACK = "!Q"
|
qiskit/qpy/interface.py
CHANGED
@@ -15,8 +15,8 @@
|
|
15
15
|
from __future__ import annotations
|
16
16
|
|
17
17
|
from json import JSONEncoder, JSONDecoder
|
18
|
-
from typing import Union, List, BinaryIO, Type, Optional
|
19
|
-
from collections.abc import Iterable
|
18
|
+
from typing import Union, List, BinaryIO, Type, Optional, Callable, TYPE_CHECKING
|
19
|
+
from collections.abc import Iterable, Mapping
|
20
20
|
import struct
|
21
21
|
import warnings
|
22
22
|
import re
|
@@ -27,6 +27,9 @@ from qiskit.qpy import formats, common, binary_io, type_keys
|
|
27
27
|
from qiskit.qpy.exceptions import QpyError
|
28
28
|
from qiskit.version import __version__
|
29
29
|
|
30
|
+
if TYPE_CHECKING:
|
31
|
+
from qiskit.circuit import annotation
|
32
|
+
|
30
33
|
|
31
34
|
# pylint: disable=invalid-name
|
32
35
|
QPY_SUPPORTED_TYPES = QuantumCircuit
|
@@ -78,6 +81,7 @@ def dump(
|
|
78
81
|
metadata_serializer: Optional[Type[JSONEncoder]] = None,
|
79
82
|
use_symengine: bool = False,
|
80
83
|
version: int = common.QPY_VERSION,
|
84
|
+
annotation_factories: Optional[Mapping[str, Callable[[], annotation.QPYSerializer]]] = None,
|
81
85
|
):
|
82
86
|
"""Write QPY binary data to a file
|
83
87
|
|
@@ -152,6 +156,11 @@ def dump(
|
|
152
156
|
QPY files containing ``symengine``-serialized :class:`.ParameterExpression` objects
|
153
157
|
unless the version of ``symengine`` used between the loading and generating
|
154
158
|
environments matches.
|
159
|
+
annotation_factories: Mapping of namespaces to functions that create new instances of
|
160
|
+
:class:`.annotation.QPUSerializer`, for handling the dumping of custom
|
161
|
+
:class:`.Annotation` objects. The subsequent call to :func:`load` will need to use
|
162
|
+
similar serializer objects, that understand the custom output format of those
|
163
|
+
serializers.
|
155
164
|
|
156
165
|
|
157
166
|
Raises:
|
@@ -166,9 +175,6 @@ def dump(
|
|
166
175
|
if not issubclass(type(program), QuantumCircuit):
|
167
176
|
raise TypeError(f"'{type(program)}' is not a supported data type.")
|
168
177
|
|
169
|
-
type_key = type_keys.Program.CIRCUIT
|
170
|
-
writer = binary_io.write_circuit
|
171
|
-
|
172
178
|
if version is None:
|
173
179
|
version = common.QPY_VERSION
|
174
180
|
elif common.QPY_COMPATIBILITY_VERSION > version or version > common.QPY_VERSION:
|
@@ -192,21 +198,23 @@ def dump(
|
|
192
198
|
encoding,
|
193
199
|
)
|
194
200
|
file_obj.write(header)
|
195
|
-
common.write_type_key(file_obj,
|
201
|
+
common.write_type_key(file_obj, type_keys.Program.CIRCUIT)
|
196
202
|
|
197
203
|
for program in programs:
|
198
|
-
|
204
|
+
binary_io.write_circuit(
|
199
205
|
file_obj,
|
200
206
|
program,
|
201
207
|
metadata_serializer=metadata_serializer,
|
202
208
|
use_symengine=use_symengine,
|
203
209
|
version=version,
|
210
|
+
annotation_factories=annotation_factories,
|
204
211
|
)
|
205
212
|
|
206
213
|
|
207
214
|
def load(
|
208
215
|
file_obj: BinaryIO,
|
209
216
|
metadata_deserializer: Optional[Type[JSONDecoder]] = None,
|
217
|
+
annotation_factories: Optional[Mapping[str, Callable[[], annotation.QPYSerializer]]] = None,
|
210
218
|
) -> List[QPY_SUPPORTED_TYPES]:
|
211
219
|
"""Load a QPY binary file
|
212
220
|
|
@@ -244,6 +252,9 @@ def load(
|
|
244
252
|
If this is not specified the circuit metadata will
|
245
253
|
be parsed as JSON with the stdlib ``json.load()`` function using
|
246
254
|
the default ``JSONDecoder`` class.
|
255
|
+
annotation_factories: Mapping of namespaces to functions that create new instances of
|
256
|
+
:class:`.annotation.QPUSerializer`, for handling the loading of custom
|
257
|
+
:class:`.Annotation` objects.
|
247
258
|
|
248
259
|
Returns:
|
249
260
|
The list of Qiskit programs contained in the QPY data.
|
@@ -316,14 +327,12 @@ def load(
|
|
316
327
|
else:
|
317
328
|
type_key = common.read_type_key(file_obj)
|
318
329
|
|
319
|
-
if type_key == type_keys.Program.
|
320
|
-
loader = binary_io.read_circuit
|
321
|
-
elif type_key == type_keys.Program.SCHEDULE_BLOCK:
|
330
|
+
if type_key == type_keys.Program.SCHEDULE_BLOCK:
|
322
331
|
raise QpyError(
|
323
332
|
"Payloads of type `ScheduleBlock` cannot be loaded as of Qiskit 2.0. "
|
324
333
|
"Use an earlier version of Qiskit if you want to load `ScheduleBlock` payloads."
|
325
334
|
)
|
326
|
-
|
335
|
+
if type_key != type_keys.Program.CIRCUIT:
|
327
336
|
raise TypeError(f"Invalid payload format data kind '{type_key}'.")
|
328
337
|
|
329
338
|
if data.qpy_version < 10:
|
@@ -334,11 +343,42 @@ def load(
|
|
334
343
|
programs = []
|
335
344
|
for _ in range(data.num_programs):
|
336
345
|
programs.append(
|
337
|
-
|
346
|
+
binary_io.read_circuit(
|
338
347
|
file_obj,
|
339
348
|
data.qpy_version,
|
340
349
|
metadata_deserializer=metadata_deserializer,
|
341
350
|
use_symengine=use_symengine,
|
351
|
+
annotation_factories=annotation_factories,
|
342
352
|
)
|
343
353
|
)
|
344
354
|
return programs
|
355
|
+
|
356
|
+
|
357
|
+
def get_qpy_version(
|
358
|
+
file_obj: BinaryIO,
|
359
|
+
) -> int:
|
360
|
+
"""This function identifies the QPY version of the file.
|
361
|
+
|
362
|
+
This function will read the header of ``file_obj`` and will
|
363
|
+
return the QPY format version. It will **not** advance the
|
364
|
+
cursor of ``file_obj``. If you are using this for a subsequent
|
365
|
+
read, such as to call :func:`.load`, you can pass ``file_obj``
|
366
|
+
directly. For example::
|
367
|
+
|
368
|
+
from qiskit import qpy
|
369
|
+
|
370
|
+
qpy_version = qpy.get_qpy_version(qpy_file)
|
371
|
+
if qpy_version > 12:
|
372
|
+
qpy.load(qpy_file)
|
373
|
+
|
374
|
+
Args:
|
375
|
+
file_obj: A file like object that contains the QPY binary
|
376
|
+
data for a circuit.
|
377
|
+
|
378
|
+
Returns:
|
379
|
+
The QPY version of the specified file.
|
380
|
+
"""
|
381
|
+
|
382
|
+
version = struct.unpack("!6sB", file_obj.read(7))[1]
|
383
|
+
file_obj.seek(-7, 1)
|
384
|
+
return version
|
qiskit/qpy/type_keys.py
CHANGED
@@ -18,7 +18,7 @@ QPY Type keys for several namespace.
|
|
18
18
|
|
19
19
|
import uuid
|
20
20
|
from abc import abstractmethod
|
21
|
-
from enum import Enum, IntEnum
|
21
|
+
from enum import Enum, IntEnum, IntFlag
|
22
22
|
|
23
23
|
import numpy as np
|
24
24
|
|
@@ -138,6 +138,12 @@ class Condition(IntEnum):
|
|
138
138
|
EXPRESSION = 2
|
139
139
|
|
140
140
|
|
141
|
+
class InstructionExtraFlags(IntFlag):
|
142
|
+
"""If an instruction has extra payloads associated with it."""
|
143
|
+
|
144
|
+
HAS_ANNOTATIONS = 0b1000_0000
|
145
|
+
|
146
|
+
|
141
147
|
class Container(TypeKeyBase):
|
142
148
|
"""Type key enum for container-like object."""
|
143
149
|
|
qiskit/quantum_info/__init__.py
CHANGED
@@ -30,9 +30,13 @@ Operators
|
|
30
30
|
ScalarOp
|
31
31
|
SparseObservable
|
32
32
|
SparsePauliOp
|
33
|
+
PauliLindbladMap
|
34
|
+
QubitSparsePauli
|
35
|
+
QubitSparsePauliList
|
33
36
|
CNOTDihedral
|
34
37
|
PauliList
|
35
38
|
pauli_basis
|
39
|
+
get_clifford_gate_names
|
36
40
|
|
37
41
|
.. _quantum_info_states:
|
38
42
|
|
@@ -115,6 +119,11 @@ Analysis
|
|
115
119
|
|
116
120
|
from __future__ import annotations
|
117
121
|
|
122
|
+
from qiskit._accelerate.pauli_lindblad_map import (
|
123
|
+
QubitSparsePauliList,
|
124
|
+
QubitSparsePauli,
|
125
|
+
PauliLindbladMap,
|
126
|
+
)
|
118
127
|
from qiskit._accelerate.sparse_observable import SparseObservable
|
119
128
|
|
120
129
|
from .analysis import hellinger_distance, hellinger_fidelity, Z2Symmetries
|
@@ -129,6 +138,7 @@ from .operators import (
|
|
129
138
|
commutator,
|
130
139
|
double_commutator,
|
131
140
|
pauli_basis,
|
141
|
+
get_clifford_gate_names,
|
132
142
|
)
|
133
143
|
from .operators.channel import PTM, Chi, Choi, Kraus, Stinespring, SuperOp
|
134
144
|
from .operators.dihedral import CNOTDihedral
|
@@ -554,5 +554,31 @@ _BASIS_2Q = {
|
|
554
554
|
"ecr": _append_ecr,
|
555
555
|
"dcx": _append_dcx,
|
556
556
|
}
|
557
|
+
|
558
|
+
# Clifford gate names
|
559
|
+
_CLIFFORD_GATE_NAMES = [
|
560
|
+
"id",
|
561
|
+
"x",
|
562
|
+
"y",
|
563
|
+
"z",
|
564
|
+
"h",
|
565
|
+
"s",
|
566
|
+
"sdg",
|
567
|
+
"sx",
|
568
|
+
"sxdg",
|
569
|
+
"cx",
|
570
|
+
"cz",
|
571
|
+
"cy",
|
572
|
+
"swap",
|
573
|
+
"iswap",
|
574
|
+
"ecr",
|
575
|
+
"dcx",
|
576
|
+
]
|
577
|
+
|
557
578
|
# Non-clifford gates
|
558
579
|
_NON_CLIFFORD = {"t", "tdg", "ccx", "ccz"}
|
580
|
+
|
581
|
+
|
582
|
+
def get_clifford_gate_names() -> list:
|
583
|
+
"""Returns the list of Clifford gate names."""
|
584
|
+
return _CLIFFORD_GATE_NAMES
|
@@ -708,7 +708,7 @@ class Pauli(BasePauli):
|
|
708
708
|
def apply_layout(
|
709
709
|
self, layout: TranspileLayout | list[int] | None, num_qubits: int | None = None
|
710
710
|
) -> Pauli:
|
711
|
-
"""Apply a transpiler layout to this :class:`~.Pauli`
|
711
|
+
"""Apply a transpiler layout to this :class:`~.quantum_info.Pauli`
|
712
712
|
|
713
713
|
Args:
|
714
714
|
layout: Either a :class:`~.TranspileLayout`, a list of integers or None.
|
@@ -722,7 +722,7 @@ class Pauli(BasePauli):
|
|
722
722
|
None, the operator will be expanded to the given number of qubits.
|
723
723
|
|
724
724
|
Returns:
|
725
|
-
A new :class
|
725
|
+
A new :class:`~.quantum_info.Pauli` with the provided layout applied
|
726
726
|
"""
|
727
727
|
from qiskit.transpiler.layout import TranspileLayout
|
728
728
|
|
qiskit/result/sampled_expval.py
CHANGED
@@ -23,6 +23,7 @@ from .distributions import QuasiDistribution, ProbDistribution
|
|
23
23
|
OPERS = {"Z", "I", "0", "1"}
|
24
24
|
|
25
25
|
|
26
|
+
# pylint: disable=missing-param-doc,missing-type-doc
|
26
27
|
def sampled_expectation_value(dist, oper):
|
27
28
|
"""Computes expectation value from a sampled distribution
|
28
29
|
|
@@ -30,7 +31,8 @@ def sampled_expectation_value(dist, oper):
|
|
30
31
|
|
31
32
|
Parameters:
|
32
33
|
dist (Counts or QuasiDistribution or ProbDistribution or dict): Input sampled distribution
|
33
|
-
oper (str or Pauli or SparsePauliOp): The operator for the
|
34
|
+
oper (str or :class:`~.quantum_info.Pauli` or SparsePauliOp): The operator for the
|
35
|
+
observable
|
34
36
|
|
35
37
|
Returns:
|
36
38
|
float: The expectation value
|
qiskit/synthesis/__init__.py
CHANGED
@@ -127,6 +127,10 @@ Multi Controlled Synthesis
|
|
127
127
|
==========================
|
128
128
|
|
129
129
|
.. autofunction:: synth_mcmt_vchain
|
130
|
+
.. autofunction:: synth_mcx_1_clean_kg24
|
131
|
+
.. autofunction:: synth_mcx_1_dirty_kg24
|
132
|
+
.. autofunction:: synth_mcx_2_clean_kg24
|
133
|
+
.. autofunction:: synth_mcx_2_dirty_kg24
|
130
134
|
.. autofunction:: synth_mcx_n_dirty_i15
|
131
135
|
.. autofunction:: synth_mcx_n_clean_m15
|
132
136
|
.. autofunction:: synth_mcx_1_clean_b95
|
@@ -144,6 +148,7 @@ Adders
|
|
144
148
|
.. autofunction:: adder_qft_d00
|
145
149
|
.. autofunction:: adder_ripple_c04
|
146
150
|
.. autofunction:: adder_ripple_v95
|
151
|
+
.. autofunction:: adder_ripple_r25
|
147
152
|
|
148
153
|
Multipliers
|
149
154
|
-----------
|
@@ -220,6 +225,10 @@ from .two_qubit.two_qubit_decompose import (
|
|
220
225
|
)
|
221
226
|
from .multi_controlled import (
|
222
227
|
synth_mcmt_vchain,
|
228
|
+
synth_mcx_1_clean_kg24,
|
229
|
+
synth_mcx_1_dirty_kg24,
|
230
|
+
synth_mcx_2_clean_kg24,
|
231
|
+
synth_mcx_2_dirty_kg24,
|
223
232
|
synth_mcx_n_dirty_i15,
|
224
233
|
synth_mcx_n_clean_m15,
|
225
234
|
synth_mcx_1_clean_b95,
|
@@ -232,6 +241,7 @@ from .arithmetic import (
|
|
232
241
|
adder_qft_d00,
|
233
242
|
adder_ripple_c04,
|
234
243
|
adder_ripple_v95,
|
244
|
+
adder_ripple_r25,
|
235
245
|
multiplier_cumulative_h18,
|
236
246
|
multiplier_qft_r17,
|
237
247
|
synth_integer_comparator_greedy,
|
@@ -13,6 +13,6 @@
|
|
13
13
|
"""Synthesis for arithmetic circuits."""
|
14
14
|
|
15
15
|
from .comparators import synth_integer_comparator_2s, synth_integer_comparator_greedy
|
16
|
-
from .adders import adder_qft_d00, adder_ripple_c04, adder_ripple_v95
|
16
|
+
from .adders import adder_qft_d00, adder_ripple_c04, adder_ripple_v95, adder_ripple_r25
|
17
17
|
from .multipliers import multiplier_cumulative_h18, multiplier_qft_r17
|
18
18
|
from .weighted_sum import synth_weighted_sum_carry
|
@@ -19,7 +19,9 @@ from qiskit.circuit import QuantumRegister
|
|
19
19
|
from qiskit.circuit.library.basis_change import QFTGate
|
20
20
|
|
21
21
|
|
22
|
-
def adder_qft_d00(
|
22
|
+
def adder_qft_d00(
|
23
|
+
num_state_qubits: int, kind: str = "half", annotated: bool = False
|
24
|
+
) -> QuantumCircuit:
|
23
25
|
r"""A circuit that uses QFT to perform in-place addition on two qubit registers.
|
24
26
|
|
25
27
|
For registers with :math:`n` qubits, the QFT adder can perform addition modulo
|
@@ -51,6 +53,8 @@ def adder_qft_d00(num_state_qubits: int, kind: str = "half") -> QuantumCircuit:
|
|
51
53
|
``"fixed"`` for a fixed-sized adder. A half adder contains a carry-out to represent
|
52
54
|
the most-significant bit, but the fixed-sized adder doesn't and hence performs
|
53
55
|
addition modulo ``2 ** num_state_qubits``.
|
56
|
+
annotated: If ``True``, creates appropriate control and inverse operations as
|
57
|
+
``AnnotatedOperation`` objects.
|
54
58
|
|
55
59
|
**References:**
|
56
60
|
|
@@ -98,6 +102,6 @@ def adder_qft_d00(num_state_qubits: int, kind: str = "half") -> QuantumCircuit:
|
|
98
102
|
# can be elided and cancelled by the compiler
|
99
103
|
circuit.cp(lam, qr_a[j], qr_sum[~(j + k)])
|
100
104
|
|
101
|
-
circuit.append(qft.inverse(), qr_sum[:])
|
105
|
+
circuit.append(qft.inverse(annotated=annotated), qr_sum[:])
|
102
106
|
|
103
107
|
return circuit
|