Qiskit v1.0 の機能変更
このガイドでは、Qiskit v1.0 における最も重要な機能変更の移行パスをモジュール別に説明します。 右側の目次から、対象のモジュールへ移動してください。
Qiskit v1.0 移行ツール
移行作業を簡略化するために、
flake8-qiskit-migration
ツールを使用することができます。このツールはコード内の削除されたインポートパスを検出し、代替手段を提案します。
- pipx で実行
- venv で実行
pipx がインストールされている場合は、以下のコマンドを実行するだけです。
pipx run flake8-qiskit-migration <path-to-source-directory>
このコマンドは一時的な仮想環境にパッケージをインストールし、 コードに対して実行します。
pipx を使用したくない場合は、ツール用の新しい環境を手動で作成できます。
この方法では、
nbqa を使って
Jupyter ノートブック内のコード例もチェックできます。使用が終わったら環境を削除してください。
# 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
このツールは削除されたインポートパスのみを検出します。削除されたメソッド(QuantumCircuit.qasm など)や引数の使用は検出できません。また、qk = qiskit のような代入を追跡することはできませんが、import qiskit as qk のようなエイリアスは処理できます。
詳細については、プロジェクトのリポジトリを参照してください。
グローバルインスタンスと関数
Aer
qiskit.Aer オブジェクトは Qiskit v1.0 では利用できません。代わりに、
ドロップイン代替として qiskit_aer 名前空間から同じオブジェクトを使用してください。
qiskit_aer をインストールするには、以下を実行します。
pip install qiskit-aer
BasicAer
qiskit.BasicAer オブジェクトは Qiskit v1.0 では利用できません。
移行の選択肢については、basicaer 移行セクションを参照してください。
execute
qiskit.execute 関数は Qiskit v1.0 では利用できません。この関数は Qiskit における
transpile と
run 関数の
高レベルラッパーとして機能していました。
qiskit.execute の代わりに、
transpile 関数を使用してから
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)
あるいは、Sampler プリミティブは、
削除された qiskit.execute 関数と意味的に同等です。
BackendSampler クラスは、
プリミティブをサポートしていない Backend の汎用ラッパーです。
from qiskit.primitives import BackendSampler
sampler = BackendSampler(backend)
job = sampler.run(circuit)
qiskit.circuit
QuantumCircuit.qasm
QuantumCircuit.qasm メソッドは削除されました。代わりに
qasm2.dump または
qasm2.dumps を使用してください。
Pygments 形式の出力については、qasm2.dump および qasm2.dumps は Pygments カラー出力を
提供していないため、スタンドアロンの
openqasm-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)
QuantumCircuit の Gate
以下の Gate メソッドは、同じ Gate を追加するより定着したメソッドに置き換えられ、削除されました。
| 削除済み | 代替手段 |
|---|---|
QuantumCircuit.cnot | QuantumCircuit.cx |
QuantumCircuit.toffoli | QuantumCircuit.ccx |
QuantumCircuit.fredkin | QuantumCircuit.cswap |
QuantumCircuit.mct | QuantumCircuit.mcx |
QuantumCircuit.i | QuantumCircuit.id |
QuantumCircuit.squ | QuantumCircuit.unitary |
以下の Circuit メソッドも削除されました。これらの Gate は QuantumCircuit.append を使って
Circuit に適用できます。
| 削除済み | 代替手段(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 |
例として、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
以下の QuantumCircuit メソッドも削除されました。
| 削除済み | 代替手段 |
|---|---|
QuantumCircuit.bind_parameters | QuantumCircuit.assign_parameters |
QuantumCircuit.snapshot | qiskit-aer の保存命令 |
qiskit.converters
qiskit.converters.ast_to_dag 関数は Qiskit から削除されました。この関数は
レガシーな OpenQASM 2 パーサーが生成する抽象構文木を
DAGCircuit に変換するものでした。
レガシーな OpenQASM 2 パーサーが削除された(qiskit.qasm を参照)ため、
この関数はもはや必要ありません。代わりに、
QuantumCircuit.from_qasm_file
または
QuantumCircuit.from_qasm_str
コンストラクタメソッド(または qiskit.qasm2 モジュール)を使用して
OpenQASM 2 ファイルを QuantumCircuit に解析し、次に
circuit_to_dag を使って
その QuantumCircuit を
DAGCircuit に変換してください。
# 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
qiskit.extensions モジュールは利用できなくなりました。そのオブジェクトのほとんどは
Circuit ライブラリ
(qiskit.circuit.library)に統合されました。
新しい場所への移行は、オブジェクトのインポートパスで qiskit.extensions を
qiskit.circuit.library に置き換えるだけです。これはドロップイン代替となります。
# Previous
from qiskit.extensions import DiagonalGate
# Current alternative
from qiskit.circuit.library import DiagonalGate
qiskit.circuit.library に移動したクラスは次のとおりです。
DiagonalGateHamiltonianGateInitializeIsometryqiskit.circuit.library.generalized_gates.mcg_up_diag.MCGupDiagUCGateUCPauliRotGateUCRXGateUCRYGateUCRZGateUnitaryGate
以下のクラスは、機能が冗長であったか extensions モジュールに依存していたため、
コードベースから削除されました。
| 削除済み | 代替手段 |
|---|---|
SingleQubitUnitary | qiskit.circuit.library.UnitaryGate |
Snapshot | qiskit-aer の保存命令を使用 |
ExtensionError | 適切なエラークラスに置き換え |
qiskit.primitives
qiskit.primitives モジュールにおける最も注目すべき変更点は、新しい primitives V2 インターフェース の導入です。このセクションでは、ワークフローを primitives V1 から V2 へ移行する方法と、V1 インターフェースで受け付ける入力に生じた変更点を説明します。
v1.0 リリース以降、1.0 より前の primitives インターフェースを「primitives V1」と呼びます。
V1 から V2 への移行
primitives V1 と V2 の API における正式な区別は、各 primitives 実装が継承する基底クラスにあります。新しい基底クラスへ移行する際は、qiskit.primitives からの元のインポートパスをそのまま使用できます。
| 移行元 | 移行先 |
|---|---|
BaseEstimator | BaseEstimatorV2 |
BaseSampler | BaseSamplerV2 |
V2 primitives の qiskit コア実装(qiskit.primitives からインポート可能なもの)の名前は、statevector シミュレーター Backend を使ってローカルで実行できる実装としての目的を明確にするために変更されました。新しい名前には -V2 サフィックスは付きません。
| 移行元 | 移行先 |
|---|---|
qiskit.primitives.Estimator | qiskit.primitives.StatevectorEstimator |
qiskit.primitives.Sampler | qiskit.primitives.StatevectorSampler |
V1 から V2 へ移行する際に考慮すべき概念的な違いがいくつかあります。これらの違いは基底クラスによって規定されますが、以下の例では qiskit.primitives に含まれる statevector 実装を用いて示します。
以下の例では、次のインポートと 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 と Estimator:新しい V2 primitives はベクトル化された入力を受け付けるように設計されており、1 つの Circuit を配列形式の仕様とグループ化できます。つまり、1 つの Circuit をn個 のパラメーターセット、n個のオブザーバブル、またはその両方(Estimator の場合)の配列に対して実行できます。各グループは primitive unified bloc(PUB) と呼ばれ、タプル(1 x Circuit, [n x observables], [n x parameters])として表現できます。V1 インターフェースでは同様の柔軟性が許可されておらず、代わりに入力する Circuit の数をオブザーバブルやパラメーターセットの数と一致させる必要がありました。以下の例で確認できます(タブを選択して各例を表示してください):
- 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
V2 primitives は複数の PUB を入力として受け付け、各 PUB は独自の結果を持ちます。これにより、V1 インターフェースでは常に可能とは限らなかった、さまざまなパラメーター・オブザーバブルの組み合わせで異なる Circuit を実行できます。
- 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:V2 Sampler は、V1 インターフェースの準確率分布に代わり、測定結果のサンプルをビット列またはカウントの形式で返すようになりました。ビット列は測定結果を示し、測定されたショットの順序を保持します。V2 Sampler の結果オブジェクトは、動的 Circuit との互換性のために、入力 Circuit の古典レジスタ名に基づいてデータを整理します。
# 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 1デフォルトの古典レジスタ名上の Circuit では、古典レジスタ名がデフォルトで
"meas"になっていることに注意してください。 この名前は後ほど測定ビット列へアクセスする際に使用します。# 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 と Estimator:V1 実装ではshots実行オプションとして公開されていたサンプリングのオーバーヘッドは、PUB レベルで指定できる primitives のrun()メソッドの引数になりました。V2 基底クラスは V1 API とは異なる形式で引数を公開します。-
BaseSamplerV2.runはshots引数を公開します(以前のワークフローと同様):# 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.runはprecision引数を導入し、primitive 実装が期待値の推定に対して達成すべき誤差バーを指定します:# Estimate expectation values for two PUBs, both with 0.05 precision.
estimator_v2.run([(circuit1, obs_array1), (circuit2, obs_array_2)], precision=0.05)
-
V1 インターフェースの変更点
-
Estimatorのオブザーバブル引数において、密なBaseOperatorからSparsePauliOpへの暗黙的な変換は使用できなくなりました。代わりに、SparsePauliOp.from_operator(operator)を使用して明示的にSparsePauliOpへ変換してください。 -
Estimator のオブザーバブル引数に
PauliListを使用することはできなくなりました。代わりに、SparsePauliOp(pauli_list)を使用して引数を明示的に変換してください。
qiskit.providers
basicaer
qiskit.providers.basicaer モジュールの機能のほとんどは、新しい qiskit.providers.basic_provider モジュールに置き換えられました。ただし、UnitarySimulatorPy と StatevectorSimulatorPy クラスは削除されており、これらの機能はすでに quantum_info モジュールに含まれていました。
新しいパスへの移行は簡単です。qiskit.providers.basicaer のほとんどのクラスを、対応する qiskit.providers.basic_provider のクラスに直接置き換えることができます。ただし、以下のクラスはパスと名前が変更されている点に注意してください。
| 削除済み | 代替 |
|---|---|
qiskit.providers.basicaer | qiskit.providers.basic_provider |
BasicAerProvider | BasicProvider |
BasicAerJob | BasicProviderJob |
QasmSimulatorPy | BasicSimulator |
新しいモジュールへ移行する際は、グローバルインスタンスに注意してください。qiskit.BasicAer として直接インポートできた BasicAer グローバルインスタンスの代替はありません。つまり、from qiskit import BasicProvider は有効なインポートではなくなりました。
代わりに、プロバイダークラスをサブモジュールからインポートし、ユーザーが自分でインスタンス化する必要があります。
# 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")
unitary シミュレーターと statevector シミュレーターは、別の quantum_info クラスに置き換えることができます。直接の置き換えではありませんが、変更は最小限です。以下の移行例を参照してください。
| 削除済み | 代替 |
|---|---|
UnitarySimulatorPy | quantum_info.Operator |
StatevectorSimulatorPy | quantum_info.Statevector |
以下の例は 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
qiskit.providers.fake_provider のユーザー向けコンポーネントの多くは qiskit-ibm-runtime Python パッケージへ移行されました。これには、fake provider クラス、デバイス固有のすべての fake Backend(FakeVigo、FakeNairobiV2、FakeSherbrooke など)、および fake Backend 基底クラスが含まれます。影響を受けるクラスはタブをクリックして確認してください。
- Fake Backends
- Fake Providers
qiskit.providers.fake_provider.backends内の全クラスfake_provider.fake_backend.FakeBackendfake_provider.fake_backend.FakeBackendV2
fake_provider.FakeProviderfake_provider.FakeProviderForBackendV2fake_provider.FakeProviderFactory
新しいパスへ移行するには:
-
qiskit-ibm-runtimeバージョン0.17.1以降をインストールします :pip install 'qiskit-ibm-runtime>=0.17.1' -
コード内の
qiskit.providers.fake_providerをqiskit_ibm_runtime.fake_providerに置き換えます。例:# 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()
fake Backend 基底クラスも移行されましたが、インポートパスに若干の違いがあります:
| 削除済み | 代替 |
|---|---|
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 |
ダウンストリームライブラリの単体テストに fake Backend を使用していて、qiskit-ibm-runtime の依存関係に競合がある場合は、新しい Qiskit ネイティブの汎用 fake Backend の代替も利用できます。
以下の BackendV1 クラスが含まれます(直接置き換え可能):
qiskit.providers.fake_provider.Fake5QV1qiskit.providers.fake_provider.Fake20QV1qiskit.providers.fake_provider.Fake7QPulseV1qiskit.providers.fake_provider.Fake27QPulseV1qiskit.providers.fake_provider.Fake127QPulseV1
以下は BackendV2 インスタンスを返す設定可能なクラスです :
fake_provider(特殊テスト用 Backend)
qiskit.providers.fake_provider の特殊テスト用 fake Backend クラスは、qiskit_ibm_runtime.fake_provider へは移行されていません。推奨される移行パスは、新しい GenericBackendV2 クラスを使用して類似のプロパティを持つ Backend を設定するか、カスタムターゲットを構築することです。
| 削除済み | 代替 |
|---|---|
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 |
例:新しい 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.
その他の移行のヒント
-
qiskit.providers.aerからのインポートはできなくなりました。代わりに、直接置き換え可能なqiskit_aerからインポートしてください。qiskit_aerをインストールするには、次のコマンドを実行します:pip install qiskit-aer -
qiskit.providers.fake_providerの Backend でパルスジョブを実行するサポートは Qiskit v1.0 で削除されました。これは、Qiskit Aer がそのようなジョブのシミュレーション機能を削除したためです。低レベルのハミルトニアンシミュレーションのワークロードには、Qiskit Dynamics などの専門ライブラリの使用を検討してください。