Skip to main content
IBM Quantum Platform

Note di rilascio di Qiskit 1.0


1.0.2

Preludio

Qiskit 1.0.2 è una versione con correzione di bug minori per la serie 1.0.

Correzioni di bug

  • È stato risolto un problema con 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.

  • 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 operators è un elenco vuoto. In precedenza si verificava un errore.

  • Corretto un problema di coerenza con EvolvedOperatorAnsatz con istanze con zero qubit. In precedenza, tali istanze contenevano un singolo elemento QuantumRegister in qregs con zero qubit, ma ora non viene creato alcun registro. Questo comportamento si allinea più coerentemente con la sua superclasse QuantumCircuit.

  • Corretto un arresto anomalo in convert_to_target() che si verificava quando mancavano le proprietà dei qubit ( T1, T2 o la frequenza). I valori mancanti delle proprietà in QubitProperties sono ora riempiti con None.

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

  • È stato risolto un bug per cui EstimatorPub.coerce() e SamplerPub.coerce() gestivano impropriamente un parametro di tipo BindingsArray. In precedenza veniva sollevata erroneamente un'eccezione ValueError .

  • I gestori di passaggi preimpostati utilizzati da transpile() non falliranno più sui circuiti con flusso di controllo quando 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.

  • Corretto coerce() in modo che restituisca un array 0-d quando l'input è un singolo osservabile non annidato. In precedenza, è stato erroneamente aggiornato a una sola dimensione, con la forma (1,).

  • 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 QuantumCircuit.draw() che causava la modifica dei dizionari di stile personalizzati per il cassetto Matplotlib al momento dell'esecuzione.


1.0.1

Preludio

Qiskit 1.0.1 è una release di patch che corregge un piccolo numero di bug identificati nella release Qiskit 1.0.0.

Correzioni di bug

  • 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 un pulse.Waveform come dovrebbe. Corretto #11828.

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

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

  • È stato risolto un problema in convert_durations_to_dt() , dove la funzione presumeva che gli input fossero tutti in secondi, invece di leggere l'unità effettiva. Questo potrebbe portare a ordini di grandezza errati nelle durate dei circuiti riportate.


1.0.0

Preludio

Siamo molto lieti di rilasciare Qiskit 1.0.0. Questo rilascio è il culmine di 7 anni di sviluppo per far maturare Qiskit in un SDK stabile e ad alte prestazioni per il calcolo quantistico, ed è l'inizio di una nuova era per il progetto e la comunità di Qiskit. Oltre ai miglioramenti generali delle prestazioni e della stabilità, i cambiamenti più significativi apportati dalla versione 1.0.0 riguardano la politica di stabilità, i cicli di rilascio e la gestione delle versioni. Qiskit utilizza ora formalmente il versioning semantico e questo significa che, per l'intero ciclo di vita della serie di release 1.x, il progetto si impegna a mantenere la retrocompatibilità delle sue API documentate pubblicamente. Stiamo anche iniziando a offrire il supporto per la correzione dei bug per le versioni principali, in modo da continuare ad avere un ramo supportato per 6 mesi dopo il rilascio della versione principale successiva. Questo inizia ora con le serie maggiori 1.x e 0.x : la release 0.46.x continuerà ad essere supportata, con rilasci periodici di patch contenenti correzioni di bug, per 6 mesi dopo il rilascio di 1.0. Ovvero, 0.46.x sarà supportato fino al 2024-08. Potete consultare i dettagli completi della nuova politica qui:

start/installazione#qiskit-versioning

Di fondamentale importanza in questa release è anche la modifica del packaging. Dal rilascio di Qiskit 0.7 nel 2018-12, quando Qiskit ha introdotto il suo modello di elementi, il pacchetto qiskit che si installa è un meta-pacchetto (o pacchetto di pacchetti) che installa gli elementi combinati che compongono Qiskit. Come annunciato nelle versioni precedenti (per maggiori dettagli si veda il documento 0.44.0, 0.45.3, e 0.46.0 insieme a questo post ) con il rilascio 1.0 stiamo completando la transizione per avere un singolo pacchetto qiskit che esponga solo l'SDK di base (quello che prima era qiskit-terra). Questo significa che per i rilasci >= 1.0.0, abbiamo smesso di usare il pacchetto qiskit-terra e pubblicheremo solo qiskit. Poiché questo cambiamento nella struttura dei pacchetti non è pienamente supportato dall'installatore del pacchetto Python pip, non è possibile utilizzare semplicemente pip install -U qiskit per aggiornare da qiskit 0.46.0 a 1.0.0. Per l'aggiornamento a Qiskit 1.0.0 si consiglia vivamente di creare un ambiente virtuale separato per isolare l'installazione. È disponibile una guida dettagliata alla migrazione che spiega le modifiche al packaging e come installare Qiskit 1.0.0 in diversi scenari, consultabile qui:

https://qisk.it/1-0-packaging-migration

Come tutte le nostre principali release, anche Qiskit 1.0.0 presenta una pletora di nuove funzionalità:

  • La QuantumCircuit struttura interna della classe data è stata riscritta in Rust per migliorare notevolmente l'efficienza della memoria degli oggetti QuantumCircuit degli oggetti, mettendo in cache gli argomenti delle istruzioni.
  • Una nuova versione della definizione dell'interfaccia delle primitive in qiskit.primitives con gli elementi BaseSamplerV2 e BaseEstimatorV2 classi astratte. Questa nuova versione dell'interfaccia aggiunge il supporto per l'esecuzione di chiamate vettoriali alla primitiva, in modo da poter specificare in modo efficiente gli sweep sugli insiemi di valori dei parametri e sugli osservabili.
  • Un nuovo parser sperimentale nativo di OpenQASM 3 qiskit.qasm3.loads_experimental() e qiskit.qasm3.load_experimental(). Questo nuovo parser è ancora in fase di sviluppo e presenta ancora diverse limitazioni ed è ancora sperimentale. Tuttavia, per i casi in cui è utilizzabile, il nuovo parser è significativamente più veloce e presenta un migliore messaggio di errore diagnostico che consente di individuare i casi in cui un programma OpenQASM 3 non è valido. Questo nuovo parser è scritto in Rust e si basa su una libreria Rust di recente sviluppo per il parsing di OpenQASM3, che si può trovare qui: https://github.com/Qiskit/openqasm3_parser

Infine, il rilascio di Qiskit 1.0.0 è stata l'occasione per ripulire alcuni debiti tecnici accumulati negli ultimi 7 anni di sviluppo. Noterete che la release di Qiskit 1.0.0 è praticamente priva di DeprecationWarninge, allo stesso tempo, la sezione dedicata agli aggiornamenti delle note di rilascio di 1.0.0 è più lunga del solito. Queste sono conseguenze dirette della pulizia del debito tecnico. Per agevolare la migrazione da 0.46.x a 1.0.0, oltre alle note di rilascio, abbiamo pubblicato una guida alla migrazione dedicata, disponibile qui:

Qiskit 1.0 modifica le funzionalità

Questa guida intende integrare le note di rilascio e fornire consigli mirati su come migrare le modifiche all'API dopo la rimozione delle funzionalità deprecate dalla release 0.46.0.

Caratteristiche dei circuiti

  • Aggiunto un nuovo argomento, annotated, ai metodi QuantumCircuit.inverse(), circuit.Instruction.inverse() e .inverse() dei metodi delle Instruction (come ad esempio SwapGate o SGate) per restituire facoltativamente un parametro AnnotatedOperation. Il valore predefinito di annotated è False e corrisponde al comportamento preesistente del metodo. Inoltre, per le porte standard con un metodo inverse esplicitamente definito, l'argomento annotated non ha alcun effetto, ad esempio entrambi:

    SwapGate().inverse(annotated=False)
    SwapGate().inverse(annotated=True)

    restituire un SwapGateed entrambi:

    SGate().inverse(annotated=False)
    SGate().inverse(annotated=True)

    restituire un SdgGate. La differenza si manifesta per le istruzioni personalizzate senza un inverso esplicitamente definito. Con annotated=False, il metodo restituisce una nuova istruzione con la definizione ricorsivamente invertita, proprio come prima. Mentre annotated=True restituisce un oggetto AnnotatedOperation che rappresenta l'istruzione modificata con l'opzione InverseModifier.

  • Aggiunta di una libreria di commutazione al file CommutationChecker. Questa libreria memorizza tutte le relazioni di commutazione delle porte standard non parametrizzabili in un dizionario che consente una ricerca efficiente in fase di esecuzione. Questo accelera l'esecuzione della classe CommutationChecker e, per estensione, del passaggio del transpiler CommutationAnalysis invece di calcolare se due porte standard, non parametrizzabili, sono in commutazione, deve solo cercarle nella libreria.

    Inoltre, la funzione CommutationChecker è stato rifattorizzato e ora ha un limite massimo al numero di relazioni di commutazione memorizzate nella cache che non sono presenti nella libreria di commutazione. Questo ha riguardato: #8020 e #7101

  • QuantumCircuit.assign_parameters() accetta ora chiavi stringa nella forma di mappatura dell'input. Questi nomi sono usati per cercare l'istanza corrispondente Parameter utilizzando get_parameter(). Questo vi permette di fare:

    from qiskit.circuit import QuantumCircuit, Parameter
    
    a = Parameter("a")
    qc = QuantumCircuit(1)
    qc.rx(a, 0)
    
    qc.assign_parameters({"a": 1}) == qc.assign_parameters({a: 1})
  • QuantumCircuit ha due nuovi metodi, get_parameter() e has_parameter()che recuperano rispettivamente un'istanza Parameter utilizzata nel circuito in base al nome e restituiscono un booleano che indica se un parametro con un nome corrispondente (o l'istanza esatta fornita) è utilizzato nel circuito.

  • A uuid è stata aggiunta alla classe qiskit.circuit.Parameter classe. Nei casi d'uso avanzati, questa proprietà può essere utilizzata per creare istanze qiskit.circuit.Parameter che si confrontano tra loro.

  • Aggiunto un nuovo metodo, ParameterExpression.numeric()che converte un'espressione di parametro completamente vincolata nel tipo numerico incorporato Python più restrittivo che descrive accuratamente il risultato della valutazione simbolica. Ad esempio, un numero intero simbolico diventerà un numero intmentre un numero reale simbolico diventerà un numero float e un numero complesso diventerà a complex. Questo metodo include diversi workaround per le peculiarità dei contesti di valutazione di symengine, che a volte possono portare a risultati spuri quando si chiama complex o float su un'espressione direttamente.

Caratteristiche primitive

  • La versione 2 delle primitive viene introdotta tramite una nuova classe di base sia per il campionatore che per lo stimatore, insieme a nuovi tipi per i loro ingressi e uscite. L'enfasi di questa nuova versione è sull'esecuzione di chiamate vettoriali ai metodi primitivi di run() , in modo da poter specificare in modo efficiente gli sweep sugli insiemi di valori dei parametri e sulle osservabili. Vedere StatevectorSampler e StatevectorEstimator per le implementazioni di riferimento delle primitive di V2.

    Inoltre, lo stimatore ha ottenuto un argomento precision nel metodo run() che specifica la precisione desiderata delle stime del valore di aspettativa. Analogamente, il campionatore ha spostato shots dalle opzioni agli argomenti del metodo run() del metodo. Il campionatore è stato modificato anche per restituire gli output (ad esempio, bitstring) di ogni colpo, invece di fornire un ritorno simile a Counts-e anche per memorizzare i dati provenienti da file separati di ClassicalRegisters. Ciò consente alle classi derivate di implementare il supporto del campionatore per i circuiti con flusso di controllo classico.

    Le classi base primitive di V2 sono:

    I nuovi tipi utilizzati per gli ingressi e le uscite sono:

    • SamplerPubLike: blocco unificato primitivo ( PUB ) di ingressi al campionatore; un tipo di unione di ingressi consentiti a un campionatore
    • EstimatorPubLike: Blocco primitivo unificato ( PUB ) di ingressi allo stimatore; un tipo di unione di ingressi consentiti a uno stimatore
    • PubResult: i dati e i metadati risultanti dall'esecuzione di un singolo PUB
    • DataBin: Uno spazio dei nomi per contenere i dati di una singola esecuzione di PUB
    • BitArray: una collezione di valori di bit in formato denso, a forma di array
    • PrimitiveResult: un iterabile di PubResultcon i metadati
  • L'implementazione di riferimento StatevectorEstimator di BaseEstimatorV2 è stata aggiunta. Come si vede nell'esempio seguente, questo stimatore (e tutti gli stimatori di V2 ) supporta la fornitura di array di osservabili e/o array di set di valori di parametri collegati a particolari circuiti.

    Ogni tupla di (circuit, observables, <optional> parameter values, <optional> precision), chiamata blocco primitivo unificato di stima ( PUB ), produce il proprio risultato basato su array. Il metodo run() può essere applicato a molti pub contemporaneamente.

    from qiskit.circuit import Parameter, QuantumCircuit
    from qiskit.primitives import StatevectorEstimator
    from qiskit.quantum_info import Pauli, SparsePauliOp
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define a circuit with two parameters.
    circuit = QuantumCircuit(2)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(0, 1)
    circuit.h(0)
    
    # Define a sweep over parameter values, where the second axis is over
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Define three observables. Many formats are supported here including
    # classes such as qiskit.quantum_info.SparsePauliOp. The inner length-1
    # lists cause this array of observables to have shape (3, 1), rather
    # than shape (3,) if they were omitted.
    observables = [
        [SparsePauliOp(["XX", "IY"], [0.5, 0.5])],
        [Pauli("XX")],
        [Pauli("IY")]
    ]
    
    # Instantiate a new statevector simulation based estimator object.
    estimator = StatevectorEstimator()
    
    # Estimate the expectation value for all 300 combinations of
    # observables and parameter values, where the pub result will have
    # shape (3, 100). This shape is due to our array of parameter
    # bindings having shape (100,), combined with our array of observables
    # having shape (3, 1)
    pub = (circuit, observables, params)
    job = estimator.run([pub])
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # Error-bar information is also available, but the error is 0
    # for this StatevectorEstimator.
    result.data.stds
    
    # Pull out the array-based expectation value estimate data from the
    # result and plot a trace for each observable.
    for idx, pauli in enumerate(observables):
        plt.plot(result.data.evs[idx], label=pauli)
    plt.legend()
  • L'implementazione di riferimento StatevectorSampler di BaseSamplerV2 è stata aggiunta. Come si vede nell'esempio seguente, questo campionatore (e tutti i campionatori di V2 ) supporta la fornitura di array di set di valori di parametri da associare a un singolo circuito.

    Ogni tupla di (circuit, <optional> parameter values, <optional> shots), chiamata blocco primitivo unificato di campionamento ( PUB ), produce il proprio risultato basato su array. Il metodo run() può essere applicato a molti pub contemporaneamente.

    from qiskit.circuit import (
        Parameter, QuantumCircuit, ClassicalRegister, QuantumRegister
    )
    from qiskit.primitives import StatevectorSampler
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Define our circuit registers, including classical registers
    # called 'alpha' and 'beta'.
    qreg = QuantumRegister(3)
    alpha = ClassicalRegister(2, "alpha")
    beta = ClassicalRegister(1, "beta")
    
    # Define a quantum circuit with two parameters.
    circuit = QuantumCircuit(qreg, alpha, beta)
    circuit.h(0)
    circuit.cx(0, 1)
    circuit.cx(1, 2)
    circuit.ry(Parameter("a"), 0)
    circuit.rz(Parameter("b"), 0)
    circuit.cx(1, 2)
    circuit.cx(0, 1)
    circuit.h(0)
    circuit.measure([0, 1], alpha)
    circuit.measure([2], beta)
    
    # Define a sweep over parameter values, where the second axis is over.
    # the two parameters in the circuit.
    params = np.vstack([
        np.linspace(-np.pi, np.pi, 100),
        np.linspace(-4 * np.pi, 4 * np.pi, 100)
    ]).T
    
    # Instantiate a new statevector simulation based sampler object.
    sampler = StatevectorSampler()
    
    # Start a job that will return shots for all 100 parameter value sets.
    pub = (circuit, params)
    job = sampler.run([pub], shots=256)
    
    # Extract the result for the 0th pub (this example only has one pub).
    result = job.result()[0]
    
    # There is one BitArray object for each ClassicalRegister in the
    # circuit. Here, we can see that the BitArray for alpha contains data
    # for all 100 sweep points, and that it is indeed storing data for 2
    # bits over 256 shots.
    assert result.data.alpha.shape == (100,)
    assert result.data.alpha.num_bits == 2
    assert result.data.alpha.num_shots == 256
    
    # We can work directly with a binary array in performant applications.
    raw = result.data.alpha.array
    
    # For small registers where it is anticipated to have many counts
    # associated with the same bitstrings, we can turn the data from,
    # for example, the 22nd sweep index into a dictionary of counts.
    counts = result.data.alpha.get_counts(22)
    
    # Or, convert into a list of bitstrings that preserve shot order.
    bitstrings = result.data.alpha.get_bitstrings(22)
    print(bitstrings)

Funzionalità dei fornitori

  • Aggiunta di una nuova classe, GenericBackendV2, al modulo qiskit.providers.fake_provider al modulo. Questa classe è configurabile e costruisce un'istanza di backend che può essere eseguita localmente (nello spirito dei falsi backend) BackendV2 che può essere eseguito localmente (nello spirito dei falsi backend). Gli utenti possono configurare il numero di qubit, le porte di base, la mappa di accoppiamento, la capacità di eseguire circuiti dinamici (istruzioni di flusso di controllo), le calibrazioni delle istruzioni e i tempi di misurazione del backend senza dover ricorrere alla costruzione manuale dei target. Le proprietà del Qubit e del gate (durata, errore) sono generate con un campionamento casuale da intervalli predefiniti. Il seme per questa generazione casuale può essere fissato per garantire la riproducibilità dell'output del backend. È importante notare che questo backend supporta solo le porte della libreria standard. Se si ha bisogno di un backend più flessibile, c'è sempre la possibilità di istanziare direttamente un oggetto Target da usare per la trasposizione.

    Esempio di utilizzo 1:

    from qiskit import QuantumCircuit, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a simple circuit
    circuit = QuantumCircuit(3)
    circuit.h(0)
    circuit.cx(0,1)
    circuit.cx(0,2)
    circuit.measure_all()
    circuit.draw('mpl')
    
    # Define backend with 3 qubits
    backend = GenericBackendV2(num_qubits=3)
    
    # Transpile and run
    transpiled_circuit = transpile(circuit, backend)
    result = backend.run(transpiled_circuit).result()

    Esempio di utilizzo 2:

    from qiskit import QuantumCircuit, ClassicalRegister, transpile
    from qiskit.providers.fake_provider import GenericBackendV2
    
    # Create a circuit with classical control
    creg = ClassicalRegister(19)
    qc = QuantumCircuit(25)
    qc.add_register(creg)
    qc.h(0)
    for i in range(18):
        qc.cx(0, i + 1)
    for i in range(18):
        qc.measure(i, creg[i])
    with qc.if_test((creg, 0)):
        qc.ecr(20, 21)
    
    # Define backend with custom basis gates and control flow instructions
    backend = GenericBackendV2(
        num_qubits=25,
        basis_gates=["ecr", "id", "rz", "sx", "x"],
        control_flow=True,
      )
    
    #Transpile
    transpiled_qc = transpile(qc, backend)
    Nota

    Le proprietà del rumore generate da questa classe non imitano alcun dispositivo quantistico concreto e non devono essere utilizzate per misurare alcun comportamento concreto. Si tratta di "valori predefiniti ragionevoli" che possono essere utilizzati per testare le funzionalità di backend-interfacing non legate ai valori di rumore specifici dei sistemi quantistici reali. Per una simulazione più accurata dei dispositivi esistenti, è possibile costruire manualmente un modello di rumore dal backend reale utilizzando la funzionalità offerta in qiskit_aer.

  • Il modulo qiskit.providers.fake_provider include ora una serie di falsi backend generici che seguono l'interfaccia BackendV1 interfaccia. Sono stati introdotti come alternativa ai falsi backend basati sugli snapshot esposti nel deprecato FakeProvider (FakeVigo, FakeTokyo, ecc.). L'elenco dei nuovi backend fasulli comprende:

    Possono essere importati seguendo lo schema: from qiskit.providers.fake_provider import Fake5QV1. Ulteriori dettagli sulle proprietà del backend sono disponibili nella documentazione API di ciascun backend.

OpenQASM Caratteristiche

  • Il pacchetto qiskit.qasm3 contiene ora un parser integrato, basato su Rust, per la lettura dei programmi OpenQASM 3 in QuantumCircuits, che si trova in qiskit.qasm3.load_experimental() e loads_experimental(). In genere sono diverse volte più veloci dell'attuale, puro Python load() e loads() esistenti, che richiedono inoltre l'installazione di qiskit-qasm3-import .

    Per esempio, possiamo creare un entangling di 20.000 istruzioni QuantumCircuit:

    import numpy as np
    import qiskit.qasm3
    from qiskit.circuit.library import RealAmplitudes
    
    qc = RealAmplitudes(100, reps=100, flatten=True)
    qc = qc.assign_parameters(np.random.rand(qc.num_parameters))
    oq3 = qiskit.qasm3.dumps(qc)

    Il vecchio qasm3.loads() richiedeva circa 7.3s per caricare il programma OpenQASM 3 risultante, mentre qasm3.loads_experimental() ha impiegato meno di 300ms su un Macbook Pro consumer ( i7, 2020) - una velocità di 25x!

    Il set di funzionalità supportate dal parser sperimentale è molto limitato in questa versione di anteprima, ma si espanderà man mano che sia il lato Qiskit che il parser nativo basato su Rust miglioreranno.

    Uno dei nostri obiettivi principali con questo nuovo parser, oltre agli enormi miglioramenti in termini di velocità, è quello di fornire una diagnostica degli errori di altissima qualità. Come per altre parti del parser, si tratta di un lavoro in corso, ma si inizieranno a vedere messaggi di errore di qualità molto più elevata quando si analizzano programmi OpenQASM 3 non validi con il parser sperimentale.

  • L'esportatore OpenQASM 3 (vedere dump() e dumps() in qiskit.qasm3) ora supporta la sintassi stabilizzata dell'istruzione switch in OpenQASM 3 per impostazione predefinita. La sintassi di pre-certificazione della dichiarazione switch è ancora disponibile utilizzando il flag ExperimentalFeatures.SWITCH_CASE_V1 nell'argomento experimental dell'esportatore. Non è richiesto alcun flag di caratteristica per la sintassi stabilizzata, ma se ci si interfaccia con altri strumenti non ancora aggiornati, potrebbe essere necessario passare il flag sperimentale.

    La sintassi della forma stabilizzata è leggermente diversa per quanto riguarda la terminazione degli enunciati break (non più richiesta né consentita) e i casi multipli vengono ora combinati in un'unica riga case , invece di usare il fall-through in stile C. Per maggiori dettagli, vedere la documentazione di OpenQASM 3 sul costrutto switch-case.

Caratteristiche QPY

  • Aggiunta di una nuova classe di avviso, QPYLoadingDeprecatedFeatureWarningal modulo QPY. Questa classe permette di far emergere gli avvisi di deprecazione anche se si accede alla funzione deprecata in un punto variabile dello stack di chiamate, come nel caso di molte funzioni di caricamento di QPY che vengono chiamate in modo ricorsivo.

  • Aggiunto un nuovo flag, version, alla funzione qpy.dump() funzione. Questo permette qpy.dump() di accettare facoltativamente un valore intero per la versione del formato QPY da emettere. Questo è utile se si deve generare un file QPY che verrà caricato da una versione precedente di Qiskit. Tuttavia, le versioni supportate per l'emissione sono limitate: è possibile utilizzare solo versioni comprese tra l'ultima versione di QPY (che è quella predefinita) e la versione di compatibilità di QPY che è la versione 10 (introdotta in Qiskit 0.45.0 ). La versione di compatibilità rimarrà fissa per tutta la serie di major release di 1.x.y. Questo non cambia le garanzie di retrocompatibilità del formato QPY quando si chiama qpy.load()ma consente agli utenti di emettere una versione precedente di QPY per mantenere la compatibilità e l'interoperabilità tra le serie di versioni 0.x e 1.x.

Caratteristiche dell'informazione quantistica

  • È stato aggiunto un qiskit.quantum_info.StabilizerState.from_stabilizer_list() che genera uno stato stabilizzatore da un elenco di stabilizzatori:

    from qiskit.quantum_info import StabilizerState
    
    stabilizer_list = ["ZXX", "-XYX", "+ZYY"]
    stab = StabilizerState.from_stabilizer_list(stabilizer_list)
  • SparsePauliOp.from_operator() utilizza ora un'implementazione dell'"algoritmo di decomposizione di Pauli tensorizzato" presentato in Hatznko, Binkowski e Gupta (2023). Il metodo è ora più veloce di diversi ordini di grandezza; ad esempio, è possibile decomporre un operatore casuale a 10 qubit in circa 250ms su un Macbook Pro consumer (Intel i7, 2020).

Caratteristiche della sintesi

  • Aggiunta una qiskit.synthesis.synth_circuit_from_stabilizers() che restituisce un circuito che produce lo stato stabilizzato da una serie di stabilizzatori dati.

  • Il metodo del plugin di sintesi unitaria AQC utilizza ora una valutazione più rapida della funzione obiettivo per impostazione predefinita, con conseguente miglioramento sostanziale dei tempi di sintesi.

  • Aggiungere un nuovo metodo di sintesi synth_qft_line() di un circuito QFT per la connettività lineare nearest-neighbor, che riduce significativamente il numero di SWAP per un gran numero di qubit rispetto a SABRE.

  • La classe TwoQubitWeylDecomposition è stata aggiunta all'API pubblica in qiskit.synthesis. Questa classe permette di applicare la decomposizione di Weyl agli unitari a due qubit. Se in precedenza si importava questa classe quando era una classe non pubblica nel modulo qiskit.quantum_info.synthesis , ora rimosso, occorre aggiornare i percorsi di importazione.

Funzionalità del transpiler

  • Aggiunta di una nuova classe di eccezione: InvalidLayoutError. Si tratta di una TranspilerError che viene sollevata quando un layout fornito dall'utente non è valido (dimensioni non corrispondenti, qubit duplicati, ecc.).

  • È stato aggiunto un nuovo argomento di parola chiave, num_processes, a transpile() e al metodo PassManager.run() metodo. Ciò consente di sovrascrivere sia QISKIT_NUM_PROCS che il campo num_processes nei file di configurazione dell'utente su base individuale. Ad esempio:

    from qiskit import transpile, QuantumCircuit
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    
    transpile([qc]*10, basis_gates=['u', 'cz'], num_processes=2)

    eseguirà il transpile sui 10 circuiti di ingresso utilizzando solo 2 processi e sovrascriverà il valore predefinito del sistema, la variabile d'ambiente o il file di configurazione dell'utente per quella chiamata transpile() chiamata.

  • Aggiunto un nuovo passaggio del transpiler, OptimizeAnnotatedche ottimizza le operazioni annotate su un circuito quantistico.

    Considera il seguente esempio:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.annotated_operation import (
        AnnotatedOperation,
        InverseModifier,
        ControlModifier,
    )
    from qiskit.circuit.library import CXGate, SwapGate
    from qiskit.transpiler.passes import OptimizeAnnotated
    
    # Create a quantum circuit with multiple annotated gates
    gate1 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), ControlModifier(2), InverseModifier(), ControlModifier(1)],
    )
    gate2 = AnnotatedOperation(
        SwapGate(),
        [InverseModifier(), InverseModifier()]
    )
    gate3 = AnnotatedOperation(
        AnnotatedOperation(CXGate(), ControlModifier(2)),
        ControlModifier(1)
    )
    qc = QuantumCircuit(6)
    qc.append(gate1, [3, 2, 4, 0, 5])
    qc.append(gate2, [1, 5])
    qc.append(gate3, [5, 4, 3, 2, 1])
    
    # Optimize the circuit using OptimizeAnnotated transpiler pass
    qc_optimized = OptimizeAnnotated()(qc)
    
    # This is how the optimized circuit should look like
    gate1_expected = AnnotatedOperation(SwapGate(), ControlModifier(3))
    gate2_expected = SwapGate()
    gate3_expected = AnnotatedOperation(CXGate(), ControlModifier(3))
    qc_expected = QuantumCircuit(6)
    qc_expected.append(gate1_expected, [3, 2, 4, 0, 5])
    qc_expected.append(gate2_expected, [1, 5])
    qc_expected.append(gate3_expected, [5, 4, 3, 2, 1])
    
    assert qc_optimized == qc_expected

    Nel caso di gate1, i modificatori dello swap gate annotato vengono portati nella forma canonica: le due s si annullano e le due InverseModifiersi annullano e i due ControlModifiers sono combinati. Nel caso di gate2, tutti i modificatori vengono rimossi e l'operazione annotata viene sostituita dalla sua operazione di base. Nel caso di gate3, più livelli di annotazioni vengono combinati in uno solo.

    Il costruttore del OptimizeAnnotated accetta gli argomenti opzionali target, equivalence_library, basis_gates e recurse. Quando recurse è True (il valore predefinito) e quando sono specificati target o basis_gates , il passaggio scende ricorsivamente nei circuiti definition del gate, con l'eccezione dei gate già supportati dal target o che appartengono alla libreria di equivalenza. D'altra parte, quando non sono specificati né targetbasis_gates , o quando recurse è impostato su False, il passaggio sintetizza solo le operazioni annotate "di primo livello", cioè non scende ricorsivamente nei circuiti di definition . Questo comportamento è coerente con quello del passaggio HighLevelSynthesis che deve essere richiamato per "srotolare" le operazioni annotate in porte a 1 e 2 qubit.

  • Aggiunto un nuovo elemento HighLevelSynthesisPlugin per PermutationGate basato sull'algoritmo di scambio di token di Qiskit. Per utilizzare questo plugin, specificare token_swapper quando si definisce la configurazione della sintesi ad alto livello.

    Questo plugin di sintesi può essere eseguito prima o dopo l'impostazione del layout. Quando la sintesi ha successo, il plugin produce un circuito quantistico costituito solo da porte di scambio. Quando la sintesi non riesce, il plugin emette None.

    Il codice seguente illustra come può essere eseguito il nuovo plugin:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PermutationGate
    from qiskit.transpiler import PassManager, CouplingMap
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HighLevelSynthesis, HLSConfig
    
    # This creates a circuit with a permutation gate.
    qc = QuantumCircuit(8)
    perm_gate = PermutationGate([0, 1, 4, 3, 2])
    qc.append(perm_gate, [3, 4, 5, 6, 7])
    
    # This defines the coupling map.
    coupling_map = CouplingMap.from_ring(8)
    
    # This high-level-synthesis config specifies that we want to use
    # the "token_swapper" plugin for synthesizing permutation gates,
    # with the option to use 10 trials.
    synthesis_config = HLSConfig(permutation=[("token_swapper", {"trials": 10})])
    
    # This creates the pass manager that runs high-level-synthesis on our circuit.
    # The option use_qubit_indices=True indicates that synthesis is run after the layout is set,
    # and hence should preserve the specified coupling map.
    pm = PassManager(
        HighLevelSynthesis(
            synthesis_config, coupling_map=coupling_map, target=None, use_qubit_indices=True
        )
    )
    
    qc_transpiled = pm.run(qc)
  • Aggiunti due nuovi argomenti, matrix_based e max_qubits, al costruttore del passo di CommutativeInverseCancellation del passo del transpiler. Quando matrix_based è True, il passaggio utilizza le rappresentazioni matriciali per verificare se due operazioni sono l'una l'inversa dell'altra. Questo rende i controlli più potenti e consente inoltre di annullare coppie di operazioni inverse fino a una fase, aggiornando di conseguenza la fase globale del circuito. In genere questo porta a maggiori riduzioni a scapito di un aumento del tempo di esecuzione. L'argomento max_qubits limita il numero di qubit nei controlli di commutatività e inversione basati su matrice. Ad esempio:

    import numpy as np
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes import CommutativeInverseCancellation
    
    circuit = QuantumCircuit(1)
    circuit.rz(np.pi / 4, 0)
    circuit.p(-np.pi / 4, 0)
    
    passmanager = PassManager(CommutativeInverseCancellation(matrix_based=True))
    new_circuit = passmanager.run(circuit)

    Il passaggio è in grado di annullare le porte RZ e P , mentre regola la fase globale del circuito su 15π8\frac{15 \pi}{8}.

  • Aggiunta una nuova funzione, high_level_synthesis_plugin_names()che può essere usata per ottenere l'elenco dei plugin di sintesi di alto livello installati per un determinato nome di operazione.

Funzionalità di visualizzazione

  • Le uscite text e mpl per i moduli QuantumCircuit.draw() e circuit_drawer() visualizzeranno ora informazioni dettagliate per le operazioni di AnnotatedOperation. Se il sito AnnotatedOperation.modifiers contiene un simbolo ControlModifier, l'operazione verrà visualizzata allo stesso modo dei cancelli controllati. Se il InverseModifier o PowerModifier vengono indicati con il nome dell'operazione di base. Ad esempio:

    from qiskit.circuit import (
        AnnotatedOperation,
        ControlModifier,
        PowerModifier,
        InverseModifier,
        QuantumCircuit
    )
    from qiskit.circuit.library import SGate
    
    annotated_op = AnnotatedOperation(SGate(), [PowerModifier(3.4), ControlModifier(3), InverseModifier()])
    qc = QuantumCircuit(4)
    qc.append(annotated_op, range(4))
    qc.draw("mpl")
    _images/release_notes-1.png

Varie Funzioni

  • Aggiunta di una nuova classe di base per gli avvisi, QiskitWarning. Mentre Qiskit continuerà a utilizzare le avvertenze integrate di Python (come ad esempio DeprecationWarning) quando sono più appropriati, per i casi più specifici di Qiskit, gli avvertimenti saranno sottoclassi di QiskitWarning.

  • I tester della funzionalità opzionale (qiskit.utils.optionals) ora distinguono una dipendenza opzionale che non è stata trovata (una situazione normale) da una che è stata trovata, ma che ha provocato errori durante la sua importazione. In quest'ultimo caso, ora emetteranno un avviso di OptionalDependencyImportWarning che informa l'utente dell'accaduto, poiché potrebbe indicare un'installazione fallita o una versione incompatibile.

Note sull'aggiornamento

  • Qiskit 1.0 ora richiede la versione 0.14.0 di rustworkx. La versione minima richiesta è stata aumentata per supportare il nuovo plugin di sintesi token_swapper PermutationGate per il plugin di sintesi per HighLevelSynthesisPlugin.

  • La versione minima supportata di Rust per la creazione di Qiskit dai sorgenti è ora 1.70. Questa versione è stata aumentata rispetto alla precedente versione Rust minimamente supportata di 1.64 nella serie di rilasci di Qiskit 0.45.x e 0.46.0.

  • La dipendenza da psutil è stata rimossa. La libreria psutil era usata in precedenza solo per rilevare il numero di CPU fisiche e la memoria totale del sistema; tuttavia, queste informazioni fornite non aggiungono un valore sufficiente a giustificare le dipendenze e l'overhead aggiuntivi, quindi sono state rimosse. Ciò significa che il numero predefinito di processi utilizzati da parallel_map() e le funzioni che internamente possono utilizzare parallel_map() come ad esempio transpile() e PassManager.run() possono utilizzare più o meno processi paralleli rispetto alle versioni precedenti. Se si desidera regolare il numero di processi utilizzati, è possibile utilizzare il nuovo argomento num_processes per queste funzioni, oppure la variabile d'ambiente QISKIT_NUM_PROCS o il campo num_processes in un file di configurazione utente (per maggiori dettagli, consultare la guida alla configurazione locale ) se si desidera regolare il numero di processi potenzialmente utilizzati da Qiskit.

  • I metodi scoped_parameters e search_parameters sono stati rimossi dalla classe ScheduleBlock della classe. Questi metodi restituiscono Parameter che si collegano parzialmente ai parametri dell'istanza ScheduleBlock ma l'assegnazione di valori con questi oggetti non funziona correttamente. Gli utenti dovrebbero usare ScheduleBlock.parameters e iterare attraverso ScheduleBlock.references e confrontarlo con gli attributi Schedule.parameters degli attributi delle sottoreferenze, quando si vuole distinguere in quale subroutine viene utilizzato un parametro. Per ulteriori informazioni, vedere il numero 11654.

  • Rimossa la logica per iniettare QuantumCircuit e Gate nel contesto dell'impulso (come in pulse.builder.call()), che era un comportamento legacy deprecato in Qiskit 0.46. Le pianificazioni degli impulsi devono essere costruite come un contesto di pianificazione completo; i circuiti e le porte rappresentano un livello di astrazione superiore.

    Ciò include la rimozione delle funzioni correlate:

    • pulse.builder.call_gate
    • pulse.builder.cx
    • pulse.builder.u1
    • pulse.builder.u2
    • pulse.builder.u3
    • pulse.builder.x
    • pulse.builder.active_transpiler_settings
    • pulse.builder.active_circuit_scheduler_settings
    • pulse.builder.transpiler_settings
    • pulse.builder.circuit_scheduler_settings

    Gli argomenti default_transpiler_settings e default_circuit_scheduler_settings di pulse.builder.build() vengono rimossi in modo analogo.

    from qiskit import transpile, schedule, QuantumCircuit, pulse
    from qiskit.providers.fake_provider import Fake7QPulseV1
    
    backend = Fake7QPulseV1()
    
    # Create a schedule from a hardware-based circuit.
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    qc = transpile(qc, backend)
    sched = schedule(qc, backend)
    
    # These pulse schedules can still be called in builder contexts.
    with pulse.build(backend) as qc_sched:
      pulse.call(sched)
    
    # Schedules for certain operations can also be directly retrieved
    # from BackendV1 instances:
    sched = backend.defaults().instruction_schedule_map.get('x', (0,))
    
    # ... and from BackendV2 instances:
    sched = backend.target['x'][(0,)].calibration
  • La versione minima richiesta per symengine è stata portata a >= 0.11.

Note sull'aggiornamento dei circuiti

  • Rimosso il metodo Instruction.qasm , deprecato in Qiskit 0.45.0. Utilizzo qiskit.qasm2.dump() con un testo completo QuantumCircuit invece.

  • Le proprietà Bit.register e Bit.index vengono rimosse. Sono stati deprecati in Qiskit 0.25 (rilasciato nel 2021-04). I qubit e i bit ora vivono solo nel contesto di un QuantumCircuit. L'alternativa alle proprietà è usare QuantumCircuit.find_bit() per trovare tutti i registri contenenti un circuito e l'indice del bit all'interno del circuito.

  • Il metodo QuantumCircuit.bind_parameters è stato rimosso, in seguito alla sua deprecazione in Qiskit 0.45. È possibile utilizzare QuantumCircuit.assign_parameters() come sostituto di tutti i suoi valori predefiniti, oltre a esporre ulteriori funzionalità rispetto al vecchio metodo.

  • L'importazione di Int1, Int2, BooleanFunction, classical_function() da qiskit.circuit è ora disabilitata. Invece, importare gli oggetti dal sottomodulo qiskit.circuit.classicalfunction che richiede il pacchetto tweedledum .

  • Gli attributi di soli dati header e extension_lib di QuantumCircuit sono stati rimossi in seguito alla loro deprecazione in Qiskit 0.45. Si trattava di dettagli interni dell'esportatore OpenQASM 2 che non sono più utilizzati.

  • Rimosso il modulo qiskit.extensions , in attesa di essere deprecato dalla versione 0.45 e completamente deprecato dalla versione 0.46. Le seguenti operazioni di questo modulo sono disponibili in qiskit.circuit.library:

    I seguenti oggetti sono stati rimossi:

    • SingleQubitUnitary (utilizzare invece library.UnitaryGate),
    • Snapshot (sostituito dalle istruzioni di salvataggio dell'Aer),
    • ExtensionError,

    insieme ai seguenti metodi di circuito:

    • QuantumCircuit.snapshot,
    • QuantumCircuit.squ,
    • QuantumCircuit.diagonal,
    • QuantumCircuit.hamiltonian,
    • QuantumCircuit.isometry e QuantumCircuit.iso,
    • QuantumCircuit.uc,
    • QuantumCircuit.ucrx,
    • QuantumCircuit.ucry,
    • QuantumCircuit.ucrz.

    Queste operazioni possono comunque essere eseguite aggiungendo l'istruzione appropriata a un circuito quantistico.

  • Rimossi i metodi deprecati e duplicati di QuantumCircuit metodi. Queste release includono:

  • Non è più possibile impostare QuantumCircuit.metadata per essere None, a seguito della deprecazione in Qiskit 0.43.0. Il suo tipo è dict, quindi per cancellarlo, impostarlo su {}.

  • L'attributo .Register.name_format è stato rimosso in seguito alla sua deprecazione in Qiskit 0.40.0. Non ci sono più restrizioni sui nomi dei registri e l'espressione regolare era semplicemente [a-z][a-zA-Z0-9_]*.

Note sull'aggiornamento delle primitive

Note sull'aggiornamento dei provider

  • Modificato il valore predefinito di due argomenti (add_delay e filter_faulty) nella funzione convert_to_target() della funzione. Questa funzione di conversione ora aggiunge istruzioni di ritardo e rimuove le istruzioni difettose per impostazione predefinita.

  • Il BackendProperties e PulseDefaults utilizzati dal modello FakeOpenPulse2Q sono stati aggiornati per essere coerenti internamente e per aggiungere le istruzioni mancanti. Se ci si affidava agli oggetti del modello precedente come target di compilazione, è possibile utilizzare il backend con Qiskit 0.46 ed esportare un file QuantumCircuit generato con transpile() e serializzarlo con qpy.dump per accedervi in questa release.

  • Il modulo qiskit.providers.basicaer , esposto come qiskit.BasicAer, è stato rimosso in seguito alla sua deprecazione nella release 0.46. La sua funzionalità è stata sostituita dal modulo qiskit.quantum_info e dal nuovo modulo qiskit.providers.basic_provider modulo.

    La migrazione dall'utilizzo di qiskit.providers.basicaer (qiskit.BasicAer) a qiskit.providers.basic_provider può essere eseguita come segue:

    Migrare da
    Sostituisci con
    qiskit.BasicAerIl nuovo provider non ha un'istanza globale, le importazioni dovrebbero essere da qiskit.providers.basic_provider
    qiskit.providers.basicaerbasic_provider
    BasicAerProviderBasicProvider
    BasicAerJobBasicProviderJob
    QasmSimulatorPyBasicSimulator
    UnitarySimulatorPyutilizzo Operator
    StatevectorSimulatorPyutilizzo Statevector

    Una differenza notevole è che il nuovo provider non è più esposto attraverso un'istanza globale (come BasicAer), quindi non sarà valido per fare from qiskit import BasicProvider. Invece, la classe del provider deve essere importata dal suo sottomodulo e istanziata manualmente:

    from qiskit.providers.basic_provider import BasicProvider
    
    provider = BasicProvider()
    backend = provider.get_backend("basic_simulator")

    Gli esempi seguenti mostrano i percorsi di migrazione dei tre simulatori in BasicAer.

    1. Simulatore di vettore di stato:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("statevector_simulator")
      statevector = backend.run(qc).result().get_statevector()
      
      # New path
      from qiskit.quantum_info import Statevector
      statevector = Statevector(qc)
    2. Simulatore unitario:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("unitary_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.quantum_info import Operator
      result = Operator(qc).data
    3. Simulatore Qasm:

      from qiskit import QuantumCircuit
      qc = QuantumCircuit(3)
      qc.h(0)
      qc.h(1)
      qc.cx(1,2)
      qc.measure_all()
      
      # Former path
      from qiskit import BasicAer
      backend = BasicAer.get_backend("qasm_simulator")
      result = backend.run(qc).result()
      
      # New path
      from qiskit.providers.basic_provider import BasicProvider
      backend = BasicProvider().get_backend("basic_simulator")
      result = backend.run(qc).result()
      # or, directly
      from qiskit.providers.basic_provider import BasicSimulator
      backend = BasicSimulator()
      result = backend.run(qc).result()
  • Rimossa la classe ConfigurableFakeBackend deprecata in Qiskit 0.46.0. Al suo posto si può utilizzare un'appropriata FakeBackend può essere utilizzato.

  • 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

Note sull'aggiornamento Pulse

  • Rimossa la classe deprecata qiskit.pulse.instructions.Call Non è prevista alcuna istruzione di impulso alternativa.

  • Rimossi i metodi deprecati in InstructionToQobjConverter e QobjToInstructionConverter. Questo include

    • InstructionToQobjConverter.convert_acquire()
    • InstructionToQobjConverter.convert_bundled_acquires()
    • InstructionToQobjConverter.convert_set_frequency()
    • InstructionToQobjConverter.convert_shift_frequency()
    • InstructionToQobjConverter.convert_set_phase()
    • InstructionToQobjConverter.convert_shift_phase()
    • InstructionToQobjConverter.convert_delay()
    • InstructionToQobjConverter.convert_play()
    • InstructionToQobjConverter.convert_snapshot()
    • QobjToInstructionConverter.convert_acquire()
    • QobjToInstructionConverter.convert_set_phase()
    • QobjToInstructionConverter.convert_shift_phase()
    • QobjToInstructionConverter.convert_set_frequency()
    • QobjToInstructionConverter.convert_shift_frequency()
    • QobjToInstructionConverter.convert_delay()
    • QobjToInstructionConverter.bind_pulse()
    • QobjToInstructionConverter.convert_parametric()
    • QobjToInstructionConverter.convert_snapshot()

    Questi metodi pubblici sono tutti sostituiti da metodi protetti, che vengono richiamati implicitamente dal singolo punto di ingresso, cioè richiamando la classe come una funzione.

  • La classe qiskit.pulse.library.ParametricPulse e tutte le sottoclassi vengono rimosse. Questi sono stati deprecati da Qiskit 0.39 (con qiskit-terra 0.22 ), rilasciato nel 2022-10. Si consiglia invece di utilizzare SymbolicPulse e controllate la sua documentazione per i dettagli.

OpenQASM Note sull'aggiornamento

  • I metodi qasm() delle classi QuantumRegister e ClassicalRegister sono stati rimossi. Non è necessario sostituirli; si trattava di un dettaglio interno di un'implementazione legacy dell'esportatore OpenQASM 2. Per esportare un programma in OpenQASM 2, utilizzare qasm2.dump() o qasm2.dumps().

Note sull'aggiornamento QPY

  • L'ultima versione del formato di QPY è ora la versione 11 e questo è ciò che viene emesso per impostazione predefinita quando si esegue qpy.dump().

  • Il percorso del modulo qiskit.circuit.qpy_serialization è stato rimosso, in seguito alla sua deprecazione in Qiskit 0.40.0. Per la serializzazione QPY, utilizzare qiskit.qpyche è la nuova posizione.

Note sull'aggiornamento delle informazioni quantistiche

  • Rimossi i metodi magici deprecati __getitem__/__setitem__ di Clifford. I metodi sono stati deprecati a partire da Qiskit 0.44, rilasciato nel 2023-07. Invece, indicizzare o iterare l'attributo Clifford.tableau .

  • Rimosso il modulo qiskit.quantum_info.synthesis , deprecato dalla versione 0.46. I seguenti oggetti sono stati spostati in qiskit.synthesis:

    Questa funzione è stata rimossa, poiché è già stata deprecata nella versione 0.46 : * cnot_rxx_decompose

    Queste funzioni sono state rimosse, in quanto già deprecate in una release precedente: * decompose_clifford (usare synth_clifford_full() invece) * decompose_cnotdihedral (usare synth_cnotdihedral_full() invece)

  • Le funzioni process_fidelity(), average_gate_fidelity(), gate_error() e diamond_norm() non cercheranno più di costringere gli ingressi arbitrari ai loro tipi previsti, seguendo la deprecazione in Qiskit 0.25.0. Passare direttamente a ciascun argomento gli ingressi dei tipi contrassegnati.

Note sull'aggiornamento della sintesi

Note sull'aggiornamento del transpiler

  • Il metodo deprecato Target.aquire_alignment è stato rimosso. È stato contrassegnato come deprecato in Qiskit 0.43 (versione 2023-05). Si deve invece utilizzare il metodo Target.acquire_alignment() .

  • Rimossa la funzione deprecata qiskit.transpiler.preset_passmanagers.common.get_vf2_call_limit. Utilizzare invece get_vf2_limits().

  • L'uso implicito di approximation_degree!=1.0 per impostazione predefinita nella funzione generate_preset_pass_manager() è stato disabilitato. L'impostazione predefinita precedente potrebbe causare approssimazioni indebite e inaspettate, soprattutto nei carichi di lavoro che prevedono la trotterizzazione o operazioni simili che sono vicine, ma decisamente non uguali, all'identità.

    Questa modifica porta le impostazioni predefinite per la generazione del pass-manager interno in linea con transpile()che è sempre stata l'intenzione. Per maggiori dettagli, vedere il numero 8595.

  • Rimossa la classe deprecata Unroller in qiskit.transpiler.passes.basis. Questa classe è stata deprecata in Qiskit 0.45 e il suo utilizzo può essere sostituito dall'uso combinato di BasisTranslator e UnrollCustomDefinitions.

    Si noti che BasisTranslator e UnrollCustomDefinitions prendono argomenti diversi da quelli di Unroller, poiché richiedono il passaggio di un oggetto EquivalenceLibrary .

    Dove prima si poteva usare Unroller(basis_gates) , ora si può usare:

    from qiskit.circuit.library.standard_gates.equivalence_library import (
        StandardEquivalenceLibrary as std_eqlib,
    )
    pm = PassManager([
        UnrollCustomDefinitions(std_eqlib, basis_gates)
        BasisTranslator(std_eqlib, basis_gates),
    ])
    translated = pm.run(circuit)
  • Il passaggio deprecato del transpiler NoiseAdaptiveLayout è stato rimosso. È stato contrassegnato come deprecato in Qiskit 0.46.0. Questo passaggio è stato ampiamente superato da VF2Layout e VF2PostLayout che imposta un layout basato sulle caratteristiche di rumore riportate da un backend. Insieme al passaggio, è stato rimosso il plugin layout_method "noise_adaptive" .

  • Il passaggio deprecato del transpiler CrosstalkAdaptiveSchedule è stato rimosso. È stato contrassegnato come deprecato in Qiskit 0.46.0. Questo passaggio non era più utilizzabile, perché il suo funzionamento interno dipendeva dall'impostazione di proprietà personalizzate nel payload di un file BackendProperties di un'istanza BackendV1 istanza. Poiché nessun backend imposta questi campi, il passaggio è stato rimosso. Se si dipende dal pass per un flusso di lavoro personalizzato, è possibile utilizzare la versione in Qiskit 0.46.x.

  • Rimosso il modulo qiskit.transpiler.synthesis , deprecato dalla versione 0.46. I seguenti oggetti sono stati spostati:

  • L'alias della parola chiave target quando si chiamano TwoQubitBasisDecomposer come funzioni è stata rimossa in seguito alla sua deprecazione in Qiskit 0.40.0. Si deve passare l'argomento in posizione come primo argomento, oppure usare il nuovo nome unitary.

  • Il passaggio specializzato per il transpiler LinearFunctionsSynthesis è stato rimosso in seguito alla sua deprecazione in Qiskit 0.40.0. Dalla sua deprecazione, è solo un involucro molto sottile attorno a HighLevelSynthesische si dovrebbe invece utilizzare.

  • Il percorso di importazione qiskit.transpiler.passes.scheduling.calibration_creators viene rimosso. Il transpiler lo passa in casa, RZXCalibrationBuilder e RZXCalibrationBuilderNoEcho può essere importato direttamente da qiskit.transpiler.passes.

  • Il percorso di importazione qiskit.transpiler.passes.scheduling.rzx_templates viene rimosso. Si dovrebbe importare rzx_templates() da qiskit.transpiler.passes direttamente.

  • È stato aggiornato un modello per la costruzione della piepline di passaggio. Lo zucchero sintattico mostrato di seguito per l'istanziazione del controllore di flusso è stato rimosso.

    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(my_pass, condition=condition_callable, do_while=do_while_callable)

    Invece di usare questo schema di argomenti con parole chiave, si dovrebbe istanziare esplicitamente il controllore di flusso.

    from qiskit.passmanager import ConditionalController, DoWhileController
    from qiskit.transpiler import PassManager
    
    pm = PassManager()
    pm.append(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )

    Si noti che è possibile gestire l'ordine di importanza dei controllori quando si desidera annidarli, cosa che non era possibile con gli argomenti delle parole chiave. Si può anche costruire la pipeline con il costruttore del gestore di passaggi, come di seguito, perché non c'è motivo di chiamare il metodo append ora.

    pm = PassManager(
      ConditionalController(
        DoWhileController(my_pass, do_while=do_while_callable),
        condition=condition_callable,
      )
    )
  • Il metodo append dei controllori di flusso incorporati è stato rimosso. Questo include

    • ConditionalController.append
    • DoWhileController.append
    • FlowControllerLinear.append

    La pipeline dei task in un controllore di flusso è congelata e deve essere passata quando viene creata l'istanza del controllore.

  • Rimossi i metodi passess di PassManager e StagedPassManager che restituiscono una rappresentazione dei passi inclusi sotto forma di elenco di dizionari. Tuttavia, questo formato non rappresenta in modo efficiente una pipeline di passaggi più complicata, che può includere ramificazioni condizionali e condizioni annidate. Invece di utilizzare questa rappresentazione, utilizzare il seguente schema

    pm = PassManager(...)
    pm.to_flow_controller().tasks

    Restituisce direttamente un'istanza di base linearizzata in formato tupla.

  • L'argomento max_iteration è stato rimosso da PassManager.append() e PassManager.replace().

  • Le seguenti classi legacy sono state rimosse dai moduli pass manager e transpiler in seguito alla loro deprecazione in Qiskit 0.46:

    • qiskit.passmanager.flow_controllers.FlowController
    • qiskit.transpiler.fencedobjs.FencedObject
    • qiskit.transpiler.fencedobjs.FencedPropertySet
    • qiskit.transpiler.fencedobjs.FencedDAGCircuit
    • qiskit.transpiler.runningpassmanager.RunningPassManager

Note sull'aggiornamento della visualizzazione

  • Lo stile predefinito per la visualizzazione dei circuiti con Matplotlib è stato modificato in "iqp", in linea con la piattaforma Quantum IBM.

  • Il modulo deprecato qiskit.visualization.qcstyle è stato rimosso. Questo modulo è stato contrassegnato come deprecato da Qiskit 0.39.0. Si dovrebbe invece utilizzare il sito qiskit.visualization.circuit.qcstyle.

  • Il supporto deprecato per il passaggio di un elemento QuasiDistribution, ProbDistributiono un dizionario di distribuzione all'argomento data del metodo di visualizzazione plot_histogram() è stato rimosso. Questa funzionalità è stata contrassegnata come deprecata nella release di Qiskit 0.39.0 (2022-10). Se invece si vuole tracciare un istogramma a partire da un valore di QuasiDistribution, ProbDistribution, o di un dizionario di distribuzione si deve utilizzare la funzione plot_distribution() invece di utilizzare la funzione.

  • La chiave link_interval_dt di QiskitTimelineStyle è stata rimossa. Si deve utilizzare il nuovo nome link_interval_percent.

Varie Note sull'aggiornamento

  • L'oggetto qiskit.Aer è stato rimosso in seguito alla sua deprecazione in Qiskit 0.46. È invece possibile utilizzare qiskit_aer.Aer, che è un sostituto di facile utilizzo.

  • L'importazione da qiskit.providers.aer non funzionerà più, a seguito della sua deprecazione in Qiskit 0.46. Dovreste invece importare da qiskit_aer, che è un sostituto di primo livello.

  • I lavori Pulse non sono più supportati nei backend fasulli, in seguito alla deprecazione e alla rimozione della funzionalità di simulazione sottostante in Aer. Per la simulazione a livello di impulsi, al di fuori del contesto degli oggetti circuitali, si consiglia di utilizzare una libreria speciale come Qiskit Dynamics.

  • La funzione execute() di Qiskit è stata rimossa. Questa funzione funge da involucro di alto livello per la trasposizione di un circuito con alcune opzioni di trasposizione e l'esecuzione su un backend con alcune opzioni di esecuzione. Per fare la stessa cosa, si può usare esplicitamente la funzione transpile() (con le opportune opzioni di transpile) seguita da backend.run() (con le opportune opzioni di esecuzione).

    Ad esempio, invece di correre:

    from qiskit import execute
    job = execute(circuit, backend)

    si può correre:

    from qiskit import transpile
    new_circuit = transpile(circuit, backend)
    job = backend.run(new_circuit)

    In alternativa, la primitiva Sampler è semanticamente equivalente alla funzione deprecata execute() . La classe BackendSampler è un wrapper generico per i backend che non supportano le primitive:

    from qiskit.primitives import BackendSampler
    sampler = BackendSampler(backend)
    job = sampler.run(circuit)
  • L'oggetto deprecato qiskit.IBMQ è stato rimosso. Questo oggetto alias è stato contrassegnato come deprecato nella versione di Qiskit 0.40.0. Questo oggetto alias reindirizza pigramente l'accesso agli attributi a qiskit.providers.ibmq.IBMQ. Poiché il pacchetto qiskit-ibmq-provider è stato ora ritirato e sostituito dal pacchetto qiskit-ibm-provider che mantiene il proprio spazio dei nomi, il mantenimento di questo alias non è più rilevante. Se ci si affidava all'alias qiskit.IBMQ , è necessario migrare l'utilizzo al pacchetto qiskit-ibm-provider ; per maggiori dettagli, consultare la guida alla migrazione.

  • Rimosso il modulo deprecato qiskit.tools.jupyter che in precedenza includeva Jupyter magics e widget per la visualizzazione interattiva di alcuni dati da Qiskit. Questo modulo è stato deprecato in Qiskit 0.46.0. La maggior parte di questa funzionalità era direttamente legata al pacchetto legacy qiskit-ibmq-provider e non era più valida, quindi il modulo è stato rimosso. Una funzionalità simile è disponibile nel modulo qiskit_ibm_provider.jupyter del pacchetto qiskit-ibm-provider.

  • Rimosso il modulo deprecato qiskit.tools.monitor che in precedenza includeva strumenti per il tracciamento delle istanze di JobV1 principalmente dal pacchetto legacy qiskit-ibm-provider . Questo modulo è stato contrassegnato come deprecato in Qiskit 0.46.0. È stato rimosso perché era direttamente legato al pacchetto legacy qiskit-ibm-provider .

  • Rimosso il deprecato percorso di importazione qiskit.test.mock che in precedenza era usato per reindirizzare le importazioni dei mock backend alla loro nuova posizione nel file qiskit.providers.fake_provider. Questo modulo è stato contrassegnato come deprecato in Qiskit 0.37.0. Se si utilizzava questo modulo, occorre aggiornare le importazioni da qiskit.test.mock a qiskit.providers.fake_provider al suo posto.

  • Il modulo qiskit.test non è più un modulo pubblico. Non è mai stato pensato per essere pubblico, né utilizzato al di fuori della suite di test di Qiskit. Tutte le funzionalità sono specifiche di Qiskit e non vengono fornite alternative; se avete bisogno di funzionalità simili, dovrete includerle nei vostri test harness.

  • Il modulo deprecato qiskit.tools.visualization è stato rimosso. Questo modulo è stato deprecato nella versione di Qiskit 0.46.0. Questo modulo era un redirect ereditato dalla posizione originale del modulo di visualizzazione di Qiskit ed è stato spostato in qiskit.visualization in Qiskit 0.8.0. Se si utilizza ancora questo percorso, è sufficiente aggiornare le importazioni da qiskit.tools.visualization a qiskit.visualization.

  • Il modulo deprecato qiskit.tools.events e la corrispondente utilità qiskit.tools.progressbar che esponeva sono stati rimossi. È stato deprecato nella versione di Qiskit 0.46.0. La funzionalità di questo modulo non era molto utilizzata e veniva coperta meglio da pacchetti dedicati come tqdm.

  • Il modulo qiskit.tools è stato rimosso. Questo modulo è stato deprecato in Qiskit 0.46.0. Tutti i contenuti di questo modulo sono stati rimossi, tranne la funzione qiskit.tools.parallel_map che ora può essere utilizzata da qiskit.utils.parallel_map() al suo posto.

Deprecazioni delle primitive

  • I metodi PrimitiveJob.submit() e PrimitiveJob.wait_for_final_state() sono stati rimossi in seguito alla loro deprecazione in Qiskit 0.46. Questi non dovevano essere metodi pubblici, ma erano un retaggio di una struttura ereditaria errata.

Correzioni di bug

  • Corretto il ritorno di programmi di misura impropri quando veniva richiesto solo un sottoinsieme di qubit. In precedenza, veniva restituito un programma di misura per tutti i qubit.

  • È stato risolto un problema nel cassetto del circuito text quando venivano visualizzate operazioni che non erano di circuit.instruction.Instruction classe. Queste operazioni causerebbero il fallimento del cassetto. Esempi sono stati Clifford e AnnotatedOperation.

  • È stato risolto un problema con il passaggio SetLayout in cui l'input di un elenco di interi non valido che conteneva voci duplicate causava la generazione di un file non valido e i successivi passaggi di transpiler fallivano con un errore criptico Layout e i successivi passaggi di transpiler fallivano con un errore criptico. Questo viene ora catturato quando SetLayout.run() viene richiamato un errore InvalidLayoutError viene sollevato un errore che indica la presenza di voci duplicate nell'elenco di interi.

  • QPY (utilizzando qpy.dump() e qpy.load()) ora serializzerà e deserializzerà correttamente i circuiti quantistici con operazioni annotate (AnnotatedOperation).

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

  • QuantumCircuit.compose() ora solleverà correttamente un problema di CircuitError quando ci sono duplicati negli argomenti qubits o clbits .

  • 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 problema quando si utilizza transpile() o eseguendo un gestore di passaggi preimpostato (come quello generato da generate_preset_pass_manager()) quando si punta a un backend che ha una connettività disgiunta, aggiungendo barriere extra all'output QuantumCircuit. In alcuni casi, diverse direttive a singolo qubit Barrier vengono inserite nel circuito di uscita prima di qualsiasi misura finale del circuito. Si trattava di uno stato interno generato dall'elaborazione interna per la connettività disgiunta che veniva erroneamente aggiunto al circuito di uscita. Corretto #11649

  • È stato corretto un errore quando l'utente tenta di caricare i dati di calibrazione di un cancello da una 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, non è stato possibile costruire l'oggetto impulso di Qiskit, con il risultato che non è stato possibile 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.

  • Il metodo Operator.power() funziona ora con esponenti in virgola mobile, in linea con la descrizione documentata.

  • È stato risolto un problema con il passaggio OptimizeSwapBeforeMeasure che ottimizzava in modo errato i circuiti che coinvolgevano istruzioni di scambio e misura. 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
  • È stato risolto un problema con la serializzazione di QPY quando un oggetto QuantumCircuit conteneva più istanze di istruzioni personalizzate che avevano lo stesso name attributo. Nelle versioni del formato QPY precedenti alla versione 11, il payload QPY non distingueva tra queste istanze e serializzava solo le proprietà della prima istanza di un circuito. Questo potrebbe causare una deserializzazione errata se le altre proprietà dell'istruzione personalizzata fossero diverse, ma i nomi fossero gli stessi. Questo problema è stato risolto nella versione 11 di QPY, in modo che ogni istanza di un'istruzione personalizzata venga serializzata individualmente e non si verifichi più un potenziale conflitto con nomi sovrapposti. Correzioni #8941.

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

  • Correzione di un bug nella rappresentazione delle StabilizerState nella rappresentazione delle stringhe.

  • Un bug in cui convert_to_target() e BackendV2Converter dava un errore inaspettato. Il bug si verificava quando il backend da convertire includeva le calibrazioni per un gate che non aveva una definizione nelle proprietà del backend. Tale porta viene ora trasmessa a tutti i qubit come un'istruzione ideale priva di errori, anche quando vengono riportate le calibrazioni per un insieme finito di qubit.

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

  • InstructionDurations.from_backend() restituisce ora un'istanza di qualsiasi sottoclasse di InstructionDurations invece della classe base.

  • Il passaggio UnitarySynthesis genera ora un errore all'inizializzazione quando viene specificato un plugin di sintesi inesistente, invece di aspettare il runtime per sollevarlo. Corretto #11355.

  • Il sito OpenQASM 3 esportatori qasm3.dump() e dumps() produrranno correttamente i file che dichiarano di essere la versione 3.0 piuttosto che la non qualificata 3, dato che il progetto OpenQASM 3 ha ora standardizzato la definizione delle versioni.

  • La forma parametrica di XXPlusYYGate e XXMinusYYGate restituita da get_standard_gate_name_mapping() ora include correttamente il parametro β\beta e la rotazione iniziale θ\theta.

  • Il passaggio TemplateOptimization restituirà ora espressioni parametriche utilizzando il formato nativo delle espressioni simboliche di ParameterExpressioninvece di usare sempre Sympy. Per la maggior parte delle piattaforme supportate, ciò significa che le espressioni saranno oggetti Symengine. In precedenza, il passaggio poteva restituire oggetti non corrispondenti, con conseguenti errori nel codice di gestione dei parametri.

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