Skip to main content
IBM Quantum Platform

トランスパイラ・パス

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

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

Qiskitでは、トランスパイラが、量子回路を解析または変換する単一タスクを実行する一連のパスとして実行されることによって構築される。 Pythontranspiler ドキュメントには、トランスパイルプロセスに関するより詳細な説明が含まれています。

Qiskit C API では、トランスパイラ・パス関数が 2 つの形式で提供されています。1 つは に対して動作するものであり QkDag 、もう 1 つは に対して動作するものです QkCircuit。 命名規則に従うDAGベースの関数は、および QkTargetqk_transpiler_pass_*ならびにパス固有 QkDag の設定パラメータを受け取ります。 これらの関数は、複数のパスを連結する場合(たとえば、カスタムトランスパイルパイプラインを作成する場合など)に推奨される選択肢です。なぜなら、これらはDAGオブジェクトに対して直接操作を行うため、トランスパイルセッション内でDAGを効率的に次のパスへと渡すことができるからです。 対照的に、命名 qk_transpiler_pass_standalone_* 規則に従った回路ベースの関数は、[対象] に対して QkCircuit 動作し、個々の処理を独立して実行することを目的としています。 カスタムワークフローの構築にも利用できますが、入力回路を内部でDAGに変換する必要があるため、呼び出しごとに追加のオーバーヘッドが発生します。また、変換された回路が返される場合、その結果として得られるDAGを再び回路に変換する必要があります。


DAG ベースの関数

qk_transpiler_pass_elide_permutations

QkTranspileLayout *qk_transpiler_pass_elide_permutations(QkDag *dag)

DAGに対して ElidePermutations トランスパイラ・パスを実行する。

ElidePermutations トランスパイラ・パスは、レイアウト前のDAGからすべての順列操作を削除します。

このパスは、トランスパイラ・パイプラインにおいてレイアウト(仮想量子ビットを物理量子ビットにマッピングすること)が設定される前に実行されることを意図しています。 このパスはDAGを順に処理し、スワップゲートに遭遇すると、DAG内の仮想量子ビットの順序を入れ替え、そのスワップゲートを削除します。 これにより、レイアウトを実行する前に、DAG内のスワップゲートがすべて効果的に削除されます。 この最適化は、レイアウトが設定された後は有効ではなく、その場合は実行しないでください。

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(4, "qr");
qk_dag_add_quantum_register(dag, qr);
for (uint32_t i = 0; i < qk_dag_num_qubits(dag) - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    for (uint32_t j = 0; j < i + 1; j++) {
        qk_dag_apply_gate(dag, QkGate_CX, qargs, NULL, false);
    }
}
QkTranspileLayout *elide_result = qk_transpiler_pass_elide_permutations(dag);
if (elide_result != NULL) {
    qk_transpile_layout_free(elide_result);
}
qk_quantum_register_free(qr);
qk_dag_free(dag);

安全

が、への有効な(かつNULLではない QkDAG)ポインタでない dag 場合、動作は未定義となる。

パラメーター

  • dagElidePermutations を実行する DAG へのポインタ。 変更が行われた場合、そのオブジェクトはそのまま変更されます。 ゲートが省略された場合、この関数によって元のDAGの割り当てが解放されます。

戻り値

DAG内の省略されたゲートによって誘導される出力の順列を含むレイアウトオブジェクト。 省略が行われない場合、これはNULLポインタとなり、入力DAGは変更されません。 呼び出し元は、を呼び出すことで、返されたレイアウト qk_transpile_layout_freeを解放する責任があります。

qk_transpiler_pass_check_gate_direction

bool qk_transpiler_pass_check_gate_direction(const QkDag *dag, const QkTarget *target)

DAG回路上でパス CheckGateDirection を実行する。

パスは、2量子ビットのゲートの方向が、与えられたターゲットで指定されたゲートの方向に準拠しているかどうかをチェックする。

QkTarget *target = qk_target_new(2);
uint32_t qargs[3] = {0,1};

QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
qk_target_entry_add_property(cx_entry, qargs, 2, 0.0, 0.0);
qk_target_add_instruction(target, cx_entry);

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){1,0}, NULL, false);

bool direction_ok = qk_transpiler_pass_check_gate_direction(dag, target);
qk_quantum_register_free(qr);
qk_dag_free(dag);
qk_target_free(target);

安全

または target が、それぞれ および QkTarget のオブジェクト QkDag への有効 dag な(NULL ではない)ポインタでない場合、動作は未定義となります。

パラメーター

  • dag – 「 CheckGateDirection 」パスを実行するDAG回路へのポインタ。
  • target - ゲートの方向をチェックするためのターゲットへのポインタ。

戻り値

bool - 回路内のすべての2量子ビットゲートの方向が、指定されたターゲット制約に従う場合に真。

qk_transpiler_pass_gate_direction

void qk_transpiler_pass_gate_direction(QkDag *dag, const QkTarget *target)

DAG上でパス GateDirection を実行する。

GateDirection パスでは、ハードウェアのカップリング方向に合わせて非対称ゲートを修正する。 このパスは、 cxczecrswaprzxrxxryyrzz ゲートの置換をサポートし、事前に定義されたアイデンティティを使用する。

QkTarget *target = qk_target_new(3);

uint32_t qargs[2] = {0,1};

QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
qk_target_entry_add_property(cx_entry, qargs, 2, 0.0, 0.0);
qk_target_add_instruction(target, cx_entry);

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(3, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){1,0}, NULL, false);

qk_transpiler_pass_gate_direction(dag, target);
qk_quantum_register_free(qr);
qk_dag_free(dag);
qk_target_free(target);

安全

または target が、それぞれ および QkTarget のオブジェクト QkDag への有効 dag な(NULL ではない)ポインタでない場合、動作は未定義となります。

パラメーター

  • dag – 「 GateDirection 」パスを実行するDAG回路へのポインタ。 このパスによって、DAGはその場で変更されます。
  • target - ゲートの方向をチェックするためのターゲットへのポインタ。

qk_transpiler_pass_optimize_1q_sequences

void qk_transpiler_pass_optimize_1q_sequences(QkDag *dag, const QkTarget *target)

DAG Circuit上で、 Optimize1qGatesDecomposition パスをスタンドアロンモードで実行します。

Optimize1qGatesDecomposition は、ターゲットの基底ゲートとエラー率の制約下でユニタリーを再合成することにより、単一量子ビットゲートシーケンスを最適化する。

オリジナルのチェーンを交換するかどうかの判断は、以下の点による:

  • 元のチェーンが基準から外れていた場合。
  • 元のチェーンが基礎にあったとしても、交換したチェーンの方がエラー率が低い場合。
  • 元のチェーンがIDの場合(チェーンは削除される)。

この誤差は、動作する量子ビットの個々のゲートの誤差を掛け合わせたものである。

QkTarget *target = qk_target_new(1);
double u_errors[3] = {0., 1e-4, 1e-4};
for (int idx = 0; idx < 3; idx++) {
    QkTargetEntry *u_entry = qk_target_entry_new(QkGate_U);
    uint32_t qargs[1] = {0};
    qk_target_entry_add_property(u_entry, qargs, 1, NAN, u_errors[idx]);
    qk_target_add_instruction(target, u_entry);
}

// Build circuit
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "qr");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubits[1] = {0};
for (int iter = 0; iter < 3; iter++) {
    qk_dag_apply_gate(dag, QkGate_H, qubits, NULL, false);
}

// Run transpiler pass
qk_transpiler_pass_optimize_1q_sequences(dag, target);

// Clean up
qk_target_free(target);
qk_dag_free(dag);
qk_quantum_register_free(qr);

安全

が への有効な(NULL ではない QkDag )ポインタでない dag 場合、および が への有効なポインタ QkTargetでない target 場合、動作は未定義となる。

パラメーター

  • dag – 変換対象のオブジェクト QkDag へのポインタ。
  • target - QkTarget オブジェクトへのポインタ、または null ポインタ。 NULLポインタが提供され、ゲートエラーが不明な場合、パスはゲート数が最も少ないシーケンスを選択し、そのオイラー基底セット上のすべての基底ゲートをサポートする。

qk_transpiler_pass_remove_diagonal_gates_before_measure

void qk_transpiler_pass_remove_diagonal_gates_before_measure(QkDag *dag)

DAG回路上でパス RemoveDiagonalGatesBeforeMeasure を実行する。

測定前に斜めのゲート(RZ、T、Zなど)を除去するトランスパイラーパス。 斜めの 2Q ゲートを含む。

QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "qr");
QkClassicalRegister *cr = qk_classical_register_new(1, "cr");
qk_dag_add_quantum_register(dag, qr);
qk_dag_add_classical_register(dag, cr);
qk_dag_apply_gate(dag, QkGate_Z, (uint32_t[1]){0}, NULL, false);
qk_dag_apply_measure(dag, 0, 0, false);
qk_transpiler_pass_remove_diagonal_gates_before_measure(dag);
// ...
qk_dag_free(dag);
qk_quantum_register_free(qr);
qk_classical_register_free(cr);

安全

が、への有効な(かつNULLではない QkDag)ポインタでない dag 場合、動作は未定義となる。

パラメーター

  • dag – このパスを適用するDAGへのポインタ。 このパスによって、DAGはその場で変更されます。

qk_transpiler_pass_remove_identity_equivalent

void qk_transpiler_pass_remove_identity_equivalent(QkDag *dag, const QkTarget *target, double approximation_degree)

DAG回路に対して RemoveIdentityEquivalent トランスパイラパスを実行する。

大域的な位相と指定された許容範囲まで、同一性操作に近い効果を持つゲートを削除する。 パラメータ化されたゲートは、このパスでは考慮されない。

カットオフ・フィデリティ ff に対して、このパスは、アイデンティティに関する平均ゲート・フィデリティが ff 以下のゲートを削除する。具体的には、ゲート GG は、 Fˉ<f\bar F < f ここで

barF=1+dFprocess1+d, Fprocess=Tr(G)2d2bar{F} = \frac{1 + d F_{\text{process}}}{1 + d},\ F_{\text{process}} = \frac{|\mathrm{Tr}(G)|^2}{d^2}

ここで、 d=2nd = 2^nnn の量子ビットのゲートの次元である。

この関数はマルチスレッド対応であり、デフォルトではCPUコア数と同じ数のスレッドを持つスレッドプールを起動する可能性があります。 スレッド数は、RAYON_NUM_THREADS 環境変数で調整できます。 たとえば、 RAYON_NUM_THREADS=4 を設定すると、スレッドプールは 4 スレッドに制限されます。

QkTarget *target = qk_target_new(5);
uint32_t current_num_qubits = qk_target_num_qubits(target);
QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
for (uint32_t i = 0; i < current_num_qubits - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    double inst_error = 0.0090393 * (current_num_qubits - i);
    double inst_duration = 0.020039;
    qk_target_entry_add_property(cx_entry, qargs, 2, inst_duration, inst_error);
}
QkExitCode result_cx = qk_target_add_instruction(target, cx_entry);
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(4, "qr");
qk_dag_add_quantum_register(dag, qr);
for (uint32_t i = 0; i < qk_dag_num_qubits(dag) - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    for (uint32_t j = 0; j<i+1; j++) {
    qk_dag_apply_gate(dag, QkGate_CX, qargs, NULL, false);
    }
}
uint32_t rz_qargs[1] = {1,};
double rz_params[1] = {0.,};
qk_dag_apply_gate(dag, QkGate_RZ, rz_qargs, rz_params, false);
qk_transpiler_pass_remove_identity_equivalent(dag, target, 1.0);
qk_quantum_register_free(qr);
qk_dag_free(dag);
qk_target_free(target);

安全

または target が、および QkDag への有効な(NULL dag ではない QkTarget)ポインタでない場合、動作は未定義となります。

パラメーター

  • dagRemoveIdentityEquivalent を実行する DAG へのポインタ。 このパスによってゲートが削除できた場合、参照されているこのDAGは変更後のDAGに更新されます。
  • target - RemoveIdentityEquivalent パスのターゲット。 approximation_degreeNAN に設定されている場合、操作が ID と等価かどうかを判断するための許容誤差は、ターゲットで報告されたエラー率に設定される。 そうでない場合は、公差がターゲットに依存しないため、 target
  • approximation_degree - 同値チェックのために近似する次数。 これは0から1の間の浮動小数点値、または NAN。 値が1の場合、浮動小数点精度以上の近似値は得られない。 この値は、カットオフ・フィデリティのスケーリング・ファクターとして使用される。 値が NAN の場合、 target で指定されたゲートの忠実度まで近似する。

qk_transpiler_pass_split_2q_unitaries

QkTranspileLayout *qk_transpiler_pass_split_2q_unitaries(QkDag *dag, double requested_fidelity, bool split_swaps)

DAG Circuitに対して Split2QUnitaries トランスパイラ・パスを実行する

安全

が、への有効な(かつNULLではない QkDAG)ポインタでない dag 場合、動作は未定義となる。

パラメーター

  • dagSplit2QUnitaries を実行する DAG 回路への可変ポインタ。 ゲートが最適化された場合、これは新しいDAGに置き換えられます。
  • requested_fidelity - 2量子ビットのユニタリー分割とゲート分解の許容誤差。
  • split_swaps - スワップ・ゲートを分割し、量子ビットの並べ替えを行うかどうか。

戻り値

スワップ同値な単項関数が分割された場合、この関数は、このDAG最適化によって誘導される置換を含む TranspileLayout 構造体へのポインタを返す。 スワップに相当する単項関数が分割されていない場合、これはNULLポインタになります。


回路ベースの関数

qk_transpiler_pass_standalone_basis_translator

void qk_transpiler_pass_standalone_basis_translator(QkCircuit *circuit, const QkTarget *target, size_t min_qubits)

BasisTranslator トランスパイラーのパスを回路上で実行する。

BasisTranslator トランスパイラ・パスは、標準 EquivalenceLibrary から翻訳セットを検索することで、ゲートをターゲット・ベースに翻訳する。

#include <qiskit.h>

QkCircuit *circuit = qk_circuit_new(3, 0);
qk_circuit_gate(circuit, QkGate_CCX, (uint32_t[3]){0, 1, 2}, NULL);

// Create a Target with global properties.
QkTarget *target = qk_target_new(3);
qk_target_add_instruction(target, qk_target_entry_new(QkGate_H));
qk_target_add_instruction(target, qk_target_entry_new(QkGate_T));
qk_target_add_instruction(target, qk_target_entry_new(QkGate_Tdg));
qk_target_add_instruction(target, qk_target_entry_new(QkGate_CX));

// Run pass
qk_transpiler_pass_standalone_basis_translator(circuit, target, 0);

// Free the circuit and target pointers once you're done
qk_circuit_free(circuit);
qk_target_free(target);

安全

circuit および/または target が有効でなく、 QkCircuit または QkTarget への NULL ではないポインタである場合の動作は未定義である。

パラメーター

  • circuit - BasisTranslator を実行する回路へのポインタ。 回路はインプレースで変更されるが、その回路がすでにターゲット・ベースにある場合は、回路は変更されない。
  • target - ゲートを取得するターゲット。
  • min_qubits – 変換対象の入力回路における演算に必要なクビットの最小数。

qk_transpiler_pass_standalone_commutative_cancellation

QkExitCode qk_transpiler_pass_standalone_commutative_cancellation(QkCircuit *circuit, const QkTarget *target, double approximation_degree)

CommutativeCancellation トランスパイラーのパスを回路上で実行する。

このパスにより、整流関係を通じて冗長な(自己合同)ゲートがキャンセルされる。

QkCircuit *qc = qk_circuit_new(4, 0);
uint32_t cx_qargs[2] = {0, 1};
qk_circuit_gate(qc, QkGate_CX, cx_qargs, NULL);
qk_circuit_gate(qc, QkGate_Z, (uint32_t[]){0}, NULL);
qk_circuit_gate(qc, QkGate_CX, cx_qargs, NULL);
qk_transpiler_pass_standalone_commutative_cancellation(qc, NULL, 1.0);

安全

circuit または target が有効でない場合、 QkCircuit および QkTarget の動作は未定義である。 QkCircuit がNULLであることは期待されておらず、NULLであった場合の動作は未定義である。

パラメーター

  • circuit - CommutativeCancellation を実行する回路へのポインタ。 この回路ポインターは、パスがゲートを取り除くことができれば、修正された回路で更新される。
  • target - このパスは、すべてのZ回転をRZ、P、または U1 ゲートのいずれかにアキュムレートしようとします(回路内ですでに使用されているものによる)。 回路内に1つも存在しない場合、この(オプションの)ターゲット引数は、どのゲートを使用するかを決定するための予備として使用される。 RZ、P、 U1 のいずれかが回路やターゲットにない場合、単一量子ビットのZ回転は最適化されない。
  • approximation_degree - 通約を分析するときに使用される近似次数。 (0, 1] 以内であること。

戻り値

整数のリターンコード。0はエラーなしを表し、1はパスの実行中にエラーが発生したことを示す。

qk_transpiler_pass_standalone_consolidate_blocks

void qk_transpiler_pass_standalone_consolidate_blocks(QkCircuit *circuit, const QkTarget *target, double approximation_degree, bool force_consolidate)

ConsolidateBlocks、回路にパスを通す。

ConsolidateBlocks は、同じ量子ビット上で動作するゲートの連続するブロックを1つのユニタリ・ゲートに統合するトランスパイラ・パスのことで、後で再合成することで、より最適なサブサーキットを実現する。

安全

circuitQkCircuit への有効な非NULLポインタでない場合、および targetQkTarget への有効なポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - ConsolidateBlocks を実行する回路へのポインタ。
  • target - ConsolidateBlocks を実行するターゲットへのポインタ。
  • approximation_degree - [0.0, 1.0] または NaN (デフォルトは 1.0 )の間の float。 低い方がより近似している。
  • force_consolidate - ブロック連結を強制する。

qk_transpiler_pass_standalone_convert_to_pauli_rotations

void qk_transpiler_pass_standalone_convert_to_pauli_rotations(QkCircuit *circuit)

回路上でパ ConvertToPauliRotations スをインプレースで実行する。

このパスは、回路内のすべての標準ゲート(4キュービット未満のもの)を QkPauliProductRotation ゲートのシーケンスに変換し、測定を QkPauliProductMeasurement 命令に変換します。 回路に非標準のゲートが含まれている場合、このパスはパニック状態になることに注意してください。 推奨されるワークフローは、まず標準的な形式にトランスパイルし、可能な限り回転ゲート(や QkGate_RXX その他)をそのまま保持した上で、このパスを呼び出すというものです。

安全

が有効でない circuit 場合、またはへのポインタがNULL QkCircuitでない場合、動作は未定義となる。

パラメーター

  • circuit – パスを実行する回路へのポインタ。

qk_transpiler_pass_standalone_elide_permutations

QkTranspileLayout *qk_transpiler_pass_standalone_elide_permutations(QkCircuit *circuit)

ElidePermutations トランスパイラーのパスを回路上で実行する。

パスに関する詳細については、関 qk_transpiler_pass_elide_permutations 数を参照してください。

安全

circuitQkCircuit への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - ElidePermutations を実行する回路へのポインタ。 変更があった場合、指されたオブジェクトはその場で変更される。 ゲートがエライドされた場合、元の回路のアロケーションはこの関数によって解放される。

戻り値

回路内の省略されたゲートによって生じる出力の順列を含むレイアウトオブジェクト。 省略が行われない場合、これはNULLポインタとなり、入力回路は変更されません。 呼び出し元は、を呼び出すことで、返されたレイアウト qk_transpile_layout_freeを解放する責任があります。

qk_transpiler_pass_standalone_check_gate_direction

bool qk_transpiler_pass_standalone_check_gate_direction(const QkCircuit *circuit, const QkTarget *target)

CheckGateDirection 、回路にパスを通す。

パスに関する詳細については、関 qk_transpiler_pass_check_gate_direction 数を参照してください。

安全

circuittarget がそれぞれ、 QkCircuitQkTarget オブジェクトへの有効な非NULLポインタでない場合、動作は未定義となる。

パラメーター

  • circuit – パスを実行する回路へのポインタ。
  • target - ゲートの方向をチェックするためのターゲットへのポインタ。

戻り値

すべての2量子ビットゲートの方向が目標制約を満たす場合に真となる。

qk_transpiler_pass_standalone_gate_direction

void qk_transpiler_pass_standalone_gate_direction(QkCircuit *circuit, const QkTarget *target)

GateDirection 、回路にパスを通す。

パスに関する詳細については、関 qk_transpiler_pass_gate_direction 数を参照してください。

安全

circuittarget がそれぞれ、 QkCircuitQkTarget オブジェクトへの有効な非NULLポインタでない場合、動作は未定義となる。

パラメーター

  • circuit – その場で変更を加える対象となる回路へのポインタ。
  • target – ゲートの方向指定に使用されるターゲットへのポインタ。

qk_transpiler_pass_standalone_inverse_cancellation

void qk_transpiler_pass_standalone_inverse_cancellation(QkCircuit *circuit)

InverseCancellation トランスパイラーのパスを回路上で実行する。

互いに逆である連続するゲートのペアをキャンセルする。 キャンセルされたゲートは、セルフ・インバース・ゲートのペアで構成される:

  • QkGate_H
  • QkGate_X
  • QkGate_Y
  • QkGate_Z
  • QkGate_CH
  • QkGate_CX
  • QkGate_CY
  • QkGate_CZ
  • QkGate_ECR
  • QkGate_Swap
  • QkGate_CCX
  • QkGate_CCZ
  • QkGate_CSwap
  • QkGate_RCCX
  • QkGate_C3X

と逆ゲートのペア:

  • (QkGate_T, QkGate_Tdg)
  • (QkGate_S, QkGate_Sdg)
  • (QkGate_SX, QkGate_SXdg)
  • (QkGate_CS, QkGate_CSdg)

QkCircuit *qc = qk_circuit_new(2, 2);
uint32_t qargs[1] = {0};
qk_circuit_gate(qc, QkGate_X, qargs, NULL);
qk_circuit_gate(qc, QkGate_H, qargs, NULL);
qk_circuit_gate(qc, QkGate_H, qargs, NULL);
qk_circuit_gate(qc, QkGate_Y, qargs, NULL);
qk_transpiler_pass_standalone_inverse_cancellation(qc);

安全

circuitQkCircuit への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - InverseCancellation を実行する回路へのポインタ。 パスがゲートを取り除くことができれば、元の回路はこのパスによって生成された回路に置き換えられる。

qk_transpiler_pass_standalone_litinski_transformation

void qk_transpiler_pass_standalone_litinski_transformation(QkCircuit *circuit, bool fix_clifford)

回路上でパ LitinskiTransformation スをインプレースで実行する。

このパスは、すべてのクリフォードゲートを回路の末端へと変換し、パウリ回転ゲートを ゲート QkPauliProductRotation に変換し、測定を 命令 QkPauliProductMeasurement に変換します。 なお、このパスは現在、非クリフォードゲートとして QkGate_TQkGate_Tdg 、または QkGate_RZ ゲートを持つ回路のみをサポートしており、それ以外の場合はパニック状態になります。 推奨されるワークフローは、まずClifford+RZ基底に変換し、その後このパスを実行することです。

安全

が有効でない circuit 場合、またはへのポインタがNULL QkCircuitでない場合、動作は未定義となる。

パラメーター

  • circuit – パスを実行する回路へのポインタ。
  • fix_clifford – もし true、回路の最後にクリフォードゲートを残す場合は。 それらが省略されている false 場合。

qk_transpiler_standalone_optimize_1q_sequences

void qk_transpiler_standalone_optimize_1q_sequences(QkCircuit *circuit, const QkTarget *target)

Optimize1qGatesDecomposition パスを回路上でスタンドアロンモードで実行する。

バージョン 2.4.0 以降、非推奨となっています

代わりに qk_transpiler_pass_standalone_optimize_1q_sequences() を使用してください。

安全

circuitQkCircuit への有効な非NULLポインタでない場合、および targetQkTarget への有効なポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - 変換する QkCircuit オブジェクトへのポインタ.
  • target - QkTarget オブジェクトへのポインタ、または null ポインタ。 NULLポインタが提供され、ゲートエラーが不明な場合、パスはゲート数が最も少ないシーケンスを選択し、そのオイラー基底セット上のすべての基底ゲートをサポートする。

qk_transpiler_pass_standalone_optimize_1q_sequences

void qk_transpiler_pass_standalone_optimize_1q_sequences(QkCircuit *circuit, const QkTarget *target)

Optimize1qGatesDecomposition パスを回路上でスタンドアロンモードで実行する。

パスに関する詳細については、関 qk_transpiler_pass_optimize_1q_sequences 数を参照してください。

安全

circuitQkCircuit への有効な非NULLポインタでない場合、および targetQkTarget への有効なポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - 変換する QkCircuit オブジェクトへのポインタ.
  • target - QkTarget オブジェクトへのポインタ、または null ポインタ。 NULLポインタが提供され、ゲートエラーが不明な場合、パスはゲート数が最も少ないシーケンスを選択し、そのオイラー基底セット上のすべての基底ゲートをサポートする。

qk_transpiler_pass_standalone_remove_diagonal_gates_before_measure

void qk_transpiler_pass_standalone_remove_diagonal_gates_before_measure(QkCircuit *circuit)

RemoveDiagonalGatesBeforeMeasure 、回路にパスを通す。

パスに関する詳細については、関 qk_transpiler_pass_remove_diagonal_gates_before_measure 数を参照してください。

安全

circuitQkCircuit への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit – このパスを実行する回路へのポインタ。

qk_transpiler_pass_standalone_remove_identity_equivalent

void qk_transpiler_pass_standalone_remove_identity_equivalent(QkCircuit *circuit, const QkTarget *target, double approximation_degree)

RemoveIdentityEquivalent トランスパイラーのパスを回路上で実行する。

パスに関する詳細については、関 qk_transpiler_pass_remove_identity_equivalent 数を参照してください。

この関数はマルチスレッド対応であり、デフォルトではCPUコア数と同じ数のスレッドを持つスレッドプールを起動する可能性があります。 スレッド数は、RAYON_NUM_THREADS 環境変数で調整できます。 たとえば、 RAYON_NUM_THREADS=4 を設定すると、スレッドプールは 4 スレッドに制限されます。

安全

circuit または target が、 QkCircuit および QkTarget への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - RemoveIdentityEquivalent を実行する回路へのポインタ。 この回路は、パスがゲートを取り除くことができれば、修正された回路で更新される。
  • target - RemoveIdentityEquivalent パスのターゲット。 approximation_degreeNAN に設定されている場合、操作が ID と等価かどうかを判断するための許容誤差は、ターゲットで報告されたエラー率に設定される。 そうでない場合は、公差がターゲットに依存しないため、 target
  • approximation_degree - 同値チェックのために近似する次数。 これは0から1の間の浮動小数点値、または NAN。 値が1の場合、浮動小数点精度以上の近似値は得られない。 この値は、カットオフ・フィデリティのスケーリング・ファクターとして使用される。 値が NAN の場合、 target で指定されたゲートの忠実度まで近似する。

qk_transpiler_pass_standalone_sabre_layout

QkTranspileLayout *qk_transpiler_pass_standalone_sabre_layout(QkCircuit *circuit, const QkTarget *target, const QkSabreLayoutOptions *options)

SabreLayout トランスパイラーのパスを回路上で実行する。

SabreLayout パスは、入力回路の反復的な双方向配線によってレイアウトを選択する。

ランダムな初期Layoutから始めて、アルゴリズムは回路の完全なルーティングを行い、最終的なLayoutを得る。 このfinal_layoutは、逆回路を配線するためのinitial_layoutとして使用される。 アルゴリズムは、完全なルーティングコストを削減する初期レイ アウトを見つけるまで、何回も反復する。

この方法は、量子回路の可逆性を利用し、初期レイアウトの選択に大域的な回路情報を含めようとするものである。

このパスでは、レイアウトと配線の両方が実行され、レイアウトが入力に適用されるように回路が変換されます(つまり、出力回路は、カップリングマップ上の未使用量子ビットに割り当てられたアンシラ量子ビットを持ち、マッピングされた物理量子ビットに一致するように量子ビットが並び替えられます)。 これは、ランダムな初期レイアウトを選択するために、異なるランダムシードで並列シードトライアルを実行し、必要なスワップゲート数が最小となる配線出力を選択するためである。 この最終的なスワップ計算は、最終的なルーティングを行うのと同じなので、計算後に適用した方が効率的だ。

この関数はマルチスレッドであり、デフォルトではCPU数と同じスレッド数のスレッドプールを起動する。 スレッド数は RAYON_NUM_THREADS 環境変数で調整できる。 例えば、 RAYON_NUM_THREADS=4 を設定すると、スレッドプールは4スレッドに制限される。

参照

[1] ヘンリー・ゾウ、マシュー・トレイニッシュ、ケビン・ハートマン、アレクサンダー・イヴリイ、ジェイク・リッシュマン。 “LightSABRE: 軽量で強化されたSABREアルゴリズム" arXiv:2409.08368

[2] Li, Gushu, Yufei Ding, and Yuan Xie. 「量子ビットのマッピング問題に挑む

NISQ時代の量子デバイスのために" ASPLOS 2019.

arXiv:1809.02573

安全

circuit または target が、 QkCircuit および QkTarget への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - SabreLayout を実行する回路へのポインタ。 回路はその場で変更され、元の回路のアロケーションはこの関数によって解放される。
  • target - SabreLayout を実行するターゲットへのポインタ
  • options - オプションへのポインタ。 SabreLayout

戻り値

パスによって引き起こされるレイアウトと出力の並べ替えを記述するトランスパイルレイアウト

qk_transpiler_pass_standalone_split_2q_unitaries

QkTranspileLayout *qk_transpiler_pass_standalone_split_2q_unitaries(QkCircuit *circuit, double requested_fidelity, bool split_swaps)

回路に対して Split2QUnitaries トランスパイラ・パスを実行する。

パスに関する詳細については、関 qk_transpiler_pass_split_2q_unitaries 数を参照してください。

安全

circuitQkCircuit への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuitSplit2QUnitaries を実行する回路への可変ポインタ。
  • requested_fidelity - 2量子ビットのユニタリー分割とゲート分解の許容誤差。
  • split_swaps - スワップ・ゲートを分割し、量子ビットの並べ替えを行うかどうか。

戻り値

スワップと等価なユニタリーが分割された場合、この関数は、この回路の最適化によって誘導された順列を含む TranspileLayout へのポインタを返す。 スワップ同等のユニタリーが分割されていない場合、これはヌルポインターとなる。

qk_transpiler_pass_standalone_unitary_synthesis

void qk_transpiler_pass_standalone_unitary_synthesis(QkCircuit *circuit, const QkTarget *target, size_t min_qubits, double approximation_degree)

UnitarySynthesis トランスパイラー・パスを実行する。

UnitarySynthesis トランスパイラ・パスは、回路内のあらゆる UnitaryGates をターゲットで利用可能なゲートに合成する。

QkTarget *target = qk_target_new(2);
uint32_t current_num_qubits = qk_target_num_qubits(target);
QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
for (uint32_t i = 0; i < current_num_qubits - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    double inst_error = 0.0090393 * (current_num_qubits - i);
    double inst_duration = 0.020039;
    qk_target_entry_add_property(cx_entry, qargs, 2, inst_duration, inst_error);
}
QkExitCode result_cx = qk_target_add_instruction(target, cx_entry);
QkCircuit *qc = qk_circuit_new(2, 0);
QkComplex64 c0 = {0., 0.};
QkComplex64 c1 = {1., 0.};
QkComplex64 unitary[16] = {c1, c0, c0, c0,  // row 0
                           c0, c1, c0, c0,  // row 1
                           c0, c0, c1, c0,  // row 2
                           c0, c0, c0, c1}; // row 3
uint32_t qargs[2] = {0, 1};
qk_circuit_unitary(qc, unitary, qargs, 2, false);
qk_transpiler_pass_standalone_unitary_synthesis(qc, target, 0, 1.0);

安全

circuit または target が、 QkCircuit および QkTarget への有効な非 null ポインタでない場合、動作は未定義となる。

パラメーター

  • circuit - UnitarySynthesis を実行する回路へのポインタ.
  • target - UnitarySynthesis を実行するターゲットへのポインタ
  • min_qubits - 合成するユニタリの最小量子ビット数。 ユニタリーが指定された量子ビット数に満たない場合は合成されない。
  • approximation_degree - 回路近似に使用されるヒューリスティック・ダイヤル( 1.0=no approximation, 0.0=maximal approximation)。 近似は、元のユニタリーから逸脱する代償として、合成回路をより安価にすることができる。 NANの場合、ターゲット近似は target のゲートフィデリティに基づく。

qk_transpiler_pass_standalone_vf2_layout_average

QkVF2LayoutResult *qk_transpiler_pass_standalone_vf2_layout_average(const QkCircuit *circuit, const QkTarget *target, const QkVF2LayoutConfiguration *config, bool strict_direction)

入力回路のレイアウト選択には、可能な場合、 VF2 アルゴリズムを使用する。このアルゴリズムは、回路内の特定のゲートではなく、ハードウェアエラー率のみに基づくノイズを考慮したスコアリングヒューリスティックを用いる。

この関数は、 PythonVF2Layout 空間パスに対応します。

この機能は、ハードウェアに完全に落とし込まれていない回路での使用に適しています。 回路が既に完全にハードウェアに落とし込まれており、正確な相互作用グラフのためのレイアウト改善を検討している場合は、代わりに qk_transpile_pass_standalone_vf2_layout_exact を使用してください。

このパスで解決策が見つかれば、それは「完璧なレイアウト」であり、それ以上のスワップマッピングやルーティングは必要ないことを意味する。 しかし、常に可能な解決策があるとは限らないし、解決策は存在するかもしれないが、パスが呼ばれたときに指定された範囲内では見つからないこともある。

QkTarget *target = qk_target_new(5);
uint32_t current_num_qubits = qk_target_num_qubits(target);
QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
for (uint32_t i = 0; i < current_num_qubits - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    double inst_error = 0.0090393 * (current_num_qubits - i);
    double inst_duration = 0.020039;
    qk_target_entry_add_property(cx_entry, qargs, 2, inst_duration, inst_error);
}
QkExitCode result_cx = qk_target_add_instruction(target, cx_entry);
QkCircuit *qc = qk_circuit_new(4, 0);
for (uint32_t i = 0; i < qk_circuit_num_qubits(qc) - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    for (uint32_t j = 0; j<i+1; j++) {
        qk_circuit_gate(qc, QkGate_CX, qargs, NULL);
    }
}
QkVF2LayoutConfiguration *config = qk_vf2_layout_configuration_new();
qk_vf2_layout_configuration_set_call_limit(config, 10000, 10000);
QkVF2LayoutResult *layout_result = qk_transpiler_pass_standalone_vf2_layout_average(qc, target, config, false);
qk_vf2_layout_result_free(layout_result);
qk_vf2_layout_configuration_free(config);

安全

または target が および QkCircuit への有効な circuit``QkTarget 非ヌルポインタでない場合、動作は未定義である。 が有効な QkVF2LayoutConfiguration オブジェクトを指さない非ヌルポインタである config 場合(ただしヌルポインタは問題ない)、動作は未定義である。

パラメーター

  • circuit - VF2Layout を実行する回路へのポインタ.
  • target - VF2Layout パスを実行するターゲットへのポインタ
  • config – 設定 QkVF2LayoutConfiguration 構造体へのポインタ。 このポインタがNULLの場合、パスデフォルトが使用されます。
  • strict_direction – このオプションが設定されている場合 true、このパスは、で記述された連結性における targetエッジの方向を考慮します。 通常、エラーヒューリスティックはすでにかなり大まかなものであるため、これを に false 設定することが望ましい。また、2量子ビットゲートは、局所的な1量子ビットゲートとネイティブ方向の2量子ビットゲートのみを用いて、ほぼ例外なく方向を「反転」させるように合成することができる。

戻り値

パスの結果を含む結果オブジェクトへのポインタ。 このオブジェクトはヒープに割り当てられており、関数 qk_vf2_layout_result_free で解放する必要があります。

qk_transpiler_pass_standalone_vf2_layout_exact

QkVF2LayoutResult *qk_transpiler_pass_standalone_vf2_layout_exact(const QkCircuit *circuit, const QkTarget *target, const QkVF2LayoutConfiguration *config)

入力回路のレイアウト選択には、可能な場合、 VF2 アルゴリズムを使用する。この際、結果がハードウェアと完全に互換性を持つことを前提とした、ノイズを考慮したスコアリングヒューリスティックを適用する。

この関数は、 PythonVF2PostLayout 空間パスに対応します strict_direction=True

この関数は、回路が既に完全にハードウェアに落とし込まれており、量子ビットの順列変更によって推定誤り率が改善されるかどうかを検証したい場合に適しています。 回路がハードウェア非対応の演算で構成されている場合は、代わりに qk_transpile_pass_standalone_vf2_layout_average を使用してください。

通常、このパスはレイアウト、配線、ネイティブ基底セットへの変換、最適化の後で呼び出され、入力回路がハードウェア上で実行可能であり、量子ビットインデックスが物理量子ビットを参照している状態となる。 このパスは、以下のいずれかを示す結果を返します:

  • 現在の回路が使用しているものよりも優れた仮想量子ビットから物理量子ビットへの初期マッピングの選択肢が存在する。
  • 現在の物理量子ビットの選択は、その呼び出し制限内でパスが見つかった最良のものだ。
  • 実行可能な回路を生成する有効な仮想-物理マッピングの選択は存在しない(少なくとも、パスは指定された制限内でそれを見つけることに失敗した)。

最初の2つのケースのいずれにおいても、 qk_vf2_layout_has_match は を返します true。 最初のケースのみにおいて、 qk_vf2_layout_has_improvement は を返す true

QkTarget *target = qk_target_new(5)
QkTargetEntry *cx_entry = qk_target_entry_new(QkGate_CX);
for (uint32_t i = 0; i < current_num_qubits - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    double inst_error = 0.0090393 * (current_num_qubits - i);
    double inst_duration = 0.020039;
    qk_target_entry_add_property(cx_entry, qargs, 2, inst_duration, inst_error);
}
QkExitCode result_cx = qk_target_add_instruction(target, cx_entry);
QkCircuit *qc = qk_circuit_new(4, 0);
for (uint32_t i = 0; i < qk_circuit_num_qubits(qc) - 1; i++) {
    uint32_t qargs[2] = {i, i + 1};
    for (uint32_t j = 0; j<i+1; j++) {
        qk_circuit_gate(qc, QkGate_CX, qargs, NULL);
    }
}
QkVF2LayoutConfiguration *config = qk_vf2_layout_configuration_new();
qk_vf2_layout_configuration_call_limit(config, 10000, 10000);
QkVF2LayoutResult *layout_result = qk_transpiler_pass_standalone_vf2_layout_exact(qc, target, config);
qk_vf2_layout_result_free(layout_result);
qk_vf2_layout_configuration_free(config);

安全

または target が および QkCircuit への有効な circuit``QkTarget 非ヌルポインタでない場合、動作は未定義である。 が有効な QkVF2LayoutConfiguration オブジェクトを指さない非ヌルポインタである config 場合(ただしヌルポインタは問題ない)、動作は未定義である。

パラメーター

  • circuit – レイアウト探索を実行する回路へのポインタ。
  • target – QPUを表すターゲットへのポインタ。
  • config – 設定 QkVF2LayoutConfiguration 構造体へのポインタ。 このポインタがNULLの場合、パスデフォルトが使用されます。

戻り値

パスの結果を含む結果オブジェクトへのポインタ。 このオブジェクトはヒープに割り当てられており、関数 qk_vf2_layout_result_free で解放する必要があります。

qk_transpiler_pass_standalone_vf2_layout

QkVF2LayoutResult *qk_transpiler_pass_standalone_vf2_layout(const QkCircuit *circuit, const QkTarget *target, bool strict_direction, int64_t call_limit, double time_limit, int64_t max_trials)

廃止予定のバージョンの qk_transpiler_pass_standalone_vf2_layout_average

このレガシーインターフェースはを使用せず QkVf2LayoutConfiguration、エラーヒューリスティックの処理方法が明確でない名称を有している(特定の量子ビットまたはリンクに対して QkTarget 、内の全ゲートについて平均化する)。

2.3.0 以降非推奨

に置き換えられました qk_transpiler_pass_standalone_vf2_layout_average()

安全

の安全要件は、 qk_transpiler_pass_standalone_vf2_layout_average および circuit において遵守されなければならない target

パラメーター

  • 回路 – 例えば qk_transpiler_pass_standalone_vf2_layout_average
  • ターゲット – 例えば qk_transpiler_pass_standalone_vf2_layout_average.
  • strict_direction – 例えば qk_transpiler_pass_standalone_vf2_layout_average. のように
  • call_limitcall_limit qk_vf2_layout_configuration_set_call_limit``と同様だが、call_limitbefore call_limitafter両方に同じ値が使用される。
  • time_limit – 例 qk_vf2_layout_configuration_set_time_limit
  • max_trials – 同様に qk_vf2_layout_configuration_set_max_trials

戻り値

同様に qk_transpiler_pass_standalone_vf2_layout_average

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