Skip to main content
IBM Quantum Platform

トランスパイラ

qiskit.transpiler


概要

回路トランスパイル・コンパイルの概念にすでに精通している場合は、この先はスキップしてください:

トランスパイルとは、与えられた入力回路を特定の量子デバイスのトポロジーに合わせて書き換えるプロセスであり、量子システム上で実行するために回路を最適化することである。

ほとんどの回路は、与えられたターゲット・デバイスと互換性を持たせるために一連の変換を受けなければならず、その結果得られる結果に対するノイズの影響を減らすために最適化しなければならない。 ハードウェアの制約に合わせて量子回路を書き直し、性能を最適化することは、決して簡単なことではない。 書き換えツールチェーンのロジックの流れは直線的である必要はなく、反復的なサブループ、条件分岐、その他の複雑な動作を持つことがよくある。 とはいえ、標準的なコンパイルの流れは以下のような構造になっている:

トランスパイルプロセスは、入力回路を受け取り、トランスパイルパスを適用し、出力回路を生成する。

Qiskitは、トランスパイラ・スタック全体で、回路のグラフベース DAGCircuit ではなく、トランスパイラスタック全体で回路の中間表現(IR)を使用します。 QuantumCircuit. トランスパイラ・パイプラインは PassManager オブジェクトです。 PassManager.run() メソッドは QuantumCircuit を受け取り、それを DAGCircuitに変換し、IRを一連のパス処理にかけ、最終的に QuantumCircuit を返す。 パスは AnalysisPassで回路に関するプロパティを計算し保存する。 PropertySetまたは TransformationPassのいずれかである。 パイプラインは "ステージ "に分かれていると考えることができ、各ステージは1つのハイレベルな変換を担当する。

Qiskitは、関数 generate_preset_pass_manager(). これは、 optimization_level (0から3までの間)で選択された、完全なトランスピレーションのために適切に構成されたパイプラインを返します。 よほど専門性の高いものを探しているのでなければ、ほぼ間違いなくこの入門コースになるだろう。 サンプルは次のようなものだ:

from qiskit.circuit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService

# Any abstract circuit you want:
abstract = QuantumCircuit(2)
abstract.h(0)
abstract.cx(0, 1)

# Any method you like to retrieve the backend you want to run on:
backend = QiskitRuntimeService().backend("some-backend")

# Create the pass manager for the transpilation ...
pm = generate_preset_pass_manager(backend=backend)
# ... and use it (as many times as you like).
physical = pm.run(abstract)

フォールトトレランスに向けた初期の実験において、この関数は、ターゲット基底がClifford+Tゲートで構成 generate_preset_pass_manager() されている場合、専用のトランスパイレーションパイプラインを呼び出します。詳細については、ドキュメントを clifford_t_pass_manager() 参照してください。 例:

from qiskit.circuit import QuantumCircuit
from qiskit.circuit.library import QFTGate
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import get_clifford_gate_names

# Any abstract circuit you want:
abstract = QuantumCircuit(4)
abstract.append(QFTGate(4), [0, 1, 2, 3])

# Use all Clifford+T basis gates
basis_gates = get_clifford_gate_names() + ["t", "tdg"]

# Create and run the pass manager
pm = generate_preset_pass_manager(basis_gates=basis_gates)
transpiled = pm.run(abstract)

ほとんどの場合、これだけで十分だ。 しかし、Qiskitのトランスパイラ・インフラストラクチャはすべて、高度に拡張可能で設定可能です。 このページの残りの部分では、トランスパイラ・スタックの低レベルの機能を利用する方法を詳しく説明する。


プリセットパスマネージャー

この機能は generate_preset_pass_manager() は「プリセット・パス・マネージャー」を作成する。 のインスタンスです。 PassManagerのインスタンスなので QuantumCircuit メソッドに渡します。 PassManager.run() メソッドに渡すことで使用される。 より具体的には、プリセット・パス・マネージャーは StagedPassManagerのインスタンスであり、ステージ前後のフックを含むトランスピレーションの個々のステージをより大きく設定することができる。

プリセット・パス・マネージャーには、最大6つの名前付きステージがある。 以下、実行順に要約し、より詳細な情報は以下のサブセクションに記載する。

init

概要-回路の最適化、マルチ量子ビット演算の1量子ビット演算と2量子ビット演算への削減。 詳細は初期化ステージを参照。

layout

明示的なアンシラを含むように回路を拡張することを含め、仮想量子ビットの物理量子ビットへの初期マッピングを選択する。 この段階は、 routing を包含することもある。 詳細はレイアウトステージを参照。

routing

ゲートを回路に挿入し、回路が以下の接続制約に適合するようにする。 Target. 挿入されるゲートは、まだターゲットISAと一致する必要はないので、多くの場合、単なる swap 。 この段階は、 layout 。 詳細はルーティングステージを参照。

translation

回路内のすべてのゲートを、ISAのISAと一致するものに変換する。 Target. 詳細は翻訳ステージを参照。

optimization

低レベルでハードウェアを意識した最適化。 init ステージの抽象的な最適化とは異なり、このステージは物理的な回路に作用する。 詳細は最適化ステージを参照。

scheduling

挿入 Delay 回路のウォールクロックのタイミングを明示する命令を挿入する。 これには、ウォール・クロック・タイミングの把握に依存する動的デカップリングのような、ハードウェアを意識したオンライン・エラー削減技術も含まれる。 詳しくはスケジューリングステージを参照。

プリセットのトランスパイラ・パイプラインは、 optimization_level を設定することで、ハイレベルに設定することもできます。 これは0から3までの整数で、ハードウェアに対して回路を最適化しようとする際の相対的な労力を示す。 レベル0は、不要な最適化をすべて無効にする。回路を実行可能にするために必要な変換だけが使用される。 一方、レベル3は、あらゆる最適化技術を可能にするが、その中にはコンパイル時間が非常にかかるものもある。 古典的なコンパイラーと同様、最適化レベル3が常に最良の結果をもたらすとは限らない。 Qiskitは、コンパイル時間と期待される最適化量のトレードオフとして、最適化レベル2をデフォルトとしています。

最適化レベルは、デフォルトで指定されたステージにどの実装が使われるかに影響しますが、明示的な <stage>_method="<choice>" 引数を generate_preset_pass_manager().

プリセットパイプラインの再現性

量子コンパイルでは、計算複雑度が非多項式であることが知られている問題を解くことが多く、そのため、グローバルな最適化は困難である。 このような場合、確率的アルゴリズムやヒューリスティックアルゴリズムの方が適していることが多い。 しかし、これによって再現性の問題が生じることになる。

プリセットのパス・マネージャーには、ほとんどの場合、ストキャスティックなヒューリスティック・ベースのパスが含まれている。 コンパイルの再現性を確保する必要がある場合は、ジェネレーター関数の seed_transpiler 引数に既知の整数を渡す。

Qiskitに組み込まれているすべてのプラグインは、分析結果を生成する際、また(もしあれば)ランダム化処理のシードが設定されている場合には、後でコンパイルを再現できるように、確定 DAGCircuit 的な方法でデータを変更する必要があります。 これには制限があります:

  • 確率的なコンポーネントを持つすべての組み込みパスは、ランダム化の播種方法を提供しなければならず、播種された場合は、決定論的出力のルールを尊重しなければならない。
  • ストキャスティックス成分を含まないすべてのビルトインパスは、同一の入力に対して決定論的な出力をするというルールを尊重しなければならない。 効率化のためにキャッシュを残すことは許されるが、同じ入力セットが与えられた場合、パスが複数回呼び出されたとしても、パスのリターンは同じでなければならない。 BasisTranslatorSessionEquivalenceLibrary をデフォルトで使用しており、等価ライブラリに新しいエントリが追加された場合に異なる結果が得られることはバグではありません)。 出力」とは、パスがさらに消費するために書き出すものです。これは、パスからの明示的な returnPropertySet.
  • パスの出力は、与えられたQiskitのバージョンとフリーズした環境の与えられたマシン上で、パスに利用可能なスレッドの数に関係なく、決定論的でなければならない。 Qiskitの組み込みパスの多くはスレッド同時実行を使用しており、スレッド数に応じて異なる動作をすることは許されていません。
  • 固定シードに対するパスの出力は、基礎となる Python 環境の一部が変更された場合(依存パッケージが更新された場合など)や、システムの数学ライブラリが変更された場合(BLAS の異なる実装が利用可能になった場合など)には、同じである必要はありません。
  • 固定シードに対するパスの出力は、オペレーティング・システム間で等しい必要はない(ただし、オペレーティング・システムに関連した違いの根本的な原因は、一般的にシステム数学ライブラリの実装である)。
  • コア数学カーネルの実装が異なれば、CPU命令が異なれば動作も異なることが予想される。例えば、2つの別々の浮動小数点乗算・加算命令と異なる丸め特性を持つ融合型乗加算命令などである。
  • 固定シードに対するパスの出力は、ユーザーが特別にこの動作のオプトアウトをしない限り、使用が許可されているスレッド数に関係なく、同じでなければならない。 QISKIT_SABRE_ALL_THREADS 例えば、プリセットのパスマネージャでは、セイバーのレイアウトとルーティングのメソッドは、許可されているスレッドが1つであっても、トライアルよりもスレッドが多くても、デフォルトで同じ数のトライアルを実行する必要がある。
  • 上記のルールはすべて、 PYTHONHASHSEED が明示的に設定されていない場合でも、 Python インタープリター・セッション間で適用される。

一般的に、Qiskitのユーザーは、組み込みのQiskitパス(必要に応じてシード値が設定されたもの)を任意の組み合わせ DAGCircuit で固定された入力と共に実行した後、すべての DAGCircuit() メソッドの正確な出力が決定論的であると想定できるべきである。 これには、順序について何ら保証しないメソッドの出力順序も含まれます。その意味論や正確な順序は保証されませんが、固定された入力に対する決定性は保証されます。

トランスパイラ・パスの作者は、トランスパイラ・パスを決定論的にする方法については、 Randomness and determinismを参照してください。

プリセットステージの実装の選択

Qiskitには上記のステージの実装がいくつか含まれており、さらに別の「プラグイン」としてインストールすることもできます。 ステージのどの実装が使われるかを制御するには、2つの関数の <stage>_method キーワード引数にその名前を渡します。例えば、 translation_method="translator"。 このような外部プラグインをステージに実装する方法については、以下を参照してください。 qiskit.transpiler.preset_passmanagers.plugin.

例えば、最適化レベル1で、レイアウトに trivial 、配線に sabre

from qiskit.transpiler import generate_preset_pass_manager
from qiskit.providers.fake_provider import GenericBackendV2

# Whatever backend you like:
backend = GenericBackendV2(num_qubits=5)

pass_manager = generate_preset_pass_manager(
    optimization_level=1,
    backend=backend,
    layout_method="trivial",
    routing_method="sabre",
)

各ステージで利用可能なプラグインのビルトインセットはQiskitのパブリックAPIの一部であり、すべての安定性が保証されています。 これには、そのメソッドのハイレベルな論理的効果も含まれる(例えば、 routing_method="sabre" は常にセイバー由来のアルゴリズムを使用する)。 ステージを表す PassManager しかし、ステージを表す内部構造は正確ではない。マイナーバージョン間でパスの順番が変わるかもしれないし、新しいパスが導入されるかもしれない。

ステージがある場合、 "default" というメソッドが最も変更されやすい。 Qiskitは通常、メジャーバージョンの境界を越えてデフォルトメソッドのアルゴリズムを完全に変更するだけですが、マイナーバージョン間でヒューリスティックのバランスを調整したり、デフォルトメソッドに新しいパスを追加したりすることがあります。

の出力は generate_preset_pass_manager() の出力は StagedPassManagerであるため、パス・マネージャーを作成後に変更して、完全にカスタム・ステージの実装を提供することもできる。 例えば、動的デカップリングを使用したカスタムスケジューリングステージを実行し(パス PadDynamicalDecoupling パスを使って)、さらにルーティングの前に最初の論理最適化を追加したい場合、次のようにする(前の例を基にする):

import numpy as np
from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.circuit import library as lib
from qiskit.transpiler import PassManager, generate_preset_pass_manager
from qiskit.transpiler.passes import (
    ALAPScheduleAnalysis,
    InverseCancellation,
    PadDynamicalDecoupling,
)

backend = GenericBackendV2(num_qubits=5)
dd_sequence = [lib.XGate(), lib.XGate()]
scheduling_pm = PassManager(
    [
        ALAPScheduleAnalysis(target=backend.target),
        PadDynamicalDecoupling(target=backend.target, dd_sequence=dd_sequence),
    ]
)
inverse_gate_list = [
    lib.CXGate(),
    lib.HGate(),
    (lib.RXGate(np.pi / 4), lib.RXGate(-np.pi / 4)),
    (lib.PhaseGate(np.pi / 4), lib.PhaseGate(-np.pi / 4)),
    (lib.TGate(), lib.TdgGate()),
]
logical_opt = PassManager([InverseCancellation(inverse_gate_list)])

pass_manager = generate_preset_pass_manager(optimization_level=0)
# Add pre-layout stage to run extra logical optimization
pass_manager.pre_layout = logical_opt
# Set scheduling stage to custom pass manager
pass_manager.scheduling = scheduling_pm

これで、ステージング・パス・マネージャーが run() メソッドで実行されると、 layout ステージの前に logical_opt パス・マネージャーが呼び出され、 scheduling ステージではデフォルトではなく scheduling_pm パス・マネージャーが使用されます。

プリセットパスマネージャ用にカスタムステージを構築する場合、以下の低レベルヘルパー関数が役に立つかもしれません。 qiskit.transpiler.preset_passmanagers が役に立つかもしれません。

初期化段階

関連資料

イニシャルステージの説明

IBM クアンタムガイドのinitステージに関する、ユーザー向けのより高度な説明。

init ステージは、抽象的な回路を高レベルで論理的に最適化し、複数量子ビット(3+)演算を一連の1量子ビットや2量子ビット演算に引き下げる役割を担っている。 これは第1段階の実行であるため、その入力は完全に抽象化された回路である。 init ステージは、カスタムのユーザー定義ゲートを扱うことができなければならない。 AnnotatedOperation.

init ステージの出力は、1量子ビットと2量子ビットの演算のみを含む抽象回路である。

ステージプラグインを書くとき、 init のエントリーポイントは qiskit.transpiler.init です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルトマルチ量子ビット演算のアンロールと抽象的な最適化を内蔵。

組み込み default プラグイン

最適化レベル 0 では、抽象的な最適化は行われません。 デフォルトのプラグインは、3つ以上の量子ビットを含む操作に対して、それらの階層的な definition フィールドにアクセスすることで、単にそれらを「展開」するだけです。

最適化レベル1以上では、デフォルトのプラグインは、2つの背中合わせの cx ゲートなど、隣接する逆ゲートの単純なキャンセルも行う。

最適化レベル2と3では、デフォルトのプラグインは、より幅広い抽象的な最適化を可能にする。 こちらには以下の内容が含まれます:

  • 「仮想順列エリジョン ElidePermutationsを参照)。そこでは、明示的な並べ替えを誘発する演算は削除され、代わりに仮想量子ビットの再マッピングが行われる。
  • IRの整流構造を解析し、相殺できるゲートのペアを見つける。
  • 一連の分離可能な1量子ビット演算として表現できる2量子ビット演算の数値分割。
  • 微小角度のパウリ回転や測定直前の対角線演算など、知覚不可能な演算の除去。

レイアウト段階

関連資料

レイアウト段階の説明

IBM クォンタムガイドのレイアウト段階に関する、ユーザー向けのより高度な説明。

レイアウト段階は、入力回路の仮想量子ビットとターゲットのハードウェア量子ビット間の初期マッピングを行う。 これには、入力回路を明示的なアンシラで拡張し、ターゲットが持つ量子ビット数と同じ数の量子ビットを持つようにすることと、すべての演算をハードウェア量子ビットの観点から書き換えることが含まれる。 他のツールキットや文献では、この問題を「配置」問題と呼ぶこともある。

layout original_qubit_indices レイアウトステージは、パイプラインの PropertySet.

レイアウトステージ用のすべての組み込みプラグインは、 initial_layout の引数 generate_preset_pass_manager() または transpile().

回路内の任意の時点で、入力回路の現在アクティブな "仮想 "量子ビットとバックエンドのハードウェア量子ビットとの間のマッピングを特定することができる。 ハードウェア量子ビットは、ある時点では1つの仮想量子ビットしか表現できないが、回路の過程でマッピングが変化する可能性がある。 原理的には、仮想量子ビット状態の寿命を短くすることができれば、回路実行の全ポイントでマッピングされない仮想量子ビットもあり得ますが、Qiskitの組み込みパイプラインでは今のところこの方法は使われていません。

入力回路からの仮想量子ビットが、バックエンドデバイスのコネクティビティマップ上のハードウェア量子ビットにどのようにマッピングされるかを示す図。

レイアウト・ステージは、ターゲットの接続性が回路全体を通して尊重されていることや、すべてのオペレーションがターゲット上で直接実行するのに有効であることを保証する責任はない。これらはそれぞれ、 配線ステージとトランスレーション・ステージの責任である。

初期レイアウトの選択は、出力回路の品質を左右する最も重要な要素のひとつである。 レイアウトステージは、デフォルトのパイプラインの中で最も計算量の多いステージであることが多い。レイアウト用のデフォルトプラグインでは、いくつかの異なるアルゴリズムが試されるほどである(詳細は内蔵のデフォルトプラグインで説明)。

レイアウトステージの理想的な状況は、すべてのオペレーションが配線ステージの接続性制約を尊重するような "完璧な "レイアウトを見つけることである。 Target ルーティングステージが不要になるような「完璧な」レイアウトを見つけることです。 これは通常、任意の入力回路では不可能だが、それが可能な場合は VF2Layout パスを使って有効な初期レイアウトを見つけることができる。 複数の完璧なレイアウトが見つかった場合、推定エラー率に基づくスコアリング・ヒューリスティックが使用するレイアウトを決定するために使用される。

すべての組み込みプラグインで generate_preset_pass_manager() 引数 initial_layout を渡すと、与えられたレイアウトがそのまま使われ、個々の「選択」ロジックはスキップされます。 すべての内蔵プラグインは、アンシラの割り当てを含め、回路をデバイスの全幅に埋め込む処理も行う。

独自のレイアウト・プラグインを作成する場合、レイアウト・アプリケーションの「埋め込み」段階を自動化するために generate_embed_passmanager() を使うと便利です。

ステージプラグインを書くとき、 layout のエントリーポイントは qiskit.transpiler.layout です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルト最高の最適化レベルでは、完璧なレイアウトを見つけ、セイバーベースのレイアウトとルーティングの複合パスを試みる。
高密度の初期量子ビットとして使用するバックエンドの最も密な部分グラフ(量子ビットリンク度)を見つける。
平凡な仮想量子ビット0を物理量子ビット0にマッピングする。
セイバーQiskitの強化されたSabreレイアウトアルゴリズムを使用。

すべての最適化レベルにおいて、デフォルトのレイアウト手法は default であるが、このステージの構成はレベルに応じて大きく変化する。

組み込み default プラグイン

いくつかの異なるレイアウト技術の融合。

最適化レベル0では、些細なレイアウトが選択される。

0以上の最適化レベルでは、2段階のプロセスがある:

  1. まず VF2Layout を使って "完璧な "レイアウトを見つけようとする。 同型性評価器の最大呼び出し回数は、最適化レベルに応じて増加する。 巨大で複雑なターゲットの場合、たとえ完璧なレイアウトが存在したとしても、それを見つけられる保証はない。
  2. 完璧なレイアウトが見つからない場合は SabreLayout を使用して初期レイアウトを選択する。初期レイアウトの試行回数、スワップ・マップの試行回数、および前後方向の反復回数は、最適化レベルに応じて増加する。

さらに、最適化レベル1では、歴史的な後方互換性を保つために、 VF2-based バージョンより前の些細なレイアウトも試している。

組み込み dense プラグイン

レイアウトの選択には DenseLayout パスを使ってレイアウトを選択する。 このパスでは、完全なターゲット接続性グラフの中で最も密な接続部分グラフを見つける。 仮想からハードウェアへのマッピングは、最も次数の高い仮想量子ビットを最も次数の高いハードウェア量子ビットに割り当てることで完了する。

これは、初期レイアウトを選択するための比較的安価なヒューリスティック手法であるが、一般的にセイバーベースの手法よりも出力品質がはるかに悪い。 デフォルトのレイアウト・プラグインは DenseLayout によって選択された初期マッピングをセイバーアルゴリズムのシードとして使用します。

組み込み trivial プラグイン

レイアウトの選択には TrivialLayout パスを使ってレイアウトを選択する。 これは最も単純な割り当てであり、各仮想量子ビットは同じインデックスを持つハードウェア量子ビットに割り当てられるため、仮想量子ビット0はハードウェア量子ビット0にマップされ、以下同様となる。

この方法は、ハードウェアの特性評価実験に最も有効で、入力される "抽象的な "回路はすでにデバイス上にフルワイドで存在し、その演算は物理的な演算に対応し、トランスパイラが物理的な回路の生成を形式化するために呼び出されるだけである。 QuantumCircuit.

組み込み sabre プラグイン

を使用します。 SabreLayout を使用して初期レイアウトを選択し、Qiskitの修正 Sabreルーティングアルゴリズムをサブルーチンとして使用して、候補回路を前後にスワップマッピングします。

要約すると、 オリジナルのセイバー・アルゴリズムのレイアウト・コンポーネントは、初期レイアウトを任意に選択し、回路上でルーティングを実行し、回路を反転させ、前回の「最終的な」仮想-ハードウェア割り当てを初期状態として反転回路上でルーティングを実行することで、それを「改善」しようとする。 設定された最適化レベルでは、この往復を何回繰り返すか、そして何種類のランダムな初期レイアウトを試すかを決定する。

最適化レベルが0以外の場合のデフォルトステージとの主な違いは、このプラグインがセイバーベースのアルゴリズムのみを実行することである。 完璧なレイアウトを見つけようともしないし、つまらないレイアウトをしようともしない。

ルーティング段階

関連資料

ルーティング・ステージの説明

IBM クォンタムガイドにおけるルーティングステージの、より高いレベルのユーザー向けの説明。

ルーティング・ステージは、回路の仮想接続性グラフがターゲットのハードウェア接続性グラフと互換性があることを保証する。 より簡単に言えば、ルーティング・ステージは、回路内のすべての2量子ビット・ゲートが、ターゲットISAで定義された2量子ビット演算を行うハードウェア量子ビットにマッピングされるようにする。 他のツールキットや文献では、この問題を「マッピング」または「スワップマッピング」問題と呼ぶこともある。

ルーティング・アルゴリズムは通常、 swap ゲートを回路に挿入し、回路実行の過程で量子ビットの仮想-ハードウェア・マッピングを変更することでこれを行う。

配線段階では、回路内のすべてのゲートがターゲットISAに対して有効であることを保証する必要はない。 例えば、ルーティングプラグインは、 swap ゲートを回路に残すことができます。 Target が含まれていなくても SwapGate. ただし、回路にゲートが適用されているハードウェア量子ビットのペアには、少なくとも1つの2量子ビットゲートが定義されていなければならない。 Target 回路にゲートが適用されているハードウェア量子ビットのペアには、少なくとも1つの2量子ビットゲートが定義されていなければなりません。

ルーティングステージは、ルーティングが行われた場合、 final_layoutvirtual_permutation_layout のプロパティを設定しなければならない。 PropertySet プロパティを設定しなければなりません。

Qiskitの組み込みルーティングステージはすべて、ルーティング後に追加で VF2PostLayout パスを実行します。 これにより、より低エラーの量子ビットが見つかれば、初期レイアウトを再割り当てできるかもしれない。 このパスは、 VF2Layout デフォルトのレイアウトプラグインが使用するクラス(ただし、 VF2PostLayout 回路トポロジと一致するターゲットトポロジの同型誘導サブグラフが少なくとも 1 つ存在することが保証されます。

Qiskitの組み込みルーティングプラグインはすべて、定義された2量子ビットリンクを持つすべての量子ビットのペアが、それらの2量子ビットに対して定義されたゲートのユニバーサルセットを持っていると一般的に仮定しています。 ハードウェアは必ずしもこれを尊重する必要はない(例えば、定義された2量子ビットゲートが swap だけであれば、 cx のようなエンタングル演算は実現できない)が、Qiskitはまだこの可能性を考慮していない。

挿入するスワップの最小数を求めることは、非多項式問題であることが知られている。 そのため、Qiskitの組み込みアルゴリズムの多くは確率的であり、異なるコンパイル間で大きなばらつきが見られる可能性があります。 再現性が必要な場合は、 seed_transpiler の引数 generate_preset_pass_manager() または transpile().

ステージプラグインを書くとき、 routing のエントリーポイントは qiskit.transpiler.routing です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルトQiskitが選択したデフォルトのルーティング方法を使用する。
セイバーデフォルト。 Qiskitの修正Sabreルーティングアルゴリズムを使ってマップを交換する。
なしルーティングを無効にする。 ルーティングが必要な場合はエラーを出す。
基本貪欲なスワップ挿入で、一度に1つの操作をルーティングする。
予見ゲートを実行可能にするスワップを見つけるためのヒューリスティックな刈り込みを伴う幅優先探索。

組み込み default プラグイン

Qiskitが選択したデフォルトのルーティング方法を使用する。 Qiskit 2.0 の時点で、選択されたアルゴリズムはビルトインのsabreプラグインと同じですが、実際には通常、ビルトインのデフォルトレイアウトステージプラグインが sabreベースのルーティングアルゴリズムを実行し、ルーティングステージは実行するためだけに使用されます。 VF2PostLayout.

組み込み none プラグイン

ルーティングを完全に無効にするためのダミー・プラグイン。 これは、ハードウェアのコンフィギュレーション実験や、部分的なコンパイルの特殊な場合に役立つことがある。

組み込み basic プラグイン

BasisSwap greedy swap-insertion アルゴリズムを使用する。 これは概念的に非常に簡単で、トポロジカルな順序で各オペレーションに、その接続をデバイス上で実行可能にするために必要な最短パスのスワップを挿入する。

最適化レベルは、配線後の初期レイアウトの改善を試みるステップの作業量にのみ影響します。 VF2PostLayout ステップでは、配線後の初期レイアウトを改善するための作業量にのみ影響します。

この方法は一般的に出力品質が低い。

組み込み lookahead プラグイン

ルーティングに LookaheadSwap アルゴリズムを使う。 これは本質的に、スワップ・ネットワークを生成するための幅優先探索であり、探索されるツリーは、各深さにおいて少数のスワップ候補に刈り込まれる。

このアルゴリズムは、 "sabre "プラグインの basic ヒューリスティックに似ているが、各スワップの次のような影響も小さな深さまで考慮する点が異なる。

最適化レベルは、探索の深さ、深さごとの枝刈りの量、および初期レイアウトを最適化するために VF2PostLayout による作業量に影響する。

実際には、 "sabre "プラグインは数桁速く動作し、より良い出力を生み出す。

組み込み sabre プラグイン

ルーティングに SabreSwap アルゴリズムを使う。 これは、Qiskit のオリジナルの Sabre ルーティング アルゴリズム拡張バージョンを使用します。

このルーティングアルゴリズムはスレッド並列で実行され、ルーティングのいくつかの異なる可能性を検討し、挿入されるスワップ数を最小にするものを選択する。

最適化レベルは、完全なルーティングのために何種類の確率的シードを試行するか、また、初期レイアウトの最適化後に VF2PostLayout が行う作業量に影響します。

このプラグインはほとんど常に最高のパフォーマンスを発揮する内蔵プラグインであり、ルーティングが必要なすべてのケースでQiskitがデフォルトで使用するものです。

翻訳段階

関連資料

翻訳段階の説明

IBM クォンタムガイドにおける翻訳段階の、より高いレベルのユーザー向けの説明。

トランスレーション・ステージは、回路内のすべてのゲートをターゲットISAがサポートするゲートに書き換える役割を担う。 例えば、 cx がハードウェア量子ビット0と1に対して要求されているにもかかわらず、ISAがこれらの量子ビットに対して cz 操作しか含んでいない場合、変換ステージは cz と利用可能な1量子ビットゲートを使用して cx ゲートを表現する方法を見つけなければなりません。

翻訳段階は、最適化段階に入る前に呼び出される。 最適化プラグイン(Qiskitの組み込みプラグインを含む)は、最適化ループが非ISAゲートを含む回路を返す場合、最適化ループの後の「フィックスアップ」ステージとして翻訳ステージを使用することもできます。 最適化ループは、「2量子ビットゲートの数」のようなプロパティを最小化することにしか関心がなく、その出力を局所的に等価なゲートで残すかもしれない。 これによって、2つのステージ間の懸念事項の分離が容易になる。 最適化プラグインによっては、出力がより厳しくなり、翻訳段階へのフォローアップが不要になる場合もある。

ステージプラグインを書くとき、 translation のエントリーポイントは qiskit.transpiler.translation です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルトQiskitが選択したデフォルトの翻訳方法を使用する。
変換プログラム既知の等価性を用いてゲートをターゲット基底に記号変換する。
合成1qubitゲートと2qubitゲートの各ランを行列表現に集め、そこから再合成する。

組み込み default プラグイン

Qiskitが選択したデフォルトの翻訳方法を使用する。 Qiskit 2.0 の時点では、これは Built-in translator pluginと同じですが、選択されたアルゴリズムは、 2.x シリーズの間に、すべてのターゲットに対して、または特定のクラスのターゲットに対してのみ、変更される可能性があります。

組み込み synthesis プラグイン

同じ量子ビットのゲートのランをマトリックス形式に収集し、(設定された )パスを使って再合成する。 UnitarySynthesis パスで再合成する(設定された unitary_synthesis_method )。 これは、高い最適化レベルでは、最適化ループそのものに似ている。

行列へのコレクションは、行列を使わない翻訳よりも一般的にコストがかかるが、原理的には翻訳の質は向上する。 実際には、ターゲットISAに合わせた合成アルゴリズムが必要となるため、この手法は他の手法に比べて汎用性に欠ける。 Qiskitにすでにある合成ルーチンにマッチする単純なISAをターゲットにした場合、より高品質な結果を得ることができる。

この方法を使えば、最適化ループは必要ないかもしれない。

最適化レベルはこのプラグインには影響しません。

組み込み translator プラグイン

アルゴリズムを使って BasisTranslator アルゴリズムを使って、ゲートをターゲット基底に記号変換する。 高いレベルでは、回路から要求されたゲートのセットから開始し、与えられた EquivalenceLibrary (典型的には SessionEquivalenceLibrary)からISAに向かう。

これはデフォルトの翻訳方法です。

最適化レベルはこのプラグインには影響しません。

最適化段階

関連資料

最適化段階の説明

IBM クォンタムガイドにおける最適化段階の、より高いレベルのユーザー向けの説明。

最適化段階では、ハードウェアを意識した低レベルの最適化が行われる。 initステージとは異なり、このステージへの入力はすでにISA互換の回路であるため、低レベルの最適化プラグインを特定のISAに合わせて調整することができる。

最適化プラグインには、ISAをサポートする回路を取り込み、ISAをサポートする回路を返すこと以外、ほとんど要件はない。 最適化プラグインは、しばしば DoWhileController最適化プラグインはしばしばループを含み、フィックスアップパイプラインとして設定された翻訳ステージを含むかもしれない。

Qiskitのビルトイン最適化プラグインは一般的で、非エラー補正デバイスのほとんどの実世界ISAにうまく適用されます。 内蔵プラグインは、連続的にパラメトライズされた単一量子ビットゲートを持たないISAにはあまり適していない。

ステージプラグインを書くとき、 optimization のエントリーポイントは qiskit.transpiler.optimization です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルト最適化パスのデフォルトセット。 これは最適化レベルによって大きく異なる。

組み込み default プラグイン

これは最適化レベルによって大きく異なります。

このパイプラインの詳細は、Qiskitのバージョンによって変更される場合があります。 その大まかな原則を以下に説明します。

最適化レベル0では、ステージは空である。

最適化レベル1では、1量子ビットゲートの実行を行列ベースで再合成し、2量子ビットゲートが連続して現れる場合は、非常に単純な記号的逆キャンセルを行う。 これは、回路のサイズと深さが確定するまでループする。

最適化レベル2では、レベル1の最適化に加え、ループにゲートの集合の転流解析が含まれ、キャンセルを考慮できるゲートの範囲が広がる。 ループの前に、1qubitゲートと2qubitゲートの両方が1つのマトリックスベースの再合成を受ける。

最適化レベル3では、2量子ビット行列ベースの再合成が最適化ループ内で実行される。 また、最適化ループ条件は、複数回の実行を試み、出力が変動する場合に最小点を選択する。これは、マトリックスベースの再合成が具体的なゲートの点で比較的不安定であるため、必要なことである。

最適化レベル3は通常、大規模な回路では非常に高価になる。

スケジューリング段階

関連資料

サーキットのスケジューリング

スケジューリングの概念をガイドレベルで解説。

スケジューリング・ステージは、要求があれば、明示的な命令を挿入する責任を負う。 Delay を挿入する責任があります。 プラグインはオプションで、動的デカップリングシーケンスの挿入など、ウォールタイムに依存した変換を行うこともできる。

スケジューリング・ステージへの入力はISA互換回路である。 スケジューリングステージの出力も、ISA互換回路でなければならない。 Delay また、スケジューリングステージの出力はISA互換回路でなければならない。

node_start_time スケジューリング・ステージは、パイプラインの PropertySet.

ステージプラグインを書くとき、 scheduling のエントリーポイントは qiskit.transpiler.scheduling です。 内蔵プラグインは以下の通り:

メソッド
サマリー
デフォルトスケジューリングせずに、タイミングアライメントの制約を満たそうとする。
アラップサーキットのスケジュールを組み、できるだけ遅い時間帯のオペレーションを希望する。
ASAPサーキットのスケジュールを組む。

組み込み default プラグイン

回路がすでに明示的なタイミングを持つ命令を含んでいない限り、何もしないでください。 回路内に明示的にタイミングが設定された演算がある場合は、これらのタイミングがアライメントやその他のハードウェア制約を満たすように、追加のパディングを挿入する。

組み込み alap プラグイン

できるだけ遅く」戦略を用いて、すべてのオペレーションを明示的にスケジューリングする。 これは ALAPScheduleAnalysis アルゴリズムを使ってゲートの配置を決める。

組み込み asap プラグイン

できるだけ早く」戦略を用いて、すべてのオペレーションを明示的にスケジューリングする。 これは ASAPScheduleAnalysis アルゴリズムを使ってゲートの配置を決める。


カスタムパス管理ツール

プリセットのパスマネージャーを変更するだけでなく、入力回路を変換するための完全にカスタムなパイプラインを構築するためにパスマネージャーを構築することも可能です。 これを行うには StagedPassManager クラスを直接使うことができる。 任意のステージ名を定義し、そこに PassManager インスタンスを作成します。 例えば、次のコードは、2つのステージを持つ新しい StagedPassManager を作成し、 inittranslation の2つのステージを持つ。

from qiskit.transpiler.passes import (
    UnitarySynthesis,
    Collect2qBlocks,
    ConsolidateBlocks,
    UnitarySynthesis,
    Unroll3qOrMore,
)
from qiskit.transpiler import PassManager, StagedPassManager

basis_gates = ["rx", "ry", "rxx"]
init = PassManager([UnitarySynthesis(basis_gates, min_qubits=3), Unroll3qOrMore()])
translate = PassManager(
    [
        Collect2qBlocks(),
        ConsolidateBlocks(basis_gates=basis_gates),
        UnitarySynthesis(basis_gates),
    ]
)

staged_pm = StagedPassManager(
    stages=["init", "translation"], init=init, translation=translate
)

に入れるステージ数に制限はない。 StagedPassManager. ステージはQiskitのプリセットパイプラインで使用されるステージに対応する必要はありません。

ステージ・ジェネレーター関数は、カスタム・インスタンスの構築に役立つ。 StagedPassManager インスタンスを構築するのに便利である。 多くのステージで使用される共通機能を提供するパス・マネージャーを生成する。 例えば generate_embed_passmanager()PassManager を生成する。 Layout を生成します。


カスタムトランスパイラパスの記述

Qiskitは、カスタムの特殊なトランスパイラパスで拡張できるように設計されています。

トランスパイラー・パスは2種類ある:「解析 "パス(AnalysisPass)、回路を読み込んでグローバルな解析プロパティを PropertySet に書き込むパス、および "変換 "パス(TransformationPass)があります。 DAGCircuit を変更するか、新しい DAGCircuit を返します。 歴史的に、Qiskitはこの2つのタイプを強く分離しようとしていた。 しかし、最近のQiskitでは、解析と修正の両方を1つのスタンドアローン TransformationPassに含めるのが一般的です。 パスが純粋に分析に基づくものである場合は、次のようにするのが適切である。 AnalysisPass.

パスの作成に関する基本原則

を変更または新規作成したい場合は DAGCircuitを書かなければならない。 TransformationPass. を変更せず、 PropertySet に書き込むだけなら、次のように書くべきである。 DAGCircuitを書くべきである。 AnalysisPass. 両方やりたい場合は TransformationPass. どちらの場合も、必要なメソッドは BasePass.run() だけである。 これは単一の引数( self 以外)、 dag: DAGCircuit を受け付けるべきである。 もし TranspilerPass ならば、 DAGCircuit (その場で修正すれば入力になる)を返すべきである。 AnalysisPassの場合は None を返す。

パスにイニシャライザーがある場合は、 super().__init__() を呼び出す必要があります。

通常、パスはイニシャライザーに Target イニシャライザには、コンパイル対象の量子ハードウェアを記述します。 個別のカップリング・マップや基底ゲートのリストのような "緩い "制約を受け入れることは推奨されない。 Target 一般的なヘテロジニアスハードウェアをより正しく記述するためです。

パイプラインの実行中に PassManager パイプラインの実行中、パスの run() メソッドが呼び出されると、 self.property_set 属性にアクセスし、移行の現在の PropertySet 状態を取得することができます。 この場所から読み込み、この場所に書き込む必要がある。 あなたのパスは、もしあれば、プロパティ・セット内のどの属性から読み込み、どの属性に書き込むかを明確に文書化する必要がある。

無作為性と決定論

量子コンパイルでは、大域的最適化が困難な問題を解くことが多い。 このような場合、確率的アルゴリズムや発見的アルゴリズムの方が適していることが多い。 しかし、これは再現性の問題につながる。

組み込みのQiskitパスが従わなければならないのとまったく同じルールセットのもとで、カスタムパスが決定論的でなければならないという正式な要件はありません。 ただし、独自のパスではこれらのルールに従うことを強くお勧めします。科学は再現性によって成り立っており、以前に観察された動作を再現できない場合、デバッグは悪夢となります。

トランスパイラのパスを書くとき、以下の(代表的で網羅的でない)例が決定論的であることを信頼することができます。たとえ、順序の正確なセマンティクスが完全に指定されていなくても、パスは特定の順序に依存すべきではありません

  • 順番のノードは DAGCircuit.op_nodes(). 対照的に topological_op_nodes() デフォルトでは、ノードの削除/挿入の順序にまったく影響されない順序付けキーが含まれているため、同じデータ・フローを持つ同じノード・セットが指定されれば、それが異なる順序で構築されたとしても、完全に決定論的である。
  • エッジの順番は DAGCircuit.edges().
  • からランが返される順序。 DAGCircuit.collect_2q_runs()から返される順序、およびランのノードが遭遇する正確な順序。
  • などの順序生成メソッドでノードが遭遇する順序を指定する。 predecessors(), bfs_successors()などでノードに出会う順番。

一般的には、 同じ回路をまったく同じ順番で修正することが要求される。 例えば、ノードを追加、縮小、削除する場合、これらの変更の順序は決定論的順序で行われなければならず、置換は決定論的に指定されなければならない。

これを確実にするためのヒントには、以下のようなものがある:

  • ハッシュ・ベースのコンテナを反復処理する場合は、十分に注意すること。 Python 'に対する反復。 set に対する反復は、ハッシュシードのランダム化により非決定論的である。 Rustでは、標準ライブラリのハッシュベースのコンテナ(デフォルトのハッシャーで hashbrown に相当するものを含む)に対する反復処理は、非決定論的である。

    Python に対する反復は決定論的である。 dict* は*決定論的であり、削除がなければ挿入順であることが保証され、決定論的な削除があれば任意であるが決定論的な順序であることが保証される。

    Python で set を作成し、それを反復処理する必要がある場合は、代わりに dictNone を使うことを検討してください。 を使っても問題ない。 set 純粋にメンバーテストに使う分には問題ない。

    Python Rustでは、 indexmap とその構造体である IndexMapIndexSet を、それぞれ HashMapHashSet の代わりとして使用する。 dict.

  • 関数型に確率的要素が含まれる場合は、必ず stochastic 型の seed 入力を受け入れるようにし、整数が渡された場合は出力を純粋な関数型にするようにしてください。 通常、これはシードを保存し、各呼び出しの開始時にこのシードから新しい pRNG をインスタンス化することを意味します。 BasePass.run()

  • スレッド並列処理を使用する場合は、出力がスレッドの処理順序や部分的な結果を返す順序に依存しないように注意すること。 例えば、作業をスレッドプールに分散し、最後に結果を収集する場合、出力が入力に対応する順序で配置されていることを確認する。 Python では、 concurrent.futures.ThreadPoolExecutor.map() のような関数がこれを保証する。 同様にRustでは、 rayon'の並列イテレータは、入力と同じ順序で出力を収集する。

    このイテレータの各項目に関数を適用し、あるメトリックを最小化するものを選択する」というような並列的な୧⃛(๑⃙⃘⁼̴̀꒳⁼̴́๑⃙⃘)୨⃛は、メトリックに縮退がある場合、一般的にスレッド非決定性の影響を非常に受けやすいので注意すること。 例えば、イテレータ内の2つのアイテムが同じ比較キーを持つ等しくない出力を生成する場合、スレッド環境で選択されるものは決定論的ではない。 これを避けるには、決定論的なタイブレーカーを適用して縮退を解除する。例えば、入力を列挙してシーケンス番号をタイブレーキングキーとして使用し、2つの項目が同じスコアを持つ場合、より早い入力に対応するものが確実に選択されるようにする。


量子コンピュータの表現

を特定のバックエンド用にコンパイルできるようにするには、そのバックエンドに特化した表現が必要です。 QuantumCircuit トランスパイラが特定のバックエンドをコンパイルし、効果的に最適化するためには、そのバックエンドの制約、命令セット、量子ビットの特性などを含む、そのバックエンドに特化した表現が必要です。 この BackendV2 クラスはバックエンドへの問い合わせと相互作用のためのインターフェイスを定義していますが、その範囲はジョブ投入の管理やリモートサービスとの潜在的なインターフェイスなど、トランスパイラのニーズだけではありません。 トランスパイラが必要とする特定の情報は Target クラス

たとえば、単純な Target オブジェクトを構築するには、そのオブジェクトがサポートする命令の記述を繰り返し追加すればよい:

from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)
print(target)
Target
Number of qubits: 3
Instructions:
    cx
        (0, 1):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
    u
        (0,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (1,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    rz
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    ry
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    rx
        (1,):
            Duration: 5e-08 sec.
            Error Rate: 1e-05
        (2,):
            Duration: 6e-08 sec.
            Error Rate: 2e-05
    cz
        (1, 2):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
        (2, 0):
            Duration: 5e-07 sec.
            Error Rate: 0.0001
    measure
        (0,):
            Duration: 5e-05 sec.
            Error Rate: 0.001
        (1,):
            Duration: 6e-05 sec.
            Error Rate: 0.002
        (2,):
            Duration: 5e-07 sec.
            Error Rate: 0.2

これは Target をサポートする3量子ビットのバックエンドである。 CXGate をサポートしています、 UGate をサポートします、 RZGate, RXGateそして RYGate をサポートしています、 CZGate 量子ビット1と2間、量子ビット2と0間、および Measure すべての量子ビット上。

からの情報の特定のサブセットを表現するための特定のデータ構造もある。 Target. 例えば CouplingMap クラスは、バックエンドの接続制約を有向グラフとして表現するためだけに使われます。 カップリング・マップは Target から生成できる。 Target.build_coupling_map() メソッドを使って これらのデータ構造は Target インスタンスでネイティブに動作しないトランスパイラのパスや、バックエンドが最新の Target インスタンスでネイティブに動作しないトランスパイラ・パスの一部や、最新の BackendV2 インターフェイスを使用していないバックエンドを扱うときに使用されます。

例えば、3量子ビットの例について CouplingMap 3量子ビットの例 Target 上記の

from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map().draw()

のグローバルな接続性を示している。 Target のサポートされる量子ビットの組み合わせである。 CXGateCZGate. 個々の接続性を確認するには、 CouplingMap.build_coupling_map() に操作名を渡します:

from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map('cx').draw()
from qiskit.circuit import Parameter, Measure
from qiskit.transpiler import Target, InstructionProperties
from qiskit.circuit.library import UGate, RZGate, RXGate, RYGate, CXGate, CZGate

target = Target(num_qubits=3)
target.add_instruction(CXGate(), {(0, 1): InstructionProperties(error=.0001, duration=5e-7)})
target.add_instruction(
    UGate(Parameter('theta'), Parameter('phi'), Parameter('lam')),
    {
        (0,): InstructionProperties(error=.00001, duration=5e-8),
        (1,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RZGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RYGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    RXGate(Parameter('theta')),
    {
        (1,): InstructionProperties(error=.00001, duration=5e-8),
        (2,): InstructionProperties(error=.00002, duration=6e-8)
    }
)
target.add_instruction(
    CZGate(),
    {
        (1, 2): InstructionProperties(error=.0001, duration=5e-7),
        (2, 0): InstructionProperties(error=.0001, duration=5e-7)
    }
)
target.add_instruction(
    Measure(),
    {
        (0,): InstructionProperties(error=.001, duration=5e-5),
        (1,): InstructionProperties(error=.002, duration=6e-5),
        (2,): InstructionProperties(error=.2, duration=5e-7)
    }
)

target.build_coupling_map('cz').draw()

回路のスケジューリング

関連資料

スケジューリング段階

プリセット・パス・マネージャーのスケジューリング・ステージの設定方法。

回路がターゲット・ベースに変換され、デバイスにマッピングされ、最適化された後、スケジューリング・フェーズを適用して、回路内のすべてのアイドル時間を考慮することもできる。 高度なレベルでは、スケジューリングは、命令を実行する間の量子ビットのアイドル時間を考慮し、回路に遅延を挿入すると考えることができる。 例えば、次のような回路から始めるとする:

先に説明した回路を示す図。

を呼び出すことができる。 transpile()scheduling_method

from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import GenericBackendV2

backend = GenericBackendV2(5)

ghz = QuantumCircuit(5)
ghz.h(0)
ghz.cx(0,range(1,5))

circ = transpile(ghz, backend, scheduling_method="asap")
circ.draw(output='mpl')
先のコードで出力された回路図。

トランスパイラが各量子ビットのアイドル時間を考慮して Delay が挿入されている。 回路のタイミングをよりよく知るために、 timeline.draw()

サーキットタイムラインドロワーからの出力。

回路のスケジューリングには、解析と制約マッピングの2つのパートがあり、その後にパディング・パスが続く。 最初の部分では、 ALAPSchedulingAnalysisASAPSchedulingAnalysis のようなスケジューリング解析パスを実行する必要がある。このパスは、回路を解析し、プロパティセット内のスケジューリングアルゴリズム( ALAPSchedulingAnalysis では "as late as possible"、 ASAPSchedulingAnalysis では "as soon as possible")を使用して回路内の各命令の開始時刻を記録する。 回路が初期スケジューリングされると、アライメント制約などターゲット・バックエンドのタイミング制約を考慮するために、追加のパスを実行することができる。 これは通常 ConstrainedReschedule パスで行われ、プロパティセットのスケジューリングセットをターゲットバックエンドの制約に合わせます。 すべてのスケジューリングと調整/再スケジューリングが終了すると、次のようなパディング・パスが行われる。 PadDelay または PadDynamicalDecoupling などのパディングパスが実行され、命令が回路に挿入される。


トランスパイラ API

ハードウェアの詳細

Target([description, num_qubits, dt,...] )Target オブジェクトの意図は、Qiskitのコンパイラに特定のバックエンドの制約を通知し、コンパイラが入力回路をデバイスに最適化された動作するものにコンパイルできるようにすることです。
InstructionProperties[(期間、エラー)]ゲート実装のプロパティの表現。
WrapAngleRegistry()アングルラッピング機能の登録

パス管理者の定義

StagedPassManager[段階]個々のステージから構築されるパスマネージャーパイプライン。
PassManager([passes, max_iteration] )パスのセットのマネージャーと、トランスピレーション中のスケジューリング。
PassManagerConfig([initial_layout,...] )パスマネージャーの設定。
generate_preset_pass_manager([...])プリセットを生成する PassManager

レイアウトとトポロジー

Layout([input_dict] )レイアウトを表す双方向ディクテーション。
CouplingMap([カップリングリスト, 説明] )固定結合を指定する有向グラフ。
TranspileLayout(initial_layout,...[,...] )トランスパイラからの出力回路のレイアウト属性。

スケジューリング

InstructionDurations([instruction_durations, dt] )スケジューリングのための指示の持続時間を提供するヘルパークラス。

要約パス

TransformationPass(*args, **kwargs)変換パス:プロパティセットではなく、DAGを変更する。
AnalysisPass(*args, **kwargs)分析パス:DAGではなくプロパティセットを変更する。

例外

TranspilerError

exception qiskit.transpiler.TranspilerError(*message)

GitHub

ベース: TranspilerAccessError

トランスパイル中に発生した例外。

エラーメッセージを設定する。

TranspilerAccessError

exception qiskit.transpiler.TranspilerAccessError(*message)

GitHub

ベース: PassManagerError

廃止:トランスパイラパスのアクセスエラーの例外。

エラーメッセージを設定する。

CouplingError

exception qiskit.transpiler.CouplingError(*msg)

GitHub

ベース: QiskitError

カップリング・グラフ・オブジェクトによって発生するエラーの基底クラス。

エラーメッセージを設定する。

LayoutError

exception qiskit.transpiler.LayoutError(*msg)

GitHub

ベース: QiskitError

レイアウトオブジェクトによって発生したエラー。

エラーメッセージを設定する。

CircuitTooWideForTarget

exception qiskit.transpiler.CircuitTooWideForTarget(*message)

GitHub

ベース: TranspilerError

ターゲットに対して回路が広すぎる場合、エラーが発生する。

エラーメッセージを設定する。

InvalidLayoutError

exception qiskit.transpiler.InvalidLayoutError(*message)

GitHub

ベース: TranspilerError

ユーザーが提供したレイアウトが無効な場合に発生するエラー。

エラーメッセージを設定する。

最適化指標

OptimizationMetric(*値)移調の際に考慮される最適化指標。
このページは役に立ちましたか?
GitHub に関するバグ、誤字の報告、またはコンテンツのリクエスト。