Qiskit SDK 2.2 note di rilascio
2.2.3
Preludio
Qiskit 2.2.3 corregge un bug introdotto da Qiskit 2.2.2 quando si utilizza il run() metodo su un PassManager per più di un circuito.
Note sull'aggiornamento
ConsolidateBlocksora legge unaPropertySetchiaveConsolidateBlocks_qubit_mapall'ingresso. Questa chiave e il suo valore non sono pubblici e non devono essere letti o scritti da altri pass.
Correzioni di bug
- Riutilizzo fisso della stessa
ConsolidateBlocksistanza su più circuiti, comprese le chiamate atranspile()con più di un circuito e nessuna parallelizzazione basata sui processi. Un bug introdotto in Qiskit 2.2.2 causava il panico del passaggio o la produzione di output non validi se la stessa istanza veniva riutilizzata su circuiti diversi.
2.2.2
Preludio
Qiskit 2.2.2 è una release di correzione di bug per la serie di versioni minori v2.2.
Correzioni di bug
-
Corretta l'implementazione di
__deepcopy__()inQuantumCircuitche non eseguiva la copia profonda dei parametri del circuito. Di conseguenza, la mutazione di unBoxOpin un circuito copiato non influisce più sul circuito originale. -
Risolto un problema nel
Optimize1qGatesDecompositionpassaggio quando il passaggio viene inizializzato con unTargetcontenente gate a 1 qubit con parametri angolari fissi. In precedenza, il passaggio avrebbe potenzialmente generato porte non incluse nel target, poiché non verificava se le porte nel target supportassero valori di parametri arbitrari. Corretto #14743. -
Corretto il comportamento errato nel
BasisTranslatorpassaggio in cui un gate multi-qubit all'interno di unControlFlowOpblocco veniva tracciato utilizzando i suoi indici qubit locali invece di utilizzare gli indici assoluti dal circuito sorgente. -
Il passaggio del
ConsolidateBlockstranspiler ora valuterà correttamente se un determinato gate è supportato dall'hardware durante la ricorsione nelle operazioni di flusso di controllo. -
qpy.dump()ora è in grado di gestire la scrittura su.gzfile aperti utilizzando il modulo dellagziplibreria standard con versioni QPY 16 o superiori. Per ulteriori dettagli, consultare il numero 15157. -
Corretto il metodo
MCPhaseGate.inverse()per preservare gli stati di controllo dei cancelli controllati in apertura durante il calcolo dei loro inversi. -
ConsolidateBlocksora restituirà un'eccezione Python -space invece di andare in panico quando rileva un'analisi non valida o non aggiornata nelle chiavi legacyrun_list``block_listPropertySeto. Corretto #14646. -
Optimize1qGatesDecompositionora genererà unTranspilerErroranziché un panic Rust-space quando si tenta di eseguire su un circuito troppo grande per ilTarget. Risolto #15116. -
I passaggi di pianificazione,
ALAPScheduleAnalysiseASAPScheduleAnalysis, ora gestiranno correttamente i circuiti che non contengono operazioni. In precedenza avevano sollevato unaTranspilerErroraffermando falsamente che "Non sono state fornite durate". Corretto #15145. -
Risolto un errore nel disegno del testo del circuito, che poteva verificarsi quando i blocchi del circuito all'interno delle operazioni di flusso di controllo erano definiti su registri diversi rispetto al circuito esterno. Questa situazione potrebbe verificarsi, ad esempio, quando si aggiungono
ControlFlowOpoperazioni direttamente o per i circuiti dopo la transpilazione.
2.2.1
Preludio
Qiskit 2.2.1 è una piccola release di patch che risolve diversi bug identificati nella release 2.2.0.
Note sull'aggiornamento del transpiler
- I limiti massimi di chiamata e prova per l'esecuzione con corrispondenza esatta di
VF2PostLayoutinoptimization_level=3sono stati ridotti per evitare tempi di esecuzione eccessivi per circuiti di prova altamente simmetrici mappati su mappe di accoppiamento di grandi dimensioni.
Correzioni di bug
-
DAGCircuit.apply_operation_back(),apply_operation_back()e oracircuit_to_dag()aggiungerà nuovi bordi in un ordine deterministico. Il comportamento precedente poteva causare il passaggio di determinati transpilatori (comeSabreSwap) attraverso il DAG in ordini non deterministici. -
DAGCircuit.apply_operation_front()non è più possibile inserire loop auto-validi durante la gestione di nodi che includono condizioni classiche. -
Risolto un problema con
pickleil supporto per ilSabreSwapin cuiSabreSwapun'istanza dava errore quando veniva sottoposta a pickling dopo l'esecuzioneSabreSwap.run()del metodo. Corretto #15071. -
Risolto un problema per cui
is_unitary()non rispettava correttamente i valori di tolleranza di input durante la verifica dell'unitarità di un operatore. Il metodo ora utilizza correttamente i parametrirtoleatolforniti quando semplifica l'operatore e verifica se è uguale all'identità. Questo risolve il problema #14107.
2.2.0
Preludio
Qiskit v2.2 aggiunge diversi miglioramenti per l'API C e il transpiler, oltre a molti altri miglioramenti e correzioni di bug. Le principali caratteristiche di questa nuova versione sono:
- Funzione di transpilazione API C: l'API C ora include una funzione per la transpilazione di un circuito quantistico:
qk_transpile(). Questa funzione è equivalente alla funzionetranspile()Python per un contesto C autonomo.- Passaggio di trasformazione Litinski: un nuovo passaggio di trasformazione
LitinskiTransformationche implementa la trasformazione descritta arXiv:1808.02892. Questo passaggio viene solitamente utilizzato nella compilazione per architetture tolleranti ai guasti.- Supporto dei limiti angolari per gli obiettivi: la
Targetclasse ora supporta la specificazione dei limiti per i valori consentiti per le operazioni parametrizzate aggiunte all'obiettivo. Quando si aggiunge un'istruzione alTargetè possibile aggiungere l'argomento opzionale angle_bounds per specificare i limiti superiore e inferiore per i gate di rotazione parametrizzati. È stato aggiuntoWrapAnglesun nuovo passaggio di transpilazione per applicare i vincoli angolari come parte di una pipeline di transpilazione.
La serie di release v2.2 è l'ultima serie di release minore con supporto Python 3.9. La versione di Rust minimamente supportata per compilare Qiskit dai sorgenti è ora Rust v1.85, aumentata da 1.79 in 2.1.0. Per ulteriori informazioni su queste e altre modifiche apportate, consultate le note di rilascio qui sotto e la documentazione aggiornata.
Funzionalità API C
-
Aggiunte nuove funzioni di passaggio del transpiler standalone all'API C. Queste funzioni ricevono un
QkCircuitsu cui eseguire il passaggio e sono equivalenti alla chiamata di un passaggio istanziato. -
Il
QkTargettipo ora può rappresentare target che supportano tipiQkGateparametrizzati che accettano qualsiasi valore di parametro. In precedenza, questi gate potevano essere aggiunti al target solo con un valore angolare fisso supportato utilizzandoqk_target_entry_new_fixed()per creare ilQkTargetEntry. Ora, laqk_target_entry_new()funzione può essere utilizzata con porte parametrizzate. Quando viene utilizzata con porte parametrizzate, questa funzione indica che la porta nella destinazione supporta qualsiasi valore per tutti i parametri della porta. Ad esempio:#include <qiskit.h> QkTarget *target = qk_target_new(5); QkTargetEntry *rz_entry = qk_target_entry_new(QkGate_RZ); for (uint32_t i = 0; i < 5; i++) { uint32_t qargs[1] = {i}; qk_target_entry_add_property(rz_entry, qargs, 1, 1.2e-6, 1.3e-9); } qk_target_add_instruction(target, rz_entry); // Clean up after using target qk_target_free(target);Questo crea un target a 5 qubit che accetterà un gate RZ su qualsiasi qubit con qualsiasi valore di parametro supportato da quel gate.
-
Aggiunto
qk_obs_apply_layout()per applicare nuovi layout di qubit a unQkObsosservabile. Questa funzione accetta l'osservabile, i nuovi indici dei qubit e un numero di qubit in uscita. È importante sottolineare che questa funzione consente di applicare layout di transpilazione, solitamente forniti comeQkTranspileLayoutda un passaggio di transpilazione, a un osservabile. Ad esempio:// get the number of output qubits -- transpile_layout is a QkTranspileLayout* uint32_t num_output_qubits = qk_transpile_layout_num_output_qubits(transpile_layout); // get the layout including the ancillas (hence the ``false`` in the function call) uint32_t *layout = malloc(sizeof(uint32_t) * num_output_qubits); qk_transpile_layout_final_layout(transpile_layout, false, layout); // apply the layout -- obs is a QkObs* int exit = qk_obs_apply_layout(obs, layout, num_output_qubits); // free the layout array free(layout); -
Aggiunta una nuova funzione
qk_transpile()all'API C di Qiskit. Questa funzione viene utilizzata per transpilare circuiti quantistici in un contesto C autonomo senza utilizzare Python. Questo è l'ultimo componente principale necessario nell'API C per i flussi di lavoro tipici di esecuzione hardware che utilizzano Qiskit.Questa funzione rispecchia i gestori di passaggi preimpostati utilizzati per il transpiler Python, tranne per alcuni passaggi e funzionalità che vengono saltati se non sono rilevanti per i circuiti costruiti con l'API C. Questo rende la funzione adatta solo a contesti C standalone.
-
Aggiunto un nuovo tipo
QkTranspileLayoutall'API C. Questo tipo viene utilizzato per ragionare sulle permutazioni causate dal transpiler.
Caratteristiche dei circuiti
-
Viene fornito un nuovo metodo,
QuantumCircuit.ensure_physical(), per garantire che un circuito sia definito su qubit fisici, con gli indici dei qubit che fanno riferimento ai qubit fisici. Per ulteriori dettagli sui concetti relativi ai metadati, consultare la nuova discussione sulle rappresentazioni astratte e fisiche dei circuiti nella documentazione. I concetti di circuiti "astratti" e "fisici" non sono affatto nuovi per Qiskit, ma solo la documentazione esplicita. -
La classe
Durationha ottenuto una nuova varianteps, che può essere utilizzata per rappresentare una durata in picosecondi. -
Migliorato
PauliEvolutionGate.control(),PauliEvolutionGate.power()ePauliEvolutionGate.inverse()per restituire rappresentazioni più efficienti in termini di aPauliEvolutionGate. Per il calcolo delle versioni controllate ed esponenziali del gate di evoluzione, questa modifica porta a circuiti significativamente più superficiali e a un numero inferiore di gate rispetto ai meccanismi generici utilizzati in precedenza. La decomposizione inversa non cambia, ma ora viene generata in modo più efficiente e consente ottimizzazioni migliori del compilatore. -
È stato aggiunto
ParameterExpression.bind_all()un nuovo metodo fast-path per supportare il caso d'uso del binding di molteParameterExpressionistanze diverse a valori numerici utilizzando lo stesso dizionario di mappature. Il metodobind()esistente presenta un notevole overhead e allocazioni non necessarie, poiché restituisce sempre unParameterExpressionper garantire la coerenza di digitazione.
OpenQASM Caratteristiche
-
Aggiunto supporto parziale per
defcali simboli nell'esportatore OpenQASM3. Ciò consente ai pacchetti a valle di esportare istruzioni personalizzate che operano sia su bit quantistici che classici utilizzandoqiskit.qasm3.dumps(). Gli utenti possono ora definire istruzioni personalizzate (ad esempio, unCustomMeasureche agisce su un qubit e restituisce un bit classico) e specificarne il comportamento utilizzandoDefcalInstruction. Questi defcal vengono passati all'esportatore tramiteimplicit_defcalsl'argomento inqiskit.qasm3.dumps().Ad esempio:
from qiskit.circuit import Instruction, QuantumCircuit from qiskit.qasm3 import dumps from qiskit.qasm3.exporter import DefcalInstruction, types custom_measure = Instruction("measure_2", 1, 1, []) qc = QuantumCircuit(1, 1) qc.h(0) qc.append(custom_measure, [0], [0]) qc.measure(0, 0) defcals = { "measure_2": DefcalInstruction("measure_2", 0, 1, types.Bool()), } out_qasm = dumps(qc, implicit_defcals=defcals) print(out_qasm)Verrebbe visualizzata la seguente stringa valida OpenQASM3 :
OPENQASM 3.0; bit[1] c; qubit[1] q; h q[0]; c[0] = measure_2 q[0]; c[0] = measure q[0];Questo approccio presuppone che la definizione della grammatica per il defcal sia fornita esternamente (ad esempio, in un file di intestazione), anche se tale file non è strettamente necessario per il funzionamento dell'esportatore.
-
Le funzioni
qasm3.loads()eqasm3.load()ora hanno un argomento aggiuntivo chiamatonum_qubits. Se fornite, le funzioni restituiranno circuiti che avranno qubit pari anum_qubits. Se non fornito, il circuito restituito avrà qubit pari all'indice massimo osservato nel circuito serializzato. Per ulteriori dettagli, consultare il numero 14435.
Caratteristiche QPY
-
Aggiunta un'impostazione denominata
min_qpy_versionnel file di configurazione utente. Quando impostato, definisce la versione minima consentita di QPY perqpy.load(). Se la versione del formato di un file QPY è inferiore all'impostazioneminimum_qpy_versionrispettominimum_qpy_versionall'impostazione verrà generata un'eccezione. -
Introdotto il formato QPY versione 16. Questa nuova versione introduce una nuova tabella di inizio circuito nell'intestazione del file, che contiene gli offset di byte dell'inizio di ogni circuito in un file QPY. Ciò consente un caricamento potenzialmente più efficiente dei circuiti dai file QPY e un'implementazione di Rust potenzialmente multi-thread in futuro. Inoltre, la nuova versione del formato aggiunge il supporto per la nuova variante
DURATIONdei picosecondi.
Caratteristiche dell'informazione quantistica
-
Aggiunti i metodi
PauliLindbladMap.drop_qubits()PauliLindbladMap.keep_qubits()e per tracciare i sottosistemi fuori dalle mappe di Pauli Lindblad. -
Aggiunti i metodi
QubitSparsePauli.to_pauli()eQubitSparsePauliList.to_pauli_list(), che convertono gli oggetti sparsi nelle corrispondenti versioni dense,PauliePauliList, rispettivamente. -
Aggiunte le classi
PhasedQubitSparsePauliPhasedQubitSparsePauliListe. Queste classi rappresentano rispettivamente un singolo operatore di Pauli e un elenco di operatori di Pauli memorizzati in formato qubit-sparse. Queste classi sono molto simili aQubitSparsePaulieQubitSparsePauliList, tranne per il fatto che contengono anche informazioni di fase. -
Aggiunto il metodo
QubitSparsePauliList.to_dense_array(). Restituisce l'elenco come un array di numeri interi con i valori diPauli.
Caratteristiche della sintesi
-
Aggiunto nuovo algoritmo di sintesi per
ModularAdderGateche non richiede qubit ausiliari e ha un conteggio CX migliore rispetto aadder_qft_d00(): -
Aggiunto un nuovo algoritmo di sintesi,
synth_mcx_noaux_hp24(), perMCXGateche non richiede alcun qubit ausiliario. Questo metodo produce un numero lineare, anziché quadratico, di porte CX rispettosynth_mcx_noaux_v24()all'algoritmo esistente. In particolare, il nuovo metodo è migliore quando il numero di qubit di controllo è superiore a cinque. L'algoritmo si basa sull'articolo "Compiling Conditional Quantum Gates without Using Helper Qubits" (Compilazione di porte quantistiche condizionali senza l'uso di qubit ausiliari) di Huang e Palsberg ( https://dl.acm.org/doi/10.1145/3656436 ). -
Migliorata la
qs_decomposition()funzione originariamente basata su Shende et. al. (https://arxiv.org/abs/quant-ph/0406176). Il nuovo metodo di sintesi si basa su Krol e Al-Ars ( https://arxiv.org/abs/2403.13692 ) e riduce il numero totale diCXGates di un unitariano n-qubit generale di unCXGate. Grazie alla decomposizione migliorata, un'unità generale a 3 qubit può essere decomposta utilizzando 19CXGates (anziché 20). -
Aggiunto
synth_mcmt_xgate()per sintetizzare il gate multi-controllo multi-target quando il gate di base èXGate. Ha una decomposizione in un numero lineare di porte CX e 0 qubit ancilla insieme al plugin di sintesi diMCMTSynthesisXGatealto livello.
Funzionalità del transpiler
-
Aggiunto nuovo plugin di sintesi di alto livello per sintetizzare un
ModularAdderGate:ModularAdderSynthesisV17, basato suadder_modular_v17().
Il
ModularAdderSynthesisDefaultè stato aggiornato per seguire la seguente sequenza di sintetizzatori addizionatori modulari:"ModularAdder.qft_d00"quando il numero di qubit è ,"ModularAdder.modular_v17"in tutti gli altri casi. -
Aggiunto un nuovo passaggio del
LitinskiTransformationtranspiler che implementa la trasformazione descritta in arXiv:1808.02892.L'input del passaggio è un circuito con porte Clifford e porte di rotazione RZ a singolo qubit, mentre l'output è un circuito con rotazioni Pauli multi-qubit (implementate come
PauliEvolutionGateporte ) seguite da porte Clifford. Il passaggio generaTranspilerErrorun'eccezione se il circuito contiene porte non supportate.Il pass supporta tutti i gate Clifford presenti nell'elenco restituito da
get_clifford_gate_names(), ovvero["id", "x", "y", "z", "h", "s", "sdg", "sx", "sxdg", "cx", "cz", "cy", "swap", "iswap", "ecr", "dcx"]. L'elenco delle rotazioni RZ supportate è["t", "tdg", "rz"](convertiamo automaticamente i gate T e Tdg in rotazioni RZ).Inoltre, il
LitinskiTransformationcostruttore accetta un argomentofix_clifford. QuandoFalse(non predefinito), il circuito restituito contiene soloPauliEvolutionGategate, con i gate Clifford finali omessi. Si noti che in questo caso gli operatori dei circuiti originali e sintetizzati non saranno generalmente equivalenti.Ad esempio:
from qiskit.circuit import QuantumCircuit from qiskit.transpiler.passes import LitinskiTransformation from qiskit.quantum_info import Operator # The following quantum circuit consists of 5 Clifford gates # and two single-qubits RZ-rotation gates (note that Tdg is # an RZ-rotation). qc = QuantumCircuit(2) qc.cx(0, 1) qc.rz(0.1, 0) qc.cz(0, 1) qc.tdg(1) qc.h(1) qc.s(1) qc.cz(1, 0) # The transformed circuit consists of two PauliEvolution gates # and the same Clifford gates as in the original circuit. qct = LitinskiTransformation()(qc) # The circuits before and after the transformation are equivalent assert Operator(qc) == Operator(qct) -
Aggiunto un nuovo plugin di sintesi di
MCXSynthesisNoAuxHP24alto livello perMCXGategli oggetti. Inoltre, il plugin di sintesiMCXSynthesisDefaultpredefinito perMCXGategli oggetti è stato aggiornato in modo da scegliere sempre il metodo di sintesi migliore in base al numero disponibile di qubit ausiliari. -
Aggiunto supporto per specificare
Targeti limiti angolari nelle istruzioni. Prima di questa versione,Targetera possibile specificare che un'operazione che accettava un parametro consentisse qualsiasi valore valido o un valore specifico. Ad esempio, seRZGate(Parameter("theta"))venisse aggiunto all'obiettivo, ciò indicherebbe che è consentito unRZGatecon qualsiasi valore per theta. Se inveceRZGate(math.pi)venisse aggiunto al target, ciò indicherebbeRZGateche solo è l'unico valore consentito sul target. Questa nuova funzione consente di limitare gli angoli consentiti a qualsiasifloatvalore compreso tra un limite inclusivo. Ad esempio, è possibile aggiungereRZGate(math.pi)aTargete limitare il valore dell'angolo tra i valori 0 e .Esistono diversi metodi disponibili per lavorare con i limiti angolari sul bersaglio. Il primo è
Target.add_instruction()che ha un nuovo argomentoangle_boundschiave utilizzato per aggiungere un limite angolare a un'istruzione nelTarget. Per lavorare con i limiti angolari, dovrai anche registrare una funzione di callback nel registroWRAP_ANGLE_REGISTRYglobale che indicherà al transpiler eWrapAnglespass come regolare i gate per i limiti angolari. La funzione di callback prenderà un elenco di valorifloatarbitrari che rappresentano gli angoli del gate dal circuito, nonché gli indici dei qubit nel circuito su cui il gate stava operando, e restituirà unDAGCircuitche rappresenta un circuito equivalente per il gate con quell'angolo, ma rispettando i limiti dell'angolo e altriTargetvincoli. Ad esempio:import math from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target from qiskit.transpiler.passes.utils.wrap_angles import WRAP_ANGLE_REGISTRY target = Target(num_qubits=1) target.add_instruction(RZGate(Parameter("theta")), angle_bounds=[(-math.pi, math.pi)]) def callback(angles: List[float], qubits: List[int]) -> DAGCircuit: """Callback function to wrap RZ gate angles Args: angles: The list of floating point parameter values for the instance of RZGate in the circuit qubits: The physical qubit indices that this gate is operating on Returns: The DAGCircuit of the equivalent circuit""" angle = angles[0] dag = DAGCircuit() dag.add_qubits([Qubit()]) if angle > 0: divisor = math.pi else: divisor = -math.pi gate_counts = int(angles[0] // divisor) rem = angles[0] % divisor for _ in range(gate_counts): dag.apply_operation_back(RZGate(math.pi), [dag.qubits[0]], check=True) dag.apply_operation_back(rem, [dag.qubits[0]], check=True) WRAP_ANGLE_REGISTRY.add_wrapper("rz", callback)Target.has_angle_bounds()può essere utilizzato per verificare se nel target sono stati impostati dei limiti angolari eTarget.gate_has_angle_bounds().Se si desidera applicare i limiti angolari da un target a qualsiasi gate in un circuito, è necessario utilizzare il passaggio
WrapAnglestranspiler. -
Aggiunto un nuovo kwarg
check_angle_boundsalTarget.instruction_supported()metodo. Quando è impostato suTrue(impostazione predefinita), il metodo verificherà se il specificato è conformeparametersanche a eventuali limiti angolari che potrebbero esistere per l'istruzione oggetto della query. -
Aggiunto un nuovo passaggio
WrapAnglesdel transpiler utilizzato per applicare vincoli angolari sui gate nelTarget. Se unTargetha definito dei limiti angolari, questo passaggio analizzerà tutti i parametri dei gate nel circuito e li confronterà con i limiti specificati nel target. Ad esempio, se un target contiene un gate personalizzato con limiti angolari, il passaggio scomporrà tale gate in un gate conforme ai limiti:from qiskit.circuit import Gate, Parameter, QuantumCircuit, Qubit from qiskit.dagcircuit import DAGCircuit from qiskit.transpiler import Target, WrapAngleRegistry from qiskit.transpiler.passes import WrapAngles class MyCustomGate(Gate): def __init__(self, angle): super().__init__("my_custom", 1, [angle]) param = Parameter("a") circuit = QuantumCircuit(1) circuit.append(MyCustomGate(6.0), [0]) target = Target(num_qubits=1) target.add_instruction(MyCustomGate(param), angle_bounds=[(0, 0.5)]) def callback(angles, _qubits): angle = angles[0] if angle > 0: number_of_gates = angle / 0.5 else: number_of_gates = (6.28 - angle) / 0.5 dag = DAGCircuit() dag.add_qubits([Qubit()]) for _ in range(int(number_of_gates)): dag.apply_operation_back(MyCustomGate(0.5), [dag.qubits[0]]) return dag registry = WrapAngleRegistry() registry.add_wrapper("my_custom", callback) wrap_pass = WrapAngles(target, registry) res = wrap_pass(circuit) res.draw('mpl')
-
DAGCircuitora dispone di un'implementazione manuale di__deepcopy__(). Si tratta di una velocità di gran lunga superiore rispetto alla precedente implementazione implicita del protocollo pickle, specialmente per circuiti di grandi dimensioni. Ciò influisce positivamente anche sulle prestazioni di compilazione durante l'esecuzionetranspile()o l'esecuzione dei gestori di passaggi predefiniti restituiti dagenerate_preset_pass_manager()aoptimization_level=3come livello di ottimizzazione 3, poiché le copie profonde interne copiano ilDAGCircuitper ogni iterazione del ciclo di ottimizzazione nellaoptimizationfase. -
Viene fornito un nuovo metodo,
DAGCircuit.make_physical(), che sostituisce in modo efficiente i qubit nelDAGCircuitcon il registro canonico dei qubit fisici, includendo potenzialmente l'espansione. È disponibileQuantumCircuit.ensure_physical()anche un metodo simile. -
Un nuovo metodo,
DAGCircuit.structurally_equal(), può essere utilizzato se dueDAGCircuitistanze sono state create e modificate esattamente nello stesso ordine. Si tratta di un test molto più rigoroso rispetto al controllo di equivalenza semantica standard==dell'overload e può essere utilizzato dagli autori di transpiler-pass per verificare che i loro ordini di modifica siano deterministici. -
Le sottoclassi personalizzate di
BasePassManagerpossono ora modificare il loroproperty_setattributo durante il loro_passmanager_frontend()metodo per inizializzare le proprietà iniziali. Ciò garantisce simmetria, poiché in precedenza era possibile leggere solo le proprietà finali durante_passmanager_backend(). -
Aggiunta una nuova classe
OptimizationMetricche specifica il criterio di ottimizzazione nelHighLevelSynthesispassaggio. Attualmente le due metriche supportate sono:COUNT_2Q: ottimizza il numero di porte a due qubit.COUNT_T: ottimizza il numero di porte T, quando si traspone in un insieme di basi Clifford+T.
Il transpiler seleziona automaticamente la metrica di destinazione in base al set di porte di base, ad esempio utilizzerà
COUNT_Tse viene rilevato un set di base Clifford+T. Tuttavia, questa classe non può essere attualmente impostata manualmente durante l'esecuzionetranspile()o l'esecuzione di un gestore di passaggi preimpostato generato dagenerate_preset_pass_manager(). -
Aggiunto un nuovo argomento
optimization_metrical costruttore per ilHighLevelSynthesispassaggio del transpiler che accetta unOptimizationMetricoggetto. Quando è impostato suCOUNT_T, il passaggio sceglie decomposizioni più adatte al set di porte Clifford+T. -
I plugin di sintesi di alto livello predefiniti per
ModularAdderGateeMultiplierGateproducono conteggi T migliori durante la transpilazione nel set di basi Clifford+T. -
Il plugin di sintesi di alto livello predefinito per
MCXGateproduce conteggi T migliori durante la transpilazione nel set di basi Clifford+T, a condizione che sia disponibile almeno 1 qubit ancilla. -
Aggiunto un set predefinito di gate inversi per il passaggio
InverseCancellationdel transpiler. In precedenza, un elenco esplicito di porte o coppie di porte da cancellare era un argomento obbligatorio per il costruttore dell'oggetto pass. Questo elenco è facoltativo e, se non viene fornito alcun elenco, i gate autoinversi sono:e le coppie inverse:
sarà annullato dal passaggio.
-
Aggiunto un nuovo argomento al
InverseCancellationcostruttore,run_default, che quando impostato suTrueeseguirà il nuovo elenco predefinito di gate di cancellazione inversa oltre a eventuali gate personalizzati forniti. Questo è destinato ai casi in cui si desidera eseguire una serie personalizzata di cancellazioni inverse oltre ai gate predefiniti. -
TranspileLayoutha due nuovi metodi:from_property_set()ewrite_into_property_set(), che formalizzano l'attuale struttura ad hoc delle proprietà di transpilazione e il modo in cui vengono convertite in unTranspileLayout. Ciò consente ai passaggi durante una pipeline di transpiler di accedere a ciò cheTranspileLayoutsarà il, modificarlo nella forma completamente strutturata e quindi riscriverlo nella forma canonica.Si prevede che nella futura versione 3.0 di Qiskit, il
TranspileLayout(o qualcosa di simile) sarà un attributo diretto della rappresentazione intermedia delDAGCircuittranspiler e sarà richiesto dai passaggi per essere mantenuto sincronizzato con il resto delDAGCircuit. -
Riattivato il passaggio del transpiler
VF2PostLayoutin esecuzione nellaoptimizationfase peroptimization_level=3con latranspile()funzione e gli oggetti gestori di passaggio generati restituiti dallagenerate_preset_pass_manager()funzione. Il passaggio viene eseguitostrict_direction=Truedopo tutte le ottimizzazioni fisiche effettuate nella fase per tentare di migliorare il layout un'ultima volta con il circuito di uscita esatto. Questa funzione era stata precedentemente abilitata in Qiskit v2.1.0, ma è stata ripristinata in 2.1.2 a causa di problemi con l'implementazione iniziale. Questi problemi sono stati risolti e il layout verrà applicato correttamente se ne viene trovato uno migliore.
Funzionalità di visualizzazione
-
È stata aggiunta una nuova opzione,
measure_arrows, ai backendmpltexte per il disegnatore diqiskit.visualization.circuit_drawer()circuiti eqiskit.circuit.QuantumCircuit.draw(). Quando questa opzione è impostata suTrue, il cassetto disegnerà una freccia dallameasurecasella ai bit classici sottostanti. Questo era il comportamento precedente nei cassetti. Se è impostato suFalse, non verranno disegnate frecce e invece il registro classico e il bit utilizzato dalmeasuresaranno indicati all'interno dellameasurecasella. Ciò consente dimeasureimpilare le scatole in uno strato verticale.Se non è impostata alcuna opzione, l'impostazione predefinita è
True. L'utente può modificare l'impostazione predefinita nel file di configurazione utente, che si trova di default nella directory~/.qiskit, nel filesettings.conf. Sotto la voce[Default], l'utente può inserirecircuit_measure_arrows = Falseper modificare l'impostazione predefinita.
Note sull'aggiornamento
- La versione minima di Rust supportata per la compilazione di Qiskit dai sorgenti (compresa la compilazione dell'API C in modalità standalone) è stata aumentata da Rust 1.79 a Rust 1.85. Questa modifica si è resa necessaria per consentire l'utilizzo di una versione più recente della libreria di algebra lineare Rust faer, utilizzata in Qiskit. Sono stati riscontrati problemi durante l'esecuzione di Qiskit su Windows con la versione precedente di faer. Questi problemi sono stati risolti nella nuova versione, ma per compilare la nuova versione di faer è necessaria una nuova versione del compilatore Rust.
Note sull'aggiornamento dei circuiti
-
La definizione del circuito di
ModularAdderGateè stata aggiornata per utilizzareadder_modular_v17(). Per ottenere il comportamento precedente, utilizzare invece la definizioneadder_qft_d00()di. -
I metodi
XGate.control(),CXGate.control(),CCXGate.control()C3XGate.control(),C4XGate.control(), eMCXGate.control()non restituiscono più unAnnotatedOperationquando l'argomentoannotatedè impostato suTrue, ma restituiscono invece lo stesso esplicitoMCXGateche si otterrebbe quandoannotatedèFalse. Ciò è coerente con il modo in cui l'argomentoannotatedviene utilizzato nella libreria di circuiti standard, dove in genere evitiamo di introdurre unAnnotatedOperationquando è già disponibile una classe di gate nativa. In pratica, ciò porta a una decomposizione più efficiente dei gate annotati con controllo nella famiglia MCX.
Note sull'aggiornamento dell'API C
-
La maggior parte degli usi di
uintptr_tè stata modificata insize_t. In particolare, sono stati modificati i seguenti usi:QkOpCount.countQkOpCounts.lenQkObsTerm.len- Il tipo di ritorno di
qk_circuit_num_instructions(). indexL'argomento inqk_circuit_get_instruction().boundariesL'argomento inqk_obs_new().- I tipi di ritorno di
qk_obs_num_terms(),qk_obs_len(), eqk_obs_boundaries(). - Il tipo di ritorno di
qk_target_entry_num_properties(), eqk_target_num_instructions().
Questa modifica si è resa necessaria perché lo strumento utilizzato per generare i file header C dal codice rust di Qiskit, cbindgen, utilizzava
uintptr_tper impostazione predefinita nei punti in cuisize_tsi allineava meglio all'uso dei tipi in Rust. Questa modifica è stata apportata per rendere più chiaro il modo in cui i valori dell'API C sono destinati a essere utilizzati.
Note sull'aggiornamento QPY
- La versione predefinita di QPY emessa da
qpy.dump()è ora il formato QPY versione 16. Se è necessaria una versione in formato diverso, è possibile utilizzareversionl'argomento per specificare una versione precedente.
Note sull'aggiornamento delle informazioni quantistiche
SparsePauliOp.assign_parameters()ora imposterà il tipo di dati dell'arraycoeffsdi output sucomplexse tutti i parametri sono completamente vincolati a valori numerici.
Note sull'aggiornamento della sintesi
- I valori predefiniti degli argomenti
opt_a1eopt_a2diqs_decomposition()sono oraopt_a1 = Noneeopt_a2 = None. Le nuove impostazioni predefinite sceglieranno il valore ottimale in base al fatto che l'unità di input permatl'argomento sia controllata o meno, in modo da ottenere il conteggioCXGateminimo predefinito. Se desideri mantenere il comportamento precedente, puoi richiamare esplicitamenteopt_a1 = Trueeopt_a2 = Trueper mantenere lo stesso comportamento delle versioni precedenti.
Note sull'aggiornamento del transpiler
- Il circuito
PassManagerora imposta sempre le proprietàoriginal_circuit_indicesenum_input_qubitsprima dell'avvio dell'esecuzione sui singoli passaggi. Si tratta di proprietà del circuito di ingresso, che in precedenza dovevano essere impostate dai singoli passaggi, spesso come effetto collaterale del loro scopo primario.
Circuiti deprecati
-
Le seguenti classi della libreria dei circuiti sono deprecate a partire da Qiskit 2.2 e saranno rimosse in Qiskit 3.0. Sono stati sostituiti con equivalenti moderni.
Correzioni di bug
-
ApplyLayoutora gestirà correttamente il caso dell'applicazione di uno zero-qubitLayout. In precedenza, avrebbe affermato che non era stato impostato alcun layout, anche se il"layout"campo delPropertySetera uguale aLayout(). -
Risolti i problemi di perdita di memoria durante la creazione di
QkOpCountsun'istanza e durante qualsiasi chiamata aqk_opcounts_clear()ogni volta che viene passata un'istanza vuota. -
In precedenza era possibile definire un invalid
PauliEvolutionGateda un elenco di operatori, in cui gli operatori non erano tutti definiti sullo stesso numero di qubit. Questo problema è stato risolto e ora viene generato un errore quando viene definito il gate:from qiskit.quantum_info import Pauli, SparsePauliOp from qiskit.circuit.library import PauliEvolutionGate pauli = Pauli("XYZ") # 3 qubits op = SparsePauliOp(["XYIZ"], [1]) # 4 qubits evo = PauliEvolutionGate([pauli, op], time=1) -
Risolto un problema nel passaggio
VF2Layoutdel transpiler in cui, anche con un set di seed fisso, l'output del passaggio era potenzialmente non deterministico; in particolare se il circuito di input aveva qubit attivi che contenevano solo operazioni a singolo qubit. Risolto #14729 -
Risolto un bug in
PassManager.run()in cui lacallbackfunzione non veniva richiamata durante l'esecuzione con più circuiti. Il callback ora viene attivato correttamente per ogni passaggio su ciascun circuito, anche nell'esecuzione in parallelo. -
Risolti diversi problemi nel passaggio del
CommutativeInverseCancellationtranspiler. Il passaggio ora funziona correttamente su circuiti contenentiCliffordoperazioni, operazioni di controllo del flusso e operazioni non invertibili comeInitialize.Inoltre, il passaggio esegue sempre prima un controllo sintattico (non basato sulla matrice), quando identifica le coppie di porte inverse. Se le porte non sono sintatticamente uguali, l'argomento
matrix_basedè impostato suTrue, e l'operazione non agisce su più dimax_qubitsqubit, viene eseguito anche un controllo matriciale. Questo migliora leggermente il potenziale di riduzione del passaggio.Corretti i punti #14407, #14635 e #14645.
-
Corretti diversi problemi nel passaggio
CommutativeCancellationdel transpiler (e quindi intranspile()), dove la fase globale del circuito non veniva aggiornata correttamente. In particolare, la fusione di un gate X e di un gate RX ha introdotto uno sfasamento, mentre la rimozione di un gate di rotazione di Pauli con angolo della forma , ha prodotto erroneamente uno sfasamento di . -
Risolto un problema in
CommutationCheckercui i gate controllati standard non venivano gestiti correttamente se controllati su uno stato diverso dallo stato tutto-uno. Corretto #14974 -
Risolto un problema di non determinismo in
CommutativeCancellation. Ciò non ha influito sull'ordine restituito daDAGCircuit.topological_nodes()otopological_op_nodes(), che in genere dovrebbero essere utilizzati quando il determinismo dell'ordine dei nodi è importante, grazie alla loro funzione di ordinamento canonico integrata. Tuttavia, se si ispezionano i nodi in ordine arbitrario (DAGCircuit.op_nodes()) o la struttura dei bordi (DAGCircuit.edges()), l'ordine di iterazione risulterebbe non deterministico dopo una chiamata aCommutativeCancellation. -
Risolto un bug in
MCXGate.control()cui l'aggiunta di ulteriori controlli a un controlloMCXGateaperto non teneva contoctrl_statedel gate MCX controllato, causando un errorectrl_statenel gate MCX esteso. Si noti che le classi MCXCXGateesplicite,CCXGate,C3XGateeC4XGateerano già state gestite correttamente. -
Corretto l'avviso di deprezzamento per Python 3.9 in modo che venga 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.
-
Risolto un bug in
PhaseOracle,PhaseOracleGateeBitFlipOracleGatein cui il tentativo di caricare da un file dimacs generava unTypeError. -
Risolto un bug nel passaggio
ElidePermutationsdel transpiler, in cui la mappatura dei qubit non veniva aggiornata correttamente in presenza diPermutationGates, causando circuiti errati e aggiornamenti non corretti al set di proprietà del gestore dei passaggi. -
Il transpiler integrato che imposta la
final_layoutproprietà ora gestirà correttamente l'aggiornamento di questo campo se era già stato impostato. Ciò può essere osservato dal fatto che il metodoTranspileLayout.routing_permutationora restituisce una permutazione corretta dopo aver eseguito più di un passaggio che impostafinal_layout.Ciò 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. -
Risolto un bug nel
HighLevelSynthesispassaggio in cui, se il circuito conteneva oggetti di alto livello con registri classici, questi venivano mappati all'indice relativo nell'oggetto invece che all'indice corrispondente nel circuito esterno. I registri classici sono ora correttamente mappati sull'indice del circuito esterno. -
Risolto un bug in
Target.instruction_supported()in cui il controllo dell'ordine dei qubit dell'istruzione veniva saltato quando il metodo veniva chiamato conoperation_nameeparametersargomenti che corrispondevano a un'istruzione esistente. -
Corretto il comportamento
max_trialsdell'argomento quando impostatoVF2LayoutsuNoneo su un numero negativo. Il passaggio è stato documentato come limitante la ricerca in base alle dimensioni del circuito o del target se l'opzione era impostata suNonee come accettante valori negativi per specificare una ricerca illimitata. Tuttavia, nell' 2.1.0, questo comportamento è stato modificato in modo errato, cosicchéNoneeseguiva una ricerca illimitata e il tentativo di utilizzare un numero negativo generava un errore. Queste omissioni sono state corrette in modo che il pass si comporti come documentato e sia coerente con le versioni precedenti. -
Risolto un problema nei plugin di sintesi ad
MCXSynthesis1DirtyKG24alto livello eMCXSynthesis2DirtyKG24perMCXGate, in cui i plugin non consideravano i qubit ausiliari puliti disponibili come qubit ausiliari sporchi disponibili. In particolare, il pluginMCXSynthesis2DirtyKG24non si applicava quando erano disponibili un qubit ausiliario pulito e uno sporco. -
Il
PauliEvolutionGate.to_matrix()metodo ora restituisce l'esponenziale esatto della matrice , dove è iloperatore iltimepassato al gate. Questo corregge un comportamento inaspettato, poiché èPauliEvolutionGatedocumentato che rappresenta l'evoluzione temporale esatta, ma in precedenza la matrice dipendeva dal modo in cui il compilatore approssimava l'evoluzione temporale. Ilto_matrixmetodo è ora coerente con la documentazione. -
Risolto un problema di regressione delle prestazioni durante la compilazione
ParameterExpressionincrementale dalla combinazione di un numero elevato di sottoespressioni. Risolto #14653 -
È stato corretto un bug di correttezza quando si esportano circuiti con istruzioni di ritardo utilizzando le unità 'ps' in QASM3.
-
Risolto un caso limite nella visualizzazione del circuito
QFT. In precedenza, quandoQFT.inverse()veniva richiamato e poi venivano modificati gli attributi del circuito QFT, il QFT veniva visualizzato come"IQFT_dg". Questo era errato, mentre ora viene visualizzato correttamente"IQFT". Corretto #14758. -
Risolto un bug nel
PauliEvolutionSynthesisRustiqplugin che produceva circuiti errati nel caso in cui l'operatore di unPauliEvolutionGatecontenesse oggetti di tipoSparseObservable.Ad esempio:
from qiskit.circuit.library import PauliEvolutionGate from qiskit.quantum_info import SparseObservable, Operator from qiskit.transpiler.passes.synthesis.hls_plugins import PauliEvolutionSynthesisRustiq obs = SparseObservable.from_sparse_list([("1+XY", (0, 1, 2, 3), 1.5)], num_qubits=4) evo = PauliEvolutionGate(obs, 1) qct = PauliEvolutionSynthesisRustiq().run(evo) assert Operator(qct) == Operator(evo) -
Risolto un problema con la
generate_preset_pass_manager()funzione che ignorava in modo errato i dati relativi ai vincoli temporali contenuti in unTargetoggetto fornito quandobackendl'argomento non era impostato. Risolto #14329 -
Corretto un bug in
ObservablesArray.coerce_observable(), a causa del quale un'eccezione che indicava che un osservabile non era hermitiano veniva attivata in modo eccessivo. Gli osservabili uguali azeronon sono ammessi e ora invocano un fallimento aggravato. -
qiskit.circuit.library.quantum_volume()è stato aggiornato per gestire unnumpy.random.Generatorcome input per il suoseedargomento. In precedenza, un argomento generatore di questo tipo avrebbe portato a unTypeError. -
QuantumCircuit.compose()ora rimappa correttamente comunque le variabili e gli intervalli utilizzati nelleDelayistruzioni quando viene specificatovar_remapl'argomento. -
SabreLayoututilizza un layout "sottoinsieme denso" come una delle sue prove, seguendo lo stesso algoritmo diDenseLayout. In precedenza, tuttavia, la versione utilizzata da Sabre assegnava tutti i qubit virtuali, compresi quelli fittizi, a un qubit fisico, compromettendo l'efficacia dell'algoritmo, ma non la sua correttezza. Sabre utilizzerà ora solo i qubit virtuali definiti dall'utente per questa prova iniziale, il che potrebbe comportare piccoli miglioramenti nella selezione del layout se calcolati sulla media di grandi classi di circuiti. -
Risolto un bug in
SparsePauliOp.simplify()in cui il metodo rimuoveva i termini di 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.
-
TranspileLayout.initial_index_layout()ora gestirà correttamentefilter_ancillas=Truel'argomento se i qubit virtuali nel non sonoinitial_layoutstati specificati dal costruttore in ordine di indice. -
VF2Layoute oraVF2PostLayoutincluderà correttamente le assegnazioni di layout (arbitrarie) per i qubit completamente inattivi. In precedenza questo poteva essere osservato dal fallimentoTranspileLayout.initial_index_layout()delle chiamate dopo una compilazione. -
Risolto un problema nel passaggio del
VF2PostLayouttranspiler. In determinate situazioni, quando il passaggio viene eseguito con l'argomento,strict_direction=Truesi verificava un potenziale problema di scalabilità del runtime quando il grafico di interazione del circuito conteneva qubit che avevano solo operazioni a 1 qubit. Questi problemi di mappatura comportano una complessità combinatoria per il punteggio che porterebbe quasi sempre al superamento del tempo massimo per il punteggio e, in genere, non migliorerebbe il layout. Nellastrict_direction=Falsemodalità esiste un'implementazione di ricerca ottimizzata per questi problemi, ma i vincoli aggiuntivi perstrict_direction=Truenon rendono questo approccio praticabile. In questi casi, invece, laVF2PostLayoutricerca verrà ora saltata poiché il problema di layout non è risolvibile per il passaggio.
Altre note
- L'implementazione del routing Sabre utilizzato da
SabreLayouteSabreSwapora comprime le serie di nodi che diventeranno automaticamente idonei al routing contemporaneamente all'interno della sua rappresentazione interna di interazione virtuale. Ciò migliora l'efficienza del routing, riduce l'uso della memoria intermedia ed evita che le porte dell' 2q e influenzino ilookaheadcomponenti euristici.
2.1.0rc1
Note di deprecazione
-
Il supporto per l'esecuzione di Qiskit con Python 3.9 è stato deprecato e sarà rimosso nella versione di Qiskit 2.3.0. 2.3.0 è la prima release dopo la fine del ciclo di vita di Python 3.9 e non è più supportato. [1] Ciò significa che a partire dalla versione 2.3.0 sarà necessario aggiornare la versione Python in uso a Python 3.9 o superiore.