Skip to main content
IBM Quantum Platform

Note di rilascio di Qiskit 0.45

Questa pagina contiene le note di rilascio di Qiskit 0.45, la prima release dopo la completa rimozione della struttura degli "elementi". Per tutte le note di rilascio, comprese quelle che risalgono alla vecchia struttura "meta-pacchetto" di Qiskit, vedere Note di rilascio. Per una tabella delle versioni dei meta-pacchetti, vedere le note di rilascio di Qiskit 0.44.


0.45.3

Preludio

Qiskit 0.45.3 è un rilascio puntuale senza modifiche al codice, se non quella di sollevare un problema ImportError se rileva che è stato installato in un ambiente non valido con Qiskit >= 1.0.

Per informazioni sugli errori, sulla preparazione di Qiskit 1.0 e per informazioni di base più dettagliate, leggete la nostra guida alla migrazione del nuovo packaging.

Nota

Il rilascio di Qiskit 1.0 è previsto circa due settimane dopo quello di Qiskit 0.45.3, il 15 febbraio 2024, e potrebbe non essere ancora disponibile quando leggete questo messaggio. Questa modifica è stata apportata in modo proattivo.

La struttura di packaging di Qiskit sta cambiando in Qiskit 1.0, e purtroppo i requisiti modificati non possono essere comunicati completamente a pip, soprattutto se i comandi di pip install --upgrade vengono eseguiti dopo che l'ambiente è stato inizialmente configurato. Tutte le versioni di Qiskit precedenti a 1.0 (compresa questa) hanno un conflitto di installazione con Qiskit 1.0 che pip non risolve.

Se import qiskit solleva un errore ImportError per voi, il vostro ambiente è in uno stato non valido e le versioni di Qiskit 0.45/0.46 e 1.0 sono entrambe raggiungibili, il che comporterà codice sottilmente danneggiato. È necessario creare un nuovo ambiente virtuale e assicurarsi che sia installata solo una delle due versioni. In particolare, se si intende installare Qiskit 1.0, non devono essere installati pacchetti che dipendono da qiskit-terra ; questi pacchetti sono incompatibili con Qiskit 1.0 e devono essere aggiornati. Se si intende installare Qiskit 0.45 o 0.46, è necessario assicurarsi di non aver tentato di installare qiskit>=1.0.

Se sviluppate una libreria basata su Qiskit e avete ancora una dipendenza da qiskit-terra, dovreste rilasciare urgentemente un nuovo pacchetto che dipenda solo da qiskit. Dalla versione 0.44, il pacchetto qiskit contiene solo il nucleo del compilatore qiskit-terra (il componente che ora si chiama semplicemente "Qiskit"), quindi se la vostra versione minima è 0.44, potete tranquillamente passare una dipendenza da qiskit-terra>=0.44 a qiskit>=0.44 senza alcun cambiamento in ciò che verrà installato. Per maggiori dettagli e raccomandazioni per i test e la preparazione, consultare la sezione per gli sviluppatori della guida alla migrazione.


0.45.2

Preludio

Qiskit 0.45.2 è un piccolo rilascio di patch che corregge alcuni bug riscontrati nella serie di release 0.45.

Correzioni di bug

  • Chiamata copy() o copy_empty_like() su BlueprintCircuit ora propagherà correttamente l'attributo global_phase alla copia. In precedenza, la fase globale era sempre pari a zero dopo la copia.

  • QPY (utilizzando qpy.dump() e qpy.load()) ora serializzerà e deserializzerà correttamente i circuiti quantistici con gli operatori Clifford (Clifford).

  • È stato risolto un problema nel cassetto del circuito mpl in cui il testo veniva stampato oltre la fine del riquadro per un elemento di tipo SwitchCaseOp se la casella predefinita era vuota.

  • La trasmissione di qubit-argument di QuantumCircuit.delay() produce ora correttamente istruzioni individuali Delay per ogni qubit, come previsto. In precedenza, quando si davano alcuni iterabili (come ad esempio sets), produceva silenziosamente un circuito non valido che poteva fallire in punti insoliti.

  • È stato risolto un bug che causava un errore quando l'utente cercava di caricare i dati di calibrazione di un gate in una situazione particolare Target in una situazione particolare. Ciò si verifica quando il backend riporta solo dati di calibrazione parziali, ad esempio facendo riferimento a un impulso di forma d'onda in una definizione di comando ma non includendo tale impulso nella libreria degli impulsi. In questa situazione, l'oggetto impulso di Qiskit non può essere costruito, con il risultato di non riuscire a costruire il programma degli impulsi per la calibrazione. Ora, quando i dati di calibrazione sono incompleti, il Target lo considera come se non fosse stata segnalata alcuna calibrazione e non solleva alcuna eccezione.

  • È stato risolto un problema con il passaggio Optimize1qGatesDecomposition in cui potenzialmente risintetizzava un singolo gate ideale (il che significa che il tasso di errore è 0.0) che era presente nel file Target. Questo problema è stato risolto in modo che il passaggio Optimize1qGatesDecomposition passerà al gate del circuito se il tasso di errore (che include il numero di gate) è lo stesso. Corretto #10568

  • È stato risolto un problema con il passaggio OptimizeSwapBeforeMeasure che ottimizzava in modo errato i circuiti che coinvolgevano istruzioni di scambio e misura. Questo commit risolve il bug cambiando DAGCircuit.successors() a DAGCircuit.descendants(). Inoltre, sono stati aggiunti un paio di test supplementari per garantire che il bug sia stato risolto. Ad esempio:

    from qiskit import QuantumCircuit
    from qiskit.transpiler.passes import OptimizeSwapBeforeMeasure
    pass_ = OptimizeSwapBeforeMeasure()
    qc = QuantumCircuit(2, 1)
    qc.swap(0, 1)
    qc.measure(0, 0)
    qc.measure(0, 0)
    print(qc.draw())
    print(pass_(qc).draw())

    che in precedenza avrebbe stampato:

            ┌─┐┌─┐
    q_0: ─X─┤M├┤M├
          │ └╥┘└╥┘
    q_1: ─X──╫──╫─
             ║  ║
    c: 1/════╩══╩═
             0  0
         ┌─┐
    q_0: ┤M├───
         └╥┘┌─┐
    q_1: ─╫─┤M├
          ║ └╥┘
    c: 1/═╩══╩═
          0  0

    e ora il secondo circuito è correttamente ottimizzato per:

    q_0: ──────
         ┌─┐┌─┐
    q_1: ┤M├┤M├
         └╥┘└╥┘
    c: 1/═╩══╩═
          0  0
  • Correzione di un bug nella rappresentazione delle StabilizerState nella rappresentazione delle stringhe.


0.45.1

Preludio

Qiskit Terra 0.45.1 è una piccola patch che corregge diversi bug riscontrati nella serie di release 0.45. È anche la prima versione ad avere il supporto ufficiale per Python 3.12. La release 0.45.1 supporta Python 3.8, 3.9, 3.10, 3.11 e 3.12.

Nuove funzioni

  • Aggiunto il supporto per l'utilizzo di Qiskit con Python 3.12. A partire da questa versione Qiskit supporta l'esecuzione con le versioni di Python 3.8, 3.9, 3.10, 3.11 e 3.12.

Correzioni di bug

  • QuantumCircuit.barrier() genererà ora un output corretto quando gli verrà dato un oggetto set come uno dei suoi ingressi. In precedenza, aggiungeva un'operazione non valida al circuito, anche se in pratica questo non causava problemi osservabili. Corretto #11208

  • La proprietà Instruction.condition_bits ora gestirà correttamente le espressioni classiche di runtime (qiskit.circuit.classical).

  • Corretto l'uso hash() degli oggetti di Qiskit Pulse Channel (come ad esempio DriveChannel) nei casi in cui il canale veniva trasferito da un processo di Python a un altro che utilizzava un seme di hash diverso.

  • I cancelli personalizzati condizionati importati da OpenQASM 2 ora mantengono correttamente le condizioni quando vengono decapati e copiati in profondità. In precedenza, qualsiasi gate condizionale personalizzato (definito da un'istruzione gate in un file OpenQASM 2) perdeva la sua condizione quando veniva copiato o decapato.

  • Corretta la deserializzazione QPY degli elementi StatePreparation e Initialize con parametri stringa e interi (invece di un vettore di stato esplicito, che funzionava già). Corretto #11158.

  • È stato risolto un bug in SabreLayout che non riusciva ad aggiungere le informazioni sul registro all'oggetto Layout utilizzato per TranspileLayout.initial_layout. Questo ha influito sulla visualizzazione dei circuiti con QuantumCircuit.draw() e circuit_drawer() dopo la trasposizione, che mostrava un'etichetta di qubit virtuale della forma Qubit[QuantumRegister(6, 'q', 0)] anziché l'etichetta di qubit virtuale prevista utilizzando il nome del registro (ad esempio q0). Corretto #11038

  • È stato risolto un problema con qpy.dump() che portava la funzione a ignorare potenzialmente il valore di use_symengine durante la serializzazione di un oggetto ScheduleBlock oggetto. In questo modo verrebbe generato un payload QPY non valido, in quanto dichiarerebbe di usare symengine per le espressioni simboliche, ma in realtà conterrebbe dati serializzati symy.

  • Corretto un bug che causava l'errore di UnitaryOverlap si bloccava al momento dell'inizializzazione se veniva fornito un circuito di ingresso contenente una barriera.


0.45.0

Preludio

Qiskit 0.45.0 è l'ultimo rilascio di funzionalità prima di 1.0. Prepara il terreno per le modifiche all'API che stiamo pianificando per la nostra prima versione principale, che comprende molte rimozioni di funzionalità precedentemente deprecate e una serie di nuove deprecazioni.

Nota

Se il vostro progetto dipende da Qiskit, potrebbe fare affidamento su funzionalità che non saranno più supportate in Qiskit 1.0. Per questo motivo, si consiglia di impostare in modo proattivo la versione supportata all'indirizzo <1.0.

Alcune caratteristiche salienti di Qiskit 0.45.0 sono:

  • A partire da questa versione, tutte le porte non parametrizzate della libreria di circuiti standard di Qiskit sono ora singleton. Per impostazione predefinita, questi gate condividono una singola istanza in memoria, quindi una volta istanziato un gate di un tipo specifico, diciamo XGateviene istanziato, tutte le istanze successive di XGate sarà un riferimento alla prima. Ciò si traduce in una riduzione dell'uso della memoria e dell'overhead di costruzione quando si utilizzano più porte dello stesso tipo in un circuito. Per realizzare questa caratteristica, sono state introdotte nuove classi di base: SingletonInstruction e SingletonGate. Per maggiori dettagli, consultare le note sulle caratteristiche.
  • Abbiamo aggiunto una nuova interfaccia generica per il gestore di pass, che si trova nel nuovo modulo qiskit.passmanager modulo. Si tratta di una generalizzazione del pass manager utilizzato per costruire il transpiler Qiskit e introduce un framework generico per consentire agli utenti di creare nuovi pass manager che utilizzano diverse rappresentazioni intermedie (IR). Il modulo comprende una classe base generica di pass manager, i controllori di flusso e l'infrastruttura necessaria per gestire l'esecuzione dei compiti del pass manager. La nuova interfaccia è stata utilizzata per ricostruire il gestore di passaggi esistente nel modulo qiskit.transpiler pulendo i debiti tecnici del codice e migliorando l'usabilità e le prestazioni. Per maggiori dettagli, consultare le note sulle funzioni e sugli aggiornamenti.
  • 0.45.0 consente agli utenti di interagire meglio con le permutazioni del layout eseguite dal transpiler. I dati contenuti nella classe TranspileLayout sono ora più accessibili grazie a una serie di nuovi metodi e attributi. E un nuovo SparsePauliOp.apply_layout() metodo consente di applicare una specifica permutazione del layout a un SparsePauliOp osservabile costruito per un circuito in ingresso al transpiler. Per maggiori dettagli, consultare le note sulle caratteristiche.
  • Infine, abbiamo introdotto le operazioni annotate con la nuova classe AnnotatedOperation che consente di formulare istruzioni circuitali complesse come istruzioni di base con una serie di modificatori. Ad esempio, invece di un tipo di operazione specifico che implementa l'inverso controllato di a RXGatesi può usare un tipo annotato RXGate con gli attributi inverso e controllo. Per maggiori dettagli, consultare le note sulle caratteristiche.

Caratteristiche dei circuiti

  • Aggiunta di una nuova classe AnnotatedOperation che è una sottoclasse di Operation e rappresenta una qualche "operazione di base" modificata da un elenco di "modificatori". L'operazione di base è di tipo Operation e i modificatori attualmente supportati sono di tipo InverseModifier, ControlModifier e PowerModifier. I modificatori vengono applicati nell'ordine in cui compaiono nell'elenco.

    Ad esempio:

    gate = AnnotatedOperation(
      base_op=SGate(),
      modifiers=[
          InverseModifier(),
          ControlModifier(1),
          InverseModifier(),
          PowerModifier(2),
      ],
    )

    è logicamente equivalente a gate = SGate().inverse().control(1).inverse().power(2), o a:

    gate = AnnotatedOperation(
      AnnotatedOperation(SGate(), [InverseModifier(), ControlModifier(1)]),
      [InverseModifier(), PowerModifier(2)],
    )

    Tuttavia, questa equivalenza è solo logica, le rappresentazioni interne sono molto diverse.

    Per comodità, un singolo modificatore può essere passato anche direttamente, quindi AnnotatedGate(SGate(), [ControlModifier(1)]) è equivalente a AnnotatedGate(SGate(), ControlModifier(1)).

    Una caratteristica distintiva di un'operazione annotata è che la definizione del circuito non viene costruita quando l'operazione viene dichiarata, ma avviene solo durante la transpilazione, in particolare durante il passaggio di transpiler HighLevelSynthesis transpiler.

    Un'operazione annotata può essere vista anche come un oggetto di "livello superiore" o "più astratto" che può essere aggiunto a un circuito quantistico. Ciò consente di scrivere passaggi di ottimizzazione del transpiler che fanno uso di questa rappresentazione di livello superiore, ad esempio eliminando un gate che è immediatamente seguito dal suo inverso (si noti che questa riduzione potrebbe non essere possibile se sia il gate che il suo inverso sono prima sintetizzati in gate più semplici).

    In un certo senso, un'operazione annotata può essere vista come un'estensione di ControlledGateche permette di aggiungere un controllo all'operazione di base. In futuro prevediamo di sostituire ControlledGate da AnnotatedOperation. Analogamente alle porte controllate, il transpiler sintetizza le operazioni annotate prima che avvenga il layout/routing.

    Al momento, le operazioni annotate possono comparire solo nel livello superiore di un circuito quantistico, cioè non possono comparire all'interno del circuito ricorsivamente definito definition . Abbiamo in programma di rimuovere questa limitazione in un secondo momento.

  • Aggiunta una nuova opzione max_num_qubits a qiskit.circuit.CommutationChecker.commute() che specifica il numero massimo di qubit da considerare per il più costoso controllo di commutatività basato sulla moltiplicazione matriciale. In questo modo si evita di cercare di allocare internamente array di dimensioni 2N×2N2^N \times 2^N. Versioni più semplici del controllo di commutatività (per esempio, due operazioni quantistiche commutano quando sono su insiemi disgiunti di qubit) continuano a funzionare senza questo limite.

  • Aggiunto un nuovo parametro, check_input, al costruttore della classe UnitaryGate classe. Questo flag viene utilizzato per disabilitare i controlli di inizializzazione predefiniti che l'oggetto di input rappresenti una matrice unitaria. Questo può essere usato per accelerare la creazione di oggetti se si sa che l'input è già una matrice UnitaryGate se si sa che l'input è già una matrice unitaria. Questa nuova opzione deve essere usata solo in questi casi, perché se è impostata su False e l'input non è unitario, si otterrà un oggetto UnitaryGate non valido.

  • È stato aggiunto un nuovo metodo Parameter.assign() è stato aggiunto. Questo metodo serve principalmente a migliorare rapidamente le prestazioni di QuantumCircuit.assign_parameters() per il caso comune di circuiti che contengono prevalentemente "espressioni" che in realtà sono solo singoli parametri da assegnare successivamente.

  • Le prestazioni di QuantumCircuit.assign_parameters() quando si assegna un singolo parametro di un circuito che coinvolge molti parametri è stato migliorato.

  • Introdotte due nuove classi, SingletonInstruction e SingletonGateche sono sottoclassi di Instruction e Gate rispettivamente, che utilizzano una singola istanza per tutti gli oggetti di quel tipo. L'intento di questa classe è di ridurre al minimo la memoria e l'overhead di costruzione dell'uso di più porte in un circuito, con il compromesso di avere uno stato globale condiviso. Per questo motivo, questa classe è applicabile solo ai gate che non hanno uno stato unico e/o mutabile memorizzato in un'istanza. Ad esempio, il miglior esempio di questo è XGate non contiene alcuno stato e potrebbe fare leva su SingletonGate (e lo fa a partire da questa versione), mentre RXGate memorizza un parametro angolare in un'istanza e quindi non può usare SingletonGate perché una singola istanza globale condivisa non può rappresentare i valori dei parametri.

    L'altro potenziale problema da tenere presente quando si usano le classi singleton è che il modello di dati Instruction supporta alcuni stati mutabili. In particolare, il label, duration, unit, e condition sono tutti accessibili e modificabili nella classe Instruction e nelle sue sottoclassi dirette. Tuttavia, questo è incompatibile con la presenza di un oggetto condiviso tramite SingletonInstruction. Per le istanze di SingletonInstructionl'impostazione diretta di questi attributi non è consentita e solleva un'eccezione. Se sono necessari per una particolare istanza, è necessario assicurarsi di avere un'istanza mutabile usando Instruction.to_mutable() (o usare Instruction.c_if() per condition). label, duration e unit possono anche essere dati come argomenti di parole chiave durante la costruzione delle classi.

  • Le seguenti porte della libreria standard sono ora istanze di SingletonGate:

    Ciò significa che se queste classi sono istanziate come (ad esempio) XGate() utilizzando tutti i valori predefiniti del costruttore, condivideranno tutti una singola istanza globale. Ciò si traduce in una grande riduzione dell'overhead di memoria per > 1 oggetto di questi tipi e in tempi di costruzione degli oggetti significativamente più rapidi.

  • Introdotta una nuova classe SingletonControlledGate che è una sottoclasse di ControlledGate che utilizza una singola istanza per tutti gli oggetti di quel tipo. L'intento di questa classe è quello di ridurre al minimo la memoria e l'overhead di costruzione dell'uso di più porte in un circuito, con il compromesso di avere uno stato globale condiviso. Per questo motivo, questa classe è applicabile solo ai gate che non hanno uno stato unico e/o mutabile memorizzato in un'istanza. Ad esempio, un oggetto CXGate non contiene alcuno stato e quindi può fare leva su SingletonControlledGate (e lo fa a partire da questa versione). Al contrario, CRXGate memorizza un parametro angolare come parte dei suoi dati di istanza e quindi non può utilizzare il metodo SingletonControlledGate.

    L'altro potenziale problema da tenere presente quando si usa il metodo SingletonControlledGate è che il modello di dati originale di ControlledGate supporta la mutazione. In particolare, il label, duration, unit, condition, e ctrl_state sono tutti accessibili e mutabili nell'oggetto ControlledGatema la mutazione di questi attributi su SingletonControlledGate non è consentita e solleva un'eccezione. Questi attributi possono essere personalizzati, ma solo al momento della creazione (cioè tramite il costruttore). In questo caso, il nuovo gate costruito sarà un'istanza separata con lo stato personalizzato, invece dell'istanza condivisa a livello globale. Si può anche usare il metodo SingletonControlledGate.to_mutable() per ottenere una copia mutabile di un oggetto gate e poi mutare gli attributi come si farebbe con qualsiasi altro oggetto Instruction oggetto.

  • Le seguenti porte della libreria standard sono ora istanze di SingletonControlledGate:

    Ciò significa che, a meno che non siano impostati label, condition, duration, unit o ctrl_state sull'istanza al momento della creazione, tutti condivideranno una singola istanza globale ogni volta che viene creato un nuovo oggetto gate. Ciò si traduce in una forte riduzione dell'overhead di memoria per > 1 oggetto di questi tipi.

  • Aggiunto un nuovo metodo Instruction.to_mutable() e l'attributo Instruction.mutable utilizzati per ottenere una copia mutabile e verificare se un oggetto Instruction è mutabile. Con l'introduzione di SingletonGate questi metodi possono essere utilizzati per avere un'interfaccia unificata per gestire la mutabilità degli oggetti istruzione.

  • È stato aggiunto l'attributo Instruction.base_classche permette di ottenere il tipo "base" di un'istruzione. Molte istruzioni soddisfano type(obj) == obj.base_class, tuttavia le istanze singleton di SingletonInstruction e SingletonGate sono sottoclassi del loro tipo base. Si può usare l'attributo new base_class per trovare la classe base di questi elementi. Si veda la documentazione dell'attributo per le considerazioni su quando altre sottoclassi possono modificare il loro attributo base_classe cosa significa per l'esecuzione.

  • Aggiunto il UnitaryOverlap alla libreria dei circuiti Qiskit. Può essere utilizzato per calcolare la fedeltà degli stati generati dagli unitari esaminando la probabilità della distribuzione di uscita nello stato all-zeros o, equivalentemente, calcolando il valore di aspettativa del proiettore sullo stato all-zeros. Ciò è utile in applicazioni come l'apprendimento automatico e il calcolo degli stati eccitati nella chimica quantistica, per citarne alcune.

Caratteristiche di Pulse

  • Abilitato lo scheduling circuito-impulso tramite BackendV2.

    # import a fake backend which is a sub-class of BackendV2
    from qiskit.providers.fake_provider import FakePerth
    from qiskit.compiler.scheduler import schedule
    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(1, 1)
    qc.x(0)
    qc.measure(0,0)
    sched = schedule(circuits=qc, backend=FakePerth())

    Poiché BackendV2 non era supportato dalla funzione schedule() questo causava l'errore del metodo schedule() quando l'argomento backend veniva fornito con un'istanza di BackendV2. Per ulteriori informazioni, consultare il numero 10837.

OpenQASM Caratteristiche

  • Il modulo OpenQASM 2 qiskit.qasm2 ha ottenuto le funzioni di esportazione dump() e dumps(). Vengono utilizzati in modo molto simile al precedente QuantumCircuit.qasm():

    from qiskit import qasm2, QuantumCircuit
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure([0, 1], [0, 1])
    print(qasm2.dumps(qc))

    Le nuove funzioni derivano dallo stesso codice di QuantumCircuit.qasm()che verrà lentamente eliminato e sostituito con i nuovi percorsi, per fornire un'interfaccia più coerente rispetto a OpenQASM 3 (qiskit.qasm3) e QPY (qiskit.qpy). Questo è particolarmente importante perché il nome del metodo qasm() non fornisce alcuna indicazione sulla versione di OpenQASM e, da quando è stato aggiunto, Qiskit ha acquisito diversi moduli di serializzazione che potrebbero facilmente confondersi.

Caratteristiche QPY

  • QPY ora supporta l'uso della serializzazione e deserializzazione nativa di symengine per gli oggetti di tipo ParameterExpression e per le espressioni simboliche nei blocchi di programmazione Pulse. Si tratta di un'alternativa di serializzazione più veloce, ma non supportata da tutte le piattaforme. Verificare che la piattaforma di destinazione sia supportata dalla libreria symengine prima di impostare questa opzione, poiché sarà richiesta da qpy per deserializzare il payload.

    La funzione può essere attivata tramite il parametro use_symengine in qpy.dump():

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit import qpy
    
    theta = Parameter("theta")
    phi = Parameter("phi")
    sum_param = theta + phi
    
    qc = QuantumCircuit(1)
    qc.rz(sum_param, 0)
    qc.measure_all()
    
    with open('bell.qpy', 'wb') as fd:
        qpy.dump(qc, fd, use_symengine=True)
    
    with open('bell.qpy', 'rb') as fd:
        new_qc = qpy.load(fd)[0]

Caratteristiche dell'informazione quantistica

  • Aggiunto Clifford.from_linear_function() e Clifford.from_permutation() che creano un oggetto Clifford da LinearFunction e da PermutationGate rispettivamente. Di conseguenza, a Clifford può ora essere costruito direttamente da a LinearFunction, a PermutationGateo da un circuito quantistico contenente tali porte.

  • La Operator ha ora un metodo draw() che consente di visualizzarla come matrice di testo, oggetto IPython LaTeX o sorgente LaTeX. Il tipo di disegno predefinito è ancora l'ASCII __repr__ dell'operatore.

  • Aggiunto un nuovo metodo, apply_layout()alla classe SparsePauliOp alla classe. Questo metodo viene utilizzato per applicare un TranspileLayout layout del transpiler a un SparsePauliOp osservabile che è stato costruito per un circuito di ingresso al transpiler. Questo permette di lavorare con BaseEstimator e la trasposizione locale più facilmente. Ad esempio:

    from qiskit.circuit.library import RealAmplitudes
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.primitives import BackendEstimator
    from qiskit.compiler import transpile
    from qiskit.providers.fake_provider import FakeNairobiV2
    
    psi = RealAmplitudes(num_qubits=2, reps=2)
    H1 = SparsePauliOp.from_list([("II", 1), ("IZ", 2), ("XI", 3)])
    backend = FakeNairobiV2()
    estimator = BackendEstimator(backend=backend, skip_transpilation=True)
    
    thetas = [0, 1, 1, 2, 3, 5]
    transpiled_psi = transpile(psi, backend, optimization_level=3)
    permuted_op = H1.apply_layout(transpiled_psi.layout)
    res = estimator.run(transpiled_psi, permuted_op, thetas)

    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 la disposizione, che viene poi applicata a H1 usando apply_layout() per riflettere le trasformazioni eseguite da transpile().

Funzionalità del transpiler

  • La classe HighLevelSynthesis è estesa per sintetizzare circuiti con oggetti di tipo AnnotatedOperation.

  • Un nuovo qiskit.passmanager è stato aggiunto alla libreria Qiskit. Questo modulo implementa un generico gestore di passaggi e controllori di flusso e fornisce l'infrastruttura per gestire l'esecuzione dei compiti del gestore di passaggi. Il modulo fornisce classi base per i passaggi (GenericPass) e per i controllori di flusso (BaseController), oltre a una nuova classe di interfaccia, passmanager.Task, per gestire l'esecuzione del gestore dei passaggi (si veda il metodo Task.execute() ). Queste nuove classi seguono lo schema composito, in quanto i controllori di flusso sono collezioni di passaggi e un controllore può essere annidato ricorsivamente nella pipeline dei task. Occorre inoltre notare che le classi di base non conoscono i tipi di oggetti in ingresso e in uscita e devono essere sottoclassate per ottimizzare un particolare tipo di programma. Questo design unificato riduce la complessità del gestore di passaggi convenzionale e non richiede più l'uso di classi come RunningPassManager per gestire il dispatch della logica di esecuzione e la rinormalizzazione della struttura dei task. Il modulo qiskit.transpiler è stato riorganizzato per ricostruire i gestori di pass esistenti sulla base del gestore di pass generico. Per maggiori dettagli, consultare le note di aggiornamento.

  • È stato aggiunto un nuovo passaggio di analisi SabrePreLayout che crea un layout iniziale per SabreLayoutscrivendo il layout nel valore del set di proprietà sabre_starting_layouts.

    Il passaggio funziona aumentando la mappa di accoppiamento con un numero sempre maggiore di spigoli "extra" fino a quando VF2Layout riesce a trovare un isomorfismo perfetto del grafo. Più precisamente, la mappa di accoppiamento aumentata contiene spigoli tra nodi che si trovano entro una determinata distanza d nella mappa di accoppiamento originale, e il valore di d viene aumentato finché non viene trovato un isomorfismo. Il passaggio minimizza anche il numero di bordi aggiuntivi coinvolti nel layout fino a trovare un minimo locale. Questo comporta la rimozione di bordi extra e la chiamata a VF2Layout per verificare se esiste ancora un isomorfismo.

    Ecco un esempio di chiamata del metodo SabrePreLayout prima di SabreLayout:

    import math
    from qiskit.transpiler import CouplingMap, PassManager
    from qiskit.circuit.library import EfficientSU2
    from qiskit.transpiler.passes import SabrePreLayout, SabreLayout
    
    qc = EfficientSU2(16, entanglement='circular', reps=6, flatten=True)
    qc.assign_parameters([math.pi / 2] * len(qc.parameters), inplace=True)
    qc.measure_all()
    
    coupling_map = CouplingMap.from_heavy_hex(7)
    
    pm = PassManager(
        [
            SabrePreLayout(coupling_map=coupling_map),
            SabreLayout(coupling_map),
        ]
    )
    
    pm.run(qc)
  • Aggiunti gli argomenti coupling_map, target e use_qubit_indices a HighLevelSynthesis al passaggio del transpiler. L'argomento target specifica il backend del target, consentendo ai plugin di sintesi chiamati all'interno del passaggio di accedere a tutte le informazioni specifiche del target, come la mappa di accoppiamento e il set di gate supportati. L'argomento coupling_map specifica solo la mappa di accoppiamento e viene utilizzato solo quando target non è specificato. L'argomento use_qubit_indices indica se il passaggio di sintesi di alto livello viene eseguito prima o dopo l'impostazione del layout, cioè se gli indici dei qubit degli oggetti di alto livello corrispondono agli indici dei qubit sul backend di destinazione.

  • Aggiunti gli argomenti coupling_map, target e qubits a HighLevelSynthesisPlugin. L'argomento posizionale target specifica il backend del target, consentendo al plugin di accedere a tutte le informazioni specifiche del target, come la mappa di accoppiamento, l'insieme dei gate supportati e così via. L'argomento posizionale coupling_map specifica solo la mappa di accoppiamento e viene utilizzato solo quando target non è specificato. L'argomento posizionale qubits specifica l'elenco di qubit su cui è definito l'oggetto di livello superiore, nel caso in cui la sintesi sia effettuata sul circuito fisico. Il valore None indica che il layout non è ancora stato scelto.

    Ciò consente di separare in modo più netto le opzioni dei plugin di sintesi in opzioni generali dell'interfaccia per i plugin (cioè coupling_map, target, e qubits) e in opzioni specifiche dei plugin (un dizionario di configurazione a forma libera specificato tramite options). Vale la pena notare che questa modifica è retrocompatibile: se le opzioni coupling_map, ecc. non vengono aggiunte esplicitamente al metodo run() del plugin, appariranno come parte di options.

  • I DAGCircuit metodi apply_operation_back() e apply_operation_front() hanno ottenuto un argomento chiave check che può essere impostato su False per saltare la validazione che gli input soddisfino gli invarianti della struttura dei dati DAGCircuit invarianti della struttura dei dati. È utile come ottimizzazione delle prestazioni quando il DAG viene costruito a partire da dati noti, ad esempio durante i passaggi del transpiler.

  • Il metodo CouplingMap.reduce() accetta ora un parametro aggiuntivo check_if_connected, predefinito a True. Ciò corrisponde al comportamento precedente, controllando se la mappa di accoppiamento ridotta rimane connessa e sollevando un CouplingError in caso contrario. Se impostato su False, il controllo viene saltato, consentendo l'uso di mappe di accoppiamento ridotto disconnesse.

  • Il costruttore per HighLevelSynthesis transpiler pass ora accetta argomenti aggiuntivi equivalence_library, basis_gates, e min_qubits. Il passaggio può ora srotolare le definizioni personalizzate in modo simile a quello di UnrollCustomDefinitionse come tale sostituisce completamente la funzionalità di quest'ultimo passaggio. In particolare, HighLevelSynthesis è ora ricorsivo, risolvendo una svista dell'implementazione iniziale. Pertanto, quando vengono specificati target o basis_gates , il sistema sintetizza ricorsivamente tutti gli oggetti di alto livello, le operazioni annotate e le porte personalizzate del circuito, HighLevelSynthesis sintetizza ricorsivamente tutti gli oggetti di alto livello, le operazioni annotate e le porte personalizzate del circuito, lasciando solo le porte supportate dal target o appartenenti alla libreria di equivalenza. Questo permette di utilizzare HighLevelSynthesis come sostituto di UnrollCustomDefinitions. D'altra parte, quando non vengono specificati né targetbasis_gates , il passaggio sintetizza solo gli oggetti di alto livello e le operazioni annotate, cioè non scende ricorsivamente nel campo dei gate personalizzati definition . Questo è retrocompatibile sia con UnrollCustomDefinitions (che non farebbe nulla) sia con il vecchio comportamento del passaggio di sintesi di alto livello, che permette di usarlo come trasformazione intermedia, sintetizzando solo oggetti di alto livello come specificato da HLSConfig.

  • Miglioramento significativo delle prestazioni del passaggio MergeAdjacentBarriers transpiler, che ricostruisce l'intero DAG per unire le barriere.

  • Aggiunto un nuovo argomento di parola chiave, min_qubits, al costruttore del passaggio di BasisTranslator transpiler. Se impostato su un valore diverso da zero, viene utilizzato per impostare un numero minimo di qubit per filtrare le operazioni da tradurre nel circuito. Ad esempio, se min_qubits=3 è impostato, l'istanza BasisTranslator tradurrà solo le porte del circuito che operano su 3 o più qubit.

  • Aggiunto un nuovo argomento di parola chiave, min_qubits, al costruttore del passaggio di UnrollCustomDefinitions transpiler. Se impostato su un valore diverso da zero, viene utilizzato per impostare un numero minimo di qubit per filtrare le operazioni da tradurre nel circuito. Ad esempio, se min_qubits=3 è impostato, l'istanza UnrollCustomDefinitions tradurrà solo le porte del circuito che operano su 3 o più qubit.

  • È stato aggiunto il supporto al passaggio SabreLayout per aggiungere prove con layout di partenza specificati. Il passaggio del SabreLayout il passaggio di transpiler di solito esegue più prove di layout che iniziano tutte con layout completamente casuali e poi usa un passaggio di instradamento per permutare il layout invece di inserire gli swap per trovare un layout che risulti in un minor numero di porte di swap. Questa nuova funzione consente di eseguire un AnalysisPass prima di SabreLayout che imposta il campo "sabre_starting_layout" nell'insieme di proprietà per fornire all'applicazione SabreLayout con ulteriori layout di partenza da utilizzare nelle sue prove interne. Ad esempio, se si vuole eseguire DenseLayout come punto di partenza per una prova in SabreLayout si farebbe una cosa del tipo

    from qiskit.providers.fake_provider import FakeSherbrooke
    from qiskit.transpiler import AnalysisPass, PassManager
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit.transpiler.passes import DenseLayout
    
    class SabreDenseLayoutTrial(AnalysisPass):
    
      def __init__(self, target):
          self.dense_pass = DenseLayout(target=target)
          super().__init__()
    
      def run(self, dag):
          self.dense_pass.run(dag)
          self.property_set["sabre_starting_layouts"] = [self.dense_pass.property_set["layout"]]
    
    backend = FakeSherbrooke()
    opt_level_1 = generate_preset_pass_manager(1, backend)
    pre_layout = PassManager([SabreDenseLayoutTrial(backend.target)])
    opt_level_1.pre_layout = pre_layout

    Poi, quando opt_level_1 StagedPassManager viene eseguito con un circuito, l'uscita del DenseLayout verrà utilizzato per una delle prove SabreLayout in aggiunta alle 5 prove completamente casuali che vengono eseguite per impostazione predefinita nel livello di ottimizzazione 1.

  • Sono stati aggiunti due nuovi passaggi di transpiler per generare calibrazioni di gate RX a impulso singolo al volo. Queste calibrazioni RX a impulso singolo ridurranno il tempo di gate a metà, come descritto in P.Gokhale et al, Optimized Quantum Compilation for Near-Term Algorithms with OpenPulse (2020), arXiv:2004.11205.

    Per ridurre la quantità di dati di calibrazione RX da generare, NormalizeRXAngle esegue tre ottimizzazioni: il wrapping degli RXGate a [0, pi], sostituendo RX(pi/2) e RX(pi) con SXGate e XGatee la quantizzazione degli angoli di rotazione. Questo passaggio deve essere eseguito prima di RXCalibrationBuilderche genera le calibrazioni RX al volo.

    Le ottimizzazioni eseguite da NormalizeRXAngle riducono la quantità di dati di calibrazione e ci permettono di sfruttare gli impulsi calibrati via hardware, più precisi. Le calibrazioni generate da RXCalibrationBuilder sono bootstrappate dalla calibrazione SXGate che dovrebbe essere già presente nel target. L'ampiezza viene scalata linearmente per ottenere l'angolo di rotazione arbitrario desiderato.

    Queste calibrazioni a impulso singolo riducono il tempo dimezzato rispetto alla RXGate tempo dimezzato, rispetto alla sequenza convenzionale che consiste in due SXGate impulsi. La riduzione del tempo di apertura potrebbe comportare un miglioramento della fedeltà.

  • Aggiunti nuovi metodi per TranspileLayout, initial_index_layout() e routing_permutation(), che vengono utilizzati per generare una vista a elenco degli elementi TranspileLayout.initial_layout e TranspileLayout.final_layout rispettivamente. Ad esempio, se l'attributo final_layout era:

    Layout({
      qr[0]: 2,
      qr[1]: 3,
      qr[2]: 0,
      qr[3]: 1,
    })

    allora routing_permutation() restituirà:

    [2, 3, 0, 1]
  • Aggiunto un nuovo metodo a TranspileLayout, initial_virtual_layout(), che è equivalente all'attributo TranspileLayout.initial_layout ma offre la possibilità di filtrare i qubit ancilla che sono stati aggiunti al circuito. Per impostazione predefinita, l'opzione TranspileLayout.initial_layout includerà di solito qualsiasi ancillare aggiunto dal transpiler.

  • Aggiunto un nuovo metodo, final_index_layout() e final_virtual_layout() alla classe TranspileLayout classe. Questi metodi vengono utilizzati per restituire un layout finale (la mappatura dei qubit del circuito di ingresso nella posizione finale dell'uscita). Questo si distingue dall'attributo final_layout che è la permutazione causata dall'instradamento come oggetto Layout oggetto. Il metodo final_index_layout() restituisce un elenco che mostra la posizione di uscita di ciascun qubit nel circuito di ingresso del transpiler. Ad esempio, con un circuito originale:

    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.cx(0, 2)

    e l'output del transpiler era:

    tqc = QuantumCircuit(3)
    tqc.h(2)
    tqc.cx(2, 1)
    tqc.swap(0, 1)
    tqc.cx(2, 1)

    allora l'output di final_index_layout() restituirebbe un elenco di:

    [2, 0, 1]

    L'opzione final_virtual_layout() restituisce questo come oggetto Layout quindi il risultato dell'esempio precedente sarebbe:

    Layout({
      qc.qubits[0]: 2,
      qc.qubits[1]: 0,
      qc.qubits[2]: 1,
    })

Funzionalità di visualizzazione

  • Aggiunta la possibilità di visualizzare le condizioni come espressioni da Expr nel metodo QuantumCircuit.draw() e nella funzione circuit_drawer() funzione quando si visualizzano circuiti che hanno ControlFlowOp istruzioni.

  • Aggiunti gli stili di colore "iqp" e "iqp-dark" per il cassetto dei circuiti matplotlib , che si basano sullo schema di colori IBM Quantum Platform.

  • In TextDrawer, le operazioni costruite da ControlFlowOp, compresi if, else, while, for e switch/case, sia che vengano istanziati direttamente sia che vengano costruiti usando i metodi in QuantumCircuit, ora visualizzeranno completamente i circuiti definiti in ControlFlowOps con le parentesi per delineare i circuiti.

  • Quando si definisce un foglio di stile personalizzato per il cassetto della linea temporale degli impulsi qiskit.visualization.timeline_drawer()le funzioni "generatore" che hanno l'attributo oggetto accepts_program impostato su True riceveranno un argomento parola chiave aggiuntivo program contenente l'intero programma che si sta disegnando QuantumCircuit che si sta disegnando.

  • Le visualizzazioni del plot_gate_map(), plot_coupling_map(). plot_error_map(), e plot_circuit_layout() sono state notevolmente migliorate per il rendering di layout di backend con un gran numero di qubit. Questo risultato è stato ottenuto sfruttando graphviz attraverso la funzione graphviz_draw() di rustworkx per eseguire una disposizione algoritmica del grafo più sofisticata e scalabile per un gran numero di qubit.

    _images/release_notes-1.png

Varie Funzioni

  • È stato aggiunto il supporto per l'espressione del segno di un ParameterExpression. Invece di assegnare un valore concreto e utilizzare numpy.sign o altre funzioni di libreria, l'utente può utilizzare l'istanza della classe ParameterExpression per calcolare il segno e può lavorare con il segno prima che l'espressione sia completamente assegnata.

    Può essere utilizzato come segue:

    from qiskit.circuit import Parameter
    
    b = Parameter("phi")
    sign_value = b.sign()
    print("sign of an unassigned Parameter is: ", sign_value)
    print("Sign of a Parameter assigned to -3 is: ", sign_value.assign(b,-3))

    Per maggiori dettagli, consultare il documento #10360.

  • Parameter ha ora un argomento chiave di uso avanzato uuid nel suo costruttore, che può essere usato per rendere il parametro Parameter sia uguale a un altro dello stesso nome. Non dovrebbe essere utilizzato dagli utenti ed è utile soprattutto per la serializzazione e la deserializzazione personalizzate.

Note sull'aggiornamento dei circuiti

  • Il ControlledGate.definition del risultato del metodo Gate.control() potrebbe essere diverso rispetto alle versioni precedenti. La generazione interna del metodo Gate.control() non utilizza più l'ormai deprecato passaggio del transpiler per generare la sua definizione Unroller per generare la sua definizione e questo può potenzialmente causare la generazione di una definizione diversa. La definizione dell'oggetto ControlledGate sarà unitariamente equivalente a quello generato in precedenza. Ma se si desidera la definizione esatta della chiamata Gate.control() si può usare una versione precedente e salvare il circuito con qpy.dump() e poi caricarlo con una versione più recente.

  • La proprietà num_ancilla_qubits della classe PolynomialPauliRotations è stata rimossa, in quanto deprecata in Qiskit 0.23.0. Utilizzare invece la proprietà PolynomialPauliRotations.num_ancillas.

  • Le seguenti porte della libreria standard:

    non sono più in grado di impostare label, condition, duration, o unit (e ctrl_state per le ControlledGate dopo l'istanziazione di un oggetto. È comunque possibile impostare condition attraverso l'uso c_if(). Si può usare to_mutable() per ottenere una copia mutabile dell'istruzione e poi usare il setter su questa copia invece che sull'oggetto originale. label, duration e unit possono essere dati come argomenti di parola chiave a questi gate al momento della costruzione e un'istanza mutabile sarà restituita automaticamente. Questa modifica si è resa necessaria per convertire queste classi in classi SingletonGate e SingletonControlledGate che riduce notevolmente l'ingombro in memoria delle istanze ripetute di questi gate.

  • Per qualsiasi cosa che interagisca con Gate, Operation, o Instruction o lavora con questi oggetti come parte di un sistema QuantumCircuit o DAGCircuit è importante notare che l'uso di riferimenti condivisi per le istanze è ormai molto più comune. In precedenza, era possibile riutilizzare e condividere un'istanza di un'operazione di circuito, ma non era molto usata e una copia generava un'istanza unica. Questo è cambiato a partire da questa versione a causa di SingletonInstruction e SingletonGate che sono stati resi disponibili (e un gran numero di porte di libreria standard ora costruite a partire da essi). Se l'uso di questi oggetti presuppone istanze uniche per ogni operazione del circuito, questo diventa un potenziale problema, poiché ora uno stato condiviso sarà riutilizzato tra operazioni dello stesso tipo (che persisteranno attraverso copie e copie profonde). Si può fare affidamento sull'attributo Instruction.mutable per verificare la mutabilità di un oggetto o utilizzare l'attributo Instruction.to_mutable() per ottenere una copia mutabile di qualsiasi istruzione.

  • Più Instruction (quelle che restituiscono i singoletti) non soddisfano più strettamente (ad esempio):

    type(XGate()) is XGate

    L'oggetto restituito sarà comunque una sottoclasse standard, quindi il metodo isinstance() (il modo corretto di fare il controllo dei tipi) continuerà a funzionare correttamente. Diverse istruzioni avevano già questa proprietà (ad es. MCXGate), ma ora è più comune, dato che molti cancelli standard sono in grado di farlo.

    Se si richiede il tipo "base" di un gate per qualche motivo, omettendo le sottoclassi sintetiche singleton, che non possono essere istanziate, si veda Instruction.base_class.

  • La definizione di UnitaryGate per gli unitari a singolo qubit è ora in termini di UGate invece della classe precedente U3Gate classe.

Note sull'aggiornamento dei provider

  • Il QasmSimulatorPy basato su python, incluso in qiskit.providers.basicaer include ora 'h' (HGate), 'p' (PhaseGate) e 'u' (UGate) nel suo set di porte base.

  • L'argomento channel nel metodo PulseBackendConfiguration.control() viene rimosso. È stato deprecato in Qiskit 0.33 (con Terra 0.19 ), rilasciato nel dicembre 2021. Utilizzate invece l'argomento qubits .

  • Sostituito l'argomento qobj[Qobj] in QasmSimulatorPy.run() con run_input[QuantumCircuit or list]

    Ecco un esempio di migrazione del codice:

    # Importing necessary Qiskit libraries
    from qiskit import transpile, QuantumCircuit
    from qiskit.aer import QasmSimulator
    
    # Defining the Quantum Circuit
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    # Transpile the circuit to optimize for the target simulator
    simulator = QasmSimulator()
    transpiled_circuit = transpile(qc, simulator)
    # Run the simulation
    job = simulator.run(transpiled_circuit, shots=1024)
    # Get the simulation result
    result = job.result()

    Tutti questi elementi sono stati deprecati da 0.22 (rilasciato il 13 ottobre 2022) e ora sono stati rimossi.

Note sull'aggiornamento Pulse

  • Le funzioni qiskit.scheduler.utils.format_meas_map(), qiskit.scheduler.utils.measure() e qiskit.scheduler.utils.measure_all() sono state spostate rispettivamente in qiskit.pulse.utils.format_meas_map(), qiskit.pulse.macros.measure() e qiskit.pulse.macros.measure_all() . La posizione precedente è stata deprecata in Qiskit 0.20.0 (Terra 0.15.0, rilasciato il 2020-08-10) e non è più supportata.

  • I metodi to_dict nelle classi pulse.transforms.AlignmentKind, pulse.transforms.AlignEquispaced, e pulse.transforms.AlignFunc vengono rimossi. Sono stati deprecati in Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022.

Note sull'aggiornamento QPY

  • L'uso della parola chiave circuits per il primo argomento posizionale della funzione qiskit.qpy.dump() è stato rimosso perché il suo uso è stato deprecato in Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Al suo posto si può usare la parola chiave programs (o semplicemente passare l'argomento in posizione), che si comporta in modo identico.

Note sull'aggiornamento delle informazioni quantistiche

  • Il metodo qiskit.quantum_info.pauli_basis() non accetta più l'argomento pauli_list . È stato deprecato in Qiskit 0.39 (con Terra 0.22 ), rilasciato nell'ottobre 2022.

  • La funzione random_stabilizer_table nel modulo qiskit.quantum_info.random viene rimossa. È stato deprecato in Qiskit 0.39 (con Terra 0.22 ), rilasciato nell'ottobre 2022. Utilizzare invece qiskit.quantum_info.random.random_pauli_list().

  • Le classi qiskit.quantum_info.PauliTable e qiskit.quantum_info.StabilizerTable sono state rimosse. È stata rimossa anche la funzione random_pauli_table() . Sono stati deprecati in Qiskit 0.43 (con Terra 0.24 ), rilasciato nel maggio 2023. Al contrario, si dovrebbe usare PauliList e random_pauli_list().

  • Gli argomenti z e x all'inizializzatore di to Pauli sono stati rimossi, in quanto deprecati in Qiskit Terra 0.17 (rilasciato nell'aprile 2021). Una coppia di x e z deve essere passata posizionalmente come una singola tupla (Pauli((z, x))).

  • L'argomento label all'inizializzatore di Pauli è stato rimosso, in quanto deprecato in Qiskit Terra 0.17 (rilasciato ad aprile 2021). Passare invece l'etichetta in modo posizionale, come ad esempio Pauli("XYZ").

  • L'importazione da qiskit.quantum_info.operators.pauli non è più consentita, poiché è stata deprecata in Qiskit Terra 0.21 (rilasciato a giugno 2022). Importate invece direttamente da qiskit.quantum_info .

Note sull'aggiornamento della sintesi

  • Il parametro order nel synthesis.SuzukiTrotter nel costruttore solleva un'eccezione anziché un avviso di deprecazione quando è impostato su un numero dispari. Le formule del prodotto di Suzuki sono simmetriche e quindi definite solo per ordini pari.

Note sull'aggiornamento del transpiler

  • Come conseguenza degli sforzi di rifattorizzazione del gestore dei passaggi, i controllori di flusso esistenti: FlowControllerLinear, ConditionalController, e DoWhileController sono ora sottoclassi del controllore BaseController. Si noti che questi controllori hanno abbandonato l'implementazione del metodo __iter__() . Ora sono iterabili solo nel contesto di un'esecuzione di un controllore di flusso, che fa passare lo stato di compilazione dopo l'esecuzione di ogni task interno.

  • La funzionalità della classe RunningPassManager è stata sostituita dal nuovo framework di gestione dei passaggi (BasePassManager e BaseController). Il gestore dei passaggi in esecuzione è ora un controllore di flusso stateless (essenzialmente, un alias di FlowControllerLinear), poiché il gestore dei passaggi è responsabile della costruzione della pipeline dei task, mentre il controllore è responsabile dell'esecuzione dei task associati. La sottoclasse di RunningPassManager non è più consigliata e questa classe sarà completamente sostituita dal controllore di flusso nelle prossime versioni.

  • È stata introdotta una nuova classe, WorkflowStatusè stata introdotta per monitorare lo stato del flusso di lavoro del gestore dei passaggi. Questo oggetto portatile viene creato quando il gestore dei passaggi viene eseguito e consegnato ai task sottostanti. In precedenza, questo stato era gestito da RunningPassManager con variabili di istanza.

  • Il transpiler specifico transpiler.PassManager (usato in transpile()) è ora una sottoclasse di passmanager.BasePassManager. Tuttavia, questa modifica della gerarchia delle classi non introduce alcun cambiamento nell'API pubblica.

  • Le eccezioni sollevate durante l'esecuzione del pass-manager ora ereditano dalla nuova versione di PassManagerError. Un fallimento generico del macchinario del gestore di pass solleverà PassManagerError per i gestori di passaggi generici, ma il transpiler specifico transpile.PassManager attualmente avvolgerà questo problema nel suo specifico TranspilerError per compatibilità all'indietro. Questo involucro sarà rimosso in futuro.

  • È stato eliminato l'uso di FencedObject nel framework del gestore dei passaggi. Questa classe wrapper non può proteggere gli attributi mutabili degli oggetti dalla modifica, ma questo non dovrebbe essere un problema per il codice implementato correttamente. I passaggi di analisi non devono modificare un IR di input, i controllori non devono aggiornare il set di proprietà e così via. È responsabilità dello sviluppatore del gestore del passaggio assicurarsi che il passaggio non modifichi gli attributi dell'oggetto,

  • Il nome del plugin default è riservato alle fasi del plugin init, layout, optimization e scheduling. Questi stadi in precedenza non riservavano il nome del plugin, ma il nome default è ora utilizzato per rappresentare il metodo predefinito di Qiskit per questi stadi. Se si utilizzano questi nomi per i plugin su questi stadi, essi entreranno in conflitto con l'uso di Qiskit e sarà necessario rinominare il plugin.

  • Disabilita l'uso della classe RemoveResetInZeroState nei passmanager preimpostati. In precedenza, quando transpile() o generate_preset_pass_manager() veniva eseguito con optimization_level a livello 1, 2 o 3, veniva eseguito RemoveResetInZeroState. Tuttavia, questo passaggio proibiva la nozione di stati iniziali arbitrari, a meno che non fossero esplicitamente impostati su zero con reset. Se è necessario eseguire il passaggio come parte della pipeline di compilazione, si può eseguire qualcosa come:

    pm = generate_preset_pass_manager(1, backend)
    pm.init.append(RemoveResetInZeroState())
    pm.run(circuit)

    per mantenere questa funzionalità per la compilazione dei circuiti.

  • Il passaggio di routing del transpiler deprecato, BIPMapping , è stato rimosso. È stato contrassegnato come deprecato nella versione di Qiskit 0.43.0. È stato sostituito da un pacchetto di plugin esterni: qiskit-bip-mapper. I dettagli di questo nuovo pacchetto sono disponibili nel repository github del pacchetto:

    https://github.com/qiskit-community/qiskit-bip-mapper

    Il passaggio è stato trasformato in un pacchetto di plugin separato per due motivi: in primo luogo, la dipendenza da CPLEX lo rende più difficile da usare e, in secondo luogo, il pacchetto di plugin si integra in modo più pulito con transpile(). L'extra opzionale bip-mapper per installare cplex e docplex per supportare questo passaggio è stato rimosso poiché nulla in Qiskit lo richiede più.

  • L'argomento qubits nel metodo InstructionDurations.get()non accetta più Qubit (o un elenco di essi). Questa funzionalità è stata deprecata in Qiskit 0.33 (con Terra 0.19 ), rilasciato nel dicembre 2021. Si utilizza invece un numero intero per gli indici dei qubit.

  • Rimosso l'argomento qubit_channel_mapping in RZXCalibrationBuilderche era deprecato in Qiskit 0.39 (rilasciato nell'ottobre 2022, con qiskit-terra 0.22 )

  • In transpiler.CouplingMap il metodo subgraph viene rimosso in quanto deprecato in 0.20. reduce() può essere utilizzato al posto del metodo subgraph.

Note sull'aggiornamento della visualizzazione

  • Rimosso il supporto all'uso della parola chiave rho per il primo argomento posizionale in plot_state_hinton(), plot_bloch_multivector(), plot_state_city(), plot_state_paulivec(), e plot_state_qsphere(). L'uso di rho è stato sostituito da state, che può essere utilizzato al suo posto. Rimosso qiskit.scheduler.utils poiché tutte le funzioni contenute sono state spostate in qiskit.pulse.macros e qiskit.pulse.utils. Tutti questi elementi sono stati deprecati da 0.15 (rilasciato il 06 agosto 2020) e ora sono stati rimossi.

  • Gli argomenti del costruttore di classe qregs, cregs, layout e global_phase per visualization.QCircuitImage sono stati rimossi, in quanto deprecati in 0.20.

  • Le funzioni di visualizzazione: plot_gate_map(), plot_coupling_map(). plot_error_map(), e plot_circuit_layout() dipendono ora dall'installazione di graphviz per funzionare. Questa modifica si è resa necessaria per consentire la visualizzazione di backend con un numero maggiore di qubit. Questo ulteriore requisito esterno si aggiunge alle dipendenze opzionali già esistenti che queste funzioni richiedevano in precedenza. I dettagli su come installare graphviz sono disponibili qui: https://graphviz.org/download/

Varie Note sull'aggiornamento

  • I QuasiDistribution potrebbero includere errori in virgola mobile. QuasiDistribution.__repr__ con numpy.round() e il parametro ndigits può essere manipolato con l'attributo di classe __ndigits__. L'impostazione predefinita è 15.

  • La classe qiskit.qobj.Qobj viene rimossa. È stato deprecato in Qiskit 0.33 (con Terra 0.19 ), rilasciato nel dicembre 2021. Al contrario, utilizzare qiskit.qobj.QasmQobj o qiskit.qobj.PulseQobj.

  • Il decoratore qiskit.utils.deprecation.deprecate_function() è stato deprecato da Qiskit 0.39.0 (rilasciato nell'ottobre 2022, con qiskit-terra 0.22.0 ) e ora è stato rimosso. Utilizzare qiskit.utils.deprecate_func() invece.

  • La funzione execute() non accetta più gli argomenti qobj_id e qobj_header . Il loro uso è stato deprecato in Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022.

  • Il passo di transpilazione qiskit.transpiler.passes.CXDirection viene rimosso. Il suo uso è stato deprecato in Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Invece, utilizzare il più generico GateDirection pass.

  • Il passo di transpilazione qiskit.transpiler.passes.CheckCXDirection viene rimosso. Il suo uso è stato deprecato in Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Invece, utilizzare il più generico CheckGateDirection pass.

  • La compilazione di Qiskit dai sorgenti richiede ora un compilatore Rust compatibile con la versione del linguaggio 1.64. Questa versione è stata aumentata rispetto alla precedente versione minima di Rust supportata da 1.61 per la creazione di versioni precedenti di Qiskit.

Deprecazioni degli algoritmi

  • Gli algoritmi di utilità in qiskit.utils.validation e qiskit.utils.algorithm_globals sono ora deprecati e saranno rimossi entro 3 mesi dalla data di rilascio. Questi strumenti sono stati introdotti con il modulo qiskit.algorithms per supportare i flussi di lavoro degli algoritmi legacy e primitivi. Ora che qiskit.algorithms è deprecato e la base di codice degli algoritmi basati sulle primitive è stata migrata in una libreria indipendente, questi strumenti non sono più utilizzati nel contesto di Qiskit. Se la vostra applicazione lo consente, vi consigliamo di migrare il vostro codice all'uso di qiskit_algoritmi, dove sarete in grado di importare le utilità pertinenti in algorithm_globals e validation da qiskit_algorithms.utils. Si noti che le funzionalità precedenti non sono state migrate al nuovo pacchetto.

Circuiti deprecati

Deprecazioni del transpiler

  • Il metodo di fabbrica del controllore di flusso FlowController.controller_factory() è deprecato insieme a FlowController.add_flow_controller() e FlowController.remove_flow_controller(). In futuro, la costruzione di task con argomenti di parole chiave nel metodo BasePassManager.append() sarà anch'essa deprecata. I controllori devono essere istanziati esplicitamente e aggiunti al gestore dei passaggi. Ad esempio, la sintassi convenzionale precedentemente utilizzata

    pm.append([task1, task2], condition=lambda x: x["value1"] > 10)

    deve essere sostituito con

    controller = ConditionalController([task1, task2], condition=lambda x: x["value1"] > 10)
    pm.append(controller)

    Quest'ultima permette un controllo più preciso sull'ordine dei controllori, soprattutto quando vengono specificati più argomenti di parole chiave insieme, e consente di costruire controllori di flusso generali che possono avere più di una pipeline o che non accettano una singola funzione condizionale semplice nei loro costruttori.

  • Il FlowControllerLinear.append(), DoWhileController.append(), e ConditionalController.append() sono tutti deprecati immediatamente. La costruzione della pipeline di task del gestore del passaggio è ora compito di BasePassManagere i singoli controllori di flusso non hanno bisogno di questo metodo. Per un controllore di flusso, tutti i passaggi dovrebbero essere specificati in una sola volta direttamente nel costruttore.

  • Il nome generale di attributi e variabili passes è sostituito da tasks in tutto il modulo qiskit.passmanager modulo. Si noti che un task deve indicare l'unione di pass e controller e la forma singolare pass è in conflitto con la parola chiave Python. In questo senso, l'uso dei compiti è di gran lunga preferibile.

  • Il passaggio Unroller è stato deprecato e sarà rimosso in una prossima versione. Il Unroller è stata sostituita dalla funzione BasisTranslator che fornisce una serie di funzionalità simili, ma le offre in modo più generale, in modo da poter tradurre un circuito in qualsiasi insieme di basi universali. La classe Unroller funziona solo in situazioni in cui le definizioni dei gate del circuito sono definite ricorsivamente in termini di base di destinazione; per i gate della libreria standard di Qiskit questo significa UGate e CXGate. Se si utilizza il pass Unroller può essere sostituito utilizzando un gestore di pass personalizzato del modulo:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import UnrollCustomDefinitions, BasisTranslator
    from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel
    
    pm = PassManager(
        [
            UnrollCustomDefinitions(sel, basis_gates=basis_gates),
            BasisTranslator(sel, target_basis=basis_gates),
        ]
    )
    pm.run(circuit)
  • L'uso del valore "unroller" per l'argomento della parola chiave translation_method nei comandi transpile() e generate_preset_pass_manager() è stato deprecato. Questo plugin per la fase di traduzione sarà rimosso da Qiskit in una prossima versione, poiché è stato sostituito dal metodo predefinito "translator" che funzionerà in modo simile al plugin "unroller" , ma supporterà un insieme più ampio di backend di destinazione.

Deprecazioni relative alla visualizzazione

  • L'impostazione predefinita del cassetto matplotlib ora emette un FutureWarning, poiché lo stile predefinito sta passando allo stile "iqp" (precedentemente noto come "iqx"). Il vecchio default è disponibile come stile "clifford" . Per tacitare l'avviso, è possibile impostare esplicitamente lo stile desiderato, ad es. g.:

    from qiskit import QuantumCircuit
    
    circuit = QuantumCircuit(2)
    circuit.x(0)
    circuit.h(0)
    circuit.cp(0.5, 0, 1)
    
    circuit.draw("mpl", style="clifford")  # or style="iqp"
  • Il passaggio di un circuito a qiskit.visualization.timeline_drawer() che non ha informazioni sull'orario di inizio del nodo programmato è deprecato. Solo i circuiti che sono stati sottoposti a uno dei passaggi di analisi della schedulazione (ad esempio ALAPScheduleAnalysis o ASAPScheduleAnalysis) possono essere visualizzati. Se si è utilizzato uno dei passaggi di programmazione di vecchio tipo (ad esempio ALAPSchedule o ASAPSchedule), è possibile propagare le informazioni di pianificazione eseguendo:

    from qiskit import transpile
    from qiskit.transpiler import InstructionDurations
    
    scheduled = transpile(
      my_old_style_circuit,
      optimization_level=0,
      scheduling_method="alap",
      instruction_durations=InstructionDurations(),
    )

    Questo comportamento era già stato previsto come deprecato in Qiskit 0.37, ma a causa di un bug nell'avviso, non è stato mostrato agli utenti fino ad ora. Il comportamento sarà rimosso in Qiskit 1.0.

Correzioni di bug

  • Il numero massimo di qubit da considerare per la verifica della commutatività basata sulla moltiplicazione matriciale in CommutationChecker è ora limitato a 3 per impostazione predefinita. Corretto #10488

  • Il passaggio GateDirection utilizza ora traduzioni a basi discrete, anziché affidarsi a una traduzione continua RYGateche dovrebbe contribuire a rendere un po' più affidabili alcuni obiettivi a basi discrete. In generale, transpile() ha un supporto solo parziale per gli insiemi di basi che non contengono un'operazione a parametrizzazione continua, quindi non sempre riesce a ottenere risultati ottimali in queste situazioni.

  • Fissa CommutationAnalysis per raggruppare le porte di un filo in insiemi, dove ogni insieme contiene solo porte che si scambiano a coppie. Questo impedisce a CommutationCancellation di eseguire ottimizzazioni non corrette. Vedere #8020

  • CUGate si comporterà correttamente durante le chiamate a QuantumCircuit.assign_parameters(). In precedenza, causava vari errori strani, spesso qualche tempo dopo l'assegnazione iniziale del circuito. Vedere #7326, #7410, #9627, #10002 e #10131.

  • L'interfaccia del costruttore del flusso di controllo (le forme di gestore del contesto di QuantumCircuit.if_test(), while_loop(), for_loop() e switch()) ora terrà correttamente traccia di un avanzamento separato della fase globale all'interno di quel blocco. È possibile aggiungere un avanzamento di fase globale a un blocco interno assegnando a QuantumCircuit.global_phase all'interno di un ambito del costruttore:

    from math import pi
    from qiskit import QuantumCircuit
    
    qc = QuantumCircuit(3, 3)
    qc.global_phase = pi / 2  # Set the outer circuit's global phase.
    
    with qc.if_test((qc.clbits[0], False)) as else_:
      # The global phase advancement in a control-flow block begins at 0,
      # because it represents how much the phase will be advanced by an
      # execution of the block.  The defined phase of the outer scope is not
      # affected by this set.
      qc.global_phase = pi
    with else_:
      # Similarly, the `else` block may induce a different global-phase
      # advancement to the `if`, so it can also be set separately.
      qc.global_phase = 1.5 * pi
    
    # The phase advancement caused directly by the outer scope is independent
    # of the phase advancement conditionally caused by each control-flow path.
    assert qc.global_phase == pi / 2

    Il significato di QuantumCircuit.global_phase è l'avanzamento della fase globale inerente a una singola esecuzione del blocco. Si tratta comunque di un avanzamento di fase globale, nel senso che se il blocco viene inserito, la fase di tutti i qubit dell'intero programma verrà anticipata.

  • Correggere la colorazione degli schemi di colore di "iqx" e "iqx-dark" matplotlib, che in precedenza disegnavano gli schemi di colore di RZGate, RZZGate, (multi)controllato PhaseGatee iSwapGate nel colore sbagliato.

  • L'hash di a Parameter è ora uguale agli hash di qualsiasi elemento ParameterExpression a cui si confronta. In precedenza gli hashtag erano diversi, il che causava voci aggiuntive spurie nelle hashmap quando Parameter e ParameterExpression erano mescolati nella stessa mappa, violando il modello di dati di Python.

  • Corretto un bug nella serializzazione di QPY (qiskit.qpy) in cui le porte unitarie controllate in un circuito potevano risultare in una mancata deserializzazione. Corretto #10802.

  • Corregge l'implementazione di random_statevector() in modo da campionare dalla distribuzione uniforme.

  • Il passaggio NoiseAdaptiveLayout ora accetta CouplingMap come argomento opzionale. Viene utilizzato dal plugin per controllare l'incoerenza tra i file configuration() e properties()come nel caso di FakeMelbourne. Corretto #7677.

  • I metodi QuantumCircuit.copy() e copy_empty_like() sollevano ora un errore se l'argomento name è digitato in modo errato, invece di generare un circuito non valido.

  • L'euristica "decay" di SabreSwap e SabreLayout ora tiene conto correttamente della profondità sui qubit fisici, invece di tenere conto erroneamente della "profondità" degli swap sui qubit virtuali.

  • Corretta una svista nel file ECRGate che impediva di impostare un attributo ECRGate.label al momento della costruzione dell'oggetto. Tutte le altre Gate consentono di impostare un argomento della parola chiave label nel costruttore.

  • Corretta una svista nel costruttore Gate (e delle sottoclassi della libreria standard) in cui i parametri duration e unit non potevano essere impostati come argomenti di parole chiave durante la costruzione. La classe madre Instruction supportava questa impostazione, ma Gate non esponeva correttamente questa interfaccia.

  • Aggiunto il supporto per consentire l'inizializzazione predefinita di SparsePauliOp passando un iterabile vuoto ai metodi statici from_list() e from_sparse_list(). Corretto #10159.

  • L'uso della classe (deprecata) Optimizer su AQC non aveva un percorso alternativo non deprecato, che avrebbe dovuto essere introdotto in Qiskit 0.44. Ora accetta un callable che implementa il protocollo Minimizer come esplicitamente indicato nell'avviso di deprecazione. Il callable può avere un aspetto simile al seguente esempio:

    from scipy.optimize import minimize
    from qiskit.transpiler.synthesis.aqc.aqc import AQC
    
    optimizer = partial(minimize, args=(), method="L-BFGS-B", options={"maxiter": 200})
    aqc = AQC(optimizer=optimizer)
  • Corretto un problema con la classe Barrier classe. Quando si aggiunge un'istanza Barrier a un'istanza QuantumCircuit con il metodo QuantumCircuit.append() in precedenza non veniva convalidata la corrispondenza tra la dimensione della barriera e i qarg specificati.

  • Il passaggio del transpiler BlockCollapser ora gestisce correttamente i circuiti che contengono più di una condizione sullo stesso registro classico.

  • BlueprintCircuit le sottoclassi ora si comportano correttamente quando il metodo semi-pubblico QuantumCircuit._append() viene usato con il blueprint in uno stato non costruito, cioè il circuito viene costruito prima di tentare l'append.

  • Regolato lo zoom, la dimensione dei caratteri e i margini in plot_state_city() per adattarsi meglio alla trama per le dimensioni delle figure. Corretto il comportamento dell'ordinamento Z delle barre e del piano di ampiezza zero e corretta la visualizzazione delle barre con valore reale negativo.

Altre note

  • Questa versione di Qiskit è esplicitamente legata alla serie Numpy 1.x, perché include estensioni compilate che non sono ancora state compilate con la serie Numpy 2.x, non ancora rilasciata. Rilasceremo una nuova versione di Qiskit con il supporto di Numpy 2.x non appena sarà possibile.

    Non possiamo impedire al vostro gestore di pacchetti di risolvere il problema con versioni precedenti di Qiskit (che non hanno lo stesso pin, ma sono comunque probabilmente incompatibili) se cercate di installare forzatamente Qiskit insieme a Numpy 2, prima che abbiamo rilasciato una versione compatibile.

  • Modificato il comportamento degli elementi VF2Layout e VF2PostLayout che in precedenza eseguivano il loro scoring interno in multithreading se i circuiti di ingresso erano sufficientemente grandi. L'uso del multithreading è stato rimosso dai passaggi, poiché si è dimostrato che causava una regressione delle prestazioni invece di un miglioramento come originariamente previsto.

Questa pagina è stata utile?
Segnala un bug, un errore di battitura o richiedi contenuti su GitHub.