Skip to main content
IBM Quantum Platform

Note di rilascio di Qiskit SDK 1.3


1.3.3

Preludio

Qiskit 1.3.3 è una versione con correzione di bug minori per la serie 1.3.

Correzioni di bug

  • È stato risolto un problema a causa del quale le etichette della barriera venivano posizionate in modo errato quando si utilizzava il parametro reverse_bits = True nel metodo QuantumCircuit.draw() metodo. Il bug causava il disallineamento delle etichette delle operazioni a barriera, generando una potenziale confusione nelle visualizzazioni dei circuiti. Corretto #13609.

  • Applicazione di un piccolo fattore di regolarizzazione contro le matrici hermitiane mal condizionate nelle rappresentazioni dei super-operatori.

  • I confronti tra istruzioni, anche all'interno di circuiti Delay di istruzioni, comprese quelle all'interno dei circuiti, ora richiedono che sia l'unità che il valore della durata siano uguali. Correzioni #13812.

  • È stato corretto un bug nel programma CommutationChecker che poteva fallire quando si verificava la relazione di commutazione di una rotazione Pauli a due qubit con un gate non presente nella cache di commutazione. Ad esempio:

    import numpy as np
    from qiskit.circuit.library import RXXGate, RGate
    from qiskit.circuit.commutation_library import SessionCommutationChecker as scc
    
    res = scc.commute(RGate(2, 2), [1], [], RXXGate(np.pi / 2), [0, 1], [])

    Questo comportamento è stato risolto e la relazione di commutazione è stata calcolata correttamente. Corretto #13742.

  • Corretto un bug in cui QuantumCircuit.qubit_stop_time() e QuantumCircuit.qubit_duration() restituiva un tempo (durata) errato. Il problema si verificava quando alcuni qubit avevano istruzioni ma altri qubit erano inattivi. Correzioni #8729.

  • È stato risolto un bug nel passaggio RemoveIdentityEquivalent in cui i gate vicini all'identità fino a una fase globale venivano rimossi dal circuito, ma la fase globale del circuito non veniva aggiornata. In particolare, RemoveIdentityEquivalent ora rimuove le porte non parametrizzate GlobalPhaseGate cancelli. Correzioni #13778.

  • Corretto un bug in random_clifford() che impediva di campionare l'intero gruppo di Clifford. Correzioni #13606.

  • Quando SabreLayout viene usato per eseguire contemporaneamente layout e routing (come nel caso delle opzioni predefinite di transpile() e generate_preset_pass_manager()) su un elemento Target o CouplingMap con connettività disgiunta e il circuito di ingresso si inserisce in un singolo componente della mappa di accoppiamento, la permutazione dell'instradamento verrà tracciata correttamente.

    In precedenza, qualsiasi qubit nella mappa di accoppiamento che non fosse collegato, anche indirettamente, a un qubit utilizzato dal circuito instradato non sarebbe stato incluso nella permutazione finale dell'instradamento. Questo potrebbe causare comportamenti sorprendenti a grande distanza dal punto di guasto, anche se la compilazione sembra essere riuscita, come le chiamate a TranspileLayout.final_index_layout() sollevando KeyError.

    Questo bug non riguardava i backend completamente connessi, come la maggior parte di essi. Correzioni #13732.


1.3.2

Preludio

Qiskit 1.3.2 è una versione con correzione di bug minori per la serie 1.3.

Note sull'aggiornamento della sintesi

  • I plugin di sintesi ad alto livello per LinearFunction non sollevano più un errore quando un oggetto diverso da LinearFunction viene passato nel metodo run . Invece, ora restituiscono None, in linea con gli altri plugin. Se ci si è affidati a questo errore, è possibile eseguire manualmente una verifica dell'istanza.

Correzioni di bug

  • In precedenza, il sistema CommutationChecker memorizzava nella cache le relazioni di commutazione di Instructioncon params come chiave per interrogare la relazione. Questo potrebbe portare a risultati errati se la definizione dell'istruzione dipendesse da informazioni aggiuntive rispetto al solo attributo params come, ad esempio, nel caso di PauliEvolutionGate. Questo comportamento è stato corretto e il controllore di commutazione memorizza le commutazioni solo per le porte standard native di Qiskit. Per le porte personalizzate, questa modifica potrebbe comportare un costo in termini di prestazioni; tuttavia, garantisce risultati corretti evitando la memorizzazione nella cache non sicura.

  • È stato risolto un bug nel programma CommutationCheckerin cui la verifica delle relazioni di commutazione di un'istruzione con valori non numerici nell'attributo params (come nel caso di PauliGate) poteva generare un errore. Corretto #13570.

  • Il CommutationChecker non gestisce correttamente le commutazioni degli elementi CRXGate, CRYGate e CRZGate per angoli di rotazione della forma (4k+2)π(4k + 2)\pi, con kZk \in \mathbb Z. In questi casi, si assumeva erroneamente che questi gate commutassero con qualsiasi gate. Questo comportamento è stato corretto e questi gate commutano correttamente con qualsiasi gate solo quando l'angolo di rotazione è un multiplo di 4π4\pi.

  • È stato corretto un bug che causava errori alle seguenti funzioni della libreria dei circuiti quando venivano chiamate con num_qubits=1: efficient_su2(), real_amplitudes(), excitation_preserving() e pauli_two_design() (per un singolo qubit, questi circuiti non contengono porte a 2 qubit). Corretto #13480.

  • Corretto un bug per cui qualsiasi istruzione denominata "mcmt" veniva erroneamente passata alla routine di sintesi di alto livello per un'istruzione di tipo MCMTGatecon conseguente fallimento o risultato non valido. Questo problema potrebbe verificarsi, ad esempio, quando si gestisce il circuito MCMT denominato "mcmt", e convertendolo implicitamente in un'istruzione (ad esempio, quando lo si aggiunge a un altro circuito ). Corretto #13563.

  • È stato risolto un problema a causa del quale la sintesi predefinita della formula di prodotto per PauliEvolutionGate non gestiva correttamente i termini con tutte le identità nell'operatore. Il termine di identità totale dovrebbe introdurre una fase globale pari a -evolution_time, ma è fuori misura di un fattore 2 e potrebbe rompersi per tempi parametrati. Corretto #13625. Corretto #13675. Corretto #13644.

  • Corretta un'incongruenza nel circuito generato dalla sintesi dell'evoluzione di Pauli con l'uso di SuzukiTrotter o LieTrotter (il metodo predefinito). Per i tempi di evoluzione parametrizzati, i circuiti risultanti contenevano parametri con una parte complessa spuria pari a zero, che influenzava l'uscita di ParameterExpression.sympify(). L'output ora contiene correttamente solo valori reali. Corretto #13642.

  • Corretto un bug che causava la produzione di un attributo di fase con forma errata da parte di PauliList.insert() con qubit=True produceva un attributo di fase con una forma errata quando l'oggetto originale era di lunghezza 1. Corretto #13623.

  • Corretto un bug in qasm3.Exporter che causava l'arresto anomalo dell'esportatore durante la gestione di un cancello unitario a causa di un'errata elaborazione del campo params . Corretto #13362.

  • Corretto un bug nel metodo Target.instruction_supported() per cui gli obiettivi con self.num_qubits==None restituivano sempre False , indipendentemente dal set di basi supportato.

  • Corretto un bug nel passaggio UnitarySynthesis in cui i blocchi di UnitaryGatesu 3 o più qubit non venivano sintetizzati correttamente. Ciò comportava, ad esempio, la sovrascrittura del circuito con l'ultimo blocco elaborato o il panico interno quando si incontravano misure dopo un blocco di questo tipo. Corretto #13586.

  • Corretto un bug nel passaggio di UnitarySynthesis in cui le porte di non-2-qubit venivano incluse nella base a 2 qubit disponibile, causando il panico di TwoQubitWeylDecomposition a causa della mancata corrispondenza delle dimensioni.

  • Corretto un bug per cui l'inizializzazione di SparsePauliOp con un numero elevato di termini di Pauli-Y (tipicamente 100\geq 100 ) e nessun coeffs esplicito risultava in un coefficiente vicino a 1 ma con un errore in virgola mobile. Il coefficiente è ora correttamente 1 per default. Corretto #13522.


1.3.1

Preludio

Qiskit 1.3.1 è una versione con correzione di bug minori per la serie 1.3.

Note sull'aggiornamento dei circuiti

  • Il metodo di controllo generico per i gate evita ora di tentare di tradurre i gate in una base supportata quando il gate è già supportato. Ciò può modificare leggermente la sintesi del gate controllato, ma non dovrebbe aumentare il numero di gate a due qubit.

Correzioni di bug


1.3.0

Preludio

La versione di Qiskit 1.3.0 apporta importanti miglioramenti alle prestazioni e alla qualità del transpiler. In questa nuova versione di Qiskit sono state introdotte molte nuove funzionalità, correzioni e miglioramenti:

  • Le strutture dati fondamentali per la trasposizione in Qiskit sono state portate internamente in Rust. Questo include componenti come DAGCircuit, Target, EquivalenceLibrary, e altri. Le API pubbliche per tutte queste strutture di dati rimangono invariate, ma le prestazioni dopo le riscritture sono migliorate.

  • La maggior parte dei passaggi del transpiler utilizzati dal gestore dei passaggi preimpostati sono stati portati in Rust, con un miglioramento medio dei tempi di esecuzione di 6x rispetto a Qiskit 1.2.4 durante l'esecuzione dei benchmark di benchpress. Alcuni dei passaggi particolarmente impattanti che hanno beneficiato delle riscritture sono stati i passaggi BasisTranslator, CommutationAnalysis, ConsolidateBlocks, e UnitarySynthesis. Per un elenco completo dei passaggi portati, si può fare riferimento alle note di rilascio delle funzioni.

  • Miglioramenti alla libreria dei circuiti che aumentano la qualità della compilazione e la velocità di costruzione dei circuiti. Le operazioni si distinguono ora in:

    • Operazioni strutturali, che hanno una decomposizione unica, e sono rappresentate come funzioni che restituiscono un valore QuantumCircuit (ad esempio: real_amplitudes()). La maggior parte di queste funzioni sono costruite in Rust, il che consente di velocizzare notevolmente i tempi di esecuzione della costruzione dei circuiti.
    • Le operazioni astratte, che possono essere implementate utilizzando diverse decomposizioni, sono rappresentate come Gate o Instruction (ad esempio: PauliEvolutionGate). In questo modo è possibile costruire un circuito quantistico astratto e lasciare che il compilatore scelga la decomposizione ottimale.

    L'uso di una descrizione astratta del circuito è particolarmente potente in combinazione con i miglioramenti apportati al passaggio di HighLevelSynthesis transpiler, che ora può tenere conto dei qubit ausiliari inattivi per trovare la migliore decomposizione disponibile per un dato gate.

  • La versione minima supportata di Python è ora 3.9, poiché Python 3.8 ha terminato il suo ciclo di vita nel 2024-10. In questa versione è stato aggiunto anche il supporto ufficiale per Python 3.13.

Caratteristiche dei circuiti

  • Migliorata la funzionalità di CommutationChecker per includere il supporto delle seguenti porte parametrizzate con parametri liberi: RXXGate, RYYGate, RZZGate, RZXGate, RXGate, RYGate, RZGate, PhaseGate, U1Gate, CRXGate, CRYGate, CRZGate, CPhaseGate. In precedenza, questi erano supportati solo con parametri vincolati.

  • Aggiunta una nuova funzione quantum_volume() per generare un volume quantico QuantumCircuit come definito in A. Cross et al. Convalidare i computer quantistici usando circuiti modello randomizzati, Phys. Rev. A 100, 032328 (2019). Questa nuova funzione differisce dalla classe esistente QuantumVolume in quanto restituisce un oggetto QuantumCircuit invece di costruire un oggetto della sottoclasse. La seconda è che questa nuova funzione è multithread e implementata in rust, quindi genera il circuito di uscita ~10x più velocemente della classe QuantumVolume classe.

  • Migliorate le prestazioni di runtime della costruzione della classe QuantumVolume con l'argomento classical_permutation impostato su True. Internamente chiama ora la funzione quantum_volume() che è scritta in Rust ed è ~10x più veloce quando si genera un circuito a volume quantico.

  • Aggiunta una nuova funzione di manipolazione dei circuiti pauli_twirl_2q_gates() che può essere usata per applicare il Pauli twirling a un dato circuito. Questo funziona solo per far ruotare un insieme fisso di porte a due qubit, attualmente CXGate, ECRGate, CZGate, iSwapGate. Ad esempio:

    from qiskit.circuit import QuantumCircuit, pauli_twirl_2q_gates
    
    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    twirled_circuit = pauli_twirl_2q_gates(qc, seed=123456)
    twirled_circuit.draw("mpl")
    _images/release_notes-1.png
  • Aggiunte porte aritmetiche binarie per l'addizione inplace di due registri nn -qubit, cioè abaa+b|a\rangle |b\rangle \mapsto |a\rangle |a+b\rangle. Il ModularAdderGate implementa l'addizione modulo 2n2^n, il registro HalfAdderGate include un qubit di riporto e il FullAdderGate include sia un qubit di riporto che uno di uscita. Per i dettagli e gli esempi, consultare la rispettiva documentazione.

    A differenza dei circuiti di libreria esistenti, come ad esempio CDKMRippleCarryAdderla gestione del gate astratto consente al compilatore (o all'utente) di selezionare la sintesi ottimale del gate, a seconda del contesto del circuito.

  • È stato aggiunto il MultiplierGate per la moltiplicazione di due registri nn -qubit, cioè ab0abab|a\rangle |b\rangle |0\rangle \mapsto |a\rangle |b\rangle |a \cdot b\rangle. Si veda la documentazione della classe per i dettagli e gli esempi.

  • I circuiti quantistici a logica booleana in qiskit.circuit.library hanno ora rappresentazioni equivalenti come Gate oggetti che ne consentono l'uso con HighLevelSynthesis transpiler e l'infrastruttura dei plugin.

  • Sono state aggiunte implementazioni specializzate di __eq__() sono state aggiunte per tutte le porte dei circuiti della libreria standard. La maggior parte dei gate standard era già specializzata in questo metodo, ma alcuni non lo erano e potevano causare rallentamenti significativi in luoghi inaspettati.

  • Aggiunto evolved_operator_ansatz(), hamiltonian_variational_ansatz(), e qaoa_ansatz() nella libreria dei circuiti per implementare circuiti variazionali basati sulle evoluzioni degli operatori. evolved_operator_ansatz() e qaoa_ansatz() sono funzionalmente equivalenti a EvolvedOperatorAnsatz e QAOAAnsatzma generalmente più performanti.

    Il hamiltonian_variational_ansatz() è progettato per prendere una singola hamiltoniana e dividerla automaticamente in termini commutativi per implementare un ansatz variazionale hamiltoniano. Questa operazione poteva già essere eseguita manualmente utilizzando il pulsante EvolvedOperatorAnsatzma ora è più comodo da usare.

  • Aggiunto grover_operator() per costruire un circuito operatore di Grover, utilizzato ad esempio nell'algoritmo di Grover e nella stima/amplificazione dell'ampiezza. Questa funzione è simile a GroverOperatorma non richiede di scegliere l'implementazione della porta X multicontrollata, bensì lascia che sia il compilatore a determinare la decomposizione ottimale. Inoltre, non avvolge il circuito in un gate opaco ed è più veloce perché sono necessarie meno decomposizioni per la trasposizione.

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import grover_operator
    
    oracle = QuantumCircuit(2)
    oracle.z(0)  # good state = first qubit is |1>
    grover_op = grover_operator(oracle, insert_barriers=True)
    grover_op.draw('mpl')
    _images/release_notes-2.png
  • Un nuovo attributo di dati, qiskit.circuit.CONTROL_FLOW_OP_NAMESè disponibile per trovare e verificare facilmente se una data operazione Instruction è un'operazione di flusso di controllo per nome.

  • La libreria di equivalenza standard (SessionEquivalenceLibrary) dispone ora di regole che possono convertire direttamente tra la libreria standard di Qiskit 2q le interazioni continue di tipo Ising (ad es. CPhaseGate, RZZGate, RZXGate, e così via) utilizzando le relazioni di equivalenza locali. In precedenza, molte di queste conversioni passavano attraverso un modulo 2-CX, con il risultato di una generazione di circuiti meno efficiente.

    Nota

    In generale, la funzione BasisTranslator non garantisce di trovare la "migliore" relazione di equivalenza per un dato Targetma troverà sempre un'equivalenza, se esiste. Per migliorare il risultato ci affidiamo a passaggi più costosi di risintesi e ottimizzazione dei gate nel transpiler. Questi passaggi non sono attualmente efficaci per gli insiemi di basi con un'interazione a due equbit parametrizzata in modo continuo, come lo sono per le interazioni a due equbit supercontrollate discrete.

  • Aggiunto un nuovo argomento "apply_synthesis" a Decomposeche consente al passaggio del transpiler di applicare la sintesi di alto livello per decomporre gli oggetti che sono definiti solo da una routine di sintesi. Ad esempio:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import Clifford
    from qiskit.transpiler.passes import Decompose
    
    cliff = Clifford(HGate())
    circuit = QuantumCircuit(1)
    circuit.append(cliff, [0])
    
    # Clifford has no .definition, it is only defined by synthesis
    nothing_happened = Decompose()(circuit)
    
    # this internally runs the HighLevelSynthesis pass to decompose the Clifford
    decomposed = Decompose(apply_synthesis=True)(circuit)
  • Aggiunta la funzione iqp() per costruire circuiti in tempo polinomiale quantistico istantaneo (IQP). Oltre alla classe esistente IQP la funzione permette anche di costruire circuiti IQP casuali:

    from qiskit.circuit.library import random_iqp
    
    random_iqp = random_iqp(num_qubits=4)
    random_iqp.draw('mpl')
    _images/release_notes-3.png
  • È stata aggiunta l'opzione MCMTGate per rappresentare un'operazione multi-controllo multi-target come un gate. Questa rappresentazione a gate del circuito esistente MCMT permette al compilatore di selezionare la migliore implementazione disponibile in base al numero e allo stato dei qubit ausiliari presenti nel circuito.

    L'implementazione desiderata può essere scelta specificando il plugin di sintesi di alto livello:

    from qiskit import QuantumCircuit, transpile
    from qiskit.circuit.library import MCMTGate, HGate
    from qiskit.transpiler.passes import HLSConfig  # used for the synthesis config
    
    mcmt = MCMTGate(HGate(), num_ctrl_qubits=5, num_target_qubits=3)
    
    circuit = QuantumCircuit(20)
    circuit.append(mcmt, range(mcmt.num_qubits))
    
    config = HLSConfig(mcmt=["vchain"])  # alternatively use the "noaux" method
    synthesized = transpile(circuit, hls_config=config)

    Inoltre, il sistema MCMTGate supporta anche stati di controllo personalizzati (cioè aperti) dei qubit di controllo.

  • Nell'ambito dell'ammodernamento della libreria di circuiti, ciascuno dei seguenti circuiti quantistici è rappresentato anche come Gate o può essere costruito con un metodo di sintesi:

  • La classe CommutationChecker è stata riscritta in Rust. Questa classe mantiene le stesse funzionalità e la stessa API pubblica, ma ora è significativamente più veloce nella maggior parte dei casi.

  • PauliFeatureMap e ZZFeatureMap supportano ora la specificazione dell'entanglement come un dizionario in cui le chiavi rappresentano il numero di qubit e i valori sono elenchi di tuple intere che definiscono quali qubit sono entangled tra loro. Ciò consente una maggiore flessibilità nella costruzione di mappe di caratteristiche adatte a specifici algoritmi quantistici. Utilizzo di esempio:

    from qiskit.circuit.library import PauliFeatureMap
    entanglement = {
      1: [(0,), (2,)],
      2: [(0, 1), (1, 2)],
      3: [(0, 1, 2)],
    }
    qc = PauliFeatureMap(3, reps=2, paulis=['Z', 'ZZ', 'ZZZ'], entanglement=entanglement, insert_barriers=True)
    qc.decompose().draw('mpl')
  • Il count_ops() in QuantumCircuit è stato riscritto in Rust. Ora funziona da 3 a 9 volte più velocemente.

  • Aggiunta di funzioni di libreria dei circuiti pauli_feature_map(), z_feature_map(), zz_feature_map() per costruire circuiti di mappe di caratteristiche di Pauli. Queste funzioni sono circa 8x più veloci degli attuali oggetti della libreria di circuiti, PauliFeatureMap, ZFeatureMap, e ZZFeatureMape le sostituiranno in futuro.

    Le funzioni possono essere utilizzate in sostituzione:

    from qiskit.circuit.library import pauli_feature_map, PauliFeatureMap
    
    fm = pauli_feature_map(20, paulis=["z", "xx", "yyy"])
    also_fm = PauliFeatureMap(20, paulis=["z", "xx", "yyy"]).decompose()

Caratteristiche primitive

  • Il supporto per i dati di livello 1 è stato aggiunto a BackendSamplerV2così come il supporto per il passaggio di opzioni al metodo run() della classe wrapped BackendV2. Le opzioni di esecuzione possono essere specificate utilizzando una voce "run_options" all'interno del dizionario options passato a BackendSamplerV2. La voce "run_options" dovrebbe essere un dizionario che mappa i nomi degli argomenti in valori da passare al metodo run() del backend. Quando nelle opzioni di esecuzione è impostato un "meas_level = 1 " , i risultati provenienti dal backend saranno trattati come risultati di livello 1 invece che come array di bit (il formato di livello 2).

  • Estimator e StatevectorEstimator restituire valori di aspettativa in modo stocastico se il circuito di ingresso include un reset per alcuni sottosistemi. Il risultato non era riproducibile in precedenza, ma ora può essere riprodotto se si imposta un seme casuale. Ad esempio:

    from qiskit.primitives import StatevectorEstimator
    
    estimator = StatevectorEstimator(seed=123)

    oppure:

    from qiskit.primitives import Estimator
    
    estimator = Estimator(options={"seed":123})

OpenQASM Caratteristiche

Caratteristiche QPY

  • Aggiunto un nuovo formato QPY versione 13 che aggiunge una rappresentazione nativa Qiskit degli oggetti ParameterExpression oggetti.

Caratteristiche dell'informazione quantistica

  • Le prestazioni di SparsePauliOp.from_operator() è stato ottimizzato sulla base dei metodi di miglioramento dell'algoritmo introdotti in Qiskit 1.0. Ora è circa cinque volte più veloce di prima per le matrici completamente dense, impiegando circa 40ms per decomporre un operatore 10q che coinvolge tutti i termini di Pauli.

  • Aggiunto un nuovo argomento assume_unitary a qiskit.quantum_info.Operator.power(). Quando True, utilizziamo un metodo più rapido basato sulla decomposizione di Schur per elevare un Operator a una potenza frazionaria.

  • Aggiunto SparsePauliOp.to_sparse_list() per convertire un operatore in un formato di elenco sparso. Questo funziona inversamente a SparsePauliOp.from_sparse_list(). Ad esempio:

    from qiskit.quantum_info import SparsePauliOp
    
    op = SparsePauliOp(["XIII", "IZZI"], coeffs=[1, 2])
    sparse = op.to_sparse_list()  # [("X", [3], 1), ("ZZ", [1, 2], 2)]
    
    other = SparsePauliOp.from_sparse_list(sparse, op.num_qubits)
    print(other == op)  # True
  • Le prestazioni di Pauli.to_label() è migliorata in modo significativo per i grandi paoli.

  • Il metodo Operator.power() ha un nuovo parametro branch_cut_rotation. Questo può essere utilizzato per spostare il punto di taglio della radice, il che può influire sulla matrice scelta come radice principale. Per impostazione predefinita, è impostato su una piccola rotazione positiva per rendere le radici degli operatori con un autovalore reale negativo (come gli operatori di Pauli) più stabili rispetto alle differenze di precisione numerica.

  • È stata aggiunta una nuova classe osservabile. SparseObservable rappresenta le osservabili come una somma di termini, in modo simile a SparsePauliOpma con due differenze fondamentali:

    1. Ogni termine completo è memorizzato come (effettivamente) una serie di coppie (qubit, bit_term) , senza memorizzare i qubit che subiscono l'identità per quel termine. Questo migliora significativamente l'utilizzo della memoria di osservabili come la somma ponderata di Paulis iciZi\sum_i c_i Z_i.
    2. L'alfabeto dei termini a singolo-qubit è sovraccompleto per lo spazio degli operatori; può rappresentare operatori di Pauli (come SparsePauliOp), ma anche proiettori sugli autostati degli operatori di Pauli, come 00\lvert 0\rangle\langle 0\rangle. Tali proiettori possono essere misurati su hardware con la stessa efficienza del loro corrispondente operatore di Pauli, ma SparsePauliOp richiederebbe un numero esponenziale di termini per rappresentare 00n{\lvert0\rangle\langle0\rvert}^{\otimes n} su nn qubit, mentre SparseObservable ha bisogno di un solo termine.

    È possibile costruire e manipolare SparseObservable utilizzando un'interfaccia familiare agli utenti di SparsePauliOp:

    from qiskit.quantum_info import SparseObservable
    
    obs = SparseObservable.from_sparse_list([
      ("XZY", (2, 1, 0), 1.5j),
      ("+-", (100, 99), 0.5j),
      ("01", (50, 49), 0.5),
    ])

    SparseObservable non è attualmente supportato come formato di ingresso alle primitive (qiskit.primitives), ma si prevede di espandere queste interfacce per includerle in futuro.

Caratteristiche della sintesi

  • Aggiunta di funzioni di sintesi synth_mcx_gray_code() e synth_mcx_noaux_v24() che sintetizzano porte X a controllo multiplo. Queste funzioni non richiedono qubit ancilla aggiuntivi.

  • Aggiunta di funzioni di sintesi synth_c3x() e synth_c4x() che sintetizzano rispettivamente le porte X a 3 e a 4 controlli.

  • Aggiungere una funzione di sintesi synth_mcx_n_dirty_i15() che sintetizza una porta X multicontrollata con kk controlli usando k2k - 2 qubit ancillari sporchi che producono un circuito con al massimo 8k68 * k - 6 porte CX, di Iten et. al. (arXiv:1501.06911).

  • Aggiungere una funzione di sintesi synth_mcx_n_clean_m15() che sintetizza una porta X multicontrollata con kk controlli utilizzando k2k - 2 qubit ancillari puliti, producendo un circuito con al massimo 6k66 * k - 6 porte CX, di Maslov ( arXiv:1508.03273 ).

  • Aggiungere una funzione di sintesi synth_mcx_1_clean_b95() che sintetizza una porta X multicontrollata con kk controlli utilizzando un singolo qubit ancillare pulito, producendo un circuito con al massimo 16k816 * k - 8 porte CX, di Barenco et al. ( arXiv:quant-ph/9503016 ).

  • Aggiunto adder_qft_d00(), adder_ripple_c04(), e adder_ripple_v95() per sintetizzare le porte dell'addizionatore, ModularAdderGate, HalfAdderGate, e FullAdderGate.

  • Aggiunto multiplier_cumulative_h18() e multiplier_qft_r17() per sintetizzare il MultiplierGate.

  • Aggiunto synth_mcmt_vchain() per sintetizzare il gate multi-target a controllo multiplo con un numero lineare di porte di Toffoli e k-1 qubit ausiliari per k qubit di controllo, insieme al plugin di sintesi ad alto livello MCMTSynthesisVChain.

  • Aggiunta di una struttura di plugin di sintesi di alto livello per il file MCMTGate, che include il MCMTSynthesisNoAux (per nessun qubit ausiliario), il già citato MCMTSynthesisVChain (con l'uso di num_control - 1 qubit ausiliari) e l'opzione MCMTSynthesisDefault per consentire al compilatore di scegliere la decomposizione ottimale.

  • La funzione random_clifford() è stata trasferita a Rust, migliorando il tempo di esecuzione di un fattore 3.

  • Aggiunto ProductFormula.expand()che consente di visualizzare l'espansione di una formula di prodotto in un formato Pauli rado. Ad esempio, possiamo interrogare il formato di un'espansione di Trotter del secondo ordine di un'hamiltoniana come:

    from qiskit.quantum_info import SparsePauliOp
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.synthesis.evolution import SuzukiTrotter
    
    hamiltonian = SparsePauliOp(["IX", "XI", "ZZ"], coeffs=[-1, -1, 1])
    evo = PauliEvolutionGate(hamiltonian, time=3.14)
    trotter = SuzukiTrotter(order=2)
    print(trotter.expand(evo))

    che stamperà

    [('X', [0], -3.14), ('X', [1], -3.14), ('ZZ', [0, 1], 6.28),
    ('X', [1], -3.14), ('X', [0], -3.14)]
  • Aggiunta la struttura del plugin per il file PauliEvolutionGate. Il plugin predefinito, PauliEvolutionSynthesisDefaultcostruisce il circuito come prima, ma in modo più veloce, perché utilizza internamente Rust. Più grande è il circuito (ad esempio. dalla dimensione dell'hamiltoniano, dal numero di timestep o dall'ordine di Suzuki-Trotter), maggiore sarà la velocizzazione. Ad esempio, un'hamiltoniana di Heisenberg a 100 qubit con 10 timestep e una formula di Trotter del 4° ordine è ora costruita ~9.4x più velocemente. Il nuovo plugin, PauliEvolutionSynthesisRustiqutilizza l'algoritmo di sintesi descritto nell'articolo " Faster and shorter synthesis of Hamiltonian simulation circuits" di (de) Brugière e Martiel " ed è implementato in Rustiq. Ad esempio:

    from qiskit.circuit import QuantumCircuit
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.circuit.library import PauliEvolutionGate
    from qiskit.compiler import transpile
    from qiskit.transpiler.passes import HLSConfig
    
    op = SparsePauliOp(["XXX", "YYY", "IZZ"])
    qc = QuantumCircuit(4)
    qc.append(PauliEvolutionGate(op), [0, 1, 3])
    config = HLSConfig(PauliEvolution=[("rustiq", {"upto_phase": False})])
    tqc = transpile(qc, basis_gates=["cx", "u"], hls_config=config)
    tqc.draw(output='mpl')
    _images/release_notes-4.png

    Questo frammento di codice utilizza il plugin di Rustiq per sintetizzare PauliEvolutionGate oggetti nel circuito quantistico qc. Il plugin viene richiamato con l'opzione aggiuntiva upto_phase = False, che consente di ottenere circuiti più piccoli a costo di non conservare la fase globale. Per l'elenco completo delle opzioni supportate, consultare la documentazione di PauliEvolutionSynthesisRustiq.

  • Porto synth_cz_depth_line_mr() a Rust. Questa funzione sintetizza un circuito CZ per la connettività linear nearest neighbor (LNN), basato sul metodo di Maslov e Roetteler. Su una matrice binaria 350x350, l'implementazione di Rust produce un aumento di velocità di circa 30x.

  • Porta synth_permutation_reverse_lnn_kms() a Rust, che sintetizza una permutazione inversa per l'architettura LNN utilizzando il metodo di Kutin, Moulton, Smithline.

  • Aggiunto un nuovo argomento preserve_order a ProductFormulache consente di riordinare i termini di Pauli nell'Hamiltoniana prima dell'espansione della formula del prodotto, per comprimere la profondità del circuito finale. Impostando questo valore a False, si ottiene un termine della forma

Z0Z1+X1X2+Y2Y3Z_0 Z_1 + X_1 X_2 + Y_2 Y_3

saranno riordinati in

Z0Z1+Y2Y3+X1X2Z_0 Z_1 + Y_2 Y_3 + X_1 X_2

che porterà le rotazioni RZZ e RYY ad essere applicate in parallelo, invece delle tre rotazioni sequenziali della prima parte.

Questa opzione può essere impostata tramite l'interfaccia del plugin:

from qiskit import QuantumCircuit, transpile
from qiskit.circuit.library import PauliEvolutionGate
from qiskit.quantum_info import SparsePauliOp
from qiskit.synthesis.evolution import SuzukiTrotter
from qiskit.transpiler.passes import HLSConfig

op = SparsePauliOp(["XXII", "IYYI", "IIZZ"])
time, reps = 0.1, 1

synthesis = SuzukiTrotter(order=2, reps=reps)
hls_config = HLSConfig(PauliEvolution=[("default", {"preserve_order": False})])

circuit = QuantumCircuit(op.num_qubits)
circuit.append(PauliEvolutionGate(op, time), circuit.qubits)

tqc = transpile(circuit, basis_gates=["u", "cx"], hls_config=hls_config)
tqc.draw('mpl')
_images/release_notes-5.png

Funzionalità del transpiler

  • Aggiungere l'argomento matrix_based al passaggio del transpiler CollectCliffords al passaggio del transpiler. Se il nuovo parametro matrix_based=True, il CollectCliffords transpiler può raccogliere porte unitarie che sono porte di Clifford per determinati parametri, per esempio RZGate porte con angoli multipli di π/2\pi / 2.

  • Il passaggio RemoveIdentityEquivalent il passaggio del transpiler viene ora eseguito come parte dei gestori dei passaggi preimpostati ai livelli di ottimizzazione 2 e 3. Il passaggio viene eseguito durante le fasi init e optimization , perché le ottimizzazioni che applica sono valide in entrambe le fasi e il passaggio è veloce da eseguire.

  • Sono stati aggiunti più plugin di sintesi ad alto livello per sintetizzare una MCXGate:

    Così come:

    • MCXSynthesisDefaultper scegliere il metodo di sintesi più efficiente in base al numero di qubit ancilla puliti e sporchi disponibili.

    A titolo di esempio, si consideri la trasposizione del seguente circuito:

    from qiskit.circuit import QuantumCircuit
    from qiskit.compiler import transpile
    
    qc = QuantumCircuit(7)
    qc.x(0)
    qc.mcx([0, 1, 2, 3], [4])
    qc.mcx([0, 1, 2, 3, 4], [5])
    qc.mcx([0, 1, 2, 3, 4, 5], [6])
    
    transpile(qc).draw('mpl', fold=-1)
    _images/release_notes-6.png

    Per il primo gate MCX, i qubit 5 e 6 possono essere utilizzati come ancillas puliti, e il miglior metodo di sintesi disponibile synth_mcx_n_clean_m15 verrà scelto. Per il secondo gate MCX, il qubit 6 può essere utilizzato come ancilla pulita, il metodo synth_mcx_n_clean_m15 non è più applicabile, quindi verrà scelto il metodo synth_mcx_1_clean_b95 . Per il terzo gate MCX, non ci sono qubit ancilla e viene scelto il metodo synth_mcx_noaux_v24 .

  • Il passaggio del transpiler SabreLayout è stato aggiornato per eseguire due o tre prove aggiuntive di layout per impostazione predefinita, indipendentemente dal valore dell'argomento della parola chiave layout_trials . Un layout banale e il suo inverso sono inclusi per tutti i backend, proprio come il DenseLayout aggiunto in 1.2.0. Inoltre, vengono aggiunti gli anelli più grandi su un grafo di connettività esagonale pesante del backend IBM se i backend sono di 127, 133 o 156 qubit. Questo può fornire un buon punto di partenza per alcuni circuiti su questi backend comunemente utilizzati, mentre per tutti gli altri è solo un'ulteriore "prova casuale".

  • Il DAGCircuit è stato reimplementato in Rust. Questa riscrittura della classe Python dovrebbe essere completamente compatibile con l'API della precedente implementazione di Python. Mentre la classe è stata precedentemente implementata utilizzando rustworkx, per il quale la struttura del grafo di dati sottostante esiste in Rust, l'implementazione della classe e di tutti i dati è stata vissuta in Python. Questa nuova versione di DAGCircuit memorizza le rappresentazioni native di Rust per tutti i suoi dati ed è più efficiente in termini di memoria, grazie alla rappresentazione compressa di qubit e clbit progettata per le istruzioni a riposo. Permette inoltre ai passaggi del transpiler di manipolare completamente un file DAGCircuit da Rust, consentendo di migliorare le prestazioni.

  • Un nuovo argomento qubits_initially_zero è stato aggiunto a qiskit.compiler.transpile(), generate_preset_pass_manager()e a PassManagerConfig. Se impostato sul valore predefinito di True, si presume che i qubit siano inizialmente nello stato 0|0\rangle, consentendo potenzialmente ulteriori opportunità di ottimizzazione per i singoli passaggi del transpiler. In particolare, il HighLevelSynthesis transpiler sceglierà una decomposizione migliore per ogni MCXGate di un circuito quando è disponibile un qubit ausiliario inattivo nello stato 0|0\rangle.

    Tuttavia, ci sono casi in cui qubits_initially_zero dovrebbe essere impostato su False, ad esempio quando si esegue il transpiling per backend che non inizializzano correttamente i qubit, o quando si chiamano manualmente i passaggi del transpiler su sottocircuiti di un circuito quantistico più grande.

  • Il costruttore per il passaggio HighLevelSynthesis accetta ora un parametro aggiuntivo: qubits_initially_zero. Se impostato su True, il passaggio assume che i qubit siano inizialmente nello stato 0|0\rangle. Inoltre, il passo tiene traccia dei qubit ausiliari puliti e sporchi durante l'esecuzione e passa queste informazioni ai plugin utilizzando i kwarg num_clean_ancillas e num_dirty_ancillas.

  • Migliorata la gestione dei qubit ancilla nel passaggio di HighLevelSynthesis transpiler. Ad esempio, un circuito può avere porte personalizzate le cui definizioni includono MCXGates. Ora gli algoritmi di sintesi per gli inner MCXGatepossono utilizzare i qubit ancilla disponibili sul circuito globale ma al di fuori delle definizioni delle porte personalizzate.

  • Aggiunto un nuovo metodo DAGCircuit.control_flow_op_nodes() che fornisce un percorso veloce per ottenere tutti gli elementi DAGOpNode in un oggetto DAGCircuit che contengono a ControlFlowOp. Questo era possibile prima di utilizzare il metodo DAGCircuit.op_nodes() e passando la classe ControlFlowOp come filtro, ma questa nuova funzione eseguirà l'operazione più velocemente.

  • La maggior parte dei passaggi del transpiler utilizzati nei gestori dei passaggi preimpostati restituiti da generate_preset_pass_manager() e utilizzati internamente da transpile() sono stati portati in Rust. Questo ha migliorato in modo significativo le prestazioni di runtime di ogni passaggio, con un conseguente miglioramento dell'efficienza operativa complessiva del transpiler. L'elenco dei passaggi portati a Rust in questa versione sono:

  • Aggiunto un nuovo passaggio di transpiler, RemoveIdentityEquivalent che viene utilizzato per rimuovere le porte che sono equivalenti a un'identità fino a una certa tolleranza. Ad esempio, se si dispone di un circuito come:

    _images/release_notes-7.png

    l'esecuzione del passaggio eliminerebbe il CPhaseGate:

    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler.passes import RemoveIdentityEquivalent
    
    qc = QuantumCircuit(2)
    qc.cp(1e-20, 0, 1)
    
    removal_pass = RemoveIdentityEquivalent()
    result = removal_pass(qc)
    result.draw("mpl")
    _images/release_notes-8.png
  • Il passaggio ConsolidateBlocks eseguirà l'equivalente del passaggio Collect2qBlocks internamente, se non è stato eseguito in un gestore di passaggi prima del passaggio. In precedenza, Collect2qBlocks o Collect1qRuns doveva essere eseguito prima di ConsolidateBlocks perché ConsolidateBlocks per fare qualcosa. Eseguendo la raccolta internamente, si riduce l'overhead del passaggio. Se Collect2qBlocks o Collect1qRuns vengono eseguiti prima di ConsolidateBlocks, vengono utilizzate le corse raccolte da quei passaggi dell'insieme di proprietà e non c'è alcun cambiamento di comportamento per il passaggio.

  • Il RemoveDiagonalGatesBeforeMeasure il passaggio del transpiler è stato aggiornato per includere più porte diagonali: PhaseGate, CPhaseGate, CSGate, CSdgGate e CCZGate. Inoltre, il codice del progetto RemoveDiagonalGatesBeforeMeasure è stato portato a Rust e ora è x20 più veloce per un circuito a 20 qubit.

Funzionalità di visualizzazione

  • La funzione timeline_drawer() la funzione di visualizzazione dispone di un nuovo argomento target, utilizzato per specificare un Target per la visualizzazione. Per impostazione predefinita, la funzione utilizza il parametro Instruction.duration per ottenere la durata di una data istruzione, ma se si specifica il target si sfrutteranno invece i dettagli di temporizzazione all'interno del target.

Problemi noti

  • Quando si usano i formati 10, 11 o 12 di QPY con circuiti che contengono ParameterExpressions, se la versione del pacchetto symengine installata nell'ambiente che ha generato il payload (qpy.dump()) non corrisponde alla versione di symengine installata nell'ambiente in cui viene caricato il payload (qpy.load()), si otterrà un errore. Se si verifica questo errore, installare la versione di symengine dal messaggio di errore prima di chiamare qpy.load(). Le versioni del formato QPY 13 o successive (o precedenti alla 10) non presentano questo problema. Pertanto, se si serializzano oggetti ParameterExpression oggetti come parte del circuito o di qualsiasi ScheduleBlock si consiglia di utilizzare la versione 13 per evitare questo problema in futuro.

Note sull'aggiornamento

  • Le seguenti classi utilizzano ora l'operazione X\sqrt{X} per diagonalizzare l'operatore Pauli-Y: PauliEvolutionGate, EvolvedOperatorAnsatz, e PauliFeatureMap. In precedenza, queste classi utilizzavano HSH S o RX(π/2)R_X(-\pi/2) come trasformazione di base. L'utilizzo dell'operazione X\sqrt{X}, rappresentata dal simbolo SXGate è più efficiente perché utilizza un solo gate implementato come singleton.

    Se vi siete basati sull'utilizzo del gate precedente, vi consigliamo di costruire i circuiti con Qiskit 1.2 e di esportarli con qpy.dump()oppure di scrivere un programma personalizzato TransformationPassche esegue la traduzione nel gate di cambio di base desiderato.

  • La versione minima supportata di Python è ora 3.9, che è stata aumentata rispetto alla precedente versione minima supportata di 3.8. Questa modifica si è resa necessaria perché il progetto upstream cPython non supporta più Python 3.8.

Note sull'aggiornamento dei circuiti

  • La classe QuantumVolume genera circuiti con matrici unitarie e permutazioni diverse per un dato valore di seme della precedente versione di Qiskit. Ciò è dovuto all'utilizzo di un nuovo generatore di numeri casuali interno per la generazione del circuito, che genera il circuito più rapidamente. Se avete bisogno di un circuito esatto con lo stesso seme, potete usare la versione precedente di Qiskit e generare il circuito con l'argomento flatten=True ed esportare il circuito con qpy.dump() e poi caricarlo con questa versione.

Note sull'aggiornamento delle primitive

  • Quando si utilizza BackendSamplerV2i metadati dei circuiti non vengono più cancellati prima di passare i circuiti al metodo run() dell'istanza wrapped BackendV2 dell'istanza wrapped. Se in precedenza ci si affidava a questo comportamento, è possibile cancellare manualmente i metadati prima di richiamare il comando BackendSamplerV2.run() chiamando circuit.metadata.clear()

Note sull'aggiornamento QPY

  • La funzione qpy.dump() emette ora la versione 13 del formato per impostazione predefinita. Ciò significa che i payload generati con questa funzione sono compatibili solo con Qiskit 1.3.0 o successivi. Se il payload deve essere caricato da una versione precedente di Qiskit, utilizzate il flag version su qpy.dump() per emettere la versione appropriata. Per maggiori dettagli, consultare la sezione Compatibilità QPY.

Note sull'aggiornamento del transpiler

  • DAGNode (e le sue sottoclassi DAGInNode, DAGOutNode, e DAGOpNode) non restituiscono più riferimenti allo stesso oggetto sottostante dai metodi di DAGCircuit metodi. In precedenza non era mai stato garantito che tutti i nodi restituiti fossero riferimenti condivisi allo stesso oggetto. Tuttavia, con la migrazione di DAGCircuit a Rust, una nuova istanza di DAGNode viene generata al volo quando un nodo viene restituito a Python. Questi oggetti saranno valutati come uguali utilizzando == o controlli simili che si basano su __eq__ , ma non saranno più identificati come lo stesso oggetto.

  • Le DAGOpNode restituite dal metodo DAGCircuit non sono più riferimenti condivisi ai dati sottostanti memorizzati nel DAG. Nella versione precedente era possibile fare qualcosa come:

    for node in dag.op_nodes():
        node.op = new_op

    tuttavia, questo tipo di mutazione è sempre stato scorretto, in quanto potrebbe rompere la cache interna del DAG e causare la corruzione della struttura dei dati. Si dovrebbe invece utilizzare l'API fornita da DAGCircuit per la mutazione, come DAGCircuit.substitute_node() o DAGCircuit.substitute_node_with_dag(). Ad esempio, il blocco di codice sopra riportato diventerebbe:

    for node in dag.op_nodes():
      dag.substitute_node(node, new_op)

    Questo è simile a una nota di aggiornamento di 1.2.0 in cui è stato notato per la mutazione dell'attributo DAGOpNode.op e non dell'attributo DAGOpNode stesso. Tuttavia, in 1.3 questo si estende all'intero oggetto, non solo all'attributo interno op . In generale, questo tipo di mutazione è sempre stato scorretto e non supportato, ma in passato poteva potenzialmente funzionare in alcuni casi.

  • Il transpile() assume che i qubit siano inizialmente nello stato 0|0\rangle. Per evitare questa assunzione, si può impostare l'argomento qubits_initially_zero a False.

Note di deprecazione

  • Il modulo qiskit.pulse e tutte le sue caratteristiche associate sono ora deprecate e saranno rimosse in Qiskit 2.0.0. Questo perché il principale fornitore di backend con supporto per gli impulsi è IBM e l'accesso a livello di impulsi è attualmente supportato solo da un sottoinsieme di backend di IBM e non è supportato dalle architetture più recenti. Allo stesso modo hanno annunciato che l' accesso a livello di impulsi sarà rimosso nel 2025 Senza che il più grande provider che utilizza la funzione supporti ancora l'accesso a livello di impulsi, l'importanza della funzione per Qiskit è significativamente diminuita e, se si considera l'onere di manutenzione continua del pacchetto, viene rimossa.

    La deprecazione include tutto il codice di Pulse in qiskit.pulse così come le funzionalità che dipendono o sono correlate a pulse, come la visualizzazione degli impulsi, la serializzazione e il supporto alla calibrazione personalizzata. Per maggiori dettagli, vedere le sezioni sulla deprecazione riportate di seguito.

    Il pacchetto Pulse nel suo complesso, insieme ai componenti direttamente collegati in Qiskit, sarà spostato nel repository Qiskit Dynamics per consentire ulteriormente la simulazione degli impulsi e dei controlli di basso livello. Qiskit 1.x continuerà a supportare il sistema qiskit.pulse fino alla fine del suo ciclo di vita.

Circuiti deprecati

  • Deprecato l'attributo Instruction.condition e il metodo Instruction.c_if() metodo. Saranno rimossi in Qiskit 2.0, insieme a qualsiasi utilizzo nel modello di dati di Qiskit. Questa funzionalità è stata sostituita dalla classe IfElseOp che può essere utilizzata per descrivere una condizione classica in un circuito. Ad esempio, un circuito che utilizza Instruction.c_if() come:

    from qiskit.circuit import QuantumCircuit
    
    qc = QuantumCircuit(2, 2)
    qc.h(0)
    qc.x(0).c_if(0, 1)
    qc.z(1.c_if(1, 0)
    qc.measure(0, 0)
    qc.measure(1, 1)

    Può essere riscritto come:

    qc = QuantumCircuit(2, 2)
    qc.h(0)
    with qc.if_test((qc.clbits[0], True)):
        qc.x(0)
    with qc.if_test((qc.clbits[1], False)):
        qc.z(1)
    qc.measure(0, 0)
    qc.measure(1, 1)

    L'ormai deprecato ConvertConditionsToIfOps può essere usato per automatizzare questa conversione per i circuiti esistenti.


  • Nell'ambito della dismissione del pacchetto Qiskit Pulse, anche le seguenti dipendenze sono state dismesse:

  • Il QuantumCircuit.unit e QuantumCircuit.duration sono stati deprecati e saranno rimossi in Qiskit 2.0.0. Questi attributi sono stati utilizzati per tracciare la durata stimata e l'unità di tale durata da eseguire sul circuito. Tuttavia, i valori di questi attributi erano sempre limitati, poiché venivano popolati correttamente solo se il transpiler veniva eseguito con le impostazioni corrette. Anche la durata era solo una supposizione basata sul percorso più lungo sulla somma delle durate di DAGCircuit e non terrebbe mai conto correttamente del flusso di controllo o delle condizioni nel circuito.

  • Il DAGCircuit.unit e DAGCircuit.duration sono stati deprecati e saranno rimossi in Qiskit 2.0.0. Questi attributi sono stati utilizzati per tracciare la durata stimata e l'unità di tale durata da eseguire sul circuito. Tuttavia, i valori di questi attributi erano sempre limitati, poiché venivano popolati correttamente solo se il transpiler veniva eseguito con le impostazioni corrette. Anche la durata era solo una supposizione basata sul percorso più lungo sulla somma delle durate di DAGCircuit e non terrebbe mai conto correttamente del flusso di controllo o delle condizioni nel circuito.

  • Il Instruction.duration e Instruction.unit sono stati deprecati e saranno rimossi in Qiskit 2.0.0. Questo include l'impostazione degli argomenti unit o duration per qualsiasi classe o sottoclasse qiskit.circuit.Instruction o di una sottoclasse. Questi attributi sono stati utilizzati per attribuire una durata di esecuzione personalizzata e un'unità per tale durata a una singola istruzione. Tuttavia, la fonte di verità della durata di un cancello è la BackendV2 Target che contiene la durata di ogni istruzione supportata dal backend. La durata di un'istruzione non è tipicamente regolabile dall'utente ed è una proprietà immutabile del backend. Se in precedenza si utilizzava questa funzionalità per sperimentare diverse durate per i gate, è possibile modificare il campo InstructionProperties.duration in un dato campo Target per impostare una durata personalizzata per un'istruzione su un backend (l'unità è sempre in secondi nel campo Target).

Deprecazioni dei provider

  • Il metodo BasicSimulator.configuration() è deprecato e sarà rimosso in 2.0.0. Questo metodo restituisce un'istanza legacy di providers.models.BackendConfiguration , che fa parte del modello deprecato di BackendV1 . Questo modello è stato sostituito con BackendV2in cui i vincoli sono memorizzati direttamente nell'istanza del backend o nel database sottostante Target (backend.target).

    Ecco una guida rapida per accedere agli attributi più comuni di BackendConfiguration nel modello BackendV2 modello:

    BackendV1 model (deprecated) ------------> BackendV2 model
    ----------------------------               ---------------
    backend.configuration().backend_name       backend.name
    backend.configuration().backend_version    backend.backend_version
    backend.configuration().n_qubits           backend.num_qubits
    backend.configuration().num_qubits         backend.num_qubits
    backend.configuration().basis_gates        backend.target.operation_names (*)
    backend.configuration().coupling_map       backend.target.build_coupling_map()
    backend.configuration().local              No representation
    backend.configuration().simulator          No representation
    backend.configuration().conditional        No representation
    backend.configuration().open_pulse         No representation     
    backend.configuration().memory             No representation      
    backend.configuration().max_shots          No representation      

    (*) Si noti che Backend.target.operation_names include basis_gates e altre istruzioni non gate; in alcune implementazioni potrebbe essere necessario filtrare l'uscita.

    Consultare questa guida per ulteriori informazioni sulla migrazione a BackendV2 modello.


  • Nell'ambito della dismissione del pacchetto Qiskit Pulse, tutte le funzionalità relative a pulse nella qiskit.providers.BackendV2 classe sono state dismesse. Ciò include i seguenti metodi:

    Di conseguenza, i corrispondenti metodi di canale nelle qiskit.providers.BackendV2Converter e qiskit.providers.fake_provider.GenericBackendV2 vengono anch'essi deprecati.

    Inoltre, gli argomenti pulse_channels e calibrate_instructions del metodo BackendV2 vengono deprecati.

  • L'argomento defaults è stato deprecato dalla funzione qiskit.providers.convert_to_target() funzione.

Deprecazioni QPY

Deprecazioni del transpiler

  • Deprecato StochasticSwap che è stato sostituito da SabreSwap. Se la classe viene richiamata dalla funzione transpile, la modifica sarà, ad esempio, la seguente:

    from qiskit import transpile
    from qiskit.circuit import QuantumCircuit
    from qiskit.transpiler import CouplingMap
    from qiskit.providers.fake_provider import GenericBackendV2
    
    
    qc = QuantumCircuit(4)
    qc.h(0)
    qc.cx(0, range(1, 4))
    qc.measure_all()
    
    cmap = CouplingMap.from_heavy_hex(3)
    backend = GenericBackendV2(num_qubits=cmap.size(), coupling_map=cmap)
    
    tqc = transpile(
        qc,
        routing_method="stochastic",
        layout_method="dense",
        seed_transpiler=12342,
        target=backend.target
    )

    a:

    tqc = transpile(
        qc,
        routing_method="sabre",
        layout_method="sabre",
        seed_transpiler=12342,
        target=backend.target
    )

    Mentre per un gestore di passaggi, il cambiamento sarebbe:

    passmanager = PassManager(StochasticSwap(coupling, 20, 13))
    new_qc = passmanager.run(qc)

    a:

    passmanager = PassManager(SabreSwap(backend.target, "basic"))
    new_qc = passmanager.run(qc)
  • Il passaggio del transpiler ConvertConditionsToIfOps è stato deprecato e sarà rimosso in Qiskit 2.0.0. Questa classe è ora deprecata perché il modello di dati sottostante a Instruction.condition da cui questo passaggio viene convertito è stato deprecato e sarà rimosso in 2.0.0.

  • La fornitura di porte personalizzate attraverso l'argomento basis_gates è deprecata per entrambi gli argomenti transpile() e generate_preset_pass_manager(). Questa funzionalità sarà rimossa in Qiskit 2.0. Le porte personalizzate sono ancora supportate nel modello Target e possono essere fornite tramite l'argomento target . Si può costruire un'istanza Target da zero o utilizzare il metodo Target.from_configuration() con l'argomento custom_name_mapping . Ad esempio:

    from qiskit.circuit.library import XGate
    from qiskit.transpiler.target import Target
    
    basis_gates = ["my_x", "cx"]
    custom_name_mapping = {"my_x": XGate()}
    target = Target.from_configuration(
        basis_gates=basis_gates, num_qubits=2, custom_name_mapping=custom_name_mapping
    )

  • Nell'ambito della dismissione del pacchetto Qiskit Pulse, gli aspetti relativi al pulsante nella qiskit.transpiler.Target classe vengono dismessi. Queste release includono:


    Inoltre, anche i seguenti passaggi del transpiler stanno per essere deprecati:

  • L'argomento inst_map in generate_preset_pass_manager(), from_configuration(), PassManagerConfig inizializzatore e generate_scheduling() viene deprecato.

  • L'argomento calibration nei metodi di inizializzazione InstructionProperties() nei metodi di inizializzazione viene deprecato.

  • Il seguente transpile() e generate_preset_pass_manager() sono deprecati in favore della definizione di un parametro personalizzato Target: instruction_durations, timing_constraints, e backend_properties. Questi argomenti possono essere usati per costruire un obiettivo con Target.from_configuration():

    Target.from_configuration(
         ...
         backend_properties = backend_properties,
         instruction_durations = instruction_durations,
         timing_constraints = timing_constraints
    )
  • Il metodo PassManagerConfig.from_backend() smetterà di supportare gli input di tipo BackendV1 nel parametro backend in una release futura non prima di 2.0. BackendV1 è deprecato e le implementazioni dovrebbero passare a BackendV2.

Varie Deprecazioni

Correzioni di bug

  • È stata risolta una regressione delle prestazioni in QuantumCircuit.assign_parameters() introdotto in Qiskit 1.2.0 quando si richiamava il metodo in un ciclo stretto, che causava il vincolo di un piccolo numero di parametri di un circuito fortemente parametrico a ogni iterazione. Se possibile, è ancora più performante richiamare il programma assign_parameters() solo una volta, con tutte le assegnazioni allo stesso tempo, in quanto ciò riduce la percentuale di tempo spesa per la normalizzazione dell'input e l'overhead del controllo degli errori.

  • Per BasicSimulator, la voce basis_gates nell'istanza di configurazione restituita dal metodo configuration() è ora un elenco anziché un'istanza dict_keys , corrispondendo al tipo previsto e consentendo la copia profonda dell'istanza di configurazione.

  • Corretto un problema con DAGCircuit.apply_operation_back() e DAGCircuit.apply_operation_front() dove in precedenza se si impostava un oggetto Clbit all'input per l'argomento qargs veniva accettato silenziosamente. Questo problema è stato risolto in modo che la mancata corrispondenza del tipo venga identificata correttamente e venga sollevata un'eccezione.

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

  • Corretto un bug in QuantumCircuit.assign_parameters()che si verificava quando si assegnavano parametri a porte standard la cui definizione era già stata attivata. In questo caso, i nuovi valori non sono stati propagati correttamente alle istanze del gate. Mentre il circuito stesso veniva compilato come previsto, ispezionando le singole operazioni si notava ancora il vecchio parametro.

    Ad esempio:

    from qiskit.circuit.library import EfficientSU2
    
    circuit = EfficientSU2(2, flatten=True)
    circuit.assign_parameters([1.25] * circuit.num_parameters, inplace=True)
    print(circuit.data[0].operation.params)  # would print θ[0] instead of 1.25

    Corretto #13478.

  • Corretto un bug con l'entanglement di "circular" e di "sca" per i NLocal e i suoi derivati. Per i blocchi di entanglement di più di 2 qubit, l'entanglement circolare mancava in precedenza di alcune connessioni. Ad esempio, per 4 qubit e una dimensione di blocco di 3, il codice precedentemente utilizzato:

    [(2, 3, 0), (0, 1, 2), (1, 2, 3)]

    ma ora sta aggiungendo correttamente le connessioni di (3, 0, 1) :

    [(2, 3, 0), (3, 0, 1), (0, 1, 2), (1, 2, 3)]

    Per questo motivo, gli entanglement "circular" e "sca" utilizzano blocchi di entangling num_qubits per strato.

  • Aggiungere altre porte di Clifford al CollectCliffords passaggio del transpiler. In particolare, abbiamo aggiunto le porte ECRGate, DCXGate, iSwapGate, SXGate e SXdgGate a questo passaggio del transpiler.

  • Corretto un bug in QuantumCircuit.decompose() in cui gli oggetti che potevano essere sintetizzati con HighLevelSynthesis venivano prima sintetizzati e poi scomposti immediatamente (cioè venivano scomposti due volte invece che una). Questo ha influito su cancelli come MCXGate o Clifford, tra gli altri.

  • Corretto un bug in QuantumCircuit.decompose()in cui gli oggetti di alto livello senza definizione non venivano decomposti se erano impostati esplicitamente tramite l'argomento "gates_to_decompose" . Ad esempio, in precedenza la seguente operazione non eseguiva la decomposizione, ma ora funziona come previsto:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import Clifford
    from qiskit.transpiler.passes import Decompose
    
    cliff = Clifford(HGate())
    circuit = QuantumCircuit(1)
    circuit.append(cliff, [0])
    
    decomposed = Decompose(gates_to_decompose=["clifford"])(circuit)
  • In precedenza il HighLevelSynthesis sintetizzava un'istruzione per la quale è disponibile un plugin di sintesi, indipendentemente dal fatto che l'istruzione sia già supportata dal target o faccia parte del passaggio esplicito basis_gates. Questo comportamento è stato corretto, in modo che tali istruzioni già supportate non vengano più sintetizzate.

  • Il passaggio di trasposizione InverseCancellation ora ricorrerà in ControlFlowOp presenti in un file QuantumCircuit. In precedenza, il passaggio ignorava le coppie di gate inversi all'interno dei blocchi del flusso di controllo che avrebbero potuto essere annullati. Per maggiori dettagli, consultare il numero #13437.

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

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

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

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

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

  • Corretto un bug quando SparsePauliOp.paulis è impostato per essere un elemento PauliList con fase non zero, in cui le chiamate successive a diversi metodi SparsePauliOp producevano risultati errati. Ora, quando SparsePauliOp.paulis è impostato su un elemento PauliList con fase non nulla, la fase viene assorbita in SparsePauliOp.coeffse la fase dell'ingresso PauliList è impostata a zero.

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

  • Corretto un problema con dag_drawer() e DAGCircuit.draw() quando si cerca di visualizzare un'istanza DAGCircuit che conteneva Var per cui il visualizzatore sollevava un'eccezione. Questo comportamento è stato corretto e verrà generata la visualizzazione prevista.

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

  • Corregge un errore quando si chiama il metodo Gate.repeat(). Per maggiori dettagli, consultare il documento #11990.

  • Corretto un bug che faceva sì che Statevector.expectation_value() dava risultati errati per l'operatore identità quando il vettore di stato non era normalizzato.

  • Il costruttore GenericBackendV2 permetteva di creare backend malformati, perché accettava porte di base che non potevano essere allocate nella dimensione del backend specificata. In altre parole, un backend con un singolo qubit non dovrebbe accettare una base con porte a due qubit.

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

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

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

  • In precedenza, DAGCircuit.replace_block_with_op() permetteva di inserire un'operazione n-qubit su un blocco di m qubit, lasciando il DAG in uno stato non valido. Questo comportamento è stato corretto e il tentativo solleverà un problema di DAGCircuitError.

  • Fissa Operator.power() quando viene chiamato con potenze non intere su una matrice la cui forma Schur non è diagonale (ad esempio, la maggior parte delle matrici non unitarie).

  • Operator.power() restituirà in modo più affidabile il valore principale atteso di una potenza di matrice frazionaria di una matrice unitaria con un autovalore 1-1. Questo è complicato in generale, perché gli effetti di arrotondamento in virgola mobile possono far sì che una matrice abbia un autovalore sul lato negativo del taglio di ramo (anche se la sua relazione matematica esatta non lo avrebbe), e l'imprecisione in varie chiamate BLAS può falsamente trovare il lato sbagliato del taglio di ramo.

    Operator.power() sposta ora la posizione del branch-cut per le potenze della matrice a una piccola rotazione complessa da 1-1. Questo non risolve il problema, ma lo sposta solo in un punto in cui è molto meno probabile che si noti per i tipi di operatori che di solito compaiono. Utilizzate il nuovo parametro branch_cut_rotation per avere un maggiore controllo su questo aspetto.

    Vedere il numero 13305.

  • Corretto un non-determinismo per-processo in SparsePauliOp.to_matrix(). L'ordine esatto delle operazioni in virgola mobile nella somma variava in precedenza per ogni processo, ma ora sarà identico tra le diverse invocazioni dello stesso script. Vedere #13413.

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

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