트랜스파일러 패스
변환은 특정 양자 디바이스의 토폴로지와 일치하도록 주어진 입력 회로를 다시 작성하거나 양자 시스템에서 실행하기 위해 회로를 최적화하는 과정입니다.
대부분의 회로는 주어진 대상 장치와 호환되도록 일련의 변환을 거쳐야 하며, 결과물에 대한 노이즈의 영향을 줄이기 위해 회로를 최적화해야 합니다. 하드웨어 제약 조건에 맞게 양자 회로를 다시 작성하고 성능을 최적화하는 일은 결코 간단하지 않습니다. 재작성 도구 체인의 논리 흐름은 선형적일 필요는 없으며 반복적인 하위 루프, 조건부 분기 및 기타 복잡한 동작을 가질 수 있습니다.
키스킷에서 트랜스파일러는 양자 회로를 분석하거나 변환하는 단일 작업을 각각 수행하는 일련의 패스로 실행하여 구축됩니다. Pythontranspiler 문서에 번역 과정에 대한 자세한 설명이 나와 있습니다.
Qiskit C API는 트랜스파일러 패스 함수를 두 가지 형태로 제공합니다. 하나는 에 대해 작동하는 QkDag 함수이고, 다른 하나는 에 대해 작동하는 QkCircuit 함수입니다. 명명 규칙을 따르는 DAG 기반 qk_transpiler_pass_* 함수들은 와 QkTarget , 그리고 패스별 구성 매개변수를 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 경우 동작이 정의되지 않습니다.
매개변수
- dag –
ElidePermutations를 실행할 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 회로에 대한 포인터.
- 대상 - 게이트 방향을 확인하는 데 사용되는 대상에 대한 포인터입니다.
리턴
bool - 회로의 모든 2큐비트 게이트의 방향이 지정된 목표 제약 조건을 준수하면 참입니다.
qk_transpiler_pass_gate_direction
void qk_transpiler_pass_gate_direction(QkDag *dag, const QkTarget *target)
DAG에서 pass를 GateDirection 실행합니다.
GateDirection 패스는 비대칭 게이트를 하드웨어 커플링 방향에 맞게 수정합니다. 이 패스는 미리 정의된 ID를 사용하여 cx, cz, ecr, swap, rzx, rxx, ryy 및 rzz 게이트의 대체를 지원합니다.
예
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를 그 자리에서 수정합니다.
- 대상 - 게이트 방향을 확인하는 데 사용되는 대상에 대한 포인터입니다.
qk_transpiler_pass_optimize_1q_sequences
void qk_transpiler_pass_optimize_1q_sequences(QkDag *dag, const QkTarget *target)
DAG Circuit에서 Optimize1qGatesDecomposition 패스를 독립 실행 모드로 실행합니다.
Optimize1qGatesDecomposition 는 대상의 기저 게이트와 오류율의 제약 조건 하에서 유니티를 재합성하여 단일 큐비트 게이트 시퀀스를 최적화합니다.
원래 체인을 교체할지 여부는 다음 사항에 따라 결정됩니다:
- 원래 체인이 기준에서 벗어난 경우.
- 원래 체인이 기준이었지만 대체 체인의 오류율이 더 낮은 경우.
- 원래 체인이 아이덴티티인 경우(체인이 제거됨).
오류는 큐비트에서 작동하는 개별 게이트의 오류를 곱한 값입니다.
이 함수는 멀티스레드 방식으로 작동하며, 기본적으로 CPU 개수와 동일한 수의 스레드로 구성된 스레드 풀을 생성할 수 있습니다. 환경 변수를 RAYON_NUM_THREADS 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어, 를 설정하면 RAYON_NUM_THREADS=4 스레드 풀이 4개의 스레드로 제한됩니다.
예
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 포인터가 아니거나, QkTarget가 dag 유효한 포인터가 아닌 target 경우 동작은 정의되지 않습니다.
매개변수
- dag – 변환할 객체를
QkDag가리키는 포인터. - 대상 -
QkTarget객체에 대한 포인터 또는 널 포인터입니다. 널 포인터가 제공되고 게이트 오류를 알 수 없는 경우 패스는 게이트 수가 가장 적은 시퀀스를 선택하고 오일러 기저 집합의 모든 기저 게이트를 지원합니다.
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 트랜스파일러 단계를 실행합니다.
전역 단계와 지정된 허용 오차까지 아이덴티티 연산에 가까운 효과를 갖는 게이트를 제거합니다. 파라미터화된 게이트는 이 패스에서 고려되지 않습니다.
컷오프 충실도 의 경우 이 패스는 아이덴티티에 대한 평균 게이트 충실도가 미만인 게이트를 제거합니다. 구체적으로, 에서 다음과 같은 경우 게이트 가 제거됩니다
여기서 은 큐비트에 대한 게이트의 크기입니다.
이 함수는 멀티스레드 방식으로 동작하며, 기본적으로 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 동작은 정의되지 않습니다.
매개변수
- dag –
RemoveIdentityEquivalent를 실행할 DAG에 대한 포인터. 패스가 게이트를 제거할 수 있는 경우, 이 DAG는 수정된 DAG로 업데이트됩니다. - 대상 - RemoveIdentityEquivalent 패스의 대상입니다.
approximation_degree을NAN으로 설정하면 작업이 ID와 동일한지 여부를 판단하는 허용 오차가 대상에서 보고된 오류율로 설정됩니다. 그렇지 않으면 허용 오차가 대상과 독립적이므로target은 사용되지 않습니다. - 근사치_degree - 동등성 검사를 위해 근사할 정도입니다. 이 값은 0에서 1 사이의 부동 소수점 값 또는
NAN일 수 있습니다. 값이 1이면 부동 소수점 정밀도 이상으로 근사하지 않습니다. 값이 < 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 회로에 대해 ‘ Split2QUnitaries ’ 트랜스파일러 단계를 실행합니다
안전
가 유효하고 null이 아닌 포인터가 QkDAG아닐 dag 경우 동작이 정의되지 않습니다.
매개변수
- dag –
Split2QUnitaries를 실행할 DAG 회로에 대한 가변 포인터. 게이트가 최적화되면 이 부분은 새로운 DAG로 대체됩니다. - 요청된_ 충실도 - 2비트 유니타리 분할 및 게이트 분해에 대한 허용 오차를 허용합니다.
- split_swaps - 스왑 게이트 분할을 시도하여 큐비트의 순열을 생성할지 여부입니다.
리턴
스왑 등가 유니터리가 분할된 경우, 이 함수는 이 DAG 최적화에 의해 유도된 순열을 포함하는 객체에 TranspileLayout 대한 포인터를 반환합니다. 스왑에 해당하는 단항 연산자가 분할되지 않은 경우, 이 변수는 null 포인터가 됩니다.
qk_transpiler_pass_2q_peephole_optimization
void qk_transpiler_pass_2q_peephole_optimization(QkDag *dag, const QkTarget *target, double approximation_degree)
TwoQubitPeepholeOptimization 트랜스파일러 단계를 실행합니다.
이 트랜스파일러 패스는 2큐비트 유니터리 피프홀 최적화를 수행하도록 설계되었습니다. 이 단계에서는 회로 내의 모든 2 큐비트 블록을 찾아내고, 해당 블록의 유니터리를 계산한 다음, 그 유니터리를 합성합니다. 합성된 2큐비트 유니터리 연산이 원래의 하위 회로보다 “더 우수하다”면, 해당 하위 회로를 사용하여 원래의 회로를 대체한다. 어떤 것이 더 나은지 판단하는 데 사용되는 휴리스틱은 먼저 회로 내의 2-큐비트 게이트 수를 확인하고, 2-큐비트 게이트 수가 더 적은 합성 방식을 우선적으로 선택합니다. 만약 2-큐비트 게이트 수가 같다면, 회로의 예상 충실도를 확인하여 예상 충실도가 더 높은 하위 회로를 선택하며, 마지막으로 필요한 경우 총 게이트 수가 가장 적은 하위 회로를 선택합니다.
대상 연산이 과완전(overcomplete)인 경우, 이 패스는 주어진 큐비트에서 지원되는 모든 게이트에 대해 지원되는 모든 분해 연산자를 모두 시도합니다. 위의 휴리스틱을 적용했을 때 기대 성능이 가장 우수한 분해가 선택되어 해당 블록을 대체하는 데 사용됩니다.
이 패스는 물리적 회로에서 실행되도록 설계되었으며, 특정 큐비트에 대한 연산 세부 사항은 대상 하드웨어 큐비트를 기준으로 한다고 가정합니다. 그러나 이 패스의 출력에는 하드웨어 연산이 사용되지 않을 수 있으며, 특히 대상 회로가 지원하는 연산 범위를 벗어난 단일 큐비트 게이트가 생성될 수 있습니다. 이는 일반적으로 대상 TwoQubitControlledUDecomposer 회로가 지원하는 매개변수화 게이트가 합성에 사용될 때만 발생합니다. 따라서 물리적 최적화 단계(예: 최적화 단계 )에서 이 패스를 실행할 경우, 해당 단계를 종료하기 전에 이러한 잘못된 단일 큐비트 게이트가 하드웨어에서 지원하는 연산으로 대체되도록 하기 위해 및/또는 Optimize1qGatesDecomposition 와 BasisTranslator 같은 패스와 함께 사용해야 합니다.
이 패스는 멀티스레드 방식으로, 분석을 병렬로 수행하며 로컬 시스템에서 사용 가능한 모든 코어를 활용합니다. Qiskit의 스레딩 동작을 보다 광범위하게 제어하는 방법에 대한 자세한 내용은 구성 가이드를 참조하시기 바랍니다. 이 가이드는 해당 패스의 동작도 제어합니다
예
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);
uint32_t forward[2] = {0, 1};
uint32_t reverse[2] = {1, 0};
for (int i = 0; i < 10; i++) {
if (i % 2) {
qk_circuit_gate(qc, QkGate_CX, forward, NULL);
} else {
qk_circuit_gate(qc, QkGate_CX, reverse, NULL);
}
}
QkDag *dag = qk_circuit_to_dag(qc);
qk_circuit_free(qc);
qk_transpiler_pass_2q_peephole_optimization(dag, target, 1.0);
qk_dag_free(dag);
qk_target_free(target);안전
또는 가 유효한, target``QkDag null이 dag 아닌 포인터가 아닐 경우, QkTarget 동작은 정의되지 않습니다.
DAG 회로에 Python 가 소유한 객체가 포함된 환경에서는 이 함수를 호출하는 것이 안전하지 않습니다. 이 함수는 내부적으로 멀티스레드 방식으로 동작하므로, 회로에 Python 에서 관리하는 게이트가 포함되어 있는 경우, 작업 스레드가 해당 게이트의 속성에 접근하기 위해 GIL을 획득해야 할 수 있으며, 이로 인해 교착 상태가 발생할 수 있습니다. Python 가 소유한 회로 요소가 있는 경우, 이 패스를 실행할 때는 ‘ Python ’ 공간 TwoQubitPeepholeOptimization 클래스를 사용해야 합니다.
매개변수
- dag – ‘ TwoQubitPeepholeOptimization ’를 실행할 DAG 회로를 가리키는 포인터
- target –
TwoQubitPeepholeOptimization를 실행할 대상에 대한 포인터 - approximation_degree – 회로 근사화에 사용되는 휴리스틱 다이얼 ( 1.0=no 근사법, 0.0=maximal 근사법). 근사화를 통해 합성 회로의 크기를 줄일 수 있지만, 그 대가로 원래의 유니터리 회로에서 벗어나게 될 수 있다.
targetNAN인 경우, 목표 근사치는 의 게이트 충실도를 기반으로 합니다.
회로 기반 함수
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 에 대한 유효하지 않은 널 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - BasisTranslator 을 실행할 회로에 대한 포인터입니다. 회로가 이미 대상 기준에 있는 경우를 제외하고는 회로가 제자리에서 변경되며, 이 경우 회로는 변경되지 않은 상태로 유지됩니다.
- 대상 - 기준 게이트를 획득할 대상입니다.
- min_qubits – 변환할 입력 회로의 연산에 필요한 최소 큐비트 수.
qk_transpiler_pass_standalone_commutative_cancellation
QkExitCode qk_transpiler_pass_standalone_commutative_cancellation(QkCircuit *circuit, const QkTarget *target, double approximation_degree)
CommutativeCancellation 트랜스파일러 패스를 회로에서 실행합니다.
이 패스는 정류 관계를 통해 중복(자체 결합) 게이트를 취소합니다.
이 함수는 멀티스레드 방식으로 작동하며, 기본적으로 CPU 개수와 동일한 수의 스레드로 구성된 스레드 풀을 생성할 수 있습니다. 환경 변수를 RAYON_NUM_THREADS 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어, 를 설정하면 RAYON_NUM_THREADS=4 스레드 풀이 4개의 스레드로 제한됩니다.
예
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일 것으로 예상되지 않으며, 만약 그렇다면 동작이 정의되지 않습니다.
매개변수
- 회로 - CommutativeCancellation 을 실행할 회로에 대한 포인터입니다. 패스가 게이트를 제거할 수 있는 경우 이 회로 포인터는 수정된 회로로 업데이트됩니다.
- 대상 - 이 패스는 회로에서 이미 사용 중인 게이트에 따라 모든 Z 회전을 RZ, P 또는 U1 게이트에 누적하려고 시도합니다. 회로에 아무것도 없는 경우, 이 (선택적) 대상 인수가 폴백으로 사용되어 사용할 게이트를 결정합니다. 회로 또는 타겟에 RZ, P 또는 U1 중 하나라도 없으면 단일 큐비트 Z 회전이 최적화되지 않습니다.
- 근사치_도 - 정류 분석 시 사용되는 근사치입니다.
(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 는 동일한 큐비트에서 작동하는 연속된 게이트 블록을 단일 게이트로 통합하여 나중에 재합성하여 보다 최적의 서브 회로를 만드는 트랜스파일러 패스입니다.
안전
circuit 가 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우와 target 가 QkTarget 에 대한 유효한 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - ConsolidateBlocks 을 실행할 회로에 대한 포인터입니다.
- 대상 - ConsolidateBlocks 을 실행할 대상에 대한 포인터입니다.
- 근사치_도 -
[0.0, 1.0]또는NaN사이의 플로트(기본값은1.0). 낮을수록 근사치가 높아집니다. - 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 , 또는 가 가리키는 포인터가 QkCircuitnull이 아닌 경우 동작은 정의되지 않습니다.
매개변수
- 회로 – 패스를 실행할 회로를 가리키는 포인터.
qk_transpiler_pass_standalone_elide_permutations
QkTranspileLayout *qk_transpiler_pass_standalone_elide_permutations(QkCircuit *circuit)
ElidePermutations 트랜스파일러 패스를 회로에서 실행합니다.
패스에 대한 자세한 내용은 해당 qk_transpiler_pass_elide_permutations 함수를 참조하십시오.
안전
circuit 이 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - 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 함수를 참조하십시오.
안전
circuit 또는 target 이 각각 QkCircuit 및 QkTarget 객체에 대한 유효하지 않은 널이 아닌 포인터인 경우 동작이 정의되지 않습니다.
매개변수
- 회로 – 패스를 실행할 회로를 가리키는 포인터.
- 대상 - 게이트 방향을 확인하는 데 사용되는 대상에 대한 포인터입니다.
리턴
모든 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 함수를 참조하십시오.
안전
circuit 또는 target 이 각각 QkCircuit 및 QkTarget 객체에 대한 유효하지 않은 널이 아닌 포인터인 경우 동작이 정의되지 않습니다.
매개변수
- 회로 – 제자리에서 수정할 회로를 가리키는 포인터.
- 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);안전
circuit 이 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - InverseCancellation 을 실행할 회로에 대한 포인터입니다. 패스가 게이트를 제거할 수 있으면 원래 회로가 이 패스가 생성한 회로로 대체됩니다.
qk_transpiler_pass_standalone_litinski_transformation
void qk_transpiler_pass_standalone_litinski_transformation(QkCircuit *circuit, bool fix_clifford)
회로에서 패스를 LitinskiTransformation 제자리에서 실행합니다.
이 패스는 모든 클리포드 게이트를 회로 끝으로 전달하며, 파울리 회전 게이트를 QkPauliProductRotation 게이트로, 측정 연산을 QkPauliProductMeasurement 명령어로 변환합니다. 현재 이 패스는 비클리포드 게이트로, QkGate_Tdg 또는 QkGate_RZ QkGate_T게이트를 포함하는 회로만 지원하며, 그 외의 경우에는 오류가 발생합니다. 권장되는 작업 흐름은 먼저 Clifford+RZ 기저로 트랜스파일링한 다음, 이 패스를 호출하는 것입니다.
안전
가 유효하지 않은 경우 circuit , 또는 가 가리키는 포인터가 QkCircuitnull이 아닌 경우 동작은 정의되지 않습니다.
매개변수
- 회로 – 패스를 실행할 회로를 가리키는 포인터.
- fix_clifford – 만약
true그렇다면, 회로 끝부분에 클리포드 게이트를 남겨두십시오. 그것들이false생략된 경우.
qk_transpiler_standalone_optimize_1q_sequences
void qk_transpiler_standalone_optimize_1q_sequences(QkCircuit *circuit, const QkTarget *target)
회로에서 독립형 모드에서 Optimize1qGatesDecomposition 패스를 실행합니다.
이 함수는 멀티스레드 방식으로 작동하며, 기본적으로 CPU 개수와 동일한 수의 스레드로 구성된 스레드 풀을 생성할 수 있습니다. 환경 변수를 RAYON_NUM_THREADS 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어, 를 설정하면 RAYON_NUM_THREADS=4 스레드 풀이 4개의 스레드로 제한됩니다.
안전
circuit 가 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우와 target 가 QkTarget 에 대한 유효한 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - 변환할
QkCircuit객체에 대한 포인터입니다. - 대상 -
QkTarget객체에 대한 포인터 또는 널 포인터입니다. 널 포인터가 제공되고 게이트 오류를 알 수 없는 경우 패스는 게이트 수가 가장 적은 시퀀스를 선택하고 오일러 기저 집합의 모든 기저 게이트를 지원합니다.
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 함수를 참조하십시오.
이 함수는 멀티스레드 방식으로 작동하며, 기본적으로 CPU 개수와 동일한 수의 스레드로 구성된 스레드 풀을 생성할 수 있습니다. 환경 변수를 RAYON_NUM_THREADS 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어, 를 설정하면 RAYON_NUM_THREADS=4 스레드 풀이 4개의 스레드로 제한됩니다.
안전
circuit 가 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우와 target 가 QkTarget 에 대한 유효한 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - 변환할
QkCircuit객체에 대한 포인터입니다. - 대상 -
QkTarget객체에 대한 포인터 또는 널 포인터입니다. 널 포인터가 제공되고 게이트 오류를 알 수 없는 경우 패스는 게이트 수가 가장 적은 시퀀스를 선택하고 오일러 기저 집합의 모든 기저 게이트를 지원합니다.
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 함수를 참조하십시오.
안전
circuit 이 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 – 이 패스를 실행할 회로에 대한 포인터.
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 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - RemoveIdentityEquivalent 을 실행할 회로에 대한 포인터입니다. 패스가 게이트를 제거할 수 있는 경우 가리키는 이 회로가 수정된 회로로 업데이트됩니다.
- 대상 - RemoveIdentityEquivalent 패스의 대상입니다.
approximation_degree을NAN으로 설정하면 작업이 ID와 동일한지 여부를 판단하는 허용 오차가 대상에서 보고된 오류율로 설정됩니다. 그렇지 않으면 허용 오차가 대상과 독립적이므로target은 사용되지 않습니다. - 근사치_degree - 동등성 검사를 위해 근사할 정도입니다. 이 값은 0에서 1 사이의 부동 소수점 값 또는
NAN일 수 있습니다. 값이 1이면 부동 소수점 정밀도 이상으로 근사하지 않습니다. 값이 < 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 선택에 전역 회로 정보를 포함하려고 합니다.
이 패스는 레이아웃과 라우팅을 모두 실행하고 레이아웃이 입력에 적용되도록 회로를 변환한 다음(즉, 출력 회로에 커플링 맵에서 사용하지 않는 큐비트에 대한 앙실라 큐비트가 할당되고 매핑된 물리적 큐비트와 일치하도록 큐비트의 순서가 재조정됨) 라우팅이 적용되도록 합니다. 이는 패스가 무작위 초기 레이아웃을 선택하고 필요한 스왑 게이트 수가 가장 적은 라우팅된 출력을 선택하기 위해 서로 다른 무작위 시드를 사용하여 병렬 시드 트라이얼을 실행하기 때문에 수행됩니다. 이 최종 스왑 계산은 최종 라우팅을 수행하는 것과 동일하므로 계산 후 적용하는 것이 더 효율적입니다.
이 함수는 멀티스레드이며 기본적으로 CPU 수와 동일한 스레드로 스레드 풀을 시작합니다. RAYON_NUM_THREADS 환경 변수를 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어 RAYON_NUM_THREADS=4 을 설정하면 스레드 풀이 4개로 제한됩니다.
참조
[1] 헨리 조우, 매튜 트레이니쉬, 케빈 하트만, 알렉산더 이브리, 제이크 리쉬먼. “LightSABRE: 가볍고 향상된 SABRE 알고리즘" arXiv:2409.08368
[2] 리, 구슈, 유페이 딩, 위안 시에. "큐비트 매핑 문제 해결하기
nISQ 시대의 양자 디바이스를 위한 것입니다." ASPLOS 2019.
안전
circuit 또는 target 이 QkCircuit 및 QkTarget 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - SabreLayout 을 실행할 회로에 대한 포인터입니다. 회로는 제자리에서 수정되고 원래 회로의 할당은 이 함수에 의해 해제됩니다.
- 대상 - SabreLayout 을 실행할 대상에 대한 포인터입니다
- 옵션 - 다음 옵션에 대한 포인터입니다 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 함수를 참조하십시오.
안전
circuit 이 QkCircuit 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- circuit –
Split2QUnitaries를 실행할 회로에 대한 가변 포인터. - 요청된_ 충실도 - 2비트 유니타리 분할 및 게이트 분해에 대한 허용 오차를 허용합니다.
- split_swaps - 스왑 게이트 분할을 시도하여 큐비트의 순열을 생성할지 여부입니다.
리턴
스왑 등가 단위가 분할되면 이 함수는 이 회로 최적화에 의해 유도된 순열을 포함하는 TranspileLayout 에 대한 포인터를 반환합니다. 스왑 등가 단위가 분할되지 않으면 이것은 널 포인터가 됩니다.
qk_transpiler_pass_standalone_2q_peephole_optimization
void qk_transpiler_pass_standalone_2q_peephole_optimization(QkCircuit *circuit, const QkTarget *target, double approximation_degree)
TwoQubitPeepholeOptimization 트랜스파일러 단계를 실행합니다.
패스에 대한 자세한 내용은 해당 qk_transpiler_pass_2q_peephole_optimization() 함수 설명서를 참조하십시오.
이 함수는 멀티스레드 방식으로 작동하며, 분석을 병렬로 수행하고 로컬 시스템에서 사용 가능한 모든 코어를 활용합니다. Qiskit의 스레딩 동작을 보다 광범위하게 제어하는 방법에 대한 자세한 내용은 구성 가이드를 참조하시기 바랍니다. 이 가이드는 해당 패스의 동작도 제어합니다
예
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);
uint32_t forward[2] = {0, 1};
uint32_t reverse[2] = {1, 0};
for (int i = 0; i < 10; i++) {
if (i % 2) {
qk_circuit_gate(qc, QkGate_CX, forward, NULL);
} else {
qk_circuit_gate(qc, QkGate_CX, reverse, NULL);
}
}
qk_transpiler_pass_standalone_2q_peephole_optimization(qc, target, 1.0);
qk_circuit_free(qc);
qk_target_free(target);안전
circuit 또는 target 이 QkCircuit 및 QkTarget 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
이 함수는 회로에 Python 가 소유한 객체가 포함된 환경에서는 호출하기에 안전하지 않습니다. 이 함수는 내부적으로 멀티스레드 방식으로 동작하므로, 회로에 Python 에서 관리하는 게이트가 포함되어 있는 경우, 작업 스레드가 해당 게이트의 속성에 접근하기 위해 GIL을 획득해야 할 수 있으며, 이로 인해 교착 상태가 발생할 수 있습니다. Python 가 소유한 회로 요소가 있는 경우, 이 패스를 실행할 때는 ‘ Python ’ 공간 TwoQubitPeepholeOptimization 클래스를 사용해야 합니다.
매개변수
- circuit – ‘ TwoQubitPeepholeOptimization ’을 실행할 회로에 대한 포인터
- target –
TwoQubitPeepholeOptimization를 실행할 대상에 대한 포인터 - approximation_degree – 회로 근사화에 사용되는 휴리스틱 다이얼 ( 1.0=no 근사법, 0.0=maximal 근사법). 근사화를 통해 합성 회로의 크기를 줄일 수 있지만, 그 대가로 원래의 유니터리 회로에서 벗어나게 될 수 있다.
targetNAN인 경우, 목표 근사치는 의 게이트 충실도를 기반으로 합니다.
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 을 타겟에서 사용 가능한 게이트로 합성합니다.
이 패스는 멀티스레드 방식으로 작동하며, 기본적으로 CPU 개수와 동일한 수의 스레드로 구성된 스레드 풀을 생성할 수 있습니다. 환경 변수를 RAYON_NUM_THREADS 사용하여 스레드 수를 조정할 수 있습니다. 예를 들어, 를 설정하면 RAYON_NUM_THREADS=4 스레드 풀이 4개의 스레드로 제한됩니다.
예
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 에 대한 유효한 널이 아닌 포인터가 아닌 경우 동작이 정의되지 않습니다.
매개변수
- 회로 - UnitarySynthesis 을 실행할 회로에 대한 포인터입니다
- 대상 - UnitarySynthesis 을 실행할 대상에 대한 포인터입니다
- 최소_큐비트 - 합성할 유니티의 최소 큐비트 수입니다. 유니티가 지정된 큐비트 수보다 작으면 합성되지 않습니다.
- 근사치_도 - 회로 근사치에 사용되는 휴리스틱 다이얼( 1.0=no 근사치, 0.0=maximal 근사치)입니다. 근사치를 사용하면 원래의 유니타리에서 벗어나는 대가로 합성 회로를 더 저렴하게 만들 수 있습니다. 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 알고리즘을 사용하여 입력 회로에 대한 레이아웃을 선택합니다(가능한 경우). 이때 회로 내 특정 게이트가 아닌 하드웨어 오류율만을 기반으로 한 노이즈 인식 점수 헤우리스틱을 적용합니다.
이 함수는 Python 공간 VF2Layout 패스에 해당합니다.
이 기능은 아직 하드웨어로 완전히 구현되지 않은 회로에 사용하기에 적합합니다. 회로가 이미 하드웨어로 완전히 구현된 상태에서 정확한 상호작용 그래프를 위한 레이아웃 개선을 원한다면 대신 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);안전
또는 가 유효한 비공 circuit``QkCircuit 포인터가 아닐 target 경우 QkTarget 동작이 정의되지 않습니다. 가 유효한 QkVF2LayoutConfiguration 객체를 가리키지 않는 비공(非空) 포인터인 config 경우 동작이 정의되지 않습니다(단, 공(空) 포인터는 허용됩니다).
매개변수
- 회로 - VF2Layout 을 실행할 회로에 대한 포인터입니다
- 대상 - 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 알고리즘을 사용하여 입력 회로에 대한 레이아웃을 선택합니다(가능한 경우). 이때 결과물이 하드웨어와 완전히 호환되어야 한다는 조건을 충족하는 노이즈 인식 점수 헤우리스틱을 적용합니다.
이 함수는 Python -공간 VF2PostLayout 패스에 해당합니다 strict_direction=True.
이 함수는 이미 하드웨어로 완전히 구현된 회로에 사용하기에 적합하며, 큐비트 순열이 더 나은 추정 오류율로 이어질 수 있는지 확인하고자 할 때 활용됩니다. 회로가 여전히 하드웨어 지원되지 않는 연산에 관한 것이라면 대신 를 qk_transpile_pass_standalone_vf2_layout_average 사용하십시오.
일반적으로 이 패스는 레이아웃, 라우팅, 네이티브 베이스셋으로의 변환 및 최적화 이후에 호출되며, 입력 회로가 이미 하드웨어에서 실행 가능하도록 큐비트 인덱스가 물리적 큐비트를 참조하도록 합니다. 이 패스는 다음 중 하나를 나타내는 결과를 반환합니다:
- 현재 회로가 사용하는 것보다 더 나은 초기 가상-물리 큐비트 매핑 선택지가 존재한다.
- 현재 선택된 물리적 큐비트는 호출 제한 내에서 발견된 패스 중 최상의 선택입니다.
- 가상-물리 매핑의 유효한 선택은 실행 가능한 회로를 생성하지 못합니다(또는 적어도, 패스가 지정된 한계 내에서 그러한 선택을 찾지 못했습니다).
처음 두 경우 모두에서, 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);안전
또는 가 유효한 비공 circuit``QkCircuit 포인터가 아닐 target 경우 QkTarget 동작이 정의되지 않습니다. 가 유효한 QkVF2LayoutConfiguration 객체를 가리키지 않는 비공(非空) 포인터인 config 경우 동작이 정의되지 않습니다(단, 공(空) 포인터는 허용됩니다).
매개변수
- 회로 – 레이아웃 검색을 실행할 회로에 대한 포인터.
- 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 대해 의 모든 게이트에 대해 평균을 취합니다).
안전
의 안전 요구사항은 및 에 circuit qk_transpiler_pass_standalone_vf2_layout_average 대해 반드시 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_limit – 와 동일하지만
qk_vf2_layout_configuration_set_call_limit, 동일한 값이 와before모두에after사용됩니다. - 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와 마찬가지로.