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 = Truenel metodoQuantumCircuit.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
Delaydi 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
CommutationCheckerche 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()eQuantumCircuit.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
RemoveIdentityEquivalentin 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,RemoveIdentityEquivalentora rimuove le porte non parametrizzateGlobalPhaseGatecancelli. Correzioni #13778. -
Corretto un bug in
random_clifford()che impediva di campionare l'intero gruppo di Clifford. Correzioni #13606. -
Quando
SabreLayoutviene usato per eseguire contemporaneamente layout e routing (come nel caso delle opzioni predefinite ditranspile()egenerate_preset_pass_manager()) su un elementoTargetoCouplingMapcon 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()sollevandoKeyError.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
LinearFunctionnon sollevano più un errore quando un oggetto diverso daLinearFunctionviene passato nel metodorun. Invece, ora restituisconoNone, 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
CommutationCheckermemorizzava nella cache le relazioni di commutazione diInstructionconparamscome chiave per interrogare la relazione. Questo potrebbe portare a risultati errati se la definizione dell'istruzione dipendesse da informazioni aggiuntive rispetto al solo attributoparamscome, ad esempio, nel caso diPauliEvolutionGate. 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'attributoparams(come nel caso diPauliGate) poteva generare un errore. Corretto #13570. -
Il
CommutationCheckernon gestisce correttamente le commutazioni degli elementiCRXGate,CRYGateeCRZGateper angoli di rotazione della forma , con . 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 . -
È 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()epauli_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 tipoMCMTGatecon conseguente fallimento o risultato non valido. Questo problema potrebbe verificarsi, ad esempio, quando si gestisce il circuitoMCMTdenominato"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
PauliEvolutionGatenon 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
SuzukiTrotteroLieTrotter(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 diParameterExpression.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()conqubit=Trueproduceva un attributo di fase con una forma errata quando l'oggetto originale era di lunghezza 1. Corretto #13623. -
Corretto un bug in
qasm3.Exporterche causava l'arresto anomalo dell'esportatore durante la gestione di un cancello unitario a causa di un'errata elaborazione del campoparams. Corretto #13362. -
Corretto un bug nel metodo
Target.instruction_supported()per cui gli obiettivi conself.num_qubits==Nonerestituivano sempreFalse, indipendentemente dal set di basi supportato. -
Corretto un bug nel passaggio
UnitarySynthesisin cui i blocchi diUnitaryGatesu 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
UnitarySynthesisin cui le porte di non-2-qubit venivano incluse nella base a 2 qubit disponibile, causando il panico diTwoQubitWeylDecompositiona causa della mancata corrispondenza delle dimensioni. -
Corretto un bug per cui l'inizializzazione di
SparsePauliOpcon un numero elevato di termini di Pauli-Y(tipicamente ) e nessuncoeffsesplicito 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
-
È stato risolto un problema per cui la chiamata a
QuantumCircuit.decompose()su un'istruzione priva di definizione all'interno di un bloccoc_ifgenerava un errore. Corretto #13493. -
Le operazioni all'interno di un flusso di controllo (ad es.
QuantumCircuit.for_loop()) non sono stati decomposti correttamente quando si è chiamatoQuantumCircuit.decompose(). Corretto #13544. -
Sono state aggiunte definizioni predefinite per
FullAdderGate,HalfAdderGate,ModularAdderGateeMultiplierGateche consentono di costruireOperators di costruire circuiti quantistici contenenti queste porte. -
Corretto il numero di qubit ancilla puliti richiesti da
FullAdderSynthesisV95,HalfAdderSynthesisV95, eModularAdderSynthesisV95plugin. -
Aggiunto il plugin
FullAdderSynthesisDefaultche sceglie la migliore decomposizione perFullAdderGatein base al numero di qubit ancilla puliti disponibili. -
Fisso
HalfAdderSynthesisDefaulteModularAdderSynthesisDefaultper i pluginHalfAdderGateeModularAdderGaterispettivamente, per scegliere la migliore decomposizione in base al numero di qubit ancilla puliti disponibili. -
È stato corretto un comportamento errato della cache durante l'assegnazione dei parametri, che poteva causare il danneggiamento delle definizioni all'interno del file di configurazione
EquivalenceLibrarysi corrompevano. Questo risolve problemi imprevisti quando si esegue la traduzione delle basi in parallelo. Corretto #13504. -
Corretta una serie di bug durante l'elaborazione di circuiti con fasi globali parametrizzate in cui la fase globale non veniva assegnata correttamente durante l'assegnazione dei parametri. Tra i casi noti che hanno interessato questo tipo di pazienti vi sono:
- l'assegnazione di parametri dopo la chiamata
QuantumCircuit.decompose()su un circuito, in cui la decomposizione introduce una fase globale - l'assegnazione di parametri su un circuito costruito a partire da un DAG tramite
dag_to_circuit() - l'assegnazione di parametri su circuiti creati con
pauli_twirl_2q_gates(), dove il circuito da roteare aveva una fase globale parametrizzata
Corretto #13534.
- l'assegnazione di parametri dopo la chiamata
-
Corretto un bug in
RZGate.control()per più di 1 qubit di controllo, che utilizzava una decomposizione inutilmente costosa. Corretto #13473.
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, eUnitarySynthesis. 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
GateoInstruction(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
HighLevelSynthesistranspiler, 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
CommutationCheckerper 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 quanticoQuantumCircuitcome 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 esistenteQuantumVolumein quanto restituisce un oggettoQuantumCircuitinvece 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 classeQuantumVolumeclasse. -
Migliorate le prestazioni di runtime della costruzione della classe
QuantumVolumecon l'argomentoclassical_permutationimpostato suTrue. Internamente chiama ora la funzionequantum_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, attualmenteCXGate,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")
-
Aggiunte porte aritmetiche binarie per l'addizione inplace di due registri -qubit, cioè . Il
ModularAdderGateimplementa l'addizione modulo , il registroHalfAdderGateinclude un qubit di riporto e ilFullAdderGateinclude 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
MultiplierGateper la moltiplicazione di due registri -qubit, cioè . Si veda la documentazione della classe per i dettagli e gli esempi. -
I circuiti quantistici a logica booleana in
qiskit.circuit.libraryhanno ora rappresentazioni equivalenti comeGateoggetti che ne consentono l'uso conHighLevelSynthesistranspiler e l'infrastruttura dei plugin.AndGate, che rappresentaAND,OrGate, che rappresentaOR,BitwiseXorGate, che rappresentaXOR,InnerProductGate, che rappresentaInnerProduct.
-
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(), eqaoa_ansatz()nella libreria dei circuiti per implementare circuiti variazionali basati sulle evoluzioni degli operatori.evolved_operator_ansatz()eqaoa_ansatz()sono funzionalmente equivalenti aEvolvedOperatorAnsatzeQAOAAnsatzma 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 pulsanteEvolvedOperatorAnsatzma 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 aGroverOperatorma 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')
-
Un nuovo attributo di dati,
qiskit.circuit.CONTROL_FLOW_OP_NAMESè disponibile per trovare e verificare facilmente se una data operazioneInstructionè 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.NotaIn generale, la funzione
BasisTranslatornon garantisce di trovare la "migliore" relazione di equivalenza per un datoTargetma 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"aDecomposeche 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 esistenteIQPla 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')
-
È stata aggiunta l'opzione
MCMTGateper rappresentare un'operazione multi-controllo multi-target come un gate. Questa rappresentazione a gate del circuito esistenteMCMTpermette 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
MCMTGatesupporta 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
Gateo può essere costruito con un metodo di sintesi:GraphStateè rappresentato daGraphStateGate,FourierCheckingpuò essere costruito utilizzandofourier_checking(),UnitaryOverlappuò essere costruito utilizzandounitary_overlap(),HiddenLinearFunctionpuò essere costruito utilizzandohidden_linear_function(),PhaseEstimationpuò essere costruito utilizzandophase_estimation().
-
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. -
PauliFeatureMapeZZFeatureMapsupportano 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()inQuantumCircuitè 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, eZZFeatureMape 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 metodorun()della classe wrappedBackendV2. Le opzioni di esecuzione possono essere specificate utilizzando una voce"run_options"all'interno del dizionariooptionspassato aBackendSamplerV2. La voce"run_options"dovrebbe essere un dizionario che mappa i nomi degli argomenti in valori da passare al metodorun()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). -
EstimatoreStatevectorEstimatorrestituire 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
- La classe
qasm3.CustomGateè ora ispezionabile programmaticamente. Il suoconstructor,name,num_paramsenum_qubitspossono essere visualizzati da Python dopo la costruzione dell'oggetto. Questo permette di ispezionare il contenuto degli attributi di dati forniti, come ad esempioSTDGATES_INC_GATES.
Caratteristiche QPY
- Aggiunto un nuovo formato QPY versione 13 che aggiunge una rappresentazione nativa Qiskit degli oggetti
ParameterExpressionoggetti.
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_unitaryaqiskit.quantum_info.Operator.power(). QuandoTrue, utilizziamo un metodo più rapido basato sulla decomposizione di Schur per elevare unOperatora una potenza frazionaria. -
Aggiunto
SparsePauliOp.to_sparse_list()per convertire un operatore in un formato di elenco sparso. Questo funziona inversamente aSparsePauliOp.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 parametrobranch_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.
SparseObservablerappresenta le osservabili come una somma di termini, in modo simile aSparsePauliOpma con due differenze fondamentali:- 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 . - 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 . Tali proiettori possono essere misurati su hardware con la stessa efficienza del loro corrispondente operatore di Pauli, maSparsePauliOprichiederebbe un numero esponenziale di termini per rappresentare su qubit, mentreSparseObservableha bisogno di un solo termine.
È possibile costruire e manipolare
SparseObservableutilizzando un'interfaccia familiare agli utenti diSparsePauliOp: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), ])SparseObservablenon è attualmente supportato come formato di ingresso alle primitive (qiskit.primitives), ma si prevede di espandere queste interfacce per includerle in futuro. - Ogni termine completo è memorizzato come (effettivamente) una serie di coppie
Caratteristiche della sintesi
-
Aggiunta di funzioni di sintesi
synth_mcx_gray_code()esynth_mcx_noaux_v24()che sintetizzano porte X a controllo multiplo. Queste funzioni non richiedono qubit ancilla aggiuntivi. -
Aggiunta di funzioni di sintesi
synth_c3x()esynth_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 controlli usando qubit ancillari sporchi che producono un circuito con al massimo 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 controlli utilizzando qubit ancillari puliti, producendo un circuito con al massimo porte CX, di Maslov ( arXiv:1508.03273 ). -
Aggiungere una funzione di sintesi
synth_mcx_1_clean_b95()che sintetizza una porta X multicontrollata con controlli utilizzando un singolo qubit ancillare pulito, producendo un circuito con al massimo porte CX, di Barenco et al. ( arXiv:quant-ph/9503016 ). -
Aggiunto
adder_qft_d00(),adder_ripple_c04(), eadder_ripple_v95()per sintetizzare le porte dell'addizionatore,ModularAdderGate,HalfAdderGate, eFullAdderGate. -
Aggiunto
multiplier_cumulative_h18()emultiplier_qft_r17()per sintetizzare ilMultiplierGate. -
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 livelloMCMTSynthesisVChain. -
Aggiunta di una struttura di plugin di sintesi di alto livello per il file
MCMTGate, che include ilMCMTSynthesisNoAux(per nessun qubit ausiliario), il già citatoMCMTSynthesisVChain(con l'uso dinum_control - 1qubit ausiliari) e l'opzioneMCMTSynthesisDefaultper 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')
Questo frammento di codice utilizza il plugin di Rustiq per sintetizzare
PauliEvolutionGateoggetti nel circuito quantistico qc. Il plugin viene richiamato con l'opzione aggiuntivaupto_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 diPauliEvolutionSynthesisRustiq. -
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_orderaProductFormulache 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 aFalse, si ottiene un termine della forma
saranno riordinati in
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')
Funzionalità del transpiler
-
Aggiungere l'argomento
matrix_basedal passaggio del transpilerCollectCliffordsal passaggio del transpiler. Se il nuovo parametromatrix_based=True, ilCollectCliffordstranspiler può raccogliere porte unitarie che sono porte di Clifford per determinati parametri, per esempioRZGateporte con angoli multipli di . -
Il passaggio
RemoveIdentityEquivalentil 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 fasiiniteoptimization, 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:MCXSynthesisNCleanM15, sulla base disynth_mcx_n_clean_m15().MCXSynthesisNDirtyI15, sulla base disynth_mcx_n_dirty_i15().MCXSynthesis1CleanB95, sulla base disynth_mcx_1_clean_b95().MCXSynthesisNoAuxV24, sulla base disynth_mcx_noaux_v24().MCXSynthesisGrayCode, sulla base disynth_mcx_gray_code().
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)
Per il primo gate MCX, i qubit
5e6possono essere utilizzati come ancillas puliti, e il miglior metodo di sintesi disponibilesynth_mcx_n_clean_m15verrà scelto. Per il secondo gate MCX, il qubit6può essere utilizzato come ancilla pulita, il metodosynth_mcx_n_clean_m15non è più applicabile, quindi verrà scelto il metodosynth_mcx_1_clean_b95. Per il terzo gate MCX, non ci sono qubit ancilla e viene scelto il metodosynth_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 chiavelayout_trials. Un layout banale e il suo inverso sono inclusi per tutti i backend, proprio come ilDenseLayoutaggiunto 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 diDAGCircuitmemorizza 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 fileDAGCircuitda Rust, consentendo di migliorare le prestazioni. -
Un nuovo argomento
qubits_initially_zeroè stato aggiunto aqiskit.compiler.transpile(),generate_preset_pass_manager()e aPassManagerConfig. Se impostato sul valore predefinito diTrue, si presume che i qubit siano inizialmente nello stato , consentendo potenzialmente ulteriori opportunità di ottimizzazione per i singoli passaggi del transpiler. In particolare, ilHighLevelSynthesistranspiler sceglierà una decomposizione migliore per ogniMCXGatedi un circuito quando è disponibile un qubit ausiliario inattivo nello stato .Tuttavia, ci sono casi in cui
qubits_initially_zerodovrebbe essere impostato suFalse, 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
HighLevelSynthesisaccetta ora un parametro aggiuntivo:qubits_initially_zero. Se impostato suTrue, il passaggio assume che i qubit siano inizialmente nello stato . Inoltre, il passo tiene traccia dei qubit ausiliari puliti e sporchi durante l'esecuzione e passa queste informazioni ai plugin utilizzando i kwargnum_clean_ancillasenum_dirty_ancillas. -
Migliorata la gestione dei qubit ancilla nel passaggio di
HighLevelSynthesistranspiler. Ad esempio, un circuito può avere porte personalizzate le cui definizioni includonoMCXGates. Ora gli algoritmi di sintesi per gli innerMCXGatepossono 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 elementiDAGOpNodein un oggettoDAGCircuitche contengono aControlFlowOp. Questo era possibile prima di utilizzare il metodoDAGCircuit.op_nodes()e passando la classeControlFlowOpcome 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 datranspile()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:ConsolidateBlocksBasisTranslatorCommutationAnalysisCommutativeCancellationElidePermutationsOptimize1qGatesDecompositionUnitarySynthesisGateDirectionCheckGateDirectionRemoveDiagonalGatesBeforeMeasureCheckMapSplit2QUnitariesFilterOpNodesDepthSizeGatesInBasisInverseCancellationBarrierBeforeFinalMeasurements
-
Aggiunto un nuovo passaggio di transpiler,
RemoveIdentityEquivalentche 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:
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")
-
Il passaggio
ConsolidateBlockseseguirà l'equivalente del passaggioCollect2qBlocksinternamente, se non è stato eseguito in un gestore di passaggi prima del passaggio. In precedenza,Collect2qBlocksoCollect1qRunsdoveva essere eseguito prima diConsolidateBlocksperchéConsolidateBlocksper fare qualcosa. Eseguendo la raccolta internamente, si riduce l'overhead del passaggio. SeCollect2qBlocksoCollect1qRunsvengono eseguiti prima diConsolidateBlocks, vengono utilizzate le corse raccolte da quei passaggi dell'insieme di proprietà e non c'è alcun cambiamento di comportamento per il passaggio. -
Il
RemoveDiagonalGatesBeforeMeasureil passaggio del transpiler è stato aggiornato per includere più porte diagonali:PhaseGate,CPhaseGate,CSGate,CSdgGateeCCZGate. Inoltre, il codice del progettoRemoveDiagonalGatesBeforeMeasureè 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 argomentotarget, utilizzato per specificare unTargetper la visualizzazione. Per impostazione predefinita, la funzione utilizza il parametroInstruction.durationper 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 pacchettosymengineinstallata nell'ambiente che ha generato il payload (qpy.dump()) non corrisponde alla versione disymengineinstallata nell'ambiente in cui viene caricato il payload (qpy.load()), si otterrà un errore. Se si verifica questo errore, installare la versione disymenginedal messaggio di errore prima di chiamareqpy.load(). Le versioni del formato QPY 13 o successive (o precedenti alla 10) non presentano questo problema. Pertanto, se si serializzano oggettiParameterExpressionoggetti come parte del circuito o di qualsiasiScheduleBlocksi consiglia di utilizzare la versione 13 per evitare questo problema in futuro.
Note sull'aggiornamento
-
Le seguenti classi utilizzano ora l'operazione per diagonalizzare l'operatore Pauli-Y:
PauliEvolutionGate,EvolvedOperatorAnsatz, ePauliFeatureMap. In precedenza, queste classi utilizzavano o come trasformazione di base. L'utilizzo dell'operazione , rappresentata dal simboloSXGateè 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 personalizzatoTransformationPassche 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
QuantumVolumegenera 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'argomentoflatten=Trueed esportare il circuito conqpy.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 metodorun()dell'istanza wrappedBackendV2dell'istanza wrapped. Se in precedenza ci si affidava a questo comportamento, è possibile cancellare manualmente i metadati prima di richiamare il comandoBackendSamplerV2.run()chiamandocircuit.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 flagversionsuqpy.dump()per emettere la versione appropriata. Per maggiori dettagli, consultare la sezione Compatibilità QPY.
Note sull'aggiornamento del transpiler
-
DAGNode(e le sue sottoclassiDAGInNode,DAGOutNode, eDAGOpNode) non restituiscono più riferimenti allo stesso oggetto sottostante dai metodi diDAGCircuitmetodi. In precedenza non era mai stato garantito che tutti i nodi restituiti fossero riferimenti condivisi allo stesso oggetto. Tuttavia, con la migrazione diDAGCircuita Rust, una nuova istanza diDAGNodeviene 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
DAGOpNoderestituite dal metodoDAGCircuitnon 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_optuttavia, 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
DAGCircuitper la mutazione, comeDAGCircuit.substitute_node()oDAGCircuit.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.ope non dell'attributoDAGOpNodestesso. Tuttavia, in 1.3 questo si estende all'intero oggetto, non solo all'attributo internoop. 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 . Per evitare questa assunzione, si può impostare l'argomentoqubits_initially_zeroaFalse.
Note di deprecazione
-
Il modulo
qiskit.pulsee 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.pulsecosì 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.pulsefino alla fine del suo ciclo di vita.
Circuiti deprecati
-
Deprecato l'attributo
Instruction.conditione il metodoInstruction.c_if()metodo. Saranno rimossi in Qiskit 2.0, insieme a qualsiasi utilizzo nel modello di dati di Qiskit. Questa funzionalità è stata sostituita dalla classeIfElseOpche può essere utilizzata per descrivere una condizione classica in un circuito. Ad esempio, un circuito che utilizzaInstruction.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
ConvertConditionsToIfOpspuò 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:
qiskit.circuit.QuantumCircuit.calibrationsqiskit.circuit.QuantumCircuit.has_calibration_for()qiskit.circuit.QuantumCircuit.add_calibration()qiskit.dagcircuit.DAGCircuit.calibrationsqiskit.dagcircuit.DAGCircuit.has_calibration_for()qiskit.dagcircuit.DAGCircuit.add_calibration()qiskit.dagcircuit.DAGDependency.calibrations
-
Il
QuantumCircuit.uniteQuantumCircuit.durationsono 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 diDAGCircuite non terrebbe mai conto correttamente del flusso di controllo o delle condizioni nel circuito. -
Il
DAGCircuit.uniteDAGCircuit.durationsono 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 diDAGCircuite non terrebbe mai conto correttamente del flusso di controllo o delle condizioni nel circuito. -
Il
Instruction.durationeInstruction.unitsono stati deprecati e saranno rimossi in Qiskit 2.0.0. Questo include l'impostazione degli argomentiunitodurationper qualsiasi classe o sottoclasseqiskit.circuit.Instructiono 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 è laBackendV2Targetche 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 campoInstructionProperties.durationin un dato campoTargetper impostare una durata personalizzata per un'istruzione su un backend (l'unità è sempre in secondi nel campoTarget).
Deprecazioni dei provider
-
Il metodo
BasicSimulator.configuration()è deprecato e sarà rimosso in 2.0.0. Questo metodo restituisce un'istanza legacy diproviders.models.BackendConfiguration, che fa parte del modello deprecato diBackendV1. Questo modello è stato sostituito conBackendV2in cui i vincoli sono memorizzati direttamente nell'istanza del backend o nel database sottostanteTarget(backend.target).Ecco una guida rapida per accedere agli attributi più comuni di
BackendConfigurationnel modelloBackendV2modello: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_namesincludebasis_gatese altre istruzioni non gate; in alcune implementazioni potrebbe essere necessario filtrare l'uscita.Consultare questa guida per ulteriori informazioni sulla migrazione a
BackendV2modello. -
Nell'ambito della dismissione del pacchetto Qiskit Pulse, tutte le funzionalità relative a pulse nella
qiskit.providers.BackendV2classe sono state dismesse. Ciò include i seguenti metodi:Di conseguenza, i corrispondenti metodi di canale nelle
qiskit.providers.BackendV2Convertereqiskit.providers.fake_provider.GenericBackendV2vengono anch'essi deprecati.Inoltre, gli argomenti
pulse_channelsecalibrate_instructionsdel metodoBackendV2vengono deprecati. -
L'argomento
defaultsè stato deprecato dalla funzioneqiskit.providers.convert_to_target()funzione.
Deprecazioni QPY
- Come parte della deprecazione del pacchetto Qiskit Pulse, anche la serializzazione dei payload basati su
qiskit.pulse.ScheduleBlock-è anch'essa deprecata. In particolare, il passaggio diqiskit.pulse.ScheduleBlockagli argomenti dei programmi nel metodoqiskit.qpy.dump().
Deprecazioni del transpiler
-
Deprecato
StochasticSwapche è stato sostituito daSabreSwap. 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 aInstruction.conditionda 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 argomentitranspile()egenerate_preset_pass_manager(). Questa funzionalità sarà rimossa in Qiskit 2.0. Le porte personalizzate sono ancora supportate nel modelloTargete possono essere fornite tramite l'argomentotarget. Si può costruire un'istanzaTargetda zero o utilizzare il metodoTarget.from_configuration()con l'argomentocustom_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.Targetclasse vengono dismessi. Queste release includono:update_from_instruction_schedule_map()has_calibration()get_calibration()instruction_schedule_map()
Inoltre, anche i seguenti passaggi del transpiler stanno per essere deprecati:
-
L'argomento
inst_mapingenerate_preset_pass_manager(),from_configuration(),PassManagerConfiginizializzatore egenerate_scheduling()viene deprecato. -
L'argomento
calibrationnei metodi di inizializzazioneInstructionProperties()nei metodi di inizializzazione viene deprecato. -
Il seguente
transpile()egenerate_preset_pass_manager()sono deprecati in favore della definizione di un parametro personalizzatoTarget:instruction_durations,timing_constraints, ebackend_properties. Questi argomenti possono essere usati per costruire un obiettivo conTarget.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 tipoBackendV1nel parametro backend in una release futura non prima di 2.0.BackendV1è deprecato e le implementazioni dovrebbero passare aBackendV2.
Varie Deprecazioni
-
Il modulo
qiskit.result.mitigationè stato deprecato e sarà rimosso in Qiskit 2.0. La deprecazione include i parametriLocalReadoutMitigatoreCorrelatedReadoutMitigatore le funzioni di utilità associate. La loro funzionalità è stata sostituita dal pacchetto mthree, presente in https://github.com/Qiskit/qiskit-addon-mthree. -
Nell'ambito della dismissione del pacchetto Qiskit Pulse, anche le seguenti funzioni e classi vengono dismesse:
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 programmaassign_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 vocebasis_gatesnell'istanza di configurazione restituita dal metodoconfiguration()è ora un elenco anziché un'istanzadict_keys, corrispondendo al tipo previsto e consentendo la copia profonda dell'istanza di configurazione. -
Corretto un problema con
DAGCircuit.apply_operation_back()eDAGCircuit.apply_operation_front()dove in precedenza se si impostava un oggettoClbitall'input per l'argomentoqargsveniva 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
C3SXGateche lo faceva fallire seGate.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.25Corretto #13478.
-
Corretto un bug con l'entanglement di
"circular"e di"sca"per iNLocale 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 entanglingnum_qubitsper strato. -
Aggiungere altre porte di Clifford al
CollectCliffordspassaggio del transpiler. In particolare, abbiamo aggiunto le porteECRGate,DCXGate,iSwapGate,SXGateeSXdgGatea questo passaggio del transpiler. -
Corretto un bug in
QuantumCircuit.decompose()in cui gli oggetti che potevano essere sintetizzati conHighLevelSynthesisvenivano prima sintetizzati e poi scomposti immediatamente (cioè venivano scomposti due volte invece che una). Questo ha influito su cancelli comeMCXGateoClifford, 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
HighLevelSynthesissintetizzava 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 esplicitobasis_gates. Questo comportamento è stato corretto, in modo che tali istruzioni già supportate non vengano più sintetizzate. -
Il passaggio di trasposizione
InverseCancellationora ricorrerà inControlFlowOppresenti in un fileQuantumCircuit. 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
Isometrya causa di un'asserzione non necessaria, che portava a un errore inUnitaryGate.control()quandoUnitaryGateaveva più di due qubit. -
L'attributo
QuantumCircuit.parameterssarà ora correttamente vuoto quando si usaQuantumCircuit.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 esempioGlobalPhaseGate. -
QuantumCircuit.depth()conterà ora le variabili e i clbit usati nelle espressioni in tempo reale come parte del calcolo della profondità. -
Correggere il
SolovayKitaevquando si caricano le approssimazioni di base da un file.npyesistente. 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 elementoPauliListcon fase non zero, in cui le chiamate successive a diversi metodiSparsePauliOpproducevano risultati errati. Ora, quandoSparsePauliOp.paulisè impostato su un elementoPauliListcon fase non nulla, la fase viene assorbita inSparsePauliOp.coeffse la fase dell'ingressoPauliListè impostata a zero. -
Corretto un bug in
qiskit.visualization.pulse_v2.interface.drawche non disegnava gli orari degli impulsi quando la funzione draw veniva chiamata con un argomentoBackendV2con 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()eDAGCircuit.draw()quando si cerca di visualizzare un'istanzaDAGCircuitche contenevaVarper cui il visualizzatore sollevava un'eccezione. Questo comportamento è stato corretto e verrà generata la visualizzazione prevista. -
Il
VF2Layoutsolleva un'eccezione quando viene fornita un'istanzaTargetsenza 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
GenericBackendV2permetteva 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 (comefloateint) 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'implementazioneGate.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 metodoOperatorche potrebbe essere meno performante rispetto a prima del round-trip. -
In precedenza,
DAGCircuit.replace_block_with_op()permetteva di inserire un'operazionen-qubit su un blocco dimqubit, lasciando il DAG in uno stato non valido. Questo comportamento è stato corretto e il tentativo solleverà un problema diDAGCircuitError. -
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 . 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 . 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 parametrobranch_cut_rotationper 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 conNoneper le proprietà dell'istruzione. Correzioni #12525.