Modificări de funcționalități în Qiskit 1.0
Acest ghid descrie căile de migrare pentru cele mai importante modificări de funcționalități din Qiskit 1.0, organizate pe module. Folosește cuprinsul din partea dreaptă pentru a naviga la modulul care te interesează.
Instrumentul de migrare Qiskit 1.0
Pentru a ușura procesul de migrare, poți folosi instrumentul
flake8-qiskit-migration
pentru a detecta căile de import eliminate din codul tău și a sugera alternative.
- Run with pipx
- Run with venv
Dacă ai instalat pipx, rulează pur și simplu
următoarea comandă.
pipx run flake8-qiskit-migration <path-to-source-directory>
Aceasta va instala pachetul într-un mediu virtual temporar și îl va rula pe codul tău.
Dacă nu vrei să folosești pipx, poți crea manual un mediu nou
pentru instrument. Această abordare îți permite și să folosești
nbqa pentru a verifica exemplele de cod din
notebook-urile Jupyter. Șterge mediul când ai terminat.
# Make new environment and install
python -m venv .flake8-qiskit-migration-venv
source .flake8-qiskit-migration-venv/bin/activate
pip install flake8-qiskit-migration
# Run plugin on Python code
flake8 --select QKT100 <path-to-source-directory> # e.g. `src/`
# (Optional) run plugin on notebooks
pip install nbqa
nbqa flake8 ./**/*.ipynb --select QKT100
# Deactivate and delete environment
deactivate
rm -r .flake8-qiskit-migration-venv
Acest instrument detectează doar căile de import eliminate. Nu detectează utilizarea metodelor
eliminate (precum QuantumCircuit.qasm) sau a argumentelor. De asemenea, nu poate urmări
atribuiri de tipul qk = qiskit, deși poate gestiona aliasuri precum
import qiskit as qk.
Pentru mai multe informații, consultă repository-ul proiectului.
Instanțe și funcții globale
Aer
Obiectul qiskit.Aer nu este disponibil în Qiskit 1.0. În schimb, folosește
același obiect din spațiul de nume qiskit_aer, care este un înlocuitor direct.
Pentru a instala qiskit_aer, rulează:
pip install qiskit-aer
BasicAer
Obiectul qiskit.BasicAer nu este disponibil în Qiskit 1.0. Consultă
secțiunea de migrare basicaer pentru
opțiuni de migrare.
execute
Funcția qiskit.execute nu este disponibilă în Qiskit 1.0. Această
funcție a servit ca un wrapper de nivel înalt în jurul funcțiilor
transpile și
run din Qiskit.
În loc de qiskit.execute, folosește funcția
transpile urmată de
backend.run().
# Legacy path
from qiskit import execute
job = execute(circuit, backend)
# New path
from qiskit import transpile
new_circuit = transpile(circuit, backend)
job = backend.run(new_circuit)
Alternativ, primitivul Sampler
este echivalent din punct de vedere semantic cu funcția qiskit.execute eliminată.
Clasa
BackendSampler este un
wrapper generic pentru Backend-uri care nu suportă primitive:
from qiskit.primitives import BackendSampler
sampler = BackendSampler(backend)
job = sampler.run(circuit)
qiskit.circuit
QuantumCircuit.qasm
Metoda QuantumCircuit.qasm a fost eliminată. În schimb, folosește
qasm2.dump sau
qasm2.dumps.
Pentru ieșire formatată cu Pygments, consultă pachetul independent
openqasm-pygments,
deoarece qasm2.dump și qasm2.dumps nu oferă ieșire colorată cu Pygments.
from qiskit import QuantumCircuit
qc = QuantumCircuit(1)
# Old
qasm_str = qc.qasm()
# Alternative
from qiskit.qasm2 import dumps
qasm_str = dumps(qc)
# Alternative: Write to file
from qiskit.qasm2 import dump
with open("my_file.qasm", "w") as f:
dump(qc, f)
Gate-uri QuantumCircuit
Următoarele metode gate au fost eliminate în favoarea unor metode mai consacrate care adaugă aceleași gate-uri:
| Eliminat | Alternativă |
|---|---|
QuantumCircuit.cnot | QuantumCircuit.cx |
QuantumCircuit.toffoli | QuantumCircuit.ccx |
QuantumCircuit.fredkin | QuantumCircuit.cswap |
QuantumCircuit.mct | QuantumCircuit.mcx |
QuantumCircuit.i | QuantumCircuit.id |
QuantumCircuit.squ | QuantumCircuit.unitary |
Următoarele metode de Circuit au fost eliminate. În schimb, aceste gate-uri pot fi
aplicate unui Circuit cu QuantumCircuit.append.
| Eliminat | Alternativă (append) |
|---|---|
QuantumCircuit.diagonal | DiagonalGate |
QuantumCircuit.hamiltonian | HamiltonianGate |
QuantumCircuit.isometry | Isometry |
QuantumCircuit.iso | Isometry |
QuantumCircuit.uc | UCGate |
QuantumCircuit.ucrx | UCRXGate |
QuantumCircuit.ucry | UCRYGate |
QuantumCircuit.ucrz | UCRZGate |
De exemplu, pentru un DiagonalGate:
from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import DiagonalGate # new location in the circuit library
circuit = QuantumCircuit(2)
circuit.h([0, 1]) # some initial state
gate = DiagonalGate([1, -1, -1, 1])
qubits = [0, 1] # qubit indices on which to apply the gate
circuit.append(gate, qubits) # apply the gate
Următoarele metode QuantumCircuit au fost, de asemenea, eliminate:
| Eliminat | Alternativă |
|---|---|
QuantumCircuit.bind_parameters | QuantumCircuit.assign_parameters |
QuantumCircuit.snapshot | instrucțiunile de salvare din qiskit-aer |
qiskit.converters
Funcția qiskit.converters.ast_to_dag a fost eliminată din Qiskit. Aceasta conveertea
arborele de sintaxă abstractă generat de parserul legacy OpenQASM 2 într-un
DAGCircuit. Deoarece
parserul legacy OpenQASM 2 a fost eliminat (vezi qiskit.qasm), această
funcție nu mai are utilitate. În schimb, parsează fișierele tale OpenQASM 2 într-un
QuantumCircuit folosind metodele constructor
QuantumCircuit.from_qasm_file
sau
QuantumCircuit.from_qasm_str
(sau modulul qiskit.qasm2), apoi
convertește acel QuantumCircuit într-un
DAGCircuit cu
circuit_to_dag.
# Previous
from qiskit.converters import ast_to_dag
from qiskit.qasm import Qasm
dag = ast_to_dag(Qasm(filename="myfile.qasm").parse())
# Current alternative
import qiskit.qasm2
from qiskit.converters import circuit_to_dag
dag = circuit_to_dag(qiskit.qasm2.load("myfile.qasm"))
qiskit.extensions
Modulul qiskit.extensions nu mai este disponibil. Majoritatea obiectelor sale au fost
integrate în biblioteca de Circuit-uri
(qiskit.circuit.library). Pentru a migra la
noua locație, înlocuiește pur și simplu qiskit.extensions cu qiskit.circuit.library
în calea de import a obiectului. Aceasta este o înlocuire directă.
# Previous
from qiskit.extensions import DiagonalGate
# Current alternative
from qiskit.circuit.library import DiagonalGate
Clasele mutate în qiskit.circuit.library sunt:
DiagonalGateHamiltonianGateInitializeIsometryqiskit.circuit.library.generalized_gates.mcg_up_diag.MCGupDiagUCGateUCPauliRotGateUCRXGateUCRYGateUCRZGateUnitaryGate
Următoarele clase au fost eliminate din baza de cod, deoarece funcționalitățile lor
erau fie redundante, fie legate de modulul extensions:
| Eliminat | Alternativă |
|---|---|
SingleQubitUnitary | qiskit.circuit.library.UnitaryGate |
Snapshot | Folosește instrucțiunile de salvare din qiskit-aer |
ExtensionError | O clasă de eroare relevantă |
qiskit.primitives
Cea mai notabilă schimbare din modulul qiskit.primitives este
introducerea noii interfețe primitive V2. Această secțiune arată cum să-ți migrezi
fluxul de lucru de la primitives V1 la primitives V2, precum și puținele modificări care au avut loc
în datele de intrare acceptate de interfața V1.
Începând cu versiunea 1.0, vom denumi interfața de primitives anterioară versiunii 1.0 „primitives V1".
Migrează de la V1 la V2
Distincția formală dintre API-urile primitives V1 și V2 constă în clasele de bază din care moștenesc implementările primitives. Pentru a face tranziția la noile clase de bază, poți păstra calea de import originală din qiskit.primitives:
| Migrează de la | Înlocuiește cu |
|---|---|
BaseEstimator | BaseEstimatorV2 |
BaseSampler | BaseSamplerV2 |
Numele implementărilor Qiskit de bază ale primitivelor V2 (cele care pot fi importate din qiskit.primitives)
au fost modificate pentru a clarifica rolul lor ca implementări ce pot fi rulate local
cu un backend simulator statevector. Noile nume nu includ sufixul -V2.
| Migrează de la | Înlocuiește cu |
|---|---|
qiskit.primitives.Estimator | qiskit.primitives.StatevectorEstimator |
qiskit.primitives.Sampler | qiskit.primitives.StatevectorSampler |
Există câteva diferențe conceptuale de care trebuie să ții cont atunci când migrezi de la V1 la V2.
Aceste diferențe sunt impuse de clasa de bază, dar sunt ilustrate în exemplele de mai jos folosind implementările
statevector din qiskit.primitives:
Pentru exemplele de mai jos, presupune că există următoarele importuri și inițializări de primitive:
from qiskit.primitives import (
Sampler,
StatevectorSampler,
Estimator,
StatevectorEstimator,
)
estimator_v1 = Estimator()
sampler_v1 = Sampler()
estimator_v2 = StatevectorEstimator()
sampler_v2 = StatevectorSampler()
# define circuits, observables and parameter values
Sampler and Estimator: Noile primitive V2 sunt proiectate să accepte intrări vectorizate, unde circuite individuale pot fi grupate cu specificații de tip array. Adică, un singur Circuit poate fi executat pentru array-uri denseturi de parametri,nobservabile sau ambele (în cazul Estimator). Fiecare grup se numește primitive unified bloc (pub) și poate fi reprezentat ca un tuplu:(1 x circuit, [n x observables], [n x parameters]). Interfața V1 nu permitea aceeași flexibilitate. În schimb, numărul de circuite de intrare trebuia să corespundă numărului de observabile și de seturi de parametri, după cum se arată în exemplele de mai jos (selectează un tab pentru a vedea fiecare exemplu):
- Estimator, 1 circuit, 4 observables
- Sampler, 1 circuit, 3 parameter sets
- Estimator, 1 circuit, 4 observables, 2 parameter sets
# executing 1 circuit with 4 observables using Estimator V1
job = estimator_v1.run([circuit] * 4, [obs1, obs2, obs3, obs4])
evs = job.result().values
# executing 1 circuit with 4 observables using Estimator V2
job = estimator_v2.run([(circuit, [obs1, obs2, obs3, obs4])])
evs = job.result()[0].data.evs
# executing 1 circuit with 3 parameter sets using Sampler V1
job = sampler_v1.run([circuit] * 3, [vals1, vals2, vals3])
dists = job.result().quasi_dists
# executing 1 circuit with 3 parameter sets using Sampler V2
job = sampler_v2.run([(circuit, [vals1, vals2, vals3])])
counts = job.result()[0].data.meas.get_counts()
# executing 1 circuit with 4 observables and 2 parameter sets using Estimator V1
job = estimator_v1.run([circuit] * 8, [obs1, obs2, obs3, obs4] * 2, [vals1, vals2] * 4)
evs = job.result().values
# executing 1 circuit with 4 observables and 2 parameter sets using Estimator V2
job = estimator_v2.run([(circuit, [[obs1, obs2, obs3, obs4]], [[vals1], [vals2]])])
evs = job.result()[0].data.evs
Primitivele V2 acceptă mai multe PUB-uri ca intrări, iar fiecare PUB primește propriul rezultat. Astfel poți rula circuite diferite cu diverse combinații de parametri/observabile, lucru care nu era întotdeauna posibil în interfața V1:
- Sampler, 2 circuits, 1 parameter set
- Estimator, 2 circuits, 2 different observables
# executing 2 circuits with 1 parameter set using Sampler V1
job = sampler_v1.run([circuit1, circuit2], [vals1] * 2)
dists = job.result().quasi_dists
# executing 2 circuits with 1 parameter set using Sampler V2
job = sampler_v2.run([(circuit1, vals1), (circuit2, vals1)])
counts1 = job.result()[0].data.meas.get_counts() # result for pub 1 (circuit 1)
counts2 = job.result()[1].data.meas.get_counts() # result for pub 2 (circuit 2)
# executing 2 circuits with 2 different observables using Estimator V1
job = estimator_v1.run([circuit1, circuit2] , [obs1, obs2])
evs = job.result().values
# executing 2 circuits with 2 different observables using Estimator V2
job = estimator_v2.run([(circuit1, obs1), (circuit2, obs2)])
evs1 = job.result()[0].data.evs # result for pub 1 (circuit 1)
evs2 = job.result()[1].data.evs # result for pub 2 (circuit 2)
-
Sampler: Sampler-ul V2 returnează acum eșantioanele rezultatelor măsurătorilor sub formă de șiruri de biți sau numărători, în loc de distribuțiile quasi-probabilistice din interfața V1. Șirurile de biți afișează rezultatele măsurătorilor, păstrând ordinea în care au fost măsurate. Obiectele rezultat ale Sampler-ului V2 organizează datele în funcție de numele registrelor clasice ale circuitelor de intrare, pentru compatibilitate cu circuitele dinamice.
# Define quantum circuit with 2 qubits
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
circuit.draw()┌───┐ ░ ┌─┐
q_0: ┤ H ├──■───░─┤M├───
└───┘┌─┴─┐ ░ └╥┘┌─┐
q_1: ─────┤ X ├─░──╫─┤M├
└───┘ ░ ║ └╥┘
meas: 2/══════ ════════╩══╩═
0 1Numele implicit al registrului clasicÎn circuitul de mai sus, observă că numele registrului clasic este implicit
"meas". Acest nume va fi folosit ulterior pentru a accesa șirurile de biți ale măsurătorilor.# Run using V1 sampler
result = sampler_v1.run(circuit).result()
quasi_dist = result.quasi_dists[0]
print(f"The quasi-probability distribution is: {quasi_dist}")The quasi-probability distribution is: {0: 0.5, 3: 0.5}# Run using V2 sampler
result = sampler_v2.run([circuit]).result()
# Access result data for pub 0
data_pub = result[0].data
# Access bitstrings for the classical register "meas"
bitstrings = data_pub.meas.get_bitstrings()
print(f"The number of bitstrings is: {len(bitstrings)}")
# Get counts for the classical register "meas"
counts = data_pub.meas.get_counts()
print(f"The counts are: {counts}")The number of bitstrings is: 1024
The counts are: {'00': 523, '11': 501} -
Sampler and Estimator: Costul de eșantionare, expus în mod obișnuit de implementările V1 prin opțiunea de rulareshots, este acum un argument al metodeirun()a primitivelor, care poate fi specificat la nivelul PUB. Clasele de bază V2 expun argumentele în formate diferite față de API-ul V1:-
BaseSamplerV2.runexpune un argumentshots(similar cu fluxul de lucru anterior):# Sample two circuits at 128 shots each.
sampler_v2.run([circuit1, circuit2], shots=128)
# Sample two circuits at different amounts of shots. The "None"s are necessary
# as placeholders
# for the lack of parameter values in this example.
sampler_v2.run([(circuit1, None, 123), (circuit2, None, 456)]) -
EstimatorV2.runintroduce un argumentprecisioncare specifică marjele de eroare pe care implementarea primitivei ar trebui să le vizeze pentru estimările valorilor de așteptare:# Estimate expectation values for two PUBs, both with 0.05 precision.
estimator_v2.run([(circuit1, obs_array1), (circuit2, obs_array_2)], precision=0.05)
-
Actualizări în interfața V1
-
Conversia implicită dintr-un
BaseOperatordens într-unSparsePauliOpîn argumentele observabilelor dinEstimatornu mai este permisă. Ar trebui să convertești explicit laSparsePauliOpfolosindSparsePauliOp.from_operator(operator)în schimb. -
Folosirea unui
PauliListîn argumentele observabilelor din Estimator nu mai este permisă. În schimb, ar trebui să convertești explicit argumentul folosindSparsePauliOp(pauli_list)mai întâi.
qiskit.providers
basicaer
Cea mai mare parte a funcționalității din modulul qiskit.providers.basicaer a fost
înlocuită cu noul modul
qiskit.providers.basic_provider,
cu excepția claselor UnitarySimulatorPy și StatevectorSimulatorPy,
care au fost eliminate; funcționalitatea lor era deja inclusă în
modulul quantum_info.
Migrarea către noile căi este simplă. Poți înlocui majoritatea
claselor din qiskit.providers.basicaer cu echivalentul lor din
qiskit.providers.basic_provider
(înlocuire directă). Reține că următoarele clase au
căi și nume noi:
| Eliminat | Alternativă |
|---|---|
qiskit.providers.basicaer | qiskit.providers.basic_provider |
BasicAerProvider | BasicProvider |
BasicAerJob | BasicProviderJob |
QasmSimulatorPy | BasicSimulator |
Fii atent la instanțele globale când migrezi la noul modul. Nu există un înlocuitor pentru
instanța globală BasicAer care putea fi importată direct ca qiskit.BasicAer. Asta înseamnă că
from qiskit import BasicProvider nu mai este un import valid.
În schimb, clasa provider trebuie importată din submodulul ei și instanțiată de utilizator:
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("backend_name")
# Current
from qiskit.providers.basic_provider import BasicProvider
backend = BasicProvider().get_backend("backend_name")
Simulatoarele unitar și statevector pot fi înlocuite cu
clase diferite din quantum_info. Aceasta nu este o
înlocuire directă, însă modificările sunt minime. Consultă următoarele exemple
de migrare:
| Eliminat | Alternativă |
|---|---|
UnitarySimulatorPy | quantum_info.Operator |
StatevectorSimulatorPy | quantum_info.Statevector |
Următoarele exemple ilustrează căile de migrare pentru simulatoarele basicaer.
- Statevector simulator
- Unitary simulator
- QASM simulator
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("statevector_simulator")
statevector = backend.run(qc).result().get_statevector()
# Current
qc.remove_final_measurements() # no measurements allowed
from qiskit.quantum_info import Statevector
statevector = Statevector(qc)
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("unitary_simulator")
result = backend.run(qc).result()
# Current
qc.remove_final_measurements() # no measurements allowed
from qiskit.quantum_info import Operator
result = Operator(qc).data
from qiskit import QuantumCircuit
qc = QuantumCircuit(3)
qc.h(0)
qc.h(1)
qc.cx(1, 2)
qc.measure_all()
# Previous
from qiskit import BasicAer
backend = BasicAer.get_backend("qasm_simulator")
result = backend.run(qc).result()
# One current option
from qiskit.providers.basic_provider import BasicProvider
backend = BasicProvider().get_backend("basic_simulator")
result = backend.run(qc).result()
# Another current option is to specify it directly
from qiskit.providers.basic_provider import BasicSimulator
backend = BasicSimulator()
result = backend.run(qc).result()
fake_provider
Majoritatea componentelor vizibile utilizatorului din
qiskit.providers.fake_provider au
fost migrate în pachetul Python qiskit-ibm-runtime. Aceasta include
clasele fake provider, toate Backend-urile false specifice dispozitivelor (cum ar fi
FakeVigo, FakeNairobiV2 și FakeSherbrooke) și clasele de bază ale
Backend-urilor false. Parcurge tab-urile de mai jos pentru a vedea clasele afectate.
- Fake Backends
- Fake Providers
- Orice clasă din
qiskit.providers.fake_provider.backends fake_provider.fake_backend.FakeBackendfake_provider.fake_backend.FakeBackendV2
fake_provider.FakeProviderfake_provider.FakeProviderForBackendV2fake_provider.FakeProviderFactory
Pentru a migra la noul path:
-
Instalează
qiskit-ibm-runtime0.17.1sau o versiune mai recentă:pip install 'qiskit-ibm-runtime>=0.17.1' -
Înlocuiește instanțele
qiskit.providers.fake_providerdin codul tău cuqiskit_ibm_runtime.fake_provider. De exemplu:# Old
from qiskit.providers.fake_provider import FakeProvider
backend1 = FakeProvider().get_backend("fake_ourense")
from qiskit.providers.fake_provider import FakeSherbrooke
backend2 = FakeSherbrooke()
# Alternative
from qiskit_ibm_runtime.fake_provider import FakeProvider
backend1 = FakeProvider().get_backend("fake_ourense")
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
backend2 = FakeSherbrooke()
Clasele de bază ale Backend-urilor false au fost de asemenea migrate, însă au unele diferențe în calea de import:
| Eliminat | Alternativă |
|---|---|
qiskit.providers.fake_provider.FakeQasmBackend | qiskit_ibm_runtime.fake_provider.fake_qasm_backend.FakeQasmBackend |
qiskit.providers.fake_provider.FakePulseBackend | qiskit_ibm_runtime.fake_provider.fake_pulse_backend.FakePulseBackend |
Dacă te bazezi pe Backend-uri false pentru testarea unitară a unei biblioteci dependente și ai conflicte cu
dependența qiskit-ibm-runtime, poți găsi și alternative de Backend-uri false generice native Qiskit.
Acestea includ următoarele clase BackendV1 (înlocuitori direcți):
qiskit.providers.fake_provider.Fake5QV1qiskit.providers.fake_provider.Fake20QV1qiskit.providers.fake_provider.Fake7QPulseV1qiskit.providers.fake_provider.Fake27QPulseV1qiskit.providers.fake_provider.Fake127QPulseV1
Aceasta este o clasă configurabilă care returnează instanțe BackendV2:
fake_provider (special testing backends)
Clasele de Backend fals destinate testelor speciale din
qiskit.providers.fake_provider nu au
fost migrate în qiskit_ibm_runtime.fake_provider. Calea de migrare recomandată
este să folosești noua clasă
GenericBackendV2
pentru a configura un Backend cu proprietăți similare sau pentru a construi un
target personalizat.
| Eliminat | Alternativă |
|---|---|
fake_provider.FakeBackendV2 | fake_provider.GenericBackendV2 |
fake_provider.FakeBackend5QV2 | fake_provider.GenericBackendV2 |
fake_provider.FakeBackendV2LegacyQubitProps | fake_provider.GenericBackendV2 |
fake_provider.FakeBackendSimple | fake_provider.GenericBackendV2 |
fake_provider.ConfigurableFakeBackend | fake_provider.GenericBackendV2 |
Exemplu: Migrează la noua clasă
GenericBackendV2:
# Legacy path
from qiskit.providers.fake_provider import FakeBackend5QV2
backend = FakeBackend5QV2()
# New path
from qiskit.providers.fake_provider import GenericBackendV2
backend = GenericBackendV2(num_qubits=5)
# Note that this class generates a 5q backend with generic
# properties that serves the same purpose as FakeBackend5QV2
# but will not be identical.
Other migration tips
-
Importul din
qiskit.providers.aernu mai este posibil. În schimb, importă dinqiskit_aer, care este un înlocuitor direct. Pentru a instalaqiskit_aer, rulează:pip install qiskit-aer -
Suportul pentru rularea job-urilor pulse pe Backend-uri din
qiskit.providers.fake_providera fost eliminat în Qiskit 1.0. Acest lucru se datorează faptului că Qiskit Aer a eliminat funcționalitatea de simulare pentru astfel de job-uri. Pentru sarcini de lucru de simulare Hamiltoniană la nivel scăzut, ia în considerare utilizarea unei biblioteci specializate, cum ar fi Qiskit Dynamics.
qiskit.pulse
ParametricPulse
Clasa de bază qiskit.pulse.library.parametric_pulses.ParametricPulse și
biblioteca de pulsuri au fost înlocuite de
qiskit.pulse.SymbolicPulse
și biblioteca de pulsuri corespunzătoare. SymbolicPulse suportă
serializarea QPY:
from qiskit import pulse, qpy
with pulse.build() as schedule:
pulse.play(pulse.Gaussian(100, 0.1, 25), pulse.DriveChannel(0))
with open('schedule.qpy', 'wb') as fd:
qpy.dump(schedule, fd)
| Eliminat | Alternativă |
|---|---|
pulse.library.parametric_pulses.ParametricPulse | qiskit.pulse.SymbolicPulse |
pulse.library.parametric_pulses.Constant | pulse.library.symbolic_pulses.Constant |
pulse.library.parametric_pulses.Drag | pulse.library.symbolic_pulses.Drag |
pulse.library.parametric_pulses.Gaussian | pulse.library.symbolic_pulses.Gaussian |
qiskit.pulse.library.parametric_pulses.GaussianSquare | pulse.library.symbolic_pulses.GaussianSquare |
Complex-valued amplitude
Amplitudinea complexă a pulsului (amp) este înlocuită de o pereche (amp,
angle). Această reprezentare este mai intuitivă, mai ales pentru unele
sarcini de calibrare, cum ar fi calibrarea unghiului:
from qiskit import pulse
from qiskit.circuit import Parameter
from math import pi
with pulse.build() as schedule:
angle = Parameter("θ")
pulse.play(pulse.Gaussian(100, 0.1, 25, angle=angle), pulse.DriveChannel(0))
schedule.assign_parameters({angle: pi})
Injecting circuit gate operations
Injectarea operațiunilor Gate din Circuit în contextul builder-ului de pulsuri prin
qiskit.pulse.builder.call nu mai este posibilă.
Această eliminare afectează argumentele de intrare de tip QuantumCircuit, precum și
următoarele funcții:
qiskit.pulse.builder.call_gateqiskit.pulse.builder.cxqiskit.pulse.builder.u1qiskit.pulse.builder.u2qiskit.pulse.builder.u3qiskit.pulse.builder.x
Dacă vrei în continuare să injectezi schedule-uri calibrate de Backend, folosește următorul tipar în locul apelării comenzilor gate.
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit import pulse
backend = GenericBackendV2(num_qubits=5)
sched = backend.target["x"][(qubit,)].calibration
with pulse.build() as only_pulse_scheds:
pulse.call(sched)
De asemenea, un QuantumCircuit poate
fi injectat în contextul builder-ului prin transpilarea și planificarea manuală a
obiectului.
from math import pi
from qiskit.compiler import schedule, transpile
qc = QuantumCircuit(2)
qc.rz(pi / 2, 0)
qc.sx(0)
qc.rz(pi / 2, 0)
qc.cx(0, 1)
qc_t = transpile(qc, backend)
sched = schedule(qc_t, backend)
with pulse.build() as only_pulse_scheds:
pulse.call(sched)
Recomandăm să scrii un program pulse minimal cu builder-ul și să îl atașezi la
QuantumCircuit prin metoda
QuantumCircuit.add_calibration
ca microcod al unei instrucțiuni gate, în loc să scrii întregul
program cu modelul pulse.
builder.build
Următoarele argumente din qiskit.pulse.builder.build au fost eliminate fără
alternativă.
default_transpiler_settingsdefault_circuit_scheduler_settings
Aceste funcții au fost de asemenea eliminate:
qiskit.pulse.builder.active_transpiler_settingsqiskit.pulse.builder.active_circuit_scheduler_settingsqiskit.pulse.builder.transpiler_settingsqiskit.pulse.builder.circuit_scheduler_settings
Motivul este că nu mai este posibil să injectezi obiecte Circuit în contextul builder-ului (consultă Injectarea operațiunilor gate de tip circuit); aceste setări erau folosite pentru conversia obiectelor injectate în reprezentări pulse.
library
Biblioteca de pulsuri discrete a fost eliminată din codul sursă. Aceasta include:
qiskit.pulse.library.constantqiskit.pulse.library.zeroqiskit.pulse.library.squareqiskit.pulse.library.sawtoothqiskit.pulse.library.triangleqiskit.pulse.library.cosqiskit.pulse.library.sinqiskit.pulse.library.gaussianqiskit.pulse.library.gaussian_derivqiskit.pulse.library.sechqiskit.pulse.library.sech_derivqiskit.pulse.library.gaussian_squareqiskit.pulse.library.drag
În schimb, folosește
qiskit.pulse.SymbolicPulse
corespunzătoare, împreună cu
SymbolicPulse.get_waveform().
De exemplu, în loc de pulse.gaussian(100,0.5,10), folosește
pulse.Gaussian(100,0.5,10).get_waveform(). Reține că faza atât pentru
Sawtooth, cât și pentru
Square este definită astfel
încât o fază de 2\\pi produce o deplasare de un ciclu complet, contrar
variantei discrete. De asemenea, reține că amplitudinile complexe nu mai sunt acceptate în
biblioteca de pulsuri simbolice; folosește în schimb float, amp și angle.
ScalableSymbolicPulse
Nu mai este posibil să încarci obiecte qiskit.pulse.ScalableSymbolicPulse din bibliotecă
cu un parametru amp complex din fișiere qpy de versiunea 5 sau mai vechi
(Qiskit Terra < 0.23.0). Nu este necesară nicio acțiune de migrare, deoarece amp complex va fi
convertit automat la float (amp, angle).
Această modificare se aplică următoarelor pulsuri:
qiskit.qasm
Modulul legacy de parsare OpenQASM 2 care se afla anterior în qiskit.qasm a fost
înlocuit de modulul qiskit.qasm2, care
oferă un parser mai rapid și mai precis pentru OpenQASM 2. Metodele de nivel înalt ale
QuantumCircuit,
from_qasm_file()
și
from_qasm_str(),
rămân neschimbate, dar vor folosi intern noul parser. Totuși, interfața publică
a modulului qasm2 nu este aceeași. În timp ce modulul qiskit.qasm
furniza o interfață către un arbore de sintaxă abstractă returnat de biblioteca de parser ply,
qiskit.qasm2 nu expune AST-ul sau detalii de implementare de nivel inferior despre parser. Acesta
primește date de intrare OpenQASM 2 și
generează un obiect QuantumCircuit.
De exemplu, dacă rulai anterior ceva similar cu:
import qiskit.qasm
from qiskit.converters import ast_to_dag, dag_to_circuit
ast = qiskit.qasm.Qasm(filename="myfile.qasm").parse()
dag = ast_to_dag(ast)
qasm_circ = dag_to_circuit(dag)
Înlocuiește cu următorul cod:
import qiskit.qasm2
qasm_circ = qiskit.qasm2.load("myfile.qasm")
qiskit.quantum_info
Modulul qiskit.quantum_info.synthesis a fost mutat în diverse
locații din codul sursă, în principal în qiskit.synthesis.
| Eliminat | Alternativă |
|---|---|
OneQubitEulerDecomposer | qiskit.synthesis.one_qubit.OneQubitEulerDecomposer |
TwoQubitBasisDecomposer | qiskit.synthesis.two_qubits.TwoQubitBasisDecomposer |
XXDecomposer | qiskit.synthesis.two_qubits.XXDecomposer |
two_qubit_cnot_decompose | qiskit.synthesis.two_qubits.two_qubit_cnot_decompose |
Quaternion | qiskit.quantum_info.Quaternion |
Această mutare nu a afectat calea obișnuită de import a Quaternion, dar nu mai poți accesa
modulul prin qiskit.quantum_info.synthesis.
În final, cnot_rxx_decompose a fost eliminat.
qiskit.test
Modulul qiskit.test nu mai este un modul public. Acesta nu a fost niciodată destinat utilizării publice,
nici în afara suitei de teste Qiskit. Toată funcționalitatea era specifică pentru Qiskit și nu
există alternativă disponibilă; dacă aveai nevoie de funcționalitate similară, ar trebui să o incluzi în propriile
infrastructuri de testare.
qiskit.tools
Modulul qiskit.tools a fost eliminat în Qiskit 1.0. Cea mai mare parte a funcționalității sale a fost
fie înlocuită cu funcționalitate similară în alte pachete, fie eliminată fără alternativă.
Excepția principală este funcția qiskit.tools.parallel_map(), care a fost mutată în
modulul qiskit.utils. Poate fi utilizată
din această nouă locație. De exemplu:
Dacă rulai anterior:
# Previous
from qiskit.tools import parallel_map
parallel_map(func, input)
# Current
from qiskit.utils import parallel_map
parallel_map(func, input)
jupyter
Submodulul qiskit.tools.jupyter a fost eliminat deoarece funcționalitatea
din acest modul este legată de pachetul moștenire qiskit-ibmq-provider, care nu mai
este acceptat. De asemenea, suporta doar BackendV1, nu și interfața mai nouă
BackendV2.
monitor
Submodulul qiskit.tools.monitor a fost eliminat deoarece era legat de
pachetul moștenire qiskit-ibmq-provider, care nu mai este acceptat (suporta, de
asemenea, doar interfața BackendV1, nu și cea mai nouă
BackendV2). Nu
există nicio alternativă furnizată pentru această funcționalitate.
visualization
Submodulul qiskit.tools.visualization a fost eliminat. Acest modul era o
redirecționare moștenire din locația originală a modulului de vizualizare Qiskit și
a fost mutat în qiskit.visualization în Qiskit
0.8.0. Dacă folosești în continuare această cale, actualizează importurile din
qiskit.tools.visualization în
qiskit.visualization.
# Previous
from qiskit.tools.visualization import plot_histogram
plot_histogram(counts)
# Current
from qiskit.visualization import plot_histogram
plot_histogram(counts)
events
Modulul qiskit.tools.events și utilitarul progressbar() pe care îl expunea
au fost eliminate. Funcționalitatea acestui modul nu era utilizată pe scară largă și este
mai bine acoperită de pachete dedicate, precum
tqdm.
qiskit.transpiler
synthesis
Elementele din modulul qiskit.transpiler.synthesis au fost migrate în locații noi:
| Eliminat | Alternativă |
|---|---|
qiskit.transpiler.synthesis.aqc (cu excepția AQCSynthesisPlugin) | qiskit.synthesis.unitary.aqc |
qiskit.transpiler.synthesis.graysynth | qiskit.synthesis.synth_cnot_phase_aam |
qiskit.transpiler.synthesis.cnot_synth | qiskit.synthesis.synth_cnot_count_full_pmh |
passes
Pasul Transpiler NoiseAdaptiveLayout a fost înlocuit de
VF2Layout și
VF2PostLayout,
care stabilesc un layout pe baza caracteristicilor de zgomot raportate ale unui
backend. Atât pasul, cât și plugin-ul de etapă de layout "noise_adaptive" corespunzător
au fost eliminate din Qiskit.
Pasul Transpiler CrosstalkAdaptiveSchedule a fost eliminat din
codul sursă. Acest pas nu mai putea fi utilizat deoarece funcționarea sa internă
depindea de proprietăți personalizate setate în payload-ul BackendProperties
al unei instanțe BackendV1. Deoarece niciun backend nu setează aceste câmpuri, pasul a
fost eliminat.
passmanager
Metodele append ale claselor
ConditionalController,
FlowControllerLinear și
DoWhileController
au fost eliminate. În schimb, toate sarcinile trebuie furnizate la momentul construirii
obiectelor controler.
qiskit.utils
Următoarele instrumente din qiskit.utils au fost eliminate fără alternativă:
qiskit.utils.arithmeticqiskit.utils.circuit_utilsqiskit.utils.entangler_mapqiskit.utils.name_unnamed_args
Aceste funcții erau utilizate exclusiv în modulele qiskit.algorithms și
qiskit.opflow, care au fost, de asemenea, eliminate.
qiskit.visualization
Modulul qiskit.visualization.qcstyle a fost eliminat. Folosește
qiskit.visualization.circuit.qcstyle ca înlocuitor direct.