qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.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 +27 -16
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/assembler/__init__.py +5 -10
- qiskit/assembler/disassemble.py +5 -6
- qiskit/circuit/__init__.py +1061 -232
- qiskit/circuit/_classical_resource_map.py +10 -6
- qiskit/circuit/_utils.py +18 -8
- qiskit/circuit/annotated_operation.py +21 -0
- qiskit/circuit/barrier.py +10 -13
- qiskit/circuit/bit.py +0 -1
- qiskit/circuit/classical/__init__.py +2 -2
- qiskit/circuit/classical/expr/__init__.py +39 -5
- qiskit/circuit/classical/expr/constructors.py +84 -1
- qiskit/circuit/classical/expr/expr.py +83 -13
- qiskit/circuit/classical/expr/visitors.py +83 -0
- qiskit/circuit/classical/types/__init__.py +5 -4
- qiskit/circuit/classicalfunction/__init__.py +1 -0
- qiskit/circuit/commutation_checker.py +86 -51
- qiskit/circuit/controlflow/_builder_utils.py +9 -1
- qiskit/circuit/controlflow/break_loop.py +8 -22
- qiskit/circuit/controlflow/builder.py +116 -1
- qiskit/circuit/controlflow/continue_loop.py +8 -22
- qiskit/circuit/controlflow/control_flow.py +47 -8
- qiskit/circuit/controlflow/for_loop.py +8 -23
- qiskit/circuit/controlflow/if_else.py +13 -27
- qiskit/circuit/controlflow/switch_case.py +14 -21
- qiskit/circuit/controlflow/while_loop.py +9 -23
- qiskit/circuit/controlledgate.py +2 -2
- qiskit/circuit/delay.py +7 -5
- qiskit/circuit/gate.py +20 -7
- qiskit/circuit/instruction.py +31 -30
- qiskit/circuit/instructionset.py +9 -22
- qiskit/circuit/library/__init__.py +3 -13
- qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
- qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
- qiskit/circuit/library/blueprintcircuit.py +29 -7
- qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
- qiskit/circuit/library/generalized_gates/isometry.py +51 -254
- qiskit/circuit/library/generalized_gates/pauli.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +4 -1
- qiskit/circuit/library/generalized_gates/rv.py +15 -11
- qiskit/circuit/library/generalized_gates/uc.py +2 -98
- qiskit/circuit/library/generalized_gates/unitary.py +9 -4
- qiskit/circuit/library/hamiltonian_gate.py +11 -5
- qiskit/circuit/library/n_local/efficient_su2.py +5 -5
- qiskit/circuit/library/n_local/n_local.py +100 -49
- qiskit/circuit/library/n_local/two_local.py +3 -59
- qiskit/circuit/library/overlap.py +3 -3
- qiskit/circuit/library/phase_oracle.py +1 -1
- qiskit/circuit/library/quantum_volume.py +39 -38
- qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
- qiskit/circuit/library/standard_gates/global_phase.py +4 -2
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +1 -2
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
- qiskit/circuit/library/standard_gates/p.py +31 -15
- qiskit/circuit/library/standard_gates/r.py +4 -3
- qiskit/circuit/library/standard_gates/rx.py +7 -4
- qiskit/circuit/library/standard_gates/rxx.py +4 -3
- qiskit/circuit/library/standard_gates/ry.py +7 -4
- qiskit/circuit/library/standard_gates/ryy.py +4 -3
- qiskit/circuit/library/standard_gates/rz.py +7 -4
- qiskit/circuit/library/standard_gates/rzx.py +4 -3
- qiskit/circuit/library/standard_gates/rzz.py +4 -3
- qiskit/circuit/library/standard_gates/s.py +4 -8
- qiskit/circuit/library/standard_gates/t.py +2 -4
- qiskit/circuit/library/standard_gates/u.py +16 -11
- qiskit/circuit/library/standard_gates/u1.py +6 -2
- qiskit/circuit/library/standard_gates/u2.py +4 -2
- qiskit/circuit/library/standard_gates/u3.py +9 -5
- qiskit/circuit/library/standard_gates/x.py +22 -11
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
- qiskit/circuit/library/standard_gates/z.py +1 -2
- qiskit/circuit/measure.py +4 -1
- qiskit/circuit/operation.py +13 -8
- qiskit/circuit/parameter.py +11 -6
- qiskit/circuit/quantumcircuit.py +1910 -260
- qiskit/circuit/quantumcircuitdata.py +2 -2
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/store.py +95 -0
- qiskit/compiler/assembler.py +22 -22
- qiskit/compiler/transpiler.py +63 -112
- qiskit/converters/__init__.py +17 -2
- qiskit/converters/circuit_to_dag.py +7 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
- qiskit/converters/circuit_to_gate.py +2 -0
- qiskit/converters/circuit_to_instruction.py +22 -0
- qiskit/converters/dag_to_circuit.py +4 -0
- qiskit/converters/dag_to_dagdependency_v2.py +44 -0
- qiskit/dagcircuit/collect_blocks.py +15 -10
- qiskit/dagcircuit/dagcircuit.py +434 -124
- qiskit/dagcircuit/dagdependency.py +19 -12
- qiskit/dagcircuit/dagdependency_v2.py +641 -0
- qiskit/dagcircuit/dagdepnode.py +19 -16
- qiskit/dagcircuit/dagnode.py +14 -4
- qiskit/passmanager/passmanager.py +11 -11
- qiskit/primitives/__init__.py +22 -12
- qiskit/primitives/backend_estimator.py +3 -5
- qiskit/primitives/backend_estimator_v2.py +410 -0
- qiskit/primitives/backend_sampler_v2.py +287 -0
- qiskit/primitives/base/base_estimator.py +4 -9
- qiskit/primitives/base/base_sampler.py +2 -2
- qiskit/primitives/containers/__init__.py +6 -4
- qiskit/primitives/containers/bit_array.py +293 -2
- qiskit/primitives/containers/data_bin.py +123 -50
- qiskit/primitives/containers/estimator_pub.py +10 -3
- qiskit/primitives/containers/observables_array.py +2 -2
- qiskit/primitives/containers/pub_result.py +1 -1
- qiskit/primitives/containers/sampler_pub.py +19 -3
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +4 -4
- qiskit/primitives/statevector_estimator.py +4 -4
- qiskit/primitives/statevector_sampler.py +7 -12
- qiskit/providers/__init__.py +65 -34
- qiskit/providers/backend.py +2 -2
- qiskit/providers/backend_compat.py +8 -10
- qiskit/providers/basic_provider/__init__.py +2 -23
- qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
- qiskit/providers/basic_provider/basic_simulator.py +81 -21
- qiskit/providers/fake_provider/__init__.py +1 -1
- qiskit/providers/fake_provider/fake_1q.py +1 -1
- qiskit/providers/fake_provider/fake_backend.py +3 -408
- qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
- qiskit/providers/models/__init__.py +2 -2
- qiskit/providers/provider.py +16 -0
- qiskit/pulse/builder.py +4 -1
- qiskit/pulse/parameter_manager.py +60 -4
- qiskit/pulse/schedule.py +29 -13
- qiskit/pulse/utils.py +61 -20
- qiskit/qasm2/__init__.py +1 -5
- qiskit/qasm2/parse.py +1 -4
- qiskit/qasm3/__init__.py +42 -5
- qiskit/qasm3/ast.py +19 -0
- qiskit/qasm3/exporter.py +178 -106
- qiskit/qasm3/printer.py +27 -5
- qiskit/qobj/converters/pulse_instruction.py +6 -6
- qiskit/qpy/__init__.py +299 -67
- qiskit/qpy/binary_io/circuits.py +216 -47
- qiskit/qpy/binary_io/schedules.py +42 -36
- qiskit/qpy/binary_io/value.py +201 -22
- qiskit/qpy/common.py +1 -1
- qiskit/qpy/exceptions.py +20 -0
- qiskit/qpy/formats.py +29 -0
- qiskit/qpy/type_keys.py +21 -0
- qiskit/quantum_info/analysis/distance.py +3 -3
- qiskit/quantum_info/analysis/make_observable.py +2 -1
- qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
- qiskit/quantum_info/operators/channel/chi.py +9 -8
- qiskit/quantum_info/operators/channel/choi.py +10 -9
- qiskit/quantum_info/operators/channel/kraus.py +2 -1
- qiskit/quantum_info/operators/channel/ptm.py +10 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
- qiskit/quantum_info/operators/channel/stinespring.py +2 -1
- qiskit/quantum_info/operators/channel/superop.py +12 -11
- qiskit/quantum_info/operators/channel/transformations.py +12 -11
- qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
- qiskit/quantum_info/operators/operator.py +43 -30
- qiskit/quantum_info/operators/scalar_op.py +10 -9
- qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
- qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
- qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
- qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
- qiskit/quantum_info/operators/symplectic/random.py +3 -2
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
- qiskit/quantum_info/states/densitymatrix.py +13 -13
- qiskit/quantum_info/states/stabilizerstate.py +3 -3
- qiskit/quantum_info/states/statevector.py +14 -13
- qiskit/quantum_info/states/utils.py +5 -3
- qiskit/result/__init__.py +6 -0
- qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -1
- qiskit/result/mitigation/utils.py +3 -2
- qiskit/scheduler/__init__.py +10 -1
- qiskit/scheduler/methods/__init__.py +1 -8
- qiskit/synthesis/__init__.py +3 -6
- qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
- qiskit/synthesis/evolution/lie_trotter.py +7 -14
- qiskit/synthesis/evolution/qdrift.py +3 -4
- qiskit/synthesis/linear/cnot_synth.py +1 -3
- qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
- qiskit/synthesis/permutation/__init__.py +1 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
- qiskit/synthesis/unitary/aqc/__init__.py +1 -1
- qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
- qiskit/synthesis/unitary/qsd.py +3 -2
- qiskit/transpiler/__init__.py +7 -3
- qiskit/transpiler/layout.py +140 -61
- qiskit/transpiler/passes/__init__.py +10 -2
- qiskit/transpiler/passes/basis/basis_translator.py +9 -4
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
- qiskit/transpiler/passes/layout/apply_layout.py +8 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
- qiskit/transpiler/passes/layout/set_layout.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +2 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
- qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
- qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
- qiskit/transpiler/passes/routing/__init__.py +1 -0
- qiskit/transpiler/passes/routing/basic_swap.py +13 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
- qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
- qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
- qiskit/transpiler/passes/utils/gates_basis.py +3 -3
- qiskit/transpiler/passmanager.py +44 -1
- qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
- qiskit/transpiler/preset_passmanagers/common.py +4 -6
- qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
- qiskit/utils/__init__.py +3 -2
- qiskit/utils/optionals.py +6 -2
- qiskit/utils/parallel.py +24 -15
- qiskit/visualization/array.py +1 -1
- qiskit/visualization/bloch.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +44 -14
- qiskit/visualization/circuit/text.py +38 -18
- qiskit/visualization/counts_visualization.py +3 -6
- qiskit/visualization/dag_visualization.py +6 -7
- qiskit/visualization/gate_map.py +9 -1
- qiskit/visualization/pulse_v2/interface.py +8 -3
- qiskit/visualization/state_visualization.py +3 -2
- qiskit/visualization/timeline/interface.py +18 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
- qiskit/_qasm2.pyd +0 -0
- qiskit/_qasm3.pyd +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
qiskit/qasm3/exporter.py
CHANGED
@@ -33,6 +33,7 @@ from qiskit.circuit import (
|
|
33
33
|
Qubit,
|
34
34
|
Reset,
|
35
35
|
Delay,
|
36
|
+
Store,
|
36
37
|
)
|
37
38
|
from qiskit.circuit.bit import Bit
|
38
39
|
from qiskit.circuit.classical import expr, types
|
@@ -62,7 +63,6 @@ from .printer import BasicPrinter
|
|
62
63
|
_RESERVED_KEYWORDS = frozenset(
|
63
64
|
{
|
64
65
|
"OPENQASM",
|
65
|
-
"U",
|
66
66
|
"angle",
|
67
67
|
"array",
|
68
68
|
"barrier",
|
@@ -239,6 +239,7 @@ class GlobalNamespace:
|
|
239
239
|
|
240
240
|
def __init__(self, includelist, basis_gates=()):
|
241
241
|
self._data = {gate: self.BASIS_GATE for gate in basis_gates}
|
242
|
+
self._data["U"] = self.BASIS_GATE
|
242
243
|
|
243
244
|
for includefile in includelist:
|
244
245
|
if includefile == "stdgates.inc":
|
@@ -282,6 +283,10 @@ class GlobalNamespace:
|
|
282
283
|
return True
|
283
284
|
return False
|
284
285
|
|
286
|
+
def has_symbol(self, name: str) -> bool:
|
287
|
+
"""Whether a symbol's name is present in the table."""
|
288
|
+
return name in self._data
|
289
|
+
|
285
290
|
def register(self, instruction):
|
286
291
|
"""Register an instruction in the namespace"""
|
287
292
|
# The second part of the condition is a nasty hack to ensure that gates that come with at
|
@@ -324,7 +329,7 @@ _Scope = collections.namedtuple("_Scope", ("circuit", "bit_map", "symbol_map"))
|
|
324
329
|
class QASM3Builder:
|
325
330
|
"""QASM3 builder constructs an AST from a QuantumCircuit."""
|
326
331
|
|
327
|
-
builtins = (Barrier, Measure, Reset, Delay, BreakLoopOp, ContinueLoopOp)
|
332
|
+
builtins = (Barrier, Measure, Reset, Delay, BreakLoopOp, ContinueLoopOp, Store)
|
328
333
|
loose_bit_prefix = "_bit"
|
329
334
|
loose_qubit_prefix = "_qubit"
|
330
335
|
gate_parameter_prefix = "_gate_p"
|
@@ -348,14 +353,12 @@ class QASM3Builder:
|
|
348
353
|
self.includeslist = includeslist
|
349
354
|
# `_global_io_declarations` and `_global_classical_declarations` are stateful, and any
|
350
355
|
# operation that needs a parameter can append to them during the build. We make all
|
351
|
-
# classical declarations global because the IBM
|
352
|
-
# strings) prefers declarations to all be global, and it's valid OQ3, so it's not vendor
|
356
|
+
# classical declarations global because the IBM qe-compiler stack (our initial consumer of
|
357
|
+
# OQ3 strings) prefers declarations to all be global, and it's valid OQ3, so it's not vendor
|
353
358
|
# lock-in. It's possibly slightly memory inefficient, but that's not likely to be a problem
|
354
359
|
# in the near term.
|
355
360
|
self._global_io_declarations = []
|
356
|
-
self.
|
357
|
-
self._gate_to_declare = {}
|
358
|
-
self._opaque_to_declare = {}
|
361
|
+
self._global_classical_forward_declarations = []
|
359
362
|
# An arbitrary counter to help with generation of unique ids for symbol names when there are
|
360
363
|
# clashes (though we generally prefer to keep user names if possible).
|
361
364
|
self._counter = itertools.count()
|
@@ -367,18 +370,15 @@ class QASM3Builder:
|
|
367
370
|
def _unique_name(self, prefix: str, scope: _Scope) -> str:
|
368
371
|
table = scope.symbol_map
|
369
372
|
name = basename = _escape_invalid_identifier(prefix)
|
370
|
-
while name in table or name in _RESERVED_KEYWORDS:
|
373
|
+
while name in table or name in _RESERVED_KEYWORDS or self.global_namespace.has_symbol(name):
|
371
374
|
name = f"{basename}__generated{next(self._counter)}"
|
372
375
|
return name
|
373
376
|
|
374
377
|
def _register_gate(self, gate):
|
375
378
|
self.global_namespace.register(gate)
|
376
|
-
self._gate_to_declare[id(gate)] = gate
|
377
379
|
|
378
380
|
def _register_opaque(self, instruction):
|
379
|
-
|
380
|
-
self.global_namespace.register(instruction)
|
381
|
-
self._opaque_to_declare[id(instruction)] = instruction
|
381
|
+
self.global_namespace.register(instruction)
|
382
382
|
|
383
383
|
def _register_variable(self, variable, scope: _Scope, name=None) -> ast.Identifier:
|
384
384
|
"""Register a variable in the symbol table for the given scope, returning the name that
|
@@ -399,6 +399,10 @@ class QASM3Builder:
|
|
399
399
|
raise QASM3ExporterError(
|
400
400
|
f"tried to reserve '{name}', but it is already used by '{table[name]}'"
|
401
401
|
)
|
402
|
+
if self.global_namespace.has_symbol(name):
|
403
|
+
raise QASM3ExporterError(
|
404
|
+
f"tried to reserve '{name}', but it is already used by a gate"
|
405
|
+
)
|
402
406
|
else:
|
403
407
|
name = self._unique_name(variable.name, scope)
|
404
408
|
identifier = ast.Identifier(name)
|
@@ -441,15 +445,66 @@ class QASM3Builder:
|
|
441
445
|
|
442
446
|
def build_program(self):
|
443
447
|
"""Builds a Program"""
|
444
|
-
self.
|
445
|
-
|
448
|
+
circuit = self.global_scope(assert_=True).circuit
|
449
|
+
if circuit.num_captured_vars:
|
450
|
+
raise QASM3ExporterError(
|
451
|
+
"cannot export an inner scope with captured variables as a top-level program"
|
452
|
+
)
|
453
|
+
header = self.build_header()
|
454
|
+
|
455
|
+
opaques_to_declare, gates_to_declare = self.hoist_declarations(
|
456
|
+
circuit.data, opaques=[], gates=[]
|
457
|
+
)
|
458
|
+
opaque_definitions = [
|
459
|
+
self.build_opaque_definition(instruction) for instruction in opaques_to_declare
|
460
|
+
]
|
461
|
+
gate_definitions = [
|
462
|
+
self.build_gate_definition(instruction) for instruction in gates_to_declare
|
463
|
+
]
|
464
|
+
|
465
|
+
# Early IBM runtime paramterisation uses unbound `Parameter` instances as `input` variables,
|
466
|
+
# not the explicit realtime `Var` variables, so we need this explicit scan.
|
467
|
+
self.hoist_global_parameter_declarations()
|
468
|
+
# Qiskit's clbits and classical registers need to get mapped to implicit OQ3 variables, but
|
469
|
+
# only if they're in the top-level circuit. The QuantumCircuit data model is that inner
|
470
|
+
# clbits are bound to outer bits, and inner registers must be closing over outer ones.
|
471
|
+
self.hoist_classical_register_declarations()
|
472
|
+
# We hoist registers before new-style vars because registers are an older part of the data
|
473
|
+
# model (and used implicitly in PrimitivesV2 outputs) so they get the first go at reserving
|
474
|
+
# names in the symbol table.
|
475
|
+
self.hoist_classical_io_var_declarations()
|
476
|
+
|
477
|
+
# Similarly, QuantumCircuit qubits/registers are only new variables in the global scope.
|
478
|
+
quantum_declarations = self.build_quantum_declarations()
|
479
|
+
# This call has side-effects - it can populate `self._global_io_declarations` and
|
480
|
+
# `self._global_classical_declarations` as a courtesy to the qe-compiler that prefers our
|
481
|
+
# hacky temporary `switch` target variables to be globally defined.
|
482
|
+
main_statements = self.build_current_scope()
|
483
|
+
|
484
|
+
statements = [
|
485
|
+
statement
|
486
|
+
for source in (
|
487
|
+
# In older versions of the reference OQ3 grammar, IO declarations had to come before
|
488
|
+
# anything else, so we keep doing that as a courtesy.
|
489
|
+
self._global_io_declarations,
|
490
|
+
opaque_definitions,
|
491
|
+
gate_definitions,
|
492
|
+
self._global_classical_forward_declarations,
|
493
|
+
quantum_declarations,
|
494
|
+
main_statements,
|
495
|
+
)
|
496
|
+
for statement in source
|
497
|
+
]
|
498
|
+
return ast.Program(header, statements)
|
499
|
+
|
500
|
+
def hoist_declarations(self, instructions, *, opaques, gates):
|
501
|
+
"""Walks the definitions in gates/instructions to make a list of gates to declare.
|
446
502
|
|
447
|
-
|
448
|
-
"""Walks the definitions in gates/instructions to make a list of gates to declare."""
|
503
|
+
Mutates ``opaques`` and ``gates`` in-place if given, and returns them."""
|
449
504
|
for instruction in instructions:
|
450
505
|
if isinstance(instruction.operation, ControlFlowOp):
|
451
506
|
for block in instruction.operation.blocks:
|
452
|
-
self.hoist_declarations(block.data)
|
507
|
+
self.hoist_declarations(block.data, opaques=opaques, gates=gates)
|
453
508
|
continue
|
454
509
|
if instruction.operation in self.global_namespace or isinstance(
|
455
510
|
instruction.operation, self.builtins
|
@@ -461,15 +516,20 @@ class QASM3Builder:
|
|
461
516
|
# tree, but isn't an OQ3 built-in. We use `isinstance` because we haven't fully
|
462
517
|
# fixed what the name/class distinction is (there's a test from the original OQ3
|
463
518
|
# exporter that tries a naming collision with 'cx').
|
464
|
-
|
465
|
-
|
466
|
-
|
519
|
+
self._register_gate(instruction.operation)
|
520
|
+
gates.append(instruction.operation)
|
521
|
+
elif instruction.operation.definition is None:
|
467
522
|
self._register_opaque(instruction.operation)
|
523
|
+
opaques.append(instruction.operation)
|
468
524
|
elif not isinstance(instruction.operation, Gate):
|
469
525
|
raise QASM3ExporterError("Exporting non-unitary instructions is not yet supported.")
|
470
526
|
else:
|
471
|
-
self.hoist_declarations(
|
527
|
+
self.hoist_declarations(
|
528
|
+
instruction.operation.definition.data, opaques=opaques, gates=gates
|
529
|
+
)
|
472
530
|
self._register_gate(instruction.operation)
|
531
|
+
gates.append(instruction.operation)
|
532
|
+
return opaques, gates
|
473
533
|
|
474
534
|
def global_scope(self, assert_=False):
|
475
535
|
"""Return the global circuit scope that is used as the basis of the full program. If
|
@@ -540,40 +600,6 @@ class QASM3Builder:
|
|
540
600
|
"""Builds a list of included files."""
|
541
601
|
return [ast.Include(filename) for filename in self.includeslist]
|
542
602
|
|
543
|
-
def build_global_statements(self) -> List[ast.Statement]:
|
544
|
-
"""Get a list of the statements that form the global scope of the program."""
|
545
|
-
definitions = self.build_definitions()
|
546
|
-
# These two "declarations" functions populate stateful variables, since the calls to
|
547
|
-
# `build_quantum_instructions` might also append to those declarations.
|
548
|
-
self.build_parameter_declarations()
|
549
|
-
self.build_classical_declarations()
|
550
|
-
context = self.global_scope(assert_=True).circuit
|
551
|
-
quantum_declarations = self.build_quantum_declarations()
|
552
|
-
quantum_instructions = self.build_quantum_instructions(context.data)
|
553
|
-
|
554
|
-
return [
|
555
|
-
statement
|
556
|
-
for source in (
|
557
|
-
# In older versions of the reference OQ3 grammar, IO declarations had to come before
|
558
|
-
# anything else, so we keep doing that as a courtesy.
|
559
|
-
self._global_io_declarations,
|
560
|
-
definitions,
|
561
|
-
self._global_classical_declarations,
|
562
|
-
quantum_declarations,
|
563
|
-
quantum_instructions,
|
564
|
-
)
|
565
|
-
for statement in source
|
566
|
-
]
|
567
|
-
|
568
|
-
def build_definitions(self):
|
569
|
-
"""Builds all the definition."""
|
570
|
-
ret = []
|
571
|
-
for instruction in self._opaque_to_declare.values():
|
572
|
-
ret.append(self.build_opaque_definition(instruction))
|
573
|
-
for instruction in self._gate_to_declare.values():
|
574
|
-
ret.append(self.build_gate_definition(instruction))
|
575
|
-
return ret
|
576
|
-
|
577
603
|
def build_opaque_definition(self, instruction):
|
578
604
|
"""Builds an Opaque gate definition as a CalibrationDefinition"""
|
579
605
|
# We can't do anything sensible with this yet, so it's better to loudly say that.
|
@@ -604,7 +630,7 @@ class QASM3Builder:
|
|
604
630
|
|
605
631
|
self.push_context(gate.definition)
|
606
632
|
signature = self.build_gate_signature(gate)
|
607
|
-
body = ast.QuantumBlock(self.
|
633
|
+
body = ast.QuantumBlock(self.build_current_scope())
|
608
634
|
self.pop_context()
|
609
635
|
return ast.QuantumGateDefinition(signature, body)
|
610
636
|
|
@@ -627,8 +653,10 @@ class QASM3Builder:
|
|
627
653
|
]
|
628
654
|
return ast.QuantumGateSignature(ast.Identifier(name), quantum_arguments, params or None)
|
629
655
|
|
630
|
-
def
|
631
|
-
"""
|
656
|
+
def hoist_global_parameter_declarations(self):
|
657
|
+
"""Extend ``self._global_io_declarations`` and ``self._global_classical_declarations`` with
|
658
|
+
any implicit declarations used to support the early IBM efforts to use :class:`.Parameter`
|
659
|
+
as an input variable."""
|
632
660
|
global_scope = self.global_scope(assert_=True)
|
633
661
|
for parameter in global_scope.circuit.parameters:
|
634
662
|
parameter_name = self._register_variable(parameter, global_scope)
|
@@ -640,11 +668,13 @@ class QASM3Builder:
|
|
640
668
|
if isinstance(declaration, ast.IODeclaration):
|
641
669
|
self._global_io_declarations.append(declaration)
|
642
670
|
else:
|
643
|
-
self.
|
671
|
+
self._global_classical_forward_declarations.append(declaration)
|
644
672
|
|
645
|
-
def
|
646
|
-
"""Extend the global classical declarations with AST nodes declaring all the
|
647
|
-
and
|
673
|
+
def hoist_classical_register_declarations(self):
|
674
|
+
"""Extend the global classical declarations with AST nodes declaring all the global-scope
|
675
|
+
circuit :class:`.Clbit` and :class:`.ClassicalRegister` instances. Qiskit's data model
|
676
|
+
doesn't involve the declaration of *new* bits or registers in inner scopes; only the
|
677
|
+
:class:`.expr.Var` mechanism allows that.
|
648
678
|
|
649
679
|
The behaviour of this function depends on the setting ``allow_aliasing``. If this
|
650
680
|
is ``True``, then the output will be in the same form as the output of
|
@@ -670,12 +700,14 @@ class QASM3Builder:
|
|
670
700
|
)
|
671
701
|
for i, clbit in enumerate(scope.circuit.clbits)
|
672
702
|
)
|
673
|
-
self.
|
674
|
-
self.
|
703
|
+
self._global_classical_forward_declarations.extend(clbits)
|
704
|
+
self._global_classical_forward_declarations.extend(
|
705
|
+
self.build_aliases(scope.circuit.cregs)
|
706
|
+
)
|
675
707
|
return
|
676
708
|
# If we're here, we're in the clbit happy path where there are no clbits that are in more
|
677
709
|
# than one register. We can output things very naturally.
|
678
|
-
self.
|
710
|
+
self._global_classical_forward_declarations.extend(
|
679
711
|
ast.ClassicalDeclaration(
|
680
712
|
ast.BitType(),
|
681
713
|
self._register_variable(
|
@@ -691,10 +723,26 @@ class QASM3Builder:
|
|
691
723
|
scope.symbol_map[bit] = ast.SubscriptedIdentifier(
|
692
724
|
name.string, ast.IntegerLiteral(i)
|
693
725
|
)
|
694
|
-
self.
|
726
|
+
self._global_classical_forward_declarations.append(
|
695
727
|
ast.ClassicalDeclaration(ast.BitArrayType(len(register)), name)
|
696
728
|
)
|
697
729
|
|
730
|
+
def hoist_classical_io_var_declarations(self):
|
731
|
+
"""Hoist the declarations of classical IO :class:`.expr.Var` nodes into the global state.
|
732
|
+
|
733
|
+
Local :class:`.expr.Var` declarations are handled by the regular local-block scope builder,
|
734
|
+
and the :class:`.QuantumCircuit` data model ensures that the only time an IO variable can
|
735
|
+
occur is in an outermost block."""
|
736
|
+
scope = self.global_scope(assert_=True)
|
737
|
+
for var in scope.circuit.iter_input_vars():
|
738
|
+
self._global_io_declarations.append(
|
739
|
+
ast.IODeclaration(
|
740
|
+
ast.IOModifier.INPUT,
|
741
|
+
_build_ast_type(var.type),
|
742
|
+
self._register_variable(var, scope),
|
743
|
+
)
|
744
|
+
)
|
745
|
+
|
698
746
|
def build_quantum_declarations(self):
|
699
747
|
"""Return a list of AST nodes declaring all the qubits in the current scope, and all the
|
700
748
|
alias declarations for these qubits."""
|
@@ -760,21 +808,37 @@ class QASM3Builder:
|
|
760
808
|
out.append(ast.AliasStatement(name, ast.IndexSet(elements)))
|
761
809
|
return out
|
762
810
|
|
763
|
-
def
|
764
|
-
"""
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
811
|
+
def build_current_scope(self) -> List[ast.Statement]:
|
812
|
+
"""Build the instructions that occur in the current scope.
|
813
|
+
|
814
|
+
In addition to everything literally in the circuit's ``data`` field, this also includes
|
815
|
+
declarations for any local :class:`.expr.Var` nodes.
|
816
|
+
"""
|
817
|
+
scope = self.current_scope()
|
818
|
+
|
819
|
+
# We forward-declare all local variables uninitialised at the top of their scope. It would
|
820
|
+
# be nice to declare the variable at the point of first store (so we can write things like
|
821
|
+
# `uint[8] a = 12;`), but there's lots of edge-case logic to catch with that around
|
822
|
+
# use-before-definition errors in the OQ3 output, for example if the user has side-stepped
|
823
|
+
# the `QuantumCircuit` API protection to produce a circuit that uses an uninitialised
|
824
|
+
# variable, or the initial write to a variable is within a control-flow scope. (It would be
|
825
|
+
# easier to see the def/use chain needed to do this cleanly if we were using `DAGCircuit`.)
|
826
|
+
statements = [
|
827
|
+
ast.ClassicalDeclaration(_build_ast_type(var.type), self._register_variable(var, scope))
|
828
|
+
for var in scope.circuit.iter_declared_vars()
|
829
|
+
]
|
830
|
+
for instruction in scope.circuit.data:
|
831
|
+
if isinstance(instruction.operation, ControlFlowOp):
|
832
|
+
if isinstance(instruction.operation, ForLoopOp):
|
833
|
+
statements.append(self.build_for_loop(instruction))
|
834
|
+
elif isinstance(instruction.operation, WhileLoopOp):
|
835
|
+
statements.append(self.build_while_loop(instruction))
|
836
|
+
elif isinstance(instruction.operation, IfElseOp):
|
837
|
+
statements.append(self.build_if_statement(instruction))
|
838
|
+
elif isinstance(instruction.operation, SwitchCaseOp):
|
839
|
+
statements.extend(self.build_switch_statement(instruction))
|
840
|
+
else: # pragma: no cover
|
841
|
+
raise RuntimeError(f"unhandled control-flow construct: {instruction.operation}")
|
778
842
|
continue
|
779
843
|
# Build the node, ignoring any condition.
|
780
844
|
if isinstance(instruction.operation, Gate):
|
@@ -795,6 +859,13 @@ class QASM3Builder:
|
|
795
859
|
]
|
796
860
|
elif isinstance(instruction.operation, Delay):
|
797
861
|
nodes = [self.build_delay(instruction)]
|
862
|
+
elif isinstance(instruction.operation, Store):
|
863
|
+
nodes = [
|
864
|
+
ast.AssignmentStatement(
|
865
|
+
self.build_expression(instruction.operation.lvalue),
|
866
|
+
self.build_expression(instruction.operation.rvalue),
|
867
|
+
)
|
868
|
+
]
|
798
869
|
elif isinstance(instruction.operation, BreakLoopOp):
|
799
870
|
nodes = [ast.BreakStatement()]
|
800
871
|
elif isinstance(instruction.operation, ContinueLoopOp):
|
@@ -803,16 +874,16 @@ class QASM3Builder:
|
|
803
874
|
nodes = [self.build_subroutine_call(instruction)]
|
804
875
|
|
805
876
|
if instruction.operation.condition is None:
|
806
|
-
|
877
|
+
statements.extend(nodes)
|
807
878
|
else:
|
808
879
|
body = ast.ProgramBlock(nodes)
|
809
|
-
|
880
|
+
statements.append(
|
810
881
|
ast.BranchingStatement(
|
811
882
|
self.build_expression(_lift_condition(instruction.operation.condition)),
|
812
883
|
body,
|
813
884
|
)
|
814
885
|
)
|
815
|
-
return
|
886
|
+
return statements
|
816
887
|
|
817
888
|
def build_if_statement(self, instruction: CircuitInstruction) -> ast.BranchingStatement:
|
818
889
|
"""Build an :obj:`.IfElseOp` into a :obj:`.ast.BranchingStatement`."""
|
@@ -820,14 +891,14 @@ class QASM3Builder:
|
|
820
891
|
|
821
892
|
true_circuit = instruction.operation.blocks[0]
|
822
893
|
self.push_scope(true_circuit, instruction.qubits, instruction.clbits)
|
823
|
-
true_body = self.
|
894
|
+
true_body = ast.ProgramBlock(self.build_current_scope())
|
824
895
|
self.pop_scope()
|
825
896
|
if len(instruction.operation.blocks) == 1:
|
826
897
|
return ast.BranchingStatement(condition, true_body, None)
|
827
898
|
|
828
899
|
false_circuit = instruction.operation.blocks[1]
|
829
900
|
self.push_scope(false_circuit, instruction.qubits, instruction.clbits)
|
830
|
-
false_body = self.
|
901
|
+
false_body = ast.ProgramBlock(self.build_current_scope())
|
831
902
|
self.pop_scope()
|
832
903
|
return ast.BranchingStatement(condition, true_body, false_body)
|
833
904
|
|
@@ -838,7 +909,7 @@ class QASM3Builder:
|
|
838
909
|
target = self._reserve_variable_name(
|
839
910
|
ast.Identifier(self._unique_name("switch_dummy", global_scope)), global_scope
|
840
911
|
)
|
841
|
-
self.
|
912
|
+
self._global_classical_forward_declarations.append(
|
842
913
|
ast.ClassicalDeclaration(ast.IntType(), target, None)
|
843
914
|
)
|
844
915
|
|
@@ -851,7 +922,7 @@ class QASM3Builder:
|
|
851
922
|
for v in values
|
852
923
|
]
|
853
924
|
self.push_scope(case_block, instruction.qubits, instruction.clbits)
|
854
|
-
case_body = self.
|
925
|
+
case_body = ast.ProgramBlock(self.build_current_scope())
|
855
926
|
self.pop_scope()
|
856
927
|
return values, case_body
|
857
928
|
|
@@ -871,7 +942,7 @@ class QASM3Builder:
|
|
871
942
|
default = None
|
872
943
|
for values, block in instruction.operation.cases_specifier():
|
873
944
|
self.push_scope(block, instruction.qubits, instruction.clbits)
|
874
|
-
case_body = self.
|
945
|
+
case_body = ast.ProgramBlock(self.build_current_scope())
|
875
946
|
self.pop_scope()
|
876
947
|
if CASE_DEFAULT in values:
|
877
948
|
# Even if it's mixed in with other cases, we can skip them and only output the
|
@@ -891,7 +962,7 @@ class QASM3Builder:
|
|
891
962
|
condition = self.build_expression(_lift_condition(instruction.operation.condition))
|
892
963
|
loop_circuit = instruction.operation.blocks[0]
|
893
964
|
self.push_scope(loop_circuit, instruction.qubits, instruction.clbits)
|
894
|
-
loop_body = self.
|
965
|
+
loop_body = ast.ProgramBlock(self.build_current_scope())
|
895
966
|
self.pop_scope()
|
896
967
|
return ast.WhileLoopStatement(condition, loop_body)
|
897
968
|
|
@@ -921,7 +992,7 @@ class QASM3Builder:
|
|
921
992
|
"The values in OpenQASM 3 'for' loops must all be integers, but received"
|
922
993
|
f" '{indexset}'."
|
923
994
|
) from None
|
924
|
-
body_ast = self.
|
995
|
+
body_ast = ast.ProgramBlock(self.build_current_scope())
|
925
996
|
self.pop_scope()
|
926
997
|
return ast.ForLoopStatement(indexset_ast, loop_parameter_ast, body_ast)
|
927
998
|
|
@@ -961,10 +1032,6 @@ class QASM3Builder:
|
|
961
1032
|
raise QASM3ExporterError(f"'{value}' is not an integer") # pragma: no cover
|
962
1033
|
return ast.IntegerLiteral(int(value))
|
963
1034
|
|
964
|
-
def build_program_block(self, instructions):
|
965
|
-
"""Builds a ProgramBlock"""
|
966
|
-
return ast.ProgramBlock(self.build_quantum_instructions(instructions))
|
967
|
-
|
968
1035
|
def _rebind_scoped_parameters(self, expression):
|
969
1036
|
"""If the input is a :class:`.ParameterExpression`, rebind any internal
|
970
1037
|
:class:`.Parameter`\\ s so that their names match their names in the scope. Other inputs
|
@@ -1008,8 +1075,8 @@ def _infer_variable_declaration(
|
|
1008
1075
|
|
1009
1076
|
This is very simplistic; it assumes all parameters are real numbers that need to be input to the
|
1010
1077
|
program, unless one is used as a loop variable, in which case it shouldn't be declared at all,
|
1011
|
-
because the ``for`` loop declares it implicitly (per the Qiskit/
|
1012
|
-
spec at
|
1078
|
+
because the ``for`` loop declares it implicitly (per the Qiskit/qe-compiler reading of the
|
1079
|
+
OpenQASM spec at openqasm/openqasm@8ee55ec).
|
1013
1080
|
|
1014
1081
|
.. note::
|
1015
1082
|
|
@@ -1058,6 +1125,14 @@ def _lift_condition(condition):
|
|
1058
1125
|
return expr.lift_legacy_condition(condition)
|
1059
1126
|
|
1060
1127
|
|
1128
|
+
def _build_ast_type(type_: types.Type) -> ast.ClassicalType:
|
1129
|
+
if type_.kind is types.Bool:
|
1130
|
+
return ast.BoolType()
|
1131
|
+
if type_.kind is types.Uint:
|
1132
|
+
return ast.UintType(type_.width)
|
1133
|
+
raise RuntimeError(f"unhandled expr type '{type_}'") # pragma: no cover
|
1134
|
+
|
1135
|
+
|
1061
1136
|
class _ExprBuilder(expr.ExprVisitor[ast.Expression]):
|
1062
1137
|
__slots__ = ("lookup",)
|
1063
1138
|
|
@@ -1069,7 +1144,7 @@ class _ExprBuilder(expr.ExprVisitor[ast.Expression]):
|
|
1069
1144
|
self.lookup = lookup
|
1070
1145
|
|
1071
1146
|
def visit_var(self, node, /):
|
1072
|
-
return self.lookup(node.var)
|
1147
|
+
return self.lookup(node) if node.standalone else self.lookup(node.var)
|
1073
1148
|
|
1074
1149
|
def visit_value(self, node, /):
|
1075
1150
|
if node.type.kind is types.Bool:
|
@@ -1080,14 +1155,8 @@ class _ExprBuilder(expr.ExprVisitor[ast.Expression]):
|
|
1080
1155
|
|
1081
1156
|
def visit_cast(self, node, /):
|
1082
1157
|
if node.implicit:
|
1083
|
-
return node.accept(self)
|
1084
|
-
|
1085
|
-
oq3_type = ast.BoolType()
|
1086
|
-
elif node.type.kind is types.Uint:
|
1087
|
-
oq3_type = ast.BitArrayType(node.type.width)
|
1088
|
-
else:
|
1089
|
-
raise RuntimeError(f"unhandled cast type '{node.type}'")
|
1090
|
-
return ast.Cast(oq3_type, node.operand.accept(self))
|
1158
|
+
return node.operand.accept(self)
|
1159
|
+
return ast.Cast(_build_ast_type(node.type), node.operand.accept(self))
|
1091
1160
|
|
1092
1161
|
def visit_unary(self, node, /):
|
1093
1162
|
return ast.Unary(ast.Unary.Op[node.op.name], node.operand.accept(self))
|
@@ -1096,3 +1165,6 @@ class _ExprBuilder(expr.ExprVisitor[ast.Expression]):
|
|
1096
1165
|
return ast.Binary(
|
1097
1166
|
ast.Binary.Op[node.op.name], node.left.accept(self), node.right.accept(self)
|
1098
1167
|
)
|
1168
|
+
|
1169
|
+
def visit_index(self, node, /):
|
1170
|
+
return ast.Index(node.target.accept(self), node.index.accept(self))
|
qiskit/qasm3/printer.py
CHANGED
@@ -34,13 +34,16 @@ from .experimental import ExperimentalFeatures
|
|
34
34
|
# indexing and casting are all higher priority than these, so we just ignore them.
|
35
35
|
_BindingPower = collections.namedtuple("_BindingPower", ("left", "right"), defaults=(255, 255))
|
36
36
|
_BINDING_POWER = {
|
37
|
-
# Power: (
|
37
|
+
# Power: (24, 23)
|
38
38
|
#
|
39
|
-
ast.Unary.Op.LOGIC_NOT: _BindingPower(right=
|
40
|
-
ast.Unary.Op.BIT_NOT: _BindingPower(right=
|
39
|
+
ast.Unary.Op.LOGIC_NOT: _BindingPower(right=22),
|
40
|
+
ast.Unary.Op.BIT_NOT: _BindingPower(right=22),
|
41
41
|
#
|
42
|
-
# Multiplication/division/modulo: (
|
43
|
-
# Addition/subtraction: (
|
42
|
+
# Multiplication/division/modulo: (19, 20)
|
43
|
+
# Addition/subtraction: (17, 18)
|
44
|
+
#
|
45
|
+
ast.Binary.Op.SHIFT_LEFT: _BindingPower(15, 16),
|
46
|
+
ast.Binary.Op.SHIFT_RIGHT: _BindingPower(15, 16),
|
44
47
|
#
|
45
48
|
ast.Binary.Op.LESS: _BindingPower(13, 14),
|
46
49
|
ast.Binary.Op.LESS_EQUAL: _BindingPower(13, 14),
|
@@ -204,11 +207,19 @@ class BasicPrinter:
|
|
204
207
|
def _visit_FloatType(self, node: ast.FloatType) -> None:
|
205
208
|
self.stream.write(f"float[{self._FLOAT_WIDTH_LOOKUP[node]}]")
|
206
209
|
|
210
|
+
def _visit_BoolType(self, _node: ast.BoolType) -> None:
|
211
|
+
self.stream.write("bool")
|
212
|
+
|
207
213
|
def _visit_IntType(self, node: ast.IntType) -> None:
|
208
214
|
self.stream.write("int")
|
209
215
|
if node.size is not None:
|
210
216
|
self.stream.write(f"[{node.size}]")
|
211
217
|
|
218
|
+
def _visit_UintType(self, node: ast.UintType) -> None:
|
219
|
+
self.stream.write("uint")
|
220
|
+
if node.size is not None:
|
221
|
+
self.stream.write(f"[{node.size}]")
|
222
|
+
|
212
223
|
def _visit_BitType(self, _node: ast.BitType) -> None:
|
213
224
|
self.stream.write("bit")
|
214
225
|
|
@@ -324,6 +335,17 @@ class BasicPrinter:
|
|
324
335
|
self.visit(node.operand)
|
325
336
|
self.stream.write(")")
|
326
337
|
|
338
|
+
def _visit_Index(self, node: ast.Index):
|
339
|
+
if isinstance(node.target, (ast.Unary, ast.Binary)):
|
340
|
+
self.stream.write("(")
|
341
|
+
self.visit(node.target)
|
342
|
+
self.stream.write(")")
|
343
|
+
else:
|
344
|
+
self.visit(node.target)
|
345
|
+
self.stream.write("[")
|
346
|
+
self.visit(node.index)
|
347
|
+
self.stream.write("]")
|
348
|
+
|
327
349
|
def _visit_ClassicalDeclaration(self, node: ast.ClassicalDeclaration) -> None:
|
328
350
|
self._start_line()
|
329
351
|
self.visit(node.type)
|
@@ -234,7 +234,7 @@ class InstructionToQobjConverter:
|
|
234
234
|
"name": "setf",
|
235
235
|
"t0": time_offset + instruction.start_time,
|
236
236
|
"ch": instruction.channel.name,
|
237
|
-
"frequency": instruction.frequency /
|
237
|
+
"frequency": instruction.frequency / 10**9,
|
238
238
|
}
|
239
239
|
return self._qobj_model(**command_dict)
|
240
240
|
|
@@ -257,7 +257,7 @@ class InstructionToQobjConverter:
|
|
257
257
|
"name": "shiftf",
|
258
258
|
"t0": time_offset + instruction.start_time,
|
259
259
|
"ch": instruction.channel.name,
|
260
|
-
"frequency": instruction.frequency /
|
260
|
+
"frequency": instruction.frequency / 10**9,
|
261
261
|
}
|
262
262
|
return self._qobj_model(**command_dict)
|
263
263
|
|
@@ -746,7 +746,7 @@ class QobjToInstructionConverter:
|
|
746
746
|
.. note::
|
747
747
|
|
748
748
|
We assume frequency value is expressed in string with "GHz".
|
749
|
-
Operand value is thus scaled by a factor of
|
749
|
+
Operand value is thus scaled by a factor of 10^9.
|
750
750
|
|
751
751
|
Args:
|
752
752
|
instruction: SetFrequency qobj instruction
|
@@ -755,7 +755,7 @@ class QobjToInstructionConverter:
|
|
755
755
|
Qiskit Pulse set frequency instructions
|
756
756
|
"""
|
757
757
|
channel = self.get_channel(instruction.ch)
|
758
|
-
frequency = self.disassemble_value(instruction.frequency) *
|
758
|
+
frequency = self.disassemble_value(instruction.frequency) * 10**9
|
759
759
|
|
760
760
|
yield instructions.SetFrequency(frequency, channel)
|
761
761
|
|
@@ -768,7 +768,7 @@ class QobjToInstructionConverter:
|
|
768
768
|
.. note::
|
769
769
|
|
770
770
|
We assume frequency value is expressed in string with "GHz".
|
771
|
-
Operand value is thus scaled by a factor of
|
771
|
+
Operand value is thus scaled by a factor of 10^9.
|
772
772
|
|
773
773
|
Args:
|
774
774
|
instruction: ShiftFrequency qobj instruction
|
@@ -777,7 +777,7 @@ class QobjToInstructionConverter:
|
|
777
777
|
Qiskit Pulse shift frequency schedule instructions
|
778
778
|
"""
|
779
779
|
channel = self.get_channel(instruction.ch)
|
780
|
-
frequency = self.disassemble_value(instruction.frequency) *
|
780
|
+
frequency = self.disassemble_value(instruction.frequency) * 10**9
|
781
781
|
|
782
782
|
yield instructions.ShiftFrequency(frequency, channel)
|
783
783
|
|