Note di rilascio di Qiskit SDK 1.1
1.1.2
Preludio
Qiskit 1.1.2 è una versione con correzione di bug minori per la serie 1.1.
Correzioni di bug
-
Corretto un bug in
BitArray.from_counts()eBitArray.from_samples(). In precedenza, questi sollevavano un errore se venivano forniti dati contenenti solo zeri e nessun valore per l'argomento opzionalenum_bits. Ora producono unBitArrayconBitArray.num_bitsimpostato su 1. -
Corretto un decoratore mancante in
C3SXGateche lo faceva fallire seGate.to_matrix()veniva chiamato. La matrice del gate viene ora restituita come previsto. -
Aggiunte le porte di Clifford mancanti al
CollectCliffordsal passaggio del transpiler. In particolare, abbiamo aggiunto le porteECRGate,DCXGate,iSWAPGate,SXGateeSXdgGatea questo passaggio del transpiler. -
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. -
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 problema con
dag_drawer()eDAGCircuit.draw()quando si cerca di visualizzare un'istanzaDAGCircuitche contenevaVarfili. Il visualizzatore sollevava un'eccezione, che è stata risolta in modo da generare la visualizzazione prevista. -
Il costruttore
GenericBackendV2permetteva in precedenza di costruire backend malformati, perché accettava porte di base che non potevano essere allocate data la dimensione del backend. Ad esempio, un backend con un singolo qubit potrebbe in precedenza accettare una base con gate a due qubit. -
Il parser OpenQASM 2 (
qiskit.qasm2) può ora gestire i condizionali con numeri interi che non rientrano in un numero intero a 64 bit. Corretto #12773. -
In precedenza,
DAGCircuit.replace_block_with_op()permetteva di inserire un'operazionen-qubit in un blocco dimqubit, lasciando il DAG in uno stato non valido. Questo comportamento è stato corretto e qualsiasi tentativo in tal senso solleva ora un problema di tipoDAGCircuitErrorcome previsto.
1.1.1
Preludio
Qiskit 1.1.1 è una versione con correzione di bug minori per la serie 1.1.
Correzioni di bug
-
Correzione di un bug in
Isometrya causa di un'asserzione non necessaria, che portava a un errore inUnitaryGate.control()quandoUnitaryGateaveva più di due qubit. -
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à. -
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 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. -
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. -
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. -
Le porte personalizzate (quelle che derivano 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. -
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.
1.1.0
Preludio
La release di Qiskit 1.1.0 è una release minore che include una miriade di nuove funzionalità e correzioni di bug. I punti salienti di questa release sono:
Il supporto per le variabili classiche tipizzate è stato aggiunto a Qiskit
QuantumCircuit. Queste variabili classiche possono essere specificate come ingressi o come variabili di scopo in un sistema di controlloQuantumCircuitdove, ad esempio, memorizzano l'output delle misure dei qubit o le operazioni del flusso di controllo. In futuro verrà aggiunto il supporto per l'impostazione dei parametri del gate o delle variabili di uscita.I metodi di sintesi dei due qubit predefiniti, utilizzati internamente dal transpiler nel passaggio
UnitarySynthesissono stati reimplementati in Rust. In questo modo si ottiene una significativa accelerazione dei tempi di esecuzione nella scomposizione di matrici unitarie a due qubit. Di conseguenza, il tempo di esecuzione della transpilazione con il livello di ottimizzazione 3 è stato notevolmente migliorato laddove l'esecuzioneUnitarySynthesiscomportava storicamente un grande overhead di runtime. Questa release inizia a funzionare ancheUnitarySynthesiscome parte della fase di ottimizzazione nel livello di ottimizzazione 2, grazie a questi miglioramenti delle prestazioni in fase di esecuzione.Inoltre, i metodi numerici utilizzati in
Isometrysono stati trasferiti in Rust, consentendo un'ampia accelerazione dei tempi di esecuzione, in particolare per la sintesi controllata di porte unitarie. La decomposizione per i sistemi multicontrollatiXGateePhaseGateè stata migliorata, con una riduzione del numero di porte utilizzate nella sintesi di oltre due ordini di grandezza.In Qiskit è stata introdotta una serie di nuovi passaggi di transpiler che consentono di ottenere una significativa accelerazione dei tempi di esecuzione, riducendo in molti casi le dimensioni dei circuiti quantistici transpilati. In particolare,
ElidePermutationseStarPreRoutinghanno dimostrato di avere un impatto significativo sulla qualità dell'output del routing e sul tempo di esecuzione eRemoveFinalResetpossono migliorare i circuiti quantistici che includono i reset.I gestori di pass predefiniti sono stati migliorati estendendoli con i nuovi pass del transpiler. In particolare, il gestore di pass preimpostati di livello di ottimizzazione 2 di
generate_preset_pass_managere utilizzato internamente datranspile()è stato riadattato per avere un miglior compromesso tra tempo di esecuzione e sforzo di ottimizzazione, in modo da poter essere utilizzato come gestore di passaggi predefinito nelle prossime versioni. Sebbene questa versione non modifichi l'impostazione predefinita per l'uso del livello 2, in genere è una scelta migliore rispetto all'uso del livello 1 o 3.Sono state aggiunte nuove implementazioni della primitiva generica V2,
BackendEstimatorV2eBackendSamplerV2per completare le implementazioni esistenti basate su vettori di stato completi.Modifiche al supporto della piattaforma: Python 3.8 è deprecato a partire da Qiskit 1.1.0 e non sarà più supportato in 1.3.0, mentre arm64 macOS è stato promosso a supporto di primo livello.
Caratteristiche dei circuiti
-
I metodi
QuantumCircuit.power(),Gate.power(), così come i metodi simili sulle sottoclassi di sottoclassi diGate(come quello diSGate) hanno tutti un argomento aggiuntivoannotatedche viene utilizzato per restituire un oggettoAnnotatedOperationquando si applica una potenza a un gate o a un circuito. Il valore predefinito diFalsecorrisponde al comportamento esistente. Inoltre, per le porte standard con un metodopoweresplicitamente definito, l'argomentoannotatednon ha alcun effetto. Ad esempio, siaSGate().power(1.5, annotated=False)cheSGate().power(1.5, annotated=True)restituiscono unPhaseGate. Una differenza nel valore diannotatedsi manifesta per le porte senza un metodo di potenza esplicitamente definito. Il valore diFalserestituisce unUnitaryGatecome prima, mentre il valore diTruerestituisce un'istruzioneAnnotatedOperationche rappresenta l'istruzione modificata con il "modificatore di potenza". -
Aggiunto un nuovo argomento
ctrl_stateaQuantumCircuit.mcp()eMCPhaseGate.Il
QuantumCircuit.mcp()e la classeMCPhaseGatesono stati aggiornati per includere un parametroctrl_state. Questo miglioramento consente agli utenti di specificare lo stato di controllo del gate di fase multicontrollato. Il parametro può accettare un valore intero o una stringa di bit e, per impostazione predefinita, controlla lo stato '1' se non viene fornito.from qiskit import QuantumCircuit qc = QuantumCircuit(4) qc.mcp(0.2,[0,1,2],3,ctrl_state=2) -
Aggiunto un nuovo argomento
ctrl_stateaQuantumCircuit.mcx().Il metodo
QuantumCircuit.mcx()nella libreria dei circuiti quantistici è stato migliorato per includere un parametro ctrl_state, che consente agli utenti di specificare lo stato di controllo della porta X multicontrollata. Questo parametro può accettare un valore decimale o una stringa di bit e, per impostazione predefinita, controlla lo stato '1' se non viene fornito.from qiskit import QuantumCircuit qc = QuantumCircuit(3, 3) qc.mcx([0, 1], 2, ctrl_state="00") -
A
QuantumCircuitpuò ora contenere variabili classiche tipizzate:from qiskit.circuit import QuantumCircuit, ClassicalRegister, QuantumRegister from qiskit.circuit.classical import expr, types qr = QuantumRegister(2, "q") cr = ClassicalRegister(2, "c") qc = QuantumCircuit(qr, cr) # Add two input variables to the circuit with different types. a = qc.add_input("a", types.Bool()) mask = qc.add_input("mask", types.Uint(2)) # Test whether the input variable was true at runtime. with qc.if_test(a) as else_: qc.x(0) with else_: qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Add a typed variable manually, initialized to the same value as the classical register. b = qc.add_var("b", expr.lift(cr)) qc.reset([0, 1]) qc.h(0) qc.cx(0, 1) qc.measure(qr, cr) # Store some calculated value into the `b` variable. qc.store(b, expr.bit_and(b, cr)) # Test whether we had equality, up to a mask. with qc.if_test(expr.equal(expr.bit_and(b, mask), mask)): qc.x(0)Queste variabili possono essere specificate come ingressi al circuito o come variabili di scopo. L'oggetto circuito non supporta ancora la rappresentazione delle uscite a variabili classiche tipizzate, ma questo verrà aggiunto in seguito, quando l'hardware e le interfacce dei risultati saranno in grado di supportarlo. I circuiti che rappresentano un blocco di un ambito interno possono anche catturare variabili da ambiti esterni.
Una variabile è un
Varche può contenere un tipo arbitrario e rappresenta una posizione di memoria unica all'interno del suo intervallo di vita quando viene aggiunta a un circuito. Questi possono essere costruiti in un circuito utilizzandoQuantumCircuit.add_var()eQuantumCircuit.add_input(), o a un livello inferiore usandoVar.new().Le variabili possono essere memorizzate manualmente, utilizzando l'istruzione
Storee il corrispondente metodo di circuitoQuantumCircuit.store(). Questo include la scrittura aClbiteClassicalRegisteristanze avvolte in nodiVarnodi.Le variabili possono essere utilizzate ovunque siano valide le espressioni classiche (vedi
qiskit.circuit.classical.expr) sono valide. Attualmente si tratta delle espressioni di destinazione delle operazioni del flusso di controllo, anche se in futuro si prevede di estendere questa funzione ai parametri dei gate, man mano che il sistema di tipi ed espressioni verrà ampliato.Per ulteriori informazioni su queste variabili e sul modello di dati associato, vedere Calcolo classico in tempo reale.
Questi sono supportati in tutto il transpiler, attraverso la serializzazione QPY (
qiskit.qpy), l'esportazione di OpenQASM 3 (qiskit.qasm3) e hanno un supporto iniziale attraverso i visualizzatori di circuiti (vediQuantumCircuit.draw()).NotaLe nuove variabili classiche e la memorizzazione richiederanno un certo tempo per essere supportate dall'hardware e dai backend dei simulatori. Non sono supportate nelle interfacce delle primitive (
qiskit.primitives), ma probabilmente informeranno tali interfacce nella loro evoluzione. -
Il modulo classico delle espressioni in tempo reale
qiskit.circuit.classicalpuò ora rappresentare l'indicizzazione e il bitshifting di numeri interi senza segno e simili (ad es.ClassicalRegister). Ad esempio, è ora possibile confrontare un registro con il bitshift di un altro:from qiskit.circuit import QuantumCircuit, ClassicalRegister from qiskit.circuit.classical import expr cr1 = ClassicalRegister(4, "cr1") cr2 = ClassicalRegister(4, "cr2") qc = QuantumCircuit(cr1, cr2) with qc.if_test(expr.equal(cr1, expr.shift_left(cr2, 2))): passQiskit può anche rappresentare una condizione che indicizza dinamicamente un registro:
with qc.if_test(expr.index(cr1, cr2)): pass -
Le prestazioni di costruzione di
NLocale delle sue sottoclassi di librerie di circuiti derivate (ad es.EfficientSU2eRealAmplitudes) è notevolmente migliorato, quando i sottoblocchi di rotazione e/o di entanglement sono semplici applicazioni di un singolo gate della libreria standard di Qiskit. Poiché questi circuiti sono costruiti in modo pigro, il miglioramento potrebbe non essere visibile immediatamente all'istanziazione della classe, ma al primo accesso alla sua struttura interna. I miglioramenti delle prestazioni sono dell'ordine di dieci volte più veloci. -
QuantumCircuit.append()ha ora un argomento per la parola chiavecopy, che ha come valore predefinitoTrue. Quando un'istruzione con parametri di runtime (ParameterExpressions) viene aggiunta a un circuito, per impostazione predefinita, il circuito ha sempre creato una copia dell'istruzione, in modo che, se si tenta di mutare l'istruzione in loco, ciò non influisce sugli altri riferimenti alla stessa istruzioneQuantumCircuit.assign_parameters()tenta di mutare l'istruzione sul posto, non influisce sugli altri riferimenti alla stessa istruzione. Ora, l'impostazione dicopy=Falseconsente di ignorare questo aspetto, in modo da evitare la penalità di copia se si sa che le istruzioni non verranno utilizzate in altri luoghi. -
QuantumCircuit.compose()ha ora un argomento per la parola chiavecopy, che ha come valore predefinitoTrue. Per impostazione predefinita,compose()copia tutte le istruzioni, in modo che le mutazioni di un circuito non influiscano sugli altri. Secopy=False, le istruzioni dell'altro circuito diventeranno direttamente di proprietà del nuovo circuito, il che può comportare la loro mutazione in loco. In questo caso, l'altro circuito non deve essere utilizzato successivamente. -
Il tempo di costruzione dei
QuantumVolumeè stato notevolmente migliorato, dell'ordine di 10x o poco più. Anche le porte interne di SU4 utilizzeranno un maggior numero di bit di casualità durante la loro generazione, portando a circuiti di volume più rappresentativi, soprattutto a larghezze e profondità elevate. -
QuantumVolumeha ora un argomento per la parola chiaveflatten. L'impostazione predefinita èFalse, dove il circuito costruito contiene una singola istruzione che a sua volta contiene la struttura del volume vero e proprio. Se si impostaTrue, il circuito avrà direttamente le matrici volumetriche SU4. -
UnitaryGateaccetta ora un argomento opzionalenum_qubits. L'unico effetto è quello di saltare l'inferenza del conteggio dei qubit, che può essere utile per le prestazioni quando si costruiscono molte porte. -
QuantumCircuitha diversi nuovi metodi per lavorare e ispezionare le variabili manualiVarvariabili.Per una discussione più approfondita su tutti questi aspetti, vedere Lavorare con i dati classici digitati in tempo reale.
I nuovi metodi sono:
add_var()add_input()add_capture()add_uninitialized_var()get_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()store()
Inoltre, ci sono diversi nuovi attributi dinamici su
QuantumCircuitche circondano queste variabili: -
ControlFlowOpe le sue sottoclassi hanno ora un metodoiter_captured_vars()che restituisce un iteratore sulle variabili uniche catturate in uno qualsiasi dei suoi blocchi immediati. -
DAGCircuitha diversi nuovi metodi per lavorare e ispezionare le variabili manualiVarvariabili. Questi sono in gran parte equivalenti alle loroQuantumCircuittranne che per il fatto che gli oggettiDAGCircuitsono ottimizzati per l'accesso programmatico con oggetti già definiti, mentre i metodi sono più focalizzati sull'uso umano interattivoQuantumCircuitsono più focalizzati sull'uso umano interattivo.I nuovi metodi sono:
add_input_var()add_captured_var()add_declared_var()has_var()iter_vars()iter_declared_vars()iter_captured_vars()iter_input_vars()
Ci sono anche nuovi attributi pubblici:
-
DAGCircuit.wiresconterrà anche tutte le variabiliVarmanuale del circuito, in quanto si tratta di un flusso di dati classico. -
Viene aggiunto un nuovo metodo,
Var.new()per costruire manualmente una variabile classica in tempo reale che possiede la sua memoria. -
QuantumCircuit.compose()ha due argomenti chiave necessari,var_remapeinline_captures, per supportare meglio le variabili classiche in tempo reale.var_remappuò essere usato per riscrivereVarnell'argomento del circuito, poiché le sue istruzioni vengono inserite nel circuito di base. Questo può essere usato per evitare conflitti di denominazione.inline_capturespuò essere impostato suTrue(per impostazione predefinitaFalse) per collegare tutti i nodiVarnodi tracciati come "catture" nel circuito di argomento con gli stessiVarnodi del circuito di base, senza tentare di ridichiarare le variabili. Questo può essere usato, in combinazione con la gestione diQuantumCircuit.copy_empty_like()vars_mode="captures", per costruire un circuito strato per strato, contenente variabili. -
DAGCircuit.compose()ha un nuovo argomento chiave,inline_captures, che può essere impostato suTrueper inserire i nodi "catturati" del circuito dell'argomento nel circuito di base senza ridichiararliVarsul circuito dell'argomento sul circuito di base senza ridichiararli. In combinazione con l'opzionevars_mode="captures"di alcuni metodiDAGCircuitpuò essere usata per combinare DAG che operano sulle stesse variabili. -
QuantumCircuit.copy_empty_like()eDAGCircuit.copy_empty_like()hanno un nuovo argomento chiave,vars_mode, che controlla il modo in cui i nodi che possiedono memoriaVarvengono tracciati nell'output. Per impostazione predefinita ("alike"), le variabili sono dichiarate nella stessa modalità di input/cattura/locale della sorgente. Può essere impostato su"captures"per convertire tutte le variabili in catture (utile concompose()) o"drop"per rimuoverle. -
È stato aggiunto un nuovo argomento per la parola chiave
vars_modeal metodoDAGCircuitmetodi:che ha lo stesso significato che ha per
copy_empty_like(). -
Tutte le "porte standard" della libreria dei circuiti (
qiskit.circuit.library) possono ora essere specificate con un nome di stringa per le operazioni di entangling inTwoLocalcircuiti, comeRealAmplitudeseEfficientSU2.
Caratteristiche primitive
-
L'implementazione
BackendEstimatorV2diBaseEstimatorV2è stata aggiunta. Questo stimatore supportaBackendV1eBackendV2.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import SparsePauliOp, random_hermitian backend = Fake7QPulseV1() estimator = BackendEstimatorV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) observable = SparsePauliOp("Z" * n_qubits) isa_circuit = transpile(circuit, backend=backend, optimization_level=1) isa_observable = observable.apply_layout(isa_circuit.layout) job = estimator.run([(isa_circuit, isa_observable)], precision=0.01) result = job.result() print(f"> Expectation value: {result[0].data.evs}") print(f"> Standard error: {result[0].data.stds}") print(f"> Metadata: {result[0].metadata}") -
L'implementazione
BackendSamplerV2diBaseSamplerV2è stata aggiunta. Questo campionatore supportaBackendV1eBackendV2che consentono l'opzionememoryper calcolare le stringhe di bit.import numpy as np from qiskit import transpile from qiskit.circuit.library import IQP from qiskit.primitives import BackendSamplerV2 from qiskit.providers.fake_provider import Fake7QPulseV1 from qiskit.quantum_info import random_hermitian backend = Fake7QPulseV1() sampler = BackendSamplerV2(backend=backend) n_qubits = 5 mat = np.real(random_hermitian(n_qubits, seed=1234)) circuit = IQP(mat) circuit.measure_all() isa_circuit = transpile(circuit, backend=backend, optimization_level=1) job = sampler.run([isa_circuit], shots=100) result = job.result() print(f"> bitstrings: {result[0].data.meas.get_bitstrings()}") print(f"> counts: {result[0].data.meas.get_counts()}") print(f"> Metadata: {result[0].metadata}") -
Aggiunti metodi per unire più
BitArraylungo vari assi.concatenate(): unire gli array lungo un asse esistente degli array.concatenate_bits(): uniscono le matrici lungo l'asse dei bit.concatenate_shots(): unire gli array lungo l'asse degli scatti.
ba = BitArray.from_samples(['00', '11']) print(ba) # BitArray(<shape=(), num_shots=2, num_bits=2>) # reshape the bit array because `concatenate` requires an axis. ba_ = ba.reshape(1, 2) print(ba_) # BitArray(<shape=(1,), num_shots=2, num_bits=2>) ba2 = BitArray.concatenate([ba_, ba_]) print(ba2.get_bitstrings()) # ['00', '11', '00', '11'] # `concatenate_bits` and `concatenates_shots` do not require any axis. ba3 = BitArray.concatenate_bits([ba, ba]) print(ba3.get_bitstrings()) # ['0000', '1111'] ba4 = BitArray.concatenate_shots([ba, ba]) print(ba4.get_bitstrings()) # ['00', '11', '00', '11'] -
Aggiunti metodi per generare un sottoinsieme di
BitArraytagliando lungo vari assi.__getitem__(): tagliare l'array lungo un asse esistente dell'array.slice_bits(): tagliare la matrice lungo l'asse dei bit.slice_shots(): tagliare la matrice lungo l'asse di ripresa.
ba = BitArray.from_samples(['0000', '0001', '0010', '0011'], 4) print(ba) # BitArray(<shape=(), num_shots=4, num_bits=4>) print(ba.get_bitstrings()) # ['0000', '0001', '0010', '0011'] ba2 = ba.reshape(2, 2) print(ba2) # BitArray(<shape=(2,), num_shots=2, num_bits=2>) print(ba2[0].get_bitstrings()) # ['0000', '0001'] print(ba2[1].get_bitstrings()) # ['0010', '0011'] ba3 = ba.slice_bits([0, 2]) print(ba3.get_bitstrings()) # ['00', '01', '00', '01'] ba4 = ba.slice_shots([0, 2]) print(ba3.get_bitstrings()) # ['0000', '0010'] -
Aggiunto un metodo
transpose()per trasporre un elementoBitArray.ba = BitArray.from_samples(['00', '11']).reshape(2, 1, 1) print(ba) # BitArray(<shape=(2, 1), num_shots=1, num_bits=2>) print(ba.transpose()) # BitArray(<shape=(1, 2), num_shots=1, num_bits=2>) -
Aggiunto un metodo
expectation_values()per calcolare i valori di aspettativa degli operatori diagonali.ba = BitArray.from_samples(['01', '11']) print(ba.expectation_values(["IZ", "ZI", "01"])) # [-1. 0. 0.5] -
DataBinsoddisfa ora ilShapedprotocollo. Ciò significa che ogniDataBinha ora gli attributi aggiuntivishape(tupleint[,...]): la forma iniziale di ogni voce dell'istanzandim(int): la lunghezza dishapesize(int): il prodotto delle voci dishape
La forma può essere passata al costruttore.
-
Aggiunte funzioni di mappatura a
DataBin, cioè__getitem__,__contains__,__iter__,keys(),values(), eitems().from qiskit import QuantumCircuit from qiskit.primitives import StatevectorSampler circuit = QuantumCircuit(1) circuit.h(0) circuit.measure_all() sampler = StatevectorSampler() result = sampler.run([circuit]).result() databin = result[0].data for creg, arr in databin.items(): print(creg, arr) for creg in databin: print(creg, databin[creg]) -
La sottoclasse
SamplerPubResultdiPubResultè stata aggiunta, cheBaseSamplerV2può essere restituita dalle implementazioni. La principale funzione aggiunta in questa nuova sottoclasse èjoin_data()che unisce (un sottoinsieme) i contenuti didatain un unico oggetto. Ciò consente di utilizzare i seguenti schemi:job_result = sampler.run([pub1, pub2, pub3], shots=123).result() # assuming all returned data entries are BitArrays counts1 = job_result[0].join_data().get_counts() bistrings2 = job_result[1].join_data().get_bitstrings() array3 = job_result[2].join_data().array
Funzionalità dei fornitori
- Il
BasicSimulatorbasato su python e incluso inbasic_providersupporta ora l'esecuzione di tutte le porte standard fino a 3 qubit definite inqiskit.circuit.library.
Caratteristiche di Pulse
-
È ora possibile assegnare parametri agli impulsi
ScheduleeScheduleBlockspecificando il nome del parametro come stringa. Il nome del parametro può essere utilizzato per assegnare i valori a tutti i parametri all'interno del campoScheduleoScheduleBlockche hanno lo stesso nome. Inoltre, il nome del parametro di un vettoreParameterVectorpuò essere usato per assegnare tutti i valori del vettore contemporaneamente (l'elenco dei valori deve quindi corrispondere alla lunghezza del vettore). -
I metodi
assign_parametersdiScheduleeScheduleBlocksupportano ora l'assegnazione di un valoreParameterVectora un elenco di valori di parametri simultaneamente, oltre ad assegnare le singole istanze diParametera valori individuali.
OpenQASM Caratteristiche
- L'esportatore OpenQASM 3 supporta l'archiviazione manuale
Varsui circuiti.
Caratteristiche QPY
- IL FORMATO QPY (
qiskit.qpy) è stata aggiunta la versione 12 del formato, che include il supporto per le variabili di proprietà della memoriaVardi memoria. Per ulteriori dettagli sulle modifiche al formato, consultare la versione 12.
Caratteristiche dell'informazione quantistica
-
Aggiunto un nuovo metodo
apply_layout()che è equivalente aapply_layout(). Questo metodo viene utilizzato per applicare unTranspileLayoutlayout del transpiler a unPauliosservabile costruito per un circuito di ingresso. Questo permette di lavorare conBaseEstimator/BaseEstimatorV2e la transpilazione locale quando l'input è di tipoPauli. Ad esempio:from qiskit.circuit.library import RealAmplitudes from qiskit.primitives import BackendEstimatorV2 from qiskit.providers.fake_provider import GenericBackendV2 from qiskit.quantum_info import Pauli from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager psi = RealAmplitudes(num_qubits=2, reps=2) H1 = Pauli("XI") backend = GenericBackendV2(num_qubits=7) estimator = BackendEstimatorV2(backend=backend) thetas = [0, 1, 1, 2, 3, 5] pm = generate_preset_pass_manager(optimization_level=3, backend=backend) transpiled_psi = pm.run(psi) permuted_op = H1.apply_layout(transpiled_psi.layout) res = estimator.run([(transpiled_psi, permuted_op, thetas)]).result()dove un circuito di ingresso viene trapiantato localmente prima di essere passato a
run(). La transpilazione espande il circuito originale da 2 a 7 qubit (la dimensione dibackend) e ne permuta il layout, che viene poi applicato aH1usandoapply_layout()per riflettere le trasformazioni effettuate dapm.run(). -
Aggiunge gli elementi
PauliList.noncommutation_graph()eSparsePauliOp.noncommutation_graph()metodi, esponendo la costruzione di grafi non commutativi, rifondendo il problema del raggruppamento degli operatori di misura in un problema di colorazione dei grafi. Questo permette agli utenti di lavorare direttamente con questi grafi, ad esempio per esplorare algoritmi di colorazione diversi da quello utilizzato daSparsePauliOp.group_commuting(). -
Le prestazioni di
SparsePauliOp.to_matrix()è stata notevolmente migliorata sia per le forme dense che per quelle rade. Per impostazione predefinita, entrambi sfruttano il parallelismo filettato disponibile sul sistema, in base alla variabile d'ambienteRAYON_NUM_THREADS. È possibile forzare temporaneamente l'esecuzione seriale utilizzando il nuovo argomento booleanoforce_serialato_matrix().
Caratteristiche della sintesi
-
Il
KMSSynthesisLinearFunctionper sintetizzare gli oggettiLinearFunctionaccetta ora due opzioni aggiuntiveuse_invertedeuse_transposed. Queste opzioni modificano la matrice su cui gira l'algoritmo di sintesi sottostante, eventualmente invertendola e/o trasponendola, e quindi regolano opportunamente il circuito sintetizzato. Variando queste opzioni, in genere si ottengono circuiti sintetizzati diversi, e in alcuni casi si possono ottenere risultati migliori rispetto ai valori predefiniti. -
Il
PMHSynthesisLinearFunctionper sintetizzare gli oggettiLinearFunctionaccetta ora diverse opzioni aggiuntive. L'opzionesection_sizeviene passata al metodo di sintesi sottostante. Le opzioniuse_invertedeuse_transposedmodificano la matrice su cui gira l'algoritmo di sintesi sottostante, eventualmente invertendola e/o trasponendola, e quindi regolano opportunamente il circuito sintetizzato. Variando queste opzioni, in genere si ottengono circuiti sintetizzati diversi, e in alcuni casi si possono ottenere risultati migliori rispetto ai valori predefiniti. -
È stato aggiunto un nuovo argomento,
use_dag, agli elementiTwoQubitBasisDecomposer.__call__()eXXDecomposer.__call__()ai metodi. Questo argomento è usato per controllare se viene restituito un oggettoDAGCircuitviene restituito quando si chiama un metodoTwoQubitBasisDecomposeroXXDecomposerinvece dell'istanza predefinitaQuantumCircuit. Ad esempio:from qiskit.circuit.library import CXGate from qiskit.quantum_info import random_unitary from qiskit.synthesis import TwoQubitBasisDecomposer decomposer = TwoQubitBasisDecomposer(CXGate(), euler_basis="PSX") decomposer(random_unitary(4), use_dag=True)restituirà un valore
DAGCircuitquando si chiama l'istanzaTwoQubitBasisDecomposerdecomposer. -
LieTrotter.synthesize()utilizza oraQuantumCircuit.repeat()per generare ulteriori ripetizioni di un passo Trotter dopo il primo passo Trotter. Questo riduce il numero diQuantumCircuit.compose()di un fattore pari arepse riduce significativamente il tempo di esecuzione per gli operatori più grandi. -
Aggiungere un nuovo metodo di sintesi
synth_permutation_reverse_lnn_kms()di permutazioni inverse per architetture lineari nearest-neighbor utilizzando il metodo di Kutin, Moulton, Smithline. Questo algoritmo sintetizza la permutazione inversa su qubit su un'architettura lineare nearest-neighbor utilizzando porte CX con profondità . -
La classe
TwoQubitBasisDecomposerè stata riscritta in Rust, migliorando notevolmente le prestazioni in fase di esecuzione. -
La classe
TwoQubitWeylDecompositionè stata riscritta in Rust per migliorare le prestazioni.
Funzionalità del transpiler
-
Estensione dell'analisi delle commutazioni eseguita da
CommutationCheckerper lavorare anche con circuiti astratti, cioè ogni operazione del circuito quantistico in ingresso viene ora controllata per la sua rappresentazione matriciale prima di procedere alla fase di analisi. In precedenza, l'analisi della commutazione veniva eseguita solo su circuiti fisici. Inoltre, ogni operazione viene ora controllata per verificarne la capacità di essere memorizzata nella cache della libreria di commutazione della sessione. Ad esempio, ora è possibile calcolare seAnnotatedOperationcommutare. Ciò consente ai passaggi del transpiler che si basano internamente suCommutationChecker, come ad esempioCommutativeCancellationdi essere eseguiti durante le prime fasi di una pipeline di transpilazione predefinita (prima della traduzione delle basi). -
Il passaggio del transpiler
ElidePermutationsviene eseguito di default nella fase di avvio per i livelli di ottimizzazione 2 e 3. Intuitivamente, la rimozione diSwapGates ePermutationGates in un circuito virtuale è quasi sempre vantaggioso, in quanto rende il circuito più corto e più facile da instradare. PoichéOptimizeSwapBeforeMeasureè un caso speciale diElidePermutationsè stato sostituito dal passaggioElidePermuationscome parte della fase di init nei gestori dei passaggi di ottimizzazione di livello 3. -
È stato aggiunto un nuovo passaggio del transpiler di ottimizzazione,
ElidePermutationsche è stato progettato per essere eseguito prima della fase di layout e che ottimizzerà tutti gli elementi di tipoSwapGates ePermutationGates in un circuito mediante la permutazione dei qubit virtuali. Ad esempio, prendendo un circuito conSwapGates:
rimuoverà gli scambi quando il passaggio viene eseguito:
from qiskit.transpiler.passes import ElidePermutations from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3) qc.h(0) qc.swap(0, 1) qc.swap(2, 0) qc.cx(1, 0) qc.measure_all() ElidePermutations()(qc).draw("mpl")
Il passaggio imposta anche il set di proprietà
virtual_permutation_layout, memorizzando la permutazione dei qubit virtuali alla fine del circuito che è stato ottimizzato. -
L'opzione
HLSConfigha ora due argomenti opzionali aggiuntivi. L'argomentoplugin_selectionpuò essere impostato su"sequential"o su"all". Se impostato su "sequenziale" (valore predefinito), per ogni oggetto di livello superiore il passaggioHighLevelSynthesisconsidererà i metodi specificati in modo sequenziale, nell'ordine in cui appaiono nell'elenco, fermandosi al primo metodo in grado di sintetizzare l'oggetto. Se si imposta "all", verranno considerati tutti i metodi specificati e verrà scelto il miglior circuito sintetizzato, secondoplugin_evaluation_fn. L'argomentoplugin_evaluation_fnè un callable opzionale che valuta la qualità del circuito quantistico sintetizzato; un valore minore significa un circuito migliore. Quando è impostato suNone, la qualità del circuito è la sua dimensione (cioè il numero di porte che contiene).L'esempio seguente illustra la nuova funzionalità:
from qiskit import QuantumCircuit from qiskit.circuit.library import LinearFunction from qiskit.synthesis.linear import random_invertible_binary_matrix from qiskit.transpiler.passes import HighLevelSynthesis, HLSConfig # Create a circuit with a linear function mat = random_invertible_binary_matrix(7, seed=37) qc = QuantumCircuit(7) qc.append(LinearFunction(mat), [0, 1, 2, 3, 4, 5, 6]) # Run different methods with different parameters, # choosing the best result in terms of depth. hls_config = HLSConfig( linear_function=[ ("pmh", {}), ("pmh", {"use_inverted": True}), ("pmh", {"use_transposed": True}), ("pmh", {"use_inverted": True, "use_transposed": True}), ("pmh", {"section_size": 1}), ("pmh", {"section_size": 3}), ("kms", {}), ("kms", {"use_inverted": True}), ], plugin_selection="all", plugin_evaluation_fn=lambda circuit: circuit.depth(), ) # synthesize qct = HighLevelSynthesis(hls_config=hls_config)(qc)Nell'esempio, eseguiamo più metodi di sintesi con diversi parametri, scegliendo il circuito migliore in termini di profondità. Si noti che ottimizzando
circuit.size()si sceglierebbe invece un circuito diverso. -
Aggiunto il
CommutativeCancellationallo stadioinitdei gestori di passaggi preimpostati per i livelli di ottimizzazione 2 e 3. Ciò consente ai gestori dei passaggi preimpostati di annullare ulteriori operazioni logiche all'inizio della pipeline di compilazione. -
I seguenti passaggi di analisi accettano ora i vincoli codificati in un
Targetgrazie al nuovo argomento di inputtarget:I vincoli di destinazione avranno la priorità sui vincoli forniti dall'utente, per coerenza con il resto della pipeline del transpiler.
-
Aggiunto un nuovo metodo
Layout.inverse()che viene utilizzato per prendere l'inverso di un oggettoLayoutoggetto. Aggiunto un nuovo metodoLayout.compose()che viene utilizzato per comporre dueLayoutoggetti. Aggiunto un nuovo metodoLayout.to_permutation()che serve a creare una permutazione corrispondente a un oggettoLayoutoggetto. -
Aggiunta una nuova riduzione al passaggio
OptimizeAnnotatedal passaggio del transpiler. Questa riduzione cerca le operazioni annotate (oggetti di tipoAnnotatedOperationche consistono in un'operazione base e in una lista di modificatori di controllo, inversi e di potenza) con le seguenti proprietà:- l'operazione di base deve essere sintetizzata (cioè non è già supportata dal target o appartiene alla libreria di equivalenza)
- il circuito di definizione per può essere espresso come - - con
In questo caso i modificatori possono essere spostati solo nella parte . Come esempio specifico, i sommatori controllati basati su QFT hanno la forma
control - [QFT -- U -- IQFT], che può essere semplificata inQFT -- control-[U] -- IQFT. Eliminando i controlli sulle partiQFTeIQFTdel circuito, si ottiene un numero significativamente inferiore di porte nel circuito transpilato. -
Aggiunti due nuovi metodi alla classe
DAGCircuitalla classe:qiskit.dagcircuit.DAGCircuit.op_successors()restituisce un iteratore aiDAGOpNodesuccessori di un nodo eqiskit.dagcircuit.DAGCircuit.op_successors()restituisce un iteratore aiDAGOpNodepredecessori di un nodo. -
Aggiunto un nuovo passaggio di transpiler,
RemoveFinalResetche rimuove qualsiasiResetche è l'istruzione finale su un filo di qubit. Ad esempio, prendendo un circuito con finaleResets:
rimuoverà gli azzeramenti finali quando il passaggio viene eseguito:
from qiskit.transpiler.passes import RemoveFinalReset from qiskit.circuit import QuantumCircuit qc = QuantumCircuit(3, 1) qc.reset(0) qc.h(range(3)) qc.cx(1, 0) qc.measure(0, 0) qc.reset(range(3)) RemoveFinalReset()(qc).draw("mpl")
-
Aggiunto un nuovo passaggio di transpiler
StarPreRoutingche ha lo scopo di identificare i sottocircuiti a connettività stellare e di sostituirli con un percorso lineare ottimale. Questo è utile per alcuni circuiti che sono composti da questa connettività circuitale, come Bernstein-Vazirani e QFT. Ad esempio:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import StarPreRouting qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) StarPreRouting()(qc).draw("mpl")
In alternativa, è possibile estendere un gestore di passaggi preimpostati esistente:
from qiskit import QuantumCircuit from qiskit.transpiler import CouplingMap from qiskit.transpiler.passes import StarPreRouting from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager cm = CouplingMap.from_line(5) qc = QuantumCircuit(5) qc.h(0) qc.cx(0, range(1, 5)) pm = generate_preset_pass_manager(2, coupling_map=cm) pm.init += StarPreRouting() result = pm.run(qc) result.draw("mpl")
Funzionalità di visualizzazione
- Il testo e i Matplotlib cassetti dei circuiti (
QuantumCircuit.draw()) hanno un supporto minimo per la visualizzazione di espressioni che coinvolgono variabili manuali in tempo reale. L'operazioneStoree le inizializzazioni delle variabili non sono ancora supportate; per circuiti dinamici di grandi dimensioni, si consiglia di utilizzare le funzionalità di esportazione di OpenQASM 3 (qasm3.dumps()) per ottenere una rappresentazione testuale di un circuito.
Varie Funzioni
- Questa versione di Qiskit finalizza il supporto per NumPy 2.0. Qiskit continuerà a supportare sia NumPy 1.x che 2.x per il prossimo futuro.
Note sull'aggiornamento
-
Rimuove la codifica delle opzioni di stile per i file
plot_histogram(). Ciò consente di applicare fedelmente i file di stile di Matplotlib alle figure. Gli utenti che desiderano andare oltre i valori predefiniti impostati da Matplotlib possono creare i propri file di stile o passare un oggetto MatplotlibAxesaplot_histograme post-applicare qualsiasi personalizzazione. -
La funzione
transpile()è stata aggiornata per convertire internamente gli ingressi del backend di tipoBackendV1inBackendV2che consente alla pipeline di transpilazione di accedere ai vincoli del backend attraverso un elemento di tipoTarget. Questa modifica non richiede alcun intervento da parte dell'utente.
Note sull'aggiornamento dei circuiti
-
L'utilizzo del numero casuale di
QuantumVolumeè cambiato, quindi si otterrà un circuito diverso per un seme fisso tra le versioni precedenti di Qiskit e questa versione. La generazione casuale-unitaria ora utilizza più bit di entropia, quindi i circuiti di grandi dimensioni saranno meno distorti. -
Le istanze interne
UnitaryGatenella definizione di un circuitoQuantumVolumenon avranno più un campolabelimpostato. In precedenza era impostato sulla stringasu4_<seed>, dove<seed>era un numero a tre cifre che indicava il seme di un'istanza interna di Numpy pRNG per quel gate. Questa operazione rappresentava un serio problema di prestazioni e il seme non avrebbe dovuto essere utile; se si ha bisogno di recuperare la matrice dal gate, è sufficiente usare il metodoGate.to_matrix()metodo.
Note sull'aggiornamento delle primitive
- La funzione
make_data_bin()non crea e restituisce più unaDataBinsottoclasse. Restituisce invece sempre la classeDataBinclasse. Tuttavia, continua a esistere per la compatibilità all'indietro, anche se alla fine sarà deprecato. Tutti gli utenti dovrebbero migrare a costruireDataBindirettamente, invece di istanziare le sottoclassi come output dimake_data_bin().
Note sull'aggiornamento dei provider
-
Implementazioni di
BackendV2(eBackendV1) potrebbero voler aggiornare i loro metodirun()per rifiutare avidamente gli input contenenti variabili classiche tipizzate (vedereqiskit.circuit.classical) e l'istruzioneStorese non le supportano. La nuova istruzioneStoreè trattata dal transpiler come una "direttiva" sempre disponibile (come la direttivaBarrier); se i vostri backend non la supportano, non sarà colta dall'opzionetranspiler.Per ulteriori informazioni, vedere Variabili in tempo reale.
Note sull'aggiornamento QPY
- Il valore di
qiskit.qpy.QPY_VERSIONè ora 12.QPY_COMPATIBILITY_VERSIONè invariato a 10.
Note sull'aggiornamento della sintesi
- Il
TwoQubitWeylDecompositionnon si auto-specializzerà più in una sottoclasse al momento della creazione. Questo era un dettaglio interno della classeTwoQubitWeylDecompositione non era un comportamento pubblico documentato, poiché tutte le sottoclassi si comportavano allo stesso modo ed erano usate solo per il dispatch interno. Tuttavia, poiché si trattava di un comportamento riscontrabile, questa nota di rilascio documenta che questo non si verificherà più e che tutte le istanze diTwoQubitWeylDecompositionsaranno dello stesso tipo. Il comportamento dei metodi pubblici della classe non cambia.
Note sull'aggiornamento del transpiler
- La preimpostazione
StagedPassManagerrestituito per il livello di ottimizzazione 2 dagenerate_preset_pass_manager()elevel_2_pass_manager()sono state rielaborate per fornire un migliore equilibrio tra tempo di esecuzione e ottimizzazione. Ciò significa che i circuiti di uscita cambieranno rispetto alle versioni precedenti. Se si ha bisogno di un gestore di passaggi esatto dal livello 2 nelle versioni precedenti, è possibile costruirlo manualmente o utilizzarlo da una versione precedente e salvare i circuiti conqpyper caricarlo con una release più recente.
Varie Note sull'aggiornamento
- La versione minima di Windows supportata è ora Windows 10. Nelle versioni precedenti non abbiamo elencato esplicitamente una versione minima supportata di Windows e implicitamente Windows 7, 8 e 8.1 avrebbero potuto funzionare (ma non sono mai stati testati). Ma a causa dell'abbandono del supporto alle vecchie versioni di Windows da parte di Rust 1.78, i binari pubblicati da Qiskit su PyPI non supporteranno più le vecchie versioni di Windows a partire da questa release. Se si utilizza una versione precedente di Windows, è possibile compilare Qiskit dai sorgenti utilizzando un compilatore Rust più vecchio (la versione minima di Rust supportata da Qiskit per la compilazione dai sorgenti è attualmente 1.70 ), ma le versioni precedenti di Windows non sono una piattaforma supportata e non sono testate.
Note di deprecazione
-
Il supporto per l'esecuzione di Qiskit con Python 3.8 è stato deprecato e sarà rimosso nella versione di Qiskit 1.3.0. 1.3.0 è la prima release dopo la fine del ciclo di vita di Python 3.8 e non è più supportato. [1] Ciò significa che a partire dalla versione 1.3.0 sarà necessario aggiornare la versione Python in uso a Python 3.9 o superiore.
Deprecazioni dei provider
-
Le classi base astratte
ProvidereProviderV1sono ora deprecate e saranno rimosse in Qiskit 2.0.0. L'astrazione offerta da queste definizioni di interfaccia non forniva un valore sostanziale; incapsulava unicamente gli attributiname,backends, e unget_backend(). Un _provider_, come concetto, continuerà a esistere come una collezione di backend. Se attualmente si sta implementando un provider, si può modificare il codice semplicemente rimuovendoProviderV1come classe padre della propria implementazione. Come parte di questo, probabilmente si vorrebbe aggiungere un'implementazione diget_backendper la retrocompatibilità. Ad esempio:def get_backend(self, name=None, **kwargs): backends = self.backends(name, **kwargs) if len(backends) > 1: raise QiskitBackendNotFoundError("More than one backend matches the criteria") if not backends: raise QiskitBackendNotFoundError("No backend matches the criteria") return backends[0]
Deprecazioni della sintesi
- Il metodo
TwoQubitWeylDecomposition.specialize()è ora deprecato e sarà rimosso nella versione di Qiskit 2.0.0. Questo metodo non ha mai avuto uno scopo pubblico e non è sicuro che un utente finale lo chiami, in quanto muterebbe la scomposizione calcolata nell'oggetto e produrrebbe campi non validi nell'oggetto. È stato usato solo internamente per costruire un nuovo oggettoTwoQubitWeylDecompositionoggetto. Nonostante ciò, era ancora una parte documentata dell'API pubblica della classe e ora è stata deprecata senza alcuna potenziale sostituzione. In questa versione solleva sempre unNotImplementedErrorquando viene chiamato, perché la sottoclasse di specializzazione è stata rimossa come parte della riscrittura di Rust della classe.
Deprecazioni del transpiler
-
Il pass
qiskit.transpiler.passes.CXCancellationè stato deprecato in favore diInverseCancellationche è più generico.CXCancellationè del tutto semanticamente equivalente aInverseCancellation([CXGate()]). -
Il passaggio di transpilazione
qiskit.transpiler.passes.ALAPScheduleè ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Il passaggio è sostituito daALAPScheduleAnalysis, che è un passaggio di analisi. -
Il passaggio di transpilazione
qiskit.transpiler.passes.ASAPScheduleè ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. È stato sostituito daASAPScheduleAnalysise dal nuovo flusso di lavoro di pianificazione. -
Il passaggio di transpilazione
qiskit.transpiler.passes.DynamicalDecouplingè ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Utilizzare invecePadDynamicalDecouplingche svolge la stessa funzione, ma richiede l'esecuzione di passaggi di pianificazione e di analisi dell'allineamento prima di questo. -
Il passaggio di transpilazione
qiskit.transpiler.passes.AlignMeasuresè ora deprecato. Era in attesa di deprezzamento da Qiskit 0.37 (con Terra 0.21 ), rilasciato nel giugno 2022. Si può invece utilizzareConstrainedRescheduleche svolge la stessa funzione e supporta anche l'allineamento a vincoli temporali aggiuntivi.
Deprecazioni relative alla visualizzazione
- I parametri
show_idleeshow_barriernei cassetti della linea temporale sono stati sostituiti rispettivamente daidle_wireseplot_barriersper adattarli ai parametri dei cassetti dei circuiti. I loro nomi precedenti sono ora deprecati e saranno rimossi nella prossima versione principale. I nuovi parametri sono del tutto equivalenti.
Correzioni di bug
-
È stato risolto un problema con la funzione
qpy.dump()per cui, quando il flaguse_symengineera impostato su un oggetto vero che valutavaTruema non era in realtà il booleanoTrue, il payload QPY generato risultava corrotto. Ad esempio, se si impostause_symengineaHAS_SYMENGINEquesto oggetto viene valutato comeTruequando viene lanciato come bool, ma in realtà non èTrue. -
Corretto un problema con la funzione
circuit_drawer()eQuantumCircuit.draw()quando si carica uno stile matplotlib tramite il file di configurazione utente. -
È stato risolto un problema per cui il passaggio
ConstrainedReschedulein precedenza dava un errore se il circuito conteneva un'istruzioneResetistruzione. Questo problema è stato corretto in modo che il passaggio non dia più errori, tuttavia l'hardware reale può comportarsi in modo diverso da quello che Qiskit scheduler presume, soprattutto per le misure e i reset a metà circuito. Lo scheduler di Qiskit sollevaRuntimeWarningse incontra un circuito contenente uno dei due. Corretto #10354 -
È stato risolto un problema con la classe
CommutationCheckerche dava errore se l'attributo di un cancellonameera codificato in UTF8. In precedenza funzionavano solo i nomi dei gate con codifica ascii. Corretto #12501 -
Corretto un problema con gli elementi
SparsePauliOp.apply_layout()ePauli.apply_layout()quando per l'argomentolayoutveniva passato un array non valido con indici duplicati o negativi. In precedenza questo non comportava un errore e la trasformazione eseguita non era valida. Questi metodi ora sollevano un problemaQiskitErrorse vengono forniti indici duplicati o negativi come parte di un layout. -
È stato risolto un problema di prestazioni nei programmi
BackendSamplerV2eBackendEstimatorV2. Corretto #12290 -
È stato risolto un problema con l'opzione
convert_to_target()per cui il convertitore ignorava erroneamente le istruzioni di flusso di controllo se erano specificate nell'attributoBackendConfiguration.supported_instructions, che è la posizione tipica in cui le istruzioni di flusso di controllo sono specificate in un oggettoBackendConfigurationoggetto. Corretto #11872. -
Corretto un problema con l'opzione
circuit_drawer()oQuantumCircuit.draw()quando si usa l'opzione di uscitampl: il programma si blocca se il circuito da disegnare contiene un'operazione ControlFlow e l'opzionefoldè impostata su -1 (cioè nessuna piega). Corretto #12012. -
Corretto un errore nella conversione delle istruzioni di impulso personalizzate nel formato legacy
qiskit.qobjal formato legacy. Il bug è stato introdotto in Qiskit 1.0.0 e causa la conversione di istruzioni con forme di impulso personalizzate che generano un errore. Dopo la correzione, la conversione viene eseguita correttamente e l'impulso personalizzato viene convertito inWaveformcome dovrebbe. Corretto #11828. -
È stato risolto un bug in
transpile()in cui i vincoli personalizzatiinstruction_durations,dtebackend_propertiesvenivano ignorati se forniti contemporaneamente a un backend di tipoBackendV2. Il comportamento dopo la correzione è ora indipendente dal fatto che il backend fornito sia di tipoBackendV1o di tipoBackendV2. Allo stesso modo,timing_constraintsè ora sovrascritto dagli input ditarget, ma ha la precedenza suBackendV1eBackendV2e gli input. -
Chiamando
EquivalenceLibrary.set_entry()aggiornerà correttamente l'oggetto grafico interno della libreria. In precedenza, i metadati venivano aggiornati, ma la struttura del grafo rimaneva inalterata, il che significava che utenti comeBasisTranslatorcontinuerebbero a usare le vecchie regole. Corretto #11958. -
L'opzione
EvolvedOperatorAnsatzgestisce correttamente il caso in cui l'argomento degli operatori è un elenco vuoto. In precedenza, ciò comportava un errore. -
D'ora in poi,
EvolvedOperatorAnsatznon avrà alcuna qreg quando ci sono zero qubit, invece di avere un'istanza con zero qubitQuantumRegisteristanza con zero qubit. Questo comportamento si allinea più coerentemente con la sua superclasseQuantumCircuit. -
Il metodo
Instruction.repeat()sposta ora un insiemeconditionall'esterno restituitoInstructione lascia incondizionate le porte interne della sua definizione. In precedenza, il metodo lasciava leClassicalRegisterall'interno della definizione interna, uno stato non valido che si manifestava in seguito come bug apparentemente non correlati, ad esempio durante la transpilazione o l'esportazione. Corretto #11935. -
È stato risolto un problema nel passaggio
InverseCancellationche in alcuni casi annullava erroneamente un gate parametrato auto-invertito anche se il valore del parametro non corrispondeva. Corretto #11815 -
Migliorare la decomposizione dei gate
MCXGateeMCPhaseGatesenza utilizzare i qubit ancilla, in modo che il numero diCXGatecrescerà in modo quadratico rispetto al numero di qubit e non esponenziale. -
È stato corretto un bug che mandava in crash la funzione
convert_to_target()quando mancano le proprietà dei qubit ( T1, T2 o la frequenza) è stato risolto. I valori mancanti delle proprietà inQubitPropertiessono riempiti conNone. -
BasePassManager.run()non disperderà più il precedentePropertySetnei nuovi flussi di lavoro quando viene richiamato più di una volta. In precedenza, per inizializzare le esecuzioni successive veniva utilizzato lo stessoPropertySetcome in precedenza, veniva utilizzato per inizializzare le esecuzioni successive, il che poteva significare che ai task venivano fornite informazioni sulle proprietà non valide. Il comportamento ora corrisponde a quello di Qiskit 0.44. Corretto #11784. -
Pauli.evolve()ora gestisce correttamente i circuiti quantistici contenenti porte ECR. In precedenza non sono stati riconosciuti come porte Clifford e si è verificato un errore. -
Corretto un bug in
Pauli.evolve()in cui l'evoluzione da parte di un circuito con un nome che corrisponde a certe porte di Clifford ('cx', 'cz', ecc.) faceva evolvere il Pauli in base al nome del circuito, non in base al contenuto del circuito. Questo bug si verifica solo con l'opzione non predefinitaframe='s'. -
È stato risolto un problema di prestazioni nella funzione
qpy.load()quando si deserializzano payload QPY con un gran numero di qubit o clbit in un circuito. -
Corretto un bug nella gestione dell'argomento
default_alignmentdibuild(). Gli input di tipoAlignmentKindsono ora correttamente elaborati come allineamenti predefiniti. -
Corretto un bug nella funzione
qiskit.pulse.utils.format_parameter_value()che convertiva involontariamente numeri interi abbastanza grandi in valori float o causava un arrotondamento imprevisto. Per i dettagli, vedere il numero 11971. -
Correzione di un problema nella classe
QDriftin cui i coefficienti dell'hamiltoniana erano precedentemente forzati a essere positivi prendendo il valore assoluto di ciascun coefficiente. Il problema è stato corretto in modo che i segni dei coefficienti negativi siano aggiunti di nuovo. -
È stato risolto un bug in
convert_durations_to_dt(), a causa del quale la funzione applicava ciecamente una conversione da secondi adtsulle durate dei circuiti, indipendentemente dalle unità originali dell'attributo. Questo potrebbe portare a ordini di grandezza errati nelle durate dei circuiti riportate. -
Fissato
SparsePauliOp.apply_layout()per funzionare correttamente con gli operatori zero-qubit. Ad esempio, se in precedenza si è creato un qubit 0 e si è applicato un layout come:op = SparsePauliOp("") op.apply_layout(None, 3)questo avrebbe precedentemente generato un errore. Ora questo restituirà correttamente un operatore della forma:
SparsePauliOp(['III'], coeffs=[1.+0.j]) -
È stata corretta una svista nel passaggio
Commuting2qGateRouterin cui le permutazioni qreg non venivano aggiunte all'insieme di proprietà del passaggio, per cui dovevano essere rintracciate manualmente dall'utente. Ora è possibile accedere alla permutazione attraverso la proprietàlayoutdel circuito di uscita e inserire il passaggio in qualsiasi pipeline di transpilazione senza perdita di informazioni. -
Corretta un'imprecisione in virgola mobile durante la scalatura di alcune unità di impulso tra secondi e nanosecondi. Se l'impulso fosse stato definito simbolicamente, la scalatura avrebbe potuto introdurre un inutile errore in virgola mobile per alcune versioni di
symengine, che avrebbe potuto dare risultati inaspettati una volta che i simboli fossero stati completamente vincolati. Corretto #12392. -
I gestori di passaggio preimpostati di
transpile()non falliranno più sui circuiti con flusso di controllo, se non è specificato un target hardware o un set di porte di base. Ora tratteranno tali obiettivi astratti come se permettessero tutte le operazioni del flusso di controllo. Corretto #11906. -
Il metodo
qiskit.instruction.Instruction.soft_compare()ha lo scopo di confrontare se due porte corrispondono nel nome, nel numero di qubit, nel numero di clbit e nel numero di parametri. Tuttavia, c'era un errore di battitura per cui non controllava il numero di qubit e il numero di clbit per una corrispondenza. Questo risolve l'apparente errore di battitura. -
Il plugin predefinito
initnon sollevava correttamente un problema di tipoTranspilerErrorquando veniva chiamato con un livello di ottimizzazione non valido. -
È stato risolto un problema con il metodo
Operator.from_circuit()in cui il metodo del costruttore interpretava in modo errato la permutazione finale del layout, causando la costruzione di un oggetto non validoOperatornon valido. In precedenza, il layout finale veniva elaborato senza tenere conto del layout iniziale, cioè l'inizializzazione non era corretta per tutti i circuiti quantistici che hanno un layout iniziale non banale. -
È stato risolto un problema di prestazioni in
PassManager.run()quando viene eseguito su più circuiti in parallelo. Non spenderà più tempo per serializzare il filePassManager(che è un requisito per l'esecuzione parallela) quando vengono forniti più ingressi, se si intende elaborare gli ingressi solo in modo seriale. -
Parameterè stato aggiornato in modo che le istanze che si confrontano abbiano sempre lo stesso hash. In precedenza, veniva confrontato solo l'elementoParameter.uuidveniva confrontato, quindi le istanzeParameteristanze con nomi diversi potevano essere confrontate in modo uguale se erano state costruite usando un valore comune per il parametrouuid(che di solito non viene passato esplicitamente). -
Corretto un bug in
plot_coupling_map()che causava una colorazione errata dei bordi della mappa di accoppiamento. Corretto #12369. -
Il parser OpenQASM 2.0 (
qasm2.load()eqasm2.loads()) è ora in grado di valutare espressioni gate-angle che includono operandi interi che farebbero traboccare l'intero di dimensioni di sistema. Questi saranno valutati in un contesto di virgola mobile a doppia precisione, proprio come il resto dell'espressione. Tuttavia, un intero arbitrariamente grande non è necessariamente rappresentabile in virgola mobile a doppia precisione, quindi è possibile che il circuito, comunque sia stato generato, abbia già perso tutta la precisione numerica modulo . -
Parameterle istanze usate come stand-ins per le variabili diinputnei programmi di OpenQASM 3 avranno ora i loro nomi sfuggiti per evitare collisioni con le porte incorporate durante l'esportazione a OpenQASM 3. In precedenza poteva verificarsi un conflitto di nomi e l'esportatore generava OpenQASM 3 non valido. -
Corretto il bug in
QuantumCircuit.draw()che causava la modifica dei dizionari di stile personalizzati per il cassetto Matplotlib al momento dell'esecuzione. -
QuantumCircuit.append()concopy=True(il suo valore predefinito) ora copierà correttamente le istruzioni parametrizzate daParameterExpressione non solo da istanzeParameteristanze. -
La gestione interna delle calibrazioni dei circuiti personalizzati e delle
InstructionDurationsè stata trasferita dalla funzionetranspile()funzione ai singoli passaggi del transpiler:DynamicalDecoupling,DynamicalDecoupling. In precedenza, le durate delle istruzioni provenienti dalle calibrazioni dei circuiti non venivano prese in considerazione a meno che non venissero incorporate manualmente nell'argomento di input dell'istruzione, ma ora i passaggi che ne hanno bisogno analizzano il circuito e scelgono il valore di durata più pertinente in base al seguente ordine di priorità: target > input personalizzato > calibrazioni dei circuiti. -
Corretto un bug in
transpile()in cui l'argomentonum_processesveniva utilizzato solo se venivano fornitidtoinstruction_durations.
Altre note
-
Il supporto per la piattaforma arm64 macOS è stato promosso da Tier 3 a Tier 1. In precedenza la piattaforma era di livello 3 perché non era disponibile un ambiente CI per testare Qiskit sulla piattaforma. Ora che Github ha messo a disposizione dei progetti open source un ambiente arm64 macOS [1] stiamo testando la piattaforma insieme alle altre piattaforme supportate dal Tier 1.
[1 ]
1.0.0rc1
Note sull'aggiornamento dei provider
-
Il modulo deprecato
qiskit.providers.fake_providerè stato migrato nel pacchettoqiskit-ibm-runtimePython. Per questo motivo, i seguenti elementi del fileqiskit.providers.fake_providersono stati rimossi a seguito della loro deprecazione in Qiskit 0.46:qiskit.providers.fake_provider.FakeProviderqiskit.providers.fake_provider.FakeProviderForBackendV2qiskit.providers.fake_provider.FakeProviderFactoryqiskit.providers.fake_provider.fake_backends.FakeBackendV2- qualsiasi backend falso contenuto in
qiskit.providers.fake_provider.backends(accessibile attraverso il provider) qiskit.providers.fake_provider.FakeQasmSimulatorqiskit.providers.fake_provider.FakeJobqiskit.providers.fake_provider.FakeQobj
Per utilizzare il nuovo modulo provider fasullo, è possibile eseguire
pip install qiskit-ibm-runtimee sostituire il percorso di importazione di qiskit (qiskit.providers.fake_provider) con il nuovo percorso di importazione (qiskit_ibm_runtime.fake_provider). Esempio di migrazione:# Legacy path from qiskit.providers.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke() # New path # run "pip install qiskit-ibm-runtime" from qiskit_ibm_runtime.fake_provider import FakeProvider, FakeSherbrooke backend1 = FakeProvider().get_backend("fake_ourense") backend2 = FakeSherbrooke()Inoltre, i seguenti backend fasulli progettati per scopi speciali di test sono stati sostituiti dalla nuova classe
GenericBackendV2e sono stati rimossi anche in seguito alla loro deprecazione in Qiskit 0.46:qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2`qiskit.providers.fake_provider.fake_backend_v2.FakeBackendV2LegacyQubitPropsqiskit.providers.fake_provider.fake_backend_v2.FakeBackend5QV2qiskit.providers.fake_provider.fake_backend_v2.FakeBackendSimple
Esempio di migrazione alla nuova
GenericBackendV2classe:# Legacy path from qiskit.providers.fake_provider import FakeBackend5QV2 backend = FakeBackend5QV2() # New path from qiskit.providers.fake_provider import GenericBackendV2 backend = GenericBackendV2(num_qubits=5) # note that this class will generate 5q backend with generic # properties that serves the same purpose as FakeBackend5QV2 # but will generate different results