Skip to main content
IBM Quantum Platform

Qiskit SDK 1.3 Versionshinweise


1.3.3

Vorspiel

Qiskit 1.3.3 ist ein kleineres Bugfix-Release für die 1.3 Serie.

Fehlerkorrekturen

  • Es wurde ein Fehler behoben, bei dem die Schrankenbeschriftungen falsch positioniert waren, wenn der Parameter reverse_bits = True in der QuantumCircuit.draw() methode. Der Fehler führte dazu, dass die Beschriftungen von Barriereoperationen falsch ausgerichtet waren, was zu Verwirrung bei der Darstellung von Schaltkreisen führen konnte. Behoben #13609.

  • Anwendung eines kleinen Regularisierungsfaktors gegen schlecht konditionierte hermitsche Matrizen in Super-Operator-Darstellungen.

  • Vergleiche von Delay anweisungen, auch innerhalb von Schaltkreisen, erfordern nun, dass sowohl die Einheiten als auch der Dauerwert gleich sind. Behebt #13812.

  • Es wurde ein Fehler in der CommutationChecker der fehlschlagen konnte, wenn man die Kommutationsbeziehung einer Zwei-Qubit-Pauli-Drehung mit einem Gatter prüfte, das sich nicht im Kommutations-Cache befindet. Zum Beispiel:

    import numpy as np
    from qiskit.circuit.library import RXXGate, RGate
    from qiskit.circuit.commutation_library import SessionCommutationChecker as scc
    
    res = scc.commute(RGate(2, 2), [1], [], RXXGate(np.pi / 2), [0, 1], [])

    Dieses Verhalten ist nun behoben und die Kommutationsbeziehung wird korrekt berechnet. Behoben #13742.

  • Ein Fehler wurde behoben, bei dem QuantumCircuit.qubit_stop_time() und QuantumCircuit.qubit_duration() eine falsche Zeit (Dauer) zurückgab. Das Problem wurde ausgelöst, wenn einige Qubits Anweisungen haben, andere Qubits aber im Leerlauf sind. Behebt #8729.

  • Es wurde ein Fehler im RemoveIdentityEquivalent transpiler-Durchgang behoben, bei dem Gatter in der Nähe der Identität bis zu einer globalen Phase aus der Schaltung entfernt wurden, die globale Phase der Schaltung aber nicht aktualisiert wurde. Insbesondere, RemoveIdentityEquivalent entfernt jetzt nicht parametrisierte GlobalPhaseGate gatter. Behebt #13778.

  • Es wurde ein Fehler in random_clifford() behoben, der verhinderte, dass die gesamte Clifford-Gruppe abgetastet wurde. Behebt #13606.

  • Wenn SabreLayout verwendet wird, um sowohl Layout als auch Routing gleichzeitig durchzuführen (wie es bei den Standardoptionen für transpile() und generate_preset_pass_manager()) auf einer Target oder CouplingMap mit disjunkten Verbindungen verwendet wird und die Eingabeschaltung in eine einzige Komponente der Kopplungskarte passt, wird die Routing-Permutation nun korrekt verfolgt.

    Zuvor wurden alle Qubits in der Kopplungskarte, die nicht, auch nicht indirekt, mit einem Qubit verbunden waren, das von der gerouteten Schaltung verwendet wurde, nicht in die endgültige Routing-Permutation einbezogen. Dies könnte zu einem überraschenden Verhalten führen, das weit vom Fehlerpunkt entfernt ist, selbst wenn die Kompilierung erfolgreich zu sein scheint, wie z. B. die Aufrufe von TranspileLayout.final_index_layout() aufrufen von KeyError.

    Dieser Fehler wirkte sich nicht auf Backends aus, die vollständig verbunden waren, was bei den meisten der Fall ist. Behebt #13732.


1.3.2

Vorspiel

Qiskit 1.3.2 ist ein kleineres Bugfix-Release für die 1.3 Serie.

Hinweise zum Upgrade der Synthese

  • Die High-Level-Synthese-Plugins für LinearFunction lösen nicht mehr einen Fehler aus, wenn ein anderes Objekt als LinearFunction an die Methode run übergeben wird. Stattdessen geben sie nun None zurück, was mit anderen Plugins übereinstimmt. Wenn Sie sich darauf verlassen haben, dass dieser Fehler ausgelöst wird, können Sie manuell eine Instanzprüfung durchführen.

Fehlerkorrekturen

  • Zuvor hatte der CommutationChecker eifrig die Kommutationsbeziehungen von Instructions mit float-only params als Schlüssel zur Abfrage der Beziehung. Dies könnte zu falschen Ergebnissen führen, wenn die Definition der Anweisung von zusätzlichen Informationen abhängt, die nicht nur das params attribut abhängt, wie z. B. im Fall von PauliEvolutionGate. Dieses Verhalten ist nun behoben, und der Kommutationsprüfer speichert Kommutationen nur noch für Qiskit-native Standardgatter. Bei benutzerdefinierten Gattern kann diese Änderung zu Leistungseinbußen führen, garantiert jedoch korrekte Ergebnisse, da eine unsichere Zwischenspeicherung vermieden wird.

  • Es wurde ein Fehler in der CommutationCheckerbehoben, bei dem die Überprüfung der Kommutierungsbeziehungen einer Anweisung mit nicht-numerischen Werten im params attribut (wie im Fall von PauliGate) einen Fehler auslösen konnte. Behoben #13570.

  • Die CommutationChecker behandelte die Kommutationen der CRXGate, CRYGate und CRZGate für Drehwinkel der Form (4k+2)π(4k + 2)\pi, mit k∈Zk \in \mathbb Z. In diesen Fällen wurde fälschlicherweise angenommen, dass diese Gatter mit jedem Gatter kommutieren. Dieses Verhalten ist nun behoben, und diese Gatter pendeln nur dann korrekt mit jedem Gatter, wenn der Drehwinkel ein Vielfaches von 4π4\pi ist.

  • Es wurde ein Fehler behoben, der dazu führte, dass die folgenden Funktionen der Schaltungsbibliothek Fehler produzierten, wenn sie mit num_qubits=1 aufgerufen wurden: efficient_su2(), real_amplitudes(), excitation_preserving() und pauli_two_design() (für ein einzelnes Qubit enthalten diese Schaltungen keine 2-Qubit-Gatter). Behoben #13480.

  • Es wurde ein Fehler behoben, bei dem eine Anweisung mit dem Namen "mcmt" fälschlicherweise an die High-Level-Syntheseroutine für eine MCMTGateübergeben wurde, was zu einem Fehler oder einem ungültigen Ergebnis führte. Dieses Problem könnte zum Beispiel auftreten, wenn die MCMT schaltkreis mit der Bezeichnung "mcmt" behandelt und implizit in eine Anweisung umgewandelt wird (z. B. beim Anhängen an einen anderen Schaltkreis). Behoben #13563.

  • Es wurde ein Fehler behoben, bei dem die Standard-Produktformelsynthese für PauliEvolutionGate nicht korrekt mit allen identischen Termen im Operator umgehen konnte. Der All-Identity-Term sollte eine globale Phase gleich -evolution_time einführen, lag aber um den Faktor 2 daneben und könnte bei parametrisierten Zeiten brechen. Behoben #13625. Behoben #13675. Behoben #13644.

  • Es wurde eine Inkonsistenz in der Schaltung behoben, die durch die Pauli-Evolution-Synthese mit SuzukiTrotter oder LieTrotter (die Standardmethode) erzeugt wurde. Bei parametrisierten Evolutionszeiten enthielten die resultierenden Schaltungen Parameter mit einem ungewollten komplexen Nullteil, der die Ausgabe von ParameterExpression.sympify(). Die Ausgabe enthält nun korrekt nur reelle Werte. Behoben #13642.

  • Ein Fehler wurde behoben, der dazu führte, dass PauliList.insert() mit qubit=True ein Phasenattribut mit der falschen Form erzeugte, wenn das ursprüngliche Objekt die Länge 1 hatte. Behoben #13623.

  • Es wurde ein Fehler in qasm3.Exporter behoben, der zum Absturz des Exporters führte, wenn er ein unitäres Tor aufgrund einer falschen Verarbeitung seines params Feldes behandelte. Behoben #13362.

  • Es wurde ein Fehler in der Target.instruction_supported() methode behoben, bei der Ziele mit self.num_qubits==None unabhängig von der unterstützten Basismenge immer False zurückgaben.

  • Es wurde ein Fehler im UnitarySynthesis transpiler-Durchgang, bei dem Blöcke von UnitaryGates auf 3 Qubits oder mehr nicht korrekt synthetisiert wurden. Dies führte z. B. dazu, dass die Schaltung mit dem zuletzt bearbeiteten Block überschrieben wurde oder dass es zu internen Paniken kam, wenn nach einem solchen Block Messungen durchgeführt wurden. Behoben #13586.

  • Es wurde ein Fehler im UnitarySynthesis transpiler-Durchgang behoben, bei dem non-2-qubit Gatter in die verfügbare 2-Qubit-Basis eingeschlossen wurden, wodurch TwoQubitWeylDecomposition aufgrund der Dimensionsinkongruenz in Panik geriet.

  • Ein Fehler wurde behoben, bei dem die Initialisierung SparsePauliOp mit einer großen Anzahl von Pauli-Y -Termen (typischerweise ≥100\geq 100 ) und ohne explizites coeffs zu einem Koeffizienten nahe bei 1, aber mit einem Fließkommafehler führte. Der Koeffizient ist jetzt standardmäßig korrekt 1. Behoben #13522.


1.3.1

Vorspiel

Qiskit 1.3.1 ist ein kleineres Bugfix-Release für die 1.3 Serie.

Hinweise zur Aktualisierung von Schaltkreisen

  • Die generische Kontrollmethode für Gatter vermeidet jetzt den Versuch, Gatter in eine unterstützte Basis zu übersetzen, wenn das Gatter bereits unterstützt wird. Dies kann die Synthese des gesteuerten Gatters geringfügig verändern, sollte aber die Anzahl der Zwei-Qubit-Gatter nicht erhöhen.

Fehlerkorrekturen


1.3.0

Vorspiel

Qiskit Version 1.3.0 bringt wesentliche Leistungs- und Qualitätsverbesserungen für den Transpiler. In dieser neuen Version von Qiskit wurden viele neue Funktionen, Fehlerbehebungen und Verbesserungen eingeführt, die wichtigsten davon sind:

  • Die Kerndatenstrukturen für die Transpilation in Qiskit wurden intern nach Rust portiert. Dazu gehören Komponenten wie die DAGCircuit, Target, EquivalenceLibraryund andere. Die öffentlichen APIs für alle diese Datenstrukturen bleiben unverändert, aber die Leistung hat sich nach den Umschreibungen verbessert.

  • Die meisten der vom Preset Pass Manager verwendeten Transpiler-Passes wurden nach Rust portiert, was bei den Benchpress-Benchmarks zu einer durchschnittlichen Verbesserung der Gesamtlaufzeit von 6x im Vergleich zu Qiskit 1.2.4 führte. Zu den besonders wirkungsvollen Pässen, die von den Überarbeitungen stark profitierten, gehörten die BasisTranslator, CommutationAnalysis, ConsolidateBlocks, und UnitarySynthesis. Eine vollständige Liste der portierten Pässe finden Sie in den Hinweisen zur Funktionsfreigabe.

  • Verbesserungen an der Schaltungsbibliothek, die die Qualität der Kompilierung und die Geschwindigkeit der Schaltungserstellung erhöhen. Die Operationen werden nun unterschieden in:

    • Strukturelle Operationen, die eine eindeutige Zerlegung haben und als Funktionen dargestellt werden, die eine QuantumCircuit (zum Beispiel: real_amplitudes()). Die meisten dieser Funktionen sind in Rust erstellt, was zu einer deutlich schnelleren Laufzeit beim Aufbau von Schaltungen führt.
    • Abstrakte Operationen, die mit Hilfe verschiedener Zerlegungen implementiert werden können, werden dargestellt als Gate oder Instruction dargestellt (zum Beispiel: PauliEvolutionGate). Dies ermöglicht den Aufbau eines abstrakten Quantenschaltkreises und lässt den Compiler die optimale Zerlegung wählen.

    Die Verwendung einer abstrakten Schaltungsbeschreibung ist besonders leistungsfähig in Kombination mit Verbesserungen des HighLevelSynthesis transpiler-Pass, der nun ungenutzte Hilfsqubits berücksichtigen kann, um die beste verfügbare Zerlegung für ein bestimmtes Gatter zu finden.

  • Die minimal unterstützte Version von Python ist jetzt 3.9, da Python 3.8 im Jahr 2024-10 ausläuft. Offizielle Unterstützung für Python 3.13 wurde ebenfalls in dieser Version hinzugefügt.

Schaltkreise Funktionen

  • Verbessert die Funktionalität von CommutationChecker um die Unterstützung für die folgenden parametrisierten Gatter mit freien Parametern: RXXGate, RYYGate, RZZGate, RZXGate, RXGate, RYGate, RZGate, PhaseGate, U1Gate, CRXGate, CRYGate, CRZGate, CPhaseGate. Vorher wurden diese nur mit gebundenen Parametern unterstützt.

  • Eine neue Funktion hinzugefügt quantum_volume() zur Erzeugung eines Quantenvolumen QuantumCircuit objekts wie in A definiert. Kreuz et al. Validierung von Quantencomputern mit Hilfe von randomisierten Modellschaltungen, Phys. Rev. A 100, 032328 (2019). Diese neue Funktion unterscheidet sich von der bestehenden QuantumVolume klasse dadurch, dass sie ein QuantumCircuit objekt zurückgibt, anstatt ein Unterklassenobjekt zu erzeugen. Zweitens ist diese neue Funktion multithreaded und in Rust implementiert, so dass sie die Ausgabeschaltung ~10x schneller erzeugt als die QuantumVolume klasse.

  • Verbesserung der Laufzeitleistung bei der Konstruktion der QuantumVolume klasse, wenn das Argument classical_permutation auf True gesetzt ist. Intern ruft es nun die quantum_volume() funktion auf, die in Rust geschrieben ist und ~10x schneller ist, wenn sie eine Quantenvolumenschaltung erzeugt.

  • Eine neue Funktion zur Schaltkreismanipulation wurde hinzugefügt pauli_twirl_2q_gates() die verwendet werden kann, um Pauli-Twirling auf einen gegebenen Schaltkreis anzuwenden. Dies funktioniert nur, wenn ein fester Satz von Zwei-Qubit-Toren gedreht wird, derzeit CXGate, ECRGate, CZGate, iSwapGate. Zum Beispiel:

    from qiskit.circuit import QuantumCircuit, pauli_twirl_2q_gates
    
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    twirled_circuit = pauli_twirl_2q_gates(qc, seed=123456)
    twirled_circuit.draw("mpl")
    _images/release_notes-1.png
  • Hinzugefügt wurden binäre arithmetische Gatter für die Inplace-Addition von zwei nn -qubit-Registern, also ∣a⟩∣b⟩↦∣a⟩∣a+b⟩|a\rangle |b\rangle \mapsto |a\rangle |a+b\rangle. Das ModularAdderGate implementiert die Addition modulo 2n2^n, das HalfAdderGate enthält ein Carry-Out-Qubit, und das FullAdderGate enthält sowohl ein Carry-In- als auch ein Carry-Out-Qubit. Einzelheiten und Beispiele finden Sie in der entsprechenden Dokumentation.

    Im Gegensatz zu den bestehenden Bibliotheksschaltungen, wie z. B CDKMRippleCarryAddererlaubt die Handhabung des abstrakten Gatters dem Compiler (oder dem Benutzer), die optimale Gattersynthese je nach Kontext der Schaltung zu wählen.

  • Hinzugefügt wurde die MultiplierGate für die Multiplikation von zwei nn -qubit Registern, also ∣a⟩∣b⟩∣0⟩↦∣a⟩∣b⟩∣a⋅b⟩|a\rangle |b\rangle |0\rangle \mapsto |a\rangle |b\rangle |a \cdot b\rangle. Siehe die Klassendokumentation für Details und Beispiele.

  • Die booleschen logischen Quantenschaltungen in qiskit.circuit.library haben jetzt äquivalente Darstellungen als Gate objekte, was ihre Verwendung mit HighLevelSynthesis transpiler-Pass und Plugin-Infrastruktur.

  • Spezialisierte Implementierungen von __eq__() wurden für alle Gatter der Standardbibliothek hinzugefügt. Die meisten Standard-Gates waren bereits auf diese Methode spezialisiert, einige wenige jedoch nicht, was zu erheblichen Verlangsamungen an unerwarteten Stellen führen konnte.

  • Hinzugefügt evolved_operator_ansatz(), hamiltonian_variational_ansatz(), und qaoa_ansatz() in die Schaltkreisbibliothek aufgenommen, um Variationsschaltungen auf der Grundlage von Operatorentwicklungen zu implementieren. evolved_operator_ansatz() und qaoa_ansatz() sind funktional äquivalent zu EvolvedOperatorAnsatz und QAOAAnsatzäquivalent, aber im Allgemeinen leistungsfähiger.

    Das Programm hamiltonian_variational_ansatz() ist darauf ausgelegt, einen einzelnen Hamiltonianer zu nehmen und ihn automatisch in kommutierende Terme aufzuspalten, um einen Hamiltonianer-Variationsansatz zu implementieren. Dies konnte bereits manuell mit der Taste EvolvedOperatorAnsatzerreicht werden, ist aber jetzt bequemer zu handhaben.

  • Hinzugefügt grover_operator() um eine Grover-Operator-Schaltung zu konstruieren, die z. B. für den Grover-Algorithmus und die Amplitudenschätzung/-verstärkung verwendet wird. Diese Funktion ist vergleichbar mit GroverOperator, verlangt aber nicht, dass Sie die Implementierung des mehrfach gesteuerten X-Gatters wählen, sondern lässt den Compiler die optimale Zerlegung bestimmen. Außerdem wird die Schaltung nicht in ein undurchsichtiges Gatter verpackt und ist schneller, da weniger Zerlegungen für die Transpilierung erforderlich sind.

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import grover_operator
    
    oracle = QuantumCircuit(2)
    oracle.z(0)  # good state = first qubit is |1>
    grover_op = grover_operator(oracle, insert_barriers=True)
    grover_op.draw('mpl')
    _images/release_notes-2.png
  • Ein neues Datenattribut, qiskit.circuit.CONTROL_FLOW_OP_NAMESsteht zur Verfügung, mit dem man leicht feststellen und überprüfen kann, ob eine bestimmte Instruction eine namentliche Kontrollflussoperation ist.

  • Die Standard-Äquivalenzbibliothek (SessionEquivalenceLibrary) verfügt nun über Regeln, die direkt zwischen den kontinuierlichen Ising-Interaktionen der Standardbibliothek 2q von Qiskit konvertieren können (z. B. CPhaseGate, RZZGate, RZXGateund so weiter) unter Verwendung lokaler Äquivalenzbeziehungen konvertieren können. Früher liefen mehrere dieser Umwandlungen über eine 2-CX-Form, was zu einer weniger effizienten Schaltungserstellung führte.

    Anmerkung

    Im Allgemeinen ist die BasisTranslator nicht garantiert, dass es die "beste" Äquivalenzrelation für eine gegebene Targetzu finden, aber es wird immer eine Äquivalenz finden, wenn eine existiert. Wir verlassen uns auf teurere Resynthese- und Gatter-Optimierungsläufe im Transpiler, um das Ergebnis zu verbessern. Diese Durchgänge sind derzeit für Basissätze mit einer kontinuierlich parametrisierten Zwei-Qubit-Wechselwirkung nicht so effektiv wie für diskrete supergesteuerte Zwei-Qubit-Wechselwirkungen.

  • Ein neues Argument "apply_synthesis" wurde zu Decomposehinzugefügt, das es dem Transpiler-Pass erlaubt, High-Level-Synthese anzuwenden, um Objekte zu zerlegen, die nur durch eine Syntheseroutine definiert sind. Zum Beispiel:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import Clifford
    from qiskit.transpiler.passes import Decompose
    
    cliff = Clifford(HGate())
    circuit = QuantumCircuit(1)
    circuit.append(cliff, [0])
    
    # Clifford has no .definition, it is only defined by synthesis
    nothing_happened = Decompose()(circuit)
    
    # this internally runs the HighLevelSynthesis pass to decompose the Clifford
    decomposed = Decompose(apply_synthesis=True)(circuit)
  • Hinzufügen der iqp() funktion zur Konstruktion von Schaltungen in Instantaneous Quantum Polynomial Time (IQP). Zusätzlich zu der bestehenden IQP klasse ermöglicht die Funktion auch die Konstruktion von zufälligen IQP-Schaltungen:

    from qiskit.circuit.library import random_iqp
    
    random_iqp = random_iqp(num_qubits=4)
    random_iqp.draw('mpl')
    _images/release_notes-3.png
  • Hinzufügen der MCMTGate hinzugefügt, um eine Multi-Control-Multi-Target-Operation als Gate darzustellen. Diese Gatterdarstellung der bestehenden MCMT schaltung ermöglicht es dem Compiler, die beste verfügbare Implementierung entsprechend der Anzahl und dem Zustand der in der Schaltung vorhandenen Hilfsqubits auszuwählen.

    Die gewünschte Implementierung kann durch Angabe des High-Level-Synthese-Plugins gewählt werden:

    from qiskit import QuantumCircuit, transpile
    from qiskit.circuit.library import MCMTGate, HGate
    from qiskit.transpiler.passes import HLSConfig  # used for the synthesis config
    
    mcmt = MCMTGate(HGate(), num_ctrl_qubits=5, num_target_qubits=3)
    
    circuit = QuantumCircuit(20)
    circuit.append(mcmt, range(mcmt.num_qubits))
    
    config = HLSConfig(mcmt=["vchain"])  # alternatively use the "noaux" method
    synthesized = transpile(circuit, hls_config=config)

    Zusätzlich unterstützt die MCMTGate auch benutzerdefinierte (d.h. offene) Kontrollzustände der Kontroll-Qubits.

  • Im Rahmen der Modernisierung der Schaltungsbibliothek wird jede der folgenden Quantenschaltungen entweder auch als Gate objekt dargestellt oder kann mit einer Synthesemethode konstruiert werden:

  • Die Klasse CommutationChecker klasse wurde in Rust umgeschrieben. Diese Klasse hat dieselbe Funktionalität und öffentliche API wie zuvor, ist aber in den meisten Fällen jetzt deutlich schneller.

  • PauliFeatureMap und ZZFeatureMap unterstützen nun die Angabe der Verschränkung als Wörterbuch, wobei die Schlüssel die Anzahl der Qubits darstellen und die Werte Listen von ganzzahligen Tupeln sind, die definieren, welche Qubits miteinander verschränkt sind. Dies ermöglicht eine größere Flexibilität bei der Erstellung von Merkmalskarten, die auf bestimmte Quantenalgorithmen zugeschnitten sind. Beispielverwendung:

    from qiskit.circuit.library import PauliFeatureMap
    entanglement = {
      1: [(0,), (2,)],
      2: [(0, 1), (1, 2)],
      3: [(0, 1, 2)],
    }
    qc = PauliFeatureMap(3, reps=2, paulis=['Z', 'ZZ', 'ZZZ'], entanglement=entanglement, insert_barriers=True)
    qc.decompose().draw('mpl')
  • Die count_ops() methode in QuantumCircuit wurde in Rust neu geschrieben. Er läuft jetzt zwischen 3 und 9 Mal schneller.

  • Funktionen der Schaltungsbibliothek hinzugefügt pauli_feature_map(), z_feature_map(), zz_feature_map() zum Aufbau von Pauli-Feature-Map-Schaltungen. Diese Funktionen sind etwa 8x schneller als die aktuellen Objekte der Schaltkreisbibliothek, PauliFeatureMap, ZFeatureMap, und ZZFeatureMapund werden sie in Zukunft ersetzen.

    Die Funktionen können als Drop-in-Ersatz verwendet werden:

    from qiskit.circuit.library import pauli_feature_map, PauliFeatureMap
    
    fm = pauli_feature_map(20, paulis=["z", "xx", "yyy"])
    also_fm = PauliFeatureMap(20, paulis=["z", "xx", "yyy"]).decompose()

Primitive Funktionen

  • Unterstützung für Daten der Ebene 1 wurde hinzugefügt in BackendSamplerV2hinzugefügt, ebenso wie die Unterstützung für die Übergabe von Optionen an die Methode run() der verpackten BackendV2. Die Laufoptionen können durch einen "run_options" Eintrag im options Wörterbuch angegeben werden, das an BackendSamplerV2. Der Eintrag "run_options" sollte ein Wörterbuch sein, das die Namen der Argumente auf Werte abbildet, die an die Methode run() des Backends übergeben werden. Wenn in den Ausführungsoptionen "meas_level = 1 " eingestellt ist, werden die Ergebnisse aus dem Backend als Level-1-Ergebnisse anstelle von Bit-Arrays (dem Level-2-Format) behandelt.

  • Estimator und StatevectorEstimator erwartungswerte auf stochastische Weise zurückgeben, wenn die Eingangsschaltung für einige Teilsysteme einen Reset beinhaltet. Das Ergebnis war bisher nicht reproduzierbar, kann aber jetzt reproduziert werden, wenn ein Zufallswert gesetzt wird. Zum Beispiel:

    from qiskit.primitives import StatevectorEstimator
    
    estimator = StatevectorEstimator(seed=123)

    oder:

    from qiskit.primitives import Estimator
    
    estimator = Estimator(options={"seed":123})

OpenQASM Funktionen

QPY-Funktionen

  • Hinzufügen eines neuen QPY-Formats Version 13, das eine Qiskit-eigene Darstellung von ParameterExpression objekten.

Quanteninformationsmerkmale

  • Die Leistung von SparsePauliOp.from_operator() wurde auf der Grundlage der in Qiskit 1.0 eingeführten Methoden zur Verbesserung des Algorithmus optimiert. Die Zerlegung eines 10q -Operators mit allen Pauli-Termen ist jetzt etwa fünfmal schneller als zuvor für vollständig dichte Matrizen und dauert etwa 40ms.

  • Ein neues Argument assume_unitary wurde zu qiskit.quantum_info.Operator.power(). Bei True verwenden wir eine schnellere Methode auf der Grundlage der Schur-Zerlegung, um Operator auf eine gebrochene Potenz zu erhöhen.

  • Hinzugefügt SparsePauliOp.to_sparse_list() um einen Operator in ein Sparse-List-Format zu konvertieren. Dies funktioniert in umgekehrter Weise wie SparsePauliOp.from_sparse_list(). Zum Beispiel:

    from qiskit.quantum_info import SparsePauliOp
    
    op = SparsePauliOp(["XIII", "IZZI"], coeffs=[1, 2])
    sparse = op.to_sparse_list()  # [("X", [3], 1), ("ZZ", [1, 2], 2)]
    
    other = SparsePauliOp.from_sparse_list(sparse, op.num_qubits)
    print(other == op)  # True
  • Die Leistung von Pauli.to_label() hat sich für große Paulis deutlich verbessert.

  • Die Methode Operator.power() hat einen neuen Parameter branch_cut_rotation. Damit kann der Verzweigungspunkt der Wurzel verschoben werden, was sich darauf auswirken kann, welche Matrix als Hauptwurzel gewählt wird. Standardmäßig ist sie auf eine kleine positive Drehung eingestellt, um Wurzeln von Operatoren mit einem reell-negativen Eigenwert (wie Pauli-Operatoren) stabiler gegenüber numerischen Präzisionsunterschieden zu machen.

  • Es wurde eine neue Observable-Klasse hinzugefügt. SparseObservable stellt Beobachtungswerte als Summe von Termen dar, ähnlich wie SparsePauliOp, jedoch mit zwei wesentlichen Unterschieden:

    1. Jeder vollständige Begriff wird (effektiv) als eine Reihe von (qubit, bit_term) Paaren gespeichert, ohne dass Qubits gespeichert werden, die die Identität für diesen Begriff erfahren. Dadurch wird die Speichernutzung von Observablen wie der gewichteten Summe von Paulis ∑iciZi\sum_i c_i Z_i erheblich verbessert.
    2. Das Alphabet der Ein-Qubit-Terme ist für den Operatorraum überkomplett; es kann Pauli-Operatoren darstellen (wie SparsePauliOp), aber auch Projektoren auf die Eigenzustände der Pauli-Operatoren, wie ∣0⟩⟨0⟩\lvert 0\rangle\langle 0\rangle. Solche Projektoren können auf der Hardware ebenso effizient gemessen werden wie der entsprechende Pauli-Operator, aber SparsePauliOp würde eine exponentielle Anzahl von Termen erfordern, um ∣0⟩⟨0∣⊗n{\lvert0\rangle\langle0\rvert}^{\otimes n} über nn Qubits darzustellen, während SparseObservable nur einen einzigen Term benötigt.

    Sie können konstruieren und manipulieren SparseObservable über eine Schnittstelle, die den Benutzern von SparsePauliOp:

    from qiskit.quantum_info import SparseObservable
    
    obs = SparseObservable.from_sparse_list([
      ("XZY", (2, 1, 0), 1.5j),
      ("+-", (100, 99), 0.5j),
      ("01", (50, 49), 0.5),
    ])

    SparseObservable wird derzeit nicht als Eingabeformat für die Primitive (qiskit.primitives), aber wir gehen davon aus, dass diese Schnittstellen in Zukunft um diese Formate erweitert werden.

Synthesefunktionen

  • Zusätzliche Synthesefunktionen synth_mcx_gray_code() und synth_mcx_noaux_v24() die mehrfach kontrollierte X-Gatter synthetisieren. Für diese Funktionen sind keine zusätzlichen Ancilla-Qubits erforderlich.

  • Zusätzliche Synthesefunktionen synth_c3x() und synth_c4x() die 3 gesteuerte bzw. 4 gesteuerte X-Gates synthetisieren.

  • Hinzufügen einer Synthesefunktion synth_mcx_n_dirty_i15() die ein mehrfach kontrolliertes X-Gatter mit kk Kontrollen unter Verwendung von k−2k - 2 dirty ancillary qubits synthetisiert und eine Schaltung mit höchstens 8∗k−68 * k - 6 CX-Gattern erzeugt, von Iten et. al. (arXiv:1501.06911).

  • Hinzufügen einer Synthesefunktion synth_mcx_n_clean_m15() die ein mehrfach kontrolliertes X-Gatter mit kk Kontrollen unter Verwendung von k−2k - 2 sauberen zusätzlichen Qubits synthetisiert und eine Schaltung mit höchstens 6∗k−66 * k - 6 CX-Gattern erzeugt, von Maslov ( arXiv:1508.03273 ).

  • Hinzufügen einer Synthesefunktion synth_mcx_1_clean_b95() zur Synthese eines mehrfach gesteuerten X-Gatters mit kk Steuerungen unter Verwendung eines einzigen sauberen zusätzlichen Qubits, das eine Schaltung mit höchstens 16∗k−816 * k - 8 CX-Gattern erzeugt, von Barenco et al. ( arXiv:quant-ph/9503016 ).

  • Hinzugefügt adder_qft_d00(), adder_ripple_c04(), und adder_ripple_v95() um die Addiergatter zu synthetisieren, ModularAdderGate, HalfAdderGate, und FullAdderGate.

  • Hinzugefügt multiplier_cumulative_h18() und multiplier_qft_r17() zur Synthese der MultiplierGate.

  • Hinzugefügt synth_mcmt_vchain() zur Synthese des Multi-Kontroll-Multi-Target-Gatters mit einer linearen Anzahl von Toffoli-Gattern und k-1 Hilfsqubits für k Kontrollqubits, zusammen mit dem High-Level-Synthese-Plugin MCMTSynthesisVChain.

  • Hinzufügen einer High-Level-Synthese-Plugin-Struktur für den MCMTGate, einschließlich der MCMTSynthesisNoAux (für keine Hilfsqubits), die bereits erwähnte MCMTSynthesisVChain (mit num_control - 1 Hilfsqubits), und die MCMTSynthesisDefault um den Compiler die optimale Dekomposition wählen zu lassen.

  • Die Funktion random_clifford() wurde nach Rust portiert, wodurch die Laufzeit um den Faktor 3 verbessert wurde.

  • Hinzugefügt ProductFormula.expand()die es ermöglicht, die Entwicklung einer Produktformel in einem spärlichen Pauli-Format zu betrachten. Wir können zum Beispiel das Format einer Trotter-Entwicklung zweiter Ordnung eines Hamiltonianers wie folgt abfragen:

    from qiskit.quantum_info import SparsePauliOp
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis.evolution import SuzukiTrotter
    
    hamiltonian = SparsePauliOp(["IX", "XI", "ZZ"], coeffs=[-1, -1, 1])
    evo = PauliEvolutionGate(hamiltonian, time=3.14)
    trotter = SuzukiTrotter(order=2)
    print(trotter.expand(evo))

    die Folgendes ausdrucken wird

    [('X', [0], -3.14), ('X', [1], -3.14), ('ZZ', [0, 1], 6.28),
    ('X', [1], -3.14), ('X', [0], -3.14)]
  • Hinzufügen der Plugin-Struktur für die PauliEvolutionGate. Das Standard-Plugin, PauliEvolutionSynthesisDefaultkonstruiert Schaltkreise wie zuvor, aber schneller, da es intern Rust verwendet. Je größer der Stromkreis ist (z. B.. durch die Hamiltongröße, die Anzahl der Zeitschritte oder die Suzuki-Trotter-Ordnung), desto größer ist der Geschwindigkeitszuwachs. Zum Beispiel wird ein 100-Qubit-Heisenberg-Hamiltonian mit 10 Zeitschritten und einer Trotter-Formel 4. Ordnung jetzt ~9.4x schneller konstruiert. Das neue Plugin, PauliEvolutionSynthesisRustiqverwendet den Synthesealgorithmus, der in der Arbeit " Faster and shorter synthesis of Hamiltonian simulation circuits" von (de) Brugière und Martiel " beschrieben und in Rustiq implementiert ist. Zum Beispiel:

    from qiskit.circuit import QuantumCircuit
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.compiler import transpile
    from qiskit.transpiler.passes import HLSConfig
    
    op = SparsePauliOp(["XXX", "YYY", "IZZ"])
    qc = QuantumCircuit(4)
    qc.append(PauliEvolutionGate(op), [0, 1, 3])
    config = HLSConfig(PauliEvolution=[("rustiq", {"upto_phase": False})])
    tqc = transpile(qc, basis_gates=["cx", "u"], hls_config=config)
    tqc.draw(output='mpl')
    _images/release_notes-4.png

    Dieser Codeschnipsel verwendet das Rustiq-Plugin zur Synthese von PauliEvolutionGate objekte in der Quantenschaltung qc. Das Plugin wird mit der zusätzlichen Option upto_phase = False aufgerufen, die es ermöglicht, kleinere Schaltkreise zu erhalten, allerdings auf Kosten der möglicherweise nicht erhaltenen globalen Phase. Die vollständige Liste der unterstützten Optionen finden Sie in der Dokumentation zu PauliEvolutionSynthesisRustiq.

  • Hafen synth_cz_depth_line_mr() nach Rust. Diese Funktion synthetisiert eine CZ-Schaltung für lineare Nächste-Nachbarn-Verbindungen (LNN), die auf der Methode von Maslov und Rötteler basiert. Bei einer binären Matrix 350x350 führt die Rust-Implementierung zu einer Beschleunigung von etwa 30x.

  • Portierung synth_permutation_reverse_lnn_kms() nach Rust, das eine umgekehrte Permutation für die LNN-Architektur unter Verwendung der Methode von Kutin, Moulton und Smithline synthetisiert.

  • Ein neues Argument preserve_order wurde zu ProductFormulahinzugefügt, das es erlaubt, die Pauli-Terme im Hamiltonian vor der Expansion der Produktformel neu zu ordnen, um die endgültige Schaltungstiefe zu komprimieren. Indem man dies auf False setzt, entsteht ein Term der Form

Z0Z1+X1X2+Y2Y3Z_0 Z_1 + X_1 X_2 + Y_2 Y_3

werden neu geordnet nach

Z0Z1+Y2Y3+X1X2Z_0 Z_1 + Y_2 Y_3 + X_1 X_2

was dazu führt, dass die Drehungen RZZ und RYY parallel durchgeführt werden, anstatt wie im ersten Teil drei aufeinanderfolgende Drehungen.

Diese Option kann über die Plugin-Schnittstelle eingestellt werden:

from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis.evolution import SuzukiTrotter
from qiskit.transpiler.passes import HLSConfig

op = SparsePauliOp(["XXII", "IYYI", "IIZZ"])
time, reps = 0.1, 1

synthesis = SuzukiTrotter(order=2, reps=reps)
hls_config = HLSConfig(PauliEvolution=[("default", {"preserve_order": False})])

circuit = QuantumCircuit(op.num_qubits)
circuit.append(PauliEvolutionGate(op, time), circuit.qubits)

tqc = transpile(circuit, basis_gates=["u", "cx"], hls_config=hls_config)
tqc.draw('mpl')
_images/release_notes-5.png

Transpiler-Funktionen

  • Fügen Sie das Argument matrix_based zum CollectCliffords transpiler-Pass. Wenn der neue Parameter matrix_based=True ist, kann der CollectCliffords transpiler-Durchgang unitäre Gatter sammeln, die für bestimmte Parameter Clifford-Gatter sind, zum Beispiel RZGate gatter mit Winkeln, die Vielfache von π/2\pi / 2 sind.

  • Der RemoveIdentityEquivalent der Transpilerdurchlauf wird nun als Teil der voreingestellten Durchlaufmanager auf den Optimierungsstufen 2 und 3 ausgeführt. Der Pass wird während der Phasen init und optimization ausgeführt, da die Optimierungen, die er anwendet, in beiden Phasen gültig sind und der Pass schnell ausgeführt werden kann.

  • Mehrere High-Level-Synthese-Plugins für die Synthese eines MCXGate:

    Sowie:

    • MCXSynthesisDefaultfür die Wahl der effizientesten Synthesemethode auf der Grundlage der Anzahl der verfügbaren sauberen und schmutzigen Ancilla-Qubits.

    Betrachten wir als Beispiel die Umsetzung der folgenden Schaltung:

    from qiskit.circuit import QuantumCircuit
    from qiskit.compiler import transpile
    
    qc = QuantumCircuit(7)
    qc.x(0)
    qc.mcx([0, 1, 2, 3], [4])
    qc.mcx([0, 1, 2, 3, 4], [5])
    qc.mcx([0, 1, 2, 3, 4, 5], [6])
    
    transpile(qc).draw('mpl', fold=-1)
    _images/release_notes-6.png

    Für das erste MCX-Gatter können die Qubits 5 und 6 als saubere Ancillas verwendet werden, und es wird die beste verfügbare Synthesemethode synth_mcx_n_clean_m15 gewählt. Für das zweite MCX-Gatter kann das Qubit 6 als saubere Ancilla verwendet werden, die Methode synth_mcx_n_clean_m15 gilt nicht mehr, also wird die Methode synth_mcx_1_clean_b95 gewählt. Für das dritte MCX-Gatter gibt es keine Ancilla-Qubits, und es wird die Methode synth_mcx_noaux_v24 gewählt.

  • Der SabreLayout transpiler-Durchlauf wurde aktualisiert, um standardmäßig zwei oder drei zusätzliche Layoutversuche durchzuführen, unabhängig vom Wert des Schlüsselwortarguments layout_trials . Ein triviales Layout und seine Umkehrung sind für alle Backends enthalten, genau wie der DenseLayout studie, die in 1.2.0 hinzugefügt wurde. Zusätzlich werden die größten Ringe auf einem IBM backend heavy hex connectivity graph hinzugefügt, wenn die Backends 127, 133 oder 156 Qubits haben. Dies kann ein guter Ausgangspunkt für einige Schaltungen auf diesen häufig verwendeten Backends sein, während es für alle anderen nur ein zusätzlicher "Zufallsversuch" ist.

  • Die DAGCircuit wurde in Rust neu implementiert. Diese Neufassung der Klasse Python sollte vollständig API-kompatibel mit der früheren Implementierung von Python sein. Während die Klasse zuvor mit rustworkx implementiert wurde, für das die zugrunde liegende Datengraphenstruktur in Rust existiert, wurde die Implementierung der Klasse und aller Daten in Python gelebt. Diese neue Version von DAGCircuit speichert alle Daten in der nativen Rust-Darstellung und ist aufgrund der komprimierten Qubit- und Clbit-Darstellung, die für ruhende Anweisungen entwickelt wurde, speichereffizienter. Es ermöglicht auch Transpilerübergänge, um eine DAGCircuit von Rust aus zu manipulieren, was Verbesserungen der Leistung ermöglicht.

  • Ein neues Argument qubits_initially_zero wurde hinzugefügt zu qiskit.compiler.transpile(), generate_preset_pass_manager(), und zu PassManagerConfig. Bei der Voreinstellung True wird davon ausgegangen, dass sich die Qubits anfangs im Zustand ∣0⟩|0\rangle befinden, was zusätzliche Optimierungsmöglichkeiten für einzelne Transpiler-Durchläufe bieten kann. Insbesondere wird der HighLevelSynthesis transpiler-Durchgang eine bessere Zerlegung für jedes MCXGate gatter in einer Schaltung eine bessere Zerlegung, wenn ein ungenutztes Hilfsqubit im Zustand ∣0⟩|0\rangle verfügbar ist.

    Es gibt jedoch Fälle, in denen qubits_initially_zero auf False gesetzt werden sollte, z. B. beim Transpilieren für Backends, die Qubits nicht ordnungsgemäß initialisieren, oder beim manuellen Aufrufen von Transpilerdurchläufen auf Unterschaltungen einer größeren Quantenschaltung.

  • Der Konstruktor für den HighLevelSynthesis transpiler pass akzeptiert jetzt ein zusätzliches Argument: qubits_initially_zero. Wenn er auf True gesetzt ist, nimmt der Pass an, dass sich die Qubits anfangs im Zustand ∣0⟩|0\rangle befinden. Außerdem verfolgt der Durchlauf die sauberen und schmutzigen Hilfs-Qubits während des gesamten Durchlaufs und gibt diese Informationen über die kwargs num_clean_ancillas und num_dirty_ancillas an die Plugins weiter.

  • Verbesserte Behandlung von Ancilla-Qubits im HighLevelSynthesis transpiler-Durchgang. Eine Schaltung kann zum Beispiel benutzerdefinierte Gatter haben, deren Definitionen Folgendes enthalten MCXGates. Nun können die Synthesealgorithmen für die inneren MCXGates die Ancilla-Qubits verwenden, die in der globalen Schaltung verfügbar sind, aber außerhalb der Definitionen der benutzerdefinierten Gatter liegen.

  • Eine neue Methode wurde hinzugefügt DAGCircuit.control_flow_op_nodes() hinzugefügt, die einen schnellen Weg bietet, um alle DAGOpNode in einer DAGCircuit die a enthalten ControlFlowOp. Dies war möglich, bevor man die DAGCircuit.op_nodes() methode und die Übergabe der ControlFlowOp klasse als Filter zu übergeben, aber diese neue Funktion wird den Vorgang schneller durchführen.

  • Die meisten der in den voreingestellten Pass-Managern verwendeten Transpiler-Pässe werden von generate_preset_pass_manager() zurückgegebenen und intern von transpile() verwendet werden, wurden nach Rust portiert. Dadurch konnte die Laufzeitleistung jedes Durchgangs erheblich verbessert werden, was zu einer signifikanten Verbesserung der Gesamteffizienz des Transpilers geführt hat. Die Liste der in dieser Version nach Rust portierten Pässe sind:

  • Es wurde ein neuer Transpiler-Pass hinzugefügt, RemoveIdentityEquivalent der verwendet wird, um Gatter zu entfernen, die bis zu einer gewissen Toleranz mit einer Identität äquivalent sind. Wenn Sie zum Beispiel eine Schaltung wie diese hätten:

    _images/release_notes-7.png

    die Ausführung des Passes würde die CPhaseGate:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import RemoveIdentityEquivalent
    
    qc = QuantumCircuit(2)
    qc.cp(1e-20, 0, 1)
    
    removal_pass = RemoveIdentityEquivalent()
    result = removal_pass(qc)
    result.draw("mpl")
    _images/release_notes-8.png
  • Der ConsolidateBlocks pass wird nun das Äquivalent des Collect2qBlocks passes intern ausgeführt, wenn er nicht zuvor in einem Passmanager ausgeführt wurde. Zuvor, Collect2qBlocks oder Collect1qRuns musste vorher ausgeführt werden ConsolidateBlocks für ConsolidateBlocks etwas tun kann. Indem die Erfassung intern erfolgt, wird der Overhead des Durchlaufs reduziert. Wenn Collect2qBlocks oder Collect1qRuns vor der Ausführung von ConsolidateBlocksausgeführt werden, werden die gesammelten Durchläufe dieser Durchläufe aus dem Eigenschaftssatz verwendet, und das Verhalten des Durchlaufs ändert sich nicht.

  • Der RemoveDiagonalGatesBeforeMeasure transpiler-Durchgang wurde um weitere diagonale Gates erweitert: PhaseGate, CPhaseGate, CSGate, CSdgGate und CCZGate. Darüber hinaus wurde der Code der RemoveDiagonalGatesBeforeMeasure nach Rust portiert und ist nun x20 schneller für eine 20-Qubit-Schaltung.

Visualisierungsfunktionen

  • Die Funktion timeline_drawer() visualisierungsfunktion hat ein neues Argument target, das zur Angabe eines Target objekt für die Visualisierung anzugeben. Standardmäßig verwendet die Funktion die Instruction.duration um die Dauer einer bestimmten Anweisung zu ermitteln, aber durch die Angabe des Ziels werden stattdessen die Timing-Details innerhalb des Ziels genutzt.

Bekannte Probleme

  • Bei der Verwendung der QPY-Formate 10, 11 oder 12 mit Schaltungen, die ParameterExpressions enthalten, wenn die Version des Pakets symengine , die in der Umgebung installiert ist, die die Nutzlast erzeugt hat (qpy.dump()) nicht mit der Version von symengine übereinstimmt, die in der Umgebung installiert ist, in der die Nutzlast geladen wird (qpy.load()), erhalten Sie eine Fehlermeldung. Wenn dieser Fehler auftritt, installieren Sie die Version symengine aus der Fehlermeldung, bevor Sie qpy.load(). Bei den QPY-Formatversionen 13 oder später (oder vor 10) tritt dieses Problem nicht auf. Wenn Sie also Objekte als Teil Ihrer ParameterExpression objekte als Teil Ihrer Schaltung oder beliebige ScheduleBlock objekte serialisieren, wird empfohlen, die Version 13 zu verwenden, um dieses Problem in Zukunft zu vermeiden.

Anmerkungen zu Upgrades

  • Die folgenden Klassen verwenden nun die Operation X\sqrt{X}, um den Pauli-Y-Operator zu diagonalisieren: PauliEvolutionGate, EvolvedOperatorAnsatz, und PauliFeatureMap. Zuvor verwendeten diese Klassen entweder HSH S oder RX(−π/2)R_X(-\pi/2) als Basistransformation. Die Verwendung der Operation X\sqrt{X}, dargestellt durch das Symbol SXGate dargestellt wird, ist effizienter, da sie nur ein einziges Gatter verwendet, das als Singleton implementiert ist.

    Wenn Sie sich auf die vorherige Verwendung von Gattern verlassen haben, empfehlen wir, die Schaltungen mit Qiskit 1.2 zu erstellen und sie mit qpy.dump()zu exportieren, oder ein eigenes TransformationPasszu schreiben, der die Übersetzung in das von Ihnen gewünschte Basiswechsel-Gatter vornimmt.

  • Die minimal unterstützte Version von Python ist jetzt 3.9, diese wurde von der vorherigen minimal unterstützten Version von 3.8 angehoben. Diese Änderung war notwendig, weil das Upstream-Projekt cPython Python 3.8 nicht mehr unterstützt.

Hinweise zur Aktualisierung von Schaltkreisen

  • Die QuantumVolume klasse erzeugt Schaltkreise mit verschiedenen unitären Matrizen und Permutationen für einen gegebenen Startwert aus der vorherigen Qiskit-Version. Dies ist darauf zurückzuführen, dass ein neuer interner Zufallszahlengenerator für die Schaltungsgenerierung verwendet wird, der die Schaltung schneller erzeugt. Wenn Sie eine exakte Schaltung mit demselben Seed benötigen, können Sie die frühere Version von Qiskit verwenden und die Schaltung mit dem Argument flatten=True generieren und die Schaltung mit qpy.dump() exportieren und dann mit dieser Version laden.

Hinweise zum Upgrade von Primitives

  • Bei Verwendung von BackendSamplerV2werden die Schaltkreis-Metadaten nicht mehr gelöscht, bevor die Schaltkreise an die Methode run() der verpackten BackendV2 instanz übergeben werden. Wenn Sie sich bisher auf dieses Verhalten verlassen haben, können Sie die Metadaten manuell löschen, bevor Sie BackendSamplerV2.run() durch den Aufruf von circuit.metadata.clear()

QPY-Upgrade-Hinweise

  • Die Funktion qpy.dump() funktion gibt nun standardmäßig die Formatversion 13 aus. Das bedeutet, dass die mit dieser Funktion erzeugten Nutzdaten standardmäßig nur mit Qiskit 1.3.0 oder höher kompatibel sind. Wenn die Nutzlast von einer früheren Version von Qiskit geladen werden muss, verwenden Sie das version Flag auf qpy.dump() um die entsprechende Version auszugeben. Weitere Einzelheiten finden Sie unter QPY-Kompatibilität.

Hinweise zum Transpiler-Upgrade

  • DAGNode objekte (und ihre Unterklassen DAGInNode, DAGOutNode, und DAGOpNode) geben nicht länger Verweise auf dasselbe zugrunde liegende Objekt von DAGCircuit methoden zurück. Dies war noch nie eine Garantie dafür, dass alle zurückgegebenen Knoten ein gemeinsamer Verweis auf dasselbe Objekt sein würden. Mit der Migration der DAGCircuit nach Rust wird eine neue DAGNode instanz erzeugt, wenn ein Knoten an Python zurückgegeben wird. Diese Objekte werden mit == oder ähnlichen Prüfungen, die sich auf __eq__ stützen, als gleich bewertet, aber nicht mehr als dasselbe Objekt identifiziert.

  • Die DAGOpNode instanzen, die von der DAGCircuit zurückgegebenen Instanzen sind keine gemeinsamen Verweise auf die in der DAG gespeicherten zugrunde liegenden Daten mehr. In früheren Versionen war es möglich, etwas zu tun wie:

    for node in dag.op_nodes():
        node.op = new_op

    diese Art der Mutation war jedoch immer unsicher, da sie die interne Zwischenspeicherung der DAG zerstören und die Datenstruktur beschädigen konnte. Stattdessen sollten Sie die API verwenden, die von DAGCircuit für Mutationen wie DAGCircuit.substitute_node() oder DAGCircuit.substitute_node_with_dag(). Zum Beispiel würde der obige Codeblock zu:

    for node in dag.op_nodes():
      dag.substitute_node(node, new_op)

    Dies ähnelt einer Upgrade-Notiz von 1.2.0, in der dies für die Mutation des DAGOpNode.op attributs, nicht des DAGOpNode selbst. In 1.3 gilt dies jedoch für das gesamte Objekt, nicht nur für das innere Attribut op . Im Allgemeinen war diese Art von Mutation immer unsolide und wurde nicht unterstützt, konnte aber früher in einigen Fällen funktionieren.

  • Die transpile() geht nun davon aus, dass sich die Qubits zunächst im Zustand ∣0⟩|0\rangle befinden. Um diese Annahme zu vermeiden, kann man das Argument qubits_initially_zero auf False setzen.

Hinweise zu veralteten Versionen

  • Das Modul qiskit.pulse modul und alle damit verbundenen Funktionen sind nun veraltet und werden in Qiskit 2.0.0 entfernt. Dies liegt daran, dass der primäre Backend-Anbieter mit Puls-Unterstützung IBM ist und der Zugriff auf Puls-Ebene derzeit nur auf einer Teilmenge der Backends von IBM unterstützt wird. Ebenso haben sie angekündigt, dass der Zugriff auf die Pulsebene im Jahr 2025 abgeschafft wird. Ohne den größten Anbieter, der die Funktion nutzt und den Pulse-Zugriff unterstützt, wird die Bedeutung der Funktion für Qiskit erheblich geschmälert und gegen den fortlaufenden Wartungsaufwand des Pakets abgewogen, das abgeschafft wird.

    Die Verwerfung umfasst den gesamten Puls-Code in qiskit.pulse sowie Funktionen, die von Puls abhängen oder damit verbunden sind, wie Pulsvisualisierung, Serialisierung und Unterstützung für benutzerdefinierte Kalibrierung. Weitere Einzelheiten finden Sie in den Abschnitten über die Veralterung weiter unten.

    Das Pulse-Paket als Ganzes wird zusammen mit den direkt verwandten Komponenten in Qiskit in das Qiskit Dynamics-Repository verschoben, um die Simulation von Pulsen und Low-Level-Steuerung weiter zu ermöglichen. Qiskit 1.x wird weiterhin den Support für das qiskit.pulse bis zum Ende seiner Nutzungsdauer unterstützen.

Veraltete Schaltungen

  • Veraltet das Instruction.condition attribut und die Instruction.c_if() methode. Sie werden in Qiskit 2.0 entfernt, zusammen mit allen Verwendungen im Qiskit-Datenmodell. Diese Funktionalität wurde ersetzt durch die IfElseOp ersetzt, die zur Beschreibung einer klassischen Bedingung in einem Schaltkreis verwendet werden kann. Zum Beispiel kann eine Schaltung mit Instruction.c_if() wie:

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.x(0).c_if(0, 1)
    qc.z(1.c_if(1, 0)
    qc.measure(0, 0)
    qc.measure(1, 1)

    Kann wie folgt erneut geschrieben werden:

    qc = QuantumCircuit(2, 2)
    qc.h(0)
    with qc.if_test((qc.clbits[0], True)):
        qc.x(0)
    with qc.if_test((qc.clbits[1], False)):
        qc.z(1)
    qc.measure(0, 0)
    qc.measure(1, 1)

    Der inzwischen veraltete ConvertConditionsToIfOps transpiler-Pass kann verwendet werden, um diese Umwandlung für bestehende Schaltungen zu automatisieren.


  • Im Rahmen der Abkündigung des Qiskit Pulse-Pakets werden auch die folgenden Abhängigkeiten abgekündigt:

  • Die QuantumCircuit.unit und QuantumCircuit.duration attribute sind veraltet und werden in Qiskit 2.0.0 entfernt. Diese Attribute wurden verwendet, um die geschätzte Dauer und die Einheit dieser Dauer für die Ausführung in der Schaltung zu ermitteln. Die Werte dieser Attribute waren jedoch immer begrenzt, da sie nur dann korrekt ausgefüllt werden konnten, wenn der Transpiler mit den richtigen Einstellungen ausgeführt wurde. Die Dauer war auch nur eine Schätzung auf der Grundlage des längsten Pfades über die Summe der Dauer von DAGCircuit und würde niemals den Kontrollfluss oder die Bedingungen in der Schaltung korrekt berücksichtigen.

  • Die DAGCircuit.unit und DAGCircuit.duration attribute sind veraltet und werden in Qiskit 2.0.0 entfernt. Diese Attribute wurden verwendet, um die geschätzte Dauer und die Einheit dieser Dauer für die Ausführung in der Schaltung zu ermitteln. Die Werte dieser Attribute waren jedoch immer begrenzt, da sie nur dann korrekt ausgefüllt werden konnten, wenn der Transpiler mit den richtigen Einstellungen ausgeführt wurde. Die Dauer war auch nur eine Schätzung auf der Grundlage des längsten Pfades über die Summe der Dauer von DAGCircuit und würde niemals den Kontrollfluss oder die Bedingungen in der Schaltung korrekt berücksichtigen.

  • Die Instruction.duration und Instruction.unit attribute sind veraltet und werden in Qiskit 2.0.0 entfernt. Dies beinhaltet das Setzen der unit oder duration Argumente für jede qiskit.circuit.Instruction oder Unterklasse. Diese Attribute wurden verwendet, um einer einzelnen Anweisung eine individuelle Ausführungsdauer und eine Einheit für diese Dauer zuzuordnen. Die Quelle der Wahrheit über die Dauer eines Tores ist jedoch die BackendV2 Target die die Dauer für jede vom Backend unterstützte Anweisung enthält. Die Dauer einer Anweisung ist nicht etwas, das normalerweise vom Benutzer eingestellt werden kann, sondern eine unveränderliche Eigenschaft des Backends. Wenn Sie diese Fähigkeit zuvor genutzt haben, um mit verschiedenen Laufzeiten für Gates zu experimentieren, können Sie das InstructionProperties.duration feld in einem gegebenen Target ändern, um eine benutzerdefinierte Dauer für eine Anweisung in einem Backend festzulegen (die Einheit ist immer in Sekunden in der Target).

Anbieter-Deprecations

  • Die Methode BasicSimulator.configuration() methode ist veraltet und wird in 2.0.0 entfernt werden. Diese Methode gibt eine alte providers.models.BackendConfiguration Instanz zurück, die Teil des veralteten BackendV1 Modells ist. Dieses Modell wurde ersetzt durch BackendV2ersetzt, bei dem die Constraints direkt in der Backend-Instanz oder in der zugrunde liegenden Target (backend.target).

    Im Folgenden finden Sie eine Kurzanleitung für den Zugriff auf die gängigsten BackendConfiguration Attribute im BackendV2 modell:

    BackendV1 model (deprecated) ------------> BackendV2 model
    ----------------------------               ---------------
    backend.configuration().backend_name       backend.name
    backend.configuration().backend_version    backend.backend_version
    backend.configuration().n_qubits           backend.num_qubits
    backend.configuration().num_qubits         backend.num_qubits
    backend.configuration().basis_gates        backend.target.operation_names (*)
    backend.configuration().coupling_map       backend.target.build_coupling_map()
    backend.configuration().local              No representation
    backend.configuration().simulator          No representation
    backend.configuration().conditional        No representation
    backend.configuration().open_pulse         No representation     
    backend.configuration().memory             No representation      
    backend.configuration().max_shots          No representation      

    (*) Es ist zu beachten, dass Backend.target.operation_names basis_gates und zusätzliche Nicht-Gate-Befehle enthält, so dass es in einigen Implementierungen erforderlich sein könnte, die Ausgabe zu filtern.

    In diesem Leitfaden finden Sie weitere Informationen zur Migration auf das BackendV2 modell.


  • Im Rahmen der Abkündigung des Qiskit Pulse-Pakets werden alle pulse-bezogenen Funktionen in qiskit.providers.BackendV2 der Klasse als veraltet markiert. Dies umfasst die folgenden Methoden:

    Folglich werden die entsprechenden Kanalmethoden in den qiskit.providers.BackendV2Converter und qiskit.providers.fake_provider.GenericBackendV2 klassen ebenfalls veraltet sein.

    Darüber hinaus werden die Argumente pulse_channels und calibrate_instructions in der BackendV2 initialisierungsmethode veraltet sein.

  • Das Argument defaults wird aus der Funktion qiskit.providers.convert_to_target() funktion.

QPY-Veraltungen

Transpiler-Veraltungen

  • Abgelehnt StochasticSwap die ersetzt wurde durch SabreSwap. Wenn die Klasse von der Transpile-Funktion aufgerufen wird, würde die Änderung beispielsweise lauten:

    from qiskit import transpile
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import CouplingMap
    from qiskit.providers.fake_provider import GenericBackendV2
    
    
    qc = QuantumCircuit(4)
    qc.h(0)
    qc.cx(0, range(1, 4))
    qc.measure_all()
    
    cmap = CouplingMap.from_heavy_hex(3)
    backend = GenericBackendV2(num_qubits=cmap.size(), coupling_map=cmap)
    
    tqc = transpile(
        qc,
        routing_method="stochastic",
        layout_method="dense",
        seed_transpiler=12342,
        target=backend.target
    )

    zu:

    tqc = transpile(
        qc,
        routing_method="sabre",
        layout_method="sabre",
        seed_transpiler=12342,
        target=backend.target
    )

    Für einen Passmanager würde die Änderung lauten:

    passmanager = PassManager(StochasticSwap(coupling, 20, 13))
    new_qc = passmanager.run(qc)

    zu:

    passmanager = PassManager(SabreSwap(backend.target, "basic"))
    new_qc = passmanager.run(qc)
  • Der Transpiler-Pass ConvertConditionsToIfOps ist veraltet und wird in Qiskit 2.0.0 entfernt werden. Diese Klasse ist jetzt veraltet, weil das zugrunde liegende Datenmodell für Instruction.condition von dem dieser Pass konvertiert, veraltet ist und in 2.0.0 entfernt werden wird.

  • Die Angabe von benutzerdefinierten Gates über das Argument basis_gates wird sowohl für transpile() und generate_preset_pass_manager(). Diese Funktion wird in Qiskit 2.0 entfernt werden. Benutzerdefinierte Gates werden weiterhin im Target modell unterstützt und können über das Argument target angegeben werden. Man kann eine Target instanz von Grund auf neu erstellen oder die Target.from_configuration() methode mit dem Argument custom_name_mapping verwenden. Zum Beispiel:

    from qiskit.circuit.library import XGate
    from qiskit.transpiler.target import Target
    
    basis_gates = ["my_x", "cx"]
    custom_name_mapping = {"my_x": XGate()}
    target = Target.from_configuration(
        basis_gates=basis_gates, num_qubits=2, custom_name_mapping=custom_name_mapping
    )

  • Im Rahmen der Abkündigung des Qiskit Pulse-Pakets werden pulse-bezogene Aspekte in der qiskit.transpiler.Target Klasse abgekündigt. Diese umfassen:


    Darüber hinaus werden auch die folgenden Transpiler-Durchläufe als veraltet markiert:

  • Das Argument inst_map in generate_preset_pass_manager(), from_configuration(), PassManagerConfig initializer und generate_scheduling() ist veraltet.

  • Das Argument calibration in InstructionProperties() initialisierungsmethoden wird veraltet sein.

  • Die folgenden transpile() und generate_preset_pass_manager() argumente sind veraltet zugunsten der Definition eines eigenen Target: instruction_durations, timing_constraints, und backend_properties. Diese Argumente können verwendet werden, um ein Ziel zu erstellen mit Target.from_configuration():

    Target.from_configuration(
         ...
         backend_properties = backend_properties,
         instruction_durations = instruction_durations,
         timing_constraints = timing_constraints
    )
  • Die Methode PassManagerConfig.from_backend() wird die Unterstützung von Eingaben des Typs BackendV1 im Backend-Parameter in einer zukünftigen Version nicht mehr unterstützen, frühestens ab 2.0. BackendV1 ist veraltet und Implementierungen sollten auf BackendV2.

Versch. Einstellung von Unterstützung

Fehlerkorrekturen

  • Behebung eines Leistungsrückgangs in QuantumCircuit.assign_parameters() die in Qiskit 1.2.0 eingeführt wurde, wenn die Methode in einer engen Schleife aufgerufen wurde, was dazu führte, dass nur eine kleine Anzahl von Parametern einer stark parametrischen Schaltung bei jeder Iteration gebunden wurde. Wenn möglich, ist es noch performanter, nur einmal assign_parameters() nur einmal aufzurufen, und zwar mit allen Zuweisungen gleichzeitig, da dies den Zeitanteil für die Eingabe-Normalisierung und den Overhead für die Fehlerüberprüfung reduziert.

  • Für BasicSimulatorist der Eintrag basis_gates in der Konfigurationsinstanz, die von der Methode configuration() zurückgegeben wird, nun eine Liste anstelle einer Instanz dict_keys , was dem erwarteten Typ entspricht und es ermöglicht, die Konfigurationsinstanz tief zu kopieren.

  • Es wurde ein Problem mit DAGCircuit.apply_operation_back() und DAGCircuit.apply_operation_front() wo früher, wenn man ein Clbit objekt in die Eingabe für das Argument qargs gesetzt wurde, dieses stillschweigend akzeptiert wurde. Dies wurde behoben, so dass die Typinkongruenz korrekt erkannt und eine Ausnahme ausgelöst wird.

  • Ein fehlender Dekorator wurde in C3SXGate der dazu führte, dass es fehlschlug, wenn Gate.to_matrix() aufgerufen wurde. Die Gate-Matrix wird nun wie erwartet zurückgegeben.

  • Ein Fehler in QuantumCircuit.assign_parameters()behoben, der bei der Zuweisung von Parametern zu Standardgattern auftrat, deren Definition bereits ausgelöst wurde. In diesem Fall wurden die neuen Werte nicht ordnungsgemäß an die Gate-Instanzen weitergegeben. Während die Schaltung selbst noch wie erwartet kompiliert wurde, wurde bei der Überprüfung der einzelnen Operationen immer noch der alte Parameter angezeigt.

    Zum Beispiel:

    from qiskit.circuit.library import EfficientSU2
    
    circuit = EfficientSU2(2, flatten=True)
    circuit.assign_parameters([1.25] * circuit.num_parameters, inplace=True)
    print(circuit.data[0].operation.params)  # would print θ[0] instead of 1.25

    Behoben #13478.

  • Behebung eines Fehlers mit der "circular" und "sca" Verschränkung für NLocal schaltungen und deren Ableitungen. Bei Verschränkungsblöcken von mehr als 2 Qubits fehlten der zirkulären Verschränkung bisher einige Verbindungen. Zum Beispiel für 4 Qubits und eine Blockgröße von 3 wurde der bisherige Code verwendet:

    [(2, 3, 0), (0, 1, 2), (1, 2, 3)]

    aber jetzt werden die (3, 0, 1) Verbindungen korrekt hinzugefügt, das heißt:

    [(2, 3, 0), (3, 0, 1), (0, 1, 2), (1, 2, 3)]

    So verwenden die Verflechtungen "circular" und "sca" num_qubits Verflechtungsblöcke pro Schicht.

  • Hinzufügen weiterer Clifford-Gatter zum CollectCliffords transpiler-Pass. Insbesondere haben wir die Gates hinzugefügt ECRGate, DCXGate, iSwapGate, SXGate und SXdgGate zu diesem Transpiler-Durchgang hinzugefügt.

  • Ein Fehler wurde behoben in QuantumCircuit.decompose() wo Objekte, die mit HighLevelSynthesis synthetisiert und dann sofort zerlegt wurden (d.h. sie wurden zweimal statt einmal zerlegt). Dies betraf Tore wie MCXGate oder Cliffordund andere.

  • Ein Fehler in QuantumCircuit.decompose()behoben, bei dem High-Level-Objekte ohne Definition nicht zerlegt wurden, wenn sie explizit über das Argument "gates_to_decompose" gesetzt wurden. Zum Beispiel führte das folgende Beispiel zuvor keine Zerlegung durch, aber jetzt funktioniert es wie erwartet:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import Clifford
    from qiskit.transpiler.passes import Decompose
    
    cliff = Clifford(HGate())
    circuit = QuantumCircuit(1)
    circuit.append(cliff, [0])
    
    decomposed = Decompose(gates_to_decompose=["clifford"])(circuit)
  • Bisher hat der HighLevelSynthesis transpiler pass eine Anweisung synthetisiert, für die ein Synthese-Plugin verfügbar ist, unabhängig davon, ob die Anweisung bereits vom Target unterstützt wird oder ein Teil der explizit übergebenen basis_gates ist. Dieses Verhalten ist nun korrigiert, so dass solche bereits unterstützten Anweisungen nicht mehr synthetisiert werden.

  • Der Transpilationsdurchgang InverseCancellation rekursiert nun in ControlFlowOp operationen, die in einer QuantumCircuit. Bisher wurden inverse Gatterpaare innerhalb von Kontrollflussblöcken, die hätten gelöscht werden können, bei der Prüfung ignoriert. Siehe #13437 für weitere Einzelheiten.

  • Behebung eines Fehlers in Isometry aufgrund einer unnötigen Behauptung, die zu einem Fehler in UnitaryGate.control() führte, wenn UnitaryGate mehr als zwei Qubits hatte.

  • Das QuantumCircuit.parameters attribut ist jetzt korrekt leer, wenn es QuantumCircuit.copy_empty_like() für einen parametrischen Schaltkreis verwendet wird. Zuvor wurde ein interner Cache ohne Invalidierung kopiert. Fix #12617.

  • QuantumCircuit.depth() verarbeitet nun korrekt Operationen, die keine Operanden haben, wie z.B GlobalPhaseGate.

  • QuantumCircuit.depth() zählt nun die in Echtzeitausdrücken verwendeten Variablen und Clbits als Teil der Tiefenberechnung.

  • Korrektur des SolovayKitaev transpiler-Durchgang beim Laden von Grundannäherungen aus einer bestehenden .npy Datei. Bisher konnte das Laden einer gespeicherten Approximation, die weitere Reduktionen (z.B. durch Gatterstornierungen) zuließ, zu einem Laufzeitfehler führen. Außerdem ging die globale Phasendifferenz zwischen dem U(2)-Gatterprodukt und der SO(3)-Darstellung während eines Speicher- und Ladevorgangs verloren. Fixes Qiskit/qiskit#12576.

  • Ein Fehler wurde behoben, wenn SparsePauliOp.paulis als ein PauliList mit einer Phase ungleich Null gesetzt wurde, bei dem nachfolgende Aufrufe von mehreren SparsePauliOp methoden zu falschen Ergebnissen führten. Wenn nun SparsePauliOp.paulis auf einen Wert PauliList mit einer Phase ungleich Null gesetzt wird, wird die Phase in SparsePauliOp.coeffsabsorbiert, und die Phase des Eingangs PauliList wird auf Null gesetzt.

  • Es wurde ein Fehler in qiskit.visualization.pulse_v2.interface.draw behoben, der keine Impulszeitpläne zeichnete, wenn die Zeichenfunktion mit einem BackendV2 argument aufgerufen wurde. Da das V2 Backend keine Hardware-Kanalfrequenzen meldet, wird in der generierten Zeichnung "no freq" angezeigt unter jeder Kanalbezeichnung.

  • Es wurde ein Problem mit dag_drawer() und DAGCircuit.draw() beim Versuch der Visualisierung einer DAGCircuit instanz zu visualisieren, die Var drähte enthielt, wofür der Visualisierer eine Ausnahme auslöste. Dieses Verhalten wurde behoben, und es wird die erwartete Visualisierung erzeugt.

  • Der VF2Layout pass würde eine Ausnahme auslösen, wenn er mit einer Target instanz ohne Konnektivitätseinschränkungen. Dies wäre bei Zielen von Aer 0.13 der Fall. Das Problem ist nun behoben.

  • Behebt einen Fehler beim Aufruf der Methode Gate.repeat(). Siehe #11990 für weitere Einzelheiten.

  • Ein Fehler wurde behoben, der dazu führte, dass Statevector.expectation_value() zu falschen Ergebnissen für den Identitätsoperator führte, wenn der Zustandsvektor nicht normalisiert war.

  • Der Konstruktor GenericBackendV2 ermöglichte die Erstellung fehlerhafter Backends, da er Basis-Gates akzeptierte, die nicht in der angegebenen Backend-Größe zugewiesen werden konnten. Das heißt, ein Backend mit einem einzigen Qubit sollte keine Basis mit Zwei-Qubit-Gattern akzeptieren.

  • ParameterExpression wurde aktualisiert, so dass vollständig gebundene Instanzen, die mit Instanzen der eingebauten numerischen Typen von Python gleich sind (wie float und int), auch Hash-Werte haben, die mit denen der anderen Instanzen übereinstimmen. Diese Änderung stellt sicher, dass diese Typen austauschbar als Wörterbuchschlüssel verwendet werden können. Siehe #12488.

  • Der OpenQASM 2 Parser (qiskit.qasm2) kann nun auch Conditionals mit Ganzzahlen behandeln, die nicht in eine 64-Bit-Ganzzahl passen. Behoben #12773.

  • Benutzerdefinierte Gatter (die aus einer gate Anweisung stammen) in importierten OpenQASM 2 Programmen haben jetzt eine Gate.to_matrix() implementierung. Zuvor hatten sie keine Matrixdefinition, was bedeutete, dass bei Rundreisen durch OpenQASM 2 die Fähigkeit zur Ableitung der Gattermatrix unnötigerweise verloren gehen konnte. Beachten Sie jedoch, dass die Matrix durch rekursives Finden der Matrizen der inneren Gatterdefinitionen berechnet wird, wie Operator tut, was weniger performant sein könnte als vor dem Round-Trip.

  • Zuvor, DAGCircuit.replace_block_with_op() eine n-Qubit-Operation auf einen Block von m -Qubits gelegt, wodurch die DAG in einen ungültigen Zustand versetzt wurde. Dieses Verhalten wurde behoben, und der Versuch wird eine DAGCircuitError.

  • Feste Operator.power() beim Aufruf mit nicht-ganzzahligen Potenzen bei einer Matrix, deren Schur-Form nicht diagonal ist (z.B. die meisten nicht-unitären Matrizen).

  • Operator.power() liefert nun zuverlässiger den erwarteten Hauptwert einer gebrochenen Matrizenpotenz einer Einheitsmatrix mit einem Eigenwert −1-1. Dies ist im Allgemeinen schwierig, da Rundungseffekte bei Fließkommazahlen dazu führen können, dass eine Matrix einen Eigenwert auf der negativen Seite der Verzweigungsgrenze hat (auch wenn ihre exakte mathematische Beziehung dies nicht tun würde), und Ungenauigkeiten in verschiedenen BLAS-Aufrufen können fälschlicherweise die falsche Seite der Verzweigungsgrenze finden.

    Operator.power() verschiebt nun die Verzweigungsschnittstelle für Matrixpotenzen um eine kleine komplexe Drehung von −1-1 weg. Dies löst das Problem nicht, sondern verlagert es nur an eine Stelle, an der es für die Arten von Operatoren, die normalerweise auftreten, weit weniger wahrscheinlich ist, dass es auffällt. Verwenden Sie den neuen Parameter branch_cut_rotation , um dies besser kontrollieren zu können.

    Siehe #13305.

  • Behebung eines prozessbasierten Nicht-Determinismus in SparsePauliOp.to_matrix(). Die genaue Reihenfolge der Fließkomma-Operationen in der Summierung variierte bisher je nach Prozess, ist jetzt aber bei verschiedenen Aufrufen desselben Skripts identisch. Siehe #13413.

  • Target.has_calibration() wurde aktualisiert, so dass sie keine Ausnahme für eine Anweisung auslöst, die dem Ziel mit None für ihre Anweisungseigenschaften hinzugefügt wurde. Behebt #12525.

War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.