Note di rilascio di Qiskit SDK 2.1
2.1.2
Preludio
Qiskit 2.1.2 è una piccola patch che corregge alcuni bug riscontrati nella serie 2.1.
Correzioni di bug
-
In Qiskit 2.1.0 il
VF2PostLayoutè stato aggiunto allo stadiooptimizationdel gestore dei passaggi preimpostati quandooptimization_level=3. Tuttavia, l'uscita del pass non è mai stata applicata al circuito. Questa versione rimuove il passaggio dallo stadiooptimizationdel gestore dei passaggi preimpostati per risparmiare i costi di esecuzione. In Qiskit 2.2.0 il passaggio sarà parte dello stadiooptimizatione l'uscita sarà applicata se il passaggio trova un layout migliore. -
È stato risolto un problema nel passaggio
VF2Layoutin cui, anche con un set di semi fisso, l'output del passaggio era potenzialmente non deterministico; in particolare se il circuito di ingresso aveva qubit attivi che contenevano solo operazioni a qubit singolo. Corretto #14729 -
Corretto un bug in
PassManager.run()in cui la funzionecallbacknon veniva invocata quando si eseguivano circuiti multipli. Il callback viene ora attivato correttamente per ogni passaggio su ogni circuito, anche nell'esecuzione parallela. -
I passaggi di transpiler incorporati che impostano la proprietà
final_layoutora gestiscono correttamente l'aggiornamento di questo campo se era già impostato. Questo può essere osservato come il metodoTranspileLayout.routing_permutationrestituisce ora una permutazione corretta dopo aver eseguito più di un passaggio che impostafinal_layout.Questo non ha influito sulle normali chiamate a
transpile()ogenerate_preset_pass_manager()utilizzando i plugin integrati di Qiskit; nessuna pipeline costruita in questa forma tenterebbe di impostarefinal_layoutpiù di una volta. -
È stato corretto un bug in
Target.instruction_supported()in cui il controllo dell'ordine dei qubit dell'istruzione veniva saltato quando il metodo veniva chiamato con gli argomentioperation_nameeparametersche corrispondevano a un'istruzione esistente. -
È stato corretto un bug di correttezza quando si esportano circuiti con istruzioni di ritardo utilizzando le unità di
psin QASM3. -
Corretto un caso limite nella visualizzazione del
QFTcircuito. In precedenza, quando si chiamavaQFT.inverse()e poi si modificavano gli attributi del circuito QFT, il nome del QFT veniva visualizzato come"IQFT_dg". Questo non era corretto e ora mostra correttamente"IQFT". Corretto #14758. -
Corretta una perdita di memoria nel coordinamento dell'uso di
qk_circuit_get_instructioneqk_circuit_instruction_clear. -
Chiarito il messaggio di errore per le versioni non valide specificate in
qpy.dump()per renderlo più facile da interpretare. -
È stato risolto un problema con la funzione
generate_preset_pass_manager()in cui la funzione ignorava erroneamente i dati relativi ai vincoli di temporizzazione contenuti nell'oggettoTargetfornito quando l'argomentobackendnon era impostato. Corretto #14329 -
Corretto un bug in
SparsePauliOp.simplify()in cui il metodo rimuoveva i termini Pauli in base alle grandezze dei loro coefficienti prima di combinare i duplicati. Ciò ha causato un comportamento errato in due casi limite fondamentali:- Quando più termini di Pauli identici avevano coefficienti piccoli, singolarmente inferiori alla soglia di semplificazione, ma la cui somma superava la soglia, tali termini venivano erroneamente rimossi.
- Quando più termini di Pauli identici avevano coefficienti superiori alla soglia ma sommati quasi a zero, venivano erroneamente mantenuti.
Vedere #14194 per maggiori dettagli.
2.1.1
Preludio
Qiskit 2.1.1 è una piccola patch che corregge alcuni bug riscontrati nella serie 2.1.
Correzioni di bug
-
Corretto un bug nel controllo di
DAGOpNodein cui il confronto tra due oggettiDAGOpNodeche contengono un'istruzioneBoxOpistruzione. In precedenza, l'attributoBoxOp.unitnon veniva considerato come parte del controllo di uguaglianza, il che poteva portare a valutare come uguali due nodi non uguali. -
Corretto l'avviso di deprezzamento per Python 3.9 in modo che sia correttamente identificato come causato dal codice utente quando si importa Qiskit. In precedenza, non veniva identificato come causato dal codice utente e ciò significava che i filtri di avviso predefiniti di Python non mostravano l'avviso all'utente.
-
Corretto il comportamento dell'argomento
max_trialsperVF2Layoutquando è impostato suNoneo su un numero negativo. È stato documentato che il passaggio limita la ricerca in base alla dimensione del circuito o dell'obiettivo se l'opzione è impostata suNonee che accetta valori negativi per specificare una ricerca senza limiti. Tuttavia, in 2.1.0 questo comportamento è stato erroneamente modificato in modo cheNoneeseguisse una ricerca senza limiti e l'uso di un numero negativo generasse un errore. Queste sviste sono state corrette in modo che il passaggio si comporti come documentato e sia coerente con le versioni precedenti. -
Corretto un problema nei plugin di sintesi ad alto livello
MCXSynthesis1DirtyKG24eMCXSynthesis2DirtyKG24perMCXGatein cui i plugin non consideravano i qubit ausiliari puliti disponibili come qubit ausiliari sporchi disponibili. In particolare, il pluginMCXSynthesis2DirtyKG24non si applica quando sono disponibili un qubit ausiliario pulito e uno sporco. -
Corretta una regressione delle prestazioni quando si costruisce in modo incrementale
ParameterExpressioncombinando un gran numero di sottoespressioni. Corretto #14653
2.1.0
Preludio
La release di Qiskit v2.1 introduce diversi importanti miglioramenti in aree chiave, tra cui l'API C, le funzionalità del transpiler e l'usabilità dei circuiti quantistici. Inoltre, include molti miglioramenti generali e correzioni di bug. I punti salienti includono:
- Estensioni dell'API C: Sulla base del lavoro iniziato nella versione precedente, Qiskit v2.1 aggiunge il supporto per la creazione e l'interazione con i circuiti quantistici tramite funzioni API C, supportando l'aggiunta di porte standard, istruzioni standard e porte unitarie. In questa versione è stato aggiunto anche un insieme di funzioni C per costruire e manipolare un oggetto
Targetin preparazione al supporto di un flusso di lavoro completo di transpilazione basato su API C nella prossima versione. Inoltre,QkComplex64è ora definito come una struct, che serve a rappresentare in modo indipendente dal compilatore i numeri complessi quando si lavora con l'API C di Qiskit. Anche il file di intestazione dell'API C è stato aggiornato in modo che sia generalmente compatibile con l'uso nativo in C++.- Supporto del set di basi Clifford+T: Il transpiling dei circuiti per un target con porte Clifford+T è ora supportato immediatamente. Se l'insieme di basi è costituito solo da porte Clifford+T, Qiskit assicura che i passaggi appropriati per la gestione di queste porte siano aggiunti ai gestori di passaggi preimpostati. Si tratta di un primo passo verso il supporto della transpilazione per i backend a tolleranza di errore.
- Miglioramenti a
BoxOp: Questa versione aggiunge la possibilità di allegare annotazioni personalizzate alle istruzioniBoxOpalle istruzioni, supportando ulteriormente il concetto di box statement di OpenQASM 3 in Qiskit. Questo include anche la serializzazione delle annotazioni nei formati QASM e QPY. Inoltre, è stato aggiunto il supporto per l'uso della durata del tratto nelle caselle.- Python 3.9 deprecazione: Python 3.9 è deprecato a partire da Qiskit v2.1 e non sarà più supportato in Qiskit v2.3.
Per maggiori dettagli su quanto sopra e molto altro, consultate le note di rilascio qui sotto e la documentazione aggiornata.
Funzionalità API C
-
L' API Qiskit C ( qiskit.h ) ora supporta la costruzione e l'interazione con i circuiti quantistici. L'API dei circuiti C è incentrata sul tipo opaco
QkCircuitche rappresenta il circuito. Il tipoQkCircuitconsente di costruire un circuito con qualsiasi elemento di circuito definito in modo nativo nel modello di dati Rust interno di Qiskit perQuantumCircuit. Attualmente comprende cancelli standard,Measure,Delay,Reset,Barrier, eUnitaryGate. Le funzionalità dell'API C dei circuiti si amplieranno nelle prossime versioni, man mano che il modello di dati di Qiskit verrà aggiunto in modo nativo al modello di dati interno di Rust, consentendo di utilizzarlo nell'API C.Ad esempio, è possibile utilizzare l'API C per costruire uno stato GHZ a 1000 qubit:
#include <qiskit.h> int main() { // Create an empty circuit with 1000 qubits and 1000 clbits QkCircuit *qc = qk_circuit_new(1000, 1000); // Add a Hadamard Gate on Qubit 0 uint32_t one_qubit[1] = {0,}; qk_circuit_gate(qc, QkGate_H, one_qubit, NULL); // The NULL pointer is for the parameter array. // Since Hadamard doesn't have parameters it // is never accessed. // Add the CX Gates: uint32_t qubits[2] = {0, 0}; uint32_t num_qubits = qk_circuit_num_qubits(qc); for (int i = 1; i<num_qubits; i++) { qubits[1] = i; qk_circuit_gate(qc, QkGate_CX, qubits, NULL); } // Add the measurements: uint32_t num_clbits = qk_circuit_num_clbits(qc); for (uint32_t i = 0; i<num_clbits; i++) { qk_circuit_measure(qc, i, i); } qk_circuit_free(qc); return 0; } -
L' API di Qiskit C ( qiskit.h ) ora supporta la costruzione di un oggetto
Targetper rappresentare un obiettivo di transpilazione. Ad esempio:#include <qiskit.h> #include <math.h> int main() { // Create a Target with 3 qubits QkTarget *target = qk_target_new(3); // Create a Target Entry for a CX Gate QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX); // Define properties for CX between qubits (0, 1) with a duration of 1.93e-9 sec and error rate 3.17e-10. uint32_t qargs[2] = {0, 1}; qk_target_entry_add_property(cx_entry, qargs, 2, 1.93e-9, 3.17e-10); // Define properties for cx between qubits (1, 0) with a duration of 1.27e-9 sec and no error. uint32_t rev_qargs[2] = {1, 2}; qk_target_entry_add_property(cx_entry, rev_qargs, 2, 1.27e-9, NAN); // Add the cx entry to the target. QkExitCode result_cx = qk_target_add_instruction(target, cx_entry); // Add global ideal Y gate entry to the target QkExitCode result_y = qk_target_add_instruction(target, qk_target_entry_new(QkGate_Y)); // Create a Target entry for a Measurement with increasing duration and error as the qubit indices increase QkTargetEntry *measure = qk_target_entry_new_measure(); for (uint32_t i = 0; i< qk_target_num_qubits(target); i++) { uint32_t q[1] = {i}; qk_target_entry_add_property(measure, q, 1, 1e-6 * (i + 1), 1e-3 * (i + 1)); } QkExitCode result_measure = qk_target_add_instruction(target, measure); return 0; } -
È stato aggiunto il supporto per l'interrogazione delle informazioni sulla versione di Qiskit dall'API C utilizzando le seguenti macro:
QISKIT_VERSION_MAJORcontiene il numero di versione principale.QISKIT_VERSION_MINORcontiene il numero di versione minore.QISKIT_VERSION_PATCHcontiene il numero di versione della patch.QISKIT_VERSIONcontiene una rappresentazione numerica delle informazioni sulla versione, che può essere utilizzata per i confronti.QISKIT_VERSION_NUMERIC(M,m,p): macro simile a una funzione che restituisce la versione " M.m.p " come valore numerico, utilizzabile per i confronti.
Ad esempio, per verificare se la versione corrente è almeno 2.1.0, si può usare:
if (QISKIT_VERSION >= QISKIT_VERSION_NUMERIC(2, 1, 0)) { // Code for version 2.1.0 or later } -
Abilitata la compatibilità con il C++ per l'API C. L'intestazione generata consente ora di chiamare direttamente oggetti e funzioni dal C++. Per esempio, un'osservabile a 100 qubit con il termine XYZ sui primi 3 qubit può essere costruita come
#include <iostream> #include <complex> #include <vector> #include <qiskit.h> int main() { uint32_t num_qubits = 100; // Use smart pointer with custom deleter to manage QkObs memory QkObs *obs = qk_obs_zero(num_qubits); // Construct the observable term std::complex<double> coeff_complex = 2.0; QkComplex64 coeff = qk_complex64_from_native(coeff_complex); std::vector<QkBitTerm> bit_terms = {QkBitTerm_X, QkBitTerm_Y, QkBitTerm_Z}; std::vector<uint32_t> indices = {0, 1, 2}; QkObsTerm term { .coeff = coeff, .len = bit_terms.size(), .bit_terms = bit_terms.data(), .indices = indices.data(), .num_qubits = num_qubits }; qk_obs_add_term(obs.get(), &term); // Print observable properties std::cout << "num_qubits: " << qk_obs_num_qubits(obs) << "\n"; std::cout << "num_terms: " << qk_obs_num_terms(obs) << "\n"; qk_obs_free(obs); return 0; }
Caratteristiche dei circuiti
-
Aggiunta una funzione
random_circuit_from_graph()che genera un circuito casuale che induce lo stesso grafo di interazione specificato da interaction_graph.La probabilità di estrarre casualmente un bordo dal grafo di interazione come porta a due qubit può essere impostata dall'utente nell'attributo del peso di un bordo nel grafo di interazione in ingresso. Se l'utente non imposta la probabilità, ogni bordo viene disegnato in modo uniforme. Cioè, ogni porta a due equbit rappresentata da un bordo nel grafo di interazione ha la stessa probabilità di essere aggiunta al circuito casuale. Se viene impostato solo un sottoinsieme di probabilità dei bordi, verrà sollevato
ValueError.In questo esempio,
cp_mapè un elenco di bordi con pesi arbitrari.from qiskit.circuit.random.utils import random_circuit_from_graph import rustworkx as rx pydi_graph = rx.PyDiGraph() n_q = 5 cp_map = [(0, 1, 0.18), (1, 2, 0.15), (2, 3, 0.15), (3, 4, 0.22)] pydi_graph.extend_from_weighted_edge_list(cp_map) # cp_map can be passed in directly as interaction_graph qc = random_circuit_from_graph(interaction_graph = pydi_graph, min_2q_gate_per_edge = 1, max_operands = 2, measure = True, conditional = True, reset = True, seed = 0, insert_1q_oper = True, prob_conditional = 0.21, prob_reset = 0.1) qc.draw(output='mpl')
-
Aggiunto un nuovo
QuantumCircuitmetodo:QuantumCircuit.has_control_flow_op()per verificare se unQuantumCircuitcontiene operazioni sul flusso di controllo. -
Un nuovo modulo
qiskit.circuit.annotatione l'oggetto principioAnnotationsono stati aggiunti.Le annotazioni sono un modo per etichettare le istruzioni (al momento solo
BoxOp) con dati locali e personalizzati dall'utente. Questi dati sono destinati a essere consumati da passaggi di transpiler personalizzati. Le annotazioni forniscono un modo per allegare i dati a istruzioni specifiche, invece di utilizzare l'oggetto contesto globalePropertySetdurante la compilazione.Tutti gli
Annotationhanno un camponamespace. Questa chiave stringa è usata per le ricerche, in modo che i consumatori possano sapere se gestiscono o meno una particolare annotazione. Attualmente non esistono metodi per interrogare la semantica astratta di una sottoclasseAnnotationma si prevede che questi metodi saranno ampliati in futuro.Per una discussione completa delle funzionalità e dei casi d'uso, vedere
qiskit.circuit.annotationper una discussione completa delle funzionalità e dei casi d'uso. -
BoxOp(create daQuantumCircuit.box()) possono ora essere annotate con istanzeAnnotationistanze personalizzate. L'uguaglianza di due caselle dipende dall'uguaglianza delle annotazioni.In genere, questo si ottiene passando un elenco di annotazioni come unico argomento posizionale quando si usa
QuantumCircuit.box()nella forma di gestore di contesto:from qiskit.circuit import annotation, QuantumCircuit class MyAnnotation(annotation.Annotation): namespace = "my.annotation" def __eq__(self, other): return isinstance(other, MyAnnotation) qc = QuantumCircuit() with qc.box([MyAnnotation()]): pass -
Il metodo
UnitaryGate.control()utilizza internamente il metodoqs_decomposition()invece diIsometryper la decomposizione utilizzata per definire il controlloUnitaryGate. Questa modifica riduce il numero diCXGateutilizzati nel filedefinitionper i risultati restituitiControlledGatedi circa 2x. -
Miglioramento della sintesi di un sistema multicontrollato
U1Gatein modo che non cresca esponenzialmente con il numero di controlli. -
L'attributo
BoxOp.durationpuò ora essere unexpr.Exprcon tipoDuration, proprio comeDelay.duration. Questo include anche il supportoStretchper la durata di unBoxOp.
Caratteristiche primitive
-
I PUB degli stimatori utilizzati come input di
BaseEstimatorV2.run()possono ora essere definiti utilizzandoSparseObservableper la componente osservabile di PUB. Questo si aggiunge ai tipi già supportati di:str,Pauli,SparsePauliOp, e una mappatura distroPauliai valori difloat. Tuttavia, se il fileSparseObservablecontiene proiettori, il supporto per la loro gestione dipende dall'implementazione della primitiva. A partire da questa versione le implementazioni in Qiskit (StatevectorEstimatoreBackendEstimatorV2),qiskit-ibm-runtime(qiskit_ibm_runtime.EstimatorV2) e le implementazioni primitive di Qiskit Aer (qiskit_aer.primitives.EstimatorV2) non supportano ancora gli osservabili proiettivi. Gli osservabili proiettivi sono quelli che contengono i termini:0,1,+,-,r, ol. -
Aggiungere il supporto alla classe
DataBinper renderla serializzabile conpickle. Questo permette di rendere ilPrimitiveJobePrimitiveResultserializzabile conpickleanche.
OpenQASM Caratteristiche
-
qasm3.dump()eqasm3.dumps()hanno un nuovo argomentoannotation_handlers, utilizzato per fornire istanze diannotation.OpenQASM3Serializeral processo di esportazione di OpenQASM 3, che può serializzare oggetti personalizzatiAnnotationin OpenQASM 3. -
Quando è installato
qiskit_qasm3_import>=0.6.0,qasm3.load()eqasm3.loads()hanno un nuovo argomentoannotation_handlers, che viene utilizzato per fornire istanze diannotation.OpenQASM3Serializeral processo di importazione di OpenQASM 3, che può deserializzare gli oggetti personalizzati diAnnotationda OpenQASM 3. Questo supporto è attualmente limitato alle dichiarazionibox, poiché questo è l'unico posto in cui Qiskit può rappresentare le annotazioni nel suo modello di dati.
Caratteristiche QPY
-
Aggiunta di un nuovo formato QPY versione 15 che include il supporto per i nuovi oggetti
Annotationcon il supporto di serializzatori e deserializzatori esterni. Il formato consente a tali serializzatori di essere statici e nel formato binario sono allocati posti sicuri per gli oggetti di stato e le rappresentazioni di annotazioni personalizzate. -
qpy.dump()eqpy.load()hanno ora un argomento opzionaleannotation_factories, che viene utilizzato per fornire funzioni di costruzione di oggettiannotation.QPYSerializeroggetti per gestireAnnotationsottoclassi. Questi devono essere forniti dall'utente, in modo simile ametadata_serializer, poiché in generale Qiskit non può conoscere tutti i possibili oggetti definiti dall'esternoAnnotationdefiniti dall'esterno. -
Aggiunta di una nuova funzione
get_qpy_version()al moduloqpymodulo. Questa funzione ispeziona un file QPY e recupera la versione del formato QPY utilizzata nel payload. La versione viene restituita come numero intero, che può essere utilizzato per scopi di registrazione o debug. vedere #14201.
Caratteristiche dell'informazione quantistica
-
È stata aggiunta una nuova classe,
PauliLindbladMapche è una parametrizzazione basata su Pauli di un sottoinsieme di mappe lineari di operatori multi-qubit, utilizzate in applicazioni di apprendimento del rumore. Questa classe dovrebbe costituire la spina dorsale di algoritmi di apprendimento del rumore migliorati e fornire un controllo migliore e più efficiente sui modelli di rumore nelle future versioni di Qiskit. -
Introdotto il
QubitSparsePaulieQubitSparsePauliListche rappresentano gli stessi concetti diPauliePauliListrispettivamente, ma memorizzano solo termini non identici, in modo analogo aSparseObservable. Queste classi sono destinate principalmente a essere utilizzate con il nuovoPauliLindbladMap.
Caratteristiche della sintesi
-
Aggiunto un nuovo algoritmo di sintesi per
HalfAdderGateche non richiede qubit ausiliari e ha un miglior numero di CX rispetto aadder_qft_d00(): -
Aggiunte nuove scomposizioni per
MCXGatel'utilizzo di ancille pulite, migliorando la profondità e l'efficienza del circuito:synth_mcx_1_clean_kg24(), utilizzando 1 qubit ancilla pulito aggiuntivosynth_mcx_1_dirty_kg24(), utilizzando 1 qubit ancilla sporco aggiuntivosynth_mcx_2_clean_kg24()utilizzando 2 qubit ancillari puliti aggiuntivisynth_mcx_2_dirty_kg24(), utilizzando 2 qubit ancillari sporchi aggiuntivi
Utilizzo di esempio:
from qiskit.synthesis.multi_controlled import synth_mcx_1_clean_kg24 n_ctrls = 10 qc = synth_mcx_1_clean_kg24(n_ctrls) qc.draw() -
La sintesi di porte multicontrollate
CZGateè stata migliorata per ridurre il numero di porte sintetizzate; in alcuni casi è possibile una riduzione fino al 99%. Questo risultato è stato ottenuto sfruttando la sintesi migliorata intorno allaMCXGatecon una sintesi controllataCZGatesintesi controllata. -
Migliorato il plugin predefinito per la sintetizzazione di
AnnotatedOperationoggetti. Il miglioramento è particolarmente utile quando si creano e si traspongono circuiti controllati con porte controllate al loro interno. Ad esempio:from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import CXGate from qiskit.compiler import transpile inner = QuantumCircuit(5) inner.append(CXGate().control(3, annotated=True), [0, 1, 2, 3, 4]) controlled_inner_gate = inner.to_gate().control(2, annotated=True) qc = QuantumCircuit(15) qc.append(controlled_inner_gate, [0, 1, 2, 3, 4, 5, 6]) qct = transpile(qc, basis_gates=["cx", "u"])Questo codice crea un circuito quantistico
qcche contiene un circuito quantistico a 2 controlli con una porta CX a 3 controlli. Con questo miglioramento, il numero di porte CX nel circuito transpilato si riduce da378a30. Si noti che specificandoannotated=Truequando si definisce la logica di controllo, le porte controllate vengono create come operazioni annotate. In questo modo si evita una sintesi avida, si permette al transpiler di rilevare checontrolled_inner_gateè equivalente a una porta X a 6 controlli e di scegliere il miglior metodo di sintesi disponibile per le porte X a più controlli, in particolare utilizzando i qubit ancilla disponibili. -
La funzione
adder_qft_d00(), utilizzata per sintetizzareModularAdderGateeHalfAdderGateaccetta ora un parametro aggiuntivoannotated. SeTrue, l'inverse-QFT-gate all'interno degli adders è implementato come un'operazione annotata, consentendo al transpiler di applicare ulteriori ottimizzazioni. -
La decomposizione quantistica di Shannon (
qs_decomposition()) include ora un'ottimizzazione che riduce il numero diCXGatenel caso in cui l'unitario di ingresso sia un unitario controllato. -
La funzione di sintesi
synth_mcx_1_clean_b95()produce ora un circuito con meno porte CX. -
La classe
SolovayKitaevDecompositionha ora degli argomenti aggiuntivi nell'inizializzatore, che permettono di costruirla direttamente da un insieme dibasis_gatese da undepthper le approssimazioni di base. -
Aggiunto
SolovayKitaevDecomposition.save_basic_approximations()per salvare l'insieme delle approssimazioni di base utilizzate dalla classe in un formato binario. Questa modifica, in combinazione con i nuovi argomenti dell'inizializzatore, consente agli utenti di evitare l'uso esplicito digenerate_basic_approximations()e affidarsi solo aSolovayKitaevDecomposition.
Funzionalità del transpiler
-
La funzione
generate_preset_pass_manager()genera ora uno speciale gestore di passaggi quando l'insieme di basi consiste solo di porte Clifford+T. Formalmente, un insieme di basi Clifford+T deve contenere solo porte Clifford, con oTGate,TdgGate, o entrambi. L'elenco completo delle porte di Clifford supportate può essere ottenuto utilizzandoget_clifford_gate_names().Ad esempio:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit.quantum_info import get_clifford_gate_names basis_gates = get_clifford_gate_names() + ["t", "tdg"] pm = generate_preset_pass_manager(basis_gates=basis_gates) qc = QuantumCircuit(1) qc.rx(0.8, 0) qct = pm.run(qc) print(qct.count_ops())Risulterebbe con:
OrderedDict([('h', 10210), ('t', 4508), ('tdg', 4503), ('sdg', 943), ('s', 941)])In precedenza, il gestore dei passaggi generati non era in grado di gestire l'esempio precedente perché non riusciva a decomporre le porte di rotazione a singolo-qubit
UGatedi rotazione a singolo qubit in porte Clifford+T. Tuttavia, il nuovo gestore del passaggio utilizza la decomposizione di Solovay-Kitaev per approssimare le porte di rotazione a singolo qubit utilizzando le porteH,TeTdg, e chiama il passaggio transpiler per tradurre ulteriormente le porte nell'insieme di basi di destinazioneBasisTranslatorper tradurre ulteriormente le porte nell'insieme di basi di destinazione. Il nuovo gestore di passaggi presenta anche altre modifiche per consentire una traduzione più efficiente in porte Clifford+T.È importante notare che l'insieme di basi di Clifford+T specificato deve essere universale, altrimenti la trasposizione potrebbe non riuscire. Sebbene l'insieme di porte
["h", "t", "tdg"]o anche["h", "t"]sia sufficiente per l'universalità, si raccomanda di aggiungere altre porte di Clifford all'insieme, se possibile, perché altrimenti la traduzione potrebbe essere meno efficiente. Ad esempio, se la porta S non è inclusa, le porte S potrebbero essere decomposte in coppie di porte T (cioè, le porte Clifford potrebbero essere decomposte in porte non Clifford, il che potrebbe non essere il comportamento desiderato).Segue un esempio leggermente più grande:
from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import QFTGate from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager qc = QuantumCircuit(4) qc.append(QFTGate(4), [0, 1, 2, 3]) basis_gates = ["cx", "s", "sdg", "h", "t", "tdg"] pm = generate_preset_pass_manager(basis_gates=basis_gates, optimization_level=2) qc = QuantumCircuit(4) qc.append(QFTGate(4), [0, 1, 2, 3]) qct = pm.run(qc) print(qct.count_ops())Risulterebbe con:
OrderedDict([('h', 96510), ('tdg', 42396), ('t', 42389), ('s', 8240), ('sdg', 8235), ('cx', 12)]) -
Aggiunto un nuovo plugin di sintesi ad alto livello
HalfAdderSynthesisR25per sintetizzare un fileHalfAdderGate. Il nuovo plugin si basa suadder_ripple_r25().L'aggiornamento è stato fatto anche per seguire la seguente sequenza di sintetizzatori half-adder
HalfAdderSynthesisDefaultè stata aggiornata per seguire la seguente sequenza di sintetizzatori di half-adder:"HalfAdder.ripple_r25"quando ci sono qubit,"HalfAdder.ripple_c04"quando è disponibile un qubit ausiliario e"HalfAdder.ripple_r25"in tutti i casi restanti. -
Sono stati aggiunti più plugin di sintesi ad alto livello per sintetizzare una
MCXGate:MCXSynthesis1CleanKG24, sulla base disynth_mcx_1_clean_kg24().MCXSynthesis1DirtyKG24, sulla base disynth_mcx_1_dirty_kg24().MCXSynthesis2CleanKG24, sulla base disynth_mcx_2_clean_kg24().MCXSynthesis2DirtyKG24, sulla base disynth_mcx_2_dirty_kg24().
La classe
MCXSynthesisDefaultè stata aggiornata per eseguire la seguente sequenza di metodi di sintesi MCX finché il primo non ha successo: :"mcx.2_clean_kg24","mcx.1_clean_kg24","mcx.n_clean_m15","mcx.n_dirty_i15"`, ``"mcx.2_dirty_kg24","mcx.1_dirty_kg24","mcx.1_clean_b95","mcx.noaux_v24". I metodi sono ordinati in modo da applicare per primi quelli di migliore qualità. -
VF2PostLayoutè stato aggiunto alla fine della fase di ottimizzazione predefinita, quando si utilizza il livello di ottimizzazione 3. -
Aggiunto un nuovo
OptimizeCliffordTche unisce coppie di porte T consecutive in porte S e coppie di porte Tdg consecutive in porte Sdg. Questa ottimizzazione è particolarmente efficace per ridurre il numero di T in seguito alla decomposizione di Solovay-Kitaev, che produce più porte T o Tdg consecutive. Ad esempio:from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import SolovayKitaev, OptimizeCliffordT qc = QuantumCircuit(1) qc.rx(0.8, 0) # Run Solovay-Kitaev pass on qc transpiled = SolovayKitaev()(qc) print(transpiled.count_ops().get("t", 0) + transpiled.count_ops().get("tdg", 0)) # Should print 12779 # Run Clifford+T optimization optimized = OptimizeCliffordT()(transpiled) print(optimized.count_ops().get("t", 0) + optimized.count_ops().get("tdg", 0)) # Should print 9011 -
È stato aggiunto il
ContextAwareDynamicalDecouplingche implementa un disaccoppiamento dinamico consapevole del contesto basato su sequenze Walsh-Hadamard. Le sequenze di ritardo inserite saranno reciprocamente ortogonali alle sequenze sui qubit vicini e terranno conto degli spettatori di controllo/target delle porte CX ed ECR. Vedere arXiv:2403.06852 per ulteriori informazioni.Esempio:
from qiskit.circuit.library import QFT from qiskit.transpiler import PassManager, CouplingMap from qiskit.transpiler.passes import ALAPScheduleAnalysis, ContextAwareDynamicalDecoupling from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager from qiskit.providers.fake_provider import GenericBackendV2 num_qubits = 10 circuit = QFT(num_qubits) circuit.measure_all() target = GenericBackendV2( 100, basis_gates=["id", "rz", "sx", "x", "ecr"], coupling_map=CouplingMap.from_grid(10, 10) ).target pm = generate_preset_pass_manager(optimization_level=2, target=target) dd = PassManager([ ALAPScheduleAnalysis(target=target), ContextAwareDynamicalDecoupling(target=target), ]) transpiled = pm.run(circuit) with_dd = dd.run(transpiled) with_dd.draw("mpl", idle_wires=False)
-
Aggiunti i seguenti attributi alla classe
DAGCircuitper consentire l'interrogazione del numero di variabili di stiramento:num_stretches,num_captured_stretchesenum_declared_stretches. -
Aggiunto un nuovo plugin per la sintesi unitaria
CliffordUnitarySynthesische tenta di sintetizzare una data porta unitaria verificando se può essere rappresentata da una Clifford, nel qual caso restituisce un circuito che implementa questa unità e che consiste solo di porte Clifford.Il plugin viene invocato dal passaggio
UnitarySynthesisquando il parametromethodè impostato su"clifford".Inoltre, il parametro
plugin_configdiUnitarySynthesispuò essere usato per passare i seguenti parametri specifici del plugin:- min_qubit: il numero minimo di qubit da considerare (il valore predefinito è 1).
- max_qubit: il numero massimo di qubit da considerare (il valore predefinito è 3).
Ad esempio:
import math from qiskit.circuit import QuantumCircuit from qiskit.circuit.library import UnitaryGate from qiskit.quantum_info import Operator from qiskit.transpiler.passes import UnitarySynthesis # clifford unitary over 2 qubits c2 = QuantumCircuit(2) c2.h(0) c2.rz(math.pi / 4, 1) c2.rz(math.pi / 4, 1) c2.sdg(1) uc2 = UnitaryGate(Operator(c2).data) # non-clifford unitary over 2 qubits n2 = QuantumCircuit(2) n2.h(0) n2.rz(math.pi / 4, 1) n2.sdg(1) un2 = UnitaryGate(Operator(n2).data) # quantum circuit with two unitary gates qc = QuantumCircuit(3) qc.append(uc2, [2, 1]) qc.append(un2, [0, 2]) transpiled = UnitarySynthesis(method="clifford")(qc) transpiled.draw("mpl")
L'esecuzione del codice sopra riportato risintetizza la prima porta unitaria in porte Clifford, mentre la seconda porta rimane invariata.
Se modifichiamo l'esempio precedente come segue:
config = {"min_qubits": 3} transpiled = UnitarySynthesis(method="clifford", plugin_config=config)(qc)allora entrambe le porte unitarie rimangono invariate.
Funzionalità di visualizzazione
-
Introdotti stili personalizzati per la funzione
dag_drawer()funzione. Ciò consente di passare un dizionario al parametrostylecon attributi personalizzati che modificano lo stile del DAG restituito dalla funzione. Ad esempio:from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit.converters import circuit_to_dag from qiskit.visualization import dag_drawer q = QuantumRegister(3, 'q') c = ClassicalRegister(3, 'c') circ = QuantumCircuit(q, c) circ.h(q[0]) circ.cx(q[0], q[1]) circ.measure(q[0], c[0]) circ.rz(0.5, q[1]).c_if(c, 2) dag = circuit_to_dag(circ) style = { "inputnodecolor": "pink", "outputnodecolor": "lightblue", "opnodecolor": "red", } dag_drawer(dag, style=style)
Note sull'aggiornamento
-
La libreria
python-dateutilnon è più una dipendenza di Qiskit. Da quando Qiskit v2.0 nulla della libreria utilizzavapython-dateutile Qiskit non dipendeva più dalla libreria. Questa versione lo rimuove dall'elenco delle dipendenze, in modo che non venga installato automaticamente come prerequisito per utilizzare Qiskit. Se ci si affidava a Qiskit per l'installazione di dateutil come dipendenza, ora è necessario assicurarsi di installarlo manualmente (è la prassi migliore per le dipendenze dirette). -
sympynon è più un requisito per l'installazione di Qiskit. Dopo la migrazione a un motore simbolico basato su Rust per la classeParameterExpressionl'uso di SymPy è stato isolato ad alcune utilità di visualizzazione, alTemplateOptimizationtranspiler pass,ParameterExpression.sympify()(che è esplicitamente per l'interoperabilità di SymPy ) eSparsePauliOp.simplify()se si usano coefficienti parametrizzati. Questa funzionalità non è la più comunemente usata, quindi SymPy è ora trattato come una dipendenza opzionale e queste funzioni solleveranno un'eccezione se vengono usate e non è installatoMissingOptionalLibraryErrorse vengono utilizzate e SymPy non è installato. -
La dipendenza da
symengine, utilizzata per la costruzione di oggettiParameterExpressionè stata rimossa. È stato sostituito da un motore simbolico interno e non è più necessario per le funzionalità principali di Qiskit. L'unica eccezione è che symengine è stato incorporato nei formati QPY 10, 11 e 12, quindi è ancora necessario se si deserializzano questi formati. La dipendenza da symengine perqpy.load()è stata resa esplicitamente facoltativa in 2.0.0, ma se in precedenza si faceva affidamento sul fatto che symengine fosse installato di default per questa funzionalità, ora sarà necessario installarlo manualmente per caricare il payload. Se si usasseParameterExpression.sympify()per ottenere un oggetto espressione symengine da un oggettoParameterExpressionora restituirà un'espressionesympy. Se si ha bisogno di usarlo con symengine, si può sfruttaresymengine.sympifyper convertire l'espressionesympyin una espressione symengine.
Note sull'aggiornamento dei circuiti
-
L'attributo
definitiondell'attributoHalfAdderGateè stato modificato per utilizzare internamenteadder_ripple_r25()per generare la definizione del gate per un circuito più efficiente senza qubit ausiliari. Se per qualche motivo si desidera la vecchia definizione, è possibile utilizzare direttamente la funzioneadder_qft_d00()che genererà un circuito equivalente a quello chedefinitionnelle versioni precedenti. -
Il circuito restituito dalla funzione
excitation_preserving()e dalla classeExcitationPreservingsono ora costruiti utilizzando un singoloXXPlusYYGate. Questo è un cambiamento rispetto alle versioni precedenti che utilizzavano un carattereRXXGateseguito da unRYYGate. Questa nuova costruzione di circuito è equivalente, ma utilizza un numero inferiore di porte che sono tutte a conservazione dell'eccitazione, per definizione più semplici. -
Gli
definitiondi alcune porte standard sono stati aggiornati secondo i seguenti principi:- Quando è disponibile, una definizione che utilizza le porte di Clifford è preferita a quelle che includono porte non di Clifford.
- Quando è disponibile, una definizione che utilizza le porte Clifford+T è preferibile a una che utilizza una porta Clifford
UGate. - L'uso di
PhaseGateè preferibile aU1Gate. - L'uso di
UGateè preferibile a`U2Gatee`U3Gate.
In particolare, il seguente invariante è ancora valido: espandendo ricorsivamente le definizioni delle porte, qualsiasi porta può essere espressa in ultima analisi utilizzando solo la base
["cx", "u"]. Le definizioni di tutte le porte standard sono tutte equivalenti, quindi non cambia la semantica delle porte, ma solo l'esatta costruzione del circuito restituita per alcune porte non è più esattamente la stessa. Questa modifica era necessaria per supportare la trasposizione Clifford+T. -
Qiskit ora utilizza la propria libreria di espressioni simboliche basata su Rust per implementare gli interni di
ParameterExpressioneParameter. Poiché si tratta di una nuova implementazione del motore matematico simbolico di base utilizzato perParameterExpressionpotrebbero esserci piccole differenze nel comportamento esatto di alcune funzionalità. Dovrebbe sempre produrre risultati equivalenti per l'API documentata. Se si riscontrano problemi di correttezza, aprire un problema.
Note sull'aggiornamento dell'API C
-
Il modo in cui i numeri complessi sono esposti nell'API C di Qiskit è cambiato. In precedenza,
QkComplex64era un typedef dipendente dal compilatore che consentiva di passare tipi complessi nativi tramite puntatore all'API di Qiskit (ad esempio comedouble complex*). Pur essendo conveniente, questo approccio si basa implicitamente su ipotesi di layout di memoria che non sono strettamente garantite.Qiskit v2.1 espone ora
QkComplex64 { double re; double im; }come struct, per garantire che la disposizione della memoria sia sempre compatibile e per un più ampio supporto del compilatore. Per comodità, vengono forniti i convertitori dipendenti dal compilatoreqk_complex64_from_nativeeqk_complex64_to_native, che consentono di tradurre dalla struct a un numero complesso nativo. Si noti che questi funzionano solo su piattaforme che supportanodouble complexo per compilatori MSVC che utilizzano_Dcomplex.Ad esempio:
#include <qiskit.h> #include <math.h> #include <stdio.h> #include <complex.h> int main(int argc, char *argv[]) { // platform-independent constructions: QkComplex64 coeff = {5.0, 3.0}; // ... or using converter // double complex native = 5.0 + I * 3; // uses C11 standard, does not work on MSVC // QkComplex64 coeff = qk_complex64_from_native(&native); // convert from native uint32_t num_qubits = 100; QkObs *obs = qk_obs_zero(num_qubits); QkBitTerm bit_terms[3] = {QkBitTerm_X, QkBitTerm_Y, QkBitTerm_Z}; uint32_t indices[3] = {0, 1, 2}; QkObsTerm term = {coeff, 3, bit_terms, indices, num_qubits}; qk_obs_add_term(obs, &term); printf("num_qubits: %u\n", qk_obs_num_qubits(obs)); printf("num_terms: %lu\n", qk_obs_num_terms(obs)); qk_obs_free(obs); return 0; }
Note sull'aggiornamento QPY
- La versione predefinita di QPY emessa da
qpy.dump()è stata cambiata con l'ultima versione 15 di QPY. Se per qualche motivo è necessario generare una versione più vecchia del formato, si può usare l'argomento della parola chiaveversionsuqpy.dump()per specificare una versione precedente da generare.
Note sull'aggiornamento della sintesi
-
Il formato di serializzazione per le approssimazioni di base negli algoritmi di Solovay-Kitaev è stato cambiato da
.npya un altro formato binario, basato suserdeebincodedi Rust. Tutte le routine che caricano approssimazioni di base (come ad esempiogenerate_basic_approximations(),SolovayKitaevDecomposition.load_basic_approximations()o l'inizializzatore diSolovayKitaev) supportano ancora il caricamento del formato legacy. Ogni nuovo file, tuttavia, verrà memorizzato nel nuovo formato. Se ci si è affidati al vecchio formato, si deve eseguire il downgrade di Qiskit a 2.2 e memorizzare i file necessari. -
I valori predefiniti per
SolovayKitaev(e le classi correlate) sono aumentati adepth=12ereps=5. Questo è dovuto al fatto che l'implementazione sottostante è ora in Rust, che ci permette di aumentare la precisione predefinita, pur rimanendo significativamente più veloce della precedente versione Python.
Note sull'aggiornamento del transpiler
-
I plugin di layout integrati per gli attuali gestori di passaggi non conterranno più il loro componente principale (ad esempio un'istanza per lo stadio "sciabola") se non vengono forniti vincoli di accoppiamento
SabreLayoutper il palco "sciabola" ) se non vengono forniti vincoli di accoppiamento. In precedenza, i plugin costruivano istanze non valide dei loro passaggi di layout, assumendo che la logica separata impedisse ai passaggi di essere eseguiti e di sollevare eccezioni.Questo non dovrebbe avere alcun effetto significativo sull'uso dei gestori di pass preimpostati o dei plugin, poiché non è mai stato valido chiamare i pass in uno stato non valido.
Note di deprecazione
-
Il supporto per l'esecuzione di Qiskit con Python 3.9 è stato deprecato e sarà rimosso nella versione di Qiskit v2.3. La versione 2.3.0 è il primo rilascio dopo che Python 3.9 ha terminato il suo ciclo di vita e non è più supportato [.] Ciò significa che a partire dalla versione 2.3.0 sarà necessario aggiornare la versione Python in uso a Python 3.9 o superiore.
Circuiti deprecati
-
La libreria dei circuiti ha subito un refactoring nella release di Qiskit v1.3, in cui sono state fornite alternative per gli oggetti di tipo
QuantumCircuitsono state fornite alternative che sono sia una funzioneInstructiono una funzione Python per la costruzione. Questo refactoring consente al compilatore di ragionare sulle istruzioni di alto livello e riduce l'overhead per i circuiti che non richiedono ottimizzazioni di alto livello.Tutte le
QuantumCircuitsono ora deprecate in favore delle loro alternative introdotte in Qiskit v1.3. Come parte di questo, anche la classe baseBlueprintCircuitè deprecata. Tutti hanno un periodo di deprezzamento esteso e saranno rimossi solo in Qiskit v3.0.La classe
BlueprintCircuitnon ha un sostituto diretto, ma utilizza una funzioneQuantumCircuitdirettamente o una funzione che genera circuiti. Per maggiori dettagli, vedereqiskit.circuit.libraryper maggiori dettagli, ma di seguito sono riportati alcuni circuiti comuni e le loro sostituzioni:QFT→QFTGateTwoLocal→n_local()(non si tratta di un errore di battitura, questa funzione copre le areeNLocaleTwoLocal)EfficientSU2→efficient_su2()RealAmplitudes→real_amplitudes()ZZFeatureMap→zz_feature_map()QuantumVolume→quantum_volume()EvolvedOperatorAnsatz→evolved_operator_ansatz()MCXGrayCode→synth_mcx_gray_code()MCXRecursive→synth_mcx_n_dirty_i15()MCXVChain→synth_mcx_n_clean_m15()
Correzioni di bug
-
Corretto un bug nella funzione
dag_drawer()e nel metodoDAGCircuit.draw()in cui l'impostazione dell'argomento della parola chiavestyle=plainnon mostrava le etichette dei circuiti per i nodi del DAG nella visualizzazione. -
Corretto un bug nel metodo
QuantumCircuit.assign_parameters()in cui i parametri non utilizzati nel circuito e passati come stringhe non venivano ignorati quando l'argomentostrict=Falseveniva impostato. Fare riferimento al problema #13933 per maggiori dettagli. -
Corretto un caso limite nella configurazione di
Makefileper Windows, in cui la variabile d'ambiente predefinitaOSnon corrispondeva all'output del comandouname -s. -
È stato corretto l'attributo
namedell'attributoOrGateche in precedenza era impostato erroneamente sulla stringa"and"invece che sul valore atteso"or", che ora viene restituito. Questo valore errato"and"entrava in conflitto con il valoreAndGate.namee avrebbe potuto portare a diversi problemi nell'utilizzo diOrgatee nella sua differenziazione da un file di tipoAndGate. -
Corretto un bug nella funzione
qpy.load()che poteva non riuscire a deserializzare circuiti i cui parametri erano stati riassegnati a parametri con gli stessi nomi. Corretti i punti #13720, #13720 e #13720. -
Il campo
GenericBackendV2per includere oraBoxOpcome tipo di istruzione supportata nella classe generataGenericBackendV2.targetquando l'argomento chiavecontrol_flow=Trueè impostato nel costruttore. -
Quando si sintetizza un
MCXGategate con 3 controlli, la funzione di sintesisynth_mcx_n_dirty_i15()richiedeva un qubit ausiliario, producendo un circuito con 5 qubit (3 di controllo, 1 di destinazione e 1 ausiliario). Tuttavia, l'algoritmo di sintesi attuale non fa uso di questo qubit ausiliario. Questo comportamento è stato corretto: il circuito sintetizzato è di oltre 4 qubit (3 di controllo e 1 di destinazione), consentendo di applicare la funzione di sintesi in un numero leggermente maggiore di casi. -
Il
QuantumCircuit.draw()ecircuit_drawer()renderà ora le istruzioniBoxOpin un'istruzioneQuantumCircuitnella stessa fetta verticale, se gli intervalli verticali non si sovrappongono, vengono ora rese nella stessa fetta verticale, quando possibile. -
Fissato il metodo
QuantumCircuit.draw()e la funzionecircuit_drawer()in modalità"mpl"per inserire meno spazio estraneo all'interno del bordo sinistro quando si disegnanoBoxOpistanze in un fileQuantumCircuit.
Altre note
-
Aggiunto un nuovo target opzionale di dipendenza extra
qpy-compat. Questo target dovrebbe essere utilizzato se si intende caricare fileqpyutilizzando i vecchi formati QPY. Il target installa i requisiti aggiuntivi utilizzati per caricare i file QPY utilizzando le versioni di formato < 13. If you are only using newer QPY format versions you do no need to install this. Theqpy.dump()only generates QPY > =13 Questo è necessario solo per caricare i file generati con le versioni di Qiskit più vecchie (precedenti a 2.0.0 ) È possibile installare questa nuova variante opzionale conpip install qiskit[qpy-compat]. -
I pesi relativi delle componenti "base" e "lookahead" dei
SabreSwapeSabreLayoutsono stati modificati quando l'inseguimento a insiemi estesi è attivo (come lo è sempre inSabreLayouted è predefinito inSabreSwap). La componente euristica relativa alla distanza tra i qubit in un singolo gate nello strato anteriore ora non si indebolisce più in modo proporzionale al numero di gate nello strato anteriore; questo comportamento era una scelta storica, ma a circuiti di grandi dimensioni ha l'effetto accidentale di far sì che lo strato anteriore venga quasi ignorato, il che è disastroso per l'efficienza.I miglioramenti di routing che ne derivano dovrebbero essere più evidenti per i circuiti che possono essere spesso stratificati in strati di più di 20 porte parallele a due qubit.