Skip to main content
IBM Quantum Platform

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

  • ConsolidateBlocks ora legge una PropertySet chiave ConsolidateBlocks_qubit_map all'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 ConsolidateBlocks istanza su più circuiti, comprese le chiamate a transpile() 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__() in QuantumCircuit che non eseguiva la copia profonda dei parametri del circuito. Di conseguenza, la mutazione di un BoxOp in un circuito copiato non influisce più sul circuito originale.

  • Risolto un problema nel Optimize1qGatesDecomposition passaggio quando il passaggio viene inizializzato con un Target contenente 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 BasisTranslator passaggio in cui un gate multi-qubit all'interno di un ControlFlowOp blocco veniva tracciato utilizzando i suoi indici qubit locali invece di utilizzare gli indici assoluti dal circuito sorgente.

  • Il passaggio del ConsolidateBlocks transpiler 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 .gz file aperti utilizzando il modulo della gzip libreria 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.

  • ConsolidateBlocks ora restituirà un'eccezione Python -space invece di andare in panico quando rileva un'analisi non valida o non aggiornata nelle chiavi legacy run_list``block_listPropertySet o. Corretto #14646.

  • Optimize1qGatesDecomposition ora genererà un TranspilerError anziché un panic Rust-space quando si tenta di eseguire su un circuito troppo grande per il Target. Risolto #15116.

  • I passaggi di pianificazione, ALAPScheduleAnalysis e ASAPScheduleAnalysis, ora gestiranno correttamente i circuiti che non contengono operazioni. In precedenza avevano sollevato una TranspilerError affermando 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 ControlFlowOp operazioni 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 VF2PostLayout in optimization_level=3 sono 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 ora circuit_to_dag() aggiungerà nuovi bordi in un ordine deterministico. Il comportamento precedente poteva causare il passaggio di determinati transpilatori (come SabreSwap) 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 pickle il supporto per il SabreSwap in cui SabreSwap un'istanza dava errore quando veniva sottoposta a pickling dopo l'esecuzione SabreSwap.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 parametri rtol e atol forniti 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 funzione transpile()Python per un contesto C autonomo.
  • Passaggio di trasformazione Litinski: un nuovo passaggio di trasformazione LitinskiTransformation che 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 Target classe ora supporta la specificazione dei limiti per i valori consentiti per le operazioni parametrizzate aggiunte all'obiettivo. Quando si aggiunge un'istruzione al Target è possibile aggiungere l'argomento opzionale angle_bounds per specificare i limiti superiore e inferiore per i gate di rotazione parametrizzati. È stato aggiunto WrapAngles un 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

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 Duration ha ottenuto una nuova variante ps , che può essere utilizzata per rappresentare una durata in picosecondi.

  • Migliorato PauliEvolutionGate.control(), PauliEvolutionGate.power() e PauliEvolutionGate.inverse() per restituire rappresentazioni più efficienti in termini di a PauliEvolutionGate. 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 molte ParameterExpression istanze diverse a valori numerici utilizzando lo stesso dizionario di mappature. Il metodo bind() esistente presenta un notevole overhead e allocazioni non necessarie, poiché restituisce sempre un ParameterExpression per garantire la coerenza di digitazione.

OpenQASM Caratteristiche

  • Aggiunto supporto parziale per defcal i simboli nell'esportatore OpenQASM3. Ciò consente ai pacchetti a valle di esportare istruzioni personalizzate che operano sia su bit quantistici che classici utilizzando qiskit.qasm3.dumps(). Gli utenti possono ora definire istruzioni personalizzate (ad esempio, un CustomMeasure che agisce su un qubit e restituisce un bit classico) e specificarne il comportamento utilizzando DefcalInstruction. Questi defcal vengono passati all'esportatore tramite implicit_defcals l'argomento in qiskit.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() e qasm3.load() ora hanno un argomento aggiuntivo chiamato num_qubits. Se fornite, le funzioni restituiranno circuiti che avranno qubit pari a num_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_version nel file di configurazione utente. Quando impostato, definisce la versione minima consentita di QPY per qpy.load(). Se la versione del formato di un file QPY è inferiore all'impostazione minimum_qpy_version rispetto minimum_qpy_version all'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 DURATION dei picosecondi.

Caratteristiche dell'informazione quantistica

Caratteristiche della sintesi

  • Aggiunto nuovo algoritmo di sintesi per ModularAdderGate che non richiede qubit ausiliari e ha un conteggio CX migliore rispetto a adder_qft_d00():

  • Aggiunto un nuovo algoritmo di sintesi, synth_mcx_noaux_hp24(), per MCXGate che non richiede alcun qubit ausiliario. Questo metodo produce un numero lineare, anziché quadratico, di porte CX rispetto synth_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 di CXGates di un unitariano n-qubit generale di un CXGate4n213\frac{4^{n − 2} − 1}{3}. Grazie alla decomposizione migliorata, un'unità generale a 3 qubit può essere decomposta utilizzando 19 CXGates (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 di MCMTSynthesisXGate alto livello.

Funzionalità del transpiler

  • Aggiunto nuovo plugin di sintesi di alto livello per sintetizzare un ModularAdderGate:

    Il ModularAdderSynthesisDefault è stato aggiornato per seguire la seguente sequenza di sintetizzatori addizionatori modulari: "ModularAdder.qft_d00" quando il numero di qubit è 4\leq 4, "ModularAdder.modular_v17" in tutti gli altri casi.

  • Aggiunto un nuovo passaggio del LitinskiTransformation transpiler 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 PauliEvolutionGate porte ) seguite da porte Clifford. Il passaggio genera TranspilerError un'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 LitinskiTransformation costruttore accetta un argomento fix_clifford. Quando False (non predefinito), il circuito restituito contiene solo PauliEvolutionGate gate, 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 MCXSynthesisNoAuxHP24 alto livello per MCXGate gli oggetti. Inoltre, il plugin di sintesi MCXSynthesisDefault predefinito per MCXGate gli 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 Target i limiti angolari nelle istruzioni. Prima di questa versione, Target era possibile specificare che un'operazione che accettava un parametro consentisse qualsiasi valore valido o un valore specifico. Ad esempio, se RZGate(Parameter("theta")) venisse aggiunto all'obiettivo, ciò indicherebbe che è consentito un RZGate con qualsiasi valore per theta. Se invece RZGate(math.pi) venisse aggiunto al target, ciò indicherebbe RZGate che solo π\pi è l'unico valore consentito sul target. Questa nuova funzione consente di limitare gli angoli consentiti a qualsiasi float valore compreso tra un limite inclusivo. Ad esempio, è possibile aggiungere RZGate(math.pi) a Target e limitare il valore dell'angolo tra i valori 0 e 2π2\pi.

    Esistono diversi metodi disponibili per lavorare con i limiti angolari sul bersaglio. Il primo è Target.add_instruction() che ha un nuovo argomento angle_bounds chiave utilizzato per aggiungere un limite angolare a un'istruzione nel Target. Per lavorare con i limiti angolari, dovrai anche registrare una funzione di callback nel registro WRAP_ANGLE_REGISTRY globale che indicherà al transpiler e WrapAngles pass come regolare i gate per i limiti angolari. La funzione di callback prenderà un elenco di valori float arbitrari che rappresentano gli angoli del gate dal circuito, nonché gli indici dei qubit nel circuito su cui il gate stava operando, e restituirà un DAGCircuit che rappresenta un circuito equivalente per il gate con quell'angolo, ma rispettando i limiti dell'angolo e altri Target vincoli. 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 e Target.gate_has_angle_bounds().

    Se si desidera applicare i limiti angolari da un target a qualsiasi gate in un circuito, è necessario utilizzare il passaggio WrapAngles transpiler.

  • Aggiunto un nuovo kwarg check_angle_bounds al Target.instruction_supported() metodo. Quando è impostato su True (impostazione predefinita), il metodo verificherà se il specificato è conforme parameters anche a eventuali limiti angolari che potrebbero esistere per l'istruzione oggetto della query.

  • Aggiunto un nuovo passaggio WrapAngles del transpiler utilizzato per applicare vincoli angolari sui gate nel Target. Se un Target ha 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')
    _images/release_notes-1.png
  • DAGCircuit ora 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'esecuzione transpile() o l'esecuzione dei gestori di passaggi predefiniti restituiti da generate_preset_pass_manager() a optimization_level=3 come livello di ottimizzazione 3, poiché le copie profonde interne copiano il DAGCircuit per ogni iterazione del ciclo di ottimizzazione nella optimization fase.

  • Viene fornito un nuovo metodo, DAGCircuit.make_physical(), che sostituisce in modo efficiente i qubit nel DAGCircuit con il registro canonico dei qubit fisici, includendo potenzialmente l'espansione. È disponibile QuantumCircuit.ensure_physical() anche un metodo simile.

  • Un nuovo metodo, DAGCircuit.structurally_equal(), può essere utilizzato se due DAGCircuit istanze 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 BasePassManager possono ora modificare il loro property_set attributo 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 OptimizationMetric che specifica il criterio di ottimizzazione nel HighLevelSynthesis passaggio. 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_T se viene rilevato un set di base Clifford+T. Tuttavia, questa classe non può essere attualmente impostata manualmente durante l'esecuzione transpile() o l'esecuzione di un gestore di passaggi preimpostato generato da generate_preset_pass_manager().

  • Aggiunto un nuovo argomento optimization_metric al costruttore per il HighLevelSynthesis passaggio del transpiler che accetta un OptimizationMetric oggetto. Quando è impostato su COUNT_T, il passaggio sceglie decomposizioni più adatte al set di porte Clifford+T.

  • I plugin di sintesi di alto livello predefiniti per ModularAdderGate e MultiplierGate producono conteggi T migliori durante la transpilazione nel set di basi Clifford+T.

  • Il plugin di sintesi di alto livello predefinito per MCXGate produce 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 InverseCancellation del 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 InverseCancellation costruttore, run_default, che quando impostato su True eseguirà 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.

  • TranspileLayout ha due nuovi metodi: from_property_set() e write_into_property_set(), che formalizzano l'attuale struttura ad hoc delle proprietà di transpilazione e il modo in cui vengono convertite in un TranspileLayout. Ciò consente ai passaggi durante una pipeline di transpiler di accedere a ciò che TranspileLayout sarà 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 del DAGCircuit transpiler e sarà richiesto dai passaggi per essere mantenuto sincronizzato con il resto del DAGCircuit.

  • Riattivato il passaggio del transpiler VF2PostLayout in esecuzione nella optimization fase per optimization_level=3 con la transpile() funzione e gli oggetti gestori di passaggio generati restituiti dalla generate_preset_pass_manager() funzione. Il passaggio viene eseguito strict_direction=True dopo 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 backend mpl text e per il disegnatore di qiskit.visualization.circuit_drawer() circuiti e qiskit.circuit.QuantumCircuit.draw(). Quando questa opzione è impostata su True, il cassetto disegnerà una freccia dalla measure casella ai bit classici sottostanti. Questo era il comportamento precedente nei cassetti. Se è impostato su False, non verranno disegnate frecce e invece il registro classico e il bit utilizzato dal measure saranno indicati all'interno della measure casella. Ciò consente di measure impilare 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 file settings.conf. Sotto la voce [Default] , l'utente può inserire circuit_measure_arrows = False per 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

Note sull'aggiornamento dell'API C

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 utilizzare version l'argomento per specificare una versione precedente.

Note sull'aggiornamento delle informazioni quantistiche

Note sull'aggiornamento della sintesi

  • I valori predefiniti degli argomenti opt_a1 e opt_a2 di qs_decomposition() sono ora opt_a1 = None e opt_a2 = None. Le nuove impostazioni predefinite sceglieranno il valore ottimale in base al fatto che l'unità di input per mat l'argomento sia controllata o meno, in modo da ottenere il conteggio CXGate minimo predefinito. Se desideri mantenere il comportamento precedente, puoi richiamare esplicitamente opt_a1 = True e opt_a2 = True per mantenere lo stesso comportamento delle versioni precedenti.

Note sull'aggiornamento del transpiler

  • Il circuito PassManager ora imposta sempre le proprietà original_circuit_indices e num_input_qubits prima 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

Correzioni di bug

  • ApplyLayout ora gestirà correttamente il caso dell'applicazione di uno zero-qubit Layout. In precedenza, avrebbe affermato che non era stato impostato alcun layout, anche se il "layout" campo del PropertySet era uguale a Layout().

  • Risolti i problemi di perdita di memoria durante la creazione di QkOpCounts un'istanza e durante qualsiasi chiamata a qk_opcounts_clear() ogni volta che viene passata un'istanza vuota.

  • In precedenza era possibile definire un invalid PauliEvolutionGate da 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 VF2Layout del 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 la callback funzione 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 CommutativeInverseCancellation transpiler. Il passaggio ora funziona correttamente su circuiti contenenti Clifford operazioni, operazioni di controllo del flusso e operazioni non invertibili come Initialize.

    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 su True, e l'operazione non agisce su più di max_qubits qubit, 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 CommutativeCancellation del transpiler (e quindi in transpile()), 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 (2+4k)π(2 + 4k)\pi, kZk \in \mathbb Z ha prodotto erroneamente uno sfasamento di 1-1.

  • 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 da DAGCircuit.topological_nodes() o topological_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 a CommutativeCancellation.

  • Risolto un bug in MCXGate.control()cui l'aggiunta di ulteriori controlli a un controllo MCXGate aperto non teneva conto ctrl_state del gate MCX controllato, causando un errore ctrl_state nel gate MCX esteso. Si noti che le classi MCX CXGateesplicite, CCXGate, C3XGate e C4XGate erano 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, PhaseOracleGate e BitFlipOracleGate in cui il tentativo di caricare da un file dimacs generava un TypeError.

  • Risolto un bug nel passaggio ElidePermutations del transpiler, in cui la mappatura dei qubit non veniva aggiornata correttamente in presenza di PermutationGates, causando circuiti errati e aggiornamenti non corretti al set di proprietà del gestore dei passaggi.

  • Il transpiler integrato che imposta la final_layout proprietà ora gestirà correttamente l'aggiornamento di questo campo se era già stato impostato. Ciò può essere osservato dal fatto che il metodo TranspileLayout.routing_permutation ora restituisce una permutazione corretta dopo aver eseguito più di un passaggio che imposta final_layout.

    Ciò non ha influito sulle normali chiamate a transpile() o generate_preset_pass_manager() utilizzando i plugin integrati di Qiskit; nessuna pipeline costruita in questa forma tenterebbe di impostare final_layout più di una volta.

  • Risolto un bug nel HighLevelSynthesis passaggio 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 con operation_name e parameters argomenti che corrispondevano a un'istruzione esistente.

  • Corretto il comportamento max_trials dell'argomento quando impostato VF2Layout su None o 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 su None e come accettante valori negativi per specificare una ricerca illimitata. Tuttavia, nell' 2.1.0, questo comportamento è stato modificato in modo errato, cosicché None eseguiva 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 MCXSynthesis1DirtyKG24 alto livello e MCXSynthesis2DirtyKG24 per MCXGate, in cui i plugin non consideravano i qubit ausiliari puliti disponibili come qubit ausiliari sporchi disponibili. In particolare, il plugin MCXSynthesis2DirtyKG24 non si applicava quando erano disponibili un qubit ausiliario pulito e uno sporco.

  • Il PauliEvolutionGate.to_matrix() metodo ora restituisce l'esponenziale esatto della matrice exp(itH)\exp(-it H), dove HH è il operator e tt il time passato al gate. Questo corregge un comportamento inaspettato, poiché è PauliEvolutionGate documentato che rappresenta l'evoluzione temporale esatta, ma in precedenza la matrice dipendeva dal modo in cui il compilatore approssimava l'evoluzione temporale. Il to_matrix metodo è ora coerente con la documentazione.

  • Risolto un problema di regressione delle prestazioni durante la compilazione ParameterExpression incrementale 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, quando QFT.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 PauliEvolutionSynthesisRustiq plugin che produceva circuiti errati nel caso in cui l'operatore di un PauliEvolutionGate contenesse oggetti di tipo SparseObservable.

    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 un Target oggetto fornito quando backend l'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 a zero non sono ammessi e ora invocano un fallimento aggravato.

  • qiskit.circuit.library.quantum_volume() è stato aggiornato per gestire un numpy.random.Generator come input per il suo seed argomento. In precedenza, un argomento generatore di questo tipo avrebbe portato a un TypeError.

  • QuantumCircuit.compose() ora rimappa correttamente comunque le variabili e gli intervalli utilizzati nelle Delay istruzioni quando viene specificato var_remap l'argomento.

  • SabreLayout utilizza un layout "sottoinsieme denso" come una delle sue prove, seguendo lo stesso algoritmo di DenseLayout. 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:

    1. 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.
    2. 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à correttamente filter_ancillas=True l'argomento se i qubit virtuali nel non sono initial_layout stati specificati dal costruttore in ordine di indice.

  • VF2Layout e ora VF2PostLayout includerà correttamente le assegnazioni di layout (arbitrarie) per i qubit completamente inattivi. In precedenza questo poteva essere osservato dal fallimento TranspileLayout.initial_index_layout() delle chiamate dopo una compilazione.

  • Risolto un problema nel passaggio del VF2PostLayout transpiler. In determinate situazioni, quando il passaggio viene eseguito con l'argomento, strict_direction=True si 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. Nella strict_direction=False modalità esiste un'implementazione di ricerca ottimizzata per questi problemi, ma i vincoli aggiuntivi per strict_direction=True non rendono questo approccio praticabile. In questi casi, invece, la VF2PostLayout ricerca verrà ora saltata poiché il problema di layout non è risolvibile per il passaggio.

Altre note

  • L'implementazione del routing Sabre utilizzato da SabreLayout e SabreSwap ora 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 i lookahead componenti 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.

    [1] https://devguide.python.org/versions/

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