QkDag
typedef struct QkDag QkDagこの QkDag 構造体は、量子回路のQiskitトランスパイラによる有向非循環グラフ(DAG)表現への低レベルインターフェースを公開し、トランスパイラ処理で使用される。 Qiskitの内部データモデルで定義されているもののみを公開します。 したがって、上位クラスの DAGCircuitPython が提供する一部の機能が欠けている。
現在のC APIは、Qiskitの内部Rustデータモデルで定義された操作を含むDAGの構築のみをサポートしています。 一般的に、これには標準ゲートライブラリのゲートのみ、標準の非ユニタリ演算(現在 Barrier、 Measure、 Reset、、および Delay)、ならびに が UnitaryGate含まれます。 この機能は、Rustのデータモデルがネイティブでより多くの機能をサポートするよう拡張されるにつれて、時間をかけて拡張されていきます。
データ型
QkDagNodeType
enum QkDagNodeType
. QkDag内のノードの種類
操作ノードは適用された命令を表す。 残りのノードは「ワイヤ」ノードと見なされ、DAGのデータ依存関係チェーンの終端点を表す。
値:
列挙子 QkDagNodeType_Operation
操作ノード。
列挙子 QkDagNodeType_QubitIn
量子ビット配線開始ノード。
列挙子 QkDagNodeType_QubitOut
量子ビットワイヤ終端ノード。
列挙子 QkDagNodeType_ClbitIn
Clbitワイヤ開始ノード。
列挙子 QkDagNodeType_ClbitOut
Clbit ワイヤエンドノード。
列挙子 QkDagNodeType_VarIn
古典的な可変ワイヤスタートノード。
列挙子 QkDagNodeType_VarOut
古典的な可変ワイヤ端点ノード。
QkOperationKind
enum QkOperationKind
その操作の種類。
これは、グラフ内の特定のノードをクエリした際に返され、呼び出し元が包含された操作の種類に応じた qk_dag_op_node_kind呼び出しを(例えば「switch」を介して)分岐処理できるようにすることを目的としています。
値:
列挙子 QkOperationKind_Gate
列挙子 QkOperationKind_Barrier
列挙子 QkOperationKind_Delay
列挙子 QkOperationKind_Measure
列挙子 QkOperationKind_Reset
列挙子 QkOperationKind_Unitary
列挙子 QkOperationKind_PauliProductMeasurement
列挙子 QkOperationKind_ControlFlow
列挙子 QkOperationKind_Unknown
このバリアントは、ネイティブデータモデルでまだ実装されていない操作のための不透明型として使用されます。
調査員 QkOperationKind_PauliProductRotation
QkDagNeighbors
struct QkDagNeighbors
後継者と先祖の情報を格納するための構造体。それぞれ qk_dag_successors から取得した情報 qk_dag_predecessorsである。
このオブジェクトはCから読み取り専用です。 の安全保証を満たすためには、または qk_dag_successors によって初期化されたデータ( qk_dag_neighbors_clearポインタで参照される qk_dag_predecessorsデータを含む)を上書きしてはならない。
const uint32_t *neighbors
ノード num_neighbors インデックスの配列。
size_t 隣接数
配列 neighbors の長さ。
関数
qk_dag_new
QkDag *qk_dag_new(void)
新しい空のDAGを構築する。
使用が終了したら qk_dag_free 、返されたDAGを解放する必要があります。
例
QkDag *empty = qk_dag_new();戻り値
作成されたDAGへのポインタ。
qk_dag_add_quantum_register
void qk_dag_add_quantum_register(QkDag *dag, const QkQuantumRegister *reg)
DAGに量子レジスタを追加する。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1024, "my_register");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
が有効な非ヌルポインタ QkDag でなく、かつ dag が有効な非ヌルポインタ QkQuantumRegisterでない reg 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- reg – 量子レジスタへのポインタ。
qk_dag_add_classical_register
void qk_dag_add_classical_register(QkDag *dag, const QkClassicalRegister *reg)
DAGに古典的なレジスタを追加する。
例
QkDag *dag = qk_dag_new();
QkClassicalRegister *cr = qk_classical_register_new(24, "my_register");
qk_dag_add_classical_register(dag, cr);
qk_classical_register_free(cr);
qk_dag_free(dag);安全
が有効な非ヌルポインタ QkDag でなく、かつ dag が有効な非ヌルポインタ QkClassicalRegisterでない reg 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- reg – 古典的なレジスタへのポインタ。
qk_dag_num_qubits
uint32_t qk_dag_num_qubits(const QkDag *dag)
DAGが含む量子ビットの数を取得する。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(24, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t num_qubits = qk_dag_num_qubits(dag); // num_qubits==24
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
戻り値
DAGが定義される量子ビットの数。
qk_dag_num_clbits
uint32_t qk_dag_num_clbits(const QkDag *dag)
DAGが含むclbitsの数を取得する。
例
QkDag *dag = qk_dag_new();
QkClassicalRegister *cr = qk_classical_register_new(24, "my_register");
qk_dag_add_classical_register(dag, cr);
uint32_t num_clbits = qk_dag_num_clbits(dag); // num_clbits==24
qk_classical_register_free(cr);
qk_dag_free(dag);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
戻り値
DAGが定義されるclbitsの数。
qk_dag_num_op_nodes
size_t qk_dag_num_op_nodes(const QkDag *dag)
DAG内の操作ノードの総数を返す。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
size_t num = qk_dag_num_op_nodes(dag); // 1
qk_dag_free(dag);
qk_quantum_register_free(qr);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
戻り値
DAG内の命令の総数。
qk_dag_node_type
QkDagNodeType qk_dag_node_type(const QkDag *dag, uint32_t node)
指定されたノードの型を取得します。
この結果は、未知の型のノードを反復処理する際に適切な処理を分岐させるスイッチ文で使用できます。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – タイプを取得する対象のノード。
戻り値
ノードのタイプ。
qk_dag_qubit_in_node
uint32_t qk_dag_qubit_in_node(const QkDag *dag, uint32_t qubit)
指定された量子ビットに対応する配線の入力ノードのインデックスを取得する。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- qubit – 入力ノードのインデックスを取得する量子ビット。
戻り値
量子ビット配線の入力ノード。
qk_dag_qubit_out_node
uint32_t qk_dag_qubit_out_node(const QkDag *dag, uint32_t qubit)
指定された量子ビットに対応する配線の出力ノードのインデックスを取得する。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- 量子ビット – 出力ノードのインデックスを取得する量子ビット
戻り値
量子ビット配線の出力ノード。
qk_dag_clbit_in_node
uint32_t qk_dag_clbit_in_node(const QkDag *dag, uint32_t clbit)
指定されたclbitに対応するワイヤの入力ノードのインデックスを取得する。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- clbit – 入力ノードのインデックスを取得するclbit
戻り値
clbitワイヤの入力ノード。
qk_dag_clbit_out_node
uint32_t qk_dag_clbit_out_node(const QkDag *dag, uint32_t clbit)
指定されたclbitに対応するワイヤの出力ノードのインデックスを取得する。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- clbit – 出力ノードのインデックスを取得するclbit
戻り値
clbit配線の出力ノード。
qk_dag_wire_node_value
uint32_t qk_dag_wire_node_value(const QkDag *dag, uint32_t node)
ワイヤエンドポイントノードの値を取得する。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – ワイヤ値を取得するエンドポイントノード。
戻り値
エンドポイントノード内の値(例:量子ビット、クラビット、または変数)。
qk_dag_op_node_num_qubits
uint32_t qk_dag_op_node_num_qubits(const QkDag *dag, uint32_t node)
指定された操作ノードの量子ビット数を取得します。
ノードが操作でない場合、パニック状態になる。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – クビット数を取得する操作ノード
戻り値
操作の量子ビット数。
qk_dag_op_node_num_clbits
uint32_t qk_dag_op_node_num_clbits(const QkDag *dag, uint32_t node)
指定された操作ノードのclbits数を取得します。
ノードが操作でない場合、パニック状態になる。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – 取得するclbitsの数を指定する操作ノード。
戻り値
操作のclbit数。
qk_dag_op_node_num_params
uint32_t qk_dag_op_node_num_params(const QkDag *dag, uint32_t node)
指定された操作ノードのパラメータ数を取得します。
ノードが操作でない場合、パニック状態になる。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – パラメータ数を取得する操作ノード
戻り値
操作のパラメータの数。
qk_dag_op_node_qubits
const uint32_t *qk_dag_op_node_qubits(const QkDag *dag, uint32_t node)
指定された操作ノードの量子ビットを取得する。
ノードが操作でない場合、パニック状態になる。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – クビットを取得する操作ノード。
戻り値
量子ビットへのポインタ。 要素の数を決定するために qk_dag_op_node_num_qubits 使用します。
qk_dag_op_node_clbits
const uint32_t *qk_dag_op_node_clbits(const QkDag *dag, uint32_t node)
指定された操作ノードのclbitsを取得する。
ノードが操作でない場合、パニック状態になる。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – clbitsを取得する操作ノード。
戻り値
clbitsへのポインタ 要素の数を決定するために qk_dag_op_node_num_clbits 使用します。
qk_dag_apply_gate
uint32_t qk_dag_apply_gate(QkDag *dag, QkGate gate, const uint32_t *qubits, const double *params, bool front)
DAGに適用 QkGate する。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
qk_dag_free(dag);
qk_quantum_register_free(qr);安全
型 qubits params および は、それぞれ double および uint32_t の配列へのポインタであることが期待され、その長さは標準ゲートに対する期待値と一致している必要があります。 配列の長さが不十分な場合、この関数の動作は未定義となります。これは配列の境界外を読み取ることになるためです。 特定のゲートに対して量子ビットやパラメータが存在しない場合、ヌルポインタとなる可能性があります。 特定のゲートに必要な量子ビット数とパラメータ数を調べるには qk_gate_num_params 、 qk_gate_num_qubits とを確認できます。
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – ゲートを適用するDAGへのポインタ。
- ゲート – 適用する StandardGate
- qubits – ゲートを適用
uint32_tする量子ビットインデックスの配列へのポインタ。 (例:QkGate_GlobalPhase``gate) に対して量子ビットが存在しない場合、これはヌルポインタとなる可能性があります。 - params – ゲートパラメータに使用する値
doubleの配列へのポインタ。 パラメータが存在しない場合(例:gate)QkGate_H、これはヌルポインタとなる可能性があります。 - front – 指定された量子ビットに対してゲートが最後の操作ではなく最初の操作として適用される場合
true。
戻り値
新規追加された操作ノードのインデックス。
qk_dag_apply_measure
uint32_t qk_dag_apply_measure(QkDag *dag, uint32_t qubit, uint32_t clbit, bool front)
DAGに操作を適用する。
例
回路の終了時に、すべての量子ビットを対応する量子ビットインデックスに測定する。
uint32_t num_qubits = qk_dag_num_qubits(dag);
for (uint32_t i = 0; i < num_qubits; i++) {
qk_dag_apply_measure(dag, i, i, false);
}安全
が有効なへのアラインメントされた非ヌルポインタでない dag 場合、 QkDagまたは qubit または clbit の範囲外である場合、動作は未定義となる。
パラメーター
- dag – 適用する回路。
- 量子ビット – 測定対象の量子ビットインデックス。
- clbit – 結果を格納するclbitインデックス。
- フロント – 回路の開始時にこの措置を適用するかどうか。 通常
false。
戻り値
作成された命令のノードインデックス。
qk_dag_apply_reset
uint32_t qk_dag_apply_reset(QkDag *dag, uint32_t qubit, bool front)
DAGにリセットを適用する。
例
すべての量子ビットに初期リセットを適用する。
uint32_t num_qubits = qk_dag_num_qubits(dag);
for (uint32_t qubit = 0; qubit < num_qubits; qubit++) {
qk_dag_apply_reset(dag, qubit, true);
}安全
が有効なへのアラインメントされた非ヌルポインタ QkDagでない dag 場合、または範囲外の場合 qubit 、動作は未定義です。
パラメーター
- dag – 適用する回路。
- qubit – リセットする量子ビットのインデックス。
- front – 回路の開始時にリセットを適用するかどうか。 通常
false。
戻り値
作成された命令のノードインデックス。
qk_dag_apply_barrier
uint32_t qk_dag_apply_barrier(QkDag *dag, const uint32_t *qubits, uint32_t num_qubits, bool front)
DAGにバリアを適用する。
例
すべての量子ビットに最終的なバリアを適用する:
qk_dag_apply_barrier(dag, NULL, qk_dag_num_qubits(dag), false);回路の開始時に、指定された量子ビットインデックスにバリアを適用する:
uint32_t qubits[] = {0, 2, 4, 5};
uint32_t num_qubits = sizeof(qubits) / sizeof(qubits[0]);
qk_dag_apply_barrier(dag, qubits, num_qubits, true);安全
以下の場合、動作は未定義である:
dag有効なへのQkDagアラインメントされた、NULLでないポインタではないqubits初期化済み、範囲内、かつ重複していないインデックスの読み取りnum_qubitsに対して、がqubitsNULLでない限り、アラインメントがずれているか、または無効である。
パラメーター
- dag – 適用する回路。
- 量子ビット – バリアを適用する量子ビットのインデックス。 これはnullの場合があり、その場合は
num_qubits読み取られず、バリアはDAG内の全ての量子ビットに適用される。 - num_qubits – バリアが適用される量子ビットの数。
- フロント – 回路の開始時にバリアを適用するか。 通常
false。
戻り値
作成された命令のノードインデックス。
qk_dag_apply_unitary
uint32_t qk_dag_apply_unitary(QkDag *dag, const QkComplex64 *matrix, const uint32_t *qubits, uint32_t num_qubits, bool front)
DAGにユニタリーゲートを適用する。
の値は、量子ビット数に対応する正しいサイズの matrix 行主成分ユニタリ行列を形成すべきである。 データはポインタからコピーされ、この関数が戻るまで読み取りに対して有効である必要がある。
Qiskitのビット表記法と行列表記法の詳細については、 回路表記法を参照してください。
安全
以下のいずれかに該当する場合、動作は未定義となる:
dag有効なへのQkDagアラインメントされた、NULLでないポインタではないmatrix初期化された4**num_qubits値へのアラインメントされたポインタではないqubits初期化されたnum_qubits値へのアラインされたポインタではありません。
パラメーター
- dag – 適用する回路。
- matrix – 初期化された行主体のユニタリ行列で、全体のサイズは
4**num_qubits。 - 量子ビット – 量子ビットの異なる
uint32_tインデックスの配列。 - num_qubits – ゲートが作用する量子ビットの数。
- front – 回路の開始時にゲートを適用するかどうか。 通常
false。
戻り値
作成された命令のノードインデックス。
qk_dag_op_node_gate_op
QkGate qk_dag_op_node_gate_op(const QkDag *dag, uint32_t node, double *out_params)
指定されたノードの標準ゲートを取得します。
ノードが標準的なゲート操作でない場合、パニック状態になる。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
uint32_t h_gate_idx = qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
QkGate gate = qk_dag_op_node_gate_op(dag, h_gate_idx, NULL);
qk_dag_free(dag);
qk_quantum_register_free(qr);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。 が out_params NULLでない場合、その関数はゲートパラメータ全体を格納できる十分な大きさのバッファを指していなければならない。さもなければ、この関数は境界を超えて書き込むため、動作は未定義となる。 任意の操作ノードに必要なパラメータの数を確認するには、を qk_dag_op_node_num_params 参照してください。
パラメーター
- dag – DAGへのポインタ。
- node – 標準ゲートを取得する操作ノード
- out_params – ゲートのパラメータで埋められるバッファ。パラメータが不要な場合はNULL。
戻り値
ゲート値。
qk_dag_op_node_unitary
void qk_dag_op_node_unitary(const QkDag *dag, uint32_t node, QkComplex64 *out)
対応するノードインデックスのユニタリ行列をコピーする。
ノードがユニタリーゲートでない場合、パニック状態になる。
安全
は有効なへの非ヌルポインタでない dag 場合、が out アラインメントされていない QkDag場合、またはが 4**num_qubits の書き込み QkComplex64に対して有効でない out 場合、動作は未定義である。
パラメーター
- dag – 読み取る回路。
- node – ユニタリ行列命令のノードインデックス。
- out – 行優先順序で複雑な
4**num_qubits値用に割り当てられ整列されたメモリ。ここでnum_qubitsはゲートが作用する量子ビットの数である。
qk_dag_op_node_kind
QkOperationKind qk_dag_op_node_kind(const QkDag *dag, uint32_t node)
操作ノードの「種類」を取得する。
この結果は、操作ノードを反復処理する際に適切な処理を分岐させるスイッチ文で使用できます。
操作ノードでない node 場合にパニックを起こす。
安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- ノード – 「種類」を取得する操作ノード。
戻り値
ノードの「種類」。
qk_dag_successors
QkDagNeighbors qk_dag_successors(const QkDag *dag, uint32_t node)
指定されたノードの後継ノードを取得する。
後継者配列とその長さは構造 QkDagNeighbors 体として返され、配列の各要素はDAGノードインデックスに対応する。 構造体に割り当てられたメモリを解放するには、処理 qk_dag_neighbors_clear 終了時に関数を呼び出す必要があります。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);
uint32_t node_cx = qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){0, 1}, NULL, false);
QkDagNeighbors successors = qk_dag_successors(dag, node_cx);
qk_dag_neighbors_clear(&successors);
qk_dag_free(dag);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- ノード – 後継ノードを取得する対象のノード。
戻り値
後継情報を保持 QkDagNeighbors する構造体のインスタンス。
qk_dag_predecessors
QkDagNeighbors qk_dag_predecessors(const QkDag *dag, uint32_t node)
指定されたノードの前駆ノードを取得する。
先行配列とその長さは構造 QkDagNeighbors 体として返され、配列の各要素はDAGノードのインデックスに対応する。 構造体に割り当てられたメモリを解放するには、処理 qk_dag_neighbors_clear 終了時に関数を呼び出す必要があります。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);
uint32_t node_cx = qk_dag_apply_gate(dag, QkGate_CX, (uint32_t[]){0, 1}, NULL, false);
QkDagNeighbors predecessors = qk_dag_predecessors(dag, node_cx);
qk_dag_neighbors_clear(&predecessors);
qk_dag_free(dag);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- ノード – 前駆ノードを取得する対象のノード。
戻り値
前駆体情報を持つ構造 QkDagNeighbors 体のインスタンス。
qk_dag_neighbors_clear
void qk_dag_neighbors_clear(QkDagNeighbors *neighbors)
入力 QkDagNeighbors 構造体のフィールドをクリアする。
この関数は、フィールド neighbors が指すメモリを解放し、NULLに設定します。 また、フィールド num_neighbors を0に設定します。
安全
が有効な、nullでない QkDagNeighbors オブジェクトへのポインタでない neighbors 場合、その動作は未定義である。このオブジェクト qk_dag_predecessorsは、 qk_dag_successors またはで初期化されている必要がある。
パラメーター
- neighbors – オブジェクト
QkDagNeighborsへのポインタ。
qk_dag_get_instruction
void qk_dag_get_instruction(const QkDag *dag, uint32_t index, QkCircuitInstruction *instruction)
回路内の命令の詳細を返す。
これはの qk_circuit_get_instructionミラーです。 個々のプロパティを取得するには、個別の qk_dag_op_node_gate_op メソッド(例:)を使用することもできます。
再利用または廃棄する前に、必ず電話 qk_circuit_instruction_clear でリセット QkCircuitInstruction する必要があります。
例
DAGを反復処理して、どの量子ビットに測定が適用されているかを特定する:
bool *measured = calloc(qk_dag_num_qubits(dag), sizeof(*measured));
uint32_t num_ops = qk_dag_num_op_nodes(dag);
uint32_t *ops = malloc(num_ops * sizeof(*ops));
qk_dag_topological_op_nodes(dag, ops);
// Storage space for the instruction.
QkCircuitInstruction inst;
for (uint32_t i = 0; i < num_ops; i++) {
qk_dag_get_instruction(dag, ops[i], &inst);
if (!strcmp(inst.name, "measure"))
measured[inst.qubits[0]] = true;
qk_circuit_instruction_clear(&inst);
}
free(ops);
free(measured);安全
または dag のいずれかが、関連するデータ型への有効で instruction アラインメントが正しく、NULLでないポインタでない場合、動作は未定義となる。 フィールドは初期化する必要はありません instruction 。
パラメーター
- dag – 命令を取得する回路。
- index – ノードのインデックス。 有効な操作ノードではないノードのインデックスを渡すのは誤りです。
- 指示 – 書き出す場所
QkCircuitInstructionを示すポイント
qk_dag_compose
QkExitCode qk_dag_compose(QkDag *dag, const QkDag *other, const uint32_t *qubits, const uint32_t *clbits)
入力ワイヤのサブセットを、出力 other ワイヤのサブセットにマッピングする dagオプションを用いて、DAG other をインスタンス dag 上に構成する。
other 各タイプごとに、より少ない数または同数のワイヤを含む場合がある。
例
// Build the following dag
// rqr_0: ──■───────
// │ ┌───┐
// rqr_1: ──┼──┤ Y ├
// ┌─┴─┐└───┘
// rqr_2: ┤ X ├─────
// └───┘
QkDag *dag_right = qk_dag_new();
QkQuantumRegister *rqr = qk_quantum_register_new(3, "rqr");
qk_dag_add_quantum_register(dag_right, rqr);
qk_dag_add_classical_register(dag_right, rcr);
qk_dag_apply_gate(dag_right, QkGate_CX, (uint32_t[]){0, 2}, NULL, false);
qk_dag_apply_gate(dag_right, QkGate_Y, (uint32_t[]){1}, NULL, false);
// Build the following dag
// ┌───┐
// lqr_0: ──┤ H ├───
// ┌─┴───┴──┐
// lqr_1: ┤ P(0.1) ├
// └────────┘
QkDag *dag_left = qk_dag_new();
QkQuantumRegister *lqr = qk_quantum_register_new(2, "lqr");
qk_dag_add_quantum_register(dag_left, lqr);
qk_dag_add_classical_register(dag_left, lcr);
qk_dag_apply_gate(dag_left, QkGate_H, (uint32_t[]){0}, NULL, false);
qk_dag_apply_gate(dag_left, QkGate_Phase, (uint32_t[]){1}, (double[]){0.1}, false);
// Compose left circuit onto right circuit
// Should result in circuit
// ┌───┐
// rqr_0: ──■──┤ H ├──────────
// │ ├───┤┌────────┐
// rqr_1: ──┼──┤ Y ├┤ P(0.1) ├
// ┌─┴─┐└───┘└────────┘
// rqr_2: ┤ X ├───────────────
// └───┘
qk_dag_compose(dag_right, dag_left, NULL, NULL);
// Clean up after you're done
qk_dag_free(dag_left);
qk_dag_free(dag_right);
qk_quantum_register_free(lqr);
qk_quantum_register_free(rqr);安全
または other が有効な、非ヌルなへの dag ポインタ QkDagでない場合、動作は未定義である。 もし qubit nor clbit が NULL である場合、回路が所有する量よりも少ないか等しい量を含まなければならない。
パラメーター
- dag – 構築対象の有向非巡回グラフ(DAG)へのポインタ。
- その他 – 組み合わせるためのDAGへの
dagポインタ。 - 量子ビット – 量子ビットを構成する量子ビット配線を表すインデックスのリスト。
- clbits – 組み立てる対象となるclbitワイヤを表すインデックスのリスト。
戻り値
QkExitCode_Success 分解が成功した場合、それ以外の場合は失敗の原因を示すDAG固有のエラーコード。
qk_dag_free
void qk_dag_free(QkDag *dag)
DAGを解放せよ。
例
QkDag *dag = qk_dag_new();
qk_dag_free(dag);安全
が null または有効な QkDag のポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – 解放するDAGへのポインタ。
qk_dag_to_circuit
QkCircuit *qk_dag_to_circuit(const QkDag *dag)
与えられたDAGを回路に変換する。
新しい回路はDAGからコピーされる。元の dag 参照は依然として呼び出し元が所有し、解放される必要がある。 qk_dag_free 使用 qk_circuit_free 後は必ず返却された回路を解放してください。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
qk_quantum_register_free(qr);
QkCircuit *qc = qk_dag_to_circuit(dag);
qk_circuit_free(qc);
qk_dag_free(dag);安全
が有効な、ヌルでないへの QkDagポインタでない dag 場合、動作は未定義である。
パラメーター
- dag – 回路を作成する元のDAGへのポインタ。
戻り値
新しい回路へのポインタ。
qk_dag_topological_op_nodes
void qk_dag_topological_op_nodes(const QkDag *dag, uint32_t *out_order)
DAG内の操作ノードをトポロジカル順にリストして返す。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);
// get the number of operation nodes
uint32_t num_ops = qk_dag_num_op_nodes(dag); // 2
uint32_t *out_order = malloc(sizeof(uint32_t) * num_ops);
// get operation nodes listed in topological order
qk_dag_topological_op_nodes(dag, out_order);
// do something with the ordered nodes
for (uint32_t i = 0; i < num_ops; i++) {
QkGate gate = qk_dag_op_node_gate_op(dag, out_order[i], NULL);
printf("The gate at location %u is %u.\n", i, gate);
}
// free the out_order array, register, and dag pointer when done
free(out_order);
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
が有効な、NULLでないポインタでない dag 場合 QkDag 、またはが有効な、NULLでないポインタでない out_order 場合、 qk_dag_num_op_nodes(dag) その動作は未定義である uint32_t。
パラメーター
- dag – DAGへのポインタ。
- out_order – 型 の
qk_dag_num_op_nodes(dag)要素からなるuint32_t配列へのポインタ。この関数は出力先としてこの配列に書き込みを行います。
qk_dag_substitute_node_with_dag
void qk_dag_substitute_node_with_dag(QkDag *dag, uint32_t node, const QkDag *replacement)
のノードを、別のノードで QkDag 指定された部分回路に置き換える QkDag
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
uint32_t node_to_replace = qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);
// Build replacement dag for H
QkDag *replacement = qk_dag_new();
QkQuantumRegister *replacement_qr = qk_quantum_register_new(1, "other");
qk_dag_add_quantum_register(replacement, replacement_qr);
double pi_param[1] = {3.14159};
qk_dag_apply_gate(replacement, QkGate_RZ, qubit, pi_param, false);
qk_dag_apply_gate(replacement, QkGate_SX, qubit, NULL, false);
qk_dag_apply_gate(replacement, QkGate_RZ, qubit, pi_param, false);
qk_dag_substitute_node_with_dag(dag, node_to_replace, replacement);
// Free the replacement dag, register, dag, and register
qk_quantum_register_free(replacement_qr);
qk_dag_free(replacement);
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
と replacement が有効な、ヌルでないへの dag ポインタでない QkDag場合、動作は未定義である。
パラメーター
- dag – DAGへのポインタ。
- node – 他のノードと置換する操作の
QkDagノードインデックス。 これは、dagの操作ノードのノードインデックスでなければならず、qargsとcargsの数は、の量子ビット数と量子ビット数replacementと一致しなければならない。 - 代替品 – 置き換える
nodeためのQkDagもう一方。 このダグは、操作に対して同じ数の量子nodeビットを持つ必要がある。 ノードビットの順序付けは順序通りに処理されるため、qargs[0]はにreplacement``qubits[0]、qubits[0]``qargs[1]はに、といったnodeように対応付けられる。 同じパターンは古典ビットにも当てはまる。
qk_dag_copy_empty_like
QkDag *qk_dag_copy_empty_like(const QkDag *dag, QkVarsMode vars_mode, QkBlocksMode blocks_mode)
自身と同じ構造を持つが空のコピーを返す。
その構造には以下が含まれます:
- 名前およびその他のメタデータ
- グローバルフェーズ
- 期間
- すべての量子ビットと量子ビット(clbits)、レジスタを含む。
例
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(1, "my_register");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {0};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
// As the DAG does not contain any control-flow instructions,
// vars_mode and blocks_mode do not have any effect.
QkDag *copied_dag = qk_dag_copy_empty_like(dag, QkVarsMode_Alike, QkBlocksMode_Drop);
uint32_t num_ops_in_copied_dag = qk_dag_num_op_nodes(copied_dag); // 0
// do something with copied_dag
qk_quantum_register_free(qr);
qk_dag_free(dag);
qk_dag_free(copied_dag);安全
が有効なへのポインタ QkDagでない dag 場合、動作は未定義である。
パラメーター
- dag – コピーするDAGへのポインタ。
- vars_mode – 古典変数の処理モード。
- blocks_mode – ブロック処理のモード。
戻り値
コピーされたDAG回路へのポインタ。
qk_dag_replace_block_with_unitary
uint32_t qk_dag_replace_block_with_unitary(QkDag *dag, uint32_t num_block_ids, const uint32_t *block_ids, const QkComplex64 *matrix, uint32_t num_qubits, const uint32_t *qubits, bool cycle_check)
内の空でない連続したノードのブロックを、指定 QkDag されたユニタリ行列に対応する単一のユニタリゲートに置き換える。
置換が行われると、ブロック内のノードは削除され、指定された量子ビットに対して作用する新しいノードに置き換えられる。
例
// Create a DAG with H, T, S, T, H gates on the second qubit
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
uint32_t qubit[1] = {1};
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
uint32_t idx1 = qk_dag_apply_gate(dag, QkGate_T, qubit, NULL, false);
uint32_t idx2 = qk_dag_apply_gate(dag, QkGate_S, qubit, NULL, false);
uint32_t idx3 = qk_dag_apply_gate(dag, QkGate_T, qubit, NULL, false);
qk_dag_apply_gate(dag, QkGate_H, qubit, NULL, false);
// Replace the inner T, S, T gates by a unitary gate (representing Z)
uint32_t replaced_ids[3] = {idx1, idx2, idx3};
static const QkComplex64 mat_z[4] = {{1, 0}, {0, 0}, {0, 0}, {-1, 0}};
uint32_t new_node_idx =
qk_dag_replace_block_with_unitary(dag, 3, replaced_ids, mat_z, 1, qubit, false);
// free the register and dag pointer when done
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
以下のいずれかに該当する場合、動作は未定義となる:
dag有効なへのQkDagアラインメントされた、NULLでないポインタではないqubits初期化されたnum_qubits値へのアラインされたポインタではありません。matrix初期化された4**num_qubits値へのアラインメントされたポインタではないblock_ids初期化num_block_ids値への整列されたポインタではありません。
パラメーター
- dag – DAGへのポインタ。
- num_block_ids –.
block_ids内のエントリ数 この数値は0以外でなければなりません。 - block_ids – 置換対象のノードからなる、空でない配列へのポインタ。
- matrix – サイズ の初期化済み行優先
4**num_qubitsユニタリ行列へのポインタ。 - num_qubits – 結果として得られるユニタリーゲートが作用する量子ビットの数。
- 量子ビット – 個別の
uint32_t量子ビットインデックスの配列へのポインタ。 各エントリは、ユニタリーゲート内のそれぞれの引数位置に対応するDAG量子ビットのインデックスを指定します。 - cycle_check – この関数は、指定されたノード
block_idsを単一のノードに置き換えた場合にtrue、DAGにサイクルが生じるかどうか(DAGが無効になるかどうか)を確認します。 サイクルが生成された場合、DAGは変更されず、UINT32_MAXそのまま返されます。 このチェックには実行時のパフォーマンスの低下が伴います。 提供された領域が連続block_idsしたブロックであり、単一のノードに縮小された際にサイクルが生じないことが保証できる場合、これを に設定できますfalse。
戻り値
新しく追加された操作ノードのインデックス、あるいは UINT32_MAX が cycle_check であり true 、置換によって循環が生じる場合。
qk_dag_substitute_node_with_unitary
void qk_dag_substitute_node_with_unitary(QkDag *dag, uint32_t node, const QkComplex64 *matrix, uint32_t num_qubits)
グラフ内のノードにおける演算を、指定された QkDag ユニタリ行列に対応するユニタリゲートに置き換える。
新しい操作は、置き換えられる操作の形状と一致している必要があります。 そのノードのqargsとcargsは変更されません。
例
// Create a DAG with a Z-gate
QkDag *dag = qk_dag_new();
QkQuantumRegister *qr = qk_quantum_register_new(2, "qr");
qk_dag_add_quantum_register(dag, qr);
uint32_t idx_z = qk_dag_apply_gate(dag, QkGate_Z, (uint32_t[]){1}, NULL, false);
static const QkComplex64 mat[4] = {{1, 0}, {0, 0}, {0, 0}, {-1, 0}};
// Replace the Z-gate by a unitary matrix
qk_dag_substitute_node_with_unitary(dag, idx_z, mat, 1);
// free the register and dag pointer when done
qk_quantum_register_free(qr);
qk_dag_free(dag);安全
以下のいずれかに該当する場合、動作は未定義となる:
dag有効なへのQkDagアラインメントされた、NULLでないポインタではないmatrix初期化された4**num_qubits値へのアラインメントされたポインタではない
パラメーター
- dag – DAGへのポインタ。
- node – 操作が置換されるノード。 置換操作における量子ビットの数は に等しく、クラビットの数は
num_qubitsであるべきである0。 - matrix – サイズ の初期化済み行優先
4**num_qubitsユニタリ行列へのポインタ。 - num_qubits – ユニタリー演算が作用する量子ビットの数。
qk_dag_to_python
PyObject *qk_dag_to_python(QkDag *dag)
オブジェクトの QkDag 所有権を Python に渡す。
この関数を呼び出した後、ポインタ QkDag を使用することは安全ではありません。 特に、これを消去したり解放したりしようとしないでください。 呼び出し元は、 QkDagそのオブジェクトを所有していなければならず、借用した参照を保持しているだけではいけません(たとえば、から取得 QkDag * した qk_dag_borrow_from_python は所有されていません)。
安全
呼び出し元は、 Python のインタプリタに接続されている必要があります。 が、初期化済みかつ所有権が保持されているへの有効な( QkDagNULLでない)ポインタでない dag 場合、動作は未定義となる。
パラメーター
- dag – 所有されているオブジェクト。
戻り値
そのオブジェクトへの Python 参照。
qk_dag_borrow_from_python
QkDag *qk_dag_borrow_from_python(PyObject *ob)
PythonQkDag オブジェクトからポインタを取得します。
これは Python への参照を取得し、その型が正しい場合、その QkDag ポインタを抽出します。 返されるポインタは、その ob ポインタから借用されたものです。 が PyObject 正しい型でない場合、戻り値は NULL となり、 Python インタプリタの例外状態が設定されます。
この関数を呼び出すには、 Python のインタプリタに接続されている必要があります。
また、 qk_dag_convert_from_pythonを使用することもできます。これは論理的にはこの関数と全く同じですが、 Python コンバータ PyArg_Parse* 関数のファミリー向けの「コンバータ」関数として直接使用することができます。
安全
呼び出し元は、 Python のインタプリタに接続されている必要があります。 が、 Python オブジェクトへの有効な(NULLではない)ポインタでない ob 場合、動作は未定義となります。
パラメーター
- ob – Python から借用したオブジェクト。
戻り値
ネイティブオブジェクトへのポインタ、あるいは NULLPython オブジェクトの型が正しくない場合。
qk_dag_convert_from_python
int qk_dag_convert_from_python(PyObject *object, void *address)
Python オブジェクトからDAGポインタを取得します。
これは Python への参照を受け取り、その QkDag ポインタが正しい型であれば、 addressそれをに抽出します。 返されるポインタは、その object ポインタから借用されたものです。 が正しい PyObject 型でない場合、戻り値は 1 となり、 Python インタプリタの例外状態が設定され、 address は変更されません。
この関数を呼び出すには、 Python のインタプリタに接続されている必要があります。
また、 qk_dag_borrow_from_pythonを使用することもできます。これは論理的にはこれと全く同じですが、直接使用する際のシグネチャがより自然になっています。
安全
呼び出し元は、 Python のインタプリタに接続されている必要があります。 が Python オブジェクトへの有効な(NULLではない)ポインタでない object 場合、またはが正しい型の書き込み可能なデータへのポインタでない address 場合、動作は未定義となります。
パラメーター
- object – 借用された Python オブジェクト。
- アドレス – 出力を書き込む場所。
戻り値
成功時は1、失敗時は0。