Skip to main content
IBM Quantum Platform

トランスパイラ最適化レベルを設定する

  • このページのコードは、以下の要件に基づいて開発された。 これらのバージョンまたは新しいバージョンの使用をお勧めします。

    qiskit[all]~=2.5.1
    qiskit-ibm-runtime~=0.47.0
    

実際の量子デバイスはノイズやゲートエラーの影響を受けるため、回路の深さやゲート数を減らすように最適化することで、それらの回路を実行して得られる結果を大幅に改善することができる。 この関数には、1つの位置引数が必要である。 generate_preset_pass_manageroptimization_level この関数は、トランスパイラが回路の最適化に費やす労力を制御する。 この引数には、0、1、2、3のいずれかの値をとる整数を指定する。 最適化レベルを上げると、コンパイル時間が長くなる代わりに、より最適化された回路が生成される。 次の表は、各設定で実行される最適化について説明しています。

最適化レベル
説明
0

最適化なし:通常、ハードウェアの特性評価に使用

  • 基本的な翻訳
  • レイアウト/ルーティング: TrivialLayout仮想と同じ物理量子ビットを選択し、SWAPを挿入して動作させる( SabreSwap を使用)
1

光の最適化:

  • レイアウト/ルーティング:レイアウトは、まず TrivialLayout で試みられる。 追加のSWAPが必要な場合は、 SabreSwap、SWAP数が最小となるレイアウトを見つけ、 VF2LayoutPostLayout 、グラフ内の最適な量子ビットの選択を試みる。
  • InverseCancellation
  • 1Q ゲート最適化
2

中庸の最適化:

  • レイアウト/ルーティング:最適化レベル1(トリビアルなし)+ヒューリスティック最適化(探索深度を深め、最適化機能を試行する 最適化関数の探索深度と試行。 TrivialLayout 、物理量子ビット数と仮想量子ビット数を同じにしようとはしない。
  • CommutativeCancellation
3

高い最適化:

  • 最適化レベル2 + ヒューリスティックに最適化されたレイアウト/ルーティング
  • カルタンのKAK分解を用いた2量子ビットブロックの再合成。
  • ユニタリティを破るパス
    • OptimizeSwapBeforeMeasure:SWAPを避けるために測定値を移動させる
    • RemoveDiagonalGatesBeforeMeasure:測定に影響しないゲートを測定前に削除する

最適化レベルの実践

通常、2量子ビットゲートは最も重大なエラーの原因となるため、結果として得られる回路内の2量子ビットゲートの数を数えることで、トランスパイルの「ハードウェア効率」をおおよそ定量化することができる。 ここでは、ランダムなユニタリーにSWAPゲートが続く入力回路で、さまざまな最適化レベルを試してみる。

from qiskit import QuantumCircuit
from qiskit.circuit.library import UnitaryGate
from qiskit.quantum_info import Operator, random_unitary

UU = random_unitary(4, seed=12345)
rand_U = UnitaryGate(UU)

qc = QuantumCircuit(2)
qc.append(rand_U, range(2))
qc.swap(0, 1)
qc.draw("mpl", style="iqp")

Output:

Output of the previous code cell
Note

これらの例では の FakeSherbrooke``qiskit_ibm_runtime モックバックエンドを使用していますが、Qiskitと互換性のある実在のバックエンドや模擬バックエンドであれば、どれでも試すことができます。 実際の結果は異なる場合があります。

まず、最適化レベル0でトランスパイルしてみましょう。

from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()

pass_manager = generate_preset_pass_manager(
    optimization_level=0, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

トランスパイルド回路には2量子ビットのECRゲートが6つある。

最適化レベル1を繰り返す:

from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke

backend = FakeSherbrooke()

pass_manager = generate_preset_pass_manager(
    optimization_level=1, backend=backend, seed_transpiler=12345
)
qc_t1_exact = pass_manager.run(qc)
qc_t1_exact.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

トランスパイルド回路は依然として6つのECRゲートを持つが、1量子ビットゲートの数は減っている。

最適化レベル2を繰り返す:

pass_manager = generate_preset_pass_manager(
    optimization_level=2, backend=backend, seed_transpiler=12345
)
qc_t2_exact = pass_manager.run(qc)
qc_t2_exact.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

これは最適化レベル1と同じ結果になる。 最適化のレベルを上げても、必ずしも違いが出るとは限らない。

最適化レベル3でもう一度繰り返す:

pass_manager = generate_preset_pass_manager(
    optimization_level=3, backend=backend, seed_transpiler=12345
)
qc_t3_exact = pass_manager.run(qc)
qc_t3_exact.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

現在、ECRゲートは3つしかない。 最適化レベル3では、Qiskitは2量子ビットのゲート・ブロックを再合成しようとするため、この結果が得られる。 approximation_degree を1より小さい値に設定すれば、ECRゲートの数をさらに少なくすることができ、トランスパイラがゲート分解に多少の誤差をもたらす可能性のある近似を行うことができます( トランスパイラでよく使われるパラメータを参照):

pass_manager = generate_preset_pass_manager(
    optimization_level=3,
    approximation_degree=0.99,
    backend=backend,
    seed_transpiler=12345,
)
qc_t3_approx = pass_manager.run(qc)
qc_t3_approx.draw("mpl", idle_wires=False)

Output:

Output of the previous code cell

この回路にはECRゲートが2つしかないが、おおよその回路である。 その効果が正確な回路とどう違うかを理解するために、この回路が実装するユニタリー演算子と正確なユニタリー演算子との間の忠実度を計算することができる。 計算を実行する前に、まず127個の量子ビットを含むトランスパイルド回路を、アクティブ量子ビット(2個)のみを含む回路に縮小する。

import numpy as np


def trace_to_fidelity_2q(trace: float) -> float:
    return (4.0 + trace * trace.conjugate()) / 20.0


# Reduce circuits down to 2 qubits so they are easy to simulate
qc_t3_exact_small = QuantumCircuit.from_instructions(qc_t3_exact)
qc_t3_approx_small = QuantumCircuit.from_instructions(qc_t3_approx)

# Compute the fidelity
exact_fid = trace_to_fidelity_2q(
    np.trace(np.dot(Operator(qc_t3_exact_small).adjoint().data, UU))
)
approx_fid = trace_to_fidelity_2q(
    np.trace(np.dot(Operator(qc_t3_approx_small).adjoint().data, UU))
)
print(
    f"Synthesis fidelity\nExact: {exact_fid:.3f}\nApproximate: {approx_fid:.3f}"
)

Output:

Synthesis fidelity
Exact: 1.000+0.000j
Approximate: 0.992+0.000j

最適化レベルを調整すると、ECRゲートの数だけでなく、回路の他の側面にも影響が及ぶことがあります。 最適化レベルの設定がレイアウトにどのような影響を与えるかについては、 「量子コンピュータの表現」を参照してください。


次のステップ

推奨事項
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。