周期境界条件のための回路カッティング
使用時間の推定: Eagleプロセッサで2分(注: これは推定値です。実際の実行時間は異なる場合があります。)
背景
このノートブックでは、隣接するすべてのqubitペア間、最初と最後のqubitを含む、2qubit演算を持つ周期的なqubitチェーンのシミュレーションを検討します。周期的チェーンは、Isingモデルや分子シミュレーションなどの物理学や化学の問題でよく見られます。
現在のIBM Quantum®デバイスは平面的です。最初と最後のqubitが隣接している場合、トポロジー上に直接いくつかの周期的チェーンを埋め込むことが可能です。しかし、十分に大きな問題の場合、最初と最後のqubitが遠く離れている可能性があり、これら2つのqubit間の2qubit演算には多くのSWAP gateが必要になります。このような周期境界問題はこの論文で研究されています。
このノートブックでは、回路カッティングを使用して、最初と最後のqubitが隣接していないユーティリティスケールの周期的チェーン問題に対処する方法を示します。この長距離接続をカットすることで、回路の複数のインスタンスを実行し、いくらかの古典的な後処理を行うコストで、余分なSWAP gateを回避できます。要約すると、カッティングを組み込むことで、長距離2qubit演算を論理的に計算できます。言い換えれば、このアプローチは結合マップの接続性を効果的に増加させ、結果としてSWAP gateの数を削減します。
カットには2つのタイプがあることに注意してください - 回路のワイヤをカットする(wire cuttingと呼ばれる)、または2qubit gateを複数の1qubit演算に置き換える(gate cuttingと呼ばれる)。このノートブックでは、gate cuttingに焦点を当てます。gate cuttingの詳細については、qiskit-addon-cuttingの説明資料および対応する参考文献を参照してください。wire cuttingの詳細については、期待値推定のためのワイヤカッティングチュートリアル、またはqiskit-addon-cuttingのチュートリアルを参照してください。
要件
このチュートリアルを開始する前に、以下がインストールされていることを確認してください:
- Qiskit SDK v1.2以降(
pip install qiskit) - Qiskit Runtime v0.3以降(
pip install qiskit-ibm-runtime) - Circuit cutting Qiskit addon v.9.0以降(
pip install qiskit-addon-cutting)
セットアップ
# Added by doQumentation — required packages for this notebook
!pip install -q matplotlib numpy qiskit qiskit-addon-cutting qiskit-ibm-runtime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import (
BasisTranslator,
Optimize1qGatesDecomposition,
)
from qiskit.circuit.equivalence_library import (
SessionEquivalenceLibrary as sel,
)
from qiskit.converters import circuit_to_dag, dag_to_circuit
from qiskit.result import sampled_expectation_value
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
from qiskit.circuit.library import TwoLocal
from qiskit_addon_cutting import (
cut_gates,
generate_cutting_experiments,
reconstruct_expectation_values,
)
from qiskit_ibm_runtime import QiskitRuntimeService
from qiskit_ibm_runtime import SamplerV2, SamplerOptions, Batch
ステップ1: 古典的入力を量子問題にマッピング
ここでは、TwoLocal回路を生成し、いくつかの観測量を定義します。
- 入力: 回路を作成するためのパラメータ
- 出力: 抽象回路と観測量
entangler mapの最後と最初のqubit間に周期的接続を持つ、TwoLocal回路のためのハードウェア効率的なentangler mapを考えます。この長距離相互作用は、transpilation中に余分なSWAP gateを引き起こし、回路の深さを増加させる可能性があります。
バックエンドと初期レイアウトを選択
service = QiskitRuntimeService()
backend = service.least_busy(
operational=True, simulator=False, min_num_qubits=127
)
このノートブックでは、127qubit IBM Quantumデバイスのトポロジーにおける最長の1Dチェーンである109qubitの周期的1Dチェーンを考えます。127qubitデバイス上に109qubitの周期的チェーンを、最初 と最後のqubitが余分なSWAP gateを組み込むことなく隣接するように配置することは不可能です。
init_layout = [
13,
12,
11,
10,
9,
8,
7,
6,
5,
4,
3,
2,
1,
0,
14,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
36,
51,
50,
49,
48,
47,
46,
45,
44,
43,
42,
41,
40,
39,
38,
37,
52,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
74,
89,
88,
87,
86,
85,
84,
83,
82,
81,
80,
79,
78,
77,
76,
75,
90,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
112,
126,
125,
124,
123,
122,
121,
120,
119,
118,
117,
116,
115,
114,
113,
]
# the number of qubits in the circuit is governed by the length of the initial layout
num_qubits = len(init_layout)
num_qubits
109
TwoLocal回路のentangler mapを構築
coupling_map = [(i, i + 1) for i in range(0, len(init_layout) - 1)]
coupling_map.append(
(len(init_layout) - 1, 0)
) # adding in the periodic connectivity
TwoLocal回路は、rotation_blocksとentangler mapの繰り返しを複数回許可します。この場合、繰り返しの回数は、カットする必要がある周期的gateの数を決定します。サンプリングオーバーヘッドはカットの数に対して指数関数的に増加するため(詳細については期待値推定のためのワイヤカッティングチュートリアルを参照)、このノートブックでは繰り返しの回数を2に固定します。
num_reps = 2
entangler_map = []
for even_edge in coupling_map[0 : len(coupling_map) : 2]:
entangler_map.append(even_edge)
for odd_edge in coupling_map[1 : len(coupling_map) : 2]:
entangler_map.append(odd_edge)
ansatz = TwoLocal(
num_qubits=num_qubits,
rotation_blocks="rx",
entanglement_blocks="cx",
entanglement=entangler_map,
reps=num_reps,
).decompose()
ansatz.draw("mpl", fold=-1)

回路カッティングを使用した結果の品質を検証するためには、理想的な結果を知る必要があります。現在選択されている回路は、ブルートフォースの古典シミュレーションを超えています。したがって、回路をクリフォードにするために、パラメータを慎重に固定します。
Rx gateの最初の2層にはパラメータ値を割り当て、最後の層には値を割り当てます。これにより、この回路の理想的な結果は(はqubitの数)になります。したがって、との期待値(はqubitのインデックス)は、それぞれとになります。
params_last_layer = [np.pi] * ansatz.num_qubits
params = [0] * (ansatz.num_parameters - ansatz.num_qubits)
params.extend(params_last_layer)
ansatz.assign_parameters(params, inplace=True)
観測量を選択
gate cuttingの利点を定量化するために、観測量との期待値を測定します。前述のように、理想的な期待値はそれぞれとです。
observables = []
for i in range(num_qubits):
obs = "I" * (i) + "Z" + "I" * (num_qubits - i - 1)
observables.append(obs)
for i in range(num_qubits):
if i == num_qubits - 1:
obs = "Z" + "I" * (num_qubits - 2) + "Z"
else:
obs = "I" * i + "ZZ" + "I" * (num_qubits - i - 2)
observables.append(obs)
observables = SparsePauliOp(observables)
paulis = observables.paulis
coeffs = observables.coeffs