Note di rilascio di Qiskit 0.35
0.35.0
Terra 0.20.0
Preludio
I punti salienti della release Qiskit Terra 0.20.0 sono:
- L'introduzione di moduli multithread scritti in Rust per accelerare le prestazioni di alcune porzioni di Qiskit Terra e migliorare la scalabilità con un numero maggiore di qubit. Tuttavia, quando si costruisce Qiskit dai sorgenti è ora necessario un compilatore Rust.
- Maggiore supporto nativo per lavorare con gli elementi
Targetnel transpiler. Diversi passaggi supportano ora il lavoro diretto con un oggettoTargetil che rende il transpiler più robusto nei tipi di backend a cui può rivolgersi. - L'introduzione del
qiskit.primitivesmodulo. Queste API forniscono diversi livelli di astrazione per calcolare gli output di interesse daQuantumCircuite utilizzare i backend. Ad esempio, l'interfacciaBaseEstimatordefinisce un'interfaccia astratta per stimare il valore di aspettativa di un'osservabile. Questo può essere utilizzato per costruire algoritmi e applicazioni di livello superiore che si basano sulla stima dei valori di aspettativa senza doversi preoccupare dell'implementazione del calcolo del valore di aspettativa. Questo disaccoppiamento consente all'implementazione di migliorare la velocità e la qualità, pur aderendo all'interfaccia astratta definita. Allo stesso modo, il sistemaBaseSamplercalcola distribuzioni di quasi-probabilità dalle misure dei circuiti. Altre primitive saranno introdotte in futuro.
Questa versione non supporta più Python 3.6. Con questa versione, sono necessari i siti da Python 3.7 a Python 3.10.
Nuove funzioni
-
Aggiunto un nuovo metodo costruttore per la classe
Operatorclasse,Operator.from_circuit()per creare un nuovoOperatorda un oggettoQuantumCircuit. Mentre questo era possibile normalmente usando il costruttore predefinito, il metodoOperator.from_circuit()fornisce ulteriori opzioni per regolare la creazione dell'operatore. In primo luogo questo permette di permutare l'ordine dei qubit in base a un setLayout. Ad esempio:from qiskit.circuit import QuantumCircuit from qiskit import transpile from qiskit.transpiler import CouplingMap from qiskit.quantum_info import Operator circuit = QuantumCircuit(3) circuit.h(0) circuit.cx(0, 1) circuit.cx(1, 2) cmap = CouplingMap.from_line(3) out_circuit = transpile(circuit, initial_layout=[2, 1, 0], coupling_map=cmap) operator = Operator.from_circuit(out_circuit)la variabile
operatoravrà i qubit permutati in base alla disposizione, in modo da essere identica a quella restituita daOperator(circuit)prima della transpilazione. -
Aggiunto un nuovo metodo
DAGCircuit.copy_empty_like()alla classeDAGCircuitdella classe. Questo metodo viene utilizzato per creare una nuova copia di un oggetto esistente con la stessa struttura maDAGCircuitesistente con la stessa struttura, ma vuoto di istruzioni. Questo metodo è uguale al metodo privato_copy_circuit_metadata(), ma ora fa parte dell'API pubblica della classe. -
Le classi fake backend e fake provider, precedentemente disponibili in
qiskit.test.mock, sono ora accessibili anche in un nuovo modulo:qiskit.providers.fake_provider. Questo nuovo modulo sostituisce il precedenteqiskit.test.mockche sarà deprecato in Qiskit 0.21.0. -
Aggiunta di una nuova classe di gate,
LinearFunctionche codifica in modo efficiente una funzione lineare (cioè una funzione che può essere rappresentata da una sequenza diCXGateeSwapGategate). -
Aggiunto un nuovo passaggio del transpiler
CollectLinearFunctionsche raccoglie i blocchi di elementi consecutiviCXGateeSwapGatein un circuito, e sostituisce ogni blocco con unaLinearFunctiongate. -
Aggiunto un nuovo passaggio del transpiler
LinearFunctionsSynthesische sintetizza qualsiasiLinearFunctiongates utilizzando l' algoritmo di Patel-Markov-Hayes. In combinazione con il passaggioCollectLinearFunctionsconsente di raccogliere blocchi di dati consecutivi e diCXGateeSwapGatein un circuito e di risintetizzarli utilizzando l' algoritmo di Patel-Markov-Hayes. -
Aggiunto un nuovo passaggio del transpiler
LinearFunctionsToPermutationsche sostituisce un elementoLinearFunctioncon unPermutationquando possibile. -
FlowController(come ad esempioConditionalController) possono ora essere annidate all'interno di un'istanzaPassManagerquando si usa il metodoPassManager.append()quando si utilizza il metodo Ciò consente di utilizzare una logica annidata per controllare l'esecuzione dei passaggi nel filePassManager. Ad esempio:from qiskit.transpiler import ConditionalController, PassManager from qiskit.transpiler.passes import ( BasisTranslator, GatesInBasis, Optimize1qGatesDecomposition, FixedPoint, Depth ) from qiskit.circuit.equivalence_library import SessionEquivalenceLibrary as sel pm = PassManager() def opt_control(property_set): return not property_set["depth_fixed_point"] def unroll_condition(property_set): return not property_set["all_gates_in_basis"] depth_check = [Depth(), FixedPoint("depth")] opt = [Optimize1qGatesDecomposition(['rx', 'ry', 'rz', 'rxx'])] unroll = [BasisTranslator(sel, ['rx', 'ry', 'rz', 'rxx'])] unroll_check = [GatesInBasis(['rx', 'ry', 'rz', 'rxx'])] flow_unroll = [ConditionalController(unroll, condition=unroll_condition)] pm.append(depth_check + opt + unroll_check + flow_unroll, do_while=opt_control)L'oggetto
pmPassManagereseguirà il passaggioBasisTranslator(nel passounroll) in ogni iterazione del ciclo seunroll_conditionè soddisfatta. -
I costruttori per le classi
ZFeatureMapeZZFeatureMaphanno un nuovo argomento di parola chiaveparameter_prefix. Questo nuovo argomento viene utilizzato per impostare il prefisso dei parametri del circuito di codifica dei dati. Ad esempio:from qiskit.circuit.library import ZFeatureMap feature_map = ZFeatureMap(feature_dimension=4, parameter_prefix="my_prefix") feature_map.decompose().draw('mpl')il circuito generato
ZFeatureMaptutti i suoi parametri interni sono preceduti dal prefisso"my_prefix". -
Il
TemplateOptimizationpuò ora lavorare con oggettiGateche hannoParameterExpressionparametri. Un esempio illustrativo dell'uso diParameters conTemplateOptimizationè il seguente:from qiskit import QuantumCircuit, transpile, schedule from qiskit.circuit import Parameter from qiskit.transpiler import PassManager from qiskit.transpiler.passes import TemplateOptimization # New contributions to the template optimization from qiskit.transpiler.passes.calibration import RZXCalibrationBuilder, rzx_templates from qiskit.test.mock import FakeCasablanca backend = FakeCasablanca() phi = Parameter('φ') qc = QuantumCircuit(2) qc.cx(0,1) qc.p(2*phi, 1) qc.cx(0,1) print('Original circuit:') print(qc) pass_ = TemplateOptimization(**rzx_templates.rzx_templates(['zz2'])) qc_cz = PassManager(pass_).run(qc) print('ZX based circuit:') print(qc_cz) # Add the calibrations pass_ = RZXCalibrationBuilder(backend) cal_qc = PassManager(pass_).run(qc_cz.bind_parameters({phi: 0.12})) # Transpile to the backend basis gates cal_qct = transpile(cal_qc, backend) qct = transpile(qc.bind_parameters({phi: 0.12}), backend) # Compare the schedule durations print('Duration of schedule with the calibration:') print(schedule(cal_qct, backend).duration) print('Duration of standard with two CNOT gates:') print(schedule(qct, backend).duration)output
Original circuit: q_0: ──■──────────────■── ┌─┴─┐┌────────┐┌─┴─┐ q_1: ┤ X ├┤ P(2*φ) ├┤ X ├ └───┘└────────┘└───┘ ZX based circuit: ┌─────────────┐ » q_0: ────────────────────────────────────┤0 ├────────────» ┌──────────┐┌──────────┐┌──────────┐│ Rzx(2.0*φ) │┌──────────┐» q_1: ┤ Rz(-π/2) ├┤ Rx(-π/2) ├┤ Rz(-π/2) ├┤1 ├┤ Rx(-2*φ) ├» └──────────┘└──────────┘└──────────┘└─────────────┘└──────────┘» « «q_0: ──────────────────────────────────────────────── « ┌──────────┐┌──────────┐┌──────────┐┌──────────┐ «q_1: ┤ Rz(-π/2) ├┤ Rx(-π/2) ├┤ Rz(-π/2) ├┤ P(2.0*φ) ├ « └──────────┘└──────────┘└──────────┘└──────────┘ Duration of schedule with the calibration: 1600 Duration of standard with two CNOT gates: 6848 -
Il
DAGOpNode,DAGInNodeeDAGOutNodedefiniscono ora un metodo personalizzato__repr__che produce una rappresentazione. Secondo la documentazione di Python, l'output è una rappresentazione di stringa che è approssimativamente equivalente alla stringa Python usata per creare un oggetto equivalente. -
Le prestazioni del metodo
SparsePauliOp.simplify()sono state notevolmente migliorate sostituendo l'uso dinumpy.uniqueper calcolare gli elementi unici di un array con una nuova funzione simile implementata in Rust che non esegue il preordinamento dell'array. -
Aggiunto un nuovo metodo
equiv()alla classeSparsePauliOpper verificare l'equivalenza di un elementoSparsePauliOpcon un altroSparsePauliOpoggetto. A differenza dell'operatore==che confronta gli operatori in modo elementare,equiv()confronta se due operatori sono equivalenti o meno. Ad esempio:op = SparsePauliOp.from_list([("X", 1), ("Y", 1)]) op2 = SparsePauliOp.from_list([("X", 1), ("Y", 1), ("Z", 0)]) op3 = SparsePauliOp.from_list([("Y", 1), ("X", 1)]) print(op == op2) # False print(op == op3) # False print(op.equiv(op2)) # True print(op.equiv(op3)) # True -
Aggiunte nuove classi di backend fasulle da istantanee dei sistemi IBM Quantum basate sull'interfaccia
BackendV2e fornito una classeTargetper ogni backend.BackendV2sono state aggiunte versioni basate su tutti i backend esistenti, ad eccezione di tre vecchi backendFakeRueschlikon,FakeTenerifeeFakeTokyoche non hanno file di snapshot disponibili, necessari per creare una nuova classe di backend fittizia basata suBackendV2.Questi nuovi backend falsi di V2 consentiranno di testare e sviluppare le nuove funzionalità introdotte da
BackendV2eTargetcome il miglioramento del transpiler. -
Aggiunta di una nuova classe di gate
XXMinusYYGatealla libreria dei circuiti (qiskit.circuit.library) per l'interazione XX-YY. Questo gate può essere utilizzato per implementare il gate bSwap e le sue potenze. Si presenta anche nella simulazione di modelli fermionici superconduttori. -
Aggiunta di una nuova classe di gate,
XXPlusYYGatealla libreria dei circuiti (qiskit.circuit.library). Questo gate è un'interazione XX+YY parametrata a 2 qubit, nota anche come gate XY, e si basa sul gate descritto in https://arxiv.org/abs/1912.04424. -
I falsi backend
FakeBogota,FakeManila,FakeRomeeFakeSantiago, che si trovano nel moduloqiskit.providers.fake_provider, possono ora essere utilizzati come backend negli esperimenti Pulse, in quanto ora includono una macchinaPulseDefaultscreato da un'istantanea delle proprietà della macchina equivalente IBM Quantum. -
Il passaggio
ConsolidateBlocksha un nuovo argomento di parola chiave nel suo costruttore,target. Questo argomento viene usato per specificare un oggettoTargetche rappresenta il target di compilazione per il passaggio. Se viene specificato, sostituisce il kwarg dibasis_gates. Se viene specificato un target, il passaggio rispetterà le porte e i qubit per le istruzioni definite nel targetTargetquando decide quali porte consolidare in un'unità. -
La classe
Targetha un nuovo metodo,instruction_supported()che serve a interrogare il target per vedere se un'istruzione (la combinazione di un'operazione e dei qubit su cui viene eseguita) è supportata dal backend modellato dall'oggettoTarget. -
Aggiunto un nuovo kwarg,
metadata_serializer, alla funzioneqpy.dump()per specificare una sottoclasse personalizzata diJSONEncoderda utilizzare per la serializzazione dell'attributoQuantumCircuit.metadatae un doppio kwargmetadata_deserializeralla funzioneqpy.load()per specificare una sottoclasseJSONDecoder. Per impostazione predefinita, i campidump()eload()tenteranno di serializzare e deserializzare JSON con il codificatore e il decodificatore json predefiniti di stdlib. PoichéQuantumCircuit.metadatapuò contenere qualsiasi dizionario Python, anche quelli con contenuti non serializzabili JSON dal codificatore predefinito, porterà a circuiti che non possono essere serializzati. Il nuovo argomentometadata_serializerperdump()consente agli utenti di specificare unJSONEncoderpersonalizzato che sarà usato con la chiamata internajson.dump()per la serializzazione delQuantumCircuit.metadatadizionario. Questo può essere abbinato al nuovo parametrometadata_deserializerdella funzioneqpy.load()per decodificare le codifiche JSON personalizzate. Semetadata_serializerè specificato sudump()mametadata_deserializernon è specificato suload()il QPY verrà caricato, ma i metadati del circuito potrebbero non essere ricostruiti completamente.Ad esempio, se si vuole definire una serializzazione personalizzata per i metadati e poi caricarla, si può fare qualcosa di simile:
from qiskit.qpy import dump, load from qiskit.circuit import QuantumCircuit, Parameter import json import io class CustomObject: """Custom string container object.""" def __init__(self, string): self.string = string def __eq__(self, other): return self.string == other.string class CustomSerializer(json.JSONEncoder): """Custom json encoder to handle CustomObject.""" def default(self, o): if isinstance(o, CustomObject): return {"__type__": "Custom", "value": o.string} return json.JSONEncoder.default(self, o) class CustomDeserializer(json.JSONDecoder): """Custom json decoder to handle CustomObject.""" def __init__(self, *args, **kwargs): super().__init__(*args, object_hook=self.object_hook, **kwargs) def object_hook(self, o): """Hook to override default decoder.""" if "__type__" in o: obj_type = o["__type__"] if obj_type == "Custom": return CustomObject(o["value"]) return o theta = Parameter("theta") qc = QuantumCircuit(2, global_phase=theta) qc.h(0) qc.cx(0, 1) qc.measure_all() circuits = [qc, qc.copy()] circuits[0].metadata = {"key": CustomObject("Circuit 1")} circuits[1].metadata = {"key": CustomObject("Circuit 2")} with io.BytesIO() as qpy_buf: dump(circuits, qpy_buf, metadata_serializer=CustomSerializer) qpy_buf.seek(0) new_circuits = load(qpy_buf, metadata_deserializer=CustomDeserializer) -
Il passaggio
DenseLayoutha un nuovo argomento di parola chiave nel suo costruttore,target. Questo argomento viene usato per specificare un oggettoTargetche rappresenta il target di compilazione per il passaggio. Se viene specificato, sostituisce gli altri argomenti del costruttore,coupling_mapebackend_prop. -
La classe
Targetha un nuovo metodo,operation_names_for_qargs(). Questo metodo viene usato per ottenere i nomi delle operazioni (cioè la chiave di ricerca nella destinazione) per le operazioni su una data tuplaqargs. -
È stato aggiunto un nuovo passaggio
DynamicalDecouplingPaddingal moduloqiskit.transpiler.passesal modulo. Questo nuovo passaggio sostituisce quello esistenteDynamicalDecouplingper lavorare con il nuovo flusso di pianificazione del transpiler. È una sottoclasse del passaggioBasePaddinge dipende dal fatto che i passaggi di scheduling e di analisi dell'allineamento siano stati eseguiti prima di esso in unaPassManager. Questo nuovo passaggio può accettare un argomentopulse_alignmentche rappresenta un vincolo hardware per la tempistica di avvio della forma d'onda. La distanza tra le porte che compongono una sequenza di disaccoppiamento dinamico viene ora regolata per soddisfare questo vincolo, in modo che il circuito possa essere eseguito su hardware con il vincolo. Questo valore si trova solitamente inBackendConfiguration.timing_constraints. Inoltre, il passaggio ha anche un'opzioneextra_slack_distributionper controllare come distribuire l'allentamento extra quando la durata della sequenza di disaccoppiamento dinamico creata è inferiore al tempo di inattività del circuito che si desidera riempire con la sequenza. L'impostazione predefinita èmiddle, identica al comportamento convenzionale. La nuova strategiasplit_edgessuddivide uniformemente l'allentamento extra all'inizio e alla fine della sequenza, anziché aggiungerlo all'intervallo a metà della sequenza. In questo modo si può ottenere una migliore cancellazione del rumore, soprattutto quandopulse_alignment> 1. -
La classe
Z2Symmetriesespone ora le tolleranze di soglia utilizzate per tagliare le piccole parti reali e immaginarie dei coefficienti. In questo modo è possibile controllare come vengono semplificati i coefficienti dell'operatore conico. Ad esempio:from qiskit.opflow import Z2Symmetries from qiskit.quantum_info import Pauli z2_symmetries = Z2Symmetries( symmetries=[Pauli("IIZI"), Pauli("IZIZ"), Pauli("ZIII")], sq_paulis=[Pauli("IIXI"), Pauli("IIIX"), Pauli("XIII")], sq_list=[1, 0, 3], tapering_values=[1, -1, -1], tol=1e-10, )Per impostazione predefinita, i coefficienti vengono tagliati con una tolleranza di
tol=1e-14. -
Aggiunto un metodo
chop()alla classeSparsePauliOpche tronca singolarmente le parti reali e immaginarie dei coefficienti. Questo è diverso dal metodoSparsePauliOp.simplify()che rimuove un coefficiente solo se il valore assoluto è prossimo a 0. Ad esempio:>>> from qiskit.quantum_info import SparsePauliOp >>> op = SparsePauliOp(["X", "Y", "Z"], coeffs=[1+1e-17j, 1e-17+1j, 1e-17]) >>> op.simplify() SparsePauliOp(['X', 'Y'], coeffs=[1.e+00+1.e-17j, 1.e-17+1.e+00j]) >>> op.chop() SparsePauliOp(['X', 'Y'], coeffs=[1.+0.j, 0.+1.j])Si noti che il metodo chop non accumula i coefficenti dello stesso Paulis, ad es.
>>> op = SparsePauliOp(["X", "X"], coeffs=[1+1e-17j, 1e-17+1j) >>> op.chop() SparsePauliOp(['X', 'X'], coeffs=[1.+0.j, 0.+1.j]) -
Aggiunto un nuovo kwarg,
target, al costruttore per il passaggio diGatesInBasisper il passaggio del transpiler. Questo nuovo argomento può essere usato per specificare facoltativamente un oggettoTargetche rappresenta il backend. Se impostato, questo parametroTargetverrà utilizzato per determinare se un elementoDAGCircuitcontiene porte al di fuori dell'insieme di basi e l'argomentobasis_gatesnon verrà utilizzato. -
Aggiunto il supporto parziale per l'esecuzione sulle piattaforme ppc64le e s390x Linux. Questo rilascio avvierà la pubblicazione di binari precompilati per le piattaforme ppc64le e s390x Linux su tutte le versioni Python. Tuttavia, a differenza di altre piattaforme supportate, non tutte le dipendenze upstream di Qiskit supportano ancora queste piattaforme. Quindi potrebbe essere necessario un compilatore C/C++ per costruire e installare queste dipendenze e un semplice
pip install qiskit-terracon un ambiente Python funzionante non sarà sufficiente per installare Qiskit. Inoltre, questi stessi vincoli ci impediscono di testare le ruote precompilate prima di pubblicarle, quindi le stesse garanzie sul supporto della piattaforma che esistono per le altre piattaforme non si applicano qui. -
Il
GradienteQFIpossono ora calcolare la parte immaginaria dei gradienti del valore di aspettativa. Quando si utilizza una base di misurazione diversa, ad es.-Yinvece diZ, possiamo misurare la parte immaginaria dei gradienti La base di misura può essere impostata con l'argomentoaux_meas_op.Per i gradienti,
aux_meas_op = Zcalcola0.5Re[(⟨ψ(ω)|)O(θ)|dωψ(ω)〉]eaux_meas_op = -Ycalcola0.5Im[(⟨ψ(ω)|)O(θ)|dωψ(ω)〉]. Per i QFI,aux_meas_op = Zcalcola4Re[(dω⟨<ψ(ω)|)(dω|ψ(ω)〉)]eaux_meas_op = -Ycalcola4Im[(dω⟨<ψ(ω)|)(dω|ψ(ω)〉)]. Ad esempio:from qiskit import QuantumRegister, QuantumCircuit from qiskit.opflow import CircuitStateFn, Y from qiskit.opflow.gradients.circuit_gradients import LinComb from qiskit.circuit import Parameter a = Parameter("a") b = Parameter("b") params = [a, b] q = QuantumRegister(1) qc = QuantumCircuit(q) qc.h(q) qc.rz(params[0], q[0]) qc.rx(params[1], q[0]) op = CircuitStateFn(primitive=qc, coeff=1.0) aux_meas_op = -Y prob_grad = LinComb(aux_meas_op=aux_meas_op).convert(operator=op, params=params) -
La classe
InstructionDurationssupporta ora il lavoro con i parametri di un'istruzione. Ogni voce di unInstructionDurationsconsiste ora in una tupla di(inst_name, qubits, duration, parameters, unit). Ciò consente a un'istruzione diInstructionDurationsdi definire la durata di un'istruzione con un certo valore di parametro, per tenere conto di durate diverse con valori di parametro diversi su un'istruzione che richiede un parametro numerico. -
Aggiunto un nuovo valore per l'argomento della parola chiave
stylenella funzione cassetto del circuitocircuit_drawer()eQuantumCircuit.draw()metodo,iqx_dark. Quandostyleè impostato suiqx_darkcon il backend del cassettompl, la visualizzazione di output userà uno schema di colori simile a quello della modalità scura usato dal compositore IBM Quantum. Ad esempio:from qiskit.circuit import QuantumCircuit from matplotlib.pyplot import show circuit = QuantumCircuit(2) circuit.h(0) circuit.cx(0, 1) circuit.p(0.2, 1) circuit.draw("mpl", style="iqx-dark") -
Al nuovo modulo sono stati aggiunti diversi controllori di dipendenze pigre
qiskit.utils.optionalsche possono essere utilizzati per verificare se alcune funzionalità di Qiskit sono disponibili. Ad esempio, è possibile chiedere se Qiskit ha rilevato la presenza dimatplotlibchiedendoif qiskit.utils.optionals.HAS_MATPLOTLIB. Questi oggetti tentano di importare le loro dipendenze solo quando vengono interrogati, in modo da poterli usare nel codice di runtime senza influenzare il tempo di importazione. -
Il tempo di importazione di
qiskitè stato notevolmente migliorato, soprattutto per chi ha installato molte delle dipendenze opzionali di Qiskit Terra. -
La funzione
marginal_counts()supporta ora la marginalizzazione del campomemorydi un oggetto di inputResultdi un oggetto di input. Ad esempio, se l'argomento di ingressoresultè un oggetto qiskitResultottenuto da una misura a 4 qubit, possiamo marginalizzare sul primo qubit con:print(result.results[0].data.memory) marginal_result = marginal_counts(result, [0]) print(marginal_result.results[0].data.memory)L'output è:
['0x0', '0x1', '0x2', '0x3', '0x4', '0x5', '0x6', '0x7'] ['0x0', '0x1', '0x0', '0x1', '0x0', '0x1', '0x0', '0x1'] -
L'interno dell'algoritmo
StochasticSwapsono stati reimplementati per essere multithread e sono ora scritti nel linguaggio di programmazione Rust invece che in Cython. Questo aumenta in modo significativo le prestazioni in fase di esecuzione del passaggio del compilatore e per estensionetranspile()quando viene eseguito conoptimization_level0, 1 e 2. Per impostazione predefinita, il passaggio utilizzerà fino al numero di CPU logiche del sistema locale, ma è possibile controllare il numero di thread utilizzati dal passaggio impostando la variabile d'ambienteRAYON_NUM_THREADSsu un valore intero. Ad esempio, impostandoRAYON_NUM_THREADS=4il programmaStochasticSwapcon 4 thread. -
È disponibile una nuova variabile d'ambiente
QISKIT_FORCE_THREADSche consente agli utenti di controllare direttamente se le porzioni di codice potenzialmente multithread di Qiskit verranno eseguite in più thread. Attualmente è utilizzato solo dal passaggioStochasticSwapma probabilmente in futuro sarà utilizzato anche da altre parti di Qiskit. Quando questa variabile env è impostata suTRUE, qualsiasi codice multithread in Qiskit Terra utilizzerà sempre più thread, indipendentemente da qualsiasi altra condizione di runtime che avrebbe potuto far sì che la funzione utilizzasse una variante a thread singolo. Ad esempio, inStochasticSwapse il passaggio viene eseguito come parte di una chiamatatranspile()con > 1 circuito che viene eseguito in parallelo conmultiprocessingtramiteparallel_map()ilStochasticSwapnon utilizzerà thread multipli per evitare di sovrascrivere potenzialmente le risorse della CPU. Tuttavia, se si desidera utilizzare più thread nel passaggio insieme a più processi, è possibile impostareQISKIT_FORCE_THREADS=TRUE. -
Le nuove classi di backend fasulle sono disponibili all'indirizzo
qiskit.providers.fake_provider. Questi includono le versioni simulate diibm_cairo,ibm_hanoi,ibmq_kolkata,ibm_nairobieibm_washington. Come per gli altri backend fasulli, questi includono istantanee dei dati di calibrazione e di errore presi dal sistema reale e possono essere usati per test, compilazione e simulazione locali. -
Introduzione di una nuova classe
StatePreparation. Questa classe consente agli utenti di preparare uno stato desiderato allo stesso modo diInitializesenza che il reset venga applicato automaticamente.Ad esempio, per preparare un qubit nello stato :
import numpy as np from qiskit import QuantumCircuit circuit = QuantumCircuit(1) circuit.prepare_state([1/np.sqrt(2), -1/np.sqrt(2)], 0) circuit.draw()L'output è il seguente:
┌─────────────────────────────────────┐ q_0: ┤ State Preparation(0.70711,-0.70711) ├ └─────────────────────────────────────┘ -
Il
Optimize1qGatesil passaggio del transpiler ora supporta l'ottimizzazione diU1Gate,U2Gate, ePhaseGatecon parametri non vincolati in un circuito. In precedenza, se questi gate avevano parametri non vincolati, il passaggio non li utilizzava. Ad esempio:from qiskit import QuantumCircuit from qiskit.circuit import Parameter from qiskit.transpiler import PassManager from qiskit.transpiler.passes import Optimize1qGates, Unroller phi = Parameter('φ') alpha = Parameter('α') qc = QuantumCircuit(1) qc.u1(2*phi, 0) qc.u1(alpha, 0) qc.u1(0.1, 0) qc.u1(0.2, 0) pm = PassManager([Unroller(['u1', 'cx']), Optimize1qGates()]) nqc = pm.run(qc)saranno combinati al circuito con un solo gate a un solo qubit:
qc = QuantumCircuit(1) qc.u1(2*phi + alpha + 0.3, 0) -
I metodi
Pauli.evolve()ePauliList.evolve()hanno ora un nuovo argomento chiave,frame, che viene utilizzato per eseguire un'evoluzione di un Pauli da parte di un Clifford. Seframe='h'(predefinito) esegue l'evoluzione del quadro di Heisenberg di un Pauli da parte di un Clifford ( ), e seframe='s'esegue l'evoluzione del quadro di Schrödinger di un Pauli da parte di un Clifford ( ). Quest'ultima opzione consente un calcolo più rapido ed è utile in alcuni casi. Questa nuova opzione rende il calcolo del metodo di decomposizione greedy Clifford indecompose_cliffordmolto più veloce. -
Aggiunto un nuovo modulo a Qiskit:
qiskit.primitives. Il modulo delle primitive è quello in cui vengono definite le API che forniscono diverse astrazioni per il calcolo di alcune funzioni comuni daQuantumCircuitche astrae i dettagli dell'esecuzione sottostante suBackend. Ciò consente agli algoritmi e alle applicazioni di livello superiore di concentrarsi sull'esecuzione dei calcoli, senza doversi preoccupare dell'esecuzione e dell'elaborazione dei risultati, e di disporre di un'interfaccia standardizzata per i calcoli comuni. Ad esempio, la stima di un valore di aspettativa di un circuito quantistico e di un'osservabile può essere eseguita da qualsiasi classe che implementa la classe e consumata in modo standardizzato, indipendentemente dall'implementazione sottostanteBaseEstimatorclasse e consumata in modo standardizzato, indipendentemente dall'implementazione sottostante. Le applicazioni possono quindi essere scritte utilizzando direttamente l'interfaccia primitiva.Per iniziare, il modulo contiene due tipi di primitive, la
Sampler(vedereBaseSamplerper la definizione della classe astratta) eEstimator(vedereBaseEstimatorper la definizione della classe astratta). Le implementazioni di riferimento sono incluse nel moduloqiskit.primitivese sono costruite utilizzando il moduloqiskit.quantum_infoche eseguono una simulazione ideale delle operazioni primitive. L'aspettativa è che i pacchetti dei provider offrano le proprie implementazioni di queste interfacce per i provider che possono implementare in modo efficiente il protocollo in modo nativo (tipicamente utilizzando un runtime classico). Inoltre, in futuro, per i provider che non offrono un'implementazione nativa delle primitive, sarà fornito un metodo che consentirà di costruire oggetti primitivi a partire da un oggettoBackend. -
Aggiunto un nuovo modulo,
qiskit.qpyche contiene le funzionalità precedentemente esposte inqiskit.circuit.qpy_serialization. Le funzioni pubbliche precedentemente esposte suqiskit.circuit.qpy_serialization,dump()eload()sono ora disponibili in questo nuovo modulo (anche se sono ancora accessibili daqiskit.circuit.qpy_serialization, ma questo sarà deprecato in una prossima versione). Questo nuovo modulo è stato aggiunto nell'interesse della direzione futura del formato di file QPY, che nelle versioni future supporterà la rappresentazione dipulseScheduleeScheduleBlockoltre agli oggettiQuantumCircuitoggetti che supporta oggi. -
Aggiunto un nuovo attributo,
qubit_propertiesalla classeTargetclasse. Questo attributo contiene un elenco diQubitPropertiesoggetti per ogni qubit del target. Ad esempio:target.qubit_properties[2]conterrà il valore
QubitPropertiesper il qubit numero 2 nel target.Per
BackendV2autori, se in precedenza si definivaQubitPropertiesdirettamente nella propria implementazioneBackendV2sovrascrivendo il parametroBackendV2.qubit_properties()questo funzionerà ancora bene. Tuttavia, se si sposta la definizione all'oggetto sottostanteTargete si rimuove l'implementazione specializzataBackendV2.qubit_properties()che consentirà di utilizzare le proprietà dei qubit nel transpiler e di mantenere la compatibilità dell'API con l'implementazione precedente. -
Aggiunta di una nuova funzione,
qiskit.algorithms.eval_observables()che viene utilizzata per valutare gli osservabili, dato un limiteQuantumCircuit. Ha origine da un metodo privato,_eval_aux_ops(), della classeqiskit.algorithms.VQEma la nuova funzioneeval_observables()è ora più generale e può essere utilizzata in altri algoritmi, ad esempio in quelli di evoluzione temporale. -
La strategia di ricerca delle basi nel
BasisTranslatornel passaggio del transpiler è stata modificata in una variante della ricerca di Dijkstra che migliora notevolmente le prestazioni di runtime del passaggio quando si cerca di puntare a una base irraggiungibile. -
Il passaggio
DenseLayoutil passaggio del transpiler è ora multithread, il che migliora notevolmente le prestazioni in fase di esecuzione del passaggio. Per impostazione predefinita, utilizza il numero di CPU logiche del sistema locale, ma è possibile controllare il numero di thread utilizzati dal passaggio impostando la variabile d'ambienteRAYON_NUM_THREADSsu un valore intero. Ad esempio, impostandoRAYON_NUM_THREADS=4si eseguirà ilDenseLayoutcon 4 thread. -
I calcoli interni di
Statevector.expectation_value()eDensityMatrix.expectation_value()sono stati reimplementati nel linguaggio di programmazione Rust. Questa nuova implementazione è multithread e, per impostazione predefinita, per un oggettoStatevectoroDensityMatrix>= 19 qubit verrà creato un pool di thread con il numero di CPU logiche disponibili sul sistema locale. È possibile controllare il numero di thread utilizzati impostando la variabile d'ambienteRAYON_NUM_THREADSsu un valore intero. Ad esempio, impostandoRAYON_NUM_THREADS=4si utilizzeranno solo 4 thread nel pool di thread. -
Aggiunto un nuovo
SparsePauliOp.from_sparse_list()che prende un iterabile, dove gli elementi rappresentano termini di Pauli che sono a loro volta sparsi, così che"XIIIIIIIIIIIIIIIX"può ora essere scritto come("XX", [0, 16]). Ad esempio, l'operatore
può ora essere costruito come
op = SparsePauliOp.from_sparse_list([("XZ", [0, 3], 1), ("YY", [1, 4], 2)], num_qubits=5)
# or equivalently, as previously
op = SparsePauliOp.from_list([("IZIIX", 1), ("YIIYI", 2)])Ciò facilita la costruzione di operatori molto radi su molti qubit, come spesso accade per gli hamiltoniani di Ising.
-
Il passo del transpiler
UnitarySynthesisha un nuovo argomento di parola chiave nel suo costruttore,target. Si può usare per specificare facoltativamente un oggettoTargetche rappresenta il target di compilazione per il passaggio. Quando viene specificato, sostituisce i valori impostati perbasis_gates,coupling_mapebackend_props. -
La classe
UnitarySynthesisPluginha un nuovo attributo opzionale che le implementazioni possono aggiungere,supports_target. Se un plugin ha questo attributo impostato suTrue, un oggettoTargetverrà passato nel payload dioptionssotto il campotarget. L'aspettativa è che questoTargetsarà utilizzato al posto dicoupling_map,gate_lengths,basis_gatesegate_errors. -
È stato introdotto un nuovo flusso di lavoro per la creazione di oggetti per la schedulazione
PassManageroggetti per la programmazioneQuantumCircuitoggetti nel transpiler. Nel nuovo flusso di lavoro, i passaggi di pianificazione e allineamento sono tutti oggetti che aggiornano solo l'insieme di proprietà del gestore dei passaggiAnalysisPassche aggiornano solo l'insieme di proprietà del gestore dei passaggi, in particolare la nuova voce dell'insieme di proprietànode_start_time, che contiene l'ora di inizio assoluta di ciascun opnode. Una soluzione separataTransformationPasscomePadDelayviene successivamente utilizzato per applicare la schedulazione al DAG. Questo nuovo flusso di lavoro è più efficiente e può correggere i vincoli temporali aggiuntivi esposti da un backend.In precedenza, la catena di passaggi veniva implementata come
scheduling -> alignmentche erano entrambi passaggi di trasformazione, quindi c'erano più istanze ricreate durante ogni passaggioDAGCircuitricreate durante ogni passaggio. Inoltre, in ogni passaggio è stato effettuato uno scheduling per ottenere l'orario di inizio delle istruzioni. Ora la catena di passaggi richiesta diventascheduling -> alignment -> paddingdove l'aggiornamento avviene solo alla fine con il passaggioDAGCircuitaggiornamento avviene solo alla fine con il passaggiopadding.Per coloro che creano oggetti personalizzati
PassManagerche coinvolgono la programmazione dei circuiti, sarà necessario adattare il proprioPassManagerper inserire uno dei passaggi diBasePadding(attualmente oPadDelayoPadDynamicalDecouplingpuò essere utilizzato) alla fine della catena di passaggi di schedulazione. Senza il passaggio di padding, i passaggi di schedulazione non si rifletteranno nel circuito di uscita del metodorun()del metodo personalizzatoPassManager.Ad esempio, se in precedenza si costruiva il file
PassManagercon qualcosa come:from qiskit.transpiler import PassManager from qiskit.transpiler.passes import TimeUnitConversion, ALAPSchedule, ValidatePulseGates, AlignMeasures pm = PassManager() scheduling = [ ALAPSchedule(instruction_durations), PadDelay()), ValidatePulseGates(granularity=timing_constraints.granularity, min_length=timing_constraints.min_length), AlignMeasures(alignment=timing_constraints.acquire_alignment), ] pm.append(scheduling)si può invece utilizzare:
from qiskit.transpiler import PassManager from qiskit.transpiler.passes import TimeUnitConversion, ALAPScheduleAnalysis, ValidatePulseGates, AlignMeasures, PadDelay pm = PassManager() scheduling = [ ALAPScheduleAnalysis(instruction_durations), PadDelay()), ConstrainedReschedule(acquire_alignment=timing_constraints.acquire_alignment, pulse_alignment=timing_constraints.pulse_alignment), ValidatePulseGates(granularity=timing_constraints.granularity, min_length=timing_constraints.min_length), PadDelay() ] pm.append(scheduling)che sarà più efficiente e allineerà le istruzioni in base a eventuali vincoli hardware.
-
Aggiunto un nuovo passaggio di transpiler
ConstrainedReschedulepass. IlConstrainedRescheduleconsidera sia i vincoli di allineamento hardware che possono essere definiti in un oggettoBackendConfigurationpulse_alignmenteacquire_alignment. Questa nuova classe sostituisce la precedente classeAlignMeasuresin quanto esegue lo stesso allineamento (tramite l'insieme di proprietà) per le istruzioni di misura, oltre all'allineamento generale delle istruzioni. Impostando l'argomento del vincoloacquire_alignmentper il passoConstrainedRescheduleè un sostituto immediato diAlignMeasuresse abbinato a un nuovo passaggioBasePadding. -
Aggiunti due nuovi passaggi di transpiler
ALAPScheduleAnalysiseASAPScheduleAnalysische sostituiscono i passaggiALAPScheduleeASAPSchedulecome parte del flusso di lavoro del transpiler rielaborato per schedling. I nuovi passaggi eseguono lo stesso scheduling, ma nel set di proprietà e affidandosi a un passaggio diBasePaddingper regolare il circuito in base a tutte le analisi di allineamento dello scheduling.Il comportamento standard di questi passaggi allinea anche l'ordinamento temporale con l'ordinamento topologico dei nodi del DAG. Questa modifica può influenzare il risultato della programmazione se include operazioni condizionali o la misurazione simultanea di due qubit con lo stesso registro classico (edge-case). Per riprodurre il comportamento convenzionale, impostare
clbit_write_latencyidentico alla lunghezza dell'istruzione di misura.Ad esempio, si consideri la programmazione di un circuito di ingresso come:
┌───┐┌─┐ q_0: ┤ X ├┤M├────────────── └───┘└╥┘ ┌───┐ q_1: ──────╫────┤ X ├────── ║ └─╥─┘ ┌─┐ q_2: ──────╫──────╫─────┤M├ ║ ┌────╨────┐└╥┘ c: 1/══════╩═╡ c_0=0x1 ╞═╩═ 0 └─────────┘ 0from qiskit import QuantumCircuit from qiskit.transpiler import InstructionDurations, PassManager from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDelay, SetIOLatency from qiskit.visualization.timeline import draw circuit = QuantumCircuit(3, 1) circuit.x(0) circuit.measure(0, 0) circuit.x(1).c_if(0, 1) circuit.measure(2, 0) durations = InstructionDurations([("x", None, 160), ("measure", None, 800)]) pm = PassManager( [ SetIOLatency(clbit_write_latency=800, conditional_latency=0), ALAPScheduleAnalysis(durations), PadDelay(), ] ) draw(pm.run(circuit))Come si può vedere nella visualizzazione della timeline, la misura su
q_2inizia prima del gate condizionale X suq_1, che sembra essere opposto all'ordine topologico del nodo. Questo comportamento è previsto anche perché l'accesso in scrittura del clbit avviene sul bordo finale dell'istruzione di misura, mentre l'accesso in lettura del gate condizionale avviene sul bordo iniziale dell'istruzione. In questo modo, l'ordinamento topologico viene conservato sul timeslot del registro classico, che non viene catturato dalla visualizzazione della timeline. Tuttavia, questo presuppone un progetto di microarchitettura particolare e non è necessario che il circuito sia programmato in questo modo.Utilizzando la configurazione predefinita dei passaggi, il circuito è programmato come segue.
from qiskit import QuantumCircuit from qiskit.transpiler import InstructionDurations, PassManager from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDelay from qiskit.visualization.timeline import draw circuit = QuantumCircuit(3, 1) circuit.x(0) circuit.measure(0, 0) circuit.x(1).c_if(0, 1) circuit.measure(2, 0) durations = InstructionDurations([("x", None, 160), ("measure", None, 800)]) pm = PassManager([ALAPScheduleAnalysis(durations), PadDelay()]) draw(pm.run(circuit))Si noti che clbit è bloccato per tutto l'intervallo dell'istruzione di misura. Questo comportamento è stato progettato sulla base del Qiskit Pulse, in cui l'istruzione acquire prende
AcquireChanneleMemorySlotche non possono sovrapporsi ad altre istruzioni, cioè è vietato l'accesso simultaneo alla memoria da parte delle diverse istruzioni. In questo modo si allinea sempre l'ordinamento temporale con l'ordinamento topologico dei nodi. -
Aggiunto un nuovo passaggio del transpiler
PadDynamicalDecouplingche sostituisce il passaggioDynamicalDecouplingcome parte del flusso di lavoro del transpiler rielaborato per la programmazione. Questo nuovo passaggio inserisce nel circuito sequenze di disaccoppiamento dinamico, in base alle analisi di programmazione e allineamento effettuate nei passaggi precedenti. -
La funzione
plot_gate_map()e le funzioni costruite sopra di essa,plot_error_map()eplot_circuit_layout()hanno un nuovo argomento chiave,qubit_coordinates. Questo argomento accetta una sequenza di coordinate 2D da utilizzare per tracciare ogni qubit nel backend da visualizzare. Se specificata, questa sequenza deve avere una lunghezza pari al numero di qubit del backend e verrà utilizzata al posto del comportamento predefinito. -
La funzione
plot_gate_map()e le funzioni costruite sopra di essa,plot_error_map()eplot_circuit_layout()sono ora in grado di tracciare qualsiasi backend, non solo quelli con un numero di qubit uguale a uno dei backend di IBM. Si affida alla funzione retworkxspring_layout()per generare il layout della visualizzazione. Se il layout predefinito non funziona con il particolare grafico di accoppiamento di un backend, si può usare la funzionequbit_coordinatesper impostare un layout personalizzato. -
La funzione
plot_gate_map()e le funzioni costruite sopra di essa,plot_error_map()eplot_circuit_layout()sono ora in grado di funzionare con un backendBackendV2basato su backend. In precedenza, queste funzioni funzionavano solo con i backendBaseBackendoBackendV1basati su backend. -
Aggiunto un nuovo passaggio di transpiler,
SetIOLatency. Questo passaggio prende due argomenticlbit_write_latencyeconditional_latencyper definire la latenza di I/O per i bit classici e le condizioni classiche su un backend. Questo passaggio definirà quindi questi valori nel set di proprietà del gestore del passaggio per consentire ai successivi passaggi di schedulazione e allineamento di correggere queste latenze e fornire un output di schedulazione più preveggente di un circuito dinamico. -
È stato aggiunto un nuovo passaggio per il transpiler
PadDelayè stato aggiunto. Questo passaggio riempie il tempo di inattività dei fili dei qubit conDelayistruzioni. Questo passaggio fa parte del nuovo flusso di lavoro per la programmazione dei passaggi nel transpiler e dipende da un passaggio di analisi di programmazione (come ad esempioALAPScheduleAnalysisoASAPScheduleAnalysis) e da eventuali passaggi di allineamento (come ad esempioConstrainedReschedule) da eseguire prima diPadDelay. -
Il passaggio
VF2Layoutha un nuovo argomento di parola chiave,target, che viene utilizzato per fornire un oggettoTargetper il passaggio. Quando viene specificato, il parametroTargetsarà utilizzato dal passaggio per tutte le informazioni sul dispositivo di destinazione. Se viene specificata, l'opzionetargetavrà la priorità sugli argomenticoupling_mapeproperties. -
Consentire i callables come ottimizzatori in
VQEeQAOA. Ora, l'ottimizzatore può essere uno degli ottimizzatori di Qiskit, come ad esempioSPSAoppure un callable con la seguente firma:from qiskit.algorithms.optimizers import OptimizerResult def my_optimizer(fun, x0, jac=None, bounds=None) -> OptimizerResult: # Args: # fun (callable): the function to minimize # x0 (np.ndarray): the initial point for the optimization # jac (callable, optional): the gradient of the objective function # bounds (list, optional): a list of tuples specifying the parameter bounds result = OptimizerResult() result.x = # optimal parameters result.fun = # optimal function value return resultLa firma di cui sopra permette anche di passare direttamente qualsiasi minimizzatore di SciPy, per esempio come
from functools import partial from scipy.optimize import minimize optimizer = partial(minimize, method="L-BFGS-B")
Problemi noti
- Quando si esegue
parallel_map()(che viene eseguito internamente da funzioni sensibili alle prestazioni cometranspile()eassemble()) in un sottoprocesso lanciato al di fuori diparallel_map()è possibile che il dispatch parallelo eseguito all'interno diparallel_map()si blocchi e non ritorni mai. Ciò è dovuto a problemi upstream in CPython relativi al metodo predefinito per lanciare i sottoprocessi su Linux e macOS con Python 3.7 (vedere https://bugs.python.org/issue40379 per maggiori dettagli). Se si verifica questo problema, si hanno due opzioni: si possono rimuovere i processi paralleli annidati, in quanto la chiamata aparallel_map()da un processo principale dovrebbe funzionare bene; oppure si può chiamare manualmente il modulomultiprocessingdella libreria standard di CPython per eseguire un dispatch parallelo simile da un sottoprocesso, ma usare i metodi di lancio"spawn"o"forkserver"per evitare che le cose si blocchino e non ritornino mai.
Note sull'aggiornamento
-
Le classi
Qubit,ClbiteAncillaQubithanno ora l'attributo__slots__. Questo per ridurre l'utilizzo della memoria. Come effetto collaterale, non possono più avere dati arbitrari allegati come attributi. È molto improbabile che questo abbia un effetto sul codice a valle, a parte i vantaggi in termini di prestazioni. -
La dipendenza del nucleo
retworkxha avuto il suo requisito di versione spostato a 0.11.0, da 0.10.1. Questo migliora le prestazioni del passaggio di transpilazioneConsolidateBlocks. -
La versione minima supportata di
symengineè ora 0.9.0. Questo è stato necessario per migliorare la compatibilità con il modulo Python 'pickleche è usato internamente come parte del dispatch parallelo conparallel_map(). -
Il valore predefinito di
QISKIT_PARALLELquando viene eseguito con Python 3.9 su Linux è ora impostato suTRUE. Ciò significa che quando si esegueparallel_map()o le funzioni che lo chiamano internamente, come ad esempiotranspile()eassemble()la funzione verrà eseguita in più processi e dovrebbe avere prestazioni migliori in fase di esecuzione. Questa modifica è stata apportata perché i problemi di affidabilità del dispacciamento parallelo sembrano essere stati risolti (vedere #6188 per maggiori dettagli). Se si riscontrano ancora problemi, è possibile disabilitare il multiprocessing e tornare al comportamento predefinito precedente impostando la variabile d'ambienteQISKIT_PARALLELsuFALSEo impostando l'opzioneparallelsuFalsenel file di configurazione dell'utente (si prega inoltre di segnalare un problema in modo da poter tenere traccia di qualsiasi problema relativo al multiprocessing). -
La classe deprecata
MSGate, precedentemente presente inqiskit.circuit.libraryè stata rimossa. È stato originariamente deprecato nella versione 0.16.0. Si dovrebbe invece utilizzare la classeGMSche consente di creare un gate MS equivalente a 2 qubit, oltre a unMSGateper qualsiasi numero di qubit. -
Il metodo precedentemente deprecato
mirror()della classeInstructionè stato rimosso. È stato originariamente deprecato nella versione 0.15.0. Si dovrebbe invece utilizzareInstruction.reverse_ops(). -
Il metodo
num_ancilla_qubits(), precedentemente deprecato, degli elementiqiskit.circuit.library.PiecewiseLinearPauliRotationseqiskit.circuit.library.WeightedAdderè stato rimosso. È stato originariamente deprecato nella versione 0.16.0. Si devono invece utilizzare i metodiPiecewiseLinearPauliRotations.num_ancillas()eWeightedAdder.num_ancillas(). -
L'argomento
reverse, precedentemente deprecato, nel costruttore della classePolynomialPauliRotationsè stato rimosso. È stato originariamente deprecato nella versione 0.15.0. Si deve invece utilizzare il metodoQuantumCircuit.reverse_bits()per invertire ilPolynomialPauliRotationscircuito, se necessario. -
L'argomento precedentemente deprecato
anglenei costruttori degli oggettiC3SXGateeC3XGateè stato rimosso. È stato originariamente deprecato nella versione 0.17.0. Per le porte X frazionarie a 3 controlli è invece possibile utilizzare il metodoC3XGate.power(). -
Supporto per l'utilizzo degli oggetti
np.ndarraycome parte dell'attributoparamsdi un oggettoGateè stato rimosso. Questa funzione è stata deprecata da quando Qiskit Terra 0.16.0 e ora non funziona più. Si dovrebbe invece creare una nuova sottoclasse diGatee consentire esplicitamente un inputnp.ndarraysovraccaricando il metodovalidate_parameter(). -
Un nuovo extra
csp-layout-passè stato aggiunto al target di installazione dipip install qiskit-terraed è anche incluso nell'extraall. Questo non ha effetto in Qiskit Terra 0.20, ma a partire da Qiskit Terra 0.21, le dipendenze necessarie solo per il passaggio del transpiler saranno declassate da requisiti a opzioni e installate da questo extraCSPLayoutsaranno declassate da requisiti a opzioni e installate da questo extra. È possibile preparare un pacchetto che dipende da questo passaggio impostando i suoi requisiti (o il comandopip install) per puntare aqiskit-terra[csp-layout-pass]. -
Il supporto per l'esecuzione con Python 3.6 è stato rimosso. Per eseguire Qiskit è necessaria una versione minima Python di 3.7.
-
La classe
AmplitudeEstimatoreredita ora dalla classeABCdella libreria standard Python. Ciò richiede a qualsiasi sottoclasse di implementare il metodoestimate()mentre prima non era richiesto. Questo è stato fatto perché l'intento originale della classe era quello di essere sempre una classe figlia diABC, dato che l'elementoestimate()è necessario per il funzionamento di unAmplitudeEstimatoroggetto. Tuttavia, se in precedenza si definiva una sottoclasseAmplitudeEstimatorche non implementavaestimate()ora si otterrà un errore. -
L'errore sollevato da
HoareOptimizerse la dipendenza opzionalez3non è disponibile è cambiato daTranspilerErroraMissingOptionalLibraryError(che è sia un elementoQiskitErrore unImportError). Questo è stato fatto per essere coerente con le altre dipendenze opzionali. -
Su Linux, il supporto minimo della libreria è stato aumentato dalla VM manylinux2010 a manylinux2014. Questo rispecchia cambiamenti simili in Numpy e Scipy. Non dovrebbero esserci effetti significativi per la maggior parte degli utenti, a meno che il vostro sistema non contenga ancora una versione molto vecchia di
glibc. -
La funzione
marginal_counts()quando viene chiamata con un oggettoResultora marginalizzerà il campomemorydei dati dell'esperimento se è impostato nell'inputResult. In precedenza, il campomemorynell'input non era marginalizzato. Questa modifica è stata apportata perché il comportamento precedente faceva sì che il campocountsnon coincidesse con il campomemorydopo che era stato richiamato il campomarginal_counts()è stato chiamato. Se si desidera ripristinare il comportamento precedente, si può impostaremarginalize_memory=Nonecome argomento amarginal_counts()che non marginalizzerà il campomemory. -
Il
StochasticSwappuò restituire risultati diversi con lo stesso valore di seme impostato. Ciò è dovuto alla riscrittura interna del passaggio del transpiler per migliorare le prestazioni in fase di esecuzione. Tuttavia, questo significa che se si eseguetranspile()conoptimization_level0, 1 (il valore predefinito) o 2 con un valore impostato perseed_transpiler, si potrebbe ottenere un output con una diversa mappatura dello swap presente dopo l'aggiornamento a Qiskit Terra 0.20.0. -
Per compilare Qiskit Terra dai sorgenti è ora necessario un compilatore Rust. Ciò è dovuto alla riscrittura interna del passaggio di
StochasticSwapche migliora notevolmente le prestazioni del transpiler in fase di esecuzione. Il compilatore rust può essere facilmente installato usando rustup, che si trova qui: https://rustup.rs/ -
L'attributo
namedella classePauliEvolutionGateè stato modificato in modo che sia sempre"PauliEvolution". Questa modifica è stata apportata per essere coerente con le altre porte di Qiskit e consente alle altre parti di Qiskit di identificare rapidamente quando una particolare operazione in un circuito è un'operazione di tipo "a"PauliEvolutionGate. Ad esempio, consente di srotolare le porte dell'evoluzione di Pauli.In precedenza, il nome conteneva gli operatori evoluti, che ora sono disponibili tramite l'attributo
PauliEvolutionGate.label. Se si disegna un circuito con unPauliEvolutionGateil cancello mostrerà comunque la stessa informazione, ovvero quali cancelli si stanno evolvendo. -
I metodi precedentemente deprecati:
qiskit.algorithms.VQE.get_optimal_costqiskit.algorithms.VQE.get_optimal_circuitqiskit.algorithms.VQE.get_optimal_vectorqiskit.algorithms.VQE.optimal_paramsqiskit.algorithms.HamiltonianPhaseEstimationResult.most_likely_phaseqiskit.algorithms.PhaseEstimationResult.most_likely_phase
che erano stati originariamente deprecati nella versione di Qiskit Terra 0.18.0 sono stati rimossi e non funzioneranno più.
-
La classe
qiskit.algorithms.VariationalAlgorithmè ora definita come una classe base astratta (ABC) che richiederà alle classi che ereditano da essa di definire sia un metodo getter che setterVariationalAlgorithm.initial_point. -
Il kwarg
pass_managerper la funzionetranspile()è stato rimosso. È stato originariamente deprecato nella versione 0.13.0. Il metodo preferito per transpilare un circuito con un oggettoPassManagerè utilizzare il metodorun()dell'oggettoPassManagerdell'oggetto. -
La classe
ParametrizedSchedule, precedentemente deprecata, è stata rimossa e non esiste più. Questa classe è stata deprecata con la release 0.17.0. Invece di usare questa classe, si possono parametrizzare direttamente i metodiScheduleoScheduleBlockspecificando un oggettoParameterall'argomento dell'impulso parametrico. -
Il modulo
qiskit.circuit.library.probability_distributionsè stato rimosso e non esiste più, come da avviso di deprecazione di qiskit-terra 0.17.0 (rilasciato il 1° aprile 2021). Le classi interessate sonoUniformDistribution,NormalDistributioneLogNormalDistribution. Vengono tutti spostati nella libreria qiskit-finance, nel modulo della libreria dei circuiti:qiskit_finance.circuit.library.probability_distributions. -
La precedente classe
qiskit.test.mock.fake_mumbai_v2.FakeMumbaiV2è stata rinominata inFakeMumbaiFractionalCXper differenziarla dal falso backend basato sul dispositivo di Mumbai,BackendV2per il dispositivo IBM di Mumbai,qiskit.test.mock.backends.FakeMumbaiV2. Se in precedenza ci si affidava alla classeFakeMumbaiV2per ottenere un falso backend che avesse applicazioni frazionarie diCXGatedefinite nel suo target, è necessario usare la classeFakeMumbaiFractionalCX, poichéFakeMumbaiV2non avrà più quelle definizioni di gate extra nel suo fileTarget. -
Il risolutore utilizzato da
QuantumCircuit.append()(e di conseguenza tutti i metodi che aggiungono un'istruzione a un oggettoQuantumCircuit) per convertire gli specificatori di bit è stato modificato per renderlo più veloce e affidabile. Alcuni costrutti come:import numpy as np from qiskit import QuantumCircuit qc = QuantumCircuit(1, 1) qc.measure(np.array([0]), np.array([0]))funzionerà ora dove prima sollevava erroneamente un errore, ma alcuni input patologici come:
from sympy import E, I, pi qc.x(E ** (I * pi))ora darà luogo a errori laddove in precedenza potevano avere occasionalmente (erroneamente) successo. Per quasi tutti gli utilizzi corretti, non dovrebbero esserci cambiamenti degni di nota, se non una generale velocizzazione.
-
Il metodo interno semipubblico
QuantumCircuit._append()non controlla più i tipi dei suoi input e assume che non ci siano duplicati non validi nei suoi elenchi di argomenti. Questa funzione viene utilizzata da alcune parti interne di Qiskit e di altre librerie per creare istanze il più rapidamente possibile, saltando il controllo degli errori quando si sa che i dati sono già correttiQuantumCircuitil più rapidamente possibile, saltando il controllo degli errori quando si sa che i dati sono già corretti. In generale, gli utenti o le funzioni che accettano dati dell'utente dovrebbero utilizzare il metodo publicQuantumCircuit.append()che risolve gli specificatori di bit interi, trasmette i suoi argomenti e verifica la correttezza degli input. -
Cython non è più una dipendenza di compilazione di Qiskit Terra e non è più necessario installarlo quando si costruisce Qiskit Terra dai sorgenti.
-
I passmanager preimpostati in
qiskit.transpiler.preset_passmanagersper tutti i livelli di ottimizzazione 2 e 3, generati dalevel_2_pass_manager()elevel_3_pass_manager()sono stati modificati in modo da eseguire l'opzioneVF2Layoutper impostazione predefinita prima del passaggio di layout. Il passaggioVF2Layoutverifica rapidamente se è possibile trovare un layout perfetto e sostituisce ciò che è stato fatto in precedenza per i livelli di ottimizzazione 2 e 3 che utilizzavano una combinazione diTrivialLayouteCSPLayoutper cercare di trovare un layout perfetto. Questo comporterà un comportamento potenzialmente diverso quandotranspile()viene richiamato per impostazione predefinita, in quanto rimuove un percorso predefinito per tutti i livelli di ottimizzazione >=2 di utilizzo di un layout banale (in cuicircuit.qubits[0]è mappato sul qubit fisico 0,circuit.qubits[1]è mappato sul qubit fisico 1 e così via), assumendo che il layout banale sia perfetto. Se il caso d'uso dipende dal layout banale, è possibile richiederlo esplicitamente in fase di transpiling, specificandolayout_method="trivial"quando si chiama il filetranspile(). -
Il gestore dei passaggi preimpostato per il livello di ottimizzazione 1 (quando si chiama
transpile()conoptimization_level=1o quando non è impostato alcun argomentooptimization_level) come generato dalevel_1_pass_manager()è stato modificato in modo cheVF2Layoutviene richiamato per impostazione predefinita per verificare rapidamente se è possibile trovare un layout perfetto prima dell'esecuzione del comandoDenseLayout. Tuttavia, a differenza di quanto accade con i livelli di ottimizzazione 2 e 3, prima dell'esecuzione viene ancora tentato un layout banaleVF2Layoute se la mappatura è perfetta, viene utilizzato l'output diVF2Layoutverrà utilizzato.
Note di deprecazione
-
L'argomento
max_creditsdiexecute()e tutte le configurazioni diQobj(ad es.QasmQobjConfigePulseQobjConfig), è deprecato e sarà rimosso in una prossima versione. Il sistema di crediti non è più in uso nei backend di IBM Quantum da due anni e l'opzione non ha alcun effetto. Non è necessaria alcuna alternativa. Ad esempio, se si chiamaexecute()come:job = execute(qc, backend, shots=4321, max_credits=10)si può semplicemente omettere l'argomento
max_credits:job = execute(qc, backend, shots=4321) -
L'utilizzo di un intero dispari per l'argomento
ordernel costruttore della classeSuzukiTrotterè deprecato e non funzionerà più nelle prossime versioni. Le formule del prodotto utilizzate dalSuzukiTrottersono definite solo quando l'ordine è pari, poiché le formule del prodotto Suzuki sono simmetriche. -
I kwarg
qregs,cregs,layouteglobal_phasedelle classiMatplotlibDrawer,TextDrawingeQCircuitImagee il kwargcalibrationsdella classeMatplotlibDrawersono ora deprecati e saranno rimossi in una release successiva.
Correzioni di bug
-
Corretto un errore nelle funzioni di conversione dei circuiti
circuit_to_gate()ecircuit_to_instruction()(e i loro metodi di circuito associatiQuantumCircuit.to_gate()eQuantumCircuit.to_instruction()) quando si agisce su un circuito con bit senza registro o con bit in più di un registro. -
È stato risolto un problema per cui la chiamata
QuantumCircuit.copy()sui circuiti "body" di un'operazione di flusso di controllo creata con l'interfaccia del costruttore generava un errore. Ad esempio, questo era in precedenza un errore, ma ora viene restituito con successo:from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister qreg = QuantumRegister(4) creg = ClassicalRegister(1) circ = QuantumCircuit(qreg, creg) with circ.if_test((creg, 0)): circ.h(0) if_else_instruction, _, _ = circ.data[0] true_body = if_else_instruction.params[0] true_body.copy() -
Aggiunta una voce mancante dalla libreria di equivalenza delle sessioni standard tra
CXGateeCPhaseGatee traCXGateeCRZGate. -
È stato risolto un problema a causa del quale l'esecuzione dell'operatore
==tra due oggettiSparsePauliOpdava luogo a un errore quando i due operatori avevano un numero diverso di coefficienti. Ad esempio:op = SparsePauliOp.from_list([("X", 1), ("Y", 1)]) op2 = SparsePauliOp.from_list([("X", 1), ("Y", 1), ("Z", 0)]) print(op == op2)In precedenza, questo sollevava un
ValueErrorinvece di restituireFalse. -
Corretto il supporto in
transpile()per passare un oggettoInstructionScheduleMapall'oggetto sottostantePassManagerbasato sul metodoTargetperBackendV2basati su backend. In precedenza, la funzionetranspile()non effettuava questa elaborazione e tutti i passaggi del transpiler che non supportano ancora il lavoro con un oggettoTargetnon avrebbero avuto accesso alle calibrazioni degli impulsi predefinite per le istruzioni di un backendBackendV2backend. -
L'opzione
AmplitudeAmplifierè ora correttamente disponibile dal modulo rootqiskit.algorithmsdirettamente dal modulo root. In precedenza non era incluso nelle classi riesportate dal modulo principale ed era accessibile solo daqiskit.algorithms.amplitude_amplifiers. Corretto #7751. -
Corretto un problema con il backend di
mplper la funzione cassetto dei circuiticircuit_drawer()e il metodoQuantumCircuit.draw()per cui le porte con condizioni non venivano visualizzate correttamente quando un numero sufficiente di porte provocava il ripiegamento del cassetto su una seconda fila. Corretto: #7752. -
È stato risolto un problema per cui il metodo
HHL.construct_circuit(), in determinate condizioni, non restituiva un risultato correttoQuantumCircuit. In precedenza, la funzione presentava un errore di arrotondamento nel calcolo del numero di qubit necessari per rappresentare gli autovalori, che causava un'uscita errata del circuito. -
Corretto un bug di endianness in
BaseReadoutMitigator.expectation_value()quando veniva passata una stringadiagonal. Ora sarà correttamente interpretato come little endian, come il resto di Qiskit Terra, invece che come big endian. -
Risolto un problema con il
quantum_info.partial_trace()quando alla funzione è stato chiesto di non tracciare alcun sottosistema, ora restituirà correttamenteDensityMatrixdello stato di input con tutte le dimensioni rimanenti anziché generare un errore. Corretto #7613 -
Corretto un problema con il backend di
textper la funzione cassetto dei circuiticircuit_drawer()e il metodoQuantumCircuit.draw()quando le porte che utilizzano il testo laterale, come i metodiCPhaseGateeRZZGatecon condizioni classiche impostate, non venivano visualizzati correttamente. Corretto #7532. -
Corretto un problema con la funzione
circuit_drawer()e il metododraw()diQuantumCircuit. Quando si utilizza l'opzionereverse_bitscon le opzionimpl,latexotext, i bit senza registri non venivano visualizzati nell'ordine corretto. Corretto #7303. -
È stato risolto un problema nel metodo
LocalReadoutMitigator.assignment_matrix()che in precedenza rifiutava un valore di input per l'argomentoqubitsche non fosse una sequenza banale di qubit nella forma:[0, 1, 2, ..., n-1]. Il problema è stato corretto in modo che ora il metodo accetti qualsiasi elenco di indici di qubit da misurare. -
È stato risolto un problema nel calcolo del valore di aspettativa del metodo
StabilizerState.expectation_value()nel calcolo del valore di aspettativa del metodo, per cui il valore di aspettativa in uscita non era corretto se l'operatore di ingresso per l'argomento aveva una fase non banalePauliper l'argomentooperaveva una fase non banale. Corretto #7441. -
Un'espressione opflow contenente l'identità di Pauli
opflow.Inon produce più un'espressioneIGatequando viene convertita in un circuito. Questo cambiamento risolve una differenza di aspettative; la porta di identità nel circuito indica un ritardo, ma in opflow ci aspettiamo un'identità matematica, cioè nessuna operazione. -
Il
PauliGatenon inserisce più un elementoIGateper Paulis con l'etichetta"I". -
PauliSumOpi test di uguaglianza gestiscono ora il caso in cui uno degli elementi confrontati è un singolo elementoPauliOp. Ad esempio,0 * X + I == Iora viene valutato come Vero, mentre prima di questa versione era Falso. -
Corretto un problema con gli elementi
ALAPScheduleeASAPSchedulequando si lavorava con istruzioni in cui erano state impostate calibrazioni di impulsi personalizzate (ad esempio, cancelli di impulsi). In precedenza, i passaggi di programmazione non utilizzavano la durata della calibrazione personalizzata degli impulsi per queste istruzioni, con il risultato di generare una programmazione errata per il circuito. Questo problema è stato risolto in modo che ora i passaggi di programmazione utilizzino la durata della calibrazione dell'impulso personalizzato per qualsiasi istruzione del circuito che abbia una calibrazione personalizzata. -
Corretto il supporto per l'utilizzo dei parametri delle istruzioni
ParameterExpressionnei parametri dell'istruzione nel passaggioRZXCalibrationBuildernel passaggio del transpiler. In precedenza, se un parametro di istruzione includeva un boundParameterExpressionil passaggio non era in grado di gestirlo correttamente. -
Ha interrotto il parser in
QuantumCircuit.from_qasm_str()efrom_qasm_file()di accettare programmi OpenQASM che si identificano come provenienti da una versione di linguaggio diversa da 2.0. Questo parser è solo per OpenQASM 2.0; il supporto per i circuiti importati da OpenQASM 3.0 sarà aggiunto in una prossima versione. -
L'esportatore OpenQASM 3,
qasm3.Exporterevita i nomi dei registri e dei parametri che si scontrano con le parole chiave riservate di OpenQASM 3, generando un nuovo nome univoco. I registri e i parametri con lo stesso nome non avranno più conflitti di denominazione nell'output di codice dell'esportatore OpenQASM 3. Corretto #7742.
Aer 0.10.3
Nessuna modifica
Ignis 0.7.0
Nessuna modifica
IBM Q Fornitore 0.18.3
Nessuna modifica