Skip to main content
IBM Quantum Platform

Qiskit 0.35 Versionshinweise


0.35.0

Terra- 0.20.0

Vorspiel

Die Highlights der Qiskit Terra 0.20.0 Version sind:

  • Die Einführung von Multithreading-Modulen, die in Rust geschrieben sind, um die Leistung bestimmter Teile von Qiskit Terra zu beschleunigen und die Skalierung mit einer größeren Anzahl von Qubits zu verbessern. Für die Erstellung von Qiskit aus dem Quellcode ist nun jedoch ein Rust-Compiler erforderlich.
  • Mehr native Unterstützung für die Arbeit mit einem Target im Transpiler. Mehrere Durchläufe unterstützen nun das direkte Arbeiten mit einem Target objekt zu arbeiten, was den Transpiler hinsichtlich der Arten von Backends, die er ansprechen kann, robust macht.
  • Die Einführung des qiskit.primitives moduls. Diese APIs bieten verschiedene Abstraktionsebenen für die Berechnung der gewünschten Ergebnisse von QuantumCircuit und die Verwendung von Backends. Zum Beispiel definiert die BaseEstimator eine abstrakte Schnittstelle für die Schätzung eines Erwartungswerts einer Beobachtungsgröße definiert. Auf dieser Grundlage können dann Algorithmen und Anwendungen auf höherer Ebene konstruiert werden, die auf der Schätzung von Erwartungswerten beruhen, ohne dass man sich um die Implementierung der Berechnung des Erwartungswertes kümmern muss. Durch diese Entkopplung kann die Implementierung an Geschwindigkeit und Qualität gewinnen, während sie sich an die definierte abstrakte Schnittstelle hält. Ebenso kann der BaseSampler berechnet Quasi-Wahrscheinlichkeitsverteilungen aus Schaltkreismessungen. Weitere Primitive werden in Zukunft eingeführt werden.

Diese Version bietet keine Unterstützung mehr für Python 3.6. Für diese Version sind Python 3.7 bis Python 3.10 erforderlich.

Neue Funktionen

  • Hinzufügen einer neuen Konstruktormethode für die Operator klasse, Operator.from_circuit() zum Erzeugen eines neuen Operator objekts aus einer QuantumCircuit. Während dies normalerweise mit dem Standardkonstruktor möglich war, bietet die Operator.from_circuit() methode bietet zusätzliche Optionen zur Anpassung der Art und Weise, wie der Operator erstellt wird. In erster Linie können Sie damit die Reihenfolge der Qubits auf der Grundlage eines Satzes permutieren Layout. Zum Beispiel:

    from qiskit.circuit import QuantumCircuit
    from qiskit import transpile
    from qiskit.transpiler import CouplingMap
    from qiskit.quantum_info import Operator
    
    circuit = QuantumCircuit(3)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.cx(1, 2)
    
    cmap = CouplingMap.from_line(3)
    out_circuit = transpile(circuit, initial_layout=[2, 1, 0], coupling_map=cmap)
    operator = Operator.from_circuit(out_circuit)

    bei der Variablen operator werden die Qubits auf der Grundlage des Layouts permutiert, so dass sie mit dem Ergebnis von Operator(circuit) vor der Transpilierung identisch ist.

  • Hinzufügen einer neuen Methode DAGCircuit.copy_empty_like() zu der DAGCircuit klasse. Diese Methode wird verwendet, um eine neue Kopie eines bestehenden DAGCircuit objekts mit der gleichen Struktur, aber ohne Anweisungen. Diese Methode ist die gleiche wie die private Methode _copy_circuit_metadata(), ist aber jetzt Teil der öffentlichen API der Klasse.

  • Die Fake-Backend- und Fake-Provider-Klassen, die bisher in qiskit.test.mock verfügbar waren, sind nun auch in einem neuen Modul zugänglich: qiskit.providers.fake_provider. Dieses neue Modul ersetzt das vorherige Modul qiskit.test.mock , das in Qiskit 0.21.0 veraltet sein wird.

  • Eine neue Gatterklasse wurde hinzugefügt, LinearFunctionhinzugefügt, die effizient eine lineare Funktion kodiert (d.h. eine Funktion, die durch eine Folge von CXGate und SwapGate gattern dargestellt werden kann).

  • Ein neuer Transpiler-Pass wurde hinzugefügt CollectLinearFunctions der Blöcke von aufeinanderfolgenden CXGate und SwapGate gattern in einer Schaltung sammelt und jeden Block durch ein LinearFunction gatter.

  • Ein neuer Transpiler-Pass wurde hinzugefügt LinearFunctionsSynthesis der beliebige Gatter synthetisiert LinearFunction gatter unter Verwendung des Patel-Markov-Hayes-Algorithmus synthetisiert. In Kombination mit dem CollectLinearFunctions transpiler-Durchgang ermöglicht dies das Sammeln von Blöcken aus aufeinanderfolgenden CXGate und SwapGate gatter in einer Schaltung zu sammeln und sie mit dem Patel-Markov-Hayes-Algorithmus neu zu synthetisieren.

  • Ein neuer Transpiler-Pass wurde hinzugefügt LinearFunctionsToPermutations der ein LinearFunction gatter durch einen Permutation schaltkreis ersetzt, wann immer dies möglich ist.

  • FlowController klassen (wie z.B ConditionalController) können nun innerhalb einer PassManager instanz verschachtelt werden, wenn man die PassManager.append() methode. Dies ermöglicht die Verwendung von verschachtelter Logik zur Steuerung der Ausführung von Durchläufen in der PassManager. Zum Beispiel:

    from qiskit.transpiler import ConditionalController, PassManager
    from qiskit.transpiler.passes import (
      BasisTranslator, GatesInBasis, Optimize1qGatesDecomposition, FixedPoint, Depth
    )
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    pm = PassManager()
    
    def opt_control(property_set):
        return not property_set["depth_fixed_point"]
    
    def unroll_condition(property_set):
        return not property_set["all_gates_in_basis"]
    
    depth_check = [Depth(), FixedPoint("depth")]
    opt = [Optimize1qGatesDecomposition(['rx', 'ry', 'rz', 'rxx'])]
    unroll = [BasisTranslator(sel, ['rx', 'ry', 'rz', 'rxx'])]
    unroll_check = [GatesInBasis(['rx', 'ry', 'rz', 'rxx'])]
    flow_unroll = [ConditionalController(unroll, condition=unroll_condition)]
    
    pm.append(depth_check + opt + unroll_check + flow_unroll, do_while=opt_control)

    Das pm PassManager objekt führt nur dann den BasisTranslator durchlauf (im Schritt unroll ) in jeder Schleifeniteration nur dann aus, wenn die unroll_condition erfüllt ist.

  • Die Konstruktoren für die ZFeatureMap und ZZFeatureMap klassen haben ein neues Schlüsselwortargument parameter_prefix. Dieses neue Argument wird verwendet, um das Präfix der Parameter der Datenkodierungsschaltung festzulegen. Zum Beispiel:

    from qiskit.circuit.library import ZFeatureMap
    
    feature_map = ZFeatureMap(feature_dimension=4, parameter_prefix="my_prefix")
    feature_map.decompose().draw('mpl')

    die erzeugte ZFeatureMap schaltung hat allen internen Parametern das Präfix "my_prefix" vorangestellt.

  • Der TemplateOptimization transpiler-Pass kann nun mit Gate objekten arbeiten, die ParameterExpression parameter haben. Ein anschauliches Beispiel für die Verwendung von Parameters mit TemplateOptimization ist das folgende:

    from qiskit import QuantumCircuit, transpile, schedule
    from qiskit.circuit import Parameter
    
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import TemplateOptimization
    
    # New contributions to the template optimization
    from qiskit.transpiler.passes.calibration import RZXCalibrationBuilder, rzx_templates
    
    from qiskit.test.mock import FakeCasablanca
    backend = FakeCasablanca()
    
    phi = Parameter('φ')
    
    qc = QuantumCircuit(2)
    qc.cx(0,1)
    qc.p(2*phi, 1)
    qc.cx(0,1)
    print('Original circuit:')
    print(qc)
    
    pass_ = TemplateOptimization(**rzx_templates.rzx_templates(['zz2']))
    qc_cz = PassManager(pass_).run(qc)
    print('ZX based circuit:')
    print(qc_cz)
    
    # Add the calibrations
    pass_ = RZXCalibrationBuilder(backend)
    cal_qc = PassManager(pass_).run(qc_cz.bind_parameters({phi: 0.12}))
    
    # Transpile to the backend basis gates
    cal_qct = transpile(cal_qc, backend)
    qct = transpile(qc.bind_parameters({phi: 0.12}), backend)
    
    # Compare the schedule durations
    print('Duration of schedule with the calibration:')
    print(schedule(cal_qct, backend).duration)
    print('Duration of standard with two CNOT gates:')
    print(schedule(qct, backend).duration)

    Ausgaben

    Original circuit:
    
    q_0: ──■──────────────■──
         ┌─┴─┐┌────────┐┌─┴─┐
    q_1: ┤ X ├┤ P(2*φ) ├┤ X ├
         └───┘└────────┘└───┘
    ZX based circuit:
                                             ┌─────────────┐            »
    q_0: ────────────────────────────────────┤0            ├────────────»
         ┌──────────┐┌──────────┐┌──────────┐│  Rzx(2.0*φ) │┌──────────┐»
    q_1: ┤ Rz(-π/2) ├┤ Rx(-π/2) ├┤ Rz(-π/2) ├┤1            ├┤ Rx(-2*φ) ├»
         └──────────┘└──────────┘└──────────┘└─────────────┘└──────────┘»
    «
    «q_0: ────────────────────────────────────────────────
    «     ┌──────────┐┌──────────┐┌──────────┐┌──────────┐
    «q_1: ┤ Rz(-π/2) ├┤ Rx(-π/2) ├┤ Rz(-π/2) ├┤ P(2.0*φ) ├
    «     └──────────┘└──────────┘└──────────┘└──────────┘
    Duration of schedule with the calibration:
    1600
    Duration of standard with two CNOT gates:
    6848
  • Die DAGOpNode, DAGInNode und DAGOutNode klassen definieren nun eine eigene __repr__ Methode, die eine Darstellung ausgibt. Gemäß der Dokumentation Python ist die Ausgabe eine Zeichenkettendarstellung, die ungefähr der Zeichenkette Python entspricht, die zur Erstellung eines entsprechenden Objekts verwendet wird.

  • Die Leistung der SparsePauliOp.simplify() methode wurde erheblich verbessert, indem die Verwendung von numpy.unique zur Berechnung eindeutiger Elemente eines Arrays durch eine neue, ähnliche, in Rust implementierte Funktion ersetzt wurde, die das Array nicht vorsortiert.

  • Hinzufügen einer neuen Methode equiv() in der SparsePauliOp klasse hinzugefügt, um die Gleichwertigkeit einer SparsePauliOp mit einem anderen SparsePauliOp objekt. Anders als der == Operator, der Operatoren elementweise vergleicht, equiv() vergleicht, ob zwei Operatoren gleichwertig sind oder nicht. Zum Beispiel:

    op = SparsePauliOp.from_list([("X", 1), ("Y", 1)])
    op2 = SparsePauliOp.from_list([("X", 1), ("Y", 1), ("Z", 0)])
    op3 = SparsePauliOp.from_list([("Y", 1), ("X", 1)])
    
    print(op == op2)  # False
    print(op == op3)  # False
    print(op.equiv(op2))  # True
    print(op.equiv(op3))  # True
  • Hinzufügen neuer Fake-Backend-Klassen aus Snapshots der IBM Quantum -Systeme auf Basis der BackendV2 schnittstelle und stellte eine Target für jedes Backend. BackendV2 basierten Versionen aller bestehenden Backends hinzugefügt, mit Ausnahme der drei alten Backends FakeRueschlikon, FakeTenerife und FakeTokyo , da für sie keine Snapshot-Dateien verfügbar sind, die für die Erstellung einer neuen Fake-Backend-Klasse auf der Grundlage von BackendV2.

    Diese neuen V2 Fake-Backends werden das Testen und die Entwicklung neuer Funktionen ermöglichen, die von BackendV2 und Target wie z.B. die Verbesserung des Transpilers.

  • Hinzufügen einer neuen Gatterklasse XXMinusYYGate in die Schaltkreisbibliothek (qiskit.circuit.library) für die XX-YY-Interaktion hinzugefügt. Dieses Gatter kann zur Implementierung des bSwap Gatters und seiner Potenzen verwendet werden. Sie tritt auch bei der Simulation von supraleitenden fermionischen Modellen auf.

  • Neue Gatterklasse hinzugefügt, XXPlusYYGatein die Schaltkreisbibliothek (qiskit.circuit.library). Dieses Gatter ist eine parametrisierte 2-Qubit-XX+YY-Wechselwirkung, auch als XY-Gatter bekannt, und basiert auf dem in https://arxiv.org/abs/1912.04424.

  • Die gefälschten Backends FakeBogota, FakeManila, FakeRome und FakeSantiago , die im Modul qiskit.providers.fake_provider zu finden sind, können nun als Backends in Pulse-Experimenten verwendet werden, da sie nun eine PulseDefaults enthalten, das aus einem Schnappschuss der Eigenschaften der entsprechenden IBM Quantum Maschine erstellt wurde.

  • Der ConsolidateBlocks pass hat ein neues Schlüsselwortargument in seinem Konstruktor, target. Dieses Argument wird verwendet, um ein Target objekt anzugeben, das das Kompilierungsziel für den Durchgang darstellt. Wenn er angegeben wird, ersetzt er den basis_gates kwarg. Wenn ein Ziel angegeben ist, berücksichtigt der Durchlauf die Gatter und Qubits für die in der Tabelle definierten Anweisungen Target definierten Anweisungen, wenn er entscheidet, welche Gatter zu einer Unitary zusammengefasst werden sollen.

  • Die Klasse Target klasse hat eine neue Methode, instruction_supported() die verwendet wird, um das Ziel abzufragen, um zu sehen, ob eine Anweisung (die Kombination aus einer Operation und dem/den Qubit(s), auf dem/denen sie ausgeführt wird) auf dem Backend unterstützt wird, das durch die Target.

  • Ein neuer kwarg, metadata_serializer, wurde der Funktion qpy.dump() funktion hinzugefügt, um eine benutzerdefinierte JSONEncoder Unterklasse anzugeben, die bei der Serialisierung des QuantumCircuit.metadata attributs und einen doppelten kwarg metadata_deserializer in die qpy.load() funktion für die Angabe einer JSONDecoder Unterklasse. Standardmäßig werden die dump() und load() funktionen versuchen, JSON mit dem stdlib-Standard-Json-Encoder und -Decoder zu serialisieren und zu deserialisieren. Da QuantumCircuit.metadata jedes beliebige Python Wörterbuch enthalten kann, auch solche mit Inhalten, die vom Standard-Encoder nicht in JSON serialisierbar sind, führt dies zu Schaltungen, die nicht serialisiert werden können. Das neue Argument metadata_serializer für dump() ermöglicht es den Benutzern, ein benutzerdefiniertes JSONEncoder anzugeben, das mit dem internen json.dump() Aufruf zur Serialisierung des QuantumCircuit.metadata wörterbuchs. Dies kann dann mit dem neuen Argument metadata_deserializer der Funktion qpy.load() funktion kombiniert werden, um diese benutzerdefinierten JSON-Kodierungen zu dekodieren. Wenn metadata_serializer unter dump() angegeben wird, metadata_deserializer aber nicht bei load() wird der QPY geladen, aber die Metadaten des Stromkreises werden möglicherweise nicht vollständig rekonstruiert.

    Wenn Sie zum Beispiel eine benutzerdefinierte Serialisierung für Metadaten definieren und diese dann laden möchten, können Sie so vorgehen:

    from qiskit.qpy import dump, load
    from qiskit.circuit import QuantumCircuit, Parameter
    import json
    import io
    
    class CustomObject:
        """Custom string container object."""
    
        def __init__(self, string):
            self.string = string
    
        def __eq__(self, other):
            return self.string == other.string
    
    class CustomSerializer(json.JSONEncoder):
        """Custom json encoder to handle CustomObject."""
    
        def default(self, o):
            if isinstance(o, CustomObject):
                return {"__type__": "Custom", "value": o.string}
            return json.JSONEncoder.default(self, o)
    
    class CustomDeserializer(json.JSONDecoder):
        """Custom json decoder to handle CustomObject."""
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, object_hook=self.object_hook, **kwargs)
    
        def object_hook(self, o):
            """Hook to override default decoder."""
            if "__type__" in o:
                obj_type = o["__type__"]
                if obj_type == "Custom":
                    return CustomObject(o["value"])
            return o
    
    theta = Parameter("theta")
    qc = QuantumCircuit(2, global_phase=theta)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    circuits = [qc, qc.copy()]
    circuits[0].metadata = {"key": CustomObject("Circuit 1")}
    circuits[1].metadata = {"key": CustomObject("Circuit 2")}
    with io.BytesIO() as qpy_buf:
        dump(circuits, qpy_buf, metadata_serializer=CustomSerializer)
        qpy_buf.seek(0)
        new_circuits = load(qpy_buf, metadata_deserializer=CustomDeserializer)
  • Der DenseLayout pass hat ein neues Schlüsselwortargument in seinem Konstruktor, target. Dieses Argument wird verwendet, um ein Target objekt anzugeben, das das Kompilierungsziel für den Durchgang darstellt. Wenn er angegeben wird, ersetzt er die anderen Argumente des Konstruktors, coupling_map und backend_prop.

  • Die Klasse Target klasse hat eine neue Methode, operation_names_for_qargs(). Diese Methode wird verwendet, um die Namen der Operationen (d. h. die Nachschlageschlüssel im Ziel) für die Operationen auf einem gegebenen qargs Tupel zu erhalten.

  • Ein neuer Pass DynamicalDecouplingPadding wurde dem qiskit.transpiler.passes modul hinzugefügt. Dieser neue Durchgang ersetzt den bestehenden DynamicalDecoupling pass, um mit dem neuen Planungsworkflow im Transpiler zu arbeiten. Er ist eine Unterklasse des BasePadding -Durchlaufs und hängt davon ab, dass die Planungs- und Ausrichtungsanalyse-Durchläufe vor ihm in einer PassManager. Dieser neue Durchlauf kann ein pulse_alignment Argument annehmen, das eine Hardware-Beschränkung für das Start-Timing der Wellenform darstellt. Der Abstand zwischen den Gattern, die eine dynamische Entkopplungssequenz bilden, wird nun so angepasst, dass diese Bedingung erfüllt ist, so dass die Schaltung auf Hardware mit dieser Bedingung ausgeführt werden kann. Dieser Wert ist in der Regel unter BackendConfiguration.timing_constraints zu finden. Zusätzlich verfügt der Pass über eine extra_slack_distribution Option, mit der Sie steuern können, wie der zusätzliche Spielraum verteilt werden soll, wenn die Dauer der erstellten dynamischen Entkopplungssequenz kürzer ist als die Leerlaufzeit Ihrer Schaltung, die Sie mit der Sequenz füllen möchten. Die Standardeinstellung ist middle , was dem herkömmlichen Verhalten entspricht. Mit der neuen Strategie split_edges wird der zusätzliche Spielraum gleichmäßig auf den Anfang und das Ende der Sequenz aufgeteilt, anstatt ihn dem Intervall in der Mitte der Sequenz hinzuzufügen. Dies kann zu einer besseren Rauschunterdrückung führen, insbesondere wenn pulse_alignment > 1 ist.

  • Die Klasse Z2Symmetries klasse zeigt nun die Schwellentoleranzen an, mit denen kleine Real- und Imaginärteile von Koeffizienten zerhackt werden. Damit kann man steuern, wie die Koeffizienten des verjüngten Operators vereinfacht werden. Zum Beispiel:

    from qiskit.opflow import Z2Symmetries
    from qiskit.quantum_info import Pauli
    
    z2_symmetries = Z2Symmetries(
        symmetries=[Pauli("IIZI"), Pauli("IZIZ"), Pauli("ZIII")],
        sq_paulis=[Pauli("IIXI"), Pauli("IIIX"), Pauli("XIII")],
        sq_list=[1, 0, 3],
        tapering_values=[1, -1, -1],
        tol=1e-10,
    )

    Standardmäßig werden die Koeffizienten mit einer Toleranz von tol=1e-14 zerhackt.

  • Hinzufügen einer chop() methode zu der SparsePauliOp klasse hinzugefügt, die Real- und Imaginärteile von Koeffizienten einzeln abschneidet. Dies ist anders als die SparsePauliOp.simplify() methode, bei der ein Koeffizient nur dann entfernt wird, wenn der absolute Wert nahe bei 0 liegt. Zum Beispiel:

    >>> from qiskit.quantum_info import SparsePauliOp
    >>> op = SparsePauliOp(["X", "Y", "Z"], coeffs=[1+1e-17j, 1e-17+1j, 1e-17])
    >>> op.simplify()
    SparsePauliOp(['X', 'Y'],
                  coeffs=[1.e+00+1.e-17j, 1.e-17+1.e+00j])
    >>> op.chop()
    SparsePauliOp(['X', 'Y'],
                  coeffs=[1.+0.j, 0.+1.j])

    Beachten Sie, dass bei der Chop-Methode die Koeffizienten desselben Paulis nicht kumuliert werden, z. B.

    >>> op = SparsePauliOp(["X", "X"], coeffs=[1+1e-17j, 1e-17+1j)
    >>> op.chop()
    SparsePauliOp(['X', 'X'],
                  coeffs=[1.+0.j, 0.+1.j])
  • Ein neuer kwarg, target, wurde zum Konstruktor für den GatesInBasis transpiler-Pass. Dieses neue Argument kann verwendet werden, um optional ein Target objekt anzugeben, das das Backend repräsentiert. Wenn dies eingestellt ist Target verwendet, um festzustellen, ob ein DAGCircuit gatter außerhalb der Basismenge enthält, und das Argument basis_gates wird nicht verwendet.

  • Teilweise Unterstützung für den Betrieb auf den Plattformen ppc64le und s390x Linux hinzugefügt. Mit dieser Version werden vorkompilierte Binärdateien für die Plattformen ppc64le und s390x Linux auf allen Python Versionen veröffentlicht. Im Gegensatz zu anderen unterstützten Plattformen unterstützen jedoch noch nicht alle Upstream-Abhängigkeiten von Qiskit diese Plattformen. Daher kann ein C/C++-Compiler erforderlich sein, um diese Abhängigkeiten zu erstellen und zu installieren, und ein einfaches pip install qiskit-terra mit einer funktionierenden Python Umgebung wird nicht ausreichen, um Qiskit zu installieren. Außerdem hindern uns dieselben Einschränkungen daran, die vorkompilierten Räder vor der Veröffentlichung zu testen, so dass die gleichen Garantien für die Plattformunterstützung, die für andere Plattformen gelten, hier nicht gelten.

  • Die Gradient und QFI klassen können nun den Imaginärteil der Erwartungswertgradienten berechnen. Bei Verwendung einer anderen Bemessungsgrundlage, d. h. -Y anstelle von Z können wir den Imaginärteil von Gradienten messen. Die Messbasis kann mit dem Argument aux_meas_op festgelegt werden.

    Für die Gradienten berechnet aux_meas_op = Z 0.5Re[(⟨ψ(ω)|)O(θ)|dωψ(ω)〉] und aux_meas_op = -Y 0.5Im[(⟨ψ(ω)|)O(θ)|dωψ(ω)〉]. Für die QFIs berechnet aux_meas_op = Z 4Re[(dω⟨<ψ(ω)|)(dω|ψ(ω)〉)] und aux_meas_op = -Y berechnet 4Im[(dω⟨<ψ(ω)|)(dω|ψ(ω)〉)]. Zum Beispiel:

    from qiskit import QuantumRegister, QuantumCircuit
    from qiskit.opflow import CircuitStateFn, Y
    from qiskit.opflow.gradients.circuit_gradients import LinComb
    from qiskit.circuit import Parameter
    
    a = Parameter("a")
    b = Parameter("b")
    params = [a, b]
    
    q = QuantumRegister(1)
    qc = QuantumCircuit(q)
    qc.h(q)
    qc.rz(params[0], q[0])
    qc.rx(params[1], q[0])
    op = CircuitStateFn(primitive=qc, coeff=1.0)
    
    aux_meas_op = -Y
    
    prob_grad = LinComb(aux_meas_op=aux_meas_op).convert(operator=op, params=params)
  • Die Klasse InstructionDurations klasse unterstützt nun die Arbeit mit Parametern einer Anweisung. Jeder Eintrag in einem InstructionDurations objekt besteht nun aus einem Tupel von (inst_name, qubits, duration, parameters, unit). Dies ermöglicht es einem InstructionDurations die Dauer eines Befehls bei einem bestimmten Parameterwert zu definieren, um unterschiedliche Dauern bei unterschiedlichen Parameterwerten eines Befehls mit einem numerischen Parameter zu berücksichtigen.

  • Ein neuer Wert für das Schlüsselwortargument style für die Funktion Schaltkreiszeichner wurde hinzugefügt circuit_drawer() und QuantumCircuit.draw() methode, iqx_dark. Wenn style auf iqx_dark mit dem mpl Schubladen-Backend eingestellt ist, wird die Ausgabevisualisierung ein Farbschema verwenden, das dem Farbschema des dunklen Modus ähnelt, das vom IBM Quantum Composer verwendet wird. Zum Beispiel:

    from qiskit.circuit import QuantumCircuit
    from matplotlib.pyplot import show
    
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.p(0.2, 1)
    
    circuit.draw("mpl", style="iqx-dark")
  • Dem neuen Modul wurden mehrere "Lazy Dependency Checker" hinzugefügt qiskit.utils.optionalshinzugefügt, mit denen abgefragt werden kann, ob bestimmte Qiskit-Funktionen verfügbar sind. Sie können zum Beispiel fragen, ob Qiskit das Vorhandensein von matplotlib erkannt hat, indem Sie if qiskit.utils.optionals.HAS_MATPLOTLIB fragen. Diese Objekte versuchen nur, ihre Abhängigkeiten zu importieren, wenn sie abgefragt werden, so dass Sie sie im Laufzeitcode verwenden können, ohne die Importzeit zu beeinflussen.

  • Die Importzeit für qiskit wurde erheblich verbessert, insbesondere für diejenigen, die viele der optionalen Abhängigkeiten von Qiskit Terra installiert haben.

  • Die Funktion marginal_counts() funktion unterstützt nun die Marginalisierung des memory Feldes eines Eingabe Result objekts. Wenn zum Beispiel das Eingabeargument result ein qiskit Result objekt ist, das aus einer 4-Qubit-Messung stammt, können wir das erste Qubit mit marginalisieren:

    print(result.results[0].data.memory)
    marginal_result = marginal_counts(result, [0])
    print(marginal_result.results[0].data.memory)

    Die Ausgabe sieht wie folgt aus:

    ['0x0', '0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7']
    ['0x0', '0x1', '0x0', '0x1', '0x0', '0x1', '0x0', '0x1']
  • Die Interna des StochasticSwap algorithmus wurden neu implementiert, um multithreadingfähig zu sein, und sind nun in der Programmiersprache Rust statt in Cython geschrieben. Dadurch wird die Laufzeitleistung des Compiler-Passes und damit auch transpile() wenn er mit optimization_level 0, 1 und 2 ausgeführt wird. Standardmäßig verwendet der Durchlauf die Anzahl der logischen CPUs auf Ihrem lokalen System, aber Sie können die Anzahl der vom Durchlauf verwendeten Threads steuern, indem Sie die Umgebungsvariable RAYON_NUM_THREADS auf einen ganzzahligen Wert setzen. Wenn Sie zum Beispiel RAYON_NUM_THREADS=4 einstellen, läuft die StochasticSwap mit 4 Threads.

  • Eine neue Umgebungsvariable QISKIT_FORCE_THREADS steht zur Verfügung, mit der Benutzer direkt steuern können, ob potenziell multithreadingfähige Teile des Qiskit-Codes in mehreren Threads ausgeführt werden sollen. Momentan wird dies nur von dem StochasticSwap transpiler pass verwendet, aber es wird wahrscheinlich in Zukunft auch in anderen Teilen von Qiskit verwendet werden. Wenn diese Umgebungsvariable auf TRUE gesetzt ist, wird jeder Multithreading-Code in Qiskit Terra immer mehrere Threads verwenden, unabhängig von anderen Laufzeitbedingungen, die andernfalls die Funktion dazu veranlasst hätten, eine Single-Thread-Variante zu verwenden. Zum Beispiel, wenn StochasticSwap wenn der Durchlauf als Teil eines transpile() aufrufs mit > 1 Schaltkreis, der parallel zu multiprocessing über parallel_map() der StochasticSwap werden nicht mehrere Threads verwendet, um eine mögliche Überbelegung von CPU-Ressourcen zu vermeiden. Wenn Sie jedoch mehrere Threads im Durchlauf zusammen mit mehreren Prozessen verwenden möchten, können Sie QISKIT_FORCE_THREADS=TRUE einstellen.

  • Neue Fake-Backend-Klassen sind unter qiskit.providers.fake_provider verfügbar. Dazu gehören nachgebildete Versionen von ibm_cairo, ibm_hanoi, ibmq_kolkata, ibm_nairobi und ibm_washington. Wie bei den anderen Fake-Backends enthalten diese Schnappschüsse von Kalibrierungs- und Fehlerdaten, die dem realen System entnommen wurden, und können für lokale Tests, Kompilierung und Simulation verwendet werden.

  • Einführung einer neuen Klasse StatePreparation. Diese Klasse ermöglicht es dem Benutzer, einen gewünschten Zustand auf die gleiche Weise wie Initialize vorzubereiten, ohne dass der Reset automatisch durchgeführt wird.

    Um zum Beispiel ein Qubit in den Zustand (∣0⟩−∣1⟩)/2(|0\rangle - |1\rangle) / \sqrt{2} zu versetzen:

    import numpy as np
    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(1)
    circuit.prepare_state([1/np.sqrt(2), -1/np.sqrt(2)], 0)
    circuit.draw()

    Die Ausgabe ist wie folgt:

         ┌─────────────────────────────────────┐
    q_0: ┤ State Preparation(0.70711,-0.70711) ├
         └─────────────────────────────────────┘
  • Der Optimize1qGates transpiler-Pass unterstützt jetzt die Optimierung von U1Gate, U2Gate, und PhaseGate gatter mit ungebundenen Parametern in einer Schaltung. Wenn diese Gates ungebundene Parameter hatten, konnte der Pass diese nicht verwenden. Zum Beispiel:

    from qiskit import QuantumCircuit
    from qiskit.circuit import Parameter
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import Optimize1qGates, Unroller
    
    phi = Parameter('φ')
    alpha = Parameter('α')
    
    qc = QuantumCircuit(1)
    qc.u1(2*phi, 0)
    qc.u1(alpha, 0)
    qc.u1(0.1, 0)
    qc.u1(0.2, 0)
    
    pm = PassManager([Unroller(['u1', 'cx']), Optimize1qGates()])
    nqc = pm.run(qc)

    wird zu einer Schaltung mit nur einem Ein-Qubit-Gatter kombiniert:

    qc = QuantumCircuit(1)
    qc.u1(2*phi + alpha + 0.3, 0)
  • Die Methoden Pauli.evolve() und PauliList.evolve() haben jetzt ein neues Schlüsselwortargument, frame, das verwendet wird, um eine Evolution eines Pauli durch einen Clifford durchzuführen. Wenn frame='h' (Standardeinstellung), dann wird die Entwicklung des Heisenberg-Bildes von Pauli durch Clifford ( P′=C†PCP' = C^\dagger P C ) berechnet, und wenn frame='s' , dann wird die Entwicklung des Schrödinger-Bildes von Pauli durch Clifford ( P′=CPC†P' = C P C^\dagger ) berechnet. Die letztere Option führt zu einer schnelleren Berechnung und ist in bestimmten Fällen auch nützlich. Diese neue Option macht die Berechnung der gierigen Clifford-Zerlegung in decompose_clifford deutlich schneller.

  • Ein neues Modul zu Qiskit hinzugefügt: qiskit.primitives. Im Primitivmodul werden APIs definiert, die verschiedene Abstraktionen für die Berechnung bestimmter allgemeiner Funktionen von QuantumCircuit bereitstellen, wodurch die Details der zugrunde liegenden Ausführung auf Backend abstrahiert werden. Dadurch können sich Algorithmen und Anwendungen auf höherer Ebene auf die Durchführung der Berechnungen konzentrieren und müssen sich nicht um die Ausführung und Verarbeitung der Ergebnisse kümmern. Beispielsweise kann die Schätzung eines Erwartungswerts eines Quantenschaltkreises und einer Beobachtungsgröße von jeder Klasse durchgeführt werden, die die BaseEstimator implementiert und unabhängig von der zugrundeliegenden Implementierung in einer standardisierten Weise verbraucht werden. Die Anwendungen können dann direkt über die primitive Schnittstelle geschrieben werden.

    Zu Beginn enthält das Modul zwei Arten von Primitiven, die Sampler (siehe BaseSampler für die Definition der abstrakten Klasse) und Estimator (siehe BaseEstimator für die Definition der abstrakten Klasse). Referenzimplementierungen sind im qiskit.primitives modul enthalten und werden mit dem qiskit.quantum_info modul erstellt, die eine ideale Simulation der primitiven Operation durchführen. Die Erwartung ist, dass Anbieterpakete ihre eigenen Implementierungen dieser Schnittstellen für Anbieter anbieten, die das Protokoll effizient nativ implementieren können (typischerweise unter Verwendung einer klassischen Laufzeit). Zusätzlich wird in Zukunft für Provider, die keine native Implementierung der Primitive anbieten, eine Methode bereitgestellt, die es ermöglicht, primitive Objekte aus einer Backend.

  • Ein neues Modul wurde hinzugefügt, qiskit.qpy, das die Funktionalität enthält, die zuvor in qiskit.circuit.qpy_serialization enthalten war. Die öffentlichen Funktionen, die zuvor auf qiskit.circuit.qpy_serialization veröffentlicht wurden, dump() und load() sind jetzt über dieses neue Modul verfügbar (obwohl sie weiterhin über qiskit.circuit.qpy_serialization zugänglich sind, aber dies wird in einer zukünftigen Version veraltet sein). Dieses neue Modul wurde im Interesse der zukünftigen Ausrichtung des QPY-Dateiformats hinzugefügt, das in zukünftigen Versionen die Darstellung von pulse Schedule und ScheduleBlock objekte zusätzlich zu den QuantumCircuit objekte unterstützt.

  • Ein neues Attribut wurde hinzugefügt, qubit_properties zu der Target klasse. Dieses Attribut enthält eine Liste von QubitProperties objekten für jedes Qubit im Ziel. Zum Beispiel:

    target.qubit_properties[2]

    enthält die QubitProperties für das Qubit Nummer 2 im Ziel.

    Für BackendV2 autoren, wenn Sie bisher QubitProperties direkt in Ihrer BackendV2 implementierung durch Überschreiben von BackendV2.qubit_properties() definiert haben, wird dies immer noch gut funktionieren. Wenn Sie jedoch die Definition in das zugrunde liegende Target objekt verschieben und die spezialisierte BackendV2.qubit_properties() implementierung entfernen, was die Verwendung von Qubit-Eigenschaften im Transpiler ermöglicht und auch die API-Kompatibilität mit Ihrer vorherigen Implementierung aufrechterhält.

  • Eine neue Funktion wurde hinzugefügt, qiskit.algorithms.eval_observables(), die verwendet wird, um Beobachtungswerte zu bewerten, die durch eine Grenze QuantumCircuit. Sie stammt aus einer privaten Methode, _eval_aux_ops(), der Klasse qiskit.algorithms.VQE klasse, aber die neue eval_observables() funktion ist nun allgemeiner, so dass sie auch in anderen Algorithmen, z. B. Zeitentwicklungsalgorithmen, verwendet werden kann.

  • Die Strategie der Basissuche in BasisTranslator transpiler pass wurde in eine Variante der Dijkstra-Suche umgewandelt, die die Laufzeitleistung des Passes erheblich verbessert, wenn versucht wird, eine unerreichbare Basis zu finden.

  • Der DenseLayout transpiler-Durchlauf ist jetzt multithreaded, was die Laufzeitleistung des Durchlaufs erheblich verbessert. Standardmäßig wird die Anzahl der logischen CPUs auf Ihrem lokalen System verwendet, aber Sie können die Anzahl der vom Pass verwendeten Threads steuern, indem Sie die Umgebungsvariable RAYON_NUM_THREADS auf einen ganzzahligen Wert setzen. Wenn Sie zum Beispiel RAYON_NUM_THREADS=4 einstellen, wird der DenseLayout durchlauf mit 4 Threads.

  • Die internen Berechnungen von Statevector.expectation_value() und DensityMatrix.expectation_value() methoden wurden in der Programmiersprache Rust neu implementiert. Diese neue Implementierung ist multithreadingfähig und standardmäßig für eine Statevector oder DensityMatrix >= 19 Qubits wird ein Thread-Pool mit der Anzahl der auf dem lokalen System verfügbaren logischen CPUs erzeugt. Sie können die Anzahl der verwendeten Threads steuern, indem Sie die Umgebungsvariable RAYON_NUM_THREADS auf einen ganzzahligen Wert setzen. Wenn Sie zum Beispiel RAYON_NUM_THREADS=4 einstellen, werden nur 4 Threads im Thread-Pool verwendet.

  • Hinzufügen eines neuen SparsePauliOp.from_sparse_list() konstruktor hinzugefügt, der eine iterable nimmt, wobei die Elemente Pauli-Terme darstellen, die selbst sparse sind, so dass "XIIIIIIIIIIIIIIIX" jetzt als ("XX", [0, 16]) geschrieben werden kann. Zum Beispiel, der Operator

H=X0Z3+2Y1Y4H = X_0 Z_3 + 2 Y_1 Y_4

kann nun konstruiert werden als

op = SparsePauliOp.from_sparse_list([("XZ", [0, 3], 1), ("YY", [1, 4], 2)], num_qubits=5)
# or equivalently, as previously
op = SparsePauliOp.from_list([("IZIIX", 1), ("YIIYI", 2)])

Dies erleichtert die Konstruktion von sehr spärlichen Operatoren auf vielen Qubits, wie es bei Ising-Hamiltonianern oft der Fall ist.

  • Der UnitarySynthesis transpilerpass hat ein neues Schlüsselwortargument in seinem Konstruktor, target. Dies kann verwendet werden, um optional ein Target objekt anzugeben, das das Kompilierungsziel für den Durchgang darstellt. Wenn er angegeben wird, ersetzt er die für basis_gates, coupling_map und backend_props festgelegten Werte.

  • Die UnitarySynthesisPlugin abstrakte Plugin-Klasse hat ein neues optionales Attribut, das Implementierungen hinzufügen können, supports_target. Wenn ein Plugin dieses Attribut auf True gesetzt hat, wird ein Target objekt in der Nutzlast options unter dem Feld target übergeben. Die Erwartung ist, dass dieses Target objekt anstelle von coupling_map, gate_lengths, basis_gates und gate_errors verwendet wird.

  • Einführung eines neuen Transpiler-Pass-Workflows zur Erstellung von PassManager objekten für die Terminierung QuantumCircuit objekte im Transpiler. In dem neuen Arbeitsablauf sind alle Planungs- und Ausrichtungsdurchläufe AnalysisPass objekte, die nur den Eigenschaftssatz des Durchlaufmanagers aktualisieren, insbesondere das neue Eigenschaftssatz-Element node_start_time, das die absolute Startzeit jedes Opnodes enthält. Eine separate TransformationPass wie z.B PadDelay wird anschließend verwendet, um die Zeitplanung auf die DAG anzuwenden. Dieser neue Arbeitsablauf ist sowohl effizienter als auch in der Lage, zusätzliche zeitliche Beschränkungen zu korrigieren, die durch ein Backend aufgedeckt werden.

    Zuvor wurde die Durchlaufkette als scheduling -> alignment implementiert, die beide Transformationsdurchläufe waren, so dass bei jedem Durchlauf mehrere DAGCircuit instanzen während jedes Durchgangs neu erstellt. Darüber hinaus wurde in jedem Durchgang eine Zeitplanung vorgenommen, um die Startzeit der Anweisungen zu erhalten. Jetzt wird die erforderliche Passkette scheduling -> alignment -> padding , wobei die DAGCircuit aktualisierung erst am Ende mit dem Durchgang padding erfolgt.

    Für diejenigen, die benutzerdefinierte PassManager objekte erstellen, die eine Schaltkreisplanung beinhalten, müssen Sie Ihre PassManager anpassen, um einen der BasePadding Durchläufe einzufügen (derzeit entweder PadDelay oder PadDynamicalDecoupling verwendet werden kann) am Ende der Planungskette einfügen. Ohne den Auffüllungsdurchgang werden die Zeitplanungsdurchgänge nicht in der Ausgangsschaltung der run() methode Ihrer benutzerdefinierten PassManager.

    Wenn Sie zum Beispiel vorher Ihre PassManager mit etwas wie:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import TimeUnitConversion, ALAPSchedule, ValidatePulseGates, AlignMeasures
    
    pm = PassManager()
    scheduling = [
        ALAPSchedule(instruction_durations), PadDelay()),
        ValidatePulseGates(granularity=timing_constraints.granularity, min_length=timing_constraints.min_length),
        AlignMeasures(alignment=timing_constraints.acquire_alignment),
    ]
    pm.append(scheduling)

    können Sie stattdessen verwenden:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import TimeUnitConversion, ALAPScheduleAnalysis, ValidatePulseGates, AlignMeasures, PadDelay
    
    pm = PassManager()
    scheduling = [
        ALAPScheduleAnalysis(instruction_durations), PadDelay()),
        ConstrainedReschedule(acquire_alignment=timing_constraints.acquire_alignment, pulse_alignment=timing_constraints.pulse_alignment),
        ValidatePulseGates(granularity=timing_constraints.granularity, min_length=timing_constraints.min_length),
        PadDelay()
    ]
    pm.append(scheduling)

    die sowohl effizienter ist als auch die Befehle auf der Grundlage von Hardware-Beschränkungen ausrichtet.

  • Ein neuer Transpiler-Pass wurde hinzugefügt ConstrainedReschedule passieren. Der ConstrainedReschedule pass berücksichtigt sowohl Hardware-Ausrichtungsbeschränkungen, die in einem BackendConfiguration objekt definiert werden können, pulse_alignment und acquire_alignment. Diese neue Klasse ersetzt die vorher existierende AlignMeasures da sie zusätzlich zur allgemeinen Befehlsausrichtung die gleiche Ausrichtung (über den Eigenschaftssatz) für Messanweisungen durchführt. Durch das Setzen des acquire_alignment constraint-Arguments für den ConstrainedReschedule passes ist es ein sofortiger Ersatz für AlignMeasures wenn er mit einem neuen BasePadding Pass gepaart wird.

  • Zwei neue Transpilerpässe hinzugefügt ALAPScheduleAnalysis und ASAPScheduleAnalysis die die Übergänge ALAPSchedule und ASAPSchedule als Teil des überarbeiteten Transpiler-Workflows für Schedling ersetzen. Die neuen Durchläufe führen die gleiche Planung durch, jedoch im Eigenschaftssatz und unter Verwendung eines BasePadding Durchlaufs, um die Schaltung auf der Grundlage der gesamten Analyse der Planungsausrichtung anzupassen.

    Das Standardverhalten dieser Durchläufe richtet auch die zeitliche Reihenfolge an der topologischen Reihenfolge der DAG-Knoten aus. Diese Änderung kann sich auf das Ergebnis der Zeitplanung auswirken, wenn sie bedingte Operationen oder die gleichzeitige Messung von zwei Qubits mit demselben klassischen Register umfasst (Edge-Case). Um das herkömmliche Verhalten zu reproduzieren, stellen Sie clbit_write_latency gleich der Länge der Messanweisung ein.

    Betrachten Sie zum Beispiel die Planung einer Eingangsschaltung wie:

         ┌───┐┌─┐
    q_0: ┤ X ├┤M├──────────────
         └───┘└╥┘   ┌───┐
    q_1: ──────╫────┤ X ├──────
               ║    └─╥─┘   ┌─┐
    q_2: ──────╫──────╫─────┤M├
               ║ ┌────╨────┐└╥┘
    c: 1/══════╩═╡ c_0=0x1 ╞═╩═
               0 └─────────┘ 0
    from qiskit import QuantumCircuit
    from qiskit.transpiler import InstructionDurations, PassManager
    from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDelay, SetIOLatency
    from qiskit.visualization.timeline import draw
    
    circuit = QuantumCircuit(3, 1)
    circuit.x(0)
    circuit.measure(0, 0)
    circuit.x(1).c_if(0, 1)
    circuit.measure(2, 0)
    
    durations = InstructionDurations([("x", None, 160), ("measure", None, 800)])
    
    pm = PassManager(
        [
          SetIOLatency(clbit_write_latency=800, conditional_latency=0),
          ALAPScheduleAnalysis(durations),
          PadDelay(),
        ]
    )
    draw(pm.run(circuit))

    Wie Sie in der Zeitachsenansicht sehen können, beginnt die Messung auf q_2 vor dem bedingten X-Gate auf q_1, was der topologischen Anordnung des Knotens entgegengesetzt zu sein scheint. Dies ist auch das erwartete Verhalten, da der Schreibzugriff von clbit an der Endflanke des Messbefehls erfolgt und der Lesezugriff des bedingten Gatters an der Anfangsflanke des Befehls erfolgt. So bleibt die topologische Ordnung auf dem Zeitschlitz des klassischen Registers erhalten, die von der Zeitleistenansicht nicht erfasst wird. Dies setzt jedoch eine bestimmte Mikroarchitektur voraus, und die Schaltung muss nicht so geplant werden.

    Bei Verwendung der Standardkonfiguration von Pässen sieht der Schaltplan wie folgt aus.

    from qiskit import QuantumCircuit
    from qiskit.transpiler import InstructionDurations, PassManager
    from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDelay
    from qiskit.visualization.timeline import draw
    
    circuit = QuantumCircuit(3, 1)
    circuit.x(0)
    circuit.measure(0, 0)
    circuit.x(1).c_if(0, 1)
    circuit.measure(2, 0)
    
    durations = InstructionDurations([("x", None, 160), ("measure", None, 800)])
    
    pm = PassManager([ALAPScheduleAnalysis(durations), PadDelay()])
    draw(pm.run(circuit))

    Beachten Sie, dass clbit während des gesamten Intervalls der Messanweisung gesperrt ist. Dieses Verhalten basiert auf dem Qiskit Pulse, bei dem der Acquire-Befehl AcquireChannel und MemorySlot verwendet, die sich nicht mit anderen Befehlen überschneiden dürfen, d. h. ein gleichzeitiger Speicherzugriff durch die verschiedenen Befehle ist verboten. Dadurch wird auch die zeitliche Reihenfolge immer mit der topologischen Knotenreihenfolge in Einklang gebracht.

  • Ein neuer Transpiler-Pass wurde hinzugefügt PadDynamicalDecoupling der den DynamicalDecoupling durchgang als Teil des überarbeiteten Transpiler-Workflows für die Zeitplanung ersetzt. In diesem neuen Durchgang werden dynamische Entkopplungssequenzen in die Schaltung eingefügt, und zwar nach allen Planungs- und Ausrichtungsanalysen, die in früheren Durchgängen durchgeführt wurden.

  • Die plot_gate_map() visualisierungsfunktion und die darauf aufbauenden Funktionen, plot_error_map() und plot_circuit_layout()haben ein neues Schlüsselwortargument, qubit_coordinates. Dieses Argument nimmt eine Folge von 2D Koordinaten auf, die für die Darstellung jedes Qubits im zu visualisierenden Backend verwendet werden. Falls angegeben, muss diese Sequenz eine Länge haben, die der Anzahl der Qubits auf dem Backend entspricht, und sie wird anstelle des Standardverhaltens verwendet.

  • Die plot_gate_map() visualisierungsfunktion und die darauf aufbauenden Funktionen, plot_error_map() und plot_circuit_layout()sind nun in der Lage, jedes beliebige Backend darzustellen, nicht nur solche, deren Anzahl von Qubits gleich einem der IBM Backends ist. Dies beruht auf der Funktion retworkx spring_layout() , um das Layout für die Visualisierung zu erzeugen. Wenn das Standardlayout nicht mit einem bestimmten Kopplungsgraphen eines Backends funktioniert, können Sie die Funktion qubit_coordinates verwenden, um ein benutzerdefiniertes Layout festzulegen.

  • Die plot_gate_map() visualisierungsfunktion und die darauf aufbauenden Funktionen, plot_error_map() und plot_circuit_layout()sind nun in der Lage, mit einem BackendV2 basierten Backend. Bisher funktionierten diese Funktionen nur mit BaseBackend oder BackendV1 basierten Backends.

  • Ein neuer Transpiler-Pass wurde hinzugefügt, SetIOLatency. Dieser Durchlauf benötigt zwei Argumente clbit_write_latency und conditional_latency , um die E/A-Latenz für klassische Bits und klassische Bedingungen auf einem Backend zu definieren. Dieser Durchlauf definiert dann diese Werte im Eigenschaftssatz des Durchlaufmanagers, damit nachfolgende Durchläufe zur Planung und Ausrichtung diese Latenzen korrigieren und eine präzisere Planungsausgabe einer dynamischen Schaltung liefern können.

  • Ein neuer Transpiler-Pass PadDelay wurde hinzugefügt. Dieser Durchlauf füllt die ungenutzte Zeit auf den Qubit-Drähten mit Delay anweisungen. Dieser Durchlauf ist Teil des neuen Arbeitsablaufs für Planungsdurchläufe im Transpiler und hängt von einem Planungsanalyse-Durchlauf (wie ALAPScheduleAnalysis oder ASAPScheduleAnalysis) und etwaigen Ausrichtungsdurchläufen (wie z. B ConstrainedReschedule), die vor dem Durchlauf von PadDelay.

  • Der VF2Layout transpilerpass hat ein neues Schlüsselwortargument, target , das verwendet wird, um ein Target objekt für die Übergabe. Wenn angegeben, wird die Target vom Pass für alle Informationen über das Zielgerät verwendet. Wenn sie angegeben ist, hat die Option target Vorrang vor den Argumenten coupling_map und properties .

  • Erlaube Callables als Optimierer in VQE und QAOA. Nun kann der Optimierer entweder einer von Qiskits Optimierern sein, wie z.B SPSA oder ein Callable mit der folgenden Signatur sein:

    from qiskit.algorithms.optimizers import OptimizerResult
    
    def my_optimizer(fun, x0, jac=None, bounds=None) -> OptimizerResult:
        # Args:
        #     fun (callable): the function to minimize
        #     x0 (np.ndarray): the initial point for the optimization
        #     jac (callable, optional): the gradient of the objective function
        #     bounds (list, optional): a list of tuples specifying the parameter bounds
    
        result = OptimizerResult()
        result.x = # optimal parameters
        result.fun = # optimal function value
        return result

    Die obige Signatur erlaubt auch die direkte Übergabe eines beliebigen SciPy Minimizers, zum Beispiel als

    from functools import partial
    from scipy.optimize import minimize
    
    optimizer = partial(minimize, method="L-BFGS-B")

Bekannte Probleme

  • Bei der Ausführung von parallel_map() (was intern durch leistungsempfindliche Funktionen wie transpile() und assemble()) in einem Unterprozess, der außerhalb von parallel_map()gestartet wird, ist es möglich, dass die parallele Abfertigung, die innerhalb von parallel_map() ausgeführt wird, hängen bleibt und nie zurückkehrt. Dies ist auf Upstream-Probleme in CPython zurückzuführen, die die Standardmethode zum Starten von Unterprozessen auf Linux und macOS mit Python 3.7 betreffen (siehe https://bugs.python.org/issue40379 für weitere Details). Wenn Sie auf dieses Problem stoßen, haben Sie zwei Möglichkeiten: Sie können entweder die verschachtelten parallelen Prozesse entfernen, da der Aufruf parallel_map() von einem Hauptprozess aus funktionieren sollte; oder Sie können das Modul multiprocessing der CPython-Standardbibliothek manuell aufrufen, um einen ähnlichen parallelen Versand von einem Unterprozess aus durchzuführen, aber die Startmethoden "spawn" oder "forkserver" verwenden, um zu vermeiden, dass die Dinge stecken bleiben und nie zurückkehren.

Anmerkungen zu Upgrades

  • Die Klassen Qubit, Clbit und AncillaQubit haben jetzt das Attribut __slots__ . Dadurch wird ihr Speicherbedarf reduziert. Als Nebeneffekt können ihnen nicht mehr beliebige Daten als Attribute beigefügt werden. Es ist sehr unwahrscheinlich, dass dies irgendwelche Auswirkungen auf den nachgelagerten Code hat, abgesehen von Leistungsvorteilen.

  • Die Versionsanforderung für die Kernabhängigkeit retworkx wurde von 0.10.1 auf 0.11.0 angehoben. Dadurch wird die Leistung des Transpilationspasses verbessert ConsolidateBlocks.

  • Die minimal unterstützte Version von symengine ist jetzt 0.9.0. Dies war notwendig, um die Kompatibilität mit dem Modul Python 's pickle zu verbessern, das intern als Teil der parallelen Abfertigung mit parallel_map().

  • Der Standardwert von QISKIT_PARALLEL bei der Ausführung mit Python 3.9 auf Linux ist jetzt auf TRUE gesetzt. Das bedeutet, dass bei der Ausführung von parallel_map() oder Funktionen, die es intern aufrufen, wie transpile() und assemble()aufruft, wird die Funktion in mehreren Prozessen ausgeführt und sollte eine bessere Laufzeitleistung haben. Diese Änderung wurde vorgenommen, weil die Probleme mit der Zuverlässigkeit des parallelen Versands behoben zu sein scheinen (siehe #6188 für weitere Details). Wenn Sie immer noch Probleme damit haben, können Sie das Multiprocessing deaktivieren und zum vorherigen Standardverhalten zurückkehren, indem Sie die Umgebungsvariable QISKIT_PARALLEL auf FALSE setzen oder die Option parallel in Ihrer Benutzerkonfigurationsdatei auf False setzen (bitte reichen Sie auch eine Meldung ein, damit wir alle Probleme im Zusammenhang mit Multiprocessing verfolgen können).

  • Die zuvor veraltete Klasse MSGate gate, die sich in qiskit.circuit.library zu finden war, wurde entfernt. Ursprünglich war sie in der Version 0.16.0 veraltet. Stattdessen sollte die GMS klasse verwendet werden, da diese es ermöglicht, ein äquivalentes 2-Qubit-MS-Gate zusätzlich zu einem MSGate für eine beliebige Anzahl von Qubits zu erstellen.

  • Die zuvor veraltete Methode mirror() der Klasse Instruction klasse wurde entfernt. Ursprünglich war sie in der Version 0.15.0 veraltet. Stattdessen sollten Sie Instruction.reverse_ops().

  • Die zuvor veraltete num_ancilla_qubits() Methode der qiskit.circuit.library.PiecewiseLinearPauliRotations und qiskit.circuit.library.WeightedAdder klassen wurde entfernt. Ursprünglich war sie in der Version 0.16.0 veraltet. Stattdessen sollten die Methoden PiecewiseLinearPauliRotations.num_ancillas() und WeightedAdder.num_ancillas() verwendet werden.

  • Das zuvor veraltete reverse Argument im Konstruktor für die PolynomialPauliRotations klasse wurde entfernt. Ursprünglich war sie in der Version 0.15.0 veraltet. Stattdessen sollten Sie die QuantumCircuit.reverse_bits() methode zur Umkehrung des PolynomialPauliRotations stromkreis umzukehren, falls erforderlich.

  • Das zuvor veraltete angle Argument bei den Konstruktoren für die C3SXGate und C3XGate gate-Klassen wurde entfernt. Ursprünglich war sie in der Version 0.17.0 veraltet. Für gebrochene 3 gesteuerte X-Gatter können Sie stattdessen die Methode C3XGate.power() verwenden.

  • Unterstützung für die Verwendung von np.ndarray Objekten als Teil des params attributs eines Gate objekts wurde entfernt. Dies ist seit Qiskit Terra 0.16.0 veraltet und wird nicht mehr funktionieren. Stattdessen sollte man eine neue Unterklasse von Gate erstellen und explizit eine np.ndarray Eingabe durch Überladen der validate_parameter() methode.

  • Dem Installationsziel für pip install qiskit-terra wurde ein neues Extra csp-layout-pass hinzugefügt, das auch im Extra all enthalten ist. In Qiskit Terra 0.20 hat dies keine Auswirkungen, aber ab Qiskit Terra 0.21 werden die Abhängigkeiten, die nur für den CSPLayout transpiler-Pass benötigt werden, werden von Anforderungen zu Optionen herabgestuft und durch dieses Extra installiert. Sie können ein Paket, das von diesem Pass abhängt, vorbereiten, indem Sie seine Anforderungen (oder den Befehl pip install ) auf das Ziel qiskit-terra[csp-layout-pass] setzen.

  • Die Unterstützung für den Betrieb mit Python 3.6 wurde entfernt. Um Qiskit auszuführen, benötigen Sie mindestens die Version Python von 3.7.

  • Die AmplitudeEstimator erbt nun von der Klasse ABC aus der Standardbibliothek Python. Dies erfordert von jeder Unterklasse die Implementierung der estimate() methode zu implementieren, während dies vorher nicht erforderlich war. Dies wurde getan, weil die ursprüngliche Absicht der Klasse war, immer eine Unterklasse von ABC zu sein, da die estimate() für den Betrieb eines AmplitudeEstimator objekts erforderlich ist. Wenn Sie jedoch zuvor eine AmplitudeEstimator unterklasse definiert haben, die nicht estimate() nicht implementiert hat, führt dies nun zu einem Fehler.

  • Der Fehler, der von HoareOptimizer ausgelöst wird, wenn die optionale Abhängigkeit z3 nicht verfügbar ist, hat sich von TranspilerError zu MissingOptionalLibraryError (was sowohl ein QiskitError und ein ImportError). Dies wurde getan, um mit den anderen optionalen Abhängigkeiten übereinzustimmen.

  • Auf Linux wurde die minimale Bibliotheksunterstützung von manylinux2010 VM auf manylinux2014. Dies spiegelt ähnliche Änderungen in Numpy und Scipy wider. Für die meisten Benutzer sollte es keine nennenswerten Auswirkungen geben, es sei denn, Ihr System enthält noch eine sehr alte Version von glibc.

  • Die Funktion marginal_counts() funktion, wenn sie mit einem Result objekt aufgerufen wird, wird nun das memory Feld der Experimentdaten marginalisiert, wenn es in der Eingabe gesetzt ist Result. Zuvor wurde das Feld memory in der Eingabe nicht ausgegrenzt. Diese Änderung wurde vorgenommen, weil das vorherige Verhalten dazu führte, dass das Feld counts nicht mit dem Feld memory übereinstimmte, nachdem marginal_counts() aufgerufen wurde. Wenn das vorherige Verhalten gewünscht wird, kann es wiederhergestellt werden, indem man marginalize_memory=None als Argument für marginal_counts() gesetzt wird, wodurch das Feld memory nicht marginalisiert wird.

  • Der StochasticSwap transpiler-Durchgang kann bei gleichem Seed-Wert unterschiedliche Ergebnisse liefern. Dies ist auf die interne Neuschreibung des Transpiler-Passes zur Verbesserung der Laufzeitleistung zurückzuführen. Das bedeutet jedoch, dass Sie, wenn Sie transpile() mit optimization_level 0, 1 (Standard) oder 2 mit einem Wert für seed_transpiler ausgeführt haben, können Sie nach dem Upgrade auf Qiskit Terra 0.20.0 eine Ausgabe mit einer anderen Swap-Zuordnung erhalten.

  • Um Qiskit Terra aus dem Quellcode zu erstellen, wird nun ein Rust-Compiler benötigt. Dies ist auf die interne Neuschreibung des StochasticSwap transpiler-Passes, der die Laufzeitleistung des Transpilers erheblich verbessert. Der Rust-Compiler kann einfach mit rustup installiert werden, das hier zu finden ist: https://rustup.rs/

  • Das name attribut der PauliEvolutionGate klasse wurde so geändert, dass es immer "PauliEvolution" lautet. Diese Änderung wurde vorgenommen, um mit anderen Gates in Qiskit konsistent zu sein und ermöglicht es anderen Teilen von Qiskit, schnell zu erkennen, wann eine bestimmte Operation in einer Schaltung ein PauliEvolutionGate. Sie ermöglicht zum Beispiel das Abrollen zu Pauli-Evolutionstoren.

    Zuvor enthielt der Name die Operatoren, die entwickelt werden, was jetzt über das PauliEvolutionGate.label attribut. Wenn eine Schaltung mit einem PauliEvolutionGate gezeichnet wird, zeigt das Gatter immer noch die gleiche Information an, welche Gatter entwickelt werden.

  • Die zuvor veralteten Methoden:

    • qiskit.algorithms.VQE.get_optimal_cost
    • qiskit.algorithms.VQE.get_optimal_circuit
    • qiskit.algorithms.VQE.get_optimal_vector
    • qiskit.algorithms.VQE.optimal_params
    • qiskit.algorithms.HamiltonianPhaseEstimationResult.most_likely_phase
    • qiskit.algorithms.PhaseEstimationResult.most_likely_phase

    die ursprünglich in der Version Qiskit Terra 0.18.0 veraltet waren, wurden entfernt und werden nicht mehr funktionieren.

  • Die Klasse qiskit.algorithms.VariationalAlgorithm ist jetzt als abstrakte Basisklasse (ABC) definiert, so dass Klassen, die von ihr erben, sowohl eine Getter- als auch eine Setter-Methode VariationalAlgorithm.initial_point definieren müssen.

  • Der pass_manager kwarg für die transpile() funktion wurde entfernt. Ursprünglich war sie in der Version 0.13.0 veraltet. Der bevorzugte Weg, einen Schaltkreis mit einem benutzerdefinierten Objekt zu transpilieren PassManager objekt zu transponieren, ist die Verwendung der run() methode des PassManager objekts.

  • Die früher veraltete Klasse ParametrizedSchedule wurde entfernt und existiert nicht mehr. Diese Klasse wurde im Rahmen der Veröffentlichung von 0.17.0 veraltet. Anstatt diese Klasse zu verwenden, können Sie direkt die Parameter Schedule oder ScheduleBlock objekte parametrisieren, indem Sie ein Parameter objekts an das parametrische Impulsargument.

  • Das Modul qiskit.circuit.library.probability_distributions wurde entfernt und existiert nicht mehr, wie in der Deprecation Notice von qiskit-terra 0.17.0 (veröffentlicht am 1. April 2021) beschrieben. Die betroffenen Klassen sind UniformDistribution, NormalDistribution und LogNormalDistribution. Sie werden alle in die qiskit-Finanzbibliothek in das Modul der Schaltkreisbibliothek verschoben: qiskit_finance.circuit.library.probability_distributions.

  • Die bisherige Klasse qiskit.test.mock.fake_mumbai_v2.FakeMumbaiV2 wurde in FakeMumbaiFractionalCX umbenannt, um sie von dem BackendV2 basierten Fake-Backend für das Gerät IBM Mumbai, qiskit.test.mock.backends.FakeMumbaiV2 zu unterscheiden. Wenn Sie sich bisher auf die Klasse FakeMumbaiV2 verlassen haben, um ein gefälschtes Backend zu erhalten, das in seinem Ziel eine gebrochene Anwendung von CXGate definiert sind, müssen Sie die Klasse FakeMumbaiFractionalCX verwenden, da die Klasse FakeMumbaiV2 diese zusätzlichen Gatterdefinitionen nicht mehr in ihrem Target.

  • Der Resolver, der von QuantumCircuit.append() (und folglich alle Methoden, die eine Anweisung an eine QuantumCircuit) zur Konvertierung von Bitspezifizierern wurde geändert, um ihn schneller und zuverlässiger zu machen. Bestimmte Konstrukte wie:

    import numpy as np
    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(1, 1)
    qc.measure(np.array([0]), np.array([0]))

    funktionieren jetzt, wo sie vorher fälschlicherweise einen Fehler auslösten, aber bestimmte pathologische Eingaben wie z.B.:

    from sympy import E, I, pi
    qc.x(E ** (I * pi))

    wird nun Fehler auslösen, wo sie vorher gelegentlich (fälschlicherweise) erfolgreich waren. Bei fast allen korrekten Verwendungen sollte es außer einer allgemeinen Beschleunigung keine spürbaren Änderungen geben.

  • Die halböffentliche interne Methode QuantumCircuit._append() prüft nicht mehr die Typen ihrer Eingaben und geht davon aus, dass es keine ungültigen Duplikate in ihren Argumentlisten gibt. Diese Funktion wird von bestimmten internen Teilen von Qiskit und anderen Bibliotheken verwendet, um QuantumCircuit instanzen so schnell wie möglich aufzubauen, indem die Fehlerprüfung übersprungen wird, wenn die Daten bereits als korrekt bekannt sind. Im Allgemeinen sollten Benutzer oder Funktionen, die Benutzerdaten entgegennehmen, die öffentliche QuantumCircuit.append() methode verwenden, die ganzzahlige Bitspezifikationen auflöst, ihre Argumente überträgt und die Eingaben auf Korrektheit überprüft.

  • Cython ist nicht länger eine Build-Abhängigkeit von Qiskit Terra und muss nicht mehr installiert werden, wenn Qiskit Terra aus dem Quellcode erstellt wird.

  • Die voreingestellten Passmanager in qiskit.transpiler.preset_passmanagers für alle Optimierungsstufen 2 und 3, wie sie von level_2_pass_manager() und level_3_pass_manager() generiert werden, wurden so geändert, dass der VF2Layout standardmäßig vor dem Layoutdurchlauf auszuführen. Der VF2Layout durchgang wird schnell geprüft, ob ein perfektes Layout gefunden werden kann, und ersetzt die bisherige Vorgehensweise für die Optimierungsstufen 2 und 3, bei der eine Kombination aus TrivialLayout und CSPLayout um ein perfektes Layout zu finden. Dies führt zu einem potentiell anderen Verhalten, wenn transpile() standardmäßig aufgerufen wird, da es einen Standardpfad für alle Optimierungsstufen >=2 entfernt, der ein triviales Layout verwendet (bei dem circuit.qubits[0] auf das physische Qubit 0, circuit.qubits[1] auf das physische Qubit 1 usw. abgebildet wird), unter der Annahme, dass das triviale Layout perfekt ist. Wenn Ihr Anwendungsfall vom trivialen Layout abhängt, können Sie es beim Transpilieren explizit anfordern, indem Sie beim Aufruf von layout_method="trivial" angeben transpile().

  • Der voreingestellte Passmanager für Optimierungsstufe 1 (beim Aufruf transpile() mit optimization_level=1 oder wenn kein optimization_level Argument gesetzt ist), wie er von level_1_pass_manager() generiert wurde, wurde so geändert, dass VF2Layout standardmäßig aufgerufen wird, um schnell zu prüfen, ob ein perfektes Layout gefunden werden kann, bevor die DenseLayout. Anders als bei den Optimierungsstufen 2 und 3 wird jedoch vor der Ausführung von VF2Layout ein triviales Layout versucht, und wenn es ein perfektes Mapping ist, wird die Ausgabe von VF2Layout verwendet wird.

Hinweise zu veralteten Versionen

  • Das Argument max_credits für execute()und alle Konfigurationen von Qobj (z. B. QasmQobjConfig und PulseQobjConfig), ist veraltet und wird in einer zukünftigen Version entfernt werden. Das Kreditsystem wird auf IBM Quantum schon seit zwei Jahren nicht mehr verwendet, und die Option hat keine Auswirkungen. Eine Alternative ist nicht erforderlich. Wenn Sie zum Beispiel Folgendes aufrufen execute() als:

    job = execute(qc, backend, shots=4321, max_credits=10)

    können Sie das Argument max_credits einfach weglassen:

    job = execute(qc, backend, shots=4321)
  • Die Verwendung einer ungeraden Ganzzahl für das order Argument im Konstruktor der SuzukiTrotter klasse ist veraltet und wird in einer zukünftigen Version nicht mehr funktionieren. Die Produktformeln, die von der SuzukiTrotter verwendeten Produktformeln sind nur definiert, wenn die Reihenfolge gerade ist, da die Suzuki-Produktformeln symmetrisch sind.

  • Die kwargs qregs, cregs, layout und global_phase für die Klassen MatplotlibDrawer, TextDrawing und QCircuitImage sowie der kwarg calibrations für die Klasse MatplotlibDrawer sind veraltet und werden in einer späteren Version entfernt.

Fehlerkorrekturen

  • Ein Fehler in den Schaltkreisumwandlungsfunktionen wurde behoben circuit_to_gate() und circuit_to_instruction() (und den zugehörigen Schaltungsmethoden QuantumCircuit.to_gate() und QuantumCircuit.to_instruction()), wenn sie auf eine Schaltung mit registerlosen Bits oder Bits in mehr als einem Register wirken.

  • Ein Problem wurde behoben, bei dem der Aufruf von QuantumCircuit.copy() in den "body"-Schaltungen einer Kontrollflussoperation, die mit der Builder-Schnittstelle erstellt wurde, einen Fehler auslöste. Zum Beispiel war dies früher ein Fehler, aber jetzt wird es erfolgreich zurückgegeben:

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    
    qreg = QuantumRegister(4)
    creg = ClassicalRegister(1)
    circ = QuantumCircuit(qreg, creg)
    
    with circ.if_test((creg, 0)):
        circ.h(0)
    
    if_else_instruction, _, _ = circ.data[0]
    true_body = if_else_instruction.params[0]
    true_body.copy()
  • Ein fehlender Eintrag aus der Standard-Session-Äquivalenzbibliothek wurde zwischen CXGate und CPhaseGate sowie zwischen CXGate und CRZGate.

  • Ein Problem wurde behoben, bei dem die Ausführung des == Operators zwischen zwei SparsePauliOp objekten einen Fehler auslöste, wenn die beiden Operatoren eine unterschiedliche Anzahl von Koeffizienten hatten. Zum Beispiel:

    op = SparsePauliOp.from_list([("X", 1), ("Y", 1)])
    op2 = SparsePauliOp.from_list([("X", 1), ("Y", 1), ("Z", 0)])
    print(op == op2)

    Dies würde bisher ValueError auslösen, anstatt False zurückzugeben.

  • Fixierte Unterstützung in transpile() für die Übergabe eines InstructionScheduleMap objekts an das zugrunde liegende PassManager basierend auf der Target für BackendV2 basierten Backends. Zuvor hat die transpile() funktion diese Verarbeitung nicht und alle Transpilerdurchläufe, die die Arbeit mit einem Target objekt noch nicht unterstützen, hätten keinen Zugriff auf die Standard-Impulskalibrierungen für die Anweisungen aus einem BackendV2 backend.

  • Die Seite AmplitudeAmplifier ist jetzt korrekt aus dem Root qiskit.algorithms modul direkt verfügbar. Zuvor war sie nicht in den re-exportierten Klassen des Root-Moduls enthalten und war nur über qiskit.algorithms.amplitude_amplifiers zugänglich. Behoben #7751.

  • Ein Problem mit dem mpl Backend für die Schaltkreisschubladenfunktion wurde behoben circuit_drawer() und der QuantumCircuit.draw() methode, wo Gatter mit Bedingungen nicht richtig angezeigt wurden, wenn eine ausreichende Anzahl von Gattern dazu führte, dass die Schublade auf eine zweite Reihe umklappte. Behoben: #7752.

  • Ein Problem wurde behoben, bei dem die Methode HHL.construct_circuit() unter bestimmten Bedingungen kein korrektes Ergebnis lieferte QuantumCircuit. Zuvor hatte die Funktion einen Rundungsfehler bei der Berechnung der Anzahl der Qubits, die zur Darstellung der Eigenwerte erforderlich waren, was zu einer falschen Schaltungsausgabe führte.

  • Ein Endianness-Fehler wurde in BaseReadoutMitigator.expectation_value() wenn eine Zeichenkette diagonal übergeben wurde. Sie wird nun korrekt als Little Endian interpretiert, so wie der Rest von Qiskit Terra, anstatt als Big Endian.

  • Es wurde ein Problem mit der Funktion quantum_info.partial_trace() wenn die Funktion aufgefordert wurde, keine Subsysteme zu ermitteln, gibt sie nun korrekt den DensityMatrix des Eingabezustandes mit allen verbleibenden Dimensionen zurück, anstatt einen Fehler zu verursachen. Behoben #7613

  • Ein Problem mit dem text Backend für die Schaltkreisschubladenfunktion wurde behoben circuit_drawer() und der QuantumCircuit.draw() methode, wenn Gatter, die Seitentext verwenden, wie z.B. die CPhaseGate und RZZGate gatterklassen, mit klassischen Bedingungen nicht richtig angezeigt wurden. Behoben #7532.

  • Es wurde ein Problem mit der circuit_drawer() funktion und draw() methode von QuantumCircuit. Bei Verwendung der Option reverse_bits mit den Optionen mpl, latex oder text wurden Bits ohne Register nicht in der richtigen Reihenfolge angezeigt. Behoben #7303.

  • Es wurde ein Problem in der LocalReadoutMitigator.assignment_matrix() methode behoben, bei der zuvor ein Eingabewert für das Argument qubits zurückgewiesen wurde, der keine triviale Folge von Qubits in der Form: [0, 1, 2, ..., n-1] war. Dies wurde korrigiert, so dass nun eine beliebige Liste von zu messenden Qubit-Indizes von der Methode akzeptiert wird.

  • Es wurde ein Problem in der StabilizerState.expectation_value() erwartungswertberechnung der Methode behoben, bei der der Ausgabeerwartungswert falsch war, wenn der Eingabeoperator für das Argument Pauli operator für das oper Argument eine nicht-triviale Phase hatte. Behoben #7441.

  • Ein Opflow-Ausdruck, der die Pauli-Identität opflow.I enthält, erzeugt nicht mehr ein IGate wenn er in eine Schaltung umgewandelt wird. Diese Änderung behebt einen Unterschied in der Erwartung; das Identitätsgatter in der Schaltung zeigt eine Verzögerung an, während wir in Opflow eine mathematische Identität erwarten - was bedeutet, dass überhaupt keine Operation stattfindet.

  • Die Website PauliGate fügt nicht mehr ein IGate für Paulis mit der Bezeichnung "I" ein.

  • PauliSumOp gleichheitstests behandeln jetzt den Fall, dass eines der verglichenen Elemente ein einzelnes ist PauliOp. Beispielsweise ergibt 0 * X + I == I jetzt den Wert True, während er vor dieser Version False war.

  • Es wurde ein Problem mit den ALAPSchedule und ASAPSchedule transpilerdurchläufen, wenn mit Anweisungen gearbeitet wurde, für die benutzerdefinierte Impulskalibrierungen (d.h. Impulsgatter) festgelegt waren. Bisher wurde bei den Planungsdurchläufen nicht die Dauer aus der benutzerdefinierten Impulskalibrierung für diese Anweisungen verwendet, was dazu führte, dass eine falsche Planung für die Schaltung erstellt wurde. Dieses Problem wurde behoben, so dass die Planungsdurchläufe jetzt die Dauer der benutzerdefinierten Impulskalibrierung für jeden Befehl im Schaltkreis verwenden, der eine benutzerdefinierte Kalibrierung hat.

  • Unterstützung für die Verwendung von ParameterExpression anweisungsparamater im RZXCalibrationBuilder transpiler-Durchgang. Wenn ein Befehlsparameter eine Bindung ParameterExpression enthielt, konnte der Pass dies nicht korrekt verarbeiten.

  • Stoppte den Parser in QuantumCircuit.from_qasm_str() und from_qasm_file()OpenQASM Programme zu akzeptieren, die sich als aus einer anderen Sprachversion als 2.0 stammend identifizieren. Dieser Parser ist nur für OpenQASM 2.0; Unterstützung für importierte Schaltungen von OpenQASM 3.0 wird in einer kommenden Version hinzugefügt werden.

  • Der OpenQASM 3 Exporter, qasm3.Exporterentgeht nun Register- und Parameternamen, die mit reservierten OpenQASM 3 Schlüsselwörtern kollidieren, indem er einen neuen eindeutigen Namen erzeugt. Bei Registern und Parametern mit demselben Namen kommt es in der Codeausgabe des OpenQASM 3-Exporters nicht mehr zu Namenskonflikten. Behoben #7742.

Aer- 0.10.3

Keine Änderung

Ignis- 0.7.0

Keine Änderung

IBM Q Anbieter 0.18.3

Keine Änderung

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