メインコンテンツへスキップ

ダイナミカルデカップリング用のパスマネージャーを作成する

パッケージのバージョン

このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以上を使用することをお勧めします。

qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1

このページでは、PadDynamicalDecoupling パスを使用して、_ダイナミカルデカップリング_と呼ばれるエラー抑制手法をCircuitに追加する方法を説明します。

ダイナミカルデカップリングは、アイドル状態のQubitに対してパルス列(_ダイナミカルデカップリングシーケンス_と呼ばれる)を追加し、Bloch球上でQubitを反転させることで、ノイズチャネルの影響を打ち消し、デコヒーレンスを抑制する手法です。これらのパルス列は、核磁気共鳴で使用されるリフォーカシングパルスと類似しています。詳細については、A Quantum Engineer's Guide to Superconducting Qubits を参照してください。

PadDynamicalDecoupling パスはスケジュール済みのCircuitにのみ動作し、対象のバックエンドの基底Gateとは限らないGateを含むため、ALAPScheduleAnalysis および BasisTranslator パスも必要になります。

この例では、事前に初期化された ibm_fez を使用します。backend から target 情報を取得し、操作名を basis_gates として保存してください。ダイナミカルデカップリングで使用するGateにタイミング情報を追加するために target を変更する必要があるためです。

# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
from qiskit_ibm_runtime import QiskitRuntimeService

service = QiskitRuntimeService()
backend = service.backend("ibm_fez")

target = backend.target
basis_gates = list(target.operation_names)

例として efficient_su2 Circuitを作成します。まず、ダイナミカルデカップリングのパルスはCircuitがトランスパイルおよびスケジュールされた後に追加する必要があるため、BackendにCircuitをトランスパイルします。ダイナミカルデカップリングは、量子回路にアイドル時間が多い場合、つまり一部のQubitが動作している間に他のQubitが使用されていない場合に最も効果的です。このCircuitでは、2QubitのGate ecr がこのansatzにおいて順次適用されるため、そのような状況になっています。

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.circuit.library import efficient_su2

qc = efficient_su2(12, entanglement="circular", reps=1)
pm = generate_preset_pass_manager(1, target=target, seed_transpiler=12345)
qc_t = pm.run(qc)
qc_t.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

ダイナミカルデカップリングシーケンスとは、恒等演算に合成され、時間的に等間隔に配置されたGateの列です。例えば、4つのGateから構成されるXY4という単純なシーケンスを作成することから始めましょう。

from qiskit.circuit.library import XGate, YGate

X = XGate()
Y = YGate()

dd_sequence = [X, Y, X, Y]

ダイナミカルデカップリングシーケンスは等間隔のタイミングで実行されるため、YGate に関する情報を target に追加する必要があります。XGate は基底Gateですが、YGate はそうではありません。ただし、YGateXGate と同じ持続時間とエラーを持つことが事前にわかっているため、target からそれらのプロパティを取得して YGate オブジェクト用に追加するだけで済みます。ibm_fez の実際の基底Gateではないにもかかわらず YGate 命令を target に追加しているため、basis_gates を別途保存しておいた理由もここにあります。

from qiskit.transpiler import InstructionProperties

y_gate_properties = {}
for qubit in range(target.num_qubits):
y_gate_properties.update(
{
(qubit,): InstructionProperties(
duration=target["x"][(qubit,)].duration,
error=target["x"][(qubit,)].error,
)
}
)

target.add_instruction(YGate(), y_gate_properties)

efficient_su2 などのansatz Circuitはパラメータ化されているため、Backendに送信する前に値をバインドする必要があります。ここではランダムなパラメータを割り当てます。

import numpy as np

rng = np.random.default_rng(1234)
qc_t.assign_parameters(
rng.uniform(-np.pi, np.pi, qc_t.num_parameters), inplace=True
)

次に、カスタムパスを実行します。ALAPScheduleAnalysisPadDynamicalDecoupling を使用して PassManager をインスタンス化します。等間隔のダイナミカルデカップリングシーケンスを追加する前に、量子回路のタイミング情報を追加するために ALAPScheduleAnalysis を最初に実行します。これらのパスは .run() でCircuit上で実行されます。

from qiskit.transpiler import PassManager
from qiskit.transpiler.passes.scheduling import (
ALAPScheduleAnalysis,
PadDynamicalDecoupling,
)

dd_pm = PassManager(
[
ALAPScheduleAnalysis(target=target),
PadDynamicalDecoupling(target=target, dd_sequence=dd_sequence),
]
)
qc_dd = dd_pm.run(qc_t)

可視化ツール timeline_drawer を使用してCircuitのタイミングを確認し、等間隔の XGate オブジェクトと YGate オブジェクトのシーケンスがCircuit内に現れていることを確認します。

from qiskit.visualization import timeline_drawer

timeline_drawer(qc_dd, idle_wires=False, target=target)

Output of the previous code cell

最後に、YGate はBackendの実際の基底Gateではないため、BasisTranslator パスを手動で適用します(これはデフォルトのパスですが、スケジューリングの前に実行されるため、再度適用する必要があります)。セッション等価ライブラリは、Transpilerが引数として指定された基底GateにCircuitを分解できるようにするための回路等価性ライブラリです。

from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.transpiler.passes import BasisTranslator

qc_dd = BasisTranslator(sel, basis_gates)(qc_dd)
qc_dd.draw("mpl", fold=-1, idle_wires=False)

Output of the previous code cell

これで、YGate オブジェクトはCircuitから除かれ、Delay Gateの形式で明示的なタイミング情報が含まれています。ダイナミカルデカップリングが適用されたこのトランスパイル済みCircuitは、Backendに送信できる状態になりました。

次のステップ

推奨事項