Skip to main content
IBM Quantum Platform

Qiskit SDK 1.1 Versionshinweise


1.1.2

Vorspiel

Qiskit 1.1.2 ist ein kleineres Bugfix-Release für die 1.1 Serie.

Fehlerkorrekturen

  • Ein Fehler wurde behoben in BitArray.from_counts() und BitArray.from_samples(). Zuvor führten diese zu einem Fehler, wenn die Daten nur Nullen enthielten und kein Wert für das optionale Argument num_bits angegeben wurde. Jetzt produzieren sie eine BitArray mit BitArray.num_bits auf 1 gesetzt.

  • 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.

  • Hinzufügen der fehlenden 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.

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

  • 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.

  • Es wurde ein Problem mit dag_drawer() und DAGCircuit.draw() beim Versuch der Visualisierung einer DAGCircuit instanz, die Var drähte. Der Visualisierer löste bei diesem Versuch eine Ausnahme aus, die nun behoben wurde, so dass die erwartete Visualisierung erzeugt wird.

  • Der Konstruktor GenericBackendV2 erlaubte bisher die Konstruktion von fehlerhaften Backends, da er Basis-Gates akzeptierte, die angesichts der Backend-Größe nicht zugeordnet werden konnten. Ein Backend mit einem einzelnen Qubit konnte beispielsweise zuvor eine Basis mit zwei Qubit-Gates akzeptieren.

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

  • Zuvor, DAGCircuit.replace_block_with_op() eine n-Qubit-Operation auf einen Block von m -Qubits gelegt werden, wodurch die DAG in einen ungültigen Zustand versetzt wurde. Dieses Verhalten wurde behoben, und jeder Versuch, dies zu tun, führt nun zu einer DAGCircuitError wie erwartet.


1.1.1

Vorspiel

Qiskit 1.1.1 ist ein kleineres Bugfix-Release für die 1.1 Serie.

Fehlerkorrekturen

  • 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.

  • 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.

  • 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.

  • 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.

  • 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.

  • 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.

  • 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.


1.1.0

Vorspiel

Die Version 1.1.0 von Qiskit ist eine kleinere Version, die eine Vielzahl von neuen Funktionen und Fehlerkorrekturen enthält. Die Highlights dieser Veröffentlichung sind:

  • Die Unterstützung für typisierte klassische Variablen wurde zu Qiskit's QuantumCircuit. Diese klassischen Variablen können als Eingänge oder als scoped variables in einem QuantumCircuit angegeben werden, wo sie z.B. die Ausgabe von Qubit-Messungen oder Zielkontrollflussoperationen speichern. Die Unterstützung für z.B. das Setzen von Gate-Parametern oder Ausgangsvariablen wird in Zukunft hinzugefügt werden.

  • Die beiden Standard-Qubit-Synthesemethoden, die intern vom Transpiler im UnitarySynthesis durchgang verwendet werden, wurden in Rust neu implementiert. Dies führt zu erheblichen Laufzeitbeschleunigungen bei der Zerlegung von zwei unitären Qubit-Matrizen. Infolgedessen konnte die Laufzeit der Transpilierung mit Optimierungsstufe 3 erheblich verbessert werden, wo die Ausführung UnitarySynthesis in der Vergangenheit einen großen Laufzeit-Overhead verursachte. Diese Version läuft auch UnitarySynthesis als Teil der Optimierungsphase in Optimierungsstufe 2 wegen dieser Laufzeitverbesserungen.

    Darüber hinaus wurden die numerischen Methoden, die in Isometry verwendeten numerischen Methoden nach Rust verlagert, was insbesondere bei der Synthese von kontrollierten unitären Gattern zu erheblichen Laufzeitbeschleunigungen führt. Die Zerlegung für mehrfach kontrollierte XGate und PhaseGate wurde verbessert, was zu einer Verringerung der Anzahl der in der Synthese verwendeten Gatter um mehr als zwei Größenordnungen führt.

  • In Qiskit wurde eine Reihe neuer Transpiler-Passagen eingeführt, die zu erheblichen Laufzeitbeschleunigungen führen und gleichzeitig die Größe der transpilierten Quantenschaltungen in vielen Fällen verringern. Konkret, ElidePermutations und StarPreRouting haben nachweislich einen erheblichen Einfluss auf die Qualität der Routing-Ausgabe und die Laufzeit und RemoveFinalReset können Quantenschaltungen verbessern, die Rücksetzungen beinhalten.

  • Die Standard-Pass-Manager wurden verbessert, indem sie um die neu eingeführten Transpiler-Pässe erweitert wurden. Insbesondere der voreingestellte Passmanager der Optimierungsstufe 2 von generate_preset_pass_manager , der intern von transpile() verwendet wird, wurde überarbeitet, um einen besseren Kompromiss zwischen Laufzeit und Optimierungsaufwand zu erzielen, damit er in künftigen Versionen als Standard-Pass-Manager verwendet werden kann. Diese Version ändert zwar nicht die Vorgabe, Stufe 2 zu verwenden, ist aber in der Regel eine bessere Wahl als Stufe 1 oder 3.

  • Neue generische primitive V2 Implementierungen wurden hinzugefügt, BackendEstimatorV2 und BackendSamplerV2als Ergänzung zu den bestehenden vollständigen zustandsvektorbasierten Implementierungen.

  • Änderungen bei der Plattformunterstützung: Python 3.8 ist ab Qiskit 1.1.0 veraltet und wird in 1.3.0 nicht mehr unterstützt, und arm64 macOS wurde zur Tier-1-Unterstützung befördert.

Schaltkreise Funktionen

  • Die Methoden QuantumCircuit.power(), Gate.power(), sowie die ähnlichen Methoden auf Unterklassen von Unterklassen von Gate (z.B. von SGate) haben alle ein zusätzliches neues Argument annotated , das verwendet wird, um ein AnnotatedOperation objekt zurückgibt, wenn eine Leistung auf ein Tor oder eine Schaltung angewendet wird. Der Standardwert von False entspricht dem bisherigen Verhalten. Außerdem hat das Argument annotated bei Standardgattern mit einer explizit definierten power Methode keine Auswirkungen. Zum Beispiel geben sowohl SGate().power(1.5, annotated=False) als auch SGate().power(1.5, annotated=True) ein PhaseGate zurück. Ein Unterschied im Wert von annotated zeigt sich bei Gates ohne explizit definierte Leistungsmethode. Der Wert von False gibt ein UnitaryGatezurück, genau wie zuvor, während der Wert von True ein AnnotatedOperation zurückgibt, der die mit dem "Potenzmodifikator" modifizierte Anweisung darstellt.

  • Ein neues Argument ctrl_state wurde zu QuantumCircuit.mcp() und MCPhaseGate.

    Die QuantumCircuit.mcp() methode und MCPhaseGate klasse wurden aktualisiert, um einen ctrl_state Parameter aufzunehmen. Mit dieser Erweiterung kann der Benutzer den Steuerzustand des mehrfach gesteuerten Phasengatters festlegen. Der Parameter kann entweder einen Integer-Wert oder einen Bitstring annehmen und steuert standardmäßig den Zustand "1", wenn er nicht angegeben wird.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(4)
    qc.mcp(0.2,[0,1,2],3,ctrl_state=2)
  • Ein neues ctrl_state Argument wurde zu QuantumCircuit.mcx().

    Die Methode QuantumCircuit.mcx() methode in der Quantenschaltungsbibliothek wurde um einen ctrl_state-Parameter erweitert, mit dem der Benutzer den Steuerzustand des mehrfach gesteuerten X-Gatters angeben kann. Dieser Parameter kann entweder einen Dezimalwert oder einen Bitstring annehmen und steuert standardmäßig den Zustand "1", wenn er nicht angegeben wird.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.mcx([0, 1], 2, ctrl_state="00")
  • A QuantumCircuit kann nun typisierte klassische Variablen enthalten:

    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)

    Diese Variablen können entweder als Eingaben in den Schaltkreis oder als skalierte Variablen angegeben werden. Das Schaltkreisobjekt bietet noch keine Unterstützung für die Darstellung typisierter Ausgänge klassischer Variablen, aber dies wird später hinzugefügt, wenn die Hardware und die Ergebnisschnittstellen in der Lage sind, dies zu unterstützen. Schaltkreise, die einen Block eines inneren Bereichs darstellen, können auch Variablen aus äußeren Bereichen erfassen.

    Eine Variable ist ein Var knoten, der nun einen beliebigen Typ enthalten kann und einen eindeutigen Speicherplatz innerhalb seines Live-Bereichs darstellt, wenn er zu einer Schaltung hinzugefügt wird. Diese können in einer Schaltung mit QuantumCircuit.add_var() und QuantumCircuit.add_input()oder auf einer niedrigeren Ebene mit Var.new().

    Variablen können manuell gespeichert werden, indem die Store anweisung und der entsprechenden Schaltungsmethode QuantumCircuit.store(). Dazu gehört das Schreiben an Clbit und ClassicalRegister instanzen, die in Var knoten.

    Variablen können überall dort verwendet werden, wo klassische Ausdrücke (siehe qiskit.circuit.classical.expr) gültig sind. Derzeit sind dies die Zielausdrücke von Kontrollflussoperationen, obwohl wir planen, dies in Zukunft auf Gatterparameter zu erweitern, wenn das Typ- und Ausdruckssystem erweitert wird.

    Weitere Informationen über diese Variablen und das zugehörige Datenmodell finden Sie unter Klassische Echtzeitberechnung.

    Diese werden vom gesamten Transpiler unterstützt, durch QPY-Serialisierung (qiskit.qpy), OpenQASM 3 Export (qiskit.qasm3), und haben eine anfängliche Unterstützung durch die Schaltkreisvisualisierer (siehe QuantumCircuit.draw()).

    Anmerkung

    Es wird einige Zeit dauern, bis die neuen klassischen Variablen und Speicher auf der Hardware und den Simulator-Backends unterstützt werden. Sie werden nicht von den Primitivschnittstellen unterstützt (qiskit.primitives) unterstützt, werden aber wahrscheinlich in diese Schnittstellen einfließen, wenn sie weiterentwickelt werden.

  • Das klassische Modul für Echtzeit-Ausdrücke qiskit.circuit.classical kann nun auch die Indizierung und Bitverschiebung von vorzeichenlosen Ganzzahlen und bitähnlichen Werten darstellen (z.B. ClassicalRegister). Zum Beispiel ist es jetzt möglich, ein Register mit der Bitverschiebung eines anderen zu vergleichen:

    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))):
        pass

    Qiskit kann auch eine Bedingung darstellen, die dynamisch in ein Register indiziert:

    with qc.if_test(expr.index(cr1, cr2)):
        pass
  • Die Konstruktionsleistung von NLocal und den von ihr abgeleiteten Unterklassen der Schaltungsbibliothek (z. B. EfficientSU2 und RealAmplitudes) hat sich erheblich verbessert, wenn die Rotations- und/oder Verschränkungsunterblöcke einfache Anwendungen eines einzigen Qiskit-Standardbibliotheksgatters sind. Da diese Schaltkreise träge aufgebaut sind, sehen Sie die Verbesserung möglicherweise nicht sofort bei der Instanziierung der Klasse, sondern erst beim ersten Zugriff auf ihre interne Struktur. Die Leistungsverbesserungen liegen in der Größenordnung von zehnmal schneller.

  • QuantumCircuit.append() hat jetzt ein Schlüsselwortargument copy , das standardmäßig True lautet. Wenn eine Anweisung mit Laufzeitparametern (ParameterExpressions) an eine Schaltung angehängt wird, hat die Schaltung standardmäßig immer eine Kopie der Anweisung erstellt, so dass, wenn QuantumCircuit.assign_parameters() versucht, die Anweisung an Ort und Stelle zu verändern, hat dies keine Auswirkungen auf andere Verweise auf dieselbe Anweisung. Die Einstellung copy=False ermöglicht es Ihnen, dies außer Kraft zu setzen, so dass Sie die Kopierstrafe vermeiden können, wenn Sie wissen, dass Ihre Anweisungen nicht an anderen Orten verwendet werden.

  • QuantumCircuit.compose() hat jetzt ein Schlüsselwortargument copy , das standardmäßig True lautet. Standardmäßig, compose() alle Anweisungen kopiert, so dass sich Mutationen in einem Schaltkreis nicht auf andere Schaltkreise auswirken. Wenn copy=False, dann werden die Befehle der anderen Schaltung direkt von der neuen Schaltung übernommen, was bedeuten kann, dass sie an Ort und Stelle geändert werden. Der andere Stromkreis darf in diesem Fall nicht mehr verwendet werden.

  • Die Bauzeit für QuantumVolume schaltungen wurde erheblich verbessert, in der Größenordnung von 10x oder etwas mehr. Die internen SU4 Gatter verwenden nun auch mehr Zufallsbits während ihrer Erzeugung, was zu repräsentativeren Volumenschaltungen führt, insbesondere bei großen Breiten und Tiefen.

  • QuantumVolume hat jetzt ein flatten Schlüsselwortargument. Die Standardeinstellung ist False, wobei der konstruierte Schaltkreis eine einzige Anweisung enthält, die wiederum die eigentliche Volumenstruktur enthält. Wenn True eingestellt ist, verfügt der Stromkreis direkt über die volumetrischen SU4 Matrizen.

  • UnitaryGate akzeptiert jetzt ein optionales Argument num_qubits . Die einzige Auswirkung davon ist, dass die Ableitung der Qubit-Zahl übersprungen wird, was bei der Konstruktion vieler Gatter für die Leistung hilfreich sein kann.

  • QuantumCircuit verfügt über mehrere neue Methoden zur Arbeit mit und zur Überprüfung von manuellen Var variablen.

    Unter Arbeiten mit in Echtzeit eingegebenen klassischen Daten finden Sie ausführlichere Informationen zu all diesen Punkten.

    Die neuen Methoden sind:

    Darüber hinaus gibt es mehrere neue dynamische Attribute auf QuantumCircuit die diese Variablen umgeben:

  • ControlFlowOp und ihre Unterklassen haben jetzt eine iter_captured_vars() methode, die einen Iterator über die eindeutigen Variablen zurückgibt, die in einem ihrer unmittelbaren Blöcke erfasst sind.

  • DAGCircuit verfügt über mehrere neue Methoden zur Arbeit mit und zur Überprüfung von manuellen Var variablen. Diese sind weitgehend gleichwertig mit ihren QuantumCircuit gegenstücken, außer dass die DAGCircuit für den programmatischen Zugriff mit bereits definierten Objekten optimiert sind, während die QuantumCircuit methoden mehr auf die interaktive menschliche Nutzung ausgerichtet sind.

    Die neuen Methoden sind:

    Außerdem gibt es neue öffentliche Attribute:

  • DAGCircuit.wires enthält nun auch alle Var manuelle Variablen in der Schaltung, da es sich auch hier um einen klassischen Datenfluss handelt.

  • Eine neue Methode, Var.new()wird hinzugefügt, um manuell eine klassische Echtzeitvariable zu konstruieren, die ihren eigenen Speicher besitzt.

  • QuantumCircuit.compose() hat zwei notwendige Schlüsselwortargumente, var_remap und inline_captures , um klassische Echtzeitvariablen besser zu unterstützen.

    var_remap kann zum Umschreiben von Var knoten im Schaltkreisargument umzuschreiben, da seine Anweisungen in den Basisschaltkreis eingefügt werden. Dies kann dazu dienen, Namenskonflikte zu vermeiden.

    inline_captures kann auf True gesetzt werden (Standardwert ist False), um alle Var knoten, die als "Captures" im Argumentkreis verfolgt werden, mit denselben Var knoten im Basiskreis zu verknüpfen, ohne zu versuchen, die Variablen neu zu deklarieren. Dies kann in Kombination mit QuantumCircuit.copy_empty_like()vars_mode="captures" verwendet werden, um einen Schaltkreis Schicht für Schicht aufzubauen, der Variablen enthält.

  • DAGCircuit.compose() hat ein neues Schlüsselwortargument, inline_captures, das auf True gesetzt werden kann, um "eingefangene" Var knoten des Argumentkreises in den Basiskreis einzufügen, ohne sie neu zu deklarieren. In Verbindung mit der Option vars_mode="captures" für mehrere DAGCircuit kann diese Option verwendet werden, um DAGs zu kombinieren, die auf dieselben Variablen wirken.

  • QuantumCircuit.copy_empty_like() und DAGCircuit.copy_empty_like() haben ein neues Schlüsselwortargument, vars_mode , das steuert, wie alle speicherbesitzenden Var knoten in der Ausgabe nachverfolgt werden. Standardmäßig ("alike") werden die Variablen im gleichen Eingabe-/Erfassungs/Lokalmodus wie die Quelle deklariert. Dies kann auf "captures" gesetzt werden, um alle Variablen in Captures zu konvertieren (nützlich mit compose()) oder "drop" , um sie zu entfernen.

  • Ein neues vars_mode Schlüsselwortargument wurde zu den DAGCircuit methoden hinzugefügt:

    was die gleiche Bedeutung hat wie bei copy_empty_like().

  • Alle "Standardgatter" in der Schaltkreisbibliothek (qiskit.circuit.library) können nun durch Stringnamen für die Verschränkungsoperationen in TwoLocal schaltungen, wie z.B RealAmplitudes und EfficientSU2.

Primitive Funktionen

  • Die Umsetzung BackendEstimatorV2 von BaseEstimatorV2 wurde hinzugefügt. Dieser Schätzer unterstützt BackendV1 und BackendV2.

    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}")
  • Die Umsetzung BackendSamplerV2 von BaseSamplerV2 wurde hinzugefügt. Dieser Probenehmer unterstützt BackendV1 und BackendV2 die die Option memory zur Berechnung von Bitstrings erlauben.

    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}")
  • Hinzufügen von Methoden zum Verbinden mehrerer BitArray objekten entlang verschiedener Achsen.

    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']
  • Methoden zur Erzeugung einer Teilmenge von BitArray objekts durch Zerschneiden entlang verschiedener Achsen.

    • __getitem__(): Schneidet das Array entlang einer bestehenden Achse des Arrays.
    • slice_bits(): Schneiden des Arrays entlang der Bit-Achse.
    • slice_shots(): Schneiden Sie das Feld entlang der Schussachse.
    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']
  • Hinzufügen einer Methode transpose() zum Transponieren einer BitArray.

    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>)
  • Hinzufügen einer Methode expectation_values() zur Berechnung der Erwartungswerte von Diagonaloperatoren hinzugefügt.

    ba = BitArray.from_samples(['01', '11'])
    print(ba.expectation_values(["IZ", "ZI", "01"]))
    # [-1.   0.   0.5]
  • DataBin erfüllt nun das Shaped protokoll. Das bedeutet, dass jede DataBin instanz nun die zusätzlichen Attribute

    • shape (tupleint[,...]): die führende Form jedes Eintrags in der Instanz
    • ndim (int): die Länge der shape
    • size (int): das Produkt der Einträge von shape

    Die Form kann an den Konstruktor übergeben werden.

  • Hinzufügen von Mapping-ähnlichen Funktionen zu DataBin, d.h. __getitem__, __contains__, __iter__, keys(), values(), und items().

    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])
  • Die Unterklasse SamplerPubResult von PubResult wurde hinzugefügt, die BaseSamplerV2 implementierungen zurückgeben können. Die wichtigste Funktion dieser neuen Unterklasse ist join_data()die den Inhalt (eine Teilmenge) von data zu einem einzigen Objekt zusammenfasst. Dies ermöglicht die folgenden Muster:

    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

Anbieter Funktionen

Puls-Funktionen

  • Es ist nun möglich, dem Puls Parameter zuzuweisen Schedule und ScheduleBlock objekten Parameter zuzuweisen, indem man den Parameternamen als String angibt. Der Parametername kann verwendet werden, um allen Parametern innerhalb der Schedule oder ScheduleBlock die den gleichen Namen haben. Außerdem kann der Parametername eines ParameterVector verwendet werden, um alle Werte des Vektors gleichzeitig zuzuweisen (die Liste der Werte sollte daher der Länge des Vektors entsprechen).

  • Die Methoden assign_parameters von Schedule und ScheduleBlock unterstützen nun die Zuweisung eines ParameterVector einer Liste von Parameterwerten gleichzeitig zuzuweisen, zusätzlich zur Zuweisung von einzelnen Parameter instanzen zu einzelnen Werten.

OpenQASM Funktionen

  • Der OpenQASM 3 Exporter unterstützt manuell zu speichernde Var knoten auf Schaltkreisen.

QPY-Funktionen

  • QPY (qiskit.qpy) Format Version 12 wurde hinzugefügt, das die Unterstützung für speichereigene Var variablen. Weitere Einzelheiten zu den Formatänderungen finden Sie in Version 12.

Quanteninformationsmerkmale

  • Hinzufügen einer neuen apply_layout() methode hinzugefügt, die äquivalent ist zu apply_layout(). Diese Methode wird verwendet, um ein TranspileLayout layout aus dem Transpiler auf eine Pauli observable anzuwenden, das für eine Eingangsschaltung erstellt wurde. Dies ermöglicht die Arbeit mit BaseEstimator / BaseEstimatorV2 implementierungen und lokaler Transpilation, wenn die Eingabe vom Typ Pauli. Zum Beispiel:

    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()

    wo eine Eingangsschaltung lokal umgesetzt wird, bevor sie an run() weitergegeben wird. Durch die Transpilierung wird die ursprüngliche Schaltung von 2 auf 7 Qubits (die Größe von backend) erweitert und ihr Layout permutiert, das dann auf H1 angewendet wird, indem apply_layout() angewendet wird, um die von pm.run() durchgeführten Transformationen widerzuspiegeln.

  • Fügt die PauliList.noncommutation_graph() und SparsePauliOp.noncommutation_graph() methoden, die die Konstruktion von Nicht-Kommutationsgraphen aufzeigen und das Problem der Gruppierung von Messoperatoren in ein Problem der Graphenfärbung umwandeln. Dies ermöglicht es den Benutzern, direkt mit diesen Graphen zu arbeiten, zum Beispiel um andere Färbungsalgorithmen als die von SparsePauliOp.group_commuting().

  • Die Leistung von SparsePauliOp.to_matrix() wurde sowohl für dichte als auch für spärliche Formen erheblich verbessert. Standardmäßig nutzen beide nun die auf Ihrem System verfügbare Thread-Parallelität, abhängig von der Umgebungsvariablen RAYON_NUM_THREADS . Sie können die serielle Ausführung vorübergehend erzwingen, indem Sie das neue boolesche Argument force_serial an to_matrix().

Synthesefunktionen

  • Das KMSSynthesisLinearFunction plugin für die Synthese von LinearFunction objekte akzeptiert jetzt zwei zusätzliche Optionen use_inverted und use_transposed. Diese Option verändert die Matrix, auf der der zugrundeliegende Synthesealgorithmus läuft, indem er sie möglicherweise invertiert und/oder transponiert, und passt dann die synthetisierte Schaltung entsprechend an. Wenn Sie diese Optionen variieren, erhalten Sie im Allgemeinen unterschiedliche synthetisierte Schaltungen und in einigen Fällen bessere Ergebnisse als mit den Standardwerten.

  • Das PMHSynthesisLinearFunction plugin für die Synthese von LinearFunction objekte akzeptiert jetzt mehrere zusätzliche Optionen. Die Option section_size wird an die zugrunde liegende Synthesemethode übergeben. Die Optionen use_inverted und use_transposed modifizieren die Matrix, auf der der zugrundeliegende Synthesealgorithmus läuft, indem sie sie möglicherweise invertieren und/oder transponieren, und passen dann die synthetisierte Schaltung entsprechend an. Wenn Sie diese Optionen variieren, erhalten Sie im Allgemeinen unterschiedliche synthetisierte Schaltungen und in einigen Fällen bessere Ergebnisse als mit den Standardwerten.

  • Ein neues Argument, use_dag, wurde zu den TwoQubitBasisDecomposer.__call__() und XXDecomposer.__call__() methoden. Dieses Argument wird verwendet, um zu kontrollieren, ob ein DAGCircuit zurückgegeben wird, wenn man ein TwoQubitBasisDecomposer oder XXDecomposer instanz anstelle der Standard QuantumCircuit. Zum Beispiel:

    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)

    gibt eine DAGCircuit beim Aufruf der TwoQubitBasisDecomposer instanz decomposer zurück.

  • LieTrotter.synthesize() verwendet nun QuantumCircuit.repeat() um zusätzliche Wiederholungen eines Trotter-Schrittes nach dem ersten Trotter-Schritt zu erzeugen. Dies reduziert die Anzahl der QuantumCircuit.compose() aufrufe um einen Faktor von reps und verkürzt die Laufzeit für größere Operatoren erheblich.

  • Hinzufügen einer neuen Synthesemethode synth_permutation_reverse_lnn_kms() von umgekehrten Permutationen für lineare Nächste-Nachbarn-Architekturen unter Verwendung der Methode von Kutin, Moulton und Smithline. Dieser Algorithmus synthetisiert die umgekehrte Permutation auf nn Qubits über eine lineare Nearest-Neighbor-Architektur unter Verwendung von CX-Gattern mit der Tiefe 2∗n+22 * n + 2.

  • Die Klasse TwoQubitBasisDecomposer klasse wurde in Rust umgeschrieben, was die Laufzeitleistung erheblich verbessert.

  • Die TwoQubitWeylDecomposition syntheseklasse wurde zur Verbesserung der Leistung in Rust neu geschrieben.

Transpiler-Funktionen

  • Erweiterung der Kommutierungsanalyse von CommutationChecker , um auch mit abstrakten Schaltungen zu arbeiten, d.h. jede Operation in der Eingabequantenschaltung wird nun auf ihre Matrixrepräsentation überprüft, bevor mit dem Analyseschritt fortgefahren wird. Bisher wurde die Kommutierungsanalyse nur für physikalische Schaltungen durchgeführt. Außerdem wird jetzt jede Operation daraufhin überprüft, ob sie in der Sitzungskommutationsbibliothek zwischengespeichert werden kann. So kann nun zum Beispiel berechnet werden, ob AnnotatedOperation pendeln. Dies ermöglicht Transpiler-Passes, die intern auf CommutationChecker basieren, wie z.B CommutativeCancellationin früheren Phasen einer Standard-Transpilierungspipeline (vor der Basisübersetzung) ausgeführt werden.

  • Der Transpiler-Durchlauf ElidePermutations wird standardmäßig in der Init-Stufe für die Optimierungsstufen 2 und 3 ausgeführt. Intuitiv ist das Entfernen von SwapGates und PermutationGates in einer virtuellen Schaltung fast immer von Vorteil, da die Schaltung dadurch kürzer und einfacher zu leiten ist. Da OptimizeSwapBeforeMeasure ein Spezialfall von ElidePermutationsist, wurde er durch den ElidePermuations -Pass als Teil der Init-Phase in Optimierungsstufe 3-Pass-Managern ersetzt.

  • Es wurde ein neuer Optimierungs-Transpiler-Durchgang hinzugefügt, ElidePermutationshinzugefügt, der vor der Layout-Stufe ausgeführt werden soll und alle SwapGates und PermutationGates in einer Schaltung durch Permutieren virtueller Qubits. Nehmen wir zum Beispiel einen Stromkreis mit SwapGates:

    _images/release_notes-1.png

    entfernt die Swaps, wenn der Pass ausgeführt wird:

    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")
    _images/release_notes-2.png

    Der Durchlauf setzt auch die Eigenschaft virtual_permutation_layout , die die Permutation der virtuellen Qubits am Ende der Schaltung speichert, die wegoptimiert wurde.

  • Der HLSConfig hat jetzt zwei zusätzliche optionale Argumente. Das Argument plugin_selection kann entweder auf "sequential" oder auf "all" gesetzt werden. Bei der Einstellung "sequentiell" (Standard) werden für jedes Objekt einer höheren Ebene die HighLevelSynthesis pass die angegebenen Methoden in der Reihenfolge, in der sie in der Liste erscheinen, und hält bei der ersten Methode an, die das Objekt synthetisieren kann. Bei der Einstellung "alle" werden alle angegebenen Methoden berücksichtigt, und es wird die beste synthetisierte Schaltung gemäß plugin_evaluation_fn ausgewählt. Das Argument plugin_evaluation_fn ist ein optionales Callable, das die Qualität der synthetisierten Quantenschaltung bewertet; ein kleinerer Wert bedeutet eine bessere Schaltung. Bei None entspricht die Qualität der Schaltung ihrer Größe (d. h. der Anzahl der Gatter, die sie enthält).

    Das folgende Beispiel veranschaulicht die neue Funktionalität:

    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 diesem Beispiel werden mehrere Synthesemethoden mit unterschiedlichen Parametern durchgeführt, wobei die beste Schaltung in Bezug auf die Tiefe ausgewählt wird. Beachten Sie, dass bei der Optimierung von circuit.size() eine andere Schaltung gewählt würde.

  • Hinzufügen des CommutativeCancellation pass zur init Stufe der voreingestellten Passmanager für die Optimierungsstufen 2 und 3 hinzugefügt. Dies ermöglicht es den voreingestellten Pass-Managern, zusätzliche logische Operationen am Anfang der Kompilierungspipeline abzubrechen.

  • Die folgenden Analysedurchläufe akzeptieren nun Einschränkungen, die in einem Target kodierte Einschränkungen dank eines neuen target Eingabearguments:

    Die Ziel-Constraints haben aus Gründen der Kohärenz mit dem Rest der Transpiler-Pipeline Vorrang vor den vom Benutzer bereitgestellten Constraints.

  • Hinzufügen einer neuen Methode Layout.inverse() hinzugefügt, mit der die Inverse eines Layout objekts dient. Hinzufügen einer neuen Methode Layout.compose() hinzugefügt, die zum Zusammensetzen von zwei Layout objekten verwendet wird. Hinzufügen einer neuen Methode Layout.to_permutation() hinzugefügt, die für die Erstellung einer Permutation verwendet wird, die einem Layout objekt entspricht.

  • Hinzufügen einer neuen Reduktion zum OptimizeAnnotated transpiler-Durchgang. Diese Reduktion sucht nach annotierten Operationen (Objekte vom Typ AnnotatedOperation die aus einer Basisoperation BB und einer Liste MM von Kontroll-, Invers- und Potenzmodifikatoren bestehen) mit den folgenden Eigenschaften:

    • die Basisoperation BB muss synthetisiert werden (d.h. sie wird nicht bereits vom Zielsystem unterstützt oder gehört zur Äquivalenzbibliothek)
    • die Definitionsschaltung für BB kann ausgedrückt werden als PP - QQ - RR mit R=P−1R = P^{-1}

    In diesem Fall können die Modifikatoren nur in den QQ -Teil verschoben werden. Als konkretes Beispiel haben kontrollierte QFT-basierte Addierer die Form control - [QFT -- U -- IQFT], die zu QFT -- control-[U] -- IQFT vereinfacht werden kann. Wenn man die Kontrollen über die QFT und IQFT Teile der Schaltung entfernt, erhält man deutlich weniger Gatter in der transponierten Schaltung.

  • Zwei neue Methoden wurden der DAGCircuit klasse: qiskit.dagcircuit.DAGCircuit.op_successors() liefert einen Iterator zu DAGOpNode nachfolgern eines Knotens, und qiskit.dagcircuit.DAGCircuit.op_successors() gibt einen Iterator zurück zu DAGOpNode vorgängern eines Knotens zurück.

  • Ein neuer Transpiler-Pass wurde hinzugefügt, RemoveFinalResethinzugefügt, der jede Reset operation entfernt, die die letzte Anweisung auf einer Qubit-Leitung ist. Nehmen wir zum Beispiel eine Schaltung mit dem Endwert Resets:

    _images/release_notes-3.png

    entfernt die endgültigen Rücksetzungen, wenn der Durchgang ausgeführt wird:

    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")
    _images/release_notes-4.png
  • Hinzufügen eines neuen Transpiler-Passes StarPreRouting der dazu dient, Teilschaltungen mit Sternkonnektivität zu identifizieren und sie dann durch eine optimale lineare Streckenführung zu ersetzen. Dies ist nützlich für bestimmte Schaltungen, die sich aus dieser Schaltungskonnektivität zusammensetzen, wie Bernstein-Vazirani und QFT. Zum Beispiel:

    _images/release_notes-5.png
    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")
    _images/release_notes-6.png

    Alternativ kann ein bereits vorhandener voreingestellter Passmanager erweitert werden:

    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")
    _images/release_notes-7.png

Visualisierungsfunktionen

  • Die Text- und Matplotlib schaltkreis-Schubladen (QuantumCircuit.draw()) bieten eine minimale Unterstützung für die Anzeige von Ausdrücken mit manuellen Echtzeitvariablen. Die Store operation und die Variableninitialisierung werden noch nicht unterstützt; für große dynamische Schaltungen empfehlen wir die Verwendung der OpenQASM 3 Exportfunktionen (qasm3.dumps()), um eine textuelle Darstellung eines Schaltkreises zu erhalten.

Versch. Funktionen

  • Mit dieser Version von Qiskit wird die Unterstützung für NumPy 2.0 abgeschlossen. Qiskit wird in absehbarer Zukunft sowohl NumPy 1.x als auch 2.x weiterhin unterstützen.

Anmerkungen zu Upgrades

  • Entfernt das Hardcoding von Stiloptionen für plot_histogram(). Auf diese Weise lassen sich die Stildateien von Matplotlib originalgetreu auf die Figuren übertragen. Benutzer, die über die Standardeinstellungen von Matplotlib hinausgehen möchten, können ihre eigenen Stildateien erstellen oder ein Matplotlib Axes Objekt an plot_histogram übergeben und alle Anpassungen nachträglich anwenden.

  • Die Funktion transpile() funktion wurde erweitert, um Backend-Eingaben vom Typ BackendV1 in BackendV2zu konvertieren, was es der Transpilationspipeline ermöglicht, auf die Backend-Constraints durch eine Target. Diese Änderung erfordert keine Benutzeraktion.

Hinweise zur Aktualisierung von Schaltkreisen

  • Die Verwendung der Zufallszahlen von QuantumVolume hat sich geändert, so dass Sie bei älteren Versionen von Qiskit und dieser Version eine andere Schaltung für einen festen Seed erhalten werden. Die zufällig-unitäre Generierung verwendet nun mehr Bits an Entropie, so dass große Schaltungen weniger voreingenommen sind.

  • Die internen UnitaryGate instanzen in der Definition eines QuantumVolume schaltkreises werden nicht mehr mit einem label feld gesetzt. Zuvor war dies auf die Zeichenkette su4_<seed> gesetzt, wobei <seed> eine dreistellige Zahl war, die den Seed einer internen Numpy-Instanz pRNG für dieses Tor bezeichnete. Dies war ein ernstes Leistungsproblem, und der Seed sollte nicht nützlich sein; wenn Sie die Matrix aus dem Gate abrufen müssen, verwenden Sie einfach die Gate.to_matrix() methode.

Hinweise zum Upgrade von Primitives

  • Die Funktion make_data_bin() erzeugt und liefert keine DataBin unterklasse. Sie gibt stattdessen immer die DataBin klasse zurück. Aus Gründen der Abwärtskompatibilität bleibt sie jedoch bestehen, auch wenn sie mit der Zeit veraltet sein wird. Alle Benutzer sollten dazu übergehen, Instanzen direkt zu konstruieren DataBin instanzen direkt zu konstruieren, anstatt Unterklassen als Ausgabe von make_data_bin() zu instanziieren.

Hinweise zum Upgrade für Anbieter

  • Implementierungen von BackendV2 (und BackendV1) möchten vielleicht ihre run() methoden zu aktualisieren, um Eingaben, die typisierte klassische Variablen enthalten, eifrig zurückzuweisen (siehe qiskit.circuit.classical) und die Store anweisung, wenn sie diese nicht unterstützen. Die neue Store anweisung wird vom Transpiler als eine immer verfügbare "Direktive" behandelt (wie Barrier); wenn Ihre Backends dies nicht unterstützen, wird sie nicht von der transpiler.

    Weitere Informationen finden Sie unter Echtzeit-Variablen.

QPY-Upgrade-Hinweise

Hinweise zum Upgrade der Synthese

  • Die TwoQubitWeylDecomposition wird sich bei der Erstellung nicht mehr selbst in eine Unterklasse spezialisieren. Dies war ein internes Detail der TwoQubitWeylDecomposition und war kein dokumentiertes öffentliches Verhalten, da sich alle Unterklassen gleich verhielten und nur für den internen Versand verwendet wurden. Da es sich jedoch um ein auffälliges Verhalten handelte, soll diese Release Note dokumentieren, dass dies nicht mehr vorkommt und alle Instanzen von TwoQubitWeylDecomposition vom gleichen Typ sein werden. Das Verhalten der öffentlichen Methoden der Klasse ändert sich nicht.

Hinweise zum Transpiler-Upgrade

  • Die Voreinstellung StagedPassManager die für die Optimierungsstufe 2 von generate_preset_pass_manager() und level_2_pass_manager() zurückgegeben werden, wurden überarbeitet, um ein besseres Gleichgewicht zwischen Laufzeit und Optimierung zu erreichen. Das bedeutet, dass sich die Ausgangsschaltungen im Vergleich zu früheren Versionen ändern werden. Wenn Sie einen exakten Passmanager der Stufe 2 in früheren Versionen benötigen, können Sie ihn entweder manuell erstellen oder ihn aus einer früheren Version verwenden und die Schaltungen mit qpy um sie mit einer neueren Version zu laden.

Versch. Anmerkungen zu Upgrades

  • Die minimal unterstützte Version von Windows ist jetzt Windows 10. In früheren Versionen haben wir nicht explizit eine minimal unterstützte Version von Windows angegeben und implizit haben Windows 7, 8 und 8.1 möglicherweise funktioniert (wurden aber nie getestet). Da Rust 1.78 die Unterstützung für ältere Versionen von Windows eingestellt hat, werden die auf PyPI veröffentlichten Binärdateien von Qiskit ab dieser Version keine älteren Versionen von Windows mehr unterstützen. Wenn Sie eine ältere Version von Windows verwenden, können Sie Qiskit wahrscheinlich immer noch mit einem älteren Rust-Compiler aus dem Quellcode erstellen (die von Qiskit mindestens unterstützte Rust-Version für die Erstellung aus dem Quellcode ist derzeit 1.70 ), aber ältere Versionen von Windows sind keine unterstützte Plattform und werden nicht getestet.

Hinweise zu veralteten Versionen

  • Die Unterstützung für die Ausführung von Qiskit mit Python 3.8 ist veraltet und wird in der Qiskit 1.3.0 Version entfernt. Die 1.3.0 ist die erste Version, nachdem Python 3.8 das Ende seiner Lebensdauer erreicht hat und nicht mehr unterstützt wird. [1] Das bedeutet, dass Sie ab der Version 1.3.0 die von Ihnen verwendete Version Python auf Python 3.9 oder höher aktualisieren müssen.

    [1] https://devguide.python.org/versions/

Anbieter-Deprecations

  • Die abstrakten Basisklassen Provider und ProviderV1 sind nun veraltet und werden in Qiskit 2.0.0 entfernt. Die Abstraktion, die diese Schnittstellendefinitionen boten, stellte keinen wesentlichen Wert dar; sie kapselte lediglich die Attribute name, backends und eine get_backend(). Ein _provider_ als Konzept wird weiterhin als eine Sammlung von Backends existieren. Wenn Sie derzeit einen Anbieter implementieren, können Sie Ihren Code anpassen, indem Sie einfach ProviderV1 als übergeordnete Klasse Ihrer Implementierung entfernen. Als Teil davon würden Sie wahrscheinlich eine Implementierung von get_backend für die Abwärtskompatibilität hinzufügen wollen. Zum Beispiel:

    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]

Synthese-Veraltungen

  • Die TwoQubitWeylDecomposition.specialize() methode ist nun veraltet und wird in der Qiskit 2.0.0 Version entfernt. Diese Methode hatte nie einen öffentlichen Zweck und war für einen Endbenutzer unsicher, da sie die berechnete Zerlegung im Objekt verändern und ungültige Felder im Objekt erzeugen würde. Es wurde nur intern verwendet, um ein neues Objekt zu konstruieren TwoQubitWeylDecomposition objekts. Trotzdem war sie immer noch ein dokumentierter Teil der öffentlichen API für die Klasse und wird nun ohne potenziellen Ersatz veraltet. In dieser Version wird es immer eine NotImplementedError auslösen, wenn es aufgerufen wird, weil die Spezialisierung Subclassing als Teil der Rust Rewrite der Klasse entfernt wurde.

Transpiler-Veraltungen

  • Der Pass qiskit.transpiler.passes.CXCancellation wurde zugunsten von InverseCancellationveraltet, das allgemeiner ist. CXCancellation ist semantisch vollständig äquivalent zu InverseCancellation([CXGate()]).

  • Der Transpilationspass qiskit.transpiler.passes.ALAPSchedule ist jetzt veraltet. Seit Qiskit 0.37 (mit Terra 0.21 ), das im Juni 2022 veröffentlicht wurde, war es zur Veraltung anhängig. Der Durchgang wird ersetzt durch ALAPScheduleAnalysisersetzt, der ein Analysedurchgang ist.

  • Der Transpilationspass qiskit.transpiler.passes.ASAPSchedule ist jetzt veraltet. Seit Qiskit 0.37 (mit Terra 0.21 ), das im Juni 2022 veröffentlicht wurde, war es zur Veraltung anhängig. Er wurde abgelöst durch ASAPScheduleAnalysis und den neuen Terminierungs-Workflow ersetzt.

  • Der Transpilationspass qiskit.transpiler.passes.DynamicalDecoupling ist jetzt veraltet. Seit Qiskit 0.37 (mit Terra 0.21 ), das im Juni 2022 veröffentlicht wurde, war es zur Veraltung anhängig. Verwenden Sie stattdessen PadDynamicalDecouplingdie die gleiche Funktion ausführt, aber die Planung und die Ausrichtungsanalyse müssen vorher durchgeführt werden.

  • Der Transpilationspass qiskit.transpiler.passes.AlignMeasures ist jetzt veraltet. Seit Qiskit 0.37 (mit Terra 0.21 ), das im Juni 2022 veröffentlicht wurde, war es zur Veraltung anhängig. Verwenden Sie stattdessen ConstrainedRescheduledie die gleiche Funktion erfüllt und auch die Ausrichtung an zusätzlichen Zeitbeschränkungen unterstützt.

Veraltete Visualisierungen

  • Die Parameter show_idle und show_barrier in den Zeitleistenschubladen wurden durch idle_wires bzw. plot_barriers ersetzt, um den Parametern der Schaltkreisschubladen zu entsprechen. Ihre früheren Namen sind jetzt veraltet und werden in der nächsten Hauptversion entfernt. Die neuen Parameter sind völlig gleichwertig.

Fehlerkorrekturen

  • Es wurde ein Problem mit der Funktion qpy.dump() funktion behoben, bei der, wenn das use_symengine Flag auf ein wahrheitsgemäßes Objekt gesetzt wurde, das zu True ausgewertet wurde, aber eigentlich nicht der boolesche Wert True war, die generierte QPY-Nutzlast beschädigt wurde. Wenn Sie zum Beispiel use_symengine auf HAS_SYMENGINEsetzen, wird dieses Objekt als True ausgewertet, wenn es als bool gecastet wird, ist aber nicht wirklich True.

  • Es wurde ein Problem mit der circuit_drawer() funktion und QuantumCircuit.draw() methode beim Laden eines Matplotlib-Stils über die Benutzerkonfigurationsdatei.

  • Ein Problem wurde behoben, bei dem der ConstrainedReschedule transpiler-Durchlauf früher einen Fehler verursachte, wenn die Schaltung eine Reset anweisung enthielt. Dies wurde korrigiert, so dass der Durchlauf nun nicht mehr fehlerhaft ist. Allerdings kann sich die tatsächliche Hardware anders verhalten als von Qiskit Scheduler angenommen, insbesondere bei Messungen in der Mitte des Stromkreises und bei Rücksetzungen. Qiskit Scheduler meldet RuntimeWarning , wenn er auf einen Schaltkreis stößt, der einen der beiden Punkte enthält. Behoben #10354

  • Ein Problem mit der Klasse CommutationChecker wurde behoben, bei dem ein Fehler auftrat, wenn das Attribut eines Gates name attribut UTF8 kodiert war. Bisher funktionierten nur Gatternamen mit Ascii-Kodierung. Behoben #12501

  • Es wurde ein Problem mit den SparsePauliOp.apply_layout() und Pauli.apply_layout() methoden, wenn ein ungültiges Array mit doppelten oder negativen Indizes für das layout Argument übergeben wurde. Früher führte dies nicht zu einem Fehler und die durchgeführte Transformation war nicht gültig. Diese Methoden lösen nun ein QiskitError wenn doppelte Indizes oder negative Indizes als Teil eines Layouts angegeben werden.

  • Ein Leistungsproblem in den Programmen BackendSamplerV2 und BackendEstimatorV2. Behoben #12290

  • Es wurde ein Problem mit dem convert_to_target() bei dem der Konverter fälschlicherweise Kontrollflussanweisungen ignorierte, wenn sie im Attribut BackendConfiguration.supported_instructions angegeben waren, was der typische Ort ist, an dem Kontrollflussanweisungen in einem BackendConfiguration objekt angegeben werden. Behoben #11872.

  • Es wurde ein Problem mit dem circuit_drawer() oder QuantumCircuit.draw() bei der Verwendung der Ausgabeoption mpl , bei der das Programm hängen blieb, wenn der gezeichnete Schaltkreis eine ControlFlow -Operation enthielt und die Option fold auf -1 (d.h. keine Faltung) gesetzt war. Behoben #12012.

  • Es wurde ein Fehler bei der Konvertierung von benutzerdefinierten Impulsanweisungen in das Legacy qiskit.qobj format. Der Fehler wurde in Qiskit 1.0.0 eingeführt und führte dazu, dass die Konvertierung von Anweisungen mit benutzerdefinierten Pulsformen einen Fehler auslöste. Nach der Korrektur wird die Konvertierung korrekt durchgeführt, und der benutzerdefinierte Impuls wird in Waveform umgewandelt, wie es sein sollte. Behoben #11828.

  • Ein Fehler in transpile() wurde behoben, bei dem benutzerdefinierte instruction_durations, dt und backend_properties Constraints ignoriert wurden, wenn sie gleichzeitig mit einem Backend des Typs BackendV2. Das Verhalten nach der Korrektur ist nun unabhängig davon, ob das bereitgestellte Backend vom Typ BackendV1 oder Typ BackendV2. In ähnlicher Weise werden benutzerdefinierte timing_constraints jetzt durch target Eingaben überschrieben, haben aber Vorrang vor BackendV1 und BackendV2 eingaben.

  • Der Aufruf von EquivalenceLibrary.set_entry() wird nun das interne Graph-Objekt der Bibliothek korrekt aktualisiert. Bisher wurden zwar die Metadaten aktualisiert, aber die Struktur des Graphen blieb unverändert, so dass Benutzer wie BasisTranslator immer noch die alten Regeln verwenden würden. Behoben #11958.

  • Der EvolvedOperatorAnsatz behandelt jetzt korrekt den Fall, dass das Operator-Argument eine leere Liste ist. Zuvor hatte dies zu einem Fehler geführt.

  • Von nun an, EvolvedOperatorAnsatz keine Qregs mehr, wenn es null Qubits gibt, anstatt eine QuantumRegister instanz mit null Qubits. Dieses Verhalten steht im Einklang mit seiner Oberklasse QuantumCircuit.

  • Die Methode Instruction.repeat() verschiebt nun eine Menge condition zu den äußeren zurückgegebenen Instruction und lässt die inneren Gatter ihrer Definition unbedingt. Zuvor ließ die Methode ClassicalRegister instanzen innerhalb der inneren Definition, was ein ungültiger Zustand war und sich später als scheinbar unzusammenhängende Fehler manifestierte, z. B. bei der Transpilierung oder dem Export. Behoben #11935.

  • Es wurde ein Problem im InverseCancellation transpiler-Durchgang, bei dem in einigen Fällen ein selbstinverses parametrisiertes Gatter fälschlicherweise abgebrochen wurde, selbst wenn der Parameterwert nicht übereinstimmte. Behoben #11815

  • Verbessern Sie die Zerlegung der Gates MCXGate und MCPhaseGate ohne Verwendung von Ancilla-Qubits, so dass die Anzahl der CXGate quadratisch mit der Anzahl der Qubits und nicht exponentiell wächst.

  • Ein Fehler, der zum Absturz der convert_to_target() funktion abstürzt, wenn Qubit-Eigenschaften (entweder T1, T2 oder Frequenz) fehlen, wurde behoben. Die fehlenden Eigenschaftswerte in QubitProperties werden mit None aufgefüllt.

  • BasePassManager.run() wird nicht mehr die vorherige PropertySet in neue Workflows, wenn sie mehr als einmal aufgerufen werden. Zuvor wurden die gleichen PropertySet für die Initialisierung von Folgeläufen verwendet, was dazu führen konnte, dass ungültige Eigenschaftsinformationen an Aufgaben weitergegeben wurden. Das Verhalten entspricht nun dem von Qiskit 0.44. Behoben #11784.

  • Pauli.evolve() behandelt jetzt Quantenschaltungen mit ECR-Gattern korrekt. Früher wurden sie nicht als Clifford-Tore erkannt, und es wurde ein Fehler festgestellt.

  • Ein Fehler wurde behoben in Pauli.evolve() behoben, bei dem die Entwicklung durch einen Schaltkreis mit einem Namen, der mit bestimmten Clifford-Gattern ('cx', 'cz' usw.) übereinstimmt, den Pauli gemäß dem Namen des Schaltkreises entwickelt hat, nicht gemäß dem Inhalt des Schaltkreises. Dieser Fehler trat nur mit der nicht standardmäßigen Option frame='s' auf.

  • Es wurde ein Leistungsproblem in der Funktion qpy.load() funktion bei der Deserialisierung von QPY-Payloads mit einer großen Anzahl von Qubits oder Clbits in einem Schaltkreis.

  • Ein Fehler in der Behandlung des default_alignment Arguments von build(). Eingaben vom Typ AlignmentKind werden jetzt korrekt als Standardausrichtungen verarbeitet.

  • Es wurde ein Fehler in der Funktion qiskit.pulse.utils.format_parameter_value() behoben, der ungewollt große Integer-Zahlen in Float-Werte umwandelt oder unerwartete Rundungen verursacht. Siehe #11971 für weitere Informationen.

  • Behebung eines Problems in der QDrift klasse, bei dem die Koeffizienten des Hamiltonianers zuvor zwangsweise positiv waren, indem der Absolutwert jedes Koeffizienten genommen wurde. Dies wurde dahingehend korrigiert, dass die Vorzeichen der negativen Koeffizienten wieder hinzugefügt werden.

  • In convert_durations_to_dt() wurde ein Fehler behoben, bei dem die Funktion unabhängig von der ursprünglichen Einheit des Attributs blind eine Umrechnung von Sekunden in dt auf Schaltkreisdauern vornahm. Dies könnte zu falschen Größenordnungen bei den angegebenen Schaltkreisdauern führen.

  • Wurde korrigiert SparsePauliOp.apply_layout() um korrekt mit Null-Qubit-Operatoren zu arbeiten. Wenn Sie zum Beispiel zuvor ein 0-Qubit erstellt haben und ein Layout wie dieses anwenden:

    op = SparsePauliOp("")
    op.apply_layout(None, 3)

    hätte dies zuvor zu einem Fehler geführt. Dies wird nun korrekt einen Operator der Form zurückgeben: SparsePauliOp(['III'], coeffs=[1.+0.j])

  • Behebung eines Versehens im Commuting2qGateRouter transpiler-Pass, bei dem die qreg-Permutationen nicht zum Pass-Eigenschaftssatz hinzugefügt wurden, so dass sie vom Benutzer manuell nachverfolgt werden mussten. Jetzt ist es möglich, die Permutation über die Eigenschaft layout des Ausgangsschaltkreises abzurufen und den Durchgang ohne Informationsverlust in eine beliebige Transpilationspipeline einzufügen.

  • Eine Fließkomma-Ungenauigkeit bei der Skalierung bestimmter Impulseinheiten zwischen Sekunden und Nanosekunden wurde behoben. Wenn der Impuls symbolisch definiert war, konnte ein unnötiger Fließkommafehler durch die Skalierung für bestimmte Builds von symengine eingeführt werden, was zu unerwarteten Ergebnissen führen konnte, sobald die Symbole vollständig gebunden waren. Behoben #12392.

  • Die voreingestellten Pass-Manager von transpile() versagen nicht mehr bei Schaltungen mit Kontrollfluss, wenn kein Hardware-Ziel oder Basis-Gate-Set angegeben ist. Sie werden nun solche abstrakten Ziele so behandeln, als ob sie alle Kontrollflussoperationen zulassen. Behoben #11906.

  • Die Methode qiskit.instruction.Instruction.soft_compare() soll vergleichen, ob zwei Gatter in ihrem Namen, der Anzahl der Qubits, der Anzahl der Clbits und der Anzahl der Parameter übereinstimmen. Allerdings gab es einen Tippfehler, bei dem die Anzahl der Qubits und die Anzahl der Clbits nicht auf Übereinstimmung geprüft wurden. Damit ist der offensichtliche Tippfehler behoben.

  • Das Standard-Plugin init löste nicht korrekt ein TranspilerError wenn es mit einer ungültigen Optimierungsstufe aufgerufen wurde.

  • Es wurde ein Problem mit der Operator.from_circuit() konstruktormethode behoben, bei der die endgültige Layout-Permutation falsch interpretiert wurde, was dazu führte, dass ein ungültiger Operator konstruiert wurde. Bisher wurde das endgültige Layout ohne Rücksicht auf das anfängliche Layout verarbeitet, d.h. die Initialisierung war für alle Quantenschaltungen, die ein nicht-triviales Anfangslayout haben, falsch.

  • Es wurde ein Leistungsproblem in PassManager.run() wenn es über mehrere Schaltkreise parallel läuft. Es wird keine Zeit mehr für die Serialisierung der PassManager (was eine Voraussetzung für die parallele Ausführung ist), wenn mehrere Eingaben vorliegen, wenn die Eingaben nur seriell verarbeitet werden.

  • Parameter wurde aktualisiert, so dass Instanzen, die gleich sind, immer den gleichen Hash haben. Zuvor wurde nur die Parameter.uuid verglichen, so dass Parameter instanzen mit unterschiedlichen Namen konnten gleich verglichen werden, wenn sie mit einem gemeinsamen Wert für den Parameter uuid konstruiert worden waren (der normalerweise nicht explizit übergeben wird).

  • Es wurde ein Fehler in plot_coupling_map() behoben, der dazu führte, dass die Ränder der Kopplungskarte nicht korrekt eingefärbt wurden. Behoben #12369.

  • Der Parser OpenQASM 2.0 (qasm2.load() und qasm2.loads()) kann nun Gate-Winkel-Ausdrücke auswerten, die Integer-Operanden enthalten, die den System-Size-Integer überlaufen lassen würden. Diese werden in einem doppelpräzisen Fließkomma-Kontext ausgewertet, so wie der Rest des Ausdrucks immer ausgewertet wurde. Eine beliebig große ganze Zahl ist jedoch nicht notwendigerweise exakt in doppelter Genauigkeit darstellbar, so dass die Möglichkeit besteht, dass die Schaltung, wie auch immer sie erzeugt wurde, bereits alle numerische Präzision modulo 2π2\pi verloren hat.

  • Parameter instanzen, die als Stellvertreter für input -Variablen in OpenQASM 3-Programmen verwendet werden, haben nun escapte Namen, um Kollisionen mit eingebauten Gates beim Export nach OpenQASM 3 zu vermeiden. Zuvor konnte es zu Namenskonflikten kommen, und der Exporter erzeugte ungültige OpenQASM 3.

  • Fehler behoben in QuantumCircuit.draw() der dazu führte, dass benutzerdefinierte Stilwörterbücher für die Schublade Matplotlib bei der Ausführung geändert wurden.

  • QuantumCircuit.append() mit copy=True (Standardeinstellung) kopiert nun korrekt Anweisungen, die durch ParameterExpression instanzen parametrisiert sind, und nicht nur von Parameter instanzen.

  • Die interne Handhabung von kundenspezifischen Schaltkreiskalibrierungen und InstructionDurations wurde von der Funktion transpile() funktion auf die einzelnen Transpilerpässe übertragen: DynamicalDecoupling, DynamicalDecoupling. Zuvor wurden Befehlsdauern aus Schaltkreiskalibrierungen nicht berücksichtigt, es sei denn, sie wurden manuell in das Eingangsargument instruction_durations aufgenommen, aber die Pässe, die dies benötigen, analysieren nun den Schaltkreis und wählen den relevantesten Dauerwert gemäß der folgenden Prioritätsreihenfolge aus: target > custom input > circuit calibrations.

  • Es wurde ein Fehler in transpile() bei dem das Argument num_processes nur verwendet wurde, wenn dt oder instruction_durations angegeben wurde.

Sonstige Anmerkungen


1.0.0rc1

Hinweise zum Upgrade für Anbieter

  • Das abgelehnte qiskit.providers.fake_provider modul wurde in das qiskit-ibm-runtime Python Paket migriert. Aus diesem Grund wurden die folgenden Elemente in der qiskit.providers.fake_provider entfernt worden, nachdem sie in Qiskit veraltet sind 0.46:

    • qiskit.providers.fake_provider.FakeProvider
    • qiskit.providers.fake_provider.FakeProviderForBackendV2
    • qiskit.providers.fake_provider.FakeProviderFactory
    • qiskit.providers.fake_provider.fake_backends.FakeBackendV2
    • jedes gefälschte Backend, das in qiskit.providers.fake_provider.backends enthalten ist (zugänglich über den Provider)
    • qiskit.providers.fake_provider.FakeQasmSimulator
    • qiskit.providers.fake_provider.FakeJob
    • qiskit.providers.fake_provider.FakeQobj

    Um das neue Fake-Provider-Modul zu verwenden, können Sie pip install qiskit-ibm-runtime ausführen und den qiskit-Importpfad (qiskit.providers.fake_provider) durch den neuen Importpfad (qiskit_ibm_runtime.fake_provider) ersetzen. Beispiel für die Migration:

    # 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()

    Darüber hinaus wurden die folgenden, für spezielle Testzwecke entwickelten Fake-Backends durch die neue GenericBackendV2 klasse ersetzt und werden ebenfalls entfernt, nachdem sie in Qiskit veraltet sind 0.46:

    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2
    • `qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitProps
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2
    • qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple

    Beispiel für die Migration zur neuen GenericBackendV2 klasse:

    # 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
War diese Seite hilfreich?
Melden Sie auf GitHub einen Fehler, einen Tippfehler oder fordern Sie Inhalte an.