Zmiany funkcji w Qiskit 1.0
Ten przewodnik opisuje ścieżki migracji dla najważniejszych zmian funkcji w Qiskit 1.0, uporządkowanych według modułów. Skorzystaj ze spisu treści po prawej stronie, aby przejść do interesującego cię modułu.
Narzędzie migracyjne Qiskit 1.0
Aby ułatwić proces migracji, możesz użyć narzędzia
flake8-qiskit-migration,
które wykrywa usunięte ścieżki importów w twoim kodzie i sugeruje alternatywy.
- Uruchom z pipx
- Uruchom z venv
Jeśli masz zainstalowane pipx, po prostu uruchom
następujące polecenie.
pipx run flake8-qiskit-migration <path-to-source-directory>
Spowoduje to zainstalowanie pakietu w tymczasowym środowisku wirtualnym i uruchomienie go na twoim kodzie.
Jeśli nie chcesz używać pipx, możesz ręcznie utworzyć nowe
środowisko dla narzędzia. Takie podejście pozwala też używać
nbqa do sprawdzania przykładów kodu w
notebookach Jupyter. Usuń środowisko po zakończeniu.
# 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
To narzędzie wykrywa jedynie usunięte ścieżki importów. Nie wykrywa użycia usuniętych
metod (takich jak QuantumCircuit.qasm) ani argumentów. Nie śledzi też
przypisań w stylu qk = qiskit, choć radzi sobie z aliasami takimi jak
import qiskit as qk.
Więcej informacji znajdziesz w repozytorium projektu.
Globalne instancje i funkcje
Aer
Obiekt qiskit.Aer nie jest dostępny w Qiskit 1.0. Zamiast tego użyj
tego samego obiektu z przestrzeni nazw qiskit_aer, która jest bezpośrednim zamiennikiem.
Aby zainstalować qiskit_aer, uruchom:
pip install qiskit-aer
BasicAer
Obiekt qiskit.BasicAer nie jest dostępny w Qiskit 1.0. Sprawdź
sekcję migracji basicaer, aby poznać
opcje migracji.
execute
Funkcja qiskit.execute nie jest dostępna w Qiskit 1.0. Funkcja ta
służyła jako wysokopoziomowe opakowanie wokół funkcji
transpile oraz
run w Qiskit.
Zamiast qiskit.execute, użyj funkcji
transpile, a następnie
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)
Alternatywnie, prymityw Sampler
jest semantycznie równoważny usuniętej funkcji qiskit.execute.
Klasa
BackendSampler to
ogólne opakowanie dla Backendów, które nie obsługują prymitywów:
from qiskit.primitives import BackendSampler
sampler = BackendSampler(backend)
job = sampler.run(circuit)
qiskit.circuit
QuantumCircuit.qasm
Metoda QuantumCircuit.qasm została usunięta. Zamiast niej użyj
qasm2.dump lub
qasm2.dumps.
Jeśli potrzebujesz sformatowanego wyjścia Pygments, skorzystaj z samodzielnego pakietu
openqasm-pygments,
ponieważ qasm2.dump i qasm2.dumps nie zapewniają kolorowania składni przez 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)
Bramki QuantumCircuit
Następujące metody bramek zostały usunięte na rzecz bardziej ugruntowanych metod, które dodają te same Gate:
| Usunięte | Alternatywa |
|---|---|
QuantumCircuit.cnot | QuantumCircuit.cx |
QuantumCircuit.toffoli | QuantumCircuit.ccx |
QuantumCircuit.fredkin | QuantumCircuit.cswap |
QuantumCircuit.mct | QuantumCircuit.mcx |
QuantumCircuit.i | QuantumCircuit.id |
QuantumCircuit.squ | QuantumCircuit.unitary |
Następujące metody Circuit zostały usunięte. Zamiast nich Gate można dodawać do Circuit
za pomocą QuantumCircuit.append.
| Usunięte | Alternatywa (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 |
Na przykład dla 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
Usunięto również następujące metody QuantumCircuit:
| Usunięte | Alternatywa |
|---|---|
QuantumCircuit.bind_parameters | QuantumCircuit.assign_parameters |
QuantumCircuit.snapshot | Instrukcje zapisu save instructions z qiskit-aer |
qiskit.converters
Funkcja qiskit.converters.ast_to_dag została usunięta z Qiskit. Konwertowała ona
abstrakcyjne drzewo składniowe generowane przez przestarzały parser OpenQASM 2 na
DAGCircuit. Ponieważ
przestarzały parser OpenQASM 2 został usunięty (patrz qiskit.qasm),
funkcja ta nie ma już zastosowania. Zamiast tego wczytaj pliki OpenQASM 2 do
QuantumCircuit przy użyciu metod konstruktora
QuantumCircuit.from_qasm_file
lub
QuantumCircuit.from_qasm_str
(albo modułu qiskit.qasm2), a następnie
przekonwertuj ten QuantumCircuit na
DAGCircuit za pomocą
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
Moduł qiskit.extensions nie jest już dostępny. Większość jego obiektów została
zintegrowana z biblioteką Circuit
(qiskit.circuit.library). Aby przejść na
nową lokalizację, wystarczy zastąpić qiskit.extensions przez qiskit.circuit.library
w ścieżce importu obiektu. Jest to zamiennik bezpośredni (drop-in replacement).
# Previous
from qiskit.extensions import DiagonalGate
# Current alternative
from qiskit.circuit.library import DiagonalGate
Klasy przeniesione do qiskit.circuit.library to:
DiagonalGateHamiltonianGateInitializeIsometryqiskit.circuit.library.generalized_gates.mcg_up_diag.MCGupDiagUCGateUCPauliRotGateUCRXGateUCRYGateUCRZGateUnitaryGate
Następujące klasy zostały usunięte z kodu źródłowego, ponieważ ich funkcje były
redundantne lub powiązane z modułem extensions:
| Usunięte | Alternatywa |
|---|---|
SingleQubitUnitary | qiskit.circuit.library.UnitaryGate |
Snapshot | Użyj instrukcji zapisu save instructions z qiskit-aer |
ExtensionError | Odpowiednia klasa błędu |
qiskit.primitives
Najbardziej znaczącą zmianą w module qiskit.primitives jest
wprowadzenie nowego interfejsu prymitywów V2. Ta sekcja pokazuje, jak przenieść swój
przepływ pracy z prymitywów V1 do prymitywów V2, a także nieliczne zmiany, które zaszły
w danych wejściowych akceptowanych przez interfejs V1.
Począwszy od wersji 1.0, będziemy odnosić się do interfejsu prymitywów sprzed wersji 1.0 jako „prymitywy V1".
Migracja z V1 do V2
Formalne rozróżnienie między API prymitywów V1 i V2 wynika z klas bazowych, po których dziedziczą implementacje prymitywów. Aby przejść na nowe klasy bazowe, możesz zachować oryginalną ścieżkę importu z qiskit.primitives:
| Migruj z | Zamień na |
|---|---|
BaseEstimator | BaseEstimatorV2 |
BaseSampler | BaseSamplerV2 |
Nazwy implementacji prymitywów V2 w rdzeniu qiskit (tych importowalnych z qiskit.primitives)
zostały zmienione, aby lepiej oddać ich przeznaczenie jako implementacji, które można uruchamiać lokalnie
z backendem symulatora wektorów stanu. Nowe nazwy nie zawierają sufiksu -V2.
| Migruj z | Zamień na |
|---|---|
qiskit.primitives.Estimator | qiskit.primitives.StatevectorEstimator |
qiskit.primitives.Sampler | qiskit.primitives.StatevectorSampler |
Podczas migracji z V1 do V2 warto wziąć pod uwagę pewne różnice koncepcyjne.
Wynikają one z klasy bazowej, ale zostały pokazane w poniższych przykładach z użyciem implementacji opartych na wektorach stanu
dostępnych w qiskit.primitives:
W poniższych przykładach przyjmij następujące importy i inicjalizacje prymitywów:
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 i Estimator: Nowe prymitywy V2 są zaprojektowane do przyjmowania wektoryzowanych danych wejściowych, gdzie pojedyncze Circuit mogą być grupowane ze specyfikacjami w postaci tablic. Oznacza to, że jeden Circuit może być wykonany dla tablicnzestawów parametrów,nobserwabli lub obu jednocześnie (w przypadku Estimatora). Każda taka grupa nazywana jest primitive unified bloc (PUB) i może być reprezentowana jako krotka:(1 x Circuit, [n x obserwable], [n x parametry]). Interfejs V1 nie pozwalał na taką samą elastyczność. Zamiast tego liczba wejściowych Circuitów musiała odpowiadać liczbie obserwabli i zestawów parametrów, co pokazują poniższe przykłady (wybierz zakładkę, aby zobaczyć każdy z nich):
- 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
Prymitywy V2 przyjmują wiele PUBów jako dane wejściowe, a każdy PUB otrzymuje własny wynik. Pozwala to uruchamiać różne Circuity z różnymi kombinacjami parametrów i obserwabli, co nie zawsze było możliwe w interfejsie 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 V2 zwraca teraz wyniki pomiarów w postaci łańcuchów bitów (bitstrings) lub zliczeń (counts), zamiast quasi-rozkładów prawdopodobieństwa z interfejsu V1. Łańcuchy bitów pokazują wyniki pomiarów, zachowując kolejność shotów, w jakiej zostały zmierzone. Obiekty wyników Samplera V2 porządkują dane według nazw klasycznych rejestrów wejściowych Circuitów, co zapewnia kompatybilność z dynamicznymi Circuitami.
# 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 1Domyślna nazwa klasycznego rejestruW powyższym Circuit zwróć uwagę, że nazwa klasycznego rejestru domyślnie to
"meas". Ta nazwa będzie używana później do dostępu do łańcuchów bitów pomiarów.# 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 i Estimator: Narzut próbkowania, powszechnie udostępniany przez implementacje V1 poprzez opcję uruchomieniashots, jest teraz argumentem metodyrun()prymitywów, który można określić na poziomie PUB. Klasy bazowe V2 udostępniają argumenty w formatach różniących się od API V1:-
BaseSamplerV2.runudostępnia argumentshots(podobnie jak w poprzednim podejściu):# 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.runwprowadza argumentprecision, który określa słupki błędów, jakie implementacja prymitywu powinna osiągać dla estymacji wartości oczekiwanych:# Estimate expectation values for two PUBs, both with 0.05 precision.
estimator_v2.run([(circuit1, obs_array1), (circuit2, obs_array_2)], precision=0.05)
-
Aktualizacje w interfejsie V1
-
Niejawna konwersja z gęstego
BaseOperatordoSparsePauliOpw argumentach obserwabliEstimatoranie jest już dozwolona. Zamiast tego należy jawnie dokonać konwersji doSparsePauliOpza pomocąSparsePauliOp.from_operator(operator). -
Używanie
PauliListw argumentach obserwabli Estimatora nie jest już dozwolone. Zamiast tego należy jawnie przekonwertować argument, używając najpierwSparsePauliOp(pauli_list).
qiskit.providers
basicaer
Większość funkcjonalności modułu qiskit.providers.basicaer została zastąpiona nowym modułem
qiskit.providers.basic_provider,
z wyjątkiem klas UnitarySimulatorPy i StatevectorSimulatorPy,
które zostały usunięte; ich funkcjonalność była już zawarta w
module quantum_info.
Migracja do nowych ścieżek jest prosta. Większość klas z qiskit.providers.basicaer możesz zastąpić
ich odpowiednikami z
qiskit.providers.basic_provider
(zamienniki drop-in). Pamiętaj, że następujące klasy mają
nowe ścieżki i nazwy:
| Usunięto | Alternatywa |
|---|---|
qiskit.providers.basicaer | qiskit.providers.basic_provider |
BasicAerProvider | BasicProvider |
BasicAerJob | BasicProviderJob |
QasmSimulatorPy | BasicSimulator |
Pamiętaj o globalnych instancjach podczas migracji do nowego modułu. Nie ma zamiennika
dla globalnej instancji BasicAer, którą można było importować bezpośrednio jako qiskit.BasicAer. Oznacza to, że
from qiskit import BasicProvider nie jest już prawidłowym importem.
Zamiast tego klasa dostawcy musi być importowana ze swojego podmodułu i tworzona przez użytkownika:
# 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")
Symulatora unitarnego i symulator wektora stanu można zastąpić
różnymi klasami z quantum_info. Nie jest to
zamiennik drop-in, ale zmiany są minimalne. Zobacz poniższe przykłady migracji:
| Usunięto | Alternatywa |
|---|---|
UnitarySimulatorPy | quantum_info.Operator |
StatevectorSimulatorPy | quantum_info.Statevector |
Poniższe przykłady pokazują ścieżki migracji symulatorów basicaer.
- Symulator wektora stanu
- Symulator unitarny
- Symulator QASM
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
Większość komponentów qiskit.providers.fake_provider widocznych dla użytkownika została
przeniesiona do pakietu Python qiskit-ibm-runtime. Obejmuje to
klasy fałszywych dostawców, wszystkie fałszywe Backend-y specyficzne dla urządzeń (takie jak
FakeVigo, FakeNairobiV2 i FakeSherbrooke) oraz klasy bazowe fałszywych Backend-ów. Kliknij w poniższe zakładki, aby zobaczyć dotknięte klasy.
- Fałszywe Backend-y
- Fałszywi dostawcy
- Dowolna klasa w
qiskit.providers.fake_provider.backends fake_provider.fake_backend.FakeBackendfake_provider.fake_backend.FakeBackendV2
fake_provider.FakeProviderfake_provider.FakeProviderForBackendV2fake_provider.FakeProviderFactory
Aby przeprowadzić migrację do nowej ścieżki:
-
Zainstaluj
qiskit-ibm-runtimew wersji0.17.1lub nowszej:pip install 'qiskit-ibm-runtime>=0.17.1' -
Zastąp wystąpienia
qiskit.providers.fake_providerw swoim kodzie przezqiskit_ibm_runtime.fake_provider. Na przykład:# 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()
Klasy bazowe fałszywych Backend-ów również zostały przeniesione, ale mają pewne różnice w ścieżce importu:
| Usunięto | Alternatywa |
|---|---|
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 |
Jeśli zależysz od fałszywych Backend-ów do testów jednostkowych biblioteki downstream i masz konflikty z
zależnością qiskit-ibm-runtime, możesz znaleźć nowe alternatywy ogólnych fałszywych Backend-ów natywnych dla Qiskit.
Należą do nich następujące klasy BackendV1 (zamienniki drop-in):
qiskit.providers.fake_provider.Fake5QV1qiskit.providers.fake_provider.Fake20QV1qiskit.providers.fake_provider.Fake7QPulseV1qiskit.providers.fake_provider.Fake27QPulseV1qiskit.providers.fake_provider.Fake127QPulseV1
Ta konfigurowalna klasa zwraca instancje BackendV2:
fake_provider (specjalne Backend-y do testowania)
Klasy fałszywych Backend-ów do specjalnych celów testowych w
qiskit.providers.fake_provider nie zostały przeniesione do qiskit_ibm_runtime.fake_provider. Zalecaną
ścieżką migracji jest użycie nowej klasy
GenericBackendV2
do skonfigurowania Backend-u o podobnych właściwościach lub zbudowanie niestandardowego
targetu.
| Usunięto | Alternatywa |
|---|---|
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 |
Przykład: migracja do nowej klasy
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.
Inne wskazówki dotyczące migracji
-
Importowanie z
qiskit.providers.aernie jest już możliwe. Zamiast tego importuj zqiskit_aer, który jest zamiennikiem drop-in. Aby zainstalowaćqiskit_aer, uruchom:pip install qiskit-aer -
Obsługa uruchamiania zadań pulsowych na Backend-ach z
qiskit.providers.fake_providerzostała usunięta w Qiskit 1.0. Jest to spowodowane tym, że Qiskit Aer usunął swoją funkcjonalność symulacji dla takich zadań. W przypadku niskopoziomowych obciążeń symulacji hamiltonowskiej rozważ użycie specjalistycznej biblioteki, takiej jak Qiskit Dynamics.
qiskit.pulse
ParametricPulse
Klasa bazowa qiskit.pulse.library.parametric_pulses.ParametricPulse oraz
biblioteka pulsów zostały zastąpione przez
qiskit.pulse.SymbolicPulse
i odpowiadającą jej bibliotekę pulsów. SymbolicPulse obsługuje serializację
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)
| Usunięte | Alternatywa |
|---|---|
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 |
Amplituda o wartości zespolonej
Amplituda pulsu o wartości zespolonej (amp) została zastąpiona parą (amp,
angle). Taka reprezentacja jest bardziej intuicyjna, szczególnie przy niektórych
zadaniach kalibracyjnych, takich jak kalibracja kąta:
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})
Wstrzykiwanie operacji Gate z Circuit
Wstrzykiwanie operacji Gate z Circuit do kontekstu konstruktora pulsów za pomocą
qiskit.pulse.builder.call nie jest już możliwe.
Usunięcie to dotyczy argumentów wejściowych typu QuantumCircuit, a także
następujących funkcji:
qiskit.pulse.builder.call_gateqiskit.pulse.builder.cxqiskit.pulse.builder.u1qiskit.pulse.builder.u2qiskit.pulse.builder.u3qiskit.pulse.builder.x
Jeśli nadal chcesz wstrzykiwać harmonogramy skalibrowane przez Backend, użyj poniższego wzorca zamiast wywo ływania poleceń 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)
Podobnie, QuantumCircuit można
wstrzyknąć do kontekstu konstruktora poprzez ręczną transpilację i zaplanowanie
obiektu.
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)
Zalecamy pisanie minimalnego programu pulsowego przy użyciu konstruktora i
dołączanie go do QuantumCircuit za pomocą metody
QuantumCircuit.add_calibration
jako mikrokodu instrukcji Gate, zamiast pisania całego programu przy użyciu
modelu pulsowego.
builder.build
Następujące argumenty funkcji qiskit.pulse.builder.build zostały usunięte bez
alternatywy.
default_transpiler_settingsdefault_circuit_scheduler_settings
Usunięto również te funkcje:
qiskit.pulse.builder.active_transpiler_settingsqiskit.pulse.builder.active_circuit_scheduler_settingsqiskit.pulse.builder.transpiler_settingsqiskit.pulse.builder.circuit_scheduler_settings
Wynika to z tego, że nie jest już możliwe wstrzykiwanie obiektów Circuit do kontekstu konstruktora (zob. Wstrzykiwanie operacji Gate z Circuit); te ustawienia służyły do konwertowania wstrzykiwanych obiektów na reprezentacje pulsowe.
library
Dyskretna biblioteka pulsów została usunięta z bazy kodu. Obejmuje to:
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
Zamiast nich użyj odpowiadającego
qiskit.pulse.SymbolicPulse
z metodą
SymbolicPulse.get_waveform().
Na przykład zamiast pulse.gaussian(100,0.5,10) użyj
pulse.Gaussian(100,0.5,10).get_waveform(). Zwróć uwagę, że faza zarówno
Sawtooth jak i
Square jest zdefiniowana tak,
że faza 2\\pi przesuwa o pełny cykl, w przeciwieństwie do dyskretnego odpowiednika.
Zauważ też, że amplitudy zespolone nie są już obsługiwane w bibliotece pulsów symbolicznych;
zamiast nich użyj float, amp i angle.
ScalableSymbolicPulse
Nie jest już możliwe wczytywanie obiektów qiskit.pulse.ScalableSymbolicPulse
z biblioteki z zespolonym parametrem amp z plików qpy w wersji 5 lub wcześniejszej
(Qiskit Terra < 0.23.0). Nie jest wymagane żadne działanie migracyjne, gdyż
zespolone amp zostanie automatycznie przekonwertowane na float (amp, angle).
Ta zmiana dotyczy następujących pulsów:
qiskit.qasm
Poprzedni moduł parsera OpenQASM 2 dostępny w qiskit.qasm został zastąpiony przez moduł qiskit.qasm2, który zapewnia szybszy i dokładniejszy parser dla OpenQASM 2. Wysokopoziomowe metody QuantumCircuit
from_qasm_file()
oraz
from_qasm_str()
pozostają bez zmian, ale wewnętrznie będą korzystać z nowego parsera. Publiczny interfejs modułu qasm2 nie jest jednak taki sam. Podczas gdy moduł qiskit.qasm udostępniał interfejs do abstrakcyjnego drzewa składniowego zwracanego przez bibliotekę parsera ply, moduł qiskit.qasm2 nie eksponuje AST ani żadnych szczegółów implementacyjnych parsera na niższym poziomie. Zamiast tego przyjmuje wejście w formacie OpenQASM 2 i zwraca obiekt QuantumCircuit.
Na przykład, jeśli wcześniej używałeś czegoś takiego:
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)
Zastąp to następującym kodem:
import qiskit.qasm2
qasm_circ = qiskit.qasm2.load("myfile.qasm")
qiskit.quantum_info
Moduł qiskit.quantum_info.synthesis został przeniesiony do różnych lokalizacji w bazie kodu, głównie do qiskit.synthesis.
| Usunięto | Alternatywa |
|---|---|
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 |
Przeniesienie nie wpłynęło na standardową ścieżkę importu Quaternion, ale nie możesz już uzyskać do niej dostępu przez qiskit.quantum_info.synthesis.
Na koniec, cnot_rxx_decompose zostało usunięte.
qiskit.test
Moduł qiskit.test nie jest już modułem publicznym. Nigdy nie był przeznaczony do użytku publicznego ani do stosowania poza zestawem testów Qiskit. Cała funkcjonalność była specyficzna dla Qiskit i nie przewidziano żadnej alternatywy; jeśli potrzebujesz podobnej funkcjonalności, powinieneś umieścić ją we własnych zestawach testowych.
qiskit.tools
Moduł qiskit.tools został usunięty w Qiskit 1.0. Większość tej funkcjonalności została zastąpiona podobną funkcjonalnością w innych pakietach lub usunięta bez alternatywy. Głównym wyjątkiem jest funkcja qiskit.tools.parallel_map(), która została przeniesiona do modułu qiskit.utils. Można jej używać w tej nowej lokalizacji. Na przykład:
Jeśli wcześniej używałeś:
# Previous
from qiskit.tools import parallel_map
parallel_map(func, input)
# Current
from qiskit.utils import parallel_map
parallel_map(func, input)
jupyter
Submoduł qiskit.tools.jupyter został usunięty, ponieważ funkcjonalność tego modułu była powiązana ze starszym pakietem qiskit-ibmq-provider, który nie jest już obsługiwany. Ponadto obsługiwał wyłącznie BackendV1, a nie nowszy interfejs BackendV2.
monitor
Submoduł qiskit.tools.monitor został usunięty, ponieważ był powiązany ze starszym pakietem qiskit-ibmq-provider, który nie jest już obsługiwany (obsługiwał on również wyłącznie interfejs BackendV1, a nie nowszy BackendV2). Dla tej funkcjonalności nie przewidziano żadnej alternatywy.
visualization
Submoduł qiskit.tools.visualization został usunięty. Był to przestarzały przekierowanie ze pierwotnej lokalizacji modułu wizualizacji Qiskit, który w wersji Qiskit 0.8.0 został przeniesiony do qiskit.visualization. Jeśli nadal korzystasz z tej ścieżki, zaktualizuj importy z qiskit.tools.visualization na qiskit.visualization.
# Previous
from qiskit.tools.visualization import plot_histogram
plot_histogram(counts)
# Current
from qiskit.visualization import plot_histogram
plot_histogram(counts)
events
Moduł qiskit.tools.events oraz udostępniana przez niego funkcja narzędziowa progressbar() zostały usunięte. Funkcjonalność tego modułu nie była powszechnie używana i jest lepiej realizowana przez dedykowane pakiety, takie jak tqdm.
qiskit.transpiler
synthesis
Elementy modułu qiskit.transpiler.synthesis zostały przeniesione do nowych lokalizacji:
| Usunięto | Alternatywa |
|---|---|
qiskit.transpiler.synthesis.aqc (z wyjątkiem 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
Przebieg Transpilera NoiseAdaptiveLayout został zastąpiony przez
VF2Layout i
VF2PostLayout,
które ustawiają układ na podstawie zgłoszonych charakterystyk szumów Backend. Zarówno ten przebieg, jak i odpowiadająca mu wtyczka etapu układu "noise_adaptive" zostały usunięte z Qiskit.
Przebieg Transpilera CrosstalkAdaptiveSchedule został usunięty z bazy kodu. Ten przebieg nie był już użyteczny, ponieważ jego wewnętrzne działanie było uzależnione od niestandardowych właściwości ustawianych w ładunku BackendProperties instancji BackendV1. Ponieważ żaden Backend nie ustawiał tych pól, przebieg został usunięty.
passmanager
Metody append klas
ConditionalController,
FlowControllerLinear i
DoWhileController
zostały usunięte. Zamiast tego wszystkie zadania muszą być przekazane podczas konstruowania obiektów kontrolera.
qiskit.utils
Następujące narzędzia w qiskit.utils zostały usunięte bez zastępnika:
qiskit.utils.arithmeticqiskit.utils.circuit_utilsqiskit.utils.entangler_mapqiskit.utils.name_unnamed_args
Funkcje te były używane wyłącznie w modułach qiskit.algorithms i qiskit.opflow, które również zostały usunięte.
qiskit.visualization
Moduł qiskit.visualization.qcstyle został usunięty. Użyj
qiskit.visualization.circuit.qcstyle jako bezpośredniego zamiennika.