Skip to main content
IBM Quantum Platform

Note di rilascio di Qiskit 0.40


0.40.0

Con questa release viene ufficialmente deprecato il progetto del provider IBMQ di Qiskit come parte del metapacchetto Qiskit. Ciò significa che in una futura versione, pip install qiskit non includerà più automaticamente qiskit-ibmq-provider. Se attualmente si sta installando o elencando qiskit come dipendenza per ottenere qiskit-ibmq-provider, si dovrebbe aggiornare per includere esplicitamente anche qiskit-ibmq-provider . Questo viene fatto mentre il progetto Qiskit si muove verso un modello in cui il pacchetto qiskit contiene solo le funzionalità di base comuni per la costruzione e la compilazione di circuiti, programmi e applicazioni quantistiche. I pacchetti che si basano su questo nucleo o che collegano Qiskit all'hardware o ai simulatori saranno installabili come pacchetti separati.

Terra 0.23.0

Preludio

Qiskit Terra 0.23.0 è un'importante release che include una moltitudine di nuove funzionalità e correzioni di bug. I punti salienti di questa release sono:

In questa versione viene anche deprecato il supporto per l'esecuzione con Python 3.7. Ora viene emesso un DeprecationWarning se si esegue Qiskit con Python 3.7. Il supporto per Python 3.7 sarà rimosso con la release 0.25.0 (attualmente prevista per il luglio 2023); a quel punto sarà necessario avere Python 3.8 o una versione più recente per utilizzare Qiskit.

Nuove funzioni

  • Gli impulsi in qiskit.pulse.library

    può essere inizializzato con il nuovo parametro angle, in modo da fornire due parametri float: amp e angle. L'inizializzazione con il complesso amp è ancora supportata.

  • La classe AdaptVQE ha un nuovo attributo, eigenvalue_historyche viene utilizzato per tenere traccia dell'energia più bassa raggiunta per ogni iterazione di AdaptVQE. Ad esempio:

    from qiskit.algorithms.minimum_eigensolvers import VQE
    from qiskit.algorithms.minimum_eigensolvers.adapt_vqe import AdaptVQE
    from qiskit.algorithms.optimizers import SLSQP
    from qiskit.circuit.library import EvolvedOperatorAnsatz
    from qiskit.opflow import PauliSumOp
    from qiskit.primitives import Estimator
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.utils import algorithm_globals
    
    excitation_pool = [
        PauliSumOp(
            SparsePauliOp(["IIIY", "IIZY"], coeffs=[0.5 + 0.0j, -0.5 + 0.0j]), coeff=1.0
        ),
        PauliSumOp(
            SparsePauliOp(["ZYII", "IYZI"], coeffs=[-0.5 + 0.0j, 0.5 + 0.0j]), coeff=1.0
        ),
        PauliSumOp(
            SparsePauliOp(
                ["ZXZY", "IXIY", "IYIX", "ZYZX", "IYZX", "ZYIX", "ZXIY", "IXZY"],
                coeffs=[
                    -0.125 + 0.0j,
                    0.125 + 0.0j,
                    -0.125 + 0.0j,
                    0.125 + 0.0j,
                    0.125 + 0.0j,
                    -0.125 + 0.0j,
                    0.125 + 0.0j,
                    -0.125 + 0.0j,
                ],
            ),
            coeff=1.0,
        ),
    ]
    ansatz = EvolvedOperatorAnsatz(excitation_pool, initial_state=self.initial_state)
    optimizer = SLSQP()
    h2_op = PauliSumOp.from_list(
        [
            ("IIII", -0.8105479805373266),
            ("ZZII", -0.2257534922240251),
            ("IIZI", +0.12091263261776641),
            ("ZIZI", +0.12091263261776641),
            ("IZZI", +0.17218393261915543),
            ("IIIZ", +0.17218393261915546),
            ("IZIZ", +0.1661454325638243),
            ("ZZIZ", +0.1661454325638243),
            ("IIZZ", -0.2257534922240251),
            ("IZZZ", +0.16892753870087926),
            ("ZZZZ", +0.17464343068300464),
            ("IXIX", +0.04523279994605788),
            ("ZXIX", +0.04523279994605788),
            ("IXZX", -0.04523279994605788),
            ("ZXZX", -0.04523279994605788),
        ]
    )
    
    algorithm_globals.random_seed = 42
    calc = AdaptVQE(VQE(Estimator(), ansatz, self.optimizer))
    res = calc.compute_minimum_eigenvalue(operator=h2_op)
    
    print(calc.eigenvalue_history)

    il valore restituito di calc.history dovrebbe essere all'incirca [-1.85727503] , poiché si tratta di una singola iterazione.

  • La registrazione di runtime durante l'esecuzione del programma AdaptVQE è stato migliorato. Quando si esegue la classe ora, i messaggi di log di livello DEBUG e INFO saranno emessi durante l'esecuzione della classe.

  • Aggiunto un nuovo passaggio del transpiler, CollectAndCollapse, per raccogliere e consolidare blocchi di nodi in un circuito. Questo passaggio è stato progettato per essere una classe base generale per la raccolta e il consolidamento di blocchi combinati. Per essere del tutto generali, il lavoro di raccolta e collasso dei blocchi viene svolto tramite funzioni fornite durante l'istanziazione del passaggio. Ad esempio, il file CollectLinearFunctions è stato aggiornato per ereditare da CollectAndCollapse e raccoglie i blocchi di CXGate e SwapGate e sostituisce ogni blocco con un elemento LinearFunction. Il CollectCliffords che ora si basa anch'esso su CollectAndCollapse, raccoglie blocchi di porte "Clifford" e sostituisce ogni blocco con una porta Clifford.

    L'interfaccia supporta anche l'opzione do_commutative_analysis, che consente di sfruttare la commutatività tra le porte per raccogliere blocchi di nodi più grandi. Ad esempio, la raccolta di blocchi di porte CX nel seguente circuito:

    qc = QuantumCircuit(2)
    qc.cx(0, 1)
    qc.z(0)
    qc.cx(1, 0)

    l'utilizzo di do_commutative_analysis consente di consolidare i due gate CX, in quanto il primo gate CX e il gate Z si scambiano.

  • Aggiunta di una nuova classe BlockCollector che implementa varie strategie di raccolta e di una nuova classe BlockCollapser che implementa varie strategie di collasso. Attualmente BlockCollector include la strategia di raccogliere avidamente tutte le porte che aderiscono a una determinata funzione di filtro (ad esempio, raccogliere tutte le porte Clifford) e BlockCollapser include la strategia di consolidare tutte le porte di un blocco in un singolo oggetto (ad esempio, un blocco di porte Clifford può essere consolidato in un singolo oggetto) Clifford).

  • Aggiunto un nuovo CollectCliffords che raccoglie blocchi di porte di Clifford e li consolida in oggetti qiskit.quantum_info.Clifford oggetti. Questo passaggio eredita da CollectAndCollapse e in particolare supporta l'opzione do_commutative_analysis. Supporta anche due opzioni aggiuntive split_blocks e min_block_size. Per ulteriori dettagli, consultare le note di rilascio di CollectAndCollapse e CollectLinearFunctions per ulteriori dettagli.

  • Il passo CollectLinearFunctions ha diversi nuovi argomenti nel suo costruttore:

    • do_commutative_analysis: consente di sfruttare la commutatività tra le porte per raccogliere blocchi di nodi più grandi.

    • split_blocks: consente di suddividere i blocchi raccolti in sottoblocchi su sottoinsiemi disgiunti di qubit. Ad esempio, nel circuito seguente:

      qc = QuantumCircuit(4)
      qc.cx(0, 2)
      qc.cx(1, 3)
      qc.cx(2, 0)
      qc.cx(3, 1)
      qc.cx(1, 3)

      il singolo blocco di porte CX sui qubit {0, 1, 2, 3} può essere suddiviso in due sottoblocchi disgiunti, uno sui qubit {0, 2} e l'altro sui qubit {1, 3}.

    • min_block_size: consente di specificare la dimensione minima del blocco da consolidare; i blocchi con meno porte non verranno modificati. Ad esempio, nel circuito seguente:

      qc = QuantumCircuit(4)
      qc.cx(1, 2)
      qc.cx(2, 1)

      le due porte CX saranno consolidate quando min_block_size è 1 o 2, e rimarranno invariate quando min_block_size è 3 o più grande.

  • Aggiunto un algoritmo di sintesi efficiente in profondità synth_cnot_depth_line_kms() per circuiti reversibili lineari LinearFunction sull'architettura lineare nearest-neighbor, seguendo l'articolo: https://arxiv.org/abs/quant-ph/0701194.

  • Il metodo DAGCircuit.replace_block_with_op() restituirà ora il nuovo blocco DAGOpNode che viene creato quando il blocco viene sostituito. In precedenza, la chiamata a questo metodo non restituiva nulla.

  • Aggiunto un algoritmo di sintesi efficiente dal punto di vista della profondità synth_permutation_depth_lnn_kms() per Permutation rispetto all'architettura lineare nearest-neighbor, seguendo il documento: https://arxiv.org/abs/quant-ph/0701194

  • Aggiunta una nuova classe PermutationGate per rappresentare la logica di permutazione come elemento di circuito. A differenza dell'elemento di libreria Permutation che aveva una definizione statica, questa nuova classe evita di sintetizzare un circuito di permutazione quando viene dichiarata. Questo ritarda la sintesi effettiva al transpiler. Consente inoltre di utilizzare diversi algoritmi per la sintesi delle permutazioni, disponibili come plugin di permutazione ad alto livello.

    Un'altra caratteristica fondamentale di PermutationGate è che implementa l'interfaccia __array__ per restituire in modo efficiente una matrice unitaria per una permutazione.

  • Aggiunti diversi plugin di sintesi ad alto livello per sintetizzare le permutazioni:

    • BasicSynthesisPermutationsi applica alle architetture completamente connesse e si basa sull'ordinamento. Questo è l'algoritmo precedentemente utilizzato per costruire circuiti quantistici per le permutazioni.
    • ACGSynthesisPermutationsi applica alle architetture completamente connesse, ma si basa sul metodo di Alon, Chung e Graham. Sintetizza qualsiasi permutazione in profondità 2 (misurata in termini di SWAP).
    • KMSSynthesisPermutationsi applica alle architetture lineari nearest-neighbor e corrisponde al metodo Kutin, Moulton, Smithline recentemente aggiunto.

    Ad esempio:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import PermutationGate
    from qiskit.transpiler import PassManager
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig, HighLevelSynthesis
    from qiskit.transpiler.passes.synthesis.plugin import HighLevelSynthesisPluginManager
    
    # Create a permutation and add it to a quantum circuit
    perm = PermutationGate([4, 6, 3, 7, 1, 2, 0, 5])
    qc = QuantumCircuit(8)
    qc.append(perm, range(8))
    
    # Print available plugin names for synthesizing permutations
    # Returns ['acg', 'basic', 'default', 'kms']
    print(HighLevelSynthesisPluginManager().method_names("permutation"))
    
    # Default plugin for permutations
    # Returns a quantum circuit with size 6 and depth 3
    qct = PassManager(HighLevelSynthesis()).run(qc)
    print(f"Default: {qct.size() = }, {qct.depth() = }")
    
    # KMSSynthesisPermutation plugin for permutations
    # Returns a quantum circuit with size 18 and depth 6
    # but adhering to the linear nearest-neighbor architecture.
    qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("kms", {})]))).run(qc)
    print(f"kms: {qct.size() = }, {qct.depth() = }")
    
    # BasicSynthesisPermutation plugin for permutations
    # Returns a quantum circuit with size 6 and depth 3
    qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("basic", {})]))).run(qc)
    print(f"basic: {qct.size() = }, {qct.depth() = }")
    
    # ACGSynthesisPermutation plugin for permutations
    # Returns a quantum circuit with size 6 and depth 2
    qct = PassManager(HighLevelSynthesis(HLSConfig(permutation=[("acg", {})]))).run(qc)
    print(f"acg: {qct.size() = }, {qct.depth() = }")
  • Aggiunte nuove classi per gli algoritmi Quantum Fisher Information (QFI) e Quantum Geometric Tensor (QGT) che utilizzano primitives, qiskit.algorithms.gradients.QFI e qiskit.algorithms.gradients.LinCombQGTal modulo dei gradienti: qiskit.algorithms.gradients. Ad esempio:

    from qiskit.circuit import QuantumCircuit, Parameter
    from qiskit.algorithms.gradients import LinCombQGT, QFI
    
    estimator = Estimator()
    a, b = Parameter("a"), Parameter("b")
    qc = QuantumCircuit(1)
    qc.h(0)
    qc.rz(a, 0)
    qc.rx(b, 0)
    
    parameter_value = [[np.pi / 4, 0]]
    
    qgt = LinCombQGT(estimator)
    qgt_result = qgt.run([qc], parameter_value).result()
    
    qfi = QFI(qgt)
    qfi_result = qfi.run([qc], parameter_value).result()
  • Aggiunto un nuovo argomento di parola chiave, derivative_type, al costruttore dell'oggetto LinCombEstimatorGradient. Questo argomento accetta un enum DerivativeType che consente di specificare se calcolare solo le parti reali o immaginarie del gradiente.

  • Aggiunta di una nuova opzione circuit_reverse_bits al file di configurazione utente. Consente agli utenti di impostare un booleano per il comportamento predefinito preferito dell'argomento reverse_bits dei cassetti dei circuiti QuantumCircuit.draw() e circuit_drawer(). Ad esempio, aggiungendo una sezione al file di configurazione dell'utente nella posizione predefinita ~/.qiskit/settings.conf con:

    [default]
    circuit_reverse_bits = True

    cambierà l'impostazione predefinita per visualizzare i bit in ordine inverso.

  • Aggiunta di una nuova classe Z2Symmetries a qiskit.quantum_info che viene utilizzata per identificare eventuali simmetrie di Z2Z_2 da un input SparsePauliOp.

  • Aggiunta di una nuova direttiva impulso TimeBlockade. Questa direttiva si comporta in modo quasi identico all'istruzione di ritardo, ma viene rimossa prima dell'esecuzione. Questa direttiva è destinata a essere usata internamente al costruttore di impulsi e aiuta a ScheduleBlock rappresentare istruzioni con intervalli di tempo assoluti. Questo permette al costruttore di impulsi di convertire Schedule in ScheduleBlock, piuttosto che avvolgere con le istruzioni Call istruzioni.

  • Aggiunti algoritmi abilitati alle primitive per l'evoluzione quantistica variazionale che implementano l'interfaccia per l'evoluzione quantistica. La classe qiskit.algorithms.VarQRTE è utilizzata per l'evoluzione del tempo reale e la classe qiskit.algorithms.VarQITE viene utilizzata per l'evoluzione del tempo quantistico immaginario secondo un principio variazionale superato.

    Ogni algoritmo accetta un principio variazionale che implementa l'interfaccia astratta ImaginaryVariationalPrinciple interfaccia astratta. Sono incluse le seguenti implementazioni:

    Ad esempio:

    from qiskit.algorithms import TimeEvolutionProblem, VarQITE
    from qiskit.algorithms.time_evolvers.variational import ImaginaryMcLachlanPrinciple
    from qiskit.circuit.library import EfficientSU2
    from qiskit.quantum_info import SparsePauliOp
    import numpy as np
    
    observable = SparsePauliOp.from_list(
        [
            ("II", 0.2252),
            ("ZZ", 0.5716),
            ("IZ", 0.3435),
            ("ZI", -0.4347),
            ("YY", 0.091),
            ("XX", 0.091),
        ]
    )
    
    ansatz = EfficientSU2(observable.num_qubits, reps=1)
    init_param_values = np.zeros(len(ansatz.parameters))
    for i in range(len(ansatz.parameters)):
        init_param_values[i] = np.pi / 2
    var_principle = ImaginaryMcLachlanPrinciple()
    time = 1
    evolution_problem = TimeEvolutionProblem(observable, time)
    var_qite = VarQITE(ansatz, var_principle, init_param_values)
    evolution_result = var_qite.evolve(evolution_problem)
  • Aggiunte regole per la conversione di XXPlusYYGate e XXMinusYYGate ad altre porte del sito SessionEquivalenceLibrary. Questo permette di eseguire transpile() che punta a un backend o Target che utilizza questi gate.

  • Aggiunti due nuovi backend falsi, FakePrague e FakeSherbrooke al modulo qiskit.providers.fake_provider modulo. FakePrague fornisce un backend con un'istantanea delle proprietà del backend IBM Prague Egret R1 e FakeSherbrooke fornisce un backend con un'istantanea delle proprietà del backend IBM Sherbrooke Eagle R3.

  • È stato aggiunto un nuovo argomento di parola chiave, allow_unknown_parameters, ai comandi ParameterExpression.bind() e ParameterExpression.subs() ai metodi. Se impostato, questo nuovo argomento consente di passare a questi metodi un dizionario contenente parametri sconosciuti senza che venga sollevato un errore. In precedenza, questo sollevava sempre un errore senza che ci fosse modo di disabilitare questo comportamento.

  • L'argomento del metodo BaseEstimator.run() dell'argomento observables del metodo accetta ora un tipo di ingresso str o una sequenza di str , oltre agli altri tipi già accettati. Quando viene utilizzato, il formato della stringa di input deve corrispondere alla rappresentazione della stringa Pauli accettata dal costruttore per gli oggetti Pauli oggetti.

  • Aggiunto un nuovo metodo costruttore QuantumCircuit.from_instructions() che consente di creare un QuantumCircuit da un iterabile di istruzioni. Ad esempio:

    from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit.circuit.quantumcircuitdata import CircuitInstruction
    from qiskit.circuit import Measure
    from qiskit.circuit.library import HGate, CXGate
    
    
    qr = QuantumRegister(2)
    cr = ClassicalRegister(2)
    instructions = [
        CircuitInstruction(HGate(), [qr[0]], []),
        CircuitInstruction(CXGate(), [qr[0], qr[1]], []),
        CircuitInstruction(Measure(), [qr[0]], [cr[0]]),
        CircuitInstruction(Measure(), [qr[1]], [cr[1]]),
    ]
    circuit = QuantumCircuit.from_instructions(instructions)
    circuit.draw("mpl")
    _images/legacy_release_notes-3.png
  • La classe Clifford accetta ora un parametro opzionale per la parola chiave copy nel suo costruttore. Se impostato su False, un StabilizerTable fornito come input non verrà copiato, ma verrà utilizzato direttamente. Questo può avere dei vantaggi in termini di prestazioni, se i dati della tabella non verranno mai modificati con altri mezzi.

  • Le prestazioni di Clifford.compose() è stata notevolmente migliorata per tutti i numeri di qubit. Per operatori di 20 qubit, l'aumento di velocità è dell'ordine di 100 volte.

  • Aggiunta di una nuova funzione di sintesi synth_clifford_layers()per sintetizzare un file Clifford in strati. L'algoritmo si basa su S. Bravyi, D. Maslov, I circuiti senza Hadamard espongono la struttura del gruppo di Clifford, arxiv:2003.09412. Questo decompone il Clifford in 8 strati di porte, tra cui due strati di porte CZ e uno strato di porte CX. Ad esempio, un circuito Clifford a 5 qubit viene scomposto nei seguenti strati:

         ┌─────┐┌─────┐┌────────┐┌─────┐┌─────┐┌─────┐┌─────┐┌────────┐
    q_0:0    ├┤0    ├┤0       ├┤0    ├┤0    ├┤0    ├┤0    ├┤0
         │     ││     ││        ││     ││     ││     ││     ││        │
    q_1:1    ├┤1    ├┤1       ├┤1    ├┤1    ├┤1    ├┤1    ├┤1
         │     ││     ││        ││     ││     ││     ││     ││        │
    q_2:2 S2 ├┤2 CZ ├┤2 CX_dg ├┤2 H2 ├┤2 S1 ├┤2 CZ ├┤2 H1 ├┤2 Pauli ├
         │     ││     ││        ││     ││     ││     ││     ││        │
    q_3:3    ├┤3    ├┤3       ├┤3    ├┤3    ├┤3    ├┤3    ├┤3
         │     ││     ││        ││     ││     ││     ││     ││        │
    q_4:4    ├┤4    ├┤4       ├┤4    ├┤4    ├┤4    ├┤4    ├┤4
         └─────┘└─────┘└────────┘└─────┘└─────┘└─────┘└─────┘└────────┘

    Questo metodo permette di decomporre un Clifford in profondità di 2 qubit 7n+27n+2 per la connettività linear nearest neighbor (LNN).

  • I tipi di ritorno dei metodi power() di diverse classi di gate della libreria standard sono stati aggiornati per restituire oggetti di gate più specifici, in modo da ottenere un output meno dispersivo e più efficiente. Ad esempio, l'esecuzione di power() ora restituisce un'istanza IGate invece di UnitaryGate come avveniva in precedenza.

    L'elenco completo dei tipi di uscita migliorati è il seguente:

  • L'oggetto EquivalenceLibrary è ora rappresentato internamente come un PyDiGraph, questo oggetto grafo sottostante è accessibile dal nuovo attributo graph attributo. Questo attributo è destinato all'uso interno di Qiskit e pertanto deve essere sempre copiato prima di essere modificato dall'utente, per evitare che il grafico di equivalenza interno venga danneggiato.

  • Il metodo Operator.from_circuit() invertirà la permutazione dell'uscita causata dalla fase di routing/swap mapping del transpiler. Per impostazione predefinita, se in un circuito transpilato sono state inserite porte Swap, la matrice di uscita avrà la permutazione invertita, quindi la matrice restituita sarà equivalente al circuito originale non transpilato. Se si desidera disabilitare questo comportamento predefinito, l'argomento della parola chiave ignore_set_layout può essere impostato a True per farlo (oltre al comportamento precedente di ignorare il layout iniziale dalla transpilazione). Se si desidera impostare manualmente un layout finale, è possibile utilizzare il nuovo argomento della parola chiave final_layout per passare un oggetto Layout da utilizzare per la permutazione dell'output.

  • Aggiunto il supporto al passaggio GateDirection per gestire il passaggio simmetrico RXXGate, RYYGate, e RZZGate cancelli. Il passaggio ora gestirà correttamente questi cancelli e invertirà semplicemente l'ordine di qargs senza altre modifiche.

  • È stato aggiunto il supporto per l'utilizzo dell'operatore di esponenziazione Python, **, con gli oggetti Gate è ora supportato. È equivalente all'esecuzione del metodo Gate.power() sull'oggetto.

    Ad esempio:

    from qiskit.circuit.library import XGate
    
    sx = XGate() ** 0.5
  • Aggiunta di una nuova forma di impulso GaussianSquareDrag al qiskit.pulse.library modulo. Questa forma d'impulso è simile a GaussianSquare ma utilizza la forma Drag durante la salita e la discesa. La correzione della forma dell'impulso DRAG può sopprimere parte dello spettro di frequenza dell'ascesa e della caduta dell'impulso, evitando così di eccitare i qubit spettatori quando la loro frequenza è vicina a quella di pilotaggio dell'impulso.

  • Aggiunto un nuovo argomento di parola chiave, method, ai costruttori delle classi FiniteDiffEstimatorGradient e FiniteDiffSamplerGradient e. L'argomento method accetta una stringa per indicare il metodo di calcolo da utilizzare per il gradiente. Esistono tre metodi, disponibili "central", "forward" e "backward". Le definizioni dei metodi sono:

    Metodo
    Calcolo
    "central"f(x+e)f(xe)2e\frac{f(x+e)-f(x-e)}{2e}
    "forward"f(x+e)f(x)e\frac{f(x+e) - f(x)}{e}
    "backward"f(x)f(xe)e\frac{f(x)-f(x-e)}{e}

    dove ee è l'epsilon di offset.

  • Tutte le classi di gradienti in qiskit.algorithms.gradients ora conservano le operazioni non parametrizzate, invece di tentare di srotolarle. Ciò consente di valutare i gradienti su porte personalizzate e opache che le singole primitive possono gestire e di mantenere un livello di astrazione più elevato per la sintesi e la compilazione ottimizzata dopo la costruzione dei circuiti a gradienti.

  • È stato aggiunto un TranslateParameterizedGates per mappare solo le porte parametrizzate di un circuito a una base specificata, lasciando inalterate le porte non parametrizzate. Il passaggio tenta prima lo srotolamento e infine traduce se un gate parametrizzato non può essere ulteriormente srotolato.

  • Il passaggio CollectCliffords è stato ampliato per raccogliere e combinare blocchi di "porte clifford" in oggetti Clifford dove le "porte clifford" possono ora includere anche oggetti di tipo LinearFunction, Clifford, e PauliGate. Ad esempio:

    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import LinearFunction, PauliGate
    from qiskit.quantum_info.operators import Clifford
    from qiskit.transpiler.passes import CollectCliffords
    from qiskit.transpiler import PassManager
    
    # Create a Clifford
    cliff_circuit = QuantumCircuit(2)
    cliff_circuit.cx(0, 1)
    cliff_circuit.h(0)
    cliff = Clifford(cliff_circuit)
    
    # Create a linear function
    lf = LinearFunction([[0, 1], [1, 0]])
    
    # Create a pauli gate
    pauli_gate = PauliGate("XYZ")
    
    # Create a quantum circuit with the above and also simple clifford gates.
    qc = QuantumCircuit(4)
    qc.cz(0, 1)
    qc.append(cliff, [0, 1])
    qc.h(0)
    qc.append(lf, [0, 2])
    qc.append(pauli_gate, [0, 2, 1])
    qc.x(2)
    
    # Run CollectCliffords transpiler pass
    qct = PassManager(CollectCliffords()).run(qc)

    Tutti i cancelli saranno raccolti e combinati in un unico Clifford. Il circuito finale è quindi costituito da un singolo Clifford oggetto.

  • CouplingMap è ora implicitamente iterabile e l'iterazione è identica all'iterazione dell'output di CouplingMap.get_edges(). In altre parole,

    from qiskit.transpiler import CouplingMap
    coupling = CouplingMap.from_line(3)
    list(coupling) == list(coupling.get_edges())

    funzionerà come previsto, così come le altre iterazioni. Si tratta di una comodità puramente sintattica.

  • Aggiunta una nuova funzione synth_cnot_count_full_pmh() che serve a sintetizzare circuiti reversibili lineari per architetture all-to-all utilizzando il metodo di Patel, Markov e Hayes. Questa funzione è identica alla funzione disponibile qiskit.transpiler.synthesis.cnot_synth() , ma ha un nome più descrittivo ed è collocata in modo più logico nell'albero dei pacchetti. Questa nuova funzione sostituisce quella precedente, che probabilmente sarà deprecata in una versione futura.

  • InstructionScheduleMap è stato aggiornato per memorizzare i dati di calibrazione del backend nel formato PulseQobj JSON e invocare la conversione quando si accede ai dati per la prima volta, cioè la conversione pigra. Questo aggiornamento della logica interna migliora drasticamente le prestazioni del caricamento del backend, soprattutto con molte voci di calibrazione.

  • È stato aggiunto il nuovo modulo qiskit.pulse.calibration_entries . Contiene diverse classi wrapper per le diverse rappresentazioni degli orari degli impulsi.

    • ScheduleDef
    • CallableDef
    • PulseQobjDef

    Queste classi implementano i metodi get_schedule() e get_signature() , che restituiscono rispettivamente il programma degli impulsi e i nomi dei parametri da assegnare. Queste classi sono gestite internamente dal sistema InstructionScheduleMap o backend Targete quindi non appaiono in un tipico programma utente.

  • Introdotta una nuova sottoclasse ScalableSymbolicPulse, come sottoclasse di SymbolicPulse. La nuova sottoclasse ha lo stesso comportamento di SymbolicPulsecon la differenza che assume che l'inviluppo dell'impulso includa un prefattore di ampiezza complessa della forma ampei×angle\text{amp} * e^{i \times \text{angle}}. Questa forma dell'inviluppo corrisponde a molti impulsi comuni, compresi tutti gli impulsi della libreria Qiskit Pulse (che in questa versione sono stati convertiti in amp, angle rappresentazione).

    La nuova sottoclasse elimina la natura non univoca della rappresentazione amp, angle e confronta correttamente gli impulsi in base alla loro ampiezza complessa.

  • Aggiunto un nuovo argomento di parola chiave, dtype, al metodo PauliSumOp.from_list() metodo. Se specificato, questo argomento può essere usato per specificare l'indirizzo dtype dell'array numpy allocato per il file SparsePauliOp utilizzato internamente dal costruito PauliSumOp.

  • È stato aggiunto il supporto per l'importazione di programmi OpenQASM 3 in Qiskit. È possibile accedervi più facilmente utilizzando le funzioni qasm3.loads() e qasm3.load(), per caricare un programma direttamente da una stringa e indirettamente da un nome di file, rispettivamente. Ad esempio, ora si può fare:

    from qiskit import qasm3
    
    circuit = qasm3.loads("""
      OPENQASM 3.0;
      include "stdgates.inc";
    
      qubit q;
      qubit[5] qr;
      bit c;
      bit[5] cr;
    
      h q;
      c = measure q;
    
      if (c) {
        h qr[0];
        cx qr[0], qr[1];
        cx qr[0], qr[2];
        cx qr[0], qr[3];
        cx qr[0], qr[4];
      } else {
        h qr[4];
        cx qr[4], qr[3];
        cx qr[4], qr[2];
        cx qr[4], qr[1];
        cx qr[4], qr[0];
      }
      cr = measure qr;
    """)

    Questo caricherà il programma in un'istanza QuantumCircuit nella variabile circuit.

    All'inizio non sono supportate tutte le funzionalità di OpenQASM 3, perché Qiskit non dispone ancora di un modo per rappresentare l'elaborazione classica avanzata dei dati. Le capacità dell'importatore aumenteranno insieme a quelle del resto di Qiskit. L'insieme iniziale di caratteristiche dell'importatore è approssimativamente lo stesso insieme di caratteristiche che verrebbe prodotto dall'esportatore (qasm3.dump() e qasm3.dumps()).

    Si noti che il supporto di Qiskit a OpenQASM 3 non ha lo scopo di fornire una rappresentazione totalmente priva di perdite di dati di QuantumCircuits. Per questo, si può considerare l'uso di qiskit.qpy.

  • Le primitives-classi di gradienti definite dalle classi di gradienti BaseEstimatorGradient e BaseSamplerGradient sono state aggiornate per semplificare l'estensione dell'interfaccia di base. Ci sono tre nuovi metodi interni sovrascrivibili, _preprocess(), _postprocess() e _run_unique(). _preprocess() consente a una sottoclasse di personalizzare i circuiti e i parametri del gradiente di ingresso, _postprocess consente di personalizzare il risultato di uscita e _run_unique consente di calcolare il gradiente di un circuito con parametri unici.

  • Il passaggio SabreLayout ha migliorato notevolmente le prestazioni, essendo stato riscritto in Rust. Come parte di questa riscrittura, il passaggio è stato trasformato da un passaggio di analisi a un passaggio di trasformazione che eseguirà sia il layout che il routing. Ciò è stato fatto non solo per migliorare le prestazioni di esecuzione, ma anche per migliorare la qualità dei risultati. La funzionalità precedente del passaggio come passaggio di analisi può essere mantenuta impostando manualmente l'argomento routing_pass o usando il nuovo argomento skip_routing .

  • Il passo del SabreLayout ha un nuovo argomento per il costruttore layout_trials. Questo argomento viene utilizzato per controllare il numero di semi del generatore di numeri casuali con cui si cercherà di eseguire SabreLayout con. Quando è impostato, l'algoritmo di layout SABRE viene eseguito layout_trials un certo numero di volte e viene selezionato il risultato di qualità migliore (misurato nel minor numero di porte di scambio aggiunte). Queste prove di semina vengono eseguite in parallelo utilizzando il multithreading per ridurre al minimo il potenziale sovraccarico di prestazioni dovuto all'esecuzione di più volte del layout. Per impostazione predefinita, se non viene specificato, il passaggio SabreLayout utilizzerà il numero di CPU fisiche disponibili sul sistema locale.

  • Aggiunte due nuove classi SciPyRealEvolver e SciPyImaginaryEvolver che implementano metodi di integrazione per l'evoluzione temporale di uno stato quantistico. Il valore e la deviazione standard delle osservabili, così come i tempi in cui sono valutate, possono essere interrogati come TimeEvolutionResult.observables e TimeEvolutionResult.times. Ad esempio:

    from qiskit.algorithms.time_evolvers.time_evolution_problem import TimeEvolutionProblem
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.quantum_info.states.statevector import Statevector
    from qiskit.algorithms import SciPyImaginaryEvolver
    
    initial_state = Statevector.from_label("+++++")
    hamiltonian = SparsePauliOp("ZZZZZ")
    evolution_problem = TimeEvolutionProblem(hamiltonian, 100, initial_state, {"Energy":hamiltonian})
    classic_evolver = SciPyImaginaryEvolver(num_timesteps=300)
    result = classic_evolver.evolve(evolution_problem)
    print(result.observables)
  • Aggiunto il SolovayKitaev per eseguire l'algoritmo Solovay-Kitaev per l'approssimazione di unitari a singolo qubit usando un insieme discreto di porte. In combinazione con il traduttore di basi, questo permette di convertire qualsiasi circuito unitario in un insieme di porte discrete universali, che possono essere implementate con tolleranza ai guasti.

    Questo passaggio può essere utilizzato, ad esempio, dopo la compilazione delle porte U e CX:

    from qiskit import transpile
    from qiskit.circuit.library import QFT
    from qiskit.transpiler.passes.synthesis import SolovayKitaev
    
    qft = QFT(3)
    
    # optimize to general 1-qubit unitaries and CX
    transpiled = transpile(qft, basis_gates=["u", "cx"], optimization_level=1)
    
    skd = SolovayKitaev()  # uses T Tdg and H as default basis
    discretized = skd(transpiled)
    
    print(discretized.count_ops())

    La decomposizione può essere utilizzata anche con il plugin di sintesi unitaria, come il metodo "sk" sul passaggio UnitarySynthesis transpiler:

    from qiskit import QuantumCircuit
    from qiskit.quantum_info import Operator
    from qiskit.transpiler.passes import UnitarySynthesis
    
    circuit = QuantumCircuit(1)
    circuit.rx(0.8, 0)
    unitary = Operator(circuit).data
    
    unitary_circ = QuantumCircuit(1)
    unitary_circ.unitary(unitary, [0])
    
    synth = UnitarySynthesis(basis_gates=["h", "s"], method="sk")
    out = synth(unitary_circ)
    
    out.draw('mpl')
    _images/legacy_release_notes-4.png
  • La generazione di circuiti casuali con qiskit.circuit.random.random_circuit() è ora significativamente più veloce per i circuiti di grandi dimensioni.

  • La generazione di circuiti casuali con qiskit.circuit.random.random_circuit() ora produrrà tutte le porte "standard" della libreria di circuiti di Qiskit (qiskit.circuit.library). Questo include due porte a 4-qubit C3SXGate e RC3XGatee i valori consentiti di max_operands sono stati ampliati di conseguenza.

  • Il passo del Optimize1qGatesDecomposition ha un nuovo argomento di parola chiave, target, nel suo costruttore. Questo argomento può essere usato per specificare un Target che rappresenta il target di compilazione. Se utilizzato, sostituisce l'argomento basis per determinare se un'istruzione del circuito è presente nel backend di destinazione.

  • Il passo del UnrollCustomDefinitions ha un nuovo argomento di parola chiave, target, nel suo costruttore. Questo argomento può essere usato per specificare un Target che rappresenta il target di compilazione. Se utilizzato, sostituisce l'argomento basis_gates per determinare se un'istruzione del circuito è presente nel backend di destinazione.

  • Aggiunta la classe ReverseEstimatorGradient per una valutazione classica e veloce dei gradienti del valore di aspettativa basati sulla retropropagazione o sui gradienti a modalità inversa. Questa classe utilizza i vettori di stato e fornisce quindi gradienti esatti, ma scala esponenzialmente in base alle dimensioni del sistema. È stato progettato per un rapido calcolo di riferimento di sistemi di dimensioni ridotte. Può essere utilizzato, ad esempio, come:

    from qiskit.circuit.library import EfficientSU2
    from qiskit.quantum_info import SparsePauliOp
    from qiskit.algorithms.gradients import ReverseEstimatorGradient
    
    observable = SparsePauliOp.from_sparse_list([("ZZ", [0, 1], 1)], num_qubits=10)
    circuit = EfficientSU2(num_qubits=10)
    values = [i / 100 for i in range(circuit.num_parameters)]
    gradient = ReverseEstimatorGradient()
    
    result = gradient.run([circuit], [observable], [values]).result()
  • Aggiunto un nuovo argomento di parola chiave, use_dag , al costruttore della classe OneQubitEulerDecomposer classe. Quando use_dag è impostato su True , l'output del decompositore sarà un oggetto DAGCircuit invece di QuantumCircuit oggetto. Questo è utile per i passaggi di transpiler che usano OneQubitEulerDecomposer (come ad esempio Optimize1qGatesDecomposition), poiché lavorando direttamente con un elemento DAGCircuit evita l'overhead della conversione tra QuantumCircuit e DAGCircuit.

  • Aggiunta la possibilità per i passaggi di analisi di impostare pesi euristici personalizzati per i parametri VF2Layout e VF2PostLayout per i passaggi del transpiler. Se un passaggio di analisi imposta la chiave vf2_avg_error_map nell'insieme di proprietà, il suo valore viene utilizzato per le ponderazioni degli errori invece dei tassi di errore del backend Target (o BackendProperties per BackendV1). Il valore dovrebbe essere un'istanza di ErrorMap , dove ogni valore rappresenta il tasso di errore medio per tutte le operazioni a 1 o 2 qubit su quei qubit. Se un valore è NaN, il bordo corrispondente viene trattato come un bordo ideale (o un qubit per le operazioni di 1q ). Ad esempio, una mappa degli errori creata come:

    from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap
    
    error_map = ErrorMap(3)
    error_map.add_error((0, 0), 0.0024)
    error_map.add_error((0, 1), 0.01)
    error_map.add_error((1, 1), 0.0032)

    descrive un obiettivo a 2 qubit, dove il tasso di errore avg 1q è 0.0024 sul qubit 0 e 0.0032 sul qubit 1, il tasso di errore avg 2q per le porte che operano su (0, 1) è 0.01, e (1, 0) non è supportato dall'obiettivo. Verrà utilizzato per l'attribuzione del punteggio se è impostato per la chiave vf2_avg_error_map nel set di proprietà quando VF2Layout e VF2PostLayout vengono eseguiti. Ad esempio:

    from qiskit.transpiler import AnalysisPass, PassManager, Target
    from qiskit.transpiler.passes import VF2Layout
    from qiskit.transpiler.passes.layout.vf2_utils import ErrorMap
    from qiskit.circuit.library import CZGate, UGate
    from qiskit.circuit import Parameter
    
    class CustomVF2Scoring(AnalysisPass):
      """Set custom score for vf2."""
    
      def run(self, dag):
        error_map = ErrorMap(3)
        error_map.add_error((0, 0), 0.0024)
        error_map.add_error((0, 1), 0.01)
        error_map.add_error((1, 1), 0.0032)
        self.property_set["vf2_avg_error_map"] = error_map
    
    
    target = Target(num_qubits=2)
    target.add_instruction(
        UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
        {(0,): None, (1,): None}
    )
    target.add_instruction(
        CZGate(), {(0, 1): None}
    )
    
    vf2_pass = VF2Layout(target=target, seed=1234568942)
    pm = PassManager([CustomVF2Scoring(), vf2_pass])

    Questo funzionerà VF2Layout con il punteggio personalizzato di error_map per un 2 qubit Target che non contiene alcun tasso di errore.

Note sull'aggiornamento

  • Quando si inizializza una qualsiasi classe di impulsi in qiskit.pulse.library:

    fornendo un argomento amp complesso con un angle finito si otterrà PulseError ora. Ad esempio, invece di chiamare Gaussian(duration=100,sigma=20,amp=0.5j) si dovrebbe usare Gaussian(duration=100,sigma=20,amp=0.5,angle=np.pi/2) . L'inviluppo dell'impulso che prima era definito come amp * ... è a sua volta definito come amp * exp(1j * angle) * .... Questa modifica è stata apportata per supportare meglio gli esperimenti Qiskit in cui l'ampiezza e l'angolo degli impulsi sono calibrati in esperimenti separati.

  • Per Python 3.7 singledispatchmethod è ora una dipendenza. Questo è stato aggiunto per consentire di sfruttare il meccanismo di dispacciamento dei metodi nella libreria standard delle nuove versioni di Python. Se si utilizza Python >= 3.8 non è necessaria alcuna dipendenza aggiuntiva.

  • Il passaggio del transpiler MSBasisDecomposer , precedentemente deprecato e disponibile tramite il modulo qiskit.transpiler.passes è stato rimosso. È stato originariamente deprecato come parte del rilascio di Qiskit Terra 0.16.0 (10-16-2020). Al contrario, il passaggio BasisTranslator per tradurre un circuito in una base appropriata con un RXXGate

  • EquivalenceLibrary che sono inizializzati con l'attributo base non avranno più un riferimento condiviso con l'oggetto EquivalenceLibrary passato. Nelle versioni precedenti, se si modificava base dopo che era stato usato per creare una nuova istanza, entrambe le istanze riflettevano la modifica EquivalenceLibrary entrambe le istanze riflettevano la modifica. Questo non è più il caso e gli aggiornamenti di base non si rifletteranno più nella nuova versione di EquivalenceLibrary. Ad esempio, se si è creata una libreria di equivalenze con:

    import math
    
    from qiskit.circuit import QuantumCircuit
    from qiskit.circuit.library import XGate
    from qiskit.circuit.equivalence import EquivalenceLibrary
    
    original_lib = EquivalenceLibrary()
    qc = QuantumCircuit(1)
    qc.rx(math.pi, 0)
    original_lib.add_equivalence(XGate(), qc)
    new_lib = EquivalenceLibrary(base=original_lib)

    se si è modificato original_lib con:

    import from qiskit.circuit.library import SXGate
    
    qc = QuantumCircuit(1)
    qc.rx(math.pi / 2, 0)
    original_lib.add_equivalence(SXGate(), qc)

    nelle versioni precedenti new_lib includeva anche la definizione di SXGate dopo che era stata aggiunta a original_lib, ma in questa versione non sarà più così. Questa modifica è stata apportata a causa del cambiamento della struttura interna dei dati in un grafo, che ha migliorato le prestazioni della classe EquivalenceLibrary classe, soprattutto quando ci sono più esecuzioni del passaggio di BasisTranslator transpiler.

  • L'argomento di initial_state per il costruttore della classe NLocal classe, insieme all'assegnazione diretta all'atrributo NLocal.initial_state deve essere un QuantumCircuit ora. Il supporto per l'uso di altri tipi per questo argomento e attributo non è più supportato. Il supporto per altri tipi è stato deprecato con il rilascio di Qiskit Terra 0.18.0 (luglio 2021).

  • I cassetti della matrice LaTeX (ad esempio array_to_latex, Statevector.draw('latex')) ora utilizzano la stessa funzione sympy del cassetto ket-convention. Ciò significa che alcuni numeri potrebbero essere visualizzati in modo diverso rispetto alle versioni precedenti, ma che l'esperienza sarà più uniforme. Ad esempio, può identificare nuovi fattori o razionalizzare i denominatori dove prima non lo faceva. L'impostazione predefinita di precision è stata modificata da 5 a 10.

  • La versione del formato QPY emessa da dump() è stata portata alla versione 6. Questa nuova versione del formato è incompatibile con le versioni precedenti e genera un errore quando si cerca di caricarla con un deserializzatore che non è in grado di gestire la versione 6 di QPY. Questa modifica è stata necessaria per supportare l'introduzione di ScalableSymbolicPulse , che è stata gestita aggiungendo un attributo class_name_size all'intestazione degli oggetti scaricati SymbolicPulse degli oggetti scaricati.

  • Il metodo __hash__ per l'opzione SymbolicPulse è stato rimosso. Questo è stato fatto per riflettere la natura mutabile (tramite l'assegnazione dei parametri) di questa classe, che potrebbe dare luogo a errori quando si usa SymbolicPulse in situazioni in cui era richiesto un oggetto hashable. Ciò significa che il metodo incorporato hash() e l'uso di SymbolicPulse come chiavi in dizionari o membri di insiemi non funzionerà più.

  • I nomi delle Register (che include istanze di QuantumRegister e ClassicalRegigster) non sono più vincolati a essere identificatori validi di OpenQASM 2. Questo viene fatto perché la restrizione è eccessivamente rigida, dato che Qiskit diventa sempre più disaccoppiato da OpenQASM 2 e anche le specifiche di OpenQASM 3 non sono così restrittive. Se ci si affida ai registri con nomi di identificatori OpenQASM 2 validi, è necessario iniziare a fare l'escape dei nomi. Una versione semplicistica di questo metodo potrebbe essere realizzata, ad esempio, da:

    import re
    import string
    
    def escape(name: str) -> str:
      out = re.sub(r"\W", "_", name, flags=re.ASCII)
      if not out or out[0] not in string.ascii_lowercase:
        return "reg_" + out
      return out
  • I metodi QuantumCircuitu1 , u2, u3, e le loro varianti controllate cu1, cu3 e mcu1 sono stati rimossi in seguito alla loro deprecazione in Qiskit Terra 0.16.0. Questo per eliminare i nomi dei gate che di solito sono specifici di IBM, a favore dei metodi più generali p(), u(), cp() e cu(). Le classi di porte U1Gate, U2Gate e U3Gate sono ancora disponibili per l'uso con QuantumCircuit.append(), quindi i backend possono continuare a supportare basi con questi gate forniti esplicitamente.

  • I metodi QuantumCircuitcombine e extend sono stati rimossi in seguito alla loro deprecazione in Qiskit Terra 0.17.0. Questo perché queste funzioni sono semplicemente versioni meno potenti di QuantumCircuit.compose()che dovrebbero essere utilizzate al loro posto.

    L'eliminazione di extend significa anche che gli operatori + e += non sono più definiti per QuantumCircuit. Si possono invece utilizzare gli operatori & e &= che utilizzano rispettivamente QuantumCircuit.compose().

  • Le funzioni precedentemente deprecate: qiskit.circuit.measure.measure() e qiskit.circuit.reset.reset() sono state rimosse. Queste funzioni sono state deprecate nella release di Qiskit Terra 0.19.0 (dicembre 2021). Si devono invece usare i simboli QuantumCircuit.measure() e QuantumCircuit.reset() dell'oggetto QuantumCircuit a cui si vuole aggiungere un elemento Measure o Reset all'operazione.

  • I metodi precedentemente deprecati di ParameterView , ereditati da set , sono stati rimossi da ParameterView, il tipo restituito da QuantumCircuit.parameters. I metodi specifici che sono stati rimossi sono:

    • add()
    • difference()
    • difference_update()
    • discard()
    • intersection()
    • intersection_update()
    • issubset()
    • issuperset()
    • symmetric_difference()
    • symmetric_difference_update()
    • union()
    • update()

    insieme al supporto per gli operatori di Python :

    • ixor: ^=
    • isub: -=
    • ior: |=

    Questi sono stati deprecati nella release di Qiskit Terra 0.17.0 (aprile 2021). Il tipo ParameterView è ora un tipo di vista sequenza generale e non supporta più queste operazioni set .

  • I metodi di conversione precedentemente deprecati NetworkX per i metodi di conversione degli elementi DAGCircuit e DAGDependency per le classi : DAGCircuit.to_networkx(), DAGCircuit.from_networkx() e DAGDependency.to_networkx() sono stati rimossi. Questi metodi sono stati originariamente deprecati nell'ambito della release di Qiskit Terra 0.21.0 (giugno 2022). Qiskit utilizza rustworkx come libreria di grafi dalla release qiskit-terra 0.12.0 e da allora la funzione di conversione di NetworkX è stata un processo con perdite. Sono stati aggiunti originariamente in modo che gli utenti potessero sfruttare la libreria di algoritmi NetworkX’s per sfruttare funzionalità non presenti in DAGCircuit e/o rustworkx. Tuttavia, da allora sia DAGCircuit e rustworkx sono maturati e offrono maggiori funzionalità e il convertitore DAGCircuit è strettamente legato a rustworkx per il suo funzionamento e i metodi del convertitore fornivano una funzionalità limitata e pertanto sono stati rimossi.

  • tweedledum è stato rimosso come requisito fondamentale di Qiskit Terra. La funzionalità fornita (qiskit.circuit.classicalfunction) è ancora disponibile se tweedledum viene installato manualmente, ad esempio da:

    pip install tweedledum

    Questa modifica è stata apportata perché lo sviluppo di tweedledum è rallentato al punto da non riuscire a tenere il passo con i nuovi rilasci di Python e del sistema operativo, e stava bloccando alcuni utenti di Qiskit nell'installazione di Qiskit.

  • I controllori opzionali pigri HAS_MATPLOTLIB, HAS_PIL, HAS_PYLATEX e HAS_PDFTOCAIRO non sono più esposti da qiskit.visualization, essendo stati deprecati in Qiskit Terra 0.21. La posizione canonica di questi (e di molti altri controllori pigri) è qiskit.utils.optionalse tutti e quattro gli oggetti possono essere trovati lì.

  • L'argomento gate , precedentemente deprecato, del costruttore del passaggio di transpiler Decompose e il suo attributo corrispondente Decompose.gate sono stati rimossi. L'argomento e l'attributo sono stati deprecati con la release di Qiskit Terra 0.19.0 (dicembre 2021). Si deve invece utilizzare l'argomento gates_to_decompose per il costruttore insieme all'attributo Decompose.gates_to_decompose . L'argomento e l'attributo gates_to_decompose dovrebbero funzionare allo stesso modo, ma hanno un nome più esplicito e consentono di specificare elenchi di porte invece di supportare una sola porta.

  • L'argomento label , precedentemente deprecato, per il costruttore dell'oggetto MCMT e MCMTVChain è stato rimosso. È stato deprecato a partire dal rilascio di Qiskit Terra 0.19.0 (dicembre 2021). L'uso dell'argomento label su queste classi ha avuto un comportamento non definito, in quanto sono sottoclassi di QuantumCircuit invece che di Instruction. In questo modo, l'etichetta assegnata verrebbe generalmente ignorata. Se è necessario assegnare un label a un'istanza di MCMT o MCMTVChain è necessario convertirli in un'istanza di Gate con to_gate() e poi assegnare l'etichetta desiderata all'attributo label attributo. Ad esempio:

    from qiskit.circuit.library import MCMT, XGate
    
    mcmt_circuit = MCMT(XGate(), 3, 2)
    mcmt_gate = mcmt_circuit.to_gate()
    mcmt_gate.label = "Custom MCMT X"
  • La dipendenza da retworkx per Qiskit è stata rimossa e sostituita dalla libreria rustworkx . Si tratta degli stessi pacchetti, ma rustworkx è il nuovo nome di retworkx , che è stato rinominato nell'ambito del rilascio combinato di 0.12.0. Se in precedenza si utilizzava retworkx 0.12.0 con Qiskit, allora si è già installato rustworkx (retworkx 0.12.0 era solo uno shim di reindirizzamento per la retrocompatibilità). Questa modifica è stata apportata per migrare al nuovo nome del pacchetto che sarà l'unico supportato in futuro.

  • Il comportamento predefinito del SabreLayout è cambiato. Il passaggio non è più un AnalysisPass e per impostazione predefinita calcolerà il layout iniziale, lo applicherà al circuito ed eseguirà internamente anche SabreSwap internamente e applica la mappatura degli swap e imposta la proprietà final_layout con la permutazione causata dagli inserimenti degli swap. Questo significa che per gli utenti che eseguono SabreLayout come parte di un sistema personalizzato PassManager dovranno modificare il gestore di pass per tenere conto di questo (a meno che non abbiano impostato l'argomento routing_pass per SabreLayout). Questa modifica è stata apportata nell'interesse di migliorare la qualità dell'output SabreLayout ora eseguirà più prove di seme in parallelo e per calcolare quale seme fornisce i risultati migliori deve eseguire sia il layout che l'instradamento insieme. Ci sono tre modi per regolare l'utilizzo nel gestore di pass personalizzati. Il primo è quello di evitare di usare l'incorporazione nel gestore dei passaggi di preset. Se in precedenza si eseguiva qualcosa come:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.preset_passmanagers import common
    from qiskit.transpiler.passes.SabreLayout
    
    pm = PassManager()
    pm.append(SabreLayout(coupling_map)
    pm += common.generate_embed_passmanager(coupling_map)

    per calcolare il layout e poi applicarlo (che in genere era seguito dall'instradamento), è possibile regolare l'utilizzo in modo che sia semplicemente così:

    from qiskit.transpiler import PassManager
    from qiskit.transpiler.preset_passmanagers import common
    from qiskit.transpiler.passes.SabreLayout
    
    pm = PassManager()
    pm.append(SabreLayout(coupling_map)

    come SabreLayout applicherà il layout e non sarà più necessaria la fase di incorporamento. In alternativa, è possibile specificare l'argomento routing_pass , che ripristina il comportamento precedente SabreLayout al suo comportamento precedente. Per esempio, se si vuole eseguire SabreLayout come veniva eseguito nelle versioni precedenti, si può fare qualcosa di simile:

    from qiskit.transpiler.passes import SabreSwap, SabreLayout
    routing_pass = SabreSwap(
        coupling_map, "decay", seed=seed, fake_run=True
    )
    layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)

    che avrà SabreLayout eseguito come un passaggio di analisi e impostare solo il set di proprietà layout . L'approccio finale consiste nello sfruttare l'argomento skip_routing su SabreLayout, quando questo argomento è impostato su True salta l'applicazione del layout trovato e l'inserimento delle porte di scambio dal routing. Tuttavia, questo comporta una penalizzazione in termini di tempo di esecuzione, poiché SabreLayout continua a calcolare l'instradamento e non utilizza questi dati. I primi due approcci descritti non comportano costi aggiuntivi.

  • I layout calcolati dal passaggio SabreLayout (quando viene eseguito senza l'argomento routing_pass ) con un valore di seme fisso può cambiare rispetto alle versioni precedenti. Ciò è dovuto all'utilizzo di un nuovo generatore di numeri casuali nell'ambito della riscrittura del passaggio SabreLayout in Rust, che ha migliorato significativamente le prestazioni. Se si desidera avere un risultato costante, è possibile eseguire il passaggio in una versione precedente di Qiskit e sfruttare la funzione qiskit.qpy per salvare il circuito e poi caricarlo con la versione attuale. In alternativa, è possibile impostare esplicitamente l'argomento routing_pass a un'istanza di SabreSwap per rispecchiare il comportamento precedente di SabreLayout:

    from qiskit.transpiler.passes import SabreSwap, SabreLayout
    
    
    routing_pass = SabreSwap(
        coupling_map, "decay", seed=seed, fake_run=True
    )
    layout_pass = SabreLayout(coupling_map, routing_pass=routing_pass, seed=seed)

    che rispecchierà il comportamento del passaggio nella versione precedente. Si noti che se si utilizzava l'argomento swap_trials su SabreLayout nelle versioni precedenti, quando si modifica l'utilizzo in questa forma, è necessario impostare l'argomento trials sul costruttore SabreSwap se si vuole mantenere l'output precedente con un seme fisso.

  • Il circuito esatto restituito da qiskit.circuit.random.random_circuit per un dato seme è cambiato. Ciò è dovuto a miglioramenti dell'efficienza nella generazione interna di numeri casuali per la funzione.

  • La versione richiesta per il pacchetto di funzioni opzionali qiskit-toqm, installabile tramite pip install qiskit-terra[toqm], è stata aggiornata dalla versione 0.0.4 a 0.1.0. Per utilizzare il metodo di instradamento toqm con transpile() è necessario utilizzare qiskit-toqm versione 0.1.0 o più recente. Le versioni precedenti non sono più rilevabili dal transpiler.

  • L'output QuasiDistribution del metodo Sampler.run è stato aggiornato per filtrare gli stati con probabilità pari a zero. Ora, se uno stato valido non è presente nell'output del dizionario, si può assumere che abbia una probabilità pari a 0. In precedenza, tutti i risultati possibili per un determinato numero di bit (ad esempio, per un risultato a 3 bit 000, 001, 010, 011, 100, 101, 110, e 111) anche se la probabilità di un determinato stato era pari a 0. Questa modifica è stata apportata per ridurre le dimensioni dell'output, poiché per un numero maggiore di bit le dimensioni dell'output potevano essere piuttosto grandi. Inoltre, il filtraggio dei risultati a probabilità zero rende l'output coerente con altre implementazioni di BaseSampler.

  • Il comportamento del costruttore di impulsi quando viene chiamato un elemento Schedule è stato aggiornato. I programmi chiamati vengono convertiti internamente in ScheduleBlock e ora il meccanismo di riferimento viene sempre applicato invece di aggiungere i programmi avvolti dall'istruzione Call . Si noti che il blocco convertito non recupera necessariamente il contesto di allineamento originale. Si tratta semplicemente di una sequenza allineata ASAP di istruzioni a impulsi con intervalli di tempo assoluti. Si tratta di un aggiornamento della rappresentazione interna dei programmi di impulsi chiamati e quindi di nessuna modifica dell'API. Tuttavia la Call istruzione e Schedule non compaiono più nel programma di impulsi del costruttore. Questa modifica garantisce che i blocchi di programma generati siano sempre compatibili con QPY. Se si filtrano le istruzioni del programma di output in base a Callè possibile accedere al campo ScheduleBlock.references per recuperare il programma chiamato.

  • RZXCalibrationBuilder e RZXCalibrationBuilderNoEcho sono stati aggiornati per generare ScheduleBlock. Questa modifica garantisce che i circuiti transpilati siano sempre compatibili con QPY. Se si utilizza direttamente il metodo rescale_cr_inst()da un altro programma o da una sottoclasse di pass per ridimensionare l'impulso di risonanza trasversale del dispositivo, ora questo metodo è stato trasformato in una macro del costruttore di impulsi ed è necessario utilizzarlo nel contesto del costruttore di impulsi per adottare la nuova versione. La chiamata al metodo inietta un'istruzione di riproduzione nel programma dell'impulso contestuale, invece di restituire un'istruzione con l'impulso allungato Play con l'impulso allungato.

Note di deprecazione

  • Il supporto per l'esecuzione di Qiskit con Python 3.7 è stato deprecato e sarà rimosso nella release qiskit-terra 0.25.0. Ciò significa che a partire dalla versione 0.25.0 sarà necessario aggiornare la versione Python in uso a Python 3.8 o superiore.

  • La classe LinearFunctionsSynthesis è ora deprecata e sarà rimossa in una prossima versione. È stata sostituita dalla più generale classe HighLevelSynthesis che dovrebbe essere utilizzata al suo posto. Per esempio, è possibile istanziare un'istanza di HighLevelSynthesis che si comporterà come LinearFunctionSynthesis con:

    from qiskit.transpiler.passes import HighLevelSynthesis
    from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig
    
    HighLevelSynthesis(
        HLSConfig(
            linear_function=[("default", {})],
            use_default_on_unspecified=False,
        )
    )
  • Il supporto per il passaggio di liste di valori di argomenti alla funzione transpile() è deprecato e sarà rimosso nella versione 0.25.0. Questo viene fatto per ridurre notevolmente l'overhead dell'esecuzione parallela per il transpiling di più circuiti contemporaneamente. Se si utilizza questa funzionalità al momento, è possibile chiamare il comando transpile() più volte. Ad esempio, se in precedenza si faceva qualcosa come:

    from qiskit.transpiler import CouplingMap
    from qiskit import QuantumCircuit
    from qiskit import transpile
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)]
    results = transpile([qc] * 6, coupling_map=cmaps)

    invece si dovrebbe eseguire qualcosa come:

    from itertools import cycle
    from qiskit.transpiler import CouplingMap
    from qiskit import QuantumCircuit
    from qiskit import transpile
    
    qc = QuantumCircuit(2)
    qc.h(0)
    qc.cx(0, 1)
    qc.measure_all()
    cmaps = [CouplingMap.from_heavy_hex(d) for d in range(3, 15, 2)]
    
    results = []
    for qc, cmap in zip(cycle([qc]), cmaps):
        results.append(transpile(qc, coupling_map=cmap))

    Si può anche sfruttare parallel_map() o multiprocessing dalla libreria standard Python, se si vuole eseguire il tutto in parallelo.

  • La versione legacy del cassetto degli impulsi presente in qiskit.visualization.pulse è stata deprecata e sarà rimossa in una versione futura. Questo include le classi ScheduleDrawer e :class`WaveformDrawer`. Questo modulo è stato sostituito dal cassetto qiskit.visualization.pulse_v2 e l'API tipica dell'utente pulse_drawer() e PulseBlock.draw() sono già aggiornati internamente per utilizzare qiskit.visualization.pulse_v2.

  • Il metodo pulse.Instruction.draw() è stato deprecato e sarà rimosso in una versione futura. La necessità di questo metodo è stata superata dal cassetto qiskit.visualization.pulse_v2 , che non richiede che gli oggetti Instrucion abbiano un proprio metodo di disegno. Se si ha bisogno di disegnare un'istruzione a impulsi, si dovrebbe utilizzare l'opzione pulse_drawer() al suo posto.

  • L'importazione qiskit.circuit.qpy_serialization è deprecata, poiché QPY è stato promosso al livello superiore. Si dovrebbero importare gli stessi oggetti da qiskit.qpy invece. Il vecchio percorso sarà rimosso in un futuro di Qiskit Terra.

  • L'oggetto qiskit.IBMQ è deprecato. Questo oggetto alias reindirizza pigramente l'accesso agli attributi a qiskit.providers.ibmq.IBMQ. Poiché il pacchetto qiskit-ibmq-provider è stato sostituito dal pacchetto qiskit-ibm-provider , che mantiene il proprio spazio dei nomi, questo alias non è più rilevante con il nuovo pacchetto. Se ci si affidava all'alias qiskit.IBMQ , si dovrebbe aggiornare l'uso per utilizzare direttamente qiskit.providers.ibmq.IBMQ (e considerare anche la migrazione a qiskit-ibm-provider, vedere la guida alla migrazione per maggiori dettagli).

  • Diversi metodi pubblici dei convertitori di Qobj sono stati deprecati e in una prossima versione non saranno più direttamente richiamabili. L'elenco dei metodi è:

    In InstructionToQobjConverter,

    • convert_acquire()
    • convert_bundled_acquires()
    • convert_set_frequency()
    • convert_shift_frequency()
    • convert_set_phase()
    • convert_shift_phase()
    • convert_delay()
    • convert_play()
    • convert_snapshot()

    In QobjToInstructionConverter,

    • convert_acquire()
    • convert_set_phase()
    • convert_shift_phase()
    • convert_set_frequency()
    • convert_shift_frequency()
    • convert_delay()
    • bind_pulse()
    • convert_parametric()
    • convert_snapshot()

    Invece di richiamare direttamente uno di questi metodi, essi verranno selezionati implicitamente quando viene richiamata direttamente un'istanza del convertitore. Ad esempio:

    converter = QobjToInstructionConverter()
    converter(pulse_qobj)
  • Le funzioni qiskit.visualization.state_visualization.num_to_latex_ket() e qiskit.visualization.state_visualization.num_to_latex_terms() sono state deprecate e saranno rimosse in una prossima versione. Queste funzioni sono state utilizzate principalmente internamente dall'uscita LaTeX di Statevector.draw() e DensityMatrix.draw() che non utilizza più queste funzioni e si appoggia invece a sympy. Se si utilizzavano queste funzioni, si dovrebbe fare a meno di usare le funzioni nsimplify() latex() di Sympy.

  • Il metodo Register.qasm() è deprecato e sarà rimosso in una versione futura. Questo metodo si trova nelle sottoclassi QuantumRegister e ClassicalRegister. La deprecazione è dovuta al fatto che il metodo qasm() promuove una visione errata della parte responsabile della conversione sicura in OpenQASM 2; un singolo oggetto da solo non ha il contesto per fornire una conversione sicura, come ad esempio se il suo nome si scontra dopo l'escape per produrre un identificatore valido.

  • L'espressione regolare variabile di classe Register.name_format è deprecata e sarà rimossa in una prossima versione. I nomi dei registri possono ora essere qualsiasi stringa valida di Python, quindi l'espressione regolare non serve più.

  • Le funzioni qiskit.quantum_info.synthesis.decompose_clifford() e qiskit.quantum_info.synthesis.decompose_cnot_dihedral() sono deprecate e saranno rimosse in una versione futura. Sono sostituite dalle due funzioni qiskit.synthesis.synth_clifford_full() e qiskit.synthesis.synth_cnotdihedral_full() rispettivamente.

Correzioni di bug

  • È stato risolto un problema nel metodo PauliOp.adjoint() che restituiva il valore corretto per le paoli con coefficienti complessi, ad esempio: PauliOp(Pauli("iX")). Corretto #9433.

  • Corretto un problema con gli algoritmi di stima dell'ampiezza nel modulo qiskit.algorithms.amplitude_estimators (vedere amplitude_estimators) per l'utilizzo con primitive costruite a partire dalla primitiva astratta BaseSampler (come ad esempio Sampler e BackendSampler). In precedenza, i risultati della misurazione venivano estesi a un numero di bit superiore a quello effettivamente misurato, il che, per gli oracoli con più di un qubit, portava a potenziali errori nella rilevazione degli stati quantistici "buoni" per gli oracoli.

  • È stato risolto un problema a causa del quale i metodi QuantumCircuit.add_calibrations() e DAGCircuit.add_calibrations() non corrispondevano nel comportamento della logica di formattazione dei parametri. In precedenza, DAGCircuit.add_calibrations() cercava di lanciare ogni parametro in float, mentre QuantumCircuit.add_calibrations() utilizzava i parametri così come sono. Questo potrebbe causare un errore durante l'esecuzione transpile() su un sistema QuantumCircuit con gate a impulsi, poiché i parametri delle calibrazioni potrebbero essere mantenuti come oggetti ParameterExpresion .

  • Corretto un problema di deserializzazione nel file (qiskit.qpy) load() in cui i circuiti contenenti porte di classe MCXGate, MCXGrayCode, MCXRecursive, e MCXVChain non verrebbero deserializzati. Corretto #9390.

  • È stato risolto un problema in TensoredOp.to_matrix() in cui il coefficiente globale dell'operatore veniva moltiplicato alla matrice finale più di una volta. Ora, il coefficiente globale viene applicato correttamente, indipendentemente dal numero di operatori o stati tensurati. Corretto #9398.

  • L'output del metodo run() della classe BackendSampler imposta ora gli attributi shots e stddev_upper_bound della classe restituita QuasiDistribution. In precedenza questi attributi mancavano e ciò impediva alcune post-elaborazioni dell'output. Corretto #9311

  • Il metodo di esportazione di OpenQASM 2 QuantumCircuit.qasm() emette ora, per impostazione predefinita, numeri in virgola mobile di maggiore precisione per i parametri del gate. Inoltre, viene utilizzato un limite più stretto ( 1e121e-12 invece di 1e61e-6 ) per verificare se un dato parametro è vicino a una frazione/potenza di π\pi. Corretto #7166.

  • Corretto il supporto nel modulo primitives per l'esecuzione di QuantumCircuit con istruzioni di flusso di controllo (ad es. IfElseOp). In precedenza, le classi base BaseSampler e BaseEstimator non potevano normalizzare correttamente tali circuiti. Tuttavia, l'esecuzione di questi circuiti dipende dalla particolare implementazione delle primitive che supportano le istruzioni del flusso di controllo. Si tratta solo di un supporto fisso per consentire a una particolare implementazione di BaseSampler o BaseEstimator di utilizzare le istruzioni di flusso di controllo.

  • È stato risolto un problema con il metodo PauliOp.matmul() che restituiva risultati errati con iI. Corretto #8680.

  • È stato risolto un problema con la classe Approximate Quantum Compiler (AQC) che causava la restituzione di un circuito errato quando l'unitario in ingresso aveva un determinante di -1. Corretto #9327

  • Corretto un problema con il metodo QuantumCircuit.compose() che rifiutava erroneamente specificatori validi di qubit o clbit. Questo problema è stato risolto in modo che il metodo accetti ora lo stesso insieme di specificatori qubit e clbit di altri metodi QuantumCircuit come ad esempio append(). Corretto #8691.

  • È stato risolto un problema con il metodo QuantumCircuit.compose() in cui il metodo mappava erroneamente i registri nelle condizioni del circuito dato ai registri completi della base. In precedenza, la mappatura era molto imprecisa; i bit utilizzati all'interno di ogni condizione non erano soggetti alla mappatura e si cercava invece di trovare il registro corrispondente in modo impreciso. Questo potrebbe anche portare a espandere una condizione su un registro più piccolo in un registro più grande, il che non è una trasformazione valida. Ora, una condizione su un singolo bit o su un registro sarà composta in modo da riguardare esattamente i bit definiti dall'argomento clbits . Se necessario, al circuito di base verrà aggiunto un nuovo registro di aliasing. Corretto #6583.

  • È stato risolto un problema con la funzione transpile() quando viene eseguita con optimization_level impostato su 1, 2 o 3 e nessun argomento backend, basis_gates o target specificato. Se il circuito di ingresso presentasse delle serie di porte a qubit singolo che potrebbero essere semplificate, il circuito di uscita non sarebbe il più ottimizzato possibile, poiché tali serie di porte a qubit singolo non sarebbero state eliminate. Questo problema poteva essere corretto in precedenza specificando gli argomenti backend, basis_gates, o target nella chiamata transpile() ma ora l'output sarà il più semplificato possibile senza conoscere i gate di destinazione consentiti. Corretto #9217

  • È stato risolto un problema con la funzione transpile() quando viene eseguita con optimization_level=3 e nessun argomento backend, basis_gates o target specificato. Se il circuito di ingresso contenesse un qualsiasi blocco di 2 qubit equivalente a una matrice identità, il circuito di uscita non sarebbe ottimizzato al meglio e conterrebbe ancora quel blocco identità. Questo problema poteva essere corretto in precedenza specificando gli argomenti backend, basis_gates, o target nella chiamata transpile() ma ora l'output sarà il più semplificato possibile senza conoscere i gate di destinazione consentiti. Corretto #9217

  • È stato risolto un problema con LinCombSamplerGradient che potenzialmente sollevava un errore quando veniva eseguito con la classe Sampler di qiskit-aer.

  • Corretto un problema con NumPyEigensolver e per estensione NumPyMinimumEigensolver in cui la risoluzione di sottoclassi di BaseOperator diverse da Operator causava un errore.

  • È stato risolto un problema nell'output dei metadati di primitives in cui l'elenco veniva copiato per riferimento e tutti gli elementi venivano aggiornati con lo stesso valore a ogni iterazione.

  • È stato risolto un problema con QobjToInstructionConverter quando vengono chiamati più backend e questi hanno accidentalmente lo stesso nome di impulso nella libreria di impulsi. Si trattava di un caso limite che poteva verificarsi solo quando un'istanza del convertitore veniva riutilizzata su più backend (non si trattava di un modello di utilizzo tipico).

  • È stato risolto un problema con la classe PVQD a causa del quale la funzione di perdita non era in grado di squadrare la fedeltà. Il problema è stato risolto in modo che la funzione di perdita corrisponda alla definizione dell'algoritmo originale.

  • Corretto un bug in QPY (qiskit.qpy) per cui i circuiti contenenti registri i cui bit si trovavano nel circuito dopo i bit sciolti non riuscivano a essere deserializzati. Vedere il n. 9094.

  • La classe TwoQubitWeylDecomposition è ora compatibile con il protocollo pickle . In precedenza, non riusciva a deserializzare e sollevava un TypeError. Vedere il n. 7312.

  • È stato risolto un problema con il metodo LocalReadoutMitigator.quasi_probabilities() in cui l'argomento shots non veniva utilizzato. Viene ora utilizzato per impostare il numero di colpi nell'oggetto di ritorno.

  • Corretta una regressione nella costruzione di Clifford da QuantumCircuits che contiene altri oggetti Clifford oggetti.

  • Corretto un problema con la classe TwoQubitWeylDecomposition (e le sue sottoclassi) per consentire alla libreria standard Python pickle di serializzare queste classi. Questo ha parzialmente risolto il problema #7312

  • QuantumCircuit.qasm() ora eviterà correttamente i nomi di gate e registri che si scontrano con parole chiave riservate di OpenQASM 2. Correzioni #5043.

  • È stato risolto un problema nel programma RZXCalibrationBuilder in cui la sequenza di impulsi ECR era disallineata. Corretto #9013.

  • È stato risolto un problema con il programma pulse_drawer() per cui in alcuni casi la visualizzazione dell'output ometteva alcuni dei canali di una pianificazione. Corretto #8981.

Aer 0.11.2

Nessuna modifica

IBM Q Fornitore 0.19.2

Nessuna modifica

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