Skip to main content
IBM Quantum Platform

Note di rilascio di Qiskit SDK 1.1


1.1.2

Preludio

Qiskit 1.1.2 è una versione con correzione di bug minori per la serie 1.1.

Correzioni di bug

  • Corretto un bug in BitArray.from_counts() e BitArray.from_samples(). In precedenza, questi sollevavano un errore se venivano forniti dati contenenti solo zeri e nessun valore per l'argomento opzionale num_bits. Ora producono un BitArray con BitArray.num_bits impostato su 1.

  • Corretto un decoratore mancante in C3SXGate che lo faceva fallire se Gate.to_matrix() veniva chiamato. La matrice del gate viene ora restituita come previsto.

  • Aggiunte le porte di Clifford mancanti al CollectCliffords al passaggio del transpiler. In particolare, abbiamo aggiunto le porte ECRGate, DCXGate, iSWAPGate, SXGate e SXdgGate a questo passaggio del transpiler.

  • L'attributo QuantumCircuit.parameters sarà ora correttamente vuoto quando si usa QuantumCircuit.copy_empty_like() su un circuito parametrico. In precedenza, una cache interna veniva copiata senza essere invalidata. Correzione #12617.

  • Correggere il SolovayKitaev quando si caricano le approssimazioni di base da un file .npy esistente. In precedenza, il caricamento di un'approssimazione memorizzata che consentiva ulteriori riduzioni (ad esempio a causa di cancellazioni di porte) poteva causare un errore di runtime. Inoltre, la differenza di fase globale del prodotto di porta U(2) e della rappresentazione SO(3) è stata persa durante una procedura di salvataggio/ricaricamento. Correzioni Qiskit/qiskit#12576.

  • Corretto un problema con dag_drawer() e DAGCircuit.draw() quando si cerca di visualizzare un'istanza DAGCircuit che conteneva Var fili. Il visualizzatore sollevava un'eccezione, che è stata risolta in modo da generare la visualizzazione prevista.

  • Il costruttore GenericBackendV2 permetteva in precedenza di costruire backend malformati, perché accettava porte di base che non potevano essere allocate data la dimensione del backend. Ad esempio, un backend con un singolo qubit potrebbe in precedenza accettare una base con gate a due qubit.

  • Il parser OpenQASM 2 (qiskit.qasm2) può ora gestire i condizionali con numeri interi che non rientrano in un numero intero a 64 bit. Corretto #12773.

  • In precedenza, DAGCircuit.replace_block_with_op() permetteva di inserire un'operazione n-qubit in un blocco di m qubit, lasciando il DAG in uno stato non valido. Questo comportamento è stato corretto e qualsiasi tentativo in tal senso solleva ora un problema di tipo DAGCircuitError come previsto.


1.1.1

Preludio

Qiskit 1.1.1 è una versione con correzione di bug minori per la serie 1.1.

Correzioni di bug

  • Correzione di un bug in Isometry a causa di un'asserzione non necessaria, che portava a un errore in UnitaryGate.control() quando UnitaryGate aveva più di due qubit.

  • QuantumCircuit.depth() ora gestirà correttamente le operazioni che non hanno operandi, come ad esempio GlobalPhaseGate.

  • QuantumCircuit.depth() conterà ora le variabili e i clbit usati nelle espressioni in tempo reale come parte del calcolo della profondità.

  • Corretto un bug in qiskit.visualization.pulse_v2.interface.draw() che non disegnava gli orari degli impulsi quando la funzione draw veniva chiamata con un argomento BackendV2 con un argomento. Poiché il backend V2 non riporta le frequenze dei canali hardware, il disegno generato mostrerà "nessuna frequenza" sotto l'etichetta di ciascun canale.

  • Il VF2Layout solleva un'eccezione quando viene fornita un'istanza Target senza vincoli di connettività. Questo sarebbe il caso degli obiettivi di Aer 0.13. Il problema è stato ora corretto.

  • ParameterExpression è stato aggiornato in modo che le istanze completamente vincolate che si confrontano con istanze dei tipi numerici incorporati di Python (come float e int) abbiano anche valori hash che corrispondono a quelli delle altre istanze. Questa modifica garantisce che questi tipi possano essere utilizzati in modo intercambiabile come chiavi di dizionario. Vedere il numero 12488.

  • Le porte personalizzate (quelle che derivano da un'istruzione gate ) nei programmi importati da OpenQASM 2 avranno ora un'implementazione Gate.to_matrix() implementazione. In precedenza non avrebbero avuto alcuna definizione di matrice, il che significa che i roundtrip attraverso OpenQASM 2 avrebbero potuto perdere inutilmente la capacità di derivare la matrice del gate. Si noti, tuttavia, che la matrice viene calcolata trovando ricorsivamente le matrici delle definizioni dei gate interni, come fa il metodo Operator che potrebbe essere meno performante rispetto a prima del round-trip.

  • Target.has_calibration() è stato aggiornato in modo da non sollevare un'eccezione per un'istruzione che è stata aggiunta alla destinazione con None per le proprietà dell'istruzione. Correzioni #12525.


1.1.0

Preludio

La release di Qiskit 1.1.0 è una release minore che include una miriade di nuove funzionalità e correzioni di bug. I punti salienti di questa release sono:

  • Il supporto per le variabili classiche tipizzate è stato aggiunto a Qiskit QuantumCircuit. Queste variabili classiche possono essere specificate come ingressi o come variabili di scopo in un sistema di controllo QuantumCircuit dove, ad esempio, memorizzano l'output delle misure dei qubit o le operazioni del flusso di controllo. In futuro verrà aggiunto il supporto per l'impostazione dei parametri del gate o delle variabili di uscita.

  • I metodi di sintesi dei due qubit predefiniti, utilizzati internamente dal transpiler nel passaggio UnitarySynthesis sono stati reimplementati in Rust. In questo modo si ottiene una significativa accelerazione dei tempi di esecuzione nella scomposizione di matrici unitarie a due qubit. Di conseguenza, il tempo di esecuzione della transpilazione con il livello di ottimizzazione 3 è stato notevolmente migliorato laddove l'esecuzione UnitarySynthesis comportava storicamente un grande overhead di runtime. Questa release inizia a funzionare anche UnitarySynthesis come parte della fase di ottimizzazione nel livello di ottimizzazione 2, grazie a questi miglioramenti delle prestazioni in fase di esecuzione.

    Inoltre, i metodi numerici utilizzati in Isometry sono stati trasferiti in Rust, consentendo un'ampia accelerazione dei tempi di esecuzione, in particolare per la sintesi controllata di porte unitarie. La decomposizione per i sistemi multicontrollati XGate e PhaseGate è stata migliorata, con una riduzione del numero di porte utilizzate nella sintesi di oltre due ordini di grandezza.

  • In Qiskit è stata introdotta una serie di nuovi passaggi di transpiler che consentono di ottenere una significativa accelerazione dei tempi di esecuzione, riducendo in molti casi le dimensioni dei circuiti quantistici transpilati. In particolare, ElidePermutations e StarPreRouting hanno dimostrato di avere un impatto significativo sulla qualità dell'output del routing e sul tempo di esecuzione e RemoveFinalReset possono migliorare i circuiti quantistici che includono i reset.

  • I gestori di pass predefiniti sono stati migliorati estendendoli con i nuovi pass del transpiler. In particolare, il gestore di pass preimpostati di livello di ottimizzazione 2 di generate_preset_pass_manager e utilizzato internamente da transpile() è stato riadattato per avere un miglior compromesso tra tempo di esecuzione e sforzo di ottimizzazione, in modo da poter essere utilizzato come gestore di passaggi predefinito nelle prossime versioni. Sebbene questa versione non modifichi l'impostazione predefinita per l'uso del livello 2, in genere è una scelta migliore rispetto all'uso del livello 1 o 3.

  • Sono state aggiunte nuove implementazioni della primitiva generica V2, BackendEstimatorV2 e BackendSamplerV2per completare le implementazioni esistenti basate su vettori di stato completi.

  • Modifiche al supporto della piattaforma: Python 3.8 è deprecato a partire da Qiskit 1.1.0 e non sarà più supportato in 1.3.0, mentre arm64 macOS è stato promosso a supporto di primo livello.

Caratteristiche dei circuiti

  • I metodi QuantumCircuit.power(), Gate.power(), così come i metodi simili sulle sottoclassi di sottoclassi di Gate (come quello di SGate) hanno tutti un argomento aggiuntivo annotated che viene utilizzato per restituire un oggetto AnnotatedOperation quando si applica una potenza a un gate o a un circuito. Il valore predefinito di False corrisponde al comportamento esistente. Inoltre, per le porte standard con un metodo power esplicitamente definito, l'argomento annotated non ha alcun effetto. Ad esempio, sia SGate().power(1.5, annotated=False) che SGate().power(1.5, annotated=True) restituiscono un PhaseGate. Una differenza nel valore di annotated si manifesta per le porte senza un metodo di potenza esplicitamente definito. Il valore di False restituisce un UnitaryGatecome prima, mentre il valore di True restituisce un'istruzione AnnotatedOperation che rappresenta l'istruzione modificata con il "modificatore di potenza".

  • Aggiunto un nuovo argomento ctrl_state a QuantumCircuit.mcp() e MCPhaseGate.

    Il QuantumCircuit.mcp() e la classe MCPhaseGate sono stati aggiornati per includere un parametro ctrl_state . Questo miglioramento consente agli utenti di specificare lo stato di controllo del gate di fase multicontrollato. Il parametro può accettare un valore intero o una stringa di bit e, per impostazione predefinita, controlla lo stato '1' se non viene fornito.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(4)
    qc.mcp(0.2,[0,1,2],3,ctrl_state=2)
  • Aggiunto un nuovo argomento ctrl_state a QuantumCircuit.mcx().

    Il metodo QuantumCircuit.mcx() nella libreria dei circuiti quantistici è stato migliorato per includere un parametro ctrl_state, che consente agli utenti di specificare lo stato di controllo della porta X multicontrollata. Questo parametro può accettare un valore decimale o una stringa di bit e, per impostazione predefinita, controlla lo stato '1' se non viene fornito.

    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.mcx([0, 1], 2, ctrl_state="00")
  • A QuantumCircuit può ora contenere variabili classiche tipizzate:

    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)

    Queste variabili possono essere specificate come ingressi al circuito o come variabili di scopo. L'oggetto circuito non supporta ancora la rappresentazione delle uscite a variabili classiche tipizzate, ma questo verrà aggiunto in seguito, quando l'hardware e le interfacce dei risultati saranno in grado di supportarlo. I circuiti che rappresentano un blocco di un ambito interno possono anche catturare variabili da ambiti esterni.

    Una variabile è un Var che può contenere un tipo arbitrario e rappresenta una posizione di memoria unica all'interno del suo intervallo di vita quando viene aggiunta a un circuito. Questi possono essere costruiti in un circuito utilizzando QuantumCircuit.add_var() e QuantumCircuit.add_input(), o a un livello inferiore usando Var.new().

    Le variabili possono essere memorizzate manualmente, utilizzando l'istruzione Store e il corrispondente metodo di circuito QuantumCircuit.store(). Questo include la scrittura a Clbit e ClassicalRegister istanze avvolte in nodi Var nodi.

    Le variabili possono essere utilizzate ovunque siano valide le espressioni classiche (vedi qiskit.circuit.classical.expr) sono valide. Attualmente si tratta delle espressioni di destinazione delle operazioni del flusso di controllo, anche se in futuro si prevede di estendere questa funzione ai parametri dei gate, man mano che il sistema di tipi ed espressioni verrà ampliato.

    Per ulteriori informazioni su queste variabili e sul modello di dati associato, vedere Calcolo classico in tempo reale.

    Questi sono supportati in tutto il transpiler, attraverso la serializzazione QPY (qiskit.qpy), l'esportazione di OpenQASM 3 (qiskit.qasm3) e hanno un supporto iniziale attraverso i visualizzatori di circuiti (vedi QuantumCircuit.draw()).

    Nota

    Le nuove variabili classiche e la memorizzazione richiederanno un certo tempo per essere supportate dall'hardware e dai backend dei simulatori. Non sono supportate nelle interfacce delle primitive (qiskit.primitives), ma probabilmente informeranno tali interfacce nella loro evoluzione.

  • Il modulo classico delle espressioni in tempo reale qiskit.circuit.classical può ora rappresentare l'indicizzazione e il bitshifting di numeri interi senza segno e simili (ad es. ClassicalRegister). Ad esempio, è ora possibile confrontare un registro con il bitshift di un altro:

    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 può anche rappresentare una condizione che indicizza dinamicamente un registro:

    with qc.if_test(expr.index(cr1, cr2)):
        pass
  • Le prestazioni di costruzione di NLocal e delle sue sottoclassi di librerie di circuiti derivate (ad es. EfficientSU2 e RealAmplitudes) è notevolmente migliorato, quando i sottoblocchi di rotazione e/o di entanglement sono semplici applicazioni di un singolo gate della libreria standard di Qiskit. Poiché questi circuiti sono costruiti in modo pigro, il miglioramento potrebbe non essere visibile immediatamente all'istanziazione della classe, ma al primo accesso alla sua struttura interna. I miglioramenti delle prestazioni sono dell'ordine di dieci volte più veloci.

  • QuantumCircuit.append() ha ora un argomento per la parola chiave copy , che ha come valore predefinito True. Quando un'istruzione con parametri di runtime (ParameterExpressions) viene aggiunta a un circuito, per impostazione predefinita, il circuito ha sempre creato una copia dell'istruzione, in modo che, se si tenta di mutare l'istruzione in loco, ciò non influisce sugli altri riferimenti alla stessa istruzione QuantumCircuit.assign_parameters() tenta di mutare l'istruzione sul posto, non influisce sugli altri riferimenti alla stessa istruzione. Ora, l'impostazione di copy=False consente di ignorare questo aspetto, in modo da evitare la penalità di copia se si sa che le istruzioni non verranno utilizzate in altri luoghi.

  • QuantumCircuit.compose() ha ora un argomento per la parola chiave copy , che ha come valore predefinito True. Per impostazione predefinita, compose() copia tutte le istruzioni, in modo che le mutazioni di un circuito non influiscano sugli altri. Se copy=False, le istruzioni dell'altro circuito diventeranno direttamente di proprietà del nuovo circuito, il che può comportare la loro mutazione in loco. In questo caso, l'altro circuito non deve essere utilizzato successivamente.

  • Il tempo di costruzione dei QuantumVolume è stato notevolmente migliorato, dell'ordine di 10x o poco più. Anche le porte interne di SU4 utilizzeranno un maggior numero di bit di casualità durante la loro generazione, portando a circuiti di volume più rappresentativi, soprattutto a larghezze e profondità elevate.

  • QuantumVolume ha ora un argomento per la parola chiave flatten . L'impostazione predefinita è False, dove il circuito costruito contiene una singola istruzione che a sua volta contiene la struttura del volume vero e proprio. Se si imposta True, il circuito avrà direttamente le matrici volumetriche SU4.

  • UnitaryGate accetta ora un argomento opzionale num_qubits . L'unico effetto è quello di saltare l'inferenza del conteggio dei qubit, che può essere utile per le prestazioni quando si costruiscono molte porte.

  • QuantumCircuit ha diversi nuovi metodi per lavorare e ispezionare le variabili manuali Var variabili.

    Per una discussione più approfondita su tutti questi aspetti, vedere Lavorare con i dati classici digitati in tempo reale.

    I nuovi metodi sono:

    Inoltre, ci sono diversi nuovi attributi dinamici su QuantumCircuit che circondano queste variabili:

  • ControlFlowOp e le sue sottoclassi hanno ora un metodo iter_captured_vars() che restituisce un iteratore sulle variabili uniche catturate in uno qualsiasi dei suoi blocchi immediati.

  • DAGCircuit ha diversi nuovi metodi per lavorare e ispezionare le variabili manuali Var variabili. Questi sono in gran parte equivalenti alle loro QuantumCircuit tranne che per il fatto che gli oggetti DAGCircuit sono ottimizzati per l'accesso programmatico con oggetti già definiti, mentre i metodi sono più focalizzati sull'uso umano interattivo QuantumCircuit sono più focalizzati sull'uso umano interattivo.

    I nuovi metodi sono:

    Ci sono anche nuovi attributi pubblici:

  • DAGCircuit.wires conterrà anche tutte le variabili Var manuale del circuito, in quanto si tratta di un flusso di dati classico.

  • Viene aggiunto un nuovo metodo, Var.new()per costruire manualmente una variabile classica in tempo reale che possiede la sua memoria.

  • QuantumCircuit.compose() ha due argomenti chiave necessari, var_remap e inline_captures , per supportare meglio le variabili classiche in tempo reale.

    var_remap può essere usato per riscrivere Var nell'argomento del circuito, poiché le sue istruzioni vengono inserite nel circuito di base. Questo può essere usato per evitare conflitti di denominazione.

    inline_captures può essere impostato su True (per impostazione predefinita False) per collegare tutti i nodi Var nodi tracciati come "catture" nel circuito di argomento con gli stessi Var nodi del circuito di base, senza tentare di ridichiarare le variabili. Questo può essere usato, in combinazione con la gestione di QuantumCircuit.copy_empty_like()vars_mode="captures" , per costruire un circuito strato per strato, contenente variabili.

  • DAGCircuit.compose() ha un nuovo argomento chiave, inline_captures, che può essere impostato su True per inserire i nodi "catturati" del circuito dell'argomento nel circuito di base senza ridichiararli Var sul circuito dell'argomento sul circuito di base senza ridichiararli. In combinazione con l'opzione vars_mode="captures" di alcuni metodi DAGCircuit può essere usata per combinare DAG che operano sulle stesse variabili.

  • QuantumCircuit.copy_empty_like() e DAGCircuit.copy_empty_like() hanno un nuovo argomento chiave, vars_mode , che controlla il modo in cui i nodi che possiedono memoria Var vengono tracciati nell'output. Per impostazione predefinita ("alike"), le variabili sono dichiarate nella stessa modalità di input/cattura/locale della sorgente. Può essere impostato su "captures" per convertire tutte le variabili in catture (utile con compose()) o "drop" per rimuoverle.

  • È stato aggiunto un nuovo argomento per la parola chiave vars_mode al metodo DAGCircuit metodi:

    che ha lo stesso significato che ha per copy_empty_like().

  • Tutte le "porte standard" della libreria dei circuiti (qiskit.circuit.library) possono ora essere specificate con un nome di stringa per le operazioni di entangling in TwoLocal circuiti, come RealAmplitudes e EfficientSU2.

Caratteristiche primitive

  • L'implementazione BackendEstimatorV2 di BaseEstimatorV2 è stata aggiunta. Questo stimatore supporta BackendV1 e 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}")
  • L'implementazione BackendSamplerV2 di BaseSamplerV2 è stata aggiunta. Questo campionatore supporta BackendV1 e BackendV2 che consentono l'opzione memory per calcolare le stringhe di bit.

    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}")
  • Aggiunti metodi per unire più BitArray lungo vari assi.

    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']
  • Aggiunti metodi per generare un sottoinsieme di BitArray tagliando lungo vari assi.

    • __getitem__(): tagliare l'array lungo un asse esistente dell'array.
    • slice_bits(): tagliare la matrice lungo l'asse dei bit.
    • slice_shots(): tagliare la matrice lungo l'asse di ripresa.
    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']
  • Aggiunto un metodo transpose() per trasporre un elemento 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>)
  • Aggiunto un metodo expectation_values() per calcolare i valori di aspettativa degli operatori diagonali.

    ba = BitArray.from_samples(['01', '11'])
    print(ba.expectation_values(["IZ", "ZI", "01"]))
    # [-1.   0.   0.5]
  • DataBin soddisfa ora il Shaped protocollo. Ciò significa che ogni DataBin ha ora gli attributi aggiuntivi

    • shape (tupleint[,...]): la forma iniziale di ogni voce dell'istanza
    • ndim (int): la lunghezza di shape
    • size (int): il prodotto delle voci di shape

    La forma può essere passata al costruttore.

  • Aggiunte funzioni di mappatura a DataBin, cioè __getitem__, __contains__, __iter__, keys(), values(), e 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])
  • La sottoclasse SamplerPubResult di PubResult è stata aggiunta, che BaseSamplerV2 può essere restituita dalle implementazioni. La principale funzione aggiunta in questa nuova sottoclasse è join_data()che unisce (un sottoinsieme) i contenuti di data in un unico oggetto. Ciò consente di utilizzare i seguenti schemi:

    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

Funzionalità dei fornitori

Caratteristiche di Pulse

  • È ora possibile assegnare parametri agli impulsi Schedule e ScheduleBlock specificando il nome del parametro come stringa. Il nome del parametro può essere utilizzato per assegnare i valori a tutti i parametri all'interno del campo Schedule o ScheduleBlock che hanno lo stesso nome. Inoltre, il nome del parametro di un vettore ParameterVector può essere usato per assegnare tutti i valori del vettore contemporaneamente (l'elenco dei valori deve quindi corrispondere alla lunghezza del vettore).

  • I metodi assign_parameters di Schedule e ScheduleBlock supportano ora l'assegnazione di un valore ParameterVector a un elenco di valori di parametri simultaneamente, oltre ad assegnare le singole istanze di Parameter a valori individuali.

OpenQASM Caratteristiche

  • L'esportatore OpenQASM 3 supporta l'archiviazione manuale Var sui circuiti.

Caratteristiche QPY

  • IL FORMATO QPY (qiskit.qpy) è stata aggiunta la versione 12 del formato, che include il supporto per le variabili di proprietà della memoria Var di memoria. Per ulteriori dettagli sulle modifiche al formato, consultare la versione 12.

Caratteristiche dell'informazione quantistica

  • Aggiunto un nuovo metodo apply_layout() che è equivalente a apply_layout(). Questo metodo viene utilizzato per applicare un TranspileLayout layout del transpiler a un Pauli osservabile costruito per un circuito di ingresso. Questo permette di lavorare con BaseEstimator / BaseEstimatorV2 e la transpilazione locale quando l'input è di tipo Pauli. Ad esempio:

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

    dove un circuito di ingresso viene trapiantato localmente prima di essere passato a run(). La transpilazione espande il circuito originale da 2 a 7 qubit (la dimensione di backend) e ne permuta il layout, che viene poi applicato a H1 usando apply_layout() per riflettere le trasformazioni effettuate da pm.run().

  • Aggiunge gli elementi PauliList.noncommutation_graph() e SparsePauliOp.noncommutation_graph() metodi, esponendo la costruzione di grafi non commutativi, rifondendo il problema del raggruppamento degli operatori di misura in un problema di colorazione dei grafi. Questo permette agli utenti di lavorare direttamente con questi grafi, ad esempio per esplorare algoritmi di colorazione diversi da quello utilizzato da SparsePauliOp.group_commuting().

  • Le prestazioni di SparsePauliOp.to_matrix() è stata notevolmente migliorata sia per le forme dense che per quelle rade. Per impostazione predefinita, entrambi sfruttano il parallelismo filettato disponibile sul sistema, in base alla variabile d'ambiente RAYON_NUM_THREADS . È possibile forzare temporaneamente l'esecuzione seriale utilizzando il nuovo argomento booleano force_serial a to_matrix().

Caratteristiche della sintesi

  • Il KMSSynthesisLinearFunction per sintetizzare gli oggetti LinearFunction accetta ora due opzioni aggiuntive use_inverted e use_transposed. Queste opzioni modificano la matrice su cui gira l'algoritmo di sintesi sottostante, eventualmente invertendola e/o trasponendola, e quindi regolano opportunamente il circuito sintetizzato. Variando queste opzioni, in genere si ottengono circuiti sintetizzati diversi, e in alcuni casi si possono ottenere risultati migliori rispetto ai valori predefiniti.

  • Il PMHSynthesisLinearFunction per sintetizzare gli oggetti LinearFunction accetta ora diverse opzioni aggiuntive. L'opzione section_size viene passata al metodo di sintesi sottostante. Le opzioni use_inverted e use_transposed modificano la matrice su cui gira l'algoritmo di sintesi sottostante, eventualmente invertendola e/o trasponendola, e quindi regolano opportunamente il circuito sintetizzato. Variando queste opzioni, in genere si ottengono circuiti sintetizzati diversi, e in alcuni casi si possono ottenere risultati migliori rispetto ai valori predefiniti.

  • È stato aggiunto un nuovo argomento, use_dag, agli elementi TwoQubitBasisDecomposer.__call__() e XXDecomposer.__call__() ai metodi. Questo argomento è usato per controllare se viene restituito un oggetto DAGCircuit viene restituito quando si chiama un metodo TwoQubitBasisDecomposer o XXDecomposer invece dell'istanza predefinita QuantumCircuit. Ad esempio:

    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)

    restituirà un valore DAGCircuit quando si chiama l'istanza TwoQubitBasisDecomposerdecomposer .

  • LieTrotter.synthesize() utilizza ora QuantumCircuit.repeat() per generare ulteriori ripetizioni di un passo Trotter dopo il primo passo Trotter. Questo riduce il numero di QuantumCircuit.compose() di un fattore pari a reps e riduce significativamente il tempo di esecuzione per gli operatori più grandi.

  • Aggiungere un nuovo metodo di sintesi synth_permutation_reverse_lnn_kms() di permutazioni inverse per architetture lineari nearest-neighbor utilizzando il metodo di Kutin, Moulton, Smithline. Questo algoritmo sintetizza la permutazione inversa su nn qubit su un'architettura lineare nearest-neighbor utilizzando porte CX con profondità 2n+22 * n + 2.

  • La classe TwoQubitBasisDecomposer è stata riscritta in Rust, migliorando notevolmente le prestazioni in fase di esecuzione.

  • La classe TwoQubitWeylDecomposition è stata riscritta in Rust per migliorare le prestazioni.

Funzionalità del transpiler

  • Estensione dell'analisi delle commutazioni eseguita da CommutationChecker per lavorare anche con circuiti astratti, cioè ogni operazione del circuito quantistico in ingresso viene ora controllata per la sua rappresentazione matriciale prima di procedere alla fase di analisi. In precedenza, l'analisi della commutazione veniva eseguita solo su circuiti fisici. Inoltre, ogni operazione viene ora controllata per verificarne la capacità di essere memorizzata nella cache della libreria di commutazione della sessione. Ad esempio, ora è possibile calcolare se AnnotatedOperation commutare. Ciò consente ai passaggi del transpiler che si basano internamente su CommutationChecker , come ad esempio CommutativeCancellationdi essere eseguiti durante le prime fasi di una pipeline di transpilazione predefinita (prima della traduzione delle basi).

  • Il passaggio del transpiler ElidePermutations viene eseguito di default nella fase di avvio per i livelli di ottimizzazione 2 e 3. Intuitivamente, la rimozione di SwapGates e PermutationGates in un circuito virtuale è quasi sempre vantaggioso, in quanto rende il circuito più corto e più facile da instradare. Poiché OptimizeSwapBeforeMeasure è un caso speciale di ElidePermutationsè stato sostituito dal passaggio ElidePermuations come parte della fase di init nei gestori dei passaggi di ottimizzazione di livello 3.

  • È stato aggiunto un nuovo passaggio del transpiler di ottimizzazione, ElidePermutationsche è stato progettato per essere eseguito prima della fase di layout e che ottimizzerà tutti gli elementi di tipo SwapGates e PermutationGates in un circuito mediante la permutazione dei qubit virtuali. Ad esempio, prendendo un circuito con SwapGates:

    _images/release_notes-1.png

    rimuoverà gli scambi quando il passaggio viene eseguito:

    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

    Il passaggio imposta anche il set di proprietà virtual_permutation_layout , memorizzando la permutazione dei qubit virtuali alla fine del circuito che è stato ottimizzato.

  • L'opzione HLSConfig ha ora due argomenti opzionali aggiuntivi. L'argomento plugin_selection può essere impostato su "sequential" o su "all". Se impostato su "sequenziale" (valore predefinito), per ogni oggetto di livello superiore il passaggio HighLevelSynthesis considererà i metodi specificati in modo sequenziale, nell'ordine in cui appaiono nell'elenco, fermandosi al primo metodo in grado di sintetizzare l'oggetto. Se si imposta "all", verranno considerati tutti i metodi specificati e verrà scelto il miglior circuito sintetizzato, secondo plugin_evaluation_fn . L'argomento plugin_evaluation_fn è un callable opzionale che valuta la qualità del circuito quantistico sintetizzato; un valore minore significa un circuito migliore. Quando è impostato su None, la qualità del circuito è la sua dimensione (cioè il numero di porte che contiene).

    L'esempio seguente illustra la nuova funzionalità:

    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)

    Nell'esempio, eseguiamo più metodi di sintesi con diversi parametri, scegliendo il circuito migliore in termini di profondità. Si noti che ottimizzando circuit.size() si sceglierebbe invece un circuito diverso.

  • Aggiunto il CommutativeCancellation allo stadio init dei gestori di passaggi preimpostati per i livelli di ottimizzazione 2 e 3. Ciò consente ai gestori dei passaggi preimpostati di annullare ulteriori operazioni logiche all'inizio della pipeline di compilazione.

  • I seguenti passaggi di analisi accettano ora i vincoli codificati in un Target grazie al nuovo argomento di input target :

    I vincoli di destinazione avranno la priorità sui vincoli forniti dall'utente, per coerenza con il resto della pipeline del transpiler.

  • Aggiunto un nuovo metodo Layout.inverse() che viene utilizzato per prendere l'inverso di un oggetto Layout oggetto. Aggiunto un nuovo metodo Layout.compose() che viene utilizzato per comporre due Layout oggetti. Aggiunto un nuovo metodo Layout.to_permutation() che serve a creare una permutazione corrispondente a un oggetto Layout oggetto.

  • Aggiunta una nuova riduzione al passaggio OptimizeAnnotated al passaggio del transpiler. Questa riduzione cerca le operazioni annotate (oggetti di tipo AnnotatedOperation che consistono in un'operazione base BB e in una lista MM di modificatori di controllo, inversi e di potenza) con le seguenti proprietà:

    • l'operazione di base BB deve essere sintetizzata (cioè non è già supportata dal target o appartiene alla libreria di equivalenza)
    • il circuito di definizione per BB può essere espresso come PP - QQ - RR con R=P1R = P^{-1}

    In questo caso i modificatori possono essere spostati solo nella parte QQ. Come esempio specifico, i sommatori controllati basati su QFT hanno la forma control - [QFT -- U -- IQFT], che può essere semplificata in QFT -- control-[U] -- IQFT. Eliminando i controlli sulle parti QFT e IQFT del circuito, si ottiene un numero significativamente inferiore di porte nel circuito transpilato.

  • Aggiunti due nuovi metodi alla classe DAGCircuit alla classe: qiskit.dagcircuit.DAGCircuit.op_successors() restituisce un iteratore ai DAGOpNode successori di un nodo e qiskit.dagcircuit.DAGCircuit.op_successors() restituisce un iteratore ai DAGOpNode predecessori di un nodo.

  • Aggiunto un nuovo passaggio di transpiler, RemoveFinalResetche rimuove qualsiasi Reset che è l'istruzione finale su un filo di qubit. Ad esempio, prendendo un circuito con finale Resets:

    _images/release_notes-3.png

    rimuoverà gli azzeramenti finali quando il passaggio viene eseguito:

    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
  • Aggiunto un nuovo passaggio di transpiler StarPreRouting che ha lo scopo di identificare i sottocircuiti a connettività stellare e di sostituirli con un percorso lineare ottimale. Questo è utile per alcuni circuiti che sono composti da questa connettività circuitale, come Bernstein-Vazirani e QFT. Ad esempio:

    _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

    In alternativa, è possibile estendere un gestore di passaggi preimpostati esistente:

    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

Funzionalità di visualizzazione

  • Il testo e i Matplotlib cassetti dei circuiti (QuantumCircuit.draw()) hanno un supporto minimo per la visualizzazione di espressioni che coinvolgono variabili manuali in tempo reale. L'operazione Store e le inizializzazioni delle variabili non sono ancora supportate; per circuiti dinamici di grandi dimensioni, si consiglia di utilizzare le funzionalità di esportazione di OpenQASM 3 (qasm3.dumps()) per ottenere una rappresentazione testuale di un circuito.

Varie Funzioni

  • Questa versione di Qiskit finalizza il supporto per NumPy 2.0. Qiskit continuerà a supportare sia NumPy 1.x che 2.x per il prossimo futuro.

Note sull'aggiornamento

  • Rimuove la codifica delle opzioni di stile per i file plot_histogram(). Ciò consente di applicare fedelmente i file di stile di Matplotlib alle figure. Gli utenti che desiderano andare oltre i valori predefiniti impostati da Matplotlib possono creare i propri file di stile o passare un oggetto Matplotlib Axes a plot_histogram e post-applicare qualsiasi personalizzazione.

  • La funzione transpile() è stata aggiornata per convertire internamente gli ingressi del backend di tipo BackendV1 in BackendV2che consente alla pipeline di transpilazione di accedere ai vincoli del backend attraverso un elemento di tipo Target. Questa modifica non richiede alcun intervento da parte dell'utente.

Note sull'aggiornamento dei circuiti

  • L'utilizzo del numero casuale di QuantumVolume è cambiato, quindi si otterrà un circuito diverso per un seme fisso tra le versioni precedenti di Qiskit e questa versione. La generazione casuale-unitaria ora utilizza più bit di entropia, quindi i circuiti di grandi dimensioni saranno meno distorti.

  • Le istanze interne UnitaryGate nella definizione di un circuito QuantumVolume non avranno più un campo label impostato. In precedenza era impostato sulla stringa su4_<seed> , dove <seed> era un numero a tre cifre che indicava il seme di un'istanza interna di Numpy pRNG per quel gate. Questa operazione rappresentava un serio problema di prestazioni e il seme non avrebbe dovuto essere utile; se si ha bisogno di recuperare la matrice dal gate, è sufficiente usare il metodo Gate.to_matrix() metodo.

Note sull'aggiornamento delle primitive

  • La funzione make_data_bin() non crea e restituisce più una DataBin sottoclasse. Restituisce invece sempre la classe DataBin classe. Tuttavia, continua a esistere per la compatibilità all'indietro, anche se alla fine sarà deprecato. Tutti gli utenti dovrebbero migrare a costruire DataBin direttamente, invece di istanziare le sottoclassi come output di make_data_bin().

Note sull'aggiornamento dei provider

  • Implementazioni di BackendV2 (e BackendV1) potrebbero voler aggiornare i loro metodi run() per rifiutare avidamente gli input contenenti variabili classiche tipizzate (vedere qiskit.circuit.classical) e l'istruzione Store se non le supportano. La nuova istruzione Store è trattata dal transpiler come una "direttiva" sempre disponibile (come la direttiva Barrier); se i vostri backend non la supportano, non sarà colta dall'opzione transpiler.

    Per ulteriori informazioni, vedere Variabili in tempo reale.

Note sull'aggiornamento QPY

Note sull'aggiornamento della sintesi

  • Il TwoQubitWeylDecomposition non si auto-specializzerà più in una sottoclasse al momento della creazione. Questo era un dettaglio interno della classe TwoQubitWeylDecomposition e non era un comportamento pubblico documentato, poiché tutte le sottoclassi si comportavano allo stesso modo ed erano usate solo per il dispatch interno. Tuttavia, poiché si trattava di un comportamento riscontrabile, questa nota di rilascio documenta che questo non si verificherà più e che tutte le istanze di TwoQubitWeylDecomposition saranno dello stesso tipo. Il comportamento dei metodi pubblici della classe non cambia.

Note sull'aggiornamento del transpiler

  • La preimpostazione StagedPassManager restituito per il livello di ottimizzazione 2 da generate_preset_pass_manager() e level_2_pass_manager() sono state rielaborate per fornire un migliore equilibrio tra tempo di esecuzione e ottimizzazione. Ciò significa che i circuiti di uscita cambieranno rispetto alle versioni precedenti. Se si ha bisogno di un gestore di passaggi esatto dal livello 2 nelle versioni precedenti, è possibile costruirlo manualmente o utilizzarlo da una versione precedente e salvare i circuiti con qpy per caricarlo con una release più recente.

Varie Note sull'aggiornamento

  • La versione minima di Windows supportata è ora Windows 10. Nelle versioni precedenti non abbiamo elencato esplicitamente una versione minima supportata di Windows e implicitamente Windows 7, 8 e 8.1 avrebbero potuto funzionare (ma non sono mai stati testati). Ma a causa dell'abbandono del supporto alle vecchie versioni di Windows da parte di Rust 1.78, i binari pubblicati da Qiskit su PyPI non supporteranno più le vecchie versioni di Windows a partire da questa release. Se si utilizza una versione precedente di Windows, è possibile compilare Qiskit dai sorgenti utilizzando un compilatore Rust più vecchio (la versione minima di Rust supportata da Qiskit per la compilazione dai sorgenti è attualmente 1.70 ), ma le versioni precedenti di Windows non sono una piattaforma supportata e non sono testate.

Note di deprecazione

  • Il supporto per l'esecuzione di Qiskit con Python 3.8 è stato deprecato e sarà rimosso nella versione di Qiskit 1.3.0. 1.3.0 è la prima release dopo la fine del ciclo di vita di Python 3.8 e non è più supportato. [1] Ciò significa che a partire dalla versione 1.3.0 sarà necessario aggiornare la versione Python in uso a Python 3.9 o superiore.

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

Deprecazioni dei provider

  • Le classi base astratte Provider e ProviderV1 sono ora deprecate e saranno rimosse in Qiskit 2.0.0. L'astrazione offerta da queste definizioni di interfaccia non forniva un valore sostanziale; incapsulava unicamente gli attributi name, backends, e un get_backend(). Un _provider_, come concetto, continuerà a esistere come una collezione di backend. Se attualmente si sta implementando un provider, si può modificare il codice semplicemente rimuovendo ProviderV1 come classe padre della propria implementazione. Come parte di questo, probabilmente si vorrebbe aggiungere un'implementazione di get_backend per la retrocompatibilità. Ad esempio:

    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]

Deprecazioni della sintesi

  • Il metodo TwoQubitWeylDecomposition.specialize() è ora deprecato e sarà rimosso nella versione di Qiskit 2.0.0. Questo metodo non ha mai avuto uno scopo pubblico e non è sicuro che un utente finale lo chiami, in quanto muterebbe la scomposizione calcolata nell'oggetto e produrrebbe campi non validi nell'oggetto. È stato usato solo internamente per costruire un nuovo oggetto TwoQubitWeylDecomposition oggetto. Nonostante ciò, era ancora una parte documentata dell'API pubblica della classe e ora è stata deprecata senza alcuna potenziale sostituzione. In questa versione solleva sempre un NotImplementedError quando viene chiamato, perché la sottoclasse di specializzazione è stata rimossa come parte della riscrittura di Rust della classe.

Deprecazioni del transpiler

  • Il pass qiskit.transpiler.passes.CXCancellation è stato deprecato in favore di InverseCancellationche è più generico. CXCancellation è del tutto semanticamente equivalente a InverseCancellation([CXGate()]).

  • Il passaggio di transpilazione qiskit.transpiler.passes.ALAPSchedule è ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Il passaggio è sostituito da ALAPScheduleAnalysis, che è un passaggio di analisi.

  • Il passaggio di transpilazione qiskit.transpiler.passes.ASAPSchedule è ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. È stato sostituito da ASAPScheduleAnalysis e dal nuovo flusso di lavoro di pianificazione.

  • Il passaggio di transpilazione qiskit.transpiler.passes.DynamicalDecoupling è ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Utilizzare invece PadDynamicalDecouplingche svolge la stessa funzione, ma richiede l'esecuzione di passaggi di pianificazione e di analisi dell'allineamento prima di questo.

  • Il passaggio di transpilazione qiskit.transpiler.passes.AlignMeasures è ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Si può invece utilizzare ConstrainedRescheduleche svolge la stessa funzione e supporta anche l'allineamento a vincoli temporali aggiuntivi.

Deprecazioni relative alla visualizzazione

  • I parametri show_idle e show_barrier nei cassetti della linea temporale sono stati sostituiti rispettivamente da idle_wires e plot_barriers per adattarli ai parametri dei cassetti dei circuiti. I loro nomi precedenti sono ora deprecati e saranno rimossi nella prossima versione principale. I nuovi parametri sono del tutto equivalenti.

Correzioni di bug

  • È stato risolto un problema con la funzione qpy.dump() per cui, quando il flag use_symengine era impostato su un oggetto vero che valutava True ma non era in realtà il booleano True, il payload QPY generato risultava corrotto. Ad esempio, se si imposta use_symengine a HAS_SYMENGINEquesto oggetto viene valutato come True quando viene lanciato come bool, ma in realtà non è True.

  • Corretto un problema con la funzione circuit_drawer() e QuantumCircuit.draw() quando si carica uno stile matplotlib tramite il file di configurazione utente.

  • È stato risolto un problema per cui il passaggio ConstrainedReschedule in precedenza dava un errore se il circuito conteneva un'istruzione Reset istruzione. Questo problema è stato corretto in modo che il passaggio non dia più errori, tuttavia l'hardware reale può comportarsi in modo diverso da quello che Qiskit scheduler presume, soprattutto per le misure e i reset a metà circuito. Lo scheduler di Qiskit solleva RuntimeWarning se incontra un circuito contenente uno dei due. Corretto #10354

  • È stato risolto un problema con la classe CommutationChecker che dava errore se l'attributo di un cancello name era codificato in UTF8. In precedenza funzionavano solo i nomi dei gate con codifica ascii. Corretto #12501

  • Corretto un problema con gli elementi SparsePauliOp.apply_layout() e Pauli.apply_layout() quando per l'argomento layout veniva passato un array non valido con indici duplicati o negativi. In precedenza questo non comportava un errore e la trasformazione eseguita non era valida. Questi metodi ora sollevano un problema QiskitError se vengono forniti indici duplicati o negativi come parte di un layout.

  • È stato risolto un problema di prestazioni nei programmi BackendSamplerV2 e BackendEstimatorV2. Corretto #12290

  • È stato risolto un problema con l'opzione convert_to_target() per cui il convertitore ignorava erroneamente le istruzioni di flusso di controllo se erano specificate nell'attributo BackendConfiguration.supported_instructions , che è la posizione tipica in cui le istruzioni di flusso di controllo sono specificate in un oggetto BackendConfiguration oggetto. Corretto #11872.

  • Corretto un problema con l'opzione circuit_drawer() o QuantumCircuit.draw() quando si usa l'opzione di uscita mpl : il programma si blocca se il circuito da disegnare contiene un'operazione ControlFlow e l'opzione fold è impostata su -1 (cioè nessuna piega). Corretto #12012.

  • Corretto un errore nella conversione delle istruzioni di impulso personalizzate nel formato legacy qiskit.qobj al formato legacy. Il bug è stato introdotto in Qiskit 1.0.0 e causa la conversione di istruzioni con forme di impulso personalizzate che generano un errore. Dopo la correzione, la conversione viene eseguita correttamente e l'impulso personalizzato viene convertito in Waveform come dovrebbe. Corretto #11828.

  • È stato risolto un bug in transpile() in cui i vincoli personalizzati instruction_durations, dt e backend_properties venivano ignorati se forniti contemporaneamente a un backend di tipo BackendV2. Il comportamento dopo la correzione è ora indipendente dal fatto che il backend fornito sia di tipo BackendV1 o di tipo BackendV2. Allo stesso modo, timing_constraints è ora sovrascritto dagli input di target , ma ha la precedenza su BackendV1 e BackendV2 e gli input.

  • Chiamando EquivalenceLibrary.set_entry() aggiornerà correttamente l'oggetto grafico interno della libreria. In precedenza, i metadati venivano aggiornati, ma la struttura del grafo rimaneva inalterata, il che significava che utenti come BasisTranslator continuerebbero a usare le vecchie regole. Corretto #11958.

  • L'opzione EvolvedOperatorAnsatz gestisce correttamente il caso in cui l'argomento degli operatori è un elenco vuoto. In precedenza, ciò comportava un errore.

  • D'ora in poi, EvolvedOperatorAnsatz non avrà alcuna qreg quando ci sono zero qubit, invece di avere un'istanza con zero qubit QuantumRegister istanza con zero qubit. Questo comportamento si allinea più coerentemente con la sua superclasse QuantumCircuit.

  • Il metodo Instruction.repeat() sposta ora un insieme condition all'esterno restituito Instruction e lascia incondizionate le porte interne della sua definizione. In precedenza, il metodo lasciava le ClassicalRegister all'interno della definizione interna, uno stato non valido che si manifestava in seguito come bug apparentemente non correlati, ad esempio durante la transpilazione o l'esportazione. Corretto #11935.

  • È stato risolto un problema nel passaggio InverseCancellation che in alcuni casi annullava erroneamente un gate parametrato auto-invertito anche se il valore del parametro non corrispondeva. Corretto #11815

  • Migliorare la decomposizione dei gate MCXGate e MCPhaseGate senza utilizzare i qubit ancilla, in modo che il numero di CXGate crescerà in modo quadratico rispetto al numero di qubit e non esponenziale.

  • È stato corretto un bug che mandava in crash la funzione convert_to_target() quando mancano le proprietà dei qubit ( T1, T2 o la frequenza) è stato risolto. I valori mancanti delle proprietà in QubitProperties sono riempiti con None.

  • BasePassManager.run() non disperderà più il precedente PropertySet nei nuovi flussi di lavoro quando viene richiamato più di una volta. In precedenza, per inizializzare le esecuzioni successive veniva utilizzato lo stesso PropertySet come in precedenza, veniva utilizzato per inizializzare le esecuzioni successive, il che poteva significare che ai task venivano fornite informazioni sulle proprietà non valide. Il comportamento ora corrisponde a quello di Qiskit 0.44. Corretto #11784.

  • Pauli.evolve() ora gestisce correttamente i circuiti quantistici contenenti porte ECR. In precedenza non sono stati riconosciuti come porte Clifford e si è verificato un errore.

  • Corretto un bug in Pauli.evolve() in cui l'evoluzione da parte di un circuito con un nome che corrisponde a certe porte di Clifford ('cx', 'cz', ecc.) faceva evolvere il Pauli in base al nome del circuito, non in base al contenuto del circuito. Questo bug si verifica solo con l'opzione non predefinita frame='s'.

  • È stato risolto un problema di prestazioni nella funzione qpy.load() quando si deserializzano payload QPY con un gran numero di qubit o clbit in un circuito.

  • Corretto un bug nella gestione dell'argomento default_alignment di build(). Gli input di tipo AlignmentKind sono ora correttamente elaborati come allineamenti predefiniti.

  • Corretto un bug nella funzione qiskit.pulse.utils.format_parameter_value() che convertiva involontariamente numeri interi abbastanza grandi in valori float o causava un arrotondamento imprevisto. Per i dettagli, vedere il numero 11971.

  • Correzione di un problema nella classe QDrift in cui i coefficienti dell'hamiltoniana erano precedentemente forzati a essere positivi prendendo il valore assoluto di ciascun coefficiente. Il problema è stato corretto in modo che i segni dei coefficienti negativi siano aggiunti di nuovo.

  • È stato risolto un bug in convert_durations_to_dt() , a causa del quale la funzione applicava ciecamente una conversione da secondi a dt sulle durate dei circuiti, indipendentemente dalle unità originali dell'attributo. Questo potrebbe portare a ordini di grandezza errati nelle durate dei circuiti riportate.

  • Fissato SparsePauliOp.apply_layout() per funzionare correttamente con gli operatori zero-qubit. Ad esempio, se in precedenza si è creato un qubit 0 e si è applicato un layout come:

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

    questo avrebbe precedentemente generato un errore. Ora questo restituirà correttamente un operatore della forma: SparsePauliOp(['III'], coeffs=[1.+0.j])

  • È stata corretta una svista nel passaggio Commuting2qGateRouter in cui le permutazioni qreg non venivano aggiunte all'insieme di proprietà del passaggio, per cui dovevano essere rintracciate manualmente dall'utente. Ora è possibile accedere alla permutazione attraverso la proprietà layout del circuito di uscita e inserire il passaggio in qualsiasi pipeline di transpilazione senza perdita di informazioni.

  • Corretta un'imprecisione in virgola mobile durante la scalatura di alcune unità di impulso tra secondi e nanosecondi. Se l'impulso fosse stato definito simbolicamente, la scalatura avrebbe potuto introdurre un inutile errore in virgola mobile per alcune versioni di symengine, che avrebbe potuto dare risultati inaspettati una volta che i simboli fossero stati completamente vincolati. Corretto #12392.

  • I gestori di passaggio preimpostati di transpile() non falliranno più sui circuiti con flusso di controllo, se non è specificato un target hardware o un set di porte di base. Ora tratteranno tali obiettivi astratti come se permettessero tutte le operazioni del flusso di controllo. Corretto #11906.

  • Il metodo qiskit.instruction.Instruction.soft_compare() ha lo scopo di confrontare se due porte corrispondono nel nome, nel numero di qubit, nel numero di clbit e nel numero di parametri. Tuttavia, c'era un errore di battitura per cui non controllava il numero di qubit e il numero di clbit per una corrispondenza. Questo risolve l'apparente errore di battitura.

  • Il plugin predefinito init non sollevava correttamente un problema di tipo TranspilerError quando veniva chiamato con un livello di ottimizzazione non valido.

  • È stato risolto un problema con il metodo Operator.from_circuit() in cui il metodo del costruttore interpretava in modo errato la permutazione finale del layout, causando la costruzione di un oggetto non valido Operator non valido. In precedenza, il layout finale veniva elaborato senza tenere conto del layout iniziale, cioè l'inizializzazione non era corretta per tutti i circuiti quantistici che hanno un layout iniziale non banale.

  • È stato risolto un problema di prestazioni in PassManager.run() quando viene eseguito su più circuiti in parallelo. Non spenderà più tempo per serializzare il file PassManager (che è un requisito per l'esecuzione parallela) quando vengono forniti più ingressi, se si intende elaborare gli ingressi solo in modo seriale.

  • Parameter è stato aggiornato in modo che le istanze che si confrontano abbiano sempre lo stesso hash. In precedenza, veniva confrontato solo l'elemento Parameter.uuid veniva confrontato, quindi le istanze Parameter istanze con nomi diversi potevano essere confrontate in modo uguale se erano state costruite usando un valore comune per il parametro uuid (che di solito non viene passato esplicitamente).

  • Corretto un bug in plot_coupling_map() che causava una colorazione errata dei bordi della mappa di accoppiamento. Corretto #12369.

  • Il parser OpenQASM 2.0 (qasm2.load() e qasm2.loads()) è ora in grado di valutare espressioni gate-angle che includono operandi interi che farebbero traboccare l'intero di dimensioni di sistema. Questi saranno valutati in un contesto di virgola mobile a doppia precisione, proprio come il resto dell'espressione. Tuttavia, un intero arbitrariamente grande non è necessariamente rappresentabile in virgola mobile a doppia precisione, quindi è possibile che il circuito, comunque sia stato generato, abbia già perso tutta la precisione numerica modulo 2π2\pi.

  • Parameter le istanze usate come stand-ins per le variabili di input nei programmi di OpenQASM 3 avranno ora i loro nomi sfuggiti per evitare collisioni con le porte incorporate durante l'esportazione a OpenQASM 3. In precedenza poteva verificarsi un conflitto di nomi e l'esportatore generava OpenQASM 3 non valido.

  • Corretto il bug in QuantumCircuit.draw() che causava la modifica dei dizionari di stile personalizzati per il cassetto Matplotlib al momento dell'esecuzione.

  • QuantumCircuit.append() con copy=True (il suo valore predefinito) ora copierà correttamente le istruzioni parametrizzate da ParameterExpression e non solo da istanze Parameter istanze.

  • La gestione interna delle calibrazioni dei circuiti personalizzati e delle InstructionDurations è stata trasferita dalla funzione transpile() funzione ai singoli passaggi del transpiler: DynamicalDecoupling, DynamicalDecoupling. In precedenza, le durate delle istruzioni provenienti dalle calibrazioni dei circuiti non venivano prese in considerazione a meno che non venissero incorporate manualmente nell'argomento di input dell'istruzione, ma ora i passaggi che ne hanno bisogno analizzano il circuito e scelgono il valore di durata più pertinente in base al seguente ordine di priorità: target > input personalizzato > calibrazioni dei circuiti.

  • Corretto un bug in transpile() in cui l'argomento num_processes veniva utilizzato solo se venivano forniti dt o instruction_durations .

Altre note


1.0.0rc1

Note sull'aggiornamento dei provider

  • Il modulo deprecato qiskit.providers.fake_provider è stato migrato nel pacchetto qiskit-ibm-runtime Python. Per questo motivo, i seguenti elementi del file qiskit.providers.fake_provider sono stati rimossi a seguito della loro deprecazione in Qiskit 0.46:

    • qiskit.providers.fake_provider.FakeProvider
    • qiskit.providers.fake_provider.FakeProviderForBackendV2
    • qiskit.providers.fake_provider.FakeProviderFactory
    • qiskit.providers.fake_provider.fake_backends.FakeBackendV2
    • qualsiasi backend falso contenuto in qiskit.providers.fake_provider.backends (accessibile attraverso il provider)
    • qiskit.providers.fake_provider.FakeQasmSimulator
    • qiskit.providers.fake_provider.FakeJob
    • qiskit.providers.fake_provider.FakeQobj

    Per utilizzare il nuovo modulo provider fasullo, è possibile eseguire pip install qiskit-ibm-runtime e sostituire il percorso di importazione di qiskit (qiskit.providers.fake_provider) con il nuovo percorso di importazione (qiskit_ibm_runtime.fake_provider). Esempio di migrazione:

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

    Inoltre, i seguenti backend fasulli progettati per scopi speciali di test sono stati sostituiti dalla nuova classe GenericBackendV2 e sono stati rimossi anche in seguito alla loro deprecazione in Qiskit 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

    Esempio di migrazione alla nuova GenericBackendV2 classe:

    # 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
Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.