Qiskit SDK 1.1 release notes
1.1.2
Prelude
Qiskit 1.1.2 is a minor bugfix release for the 1.1 series.
Bug Fixes
-
Fixed a bug in
BitArray.from_counts()andBitArray.from_samples(). Previously these would raise an error if given data containing only zeros, and no value for the optional argumentnum_bits. Now they produce aBitArraywithBitArray.num_bitsset to 1. -
Fixed a missing decorator in
C3SXGatethat made it fail ifGate.to_matrix()was called. The gate matrix is now return as expected. -
Added missing Clifford gates to the
CollectCliffordstranspiler pass. In particular, we have added the gatesECRGate,DCXGate,iSWAPGate,SXGateandSXdgGateto this transpiler pass. -
The
QuantumCircuit.parametersattribute will now correctly be empty when usingQuantumCircuit.copy_empty_like()on a parametric circuit. Previously, an internal cache would be copied over without invalidation. Fix #12617. -
Fix the
SolovayKitaevtranspiler pass when loading basic approximations from an existing.npyfile. Previously, loading a stored approximation which allowed for further reductions (e.g. due to gate cancellations) could cause a runtime failure. Additionally, the global phase difference of the U(2) gate product and SO(3) representation was lost during a save-reload procedure. Fixes Qiskit/qiskit#12576. -
Fixed an issue with
dag_drawer()andDAGCircuit.draw()when attempting to visualize aDAGCircuitinstance that containedVarwires. The visualizer would raise an exception trying to do this which has been fixed so the expected visualization will be generated. -
The constructor
GenericBackendV2previously allowed malformed backends to be constructed because it accepted basis gates that couldn’t be allocated given the backend size. For example, a backend with a single qubit could previously accept a basis with two-qubit gates. -
The OpenQASM 2 parser (
qiskit.qasm2) can now handle conditionals with integers that do not fit within a 64-bit integer. Fixed #12773. -
Previously,
DAGCircuit.replace_block_with_op()allowed ann-qubit operation to be placed onto a block ofmqubits, leaving the DAG in an invalid state. This behavior has been fixed, and any attempt to do this will now raise aDAGCircuitErroras expected.
1.1.1
Prelude
Qiskit 1.1.1 is a minor bugfix release for the 1.1 series.
Bug Fixes
-
Fix a bug in
Isometrydue to an unnecessary assertion, that led to an error inUnitaryGate.control()whenUnitaryGatehad more that two qubits. -
QuantumCircuit.depth()will now correctly handle operations that do not have operands, such asGlobalPhaseGate. -
QuantumCircuit.depth()will now count the variables and clbits used in real-time expressions as part of the depth calculation. -
Fixed a bug in
qiskit.visualization.pulse_v2.interface.draw()that didn’t draw pulse schedules when the draw function was called with aBackendV2argument. Because the V2 backend doesn’t report hardware channel frequencies, the generated drawing will show ‘no freq.’ below each channel label. -
The
VF2Layoutpass would raise an exception when provided with aTargetinstance without connectivity constraints. This would be the case with targets from Aer 0.13. The issue is now fixed. -
ParameterExpressionwas updated so that fully bound instances that compare equal to instances of Python’s built-in numeric types (likefloatandint) also have hash values that match those of the other instances. This change ensures that these types can be used interchangeably as dictionary keys. See #12488. -
Custom gates (those stemming from a
gatestatement) in imported OpenQASM 2 programs will now have aGate.to_matrix()implementation. Previously they would have no matrix definition, meaning that roundtrips through OpenQASM 2 could needlessly lose the ability to derive the gate matrix. Note, though, that the matrix is calculated by recursively finding the matrices of the inner gate definitions, asOperatordoes, which might be less performant than before the round-trip. -
Target.has_calibration()has been updated so that it does not raise an exception for an instruction that has been added to the target withNonefor its instruction properties. Fixes #12525.
1.1.0
Prelude
The Qiskit 1.1.0 release is a minor feature release that includes a myriad of new feature and bugfixes. The highlights for this release are:
Support for typed classical variables has been added to Qiskit’s
QuantumCircuit. These classical variables can be specified as inputs or as scoped variables in aQuantumCircuitwhere they e.g. store the output of qubit measurements or target control-flow operations. Support for e.g. setting gate parameters or output variables will be added in the future.The default two qubit synthesis methods that are used internally by the transpiler in the
UnitarySynthesispass have been re-implemented in Rust. This yields significant runtime speedups when decomposing two qubit unitary matrices. As a consequence, the runtime of transpilation with optimization level 3 was significantly improved where runningUnitarySynthesisincurred a large runtime overhead historically. This release also starts runningUnitarySynthesisas part of the optimization stage in optimization level 2 because of these runtime performance improvements.Additionally, the numeric methods used in
Isometryhave been moved to Rust, enabling large runtime speed-ups in particular for controlled unitary gate synthesis. The decomposition for multi-controlledXGateandPhaseGatehas been improved resulting in a reduction in the number of gates used in the synthesis by more than two orders of magnitude.A number of new transpiler passes have been introduced to Qiskit that yield significant runtime speedups while also decreasing the size of the transpiled quantum circuits in many cases. Specifically,
ElidePermutationsandStarPreRoutinghave been demonstrated to have a significant impact on the routing output quality and runtime andRemoveFinalResetcan improve quantum circuits that include resets.The default pass managers have been improved by extending them with the newly introduced transpiler passes. In particular, the optimization level 2 preset pass manager from
generate_preset_pass_managerand used internally bytranspile()has been refactored to have a better tradeoff between runtime and optimization effort in order to serve as a default pass manager in future releases. While this release doesn’t change the default to use level 2 it is typically a better choice than using level 1 or 3.New generic primitive V2 implementations were added,
BackendEstimatorV2andBackendSamplerV2, to compliment the existing full statevector based implementations.Changes to platform support: Python 3.8 is deprecated starting with Qiskit 1.1.0 and will no longer be supported in 1.3.0, and arm64 macOS has been promoted to tier 1 support.
Circuits Features
-
The methods
QuantumCircuit.power(),Gate.power(), as well as the similar methods on subclasses of subclasses ofGate(such as ofSGate) all have an additional have a new argumentannotatedwhich is used to return anAnnotatedOperationobject when applying a power to a gate or circuit. The default value ofFalsecorresponds to the existing behavior. Furthermore, for standard gates with an explicitly definedpowermethod, the argumentannotatedhas no effect. For example, bothSGate().power(1.5, annotated=False)andSGate().power(1.5, annotated=True)return aPhaseGate. A difference in the value ofannotatedmanifests for gates without an explicitly defined power method. The value ofFalsereturns aUnitaryGate, just as before, while the value ofTruereturns anAnnotatedOperationthat represents the instruction modified with the “power modifier”. -
Added a new
ctrl_stateargument toQuantumCircuit.mcp()andMCPhaseGate.The
QuantumCircuit.mcp()method andMCPhaseGateclass have been updated to include actrl_stateparameter. This enhancement allows users to specify the control state of the multi-controlled phase gate. The parameter can accept either an integer value or a bitstring and defaults to controlling the ‘1’ state if not provided.from qiskit import QuantumCircuit qc = QuantumCircuit(4) qc.mcp(0.2,[0,1,2],3,ctrl_state=2) -
Added a new
ctrl_stateargument toQuantumCircuit.mcx().The
QuantumCircuit.mcx()method in the quantum circuit library has been enhanced to include a ctrl_state parameter, allowing users to specify the control state of the multi-controlled X gate. This parameter can accept either a decimal value or a bitstring and defaults to controlling the ‘1’ state if not provided.from qiskit import QuantumCircuit qc = QuantumCircuit(3, 3) qc.mcx([0, 1], 2, ctrl_state="00") -
A
QuantumCircuitcan now contain typed classical variables:from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister from qiskit.circuit.classical import expr, types qr = QuantumRegister(2, "q") cr = ClassicalRegister(2, "c") qc = QuantumCircuit(qr, cr) # Add two input variables to the circuit with different types. a = qc.add_input("a", types.Bool()) mask = qc.add_input("mask", types.Uint(2)) # Test whether the input variable was true at runtime. with qc.if_test(a) as else_: qc.x(0) with else_: qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Add a typed variable manually, initialized to the same value as the classical register. b = qc.add_var("b", expr.lift(cr)) qc.reset([0, 1]) qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Store some calculated value into the `b` variable. qc.store(b, expr.bit_and(b, cr)) # Test whether we had equality, up to a mask. with qc.if_test(expr.equal(expr.bit_and(b, mask), mask)): qc.x(0)These variables can be specified either as inputs to the circuit, or as scoped variables. The circuit object does not yet have support for representing typed classical-variable outputs, but this will be added later when hardware and the result interfaces are in more of a position to support it. Circuits that represent a block of an inner scope may also capture variables from outer scopes.
A variable is a
Varnode, which can now contain an arbitrary type, and represents a unique memory location within its live range when added to a circuit. These can be constructed in a circuit usingQuantumCircuit.add_var()andQuantumCircuit.add_input(), or at a lower level usingVar.new().Variables can be manually stored to, using the
Storeinstruction and its corresponding circuit methodQuantumCircuit.store(). This includes writing toClbitandClassicalRegisterinstances wrapped inVarnodes.Variables can be used wherever classical expressions (see
qiskit.circuit.classical.expr) are valid. Currently this is the target expressions of control-flow operations, though we plan to expand this to gate parameters in the future, as the type and expression system are expanded.See Real-time classical computation for more discussion of these variables, and the associated data model.
These are supported throughout the transpiler, through QPY serialization (
qiskit.qpy), OpenQASM 3 export (qiskit.qasm3), and have initial support through the circuit visualizers (seeQuantumCircuit.draw()).NoteThe new classical variables and storage will take some time to become supported on hardware and simulator backends. They are not supported in the primitives interfaces (
qiskit.primitives), but will likely inform those interfaces as they evolve. -
The classical realtime-expressions module
qiskit.circuit.classicalcan now represent indexing and bitshifting of unsigned integers and bitlikes (e.g.ClassicalRegister). For example, it is now possible to compare one register with the bitshift of another:from qiskit.circuit import QuantumCircuit, ClassicalRegister from qiskit.circuit.classical import expr cr1 = ClassicalRegister(4, "cr1") cr2 = ClassicalRegister(4, "cr2") qc = QuantumCircuit(cr1, cr2) with qc.if_test(expr.equal(cr1, expr.shift_left(cr2, 2))): passQiskit can also represent a condition that dynamically indexes into a register:
with qc.if_test(expr.index(cr1, cr2)): pass -
The construction performance of
NLocaland its derived circuit-library subclasses (e.g.EfficientSU2andRealAmplitudes) has significantly improved, when the rotation and/or entanglement subblocks are simple applications of a single Qiskit standard-library gate. Since these circuits are constructed lazily, you might not see the improvement immediately on instantiation of the class, but instead on first access to its internal structure. Performance improvements are on the order of ten times faster. -
QuantumCircuit.append()now has acopykeyword argument, which defaults toTrue. When an instruction with runtime parameters (ParameterExpressions) is appended to a circuit, by default, the circuit has always created a copy of the instruction so that ifQuantumCircuit.assign_parameters()attempts to mutate the instruction in place, it does not affect other references to the same instruction. Now, settingcopy=Falseallows you to override this, so you can avoid the copy penalty if you know your instructions will not be used in other locations. -
QuantumCircuit.compose()now has acopykeyword argument, which defaults toTrue. By default,compose()copies all instructions, so that mutations from one circuit do not affect any other. Ifcopy=False, then instructions from the other circuit will become directly owned by the new circuit, which may involve mutating them in place. The other circuit must not be used afterwards, in this case. -
Construction time for
QuantumVolumecircuits has been significantly improved, on the order of 10x or a bit more. The internal SU4 gates will now also use more bits of randomness during their generation, leading to more representative volume circuits, especially at large widths and depths. -
QuantumVolumenow has aflattenkeyword argument. This defaults toFalse, where the constructed circuit contains a single instruction that in turn contains the actual volume structure. If setTrue, the circuit will directly have the volumetric SU4 matrices. -
UnitaryGatenow accepts an optionalnum_qubitsargument. The only effect of this is to skip the inference of the qubit count, which can be helpful for performance when many gates are being constructed. -
QuantumCircuithas several new methods to work with and inspect manualVarvariables.See Working with real-time typed classical data for more in-depth discussion on all of these.
The new methods are:
add_var()add_input()add_capture()add_uninitialized_var()get_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()store()
In addition, there are several new dynamic attributes on
QuantumCircuitsurrounding these variables: -
ControlFlowOpand its subclasses now have aiter_captured_vars()method, which will return an iterator over the unique variables captured in any of its immediate blocks. -
DAGCircuithas several new methods to work with and inspect manualVarvariables. These are largely equivalent to theirQuantumCircuitcounterparts, except that theDAGCircuitones are optimized for programmatic access with already defined objects, while theQuantumCircuitmethods are more focussed on interactive human use.The new methods are:
add_input_var()add_captured_var()add_declared_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()
There are also new public attributes:
-
DAGCircuit.wireswill now also contain anyVarmanual variables in the circuit as well, as these are also classical data flow. -
A new method,
Var.new(), is added to manually construct a real-time classical variable that owns its memory. -
QuantumCircuit.compose()has two need keyword arguments,var_remapandinline_capturesto better support real-time classical variables.var_remapcan be used to rewriteVarnodes in the circuit argument as its instructions are inlined onto the base circuit. This can be used to avoid naming conflicts.inline_capturescan be set toTrue(defaults toFalse) to link allVarnodes tracked as “captures” in the argument circuit with the sameVarnodes in the base circuit, without attempting to redeclare the variables. This can be used, in combination withQuantumCircuit.copy_empty_like()’svars_mode="captures"handling, to build up a circuit layer by layer, containing variables. -
DAGCircuit.compose()has a new keyword argument,inline_captures, which can be set toTrueto inline “captured”Varnodes on the argument circuit onto the base circuit without redeclaring them. In conjunction with thevars_mode="captures"option to severalDAGCircuitmethods, this can be used to combine DAGs that operate on the same variables. -
QuantumCircuit.copy_empty_like()andDAGCircuit.copy_empty_like()have a new keyword argument,vars_modewhich controls how any memory-owningVarnodes are tracked in the output. By default ("alike"), the variables are declared in the same input/captured/local mode as the source. This can be set to"captures"to convert all variables to captures (useful withcompose()) or"drop"to remove them. -
A new
vars_modekeyword argument has been added to theDAGCircuitmethods:which has the same meaning as it does for
copy_empty_like(). -
All of the “standard gates” in the circuit library (
qiskit.circuit.library) can now be specified by string name for the entangling operations inTwoLocalcircuits, such asRealAmplitudesandEfficientSU2.
Primitives Features
-
The implementation
BackendEstimatorV2ofBaseEstimatorV2was added. This estimator supportsBackendV1andBackendV2.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import SparsePauliOp, random_hermitian backend = Fake7QPulseV1() estimator = BackendEstimatorV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) observable = SparsePauliOp("Z" * n_qubits) isa_circuit = transpile(circuit, backend=backend, optimization_level=1) isa_observable = observable.apply_layout(isa_circuit.layout) job = estimator.run([(isa_circuit, isa_observable)], precision=0.01) result = job.result() print(f"> Expectation value: {result[0].data.evs}") print(f"> Standard error: {result[0].data.stds}") print(f"> Metadata: {result[0].metadata}") -
The implementation
BackendSamplerV2ofBaseSamplerV2was added. This sampler supportsBackendV1andBackendV2that allowmemoryoption to compute bitstrings.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendSamplerV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import random_hermitian backend = Fake7QPulseV1() sampler = BackendSamplerV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) circuit.measure_all() isa_circuit = transpile(circuit, backend=backend, optimization_level=1) job = sampler.run([isa_circuit], shots=100) result = job.result() print(f"> bitstrings: {result[0].data.meas.get_bitstrings()}") print(f"> counts: {result[0].data.meas.get_counts()}") print(f"> Metadata: {result[0].metadata}") -
Added methods to join multiple
BitArrayobjects along various axes.concatenate(): join arrays along an existing axis of the arrays.concatenate_bits(): join arrays along the bit axis.concatenate_shots(): join arrays along the shots axis.
ba = BitArray.from_samples(['00', '11']) print(ba) # BitArray(<shape=(), num_shots=2, num_bits=2>) # reshape the bit array because `concatenate` requires an axis. ba_ = ba.reshape(1, 2) print(ba_) # BitArray(<shape=(1,), num_shots=2, num_bits=2>) ba2 = BitArray.concatenate([ba_, ba_]) print(ba2.get_bitstrings()) # ['00', '11', '00', '11'] # `concatenate_bits` and `concatenates_shots` do not require any axis. ba3 = BitArray.concatenate_bits([ba, ba]) print(ba3.get_bitstrings()) # ['0000', '1111'] ba4 = BitArray.concatenate_shots([ba, ba]) print(ba4.get_bitstrings()) # ['00', '11', '00', '11'] -
Added methods to generate a subset of
BitArrayobject by slicing along various axes.__getitem__(): slice the array along an existing axis of the array.slice_bits(): slice the array along the bit axis.slice_shots(): slice the array along the shot axis.
ba = BitArray.from_samples(['0000', '0001', '0010', '0011'], 4) print(ba) # BitArray(<shape=(), num_shots=4, num_bits=4>) print(ba.get_bitstrings()) # ['0000', '0001', '0010', '0011'] ba2 = ba.reshape(2, 2) print(ba2) # BitArray(<shape=(2,), num_shots=2, num_bits=2>) print(ba2[0].get_bitstrings()) # ['0000', '0001'] print(ba2[1].get_bitstrings()) # ['0010', '0011'] ba3 = ba.slice_bits([0, 2]) print(ba3.get_bitstrings()) # ['00', '01', '00', '01'] ba4 = ba.slice_shots([0, 2]) print(ba3.get_bitstrings()) # ['0000', '0010'] -
Added a method
transpose()to transpose aBitArray.ba = BitArray.from_samples(['00', '11']).reshape(2, 1, 1) print(ba) # BitArray(<shape=(2, 1), num_shots=1, num_bits=2>) print(ba.transpose()) # BitArray(<shape=(1, 2), num_shots=1, num_bits=2>) -
Added a method
expectation_values()to compute expectation values of diagonal operators.ba = BitArray.from_samples(['01', '11']) print(ba.expectation_values(["IZ", "ZI", "01"])) # [-1. 0. 0.5] -
DataBinnow satisfies theShapedprotocol. This means that everyDataBininstance now has the additional attributesshape(tuple[int, …]): the leading shape of every entry in the instancendim(int): the length ofshapesize(int): the product of the entries ofshape
The shape can be passed to the constructor.
-
Added mapping-like features to
DataBin, i.e.,__getitem__,__contains__,__iter__,keys(),values(), anditems().from qiskit import QuantumCircuit from qiskit.primitives import StatevectorSampler circuit = QuantumCircuit(1) circuit.h(0) circuit.measure_all() sampler = StatevectorSampler() result = sampler.run([circuit]).result() databin = result[0].data for creg, arr in databin.items(): print(creg, arr) for creg in databin: print(creg, databin[creg]) -
The subclass
SamplerPubResultofPubResultwas added, whichBaseSamplerV2implementations can return. The main feature added in this new subclass isjoin_data(), which joins together (a subset of) the contents ofdatainto a single object. This enables the following patterns:job_result = sampler.run([pub1, pub2, pub3], shots=123).result() # assuming all returned data entries are BitArrays counts1 = job_result[0].join_data().get_counts() bistrings2 = job_result[1].join_data().get_bitstrings() array3 = job_result[2].join_data().array
Providers Features
- The
BasicSimulatorpython-based simulator included inbasic_providernow supports running all the standard gates up to 3 qubits defined inqiskit.circuit.library.
Pulse Features
-
It is now possible to assign parameters to pulse
ScheduleandScheduleBlockobjects by specifying the parameter name as a string. The parameter name can be used to assign values to all parameters within theScheduleorScheduleBlockthat have the same name. Moreover, the parameter name of aParameterVectorcan be used to assign all values of the vector simultaneously (the list of values should therefore match the length of the vector). -
The
assign_parametersmethods ofScheduleandScheduleBlocknow support assigning aParameterVectorto a list of parameter values simultaneously in addition to assigning individualParameterinstances to individual values.
OpenQASM Features
- The OpenQASM 3 exporter supports manual-storage
Varnodes on circuits.
QPY Features
- QPY (
qiskit.qpy) format version 12 has been added, which includes support for memory-owningVarvariables. See Version 12 for more detail on the format changes.
Quantum Information Features
-
Added a new
apply_layout()method that is equivalent toapply_layout(). This method is used to apply aTranspileLayoutlayout from the transpiler to aPauliobservable that was built for an input circuit. This enables working withBaseEstimator/BaseEstimatorV2implementations and local transpilation when the input is of typePauli. For example:from qiskit.circuit.library import RealAmplitudes from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import GenericBackendV2 from qiskit.quantum_info import Pauli from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager psi = RealAmplitudes(num_qubits=2, reps=2) H1 = Pauli("XI") backend = GenericBackendV2(num_qubits=7) estimator = BackendEstimatorV2(backend=backend) thetas = [0, 1, 1, 2, 3, 5] pm = generate_preset_pass_manager(optimization_level=3, backend=backend) transpiled_psi = pm.run(psi) permuted_op = H1.apply_layout(transpiled_psi.layout) res = estimator.run([(transpiled_psi, permuted_op, thetas)]).result()where an input circuit is transpiled locally before it’s passed to
run(). Transpilation expands the original circuit from 2 to 7 qubits (the size ofbackend) and permutes its layout, which is then applied toH1usingapply_layout()to reflect the transformations performed bypm.run(). -
Adds the
PauliList.noncommutation_graph()andSparsePauliOp.noncommutation_graph()methods, exposing the construction of non-commutation graphs, recasting the measurement operator grouping problem into a graph coloring problem. This permits users to work with these graphs directly, for example to explore coloring algorithms other than the one used bySparsePauliOp.group_commuting(). -
The performance of
SparsePauliOp.to_matrix()has been greatly improved for both dense and sparse forms. By default, both will now take advantage of threaded parallelism available on your system, subject to theRAYON_NUM_THREADSenvironment variable. You can temporarily force serial execution using the newforce_serialBoolean argument toto_matrix().
Synthesis Features
-
The
KMSSynthesisLinearFunctionplugin for synthesizingLinearFunctionobjects now accepts two additional optionsuse_invertedanduse_transposed. These option modify the matrix on which the underlying synthesis algorithm runs by possibly inverting and/or transposing it, and then suitably adjust the synthesized circuit. By varying these options, we generally get different synthesized circuits, and in cases may obtain better results than for their default values. -
The
PMHSynthesisLinearFunctionplugin for synthesizingLinearFunctionobjects now accepts several additional options. The optionsection_sizeis passed to the underlying synthesis method. The optionsuse_invertedanduse_transposedmodify the matrix on which the underlying synthesis algorithm runs by possibly inverting and/or transposing it, and then suitably adjust the synthesized circuit. By varying these options, we generally get different synthesized circuits, and in cases may obtain better results than for their default values. -
Added a new argument,
use_dag, to theTwoQubitBasisDecomposer.__call__()andXXDecomposer.__call__()methods. This argument is used to control whether aDAGCircuitis returned when calling aTwoQubitBasisDecomposerorXXDecomposerinstance instead of the defaultQuantumCircuit. For example:from qiskit.circuit.library import CXGate from qiskit.quantum_info import random_unitary from qiskit.synthesis import TwoQubitBasisDecomposer decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="PSX") decomposer(random_unitary(4), use_dag=True)will return a
DAGCircuitwhen calling theTwoQubitBasisDecomposerinstancedecomposer. -
LieTrotter.synthesize()now usesQuantumCircuit.repeat()to generate additional repetitions of a Trotter step after the first Trotter step. This reduces the number ofQuantumCircuit.compose()calls by a factor ofrepsand significantly reduces the runtime for larger operators. -
Add a new synthesis method
synth_permutation_reverse_lnn_kms()of reverse permutations for linear nearest-neighbor architectures using Kutin, Moulton, Smithline method. This algorithm synthesizes the reverse permutation on qubits over a linear nearest-neighbor architecture using CX gates with depth . -
The
TwoQubitBasisDecomposerclass has been rewritten in Rust which greatly improves the runtime performance. -
The
TwoQubitWeylDecompositionsynthesis class has been rewritten in Rust for better performance.
Transpiler Features
-
Extended the commutation analysis performed by
CommutationCheckerto also work with abstract circuits, i.e. each operation in the input quantum circuit is now checked for its matrix representation before proceeding to the analysis step. Previously, the commutation analysis was only performed on physical circuits. In addition, each operation is now checked for its ability to be cached in the session commutation library. For example, this now enables computing whetherAnnotatedOperationcommute. This enables transpiler passes that rely onCommutationCheckerinternally, such asCommutativeCancellation, to run during earlier stages of a default transpilation pipeline (prior to basis translation). -
The transpiler pass
ElidePermutationsruns by default in the init stage for optimization levels 2 and 3. Intuitively, removingSwapGates andPermutationGates in a virtual circuit is almost always beneficial, as it makes the circuit shorter and easier to route. AsOptimizeSwapBeforeMeasureis a special case ofElidePermutations, it has been replaced by theElidePermuationspass as part of the init stage in optimization level 3 pass managers. -
Added a new optimization transpiler pass,
ElidePermutations, which is designed to run prior to the Layout Stage and will optimize away anySwapGates andPermutationGates in a circuit by permuting virtual qubits. For example, taking a circuit withSwapGates:
will remove the swaps when the pass is run:
from qiskit.transpiler.passes import ElidePermutations from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.swap(0, 1) qc.swap(2, 0) qc.cx(1, 0) qc.measure_all() ElidePermutations()(qc).draw("mpl")
The pass also sets the
virtual_permutation_layoutproperty set, storing the permutation of the virtual qubits at the end of the circuit that was optimized away. -
The
HLSConfignow has two additional optional arguments. The argumentplugin_selectioncan be set either to"sequential"or to"all". If set to “sequential” (default), for every higher-level-object theHighLevelSynthesispass will consider the specified methods sequentially, in the order they appear in the list, stopping at the first method that is able to synthesize the object. If set to “all”, all the specified methods will be considered, and the best synthesized circuit, according toplugin_evaluation_fnwill be chosen. The argumentplugin_evaluation_fnis an optional callable that evaluates the quality of the synthesized quantum circuit; a smaller value means a better circuit. When set toNone, the quality of the circuit is its size (i.e. the number of gates that it contains).The following example illustrates the new functionality:
from qiskit import QuantumCircuit from qiskit.circuit.library import LinearFunction from qiskit.synthesis.linear import random_invertible_binary_matrix from qiskit.transpiler.passes import HighLevelSynthesis, HLSConfig # Create a circuit with a linear function mat = random_invertible_binary_matrix(7, seed=37) qc = QuantumCircuit(7) qc.append(LinearFunction(mat), [0, 1, 2, 3, 4, 5, 6]) # Run different methods with different parameters, # choosing the best result in terms of depth. hls_config = HLSConfig( linear_function=[ ("pmh", {}), ("pmh", {"use_inverted": True}), ("pmh", {"use_transposed": True}), ("pmh", {"use_inverted": True, "use_transposed": True}), ("pmh", {"section_size": 1}), ("pmh", {"section_size": 3}), ("kms", {}), ("kms", {"use_inverted": True}), ], plugin_selection="all", plugin_evaluation_fn=lambda circuit: circuit.depth(), ) # synthesize qct = HighLevelSynthesis(hls_config=hls_config)(qc)In the example, we run multiple synthesis methods with different parameters, choosing the best circuit in terms of depth. Note that optimizing
circuit.size()instead would pick a different circuit. -
Added the
CommutativeCancellationpass to theinitstage of the preset pass managers for optimization levels 2 and 3. This enables the preset pass managers to cancel additional logical operations at the beginning of the compilation pipeline. -
The following analysis passes now accept constraints encoded in a
Targetthanks to a newtargetinput argument:The target constraints will have priority over user-provided constraints, for coherence with the rest of the transpiler pipeline.
-
Added a new method
Layout.inverse()which is used for taking the inverse of aLayoutobject. Added a new methodLayout.compose()which is used for composing twoLayoutobjects together. Added a new methodLayout.to_permutation()which is used for creating a permutation corresponding to aLayoutobject. -
Added a new reduction to the
OptimizeAnnotatedtranspiler pass. This reduction looks for annotated operations (objects of typeAnnotatedOperationthat consist of a base operation and a list of control, inverse and power modifiers) with the following properties:- the base operation needs to be synthesized (i.e. it’s not already supported by the target or belongs to the equivalence library)
- the definition circuit for can be expressed as – – with
In this case the modifiers can be moved to the -part only. As a specific example, controlled QFT-based adders have the form
control - [QFT -- U -- IQFT], which can be simplified toQFT -- control-[U] -- IQFT. By removing the controls overQFTandIQFTparts of the circuit, one obtains significantly fewer gates in the transpiled circuit. -
Added two new methods to the
DAGCircuitclass:qiskit.dagcircuit.DAGCircuit.op_successors()returns an iterator toDAGOpNodesuccessors of a node, andqiskit.dagcircuit.DAGCircuit.op_successors()returns an iterator toDAGOpNodepredecessors of a node. -
Added a new transpiler pass,
RemoveFinalReset, which will remove anyResetoperation which is the final instruction on a qubit wire. For example, taking a circuit with finalResets:
will remove the final resets when the pass is run:
from qiskit.transpiler.passes import RemoveFinalReset from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3, 1) qc.reset(0) qc.h(range(3)) qc.cx(1, 0) qc.measure(0, 0) qc.reset(range(3)) RemoveFinalReset()(qc).draw("mpl")
-
Added a new transpiler pass
StarPreRoutingwhich is designed to identify star connectivity subcircuits and then replace them with an optimal linear routing. This is useful for certain circuits that are composed of this circuit connectivity such as Bernstein-Vazirani and QFT. For example:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import StarPreRouting qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) StarPreRouting()(qc).draw("mpl")
Alternatively, an existing preset pass manager can be extended by:
from qiskit import QuantumCircuit from qiskit.transpiler import CouplingMap from qiskit.transpiler.passes import StarPreRouting from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager cm = CouplingMap.from_line(5) qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) pm = generate_preset_pass_manager(2, coupling_map=cm) pm.init += StarPreRouting() result = pm.run(qc) result.draw("mpl")
Visualization Features
- The text and Matplotlib circuit drawers (
QuantumCircuit.draw()) have minimal support for displaying expressions involving manual real-time variables. TheStoreoperation and the variable initializations are not yet supported; for large-scale dynamic circuits, we recommend using the OpenQASM 3 export capabilities (qasm3.dumps()) to get a textual representation of a circuit.
Misc. Features
- This release of Qiskit finalizes support for NumPy 2.0. Qiskit will continue to support both NumPy 1.x and 2.x for the foreseeable future.
Upgrade Notes
-
Removes the hard-coding of style options for
plot_histogram(). This allows Matplotlib style files to be faithfully applied to the figures. Users looking to go beyond the defaults set by Matplotlib can make their own style files, or pass a MatplotlibAxesobject toplot_histogramand post-apply any customizations. -
The
transpile()function has been upgraded to internally convert backend inputs of typeBackendV1toBackendV2, which allows the transpilation pipeline to now access the backend constraints through aTarget. This change does not require any user action.
Circuits Upgrade Notes
-
The random-number usage of
QuantumVolumehas changed, so you will get a different circuit for a fixed seed between older versions of Qiskit and this version. The random-unitary generation now uses more bits of entropy, so large circuits will be less biased. -
The internal
UnitaryGateinstances in the definition of aQuantumVolumecircuit will no longer have alabelfield set. Previously this was set to the stringsu4_<seed>where<seed>was a three-digit number denoting the seed of an internal Numpy pRNG instance for that gate. Doing this was a serious performance problem, and the seed ought not to have been useful; if you need to retrieve the matrix from the gate, simply use theGate.to_matrix()method.
Primitives Upgrade Notes
- The function
make_data_bin()no longer creates and returns aDataBinsubclass. It instead always returns theDataBinclass. However, it continues to exist for backwards compatibility, though will eventually be deprecated. All users should migrate to constructDataBininstances directly, instead of instantiating subclasses as output bymake_data_bin().
Providers Upgrade Notes
-
Implementations of
BackendV2(andBackendV1) may desire to update theirrun()methods to eagerly reject inputs containing typed classical variables (seeqiskit.circuit.classical) and theStoreinstruction, if they do not have support for them. The newStoreinstruction is treated by the transpiler as an always-available “directive” (likeBarrier); if your backends do not support this won’t be caught by thetranspiler.See Real-time variables for more information.
QPY Upgrade Notes
- The value of
qiskit.qpy.QPY_VERSIONis now 12.QPY_COMPATIBILITY_VERSIONis unchanged at 10.
Synthesis Upgrade Notes
- The
TwoQubitWeylDecompositionno longer will self-specialize into a subclass on creation. This was an internal detail of theTwoQubitWeylDecompositionpreviously, and was not a documented public behavior as all the subclasses behaved the same and were only used for internal dispatch. However, as it was discoverable behavior this release note is to document that this will no longer occur and all instances ofTwoQubitWeylDecompositionwill be of the same type. There is no change in behavior for public methods of the class.
Transpiler Upgrade Notes
- The preset
StagedPassManagerreturned for optimization level 2 bygenerate_preset_pass_manager()andlevel_2_pass_manager()have been reworked to provide a better balance between runtime and optimization. This means the output circuits will change compared to earlier releases. If you need an exact pass manager from level 2 in earlier releases you can either build it manually or use it from an earlier release and save the circuits withqpyto load with a newer release.
Misc. Upgrade Notes
- The minimum supported version of Windows is now Windows 10. In previous releases we did not explicitly list a minimum supported version of Windows and implicitly Windows 7, 8, and 8.1 may have worked (but were never tested). But due to Rust 1.78 dropping support for older versions of Windows Qiskit’s published binaries on PyPI will not support older versions of Windows starting with this release. If you’re using an older version of Windows you can likely still build Qiskit from source using an older Rust compiler (Qiskit’s minimum supported Rust version for building from source is currently 1.70) but older versions of Windows are not a supported platform and are untested.
Deprecation Notes
-
Support for running Qiskit with Python 3.8 has been deprecated and will be removed in the Qiskit 1.3.0 release. The 1.3.0 is the first release after Python 3.8 goes end of life and is no longer supported. [1] This means that starting in the 1.3.0 release you will need to upgrade the Python version you’re using to Python 3.9 or above.
Providers Deprecations
-
The abstract base classes
ProviderandProviderV1are now deprecated and will be removed in Qiskit 2.0.0. The abstraction offered by these interface definitions were not providing a substantial value; it solely encapsulated the attributesname,backends, and aget_backend(). A _provider_, as a concept, will continue existing as a collection of backends. If you’re implementing a provider currently you can adjust your code by simply removingProviderV1as the parent class of your implementation. As part of this you probably would want to add an implementation ofget_backendfor backwards compatibility. For example:def get_backend(self, name=None, **kwargs): backends = self.backends(name, **kwargs) if len(backends) > 1: raise QiskitBackendNotFoundError("More than one backend matches the criteria") if not backends: raise QiskitBackendNotFoundError("No backend matches the criteria") return backends[0]
Synthesis Deprecations
- The
TwoQubitWeylDecomposition.specialize()method is now deprecated and will be removed in the Qiskit 2.0.0 release. This method never had a public purpose and was unsafe for an end user to call as it would mutate the calculated decomposition in the object and produce invalid fields in the object. It was only used internally to construct a newTwoQubitWeylDecompositionobject. Despite this it was still a documented part of the public API for the class and is now being deprecated without any potential replacement. This release it always will raise aNotImplementedErrorwhen called because the specialization subclassing has been removed as part of the Rust rewrite of the class.
Transpiler Deprecations
-
The pass
qiskit.transpiler.passes.CXCancellationwas deprecated in favor ofInverseCancellation, which is more generic.CXCancellationis fully semantically equivalent toInverseCancellation([CXGate()]). -
The transpilation pass
qiskit.transpiler.passes.ALAPScheduleis now deprecated. It was pending for deprecation since Qiskit 0.37 (with Terra 0.21), released on June 2022. The pass is replaced byALAPScheduleAnalysis, which is an analysis pass. -
The transpilation pass
qiskit.transpiler.passes.ASAPScheduleis now deprecated. It was pending for deprecation since Qiskit 0.37 (with Terra 0.21), released on June 2022. It has been superseded byASAPScheduleAnalysisand the new scheduling workflow. -
The transpilation pass
qiskit.transpiler.passes.DynamicalDecouplingis now deprecated. It was pending for deprecation since Qiskit 0.37 (with Terra 0.21), released on June 2022. Instead, usePadDynamicalDecoupling, which performs the same function but requires scheduling and alignment analysis passes to run prior to it. -
The transpilation pass
qiskit.transpiler.passes.AlignMeasuresis now deprecated. It was pending for deprecation since Qiskit 0.37 (with Terra 0.21), released on June 2022. Instead, useConstrainedReschedule, which performs the same function and also supports aligning to additional timing constraints.
Visualization Deprecations
- The parameters
show_idleandshow_barrierin the timeline drawers had been replaced byidle_wiresandplot_barriersrespectively to match the circuit drawer parameters. Their previous names are now deprecated and will be removed in the next major release. The new parameters are fully equivalent.
Bug Fixes
-
Fixed an issue with the
qpy.dump()function where, when theuse_symengineflag was set to a truthy object that evaluated toTruebut was not actually the booleanTrue, the generated QPY payload would be corrupt. For example, if you setuse_symenginetoHAS_SYMENGINE, this object evaluates toTruewhen cast as a bool, but isn’t actuallyTrue. -
Fixed an issue with the
circuit_drawer()function andQuantumCircuit.draw()method when loading a matplotlib style via the user configuration file. -
Fixed an issue where the
ConstrainedRescheduletranspiler pass would previously error if the circuit contained aResetinstruction. This has been corrected so that the pass no longer errors, however an actual hardware may behave differently from what Qiskit scheduler assumes especially for mid-circuit measurements and resets. Qiskit scheduler raisesRuntimeWarningif it encounters circuit containing either. Fixed #10354 -
Fixed an issue with the
CommutationCheckerclass where it would error if a gate’snameattribute was UTF8 encoded. Previously only gate names with ascii encoding would work. Fixed #12501 -
Fixed an issue with the
SparsePauliOp.apply_layout()andPauli.apply_layout()methods when an invalid array with duplicate or negative indices were passed in for thelayoutargument. Previously this wouldn’t result in an error and the transformation performed would not be valid. These methods will now raise aQiskitErrorif duplicate indices or negative indices are provided as part of a layout. -
Fixed a performance issue in the
BackendSamplerV2andBackendEstimatorV2. Fixed #12290 -
Fixed an issue with the
convert_to_target()where the converter would incorrectly ignore control flow instructions if they were specified in theBackendConfiguration.supported_instructionsattribute which is the typical location that control flow instructions are specified in aBackendConfigurationobject. Fixed #11872. -
Fixed an issue with the
circuit_drawer()orQuantumCircuit.draw()when using themploutput option where the program would hang if the circuit being drawn had a ControlFlow operation in it and thefoldoption was set to -1 (meaning no fold). Fixed #12012. -
Fixed a bug in the conversion of custom pulse instructions to the legacy
qiskit.qobjformat. The bug was introduced in Qiskit 1.0.0 and caused conversion of instructions with custom pulse shapes to raise an error. After the fix, the conversion is carried out correctly, and the custom pulse is converted toWaveformas it should. Fixed #11828. -
A bug in
transpile()has been fixed where custominstruction_durations,dtandbackend_propertiesconstraints would be ignored when provided at the same time as a backend of typeBackendV2. The behavior after the fix is now independent of whether the provided backend is of typeBackendV1or typeBackendV2. Similarly, customtiming_constraintsare now overridden bytargetinputs but take precedence overBackendV1andBackendV2inputs. -
Calling
EquivalenceLibrary.set_entry()will now correctly update the internal graph object of the library. Previously, the metadata would be updated, but the graph structure would be unaltered, meaning that users likeBasisTranslatorwould still use the old rules. Fixed #11958. -
The
EvolvedOperatorAnsatznow correctly handles the case where the operators argument is an empty list. Previously, this would result in an error. -
From now on,
EvolvedOperatorAnsatzwill not have any qregs when thera are zero qubits, instead of having aQuantumRegisterinstance with zero qubits. This behavior aligns more consistently with its superclassQuantumCircuit. -
The method
Instruction.repeat()now moves a setconditionto the outer returnedInstructionand leave the inner gates of its definition unconditional. Previously, the method would leaveClassicalRegisterinstances within the inner definition, which was an invalid state, and would manifest itself as seemingly unrelated bugs later, such as during transpilation or export. Fixed #11935. -
Fixed an issue in the
InverseCancellationtranspiler pass where in some cases it would incorrectly cancel a self-inverse parameterized gate even if the parameter value didn’t match. Fixed #11815 -
Improve the decomposition of the gates
MCXGateandMCPhaseGatewithout using ancilla qubits, so that the number ofCXGatewill grow quadratically in the number of qubits and not exponentially. -
A bug that crashes the
convert_to_target()function when qubit properties (either T1, T2 or frequency) are missing was fixed. The missing property values inQubitPropertiesare filled withNone. -
BasePassManager.run()will no longer leak the previousPropertySetinto new workflows when called more than once. Previously, the samePropertySetas before would be used to initialize follow-on runs, which could mean that invalid property information was being given to tasks. The behavior now matches that of Qiskit 0.44. Fixed #11784. -
Pauli.evolve()now correctly handles quantum circuits containing ECR gates. Formerly they were not recognized as Clifford gates, and an error was raised. -
Fixed a bug in
Pauli.evolve()where evolving by a circuit with a name matching certain Clifford gates (‘cx’, ‘cz’, etc) would evolve the Pauli according to the name of the circuit, not by the contents of the circuit. This bug occurred only with the non-default optionframe='s'. -
Fixed a performance issue in the
qpy.load()function when deserializing QPY payloads with large numbers of qubits or clbits in a circuit. -
Fixed a bug in the handling of
default_alignmentargument ofbuild(). Inputs of typeAlignmentKindare now correctly processed as default alignments. -
Fixed a bug in
qiskit.pulse.utils.format_parameter_value()function that unintentionally converts large enough integer numbers into float values or causes unexpected rounding. See #11971 for details. -
Fix an issue in the
QDriftclass where the coefficients of the Hamiltonian were previously force to be positive by taking the absolute value of each coefficient. This has been corrected so that the negative coeffients’ signs are added back. -
A bug has been fixed in
convert_durations_to_dt()where the function would blindly apply a conversion from seconds todton circuit durations, independently of the original units of the attribute. This could lead to wrong orders of magnitude in the reported circuit durations. -
Fixed
SparsePauliOp.apply_layout()to work correctly with zero-qubit operators. For example, if you previously created a 0 qubit and applied a layout like:op = SparsePauliOp("") op.apply_layout(None, 3)this would have previously raised an error. Now this will correctly return an operator of the form:
SparsePauliOp(['III'], coeffs=[1.+0.j]) -
Fixed an oversight in the
Commuting2qGateRoutertranspiler pass where the qreg permutations were not added to the pass property set, so they would have to be tracked manually by the user. Now it’s possible to access the permutation through the output circuit’slayoutproperty and plug the pass into any transpilation pipeline without loss of information. -
Fixed a floating-point imprecision when scaling certain pulse units between seconds and nanoseconds. If the pulse was symbolically defined, an unnecessary floating-point error could be introduced by the scaling for certain builds of
symengine, which could manifest in unexpected results once the symbols were fully bound. Fixed #12392. -
The preset pass managers of
transpile()will no longer fail on circuits with control flow, if no hardware target or basis-gate set is specified. They will now treat such abstract targets as permitting all control-flow operations. Fixed #11906. -
The method
qiskit.instruction.Instruction.soft_compare()is meant to compare whether two gates match in their name, number of qubits, number of clbits, and the number of parameters. However, there was a typo where it would not check the number of qubits and number of clbits for a match. This resolves the apparent typo. -
The default
initplugin was not properly raising aTranspilerErrorwhen called with an invalid optimization level. -
Fixed an issue with the
Operator.from_circuit()constructor method where it would incorrectly interpret the final layout permutation resulting in an invalidOperatorbeing constructed. Previously, the final layout was processed without regards for the initial layout, i.e. the initialization was incorrect for all quantum circuits that have a non-trivial initial layout. -
Fixed a performance issue in
PassManager.run()when it is running over multiple circuits in parallel. It will no longer spend time serializing thePassManager(which is a requirement for parallel execution) when given multiple inputs if it is only going to process the inputs serially. -
Parameterwas updated so that instances that compare equal always have the same hash. Previously, only theParameter.uuidwas compared, soParameterinstances with different names could compare equal if they had been constructed using a common value for theuuidparameter (which is usually not passed explicitly). -
Fixed a bug in
plot_coupling_map()that caused the edges of the coupling map to be colored incorrectly. Fixed #12369. -
The OpenQASM 2.0 parser (
qasm2.load()andqasm2.loads()) can now evaluate gate-angle expressions including integer operands that would overflow the system-size integer. These will be evaluated in a double-precision floating-point context, just like the rest of the expression always has been. However, an arbitrarily large integer will not necessarily be exactly representable in double-precision floating-point, so there is a chance that however the circuit was generated, it had already lost all numerical precision modulo . -
Parameterinstances used as stand-ins forinputvariables in OpenQASM 3 programs will now have their names escaped to avoid collisions with built-in gates during the export to OpenQASM 3. Previously there could be a naming clash, and the exporter would generate invalid OpenQASM 3. -
Fixed bug in
QuantumCircuit.draw()that was causing custom style dictionaries for the Matplotlib drawer to be modified upon execution. -
QuantumCircuit.append()withcopy=True(its default) will now correctly copy instructions parametrized byParameterExpressioninstances, and not just byParameterinstances. -
The internal handling of custom circuit calibrations and
InstructionDurationshas been offloaded from thetranspile()function to the individual transpiler passes:DynamicalDecoupling,DynamicalDecoupling. Before, instruction durations from circuit calibrations would not be taken into account unless they were manually incorporated into instruction_durations input argument, but the passes that need it now analyze the circuit and pick the most relevant duration value according to the following priority order: target > custom input > circuit calibrations. -
Fixed a bug in
transpile()where thenum_processesargument would only be used ifdtorinstruction_durationswere provided.
Other Notes
-
Support for the arm64 macOS platform has been promoted from Tier 3 to Tier 1. Previously the platform was at Tier 3 because there was no available CI environment for testing Qiskit on the platform. Now that Github has made an arm64 macOS environment available to open source projects [1] we’re testing the platform along with the other Tier 1 supported platforms.
[1]
1.0.0rc1
Providers Upgrade Notes
-
The deprecated
qiskit.providers.fake_providermodule has been migrated to theqiskit-ibm-runtimePython package. For this reason, the following elements in theqiskit.providers.fake_providerhave been removed following their deprecation in Qiskit 0.46:qiskit.providers.fake_provider.FakeProviderqiskit.providers.fake_provider.FakeProviderForBackendV2qiskit.providers.fake_provider.FakeProviderFactoryqiskit.providers.fake_provider.fake_backends.FakeBackendV2- any fake backend contained in
qiskit.providers.fake_provider.backends(accessible through the provider) qiskit.providers.fake_provider.FakeQasmSimulatorqiskit.providers.fake_provider.FakeJobqiskit.providers.fake_provider.FakeQobj
To use the new fake provider module, you can run
pip install qiskit-ibm-runtimeand replace the qiskit import path (qiskit.providers.fake_provider) with the new import path (qiskit_ibm_runtime.fake_provider). Migration example:# Legacy path from qiskit.providers.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke() # New path # run "pip install qiskit-ibm-runtime" from qiskit_ibm_runtime.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke()Additionally, the following fake backends designed for special testing purposes have been superseded by the new
GenericBackendV2class, and are also removed following their deprecation in Qiskit 0.46:qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2`qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitPropsqiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple
Migration example to the new
GenericBackendV2class:# Legacy path from qiskit.providers.fake_provider import FakeBackend5QV2 backend = FakeBackend5QV2() # New path from qiskit.providers.fake_provider import GenericBackendV2 backend = GenericBackendV2(num_qubits=5) # note that this class will generate 5q backend with generic # properties that serves the same purpose as FakeBackend5QV2 # but will generate different results