Qiskit アドオンユーティリティ
パッケージバージョン
このページのコードは、以下の要件を使用して開発されました。 これらのバージョン以降を使用することをお勧めします。
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
qiskit-addon-utils~=0.3.0
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-addon-utils qiskit-ibm-runtime
Qiskit アドオンユーティリティパッケージは、1つ以上の Qiskit アドオンを含むワークフローを補完するための機能のコレクションです。例えば、このパッケージにはハミルトニアンの生成、Trotter 時間発展回路の作成、量子回路のスライスおよび結合を行う関数が含まれています。
インストール
Qiskit アドオンユーティリティをインストールする方法は、PyPI からのインストールとソースからのビルドの2つがあります。パッケージの依存関係を分離するために、仮想環境にインストールすることをお勧めします。
PyPI からのインストール
Qiskit アドオンユーティリティパッケージをインストールする最も簡単な方法は、PyPI を使用することです。
pip install 'qiskit-addon-utils'
ソースからのインストール
こちらをクリックして、このパッケージを手動でインストールする方法をお読みください。
このパッケージにコントリビュートしたい場合や手動でインストールしたい場合は、まずリポジトリをクローンしてください:
git clone git@github.com:Qiskit/qiskit-addon-utils.git
そして、pip 経由でパッケージをインストールします。パッケージリポジトリにあるチュートリアルを実行する予定がある場合は、ノートブックの依存関係もインストールしてください。リポジトリで開発する予定がある場合は、dev の依存関係をインストールしてください。
pip install tox jupyterlab -e '.[notebook-dependencies,dev]'
ユーティリティを使い始める
qiskit-addon-utils パッケージには、量子システムのシミュレーションのための問題生成、量子回路にゲートをより効率的に配置するためのグラフ彩色、および演算子バック伝播に役立つ回路スライシングなど、いくつかのモジュールがあります。以下のセクションでは各モジュールの概要を説明します。パッケージの API ドキュメントにも役立つ情報が掲載されています。
問題生成
qiskit_addon_utils.problem_generators モジュールの内容には以下が含まれます:
generate_xyz_hamiltonian()関数:Ising 型 XYZ モデルの接続性を考慮したSparsePauliOp表現を生成します:
generate_time_evolution_circuit()関数:指定された演算子の時間発展をモデル化する回路を構築します。- 異なる Pauli 文字列の順序付けを列挙するための3種類の
PauliOrderStrategyオブジェクト。これらはグラフ彩色と組み合わせて使用する際に特 に有用で、generate_xyz_hamiltonian()とgenerate_time_evolution_circuit()の両関数で引数として使用できます。
グラフ彩色
qiskit_addon_utils.coloring モジュールは、カップリングマップのエッジに色を付け、この彩色を使用して量子回路にゲートをより効率的に配置するために使用されます。エッジ彩色カップリングマップの目的は、同じ色の2つのエッジが共通のノードを共有しないようなエッジカラーのセットを見つけることです。QPU では、同じ色のエッジ(量子ビット接続)に沿ったゲートを同時に実行でき、回路の実行が高速になります。
簡単な例として、auto_color_edges() 関数を使用して、各量子ビット接続に沿って CZGate を実行するナイーブな回路のエッジ彩色を生成できます。以下のコードスニペットは、FakeSherbrooke バックエンドのカップリングマップを使用し、このナイーブな回路を作成した後、auto_color_edges() 関数を使用してより効率的な等価回路を作成します。
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
from qiskit import QuantumCircuit
from qiskit_addon_utils.coloring import auto_color_edges
from qiskit_addon_utils.slicing import combine_slices, slice_by_depth
from collections import defaultdict
backend = FakeSherbrooke()
coupling_map = backend.coupling_map
# Create naive circuit
circuit = QuantumCircuit(backend.num_qubits)
for edge in coupling_map.graph.edge_list():
circuit.cz(edge[0], edge[1])
# Color the edges of the coupling map
coloring = auto_color_edges(coupling_map)
circuit_with_coloring = QuantumCircuit(backend.num_qubits)
# Make a reverse coloring dict in order to make the circuit
color_to_edge = defaultdict(list)
for edge, color in coloring.items():
color_to_edge[color].append(edge)
# Place edges in order of color
for edges in color_to_edge.values():
for edge in edges:
circuit_with_coloring.cz(edge[0], edge[1])
print(f"The circuit without using edge coloring has depth: {circuit.depth()}")
print(
f"The circuit using edge coloring has depth: {circuit_with_coloring.depth()}"
)
The circuit without using edge coloring has depth: 37
The circuit using edge coloring has depth: 3
スライシング
最後に、qiskit-addon-utils.slicing モジュールには、回路の「スライス」(すべての量子ビットにわたる QuantumCircuit の時間的なパーティション)を作成するための関数およびトランスパイラパスが含まれています。これらのスライスは主に演算子バック伝播に使用されます。回路をスライスする主な4つの方法は、ゲートタイプ、深さ、彩色、または Barrier 命令によるものです。これらのスライシング関数の出力は QuantumCircuit オブジェクトのリストを返します。スライスされた回路は combine_slices() 関数を使用して再結合することもできます。詳細については、モジュールの API リファレンスをお読みください。
以下は、次の回路を使用してこれらのスライスを作成する方法のいくつかの例です:
import numpy as np
from qiskit import QuantumCircuit
num_qubits = 9
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
演算子バック伝播のために回路の構造を活用する明確な方法がない場合は、回路を指定された深さのスライスにパーティション分割できます。
# Slice circuit into partitions of depth 1
slices = slice_by_depth(qc, 1)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
量子システムのダイナミクスをモデル化するために Trotter 回路を実行する場合 など、ゲートタイプでスライスすることが有利な場合があります。
from qiskit_addon_utils.slicing import slice_by_gate_types
slices = slice_by_gate_types(qc)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
ワー クロードが実行される QPU の物理的な量子ビット接続性を利用するように設計されている場合は、エッジ彩色に基づいてスライスを作成できます。以下のコードスニペットは、回路エッジに3彩色を割り当て、エッジ彩色に基づいて回路をスライスします。(注意:これは非局所ゲートにのみ影響します。単一量子ビットゲートはゲートタイプでスライスされます。)
from qiskit_addon_utils.slicing import slice_by_coloring
# Assign a color to each set of connected qubits
coloring = {}
for i in range(num_qubits - 1):
coloring[(i, i + 1)] = i % 3
coloring[(num_qubits - 1, 0)] = 2
# Create a circuit with operations added in order of color
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
edges = [
edge for color in range(3) for edge in coloring if coloring[edge] == color
]
for edge in edges:
qc.cx(edge[0], edge[1])
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
# Create slices by edge color
slices = slice_by_coloring(qc, coloring=coloring)
# Recombine slices in order to visualize the partitions together
combined_slices = combine_slices(slices, include_barriers=True)
combined_slices.draw("mpl", scale=0.6)
カスタムスライシング戦略がある場合は、代わりに回路にバリアを配置してスライスする場所を指定し、slice_by_barriers 関数を使用できます。
qc = QuantumCircuit(num_qubits)
qc.ry(np.pi / 4, range(num_qubits))
qc.barrier()
qubits_1 = [i for i in range(num_qubits) if i % 2 == 0]
qubits_2 = [i for i in range(num_qubits) if i % 2 == 1]
qc.cx(qubits_1[:-1], qubits_2)
qc.cx(qubits_2, qubits_1[1:])
qc.cx(qubits_1[-1], qubits_1[0])
qc.barrier()
qc.rx(np.pi / 4, range(num_qubits))
qc.rz(np.pi / 4, range(num_qubits))
qc.draw("mpl", scale=0.6)
バリアが配置されると、各スライスを個別に確認できます。
from qiskit_addon_utils.slicing import slice_by_barriers
slices = slice_by_barriers(qc)
slices[0].draw("mpl", scale=0.6)
slices[1].draw("mpl", scale=0.6)
slices[2].draw("mpl", scale=0.6)
次のステップ
- OBP アドオンの概要をお読みください。
- SQD アドオンの仕組みを理解してください。
- AQC-Tensor アドオンについて理解を深めてください。