回路のタイミングを可視化する
このページのコードは、以下の要件に基づいて開発されました。 これらのバージョン以降のご利用をお勧めします。
qiskit[all]~=2.5.1 qiskit-ibm-runtime~=0.47.0
Qiskitに組み込まれているタイムライン・ドロワー は、静的な回路では有用ですが、ブロードキャストや分岐判定といった暗黙的な演算があるため、 動的な回路のタイミングを正確に反映できない場合があります。 動的なサーキットサポートの一環として、 IBM Quantum Compute Service は、要求があった場合、ジョブ結果内に正確なサーキットタイミング情報を返します。
- これは実験的な機能です。 現在プレビュー版として公開されているため、内容は変更される可能性があります。
- この機能は、 IBM Quantum のサンプラージョブにのみ適用されます。
- 「コンパイル」メタデータには総実行時間が返されますが、これは課金対象となる時間(QPU時間)ではありません。
タイミングデータの取得を有効にする
タイミングデータの取得を有効にするには、プリミティブジョブの実行時に実験用 scheduler_timing``True フラグを に設定してください。
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import QiskitRuntimeService, SamplerV2
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
sampler = SamplerV2(backend)
sampler.options.experimental = {
"execution": {
"scheduler_timing": True,
},
}
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()回路のタイミングデータにアクセスする
要求があった場合、各 PUB の回路タイミングデータは、ジョブ結果のメタデータ内の ["compilation"]["scheduler_timing"]["timing"]. このフィールドには、生のタイミング情報が格納されています。 タイミング情報を表示するには、 「タイミングの可視化」 のセクションに記載されているように、組み込みの可視化ツールを使用してください。
最初の PUB のサーキットタイムデータにアクセスするには、次のコードを使用してください:
job_result = sampler_job.result()
circuit_schedule = job_result[0].metadata["compilation"]["scheduler_timing"]
circuit_schedule_timing = circuit_schedule["timing"]生のタイミングデータを理解する
この draw_circuit_schedule_timing メソッドを使用して回路のタイミングデータを可視化することが最も一般的な用途ですが、返される生のタイミングデータの構造を理解しておくと役立つ場合があります。 これにより、例えば、プログラムを使って情報を抽出できるようになります。
で返されるタイミングデータ ["compilation"]["scheduler_timing"]["timing"] は、文字列のリストです。 各文字列は、あるチャネル上の単一の命令を表しており、カンマ区切りで以下のデータ型で構成されています:
Branch- その命令が制御フロー(then / else)にあるのか、それともメインブランチにあるのかを判定します。Instruction- ゲートと、演算の対象となる量子ビット。Channel- その命令によって割り当てられているチャネル。 次のいずれかです。Qubit x- 量子ビット x の駆動チャネル。AWGRx_y(任意波形発生器の表示) - 量子ビットを測定する際、表示チャンネル間の通信に使用される。 x および y の引数は、それぞれ読み出し機器の ID と量子ビット番号に対応しています。
T0- 完全なスケジュール内の授業開始時刻Duration- 命令の実行時間(単位: dt 秒)。ここで、1 dt = 1 スケジューリングサイクル。 バックエンドの値dtは、...backend.dtを使用して確認できます。Pulse- 使用されているパルス動作の種類。
例:
main,barrier,Qubit 0,7,0,barrier # A barrier on the main branch on qubit 0 at time 7 with 0 duration
main,reset_0,Qubit 0,7,64,play # A reset instruction on the main branch on qubit 0 at time 7 with duration 64 and a play operation
...タイミングを視覚化する
v0.43.0qiskit-ibm-runtime 以降では、回路のタイミングを可視化できます。 タイミングを可視化するには、まず メソッド draw_circuit_schedule_timing を使用して、結果のメタ fig データを に変換する必要があります。 このメソッドは図 plotly を返します。この図は、そのまま表示したり、ファイルに保存したり、あるいはその両方を行うことができます。 使用するコマンド plotly の詳細については、および fig.show() を参照してください fig.write_image("<path.format>")。
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
# Create a figure from the metadata
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule_timing,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")
生成された図を理解する
によって出力される回路タイミングデータの draw_circuit_schedule_timing 図は、以下の情報を示しています:
- X軸はdt 秒単位の時間であり、ここで1 dt = 1スケジューリングサイクルである。 バックエンドの値
dtは、...backend.dtを使用して確認できます。 - Y軸はチャネルです(チャネルはパルスを発するデバイスだと考えてください)。
Receive channel- それ自体が楽器ではない唯一のチャンネル。 これは、その時点でハブとの通信手順に参加しているすべてのチャネルで実行される命令です。Qubit x- 量子ビット x の駆動チャネル。AWGRx_y(任意波形発生器の表示) - 量子ビットを測定する際、表示チャンネル間の通信に使用される。 x および y の引数は、それぞれ読み出し機器の ID と量子ビット番号に対応しています。Hub- 放送を制御します。
さらに、各命令は X_Y という形式をとっており、 X は命令名、 Y はパルス種別を表します。 A play は制御パルスを印加し、Bは量子ビットの状態 capture を記録する。 各手順にカーソルを合わせると、詳細を確認することもできます。 例えば、前の図は、1161 dtの時点で量子ビット10に印加されたXゲート用の制御パルスを示しています。
エンドツーエンドの例
この例では、オプションを有効にし、メタデータから回路のタイミング情報を取得して、画像として表示する方法を説明します。
まず、環境を設定し、回路を定義してISA回路に変換し、ジョブを定義して実行します。
from qiskit_ibm_runtime import SamplerV2, QiskitRuntimeService
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.transpiler import generate_preset_pass_manager
service = QiskitRuntimeService()
backend = service.least_busy(operational=True, simulator=False)
# Create a dynamic circuit
qubits = QuantumRegister(1)
clbits = ClassicalRegister(1)
qc = QuantumCircuit(qubits, clbits)
(q0,) = qubits
(c0,) = clbits
qc.h(q0)
qc.measure(q0, c0)
with qc.if_test((c0, 1)):
qc.x(q0)
qc.measure(q0, c0)
# Convert to an ISA circuit for the given backend
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
# Generate samplers for backend targets
sampler = SamplerV2(backend)
sampler.options.experimental = {"execution": {"scheduler_timing": True}}
# Submit jobs
sampler_job = sampler.run([isa_circuit])
result = sampler_job.result()
print(
f">>> {' Job ID:':<10} {sampler_job.job_id()} ({sampler_job.status()})"
)Output:
>>> Job ID: d9mqmk7urbec73e67nng (DONE)
次に、試合日程を確認してください:
# Get the circuit schedule timing
result[0].metadata["compilation"]["scheduler_timing"]["timing"]Output:
'main,rz_0,Qubit 0,1393,0,shift_phase\nmain,sx_0,Qubit 0,1393,9,play\nmain,sx_0,Qubit 0,1397,0,shift_phase\nmain,rz_0,Qubit 0,1402,0,shift_phase\nmain,barrier,Qubit 0,1402,0,barrier\nmain,measure_0,Qubit 0,1402,64,play\nmain,measure_0,Qubit 0,1466,108,play\nmain,measure_0,AWGR0_0,1523,325,capture\nmain,measure_0,Qubit 0,1574,64,play\nmain,measure_0,Qubit 0,1638,64,play\nmain,barrier,Qubit 0,2049,0,barrier\nmain,broadcast,Hub,1523,526,broadcast\nmain,receive,Receive,2049,7,receive\nthen,x_0,Qubit 0,2064,9,play\nmain,barrier,Qubit 0,2082,0,barrier\nmain,measure_0,Qubit 0,2082,64,play\nmain,measure_0,Qubit 0,2146,108,play\nmain,measure_0,AWGR0_0,2203,325,capture\nmain,measure_0,Qubit 0,2254,64,play\nmain,measure_0,Qubit 0,2318,64,play\nmain,barrier,Qubit 0,2753,0,barrier\nmain,barrier,Qubit 0,2753,0,barrier\nmain,FINI_0,Qubit 0,2753,64,play\nmain,FINI_0,Qubit 0,2817,108,play\nmain,FINI_0,AWGR0_0,2874,325,capture\nmain,FINI_0,Qubit 0,2925,64,play\nmain,FINI_0,Qubit 0,2989,64,play\nmain,FINI_0,Qubit 0,3424,9,play\nmain,FINI_0,Qubit 0,3433,64,play\nmain,FINI_0,Qubit 0,3497,108,play\nmain,FINI_0,AWGR0_0,3554,325,capture\nmain,FINI_0,Qubit 0,3605,64,play\nmain,FINI_0,Qubit 0,3669,64,play\nmain,FINI_0,Qubit 0,4104,9,play\nmain,barrier,Qubit 0,4113,0,barrier\n'
最後に、タイミングを視覚化して保存することができます:
from qiskit_ibm_runtime.visualization import draw_circuit_schedule_timing
circuit_schedule = result[0].metadata["compilation"]["scheduler_timing"][
"timing"
]
fig = draw_circuit_schedule_timing(
circuit_schedule=circuit_schedule,
included_channels=None,
filter_readout_channels=False,
filter_barriers=False,
width=1000,
)
# Uncomment the following line to display the figure
# fig.show(renderer="notebook")
# Save to a file
# fig.write_html("scheduler_timing.html")次のステップ
- 従来のフィードフォワード制御と制御フロー (動的回路)
- 回路を可視化する