IR 转换 -- OriginIR 与 QASM(IR Conversion)
在 QProg、OriginIR 和 QASM 中间表示之间进行转换,实现电路互操作、序列化和调试。
问题
使用 pyqpanda3 构建的量子电路以内存中的 QProg 对象形式存在。在许多情况下,你需要将电路表示为纯文本字符串,以便存储、传输或与其他框架共享。支持两种基于文本的中间表示(Intermediate Representation, IR):
OriginIR 是 QPanda 的原生 IR 格式。它为每个 pyqpanda3 功能提供完整保真度,包括动态电路(Dynamic Circuits, QIF/QELSE/QWHILE)、自定义门定义(QGATE)、受控和求逆操作以及所有原生门类型。当需要在 pyqpanda3 生态系统内序列化和反序列化电路时使用 OriginIR。
OpenQASM 2.0 是 Qiskit、Cirq 及许多其他框架支持的行业标准量子汇编语言。当需要与非 QPanda 工具交换电路、从开源社区导入电路或导出电路用于发表时使用 QASM。
你需要在以下场景进行 IR 转换:
- 互操作性(Interoperability)——导入在 Qiskit 等框架中编写的 QASM 电路,或将 pyqpanda3 电路导出为 QASM 给其他框架使用。
- 持久化(Persistence)——将电路作为 OriginIR 或 QASM 文件保存到磁盘,之后无需重新运行构建代码即可加载。
- 验证(Verification)——将电路导出为文本,目视检查门序列,或通过比较字符串表示来比较两个电路。
- 调试(Debugging)——打印复杂
QProg的 IR 以了解其门结构、控制流和测量操作。 - 往返测试(Round-Trip Testing)——构建电路、导出为 IR、再导入回来,验证酉矩阵是否匹配以确认转换管道的正确性。
下图展示了 intermediate_compiler 模块支持的转换路径:
方案
intermediate_compiler 模块提供六个函数,覆盖所有转换方向:
| 函数 | 方向 | 输入 | 输出 |
|---|---|---|---|
convert_qprog_to_originir(prog, precision) | QProg -> OriginIR | QProg,可选 int | str |
convert_qprog_to_qasm(prog, precision) | QProg -> QASM | QProg,可选 int | str |
convert_originir_string_to_qprog(ir_string) | OriginIR 字符串 -> QProg | str | QProg |
convert_originir_file_to_qprog(file_path) | OriginIR 文件 -> QProg | str(路径) | QProg |
convert_qasm_string_to_qprog(qasm_string) | QASM 字符串 -> QProg | str | QProg |
convert_qasm_file_to_qprog(file_path) | QASM 文件 -> QProg | str(路径) | QProg |
precision 参数(默认值:8)控制导出字符串中浮点角度值使用的小数位数。更高的精度保留更多准确性,这对往返保真度很重要。
步骤 1:将电路导出为 OriginIR 或 QASM
使用标准 pyqpanda3 API 构建 QProg,然后调用相应的转换函数:
from pyqpanda3.core import QProg, H, CNOT, RX, measure
from pyqpanda3.intermediate_compiler import (
convert_qprog_to_originir,
convert_qprog_to_qasm,
)
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog << RX(1, 3.14159)
prog << measure([0, 1], [0, 1])
originir_str = convert_qprog_to_originir(prog)
qasm_str = convert_qprog_to_qasm(prog)
print("=== OriginIR ===")
print(originir_str)
print("=== QASM ===")
print(qasm_str)步骤 2:将 OriginIR 或 QASM 字符串导入为 QProg
将文本表示解析回可执行的 QProg:
from pyqpanda3.intermediate_compiler import (
convert_originir_string_to_qprog,
convert_qasm_string_to_qprog,
)
originir_str = """
QINIT 2
CREG 2
H q[0]
CNOT q[0],q[1]
MEASURE q[0],c[0]
MEASURE q[1],c[1]
"""
prog_from_originir = convert_originir_string_to_qprog(originir_str)步骤 3:从文件加载电路
对于存储在磁盘上的电路,使用基于文件的导入函数:
from pyqpanda3.intermediate_compiler import (
convert_originir_file_to_qprog,
convert_qasm_file_to_qprog,
)
prog = convert_originir_file_to_qprog("/path/to/circuit.txt")
prog = convert_qasm_file_to_qprog("/path/to/circuit.qasm")步骤 4:验证往返保真度
在往返转换(先导出再导入)后,比较酉矩阵以确认没有信息丢失:
from pyqpanda3.quantum_info import Unitary
prog = QProg()
prog << H(0) << CNOT(0, 1)
qasm_str = convert_qprog_to_qasm(prog, precision=15)
prog2 = convert_qasm_string_to_qprog(qasm_str)
mat1 = Unitary(prog.to_circuit())
mat2 = Unitary(prog2.to_circuit())
# Compute squared distance between the two unitary matrices
diff = abs(mat1.ndarray() - mat2.ndarray()) ** 2
print(f"Round-trip error: {diff.max():.2e}")代码
示例 1:构建 Bell 态并导出为两种格式
本示例创建 Bell 态电路并将其导出为 OriginIR 和 QASM:
from pyqpanda3.core import QProg, H, CNOT, measure
from pyqpanda3.intermediate_compiler import (
convert_qprog_to_originir,
convert_qprog_to_qasm,
)
# Build a Bell state circuit
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog << measure([0, 1], [0, 1])
# Export to OriginIR (QPanda's native format)
originir_str = convert_qprog_to_originir(prog)
print("OriginIR representation:")
print(originir_str)
print()
# Export to QASM 2.0 (industry standard)
qasm_str = convert_qprog_to_qasm(prog)
print("QASM representation:")
print(qasm_str)预期 OriginIR 输出:
QINIT 2
CREG 2
H q[0]
CNOT q[0],q[1]
MEASURE q[0],c[0]
MEASURE q[1],c[1]预期 QASM 输出:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[2];
creg c[2];
h q[0];
cx q[0],q[1];
measure q[0] -> c[0];
measure q[1] -> c[1];示例 2:导入 OriginIR 字符串并运行
本示例解析 OriginIR 字符串,在模拟器上运行结果电路,并打印测量计数:
from pyqpanda3.core import CPUQVM
from pyqpanda3.intermediate_compiler import convert_originir_string_to_qprog
originir_str = """
QINIT 3
CREG 2
H q[2]
H q[0]
H q[1]
CONTROL q[1]
RX q[2],(-3.141593)
ENDCONTROL
CONTROL q[0]
RX q[2],(-3.141593)
RX q[2],(-3.141593)
ENDCONTROL
DAGGER
H q[1]
H q[0]
ENDDAGGER
MEASURE q[0],c[0]
MEASURE q[1],c[1]
"""
prog = convert_originir_string_to_qprog(originir_str)
machine = CPUQVM()
machine.run(prog=prog, shots=1000)
counts = machine.result().get_counts()
print("Measurement counts:", counts)示例 3:导入 QASM 字符串并运行
本示例导入用 QASM 编写的量子隐形传态电路:
from pyqpanda3.core import CPUQVM
from pyqpanda3.intermediate_compiler import convert_qasm_string_to_qprog
qasm_str = """
// quantum teleportation example
OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
creg c[3];
gate post q {
h q;
}
u3(0.3,0.2,0.1) q[0];
h q[1];
cx q[1],q[2];
barrier q;
cx q[0],q[1];
h q[0];
measure q[0] -> c[0];
measure q[1] -> c[1];
if(c==1) z q[2];
if(c==2) x q[2];
if(c==3) y q[2];
post q[2];
measure q[2] -> c[2];
"""
prog = convert_qasm_string_to_qprog(qasm_str)
machine = CPUQVM()
machine.run(prog=prog, shots=1000)
counts = machine.result().get_counts()
print("Teleportation counts:", counts)示例 4:带验证的往返转换
本示例演示完整的往返流程:构建电路、导出为 QASM、导入回来,并验证酉矩阵是否匹配。这是验证转换管道保持电路语义的常见模式。
from pyqpanda3.core import QProg, H, CNOT, RX, RY, RZ, CZ
from pyqpanda3.intermediate_compiler import (
convert_qprog_to_qasm,
convert_qasm_string_to_qprog,
convert_qprog_to_originir,
)
from pyqpanda3.quantum_info import Unitary
import numpy as np
# Build a non-trivial circuit
prog = QProg()
prog << H(0)
prog << H(1)
prog << CNOT(0, 1)
prog << RZ(0, 1.2345)
prog << RZ(1, 2.3456)
prog << CNOT(0, 1)
prog << RX(0, 0.5678)
prog << RY(1, 0.9012)
prog << CZ(0, 1)
# Use high precision for the round-trip to avoid floating-point loss
qasm_str = convert_qprog_to_qasm(prog, precision=15)
print("Exported QASM:")
print(qasm_str)
# Import the QASM string back into a QProg
prog2 = convert_qasm_string_to_qprog(qasm_str)
# Also verify the OriginIR path
originir_str = convert_qprog_to_originir(prog, precision=15)
print("\nExported OriginIR:")
print(originir_str)
# Compare unitary matrices
mat1 = Unitary(prog.to_circuit())
mat2 = Unitary(prog2.to_circuit())
diff = np.abs(mat1.ndarray() - mat2.ndarray()) ** 2
max_error = diff.max()
print(f"\nRound-trip max squared error: {max_error:.2e}")
assert max_error < 1e-10, "Round-trip fidelity check failed!"
print("Round-trip verified successfully.")示例 5:将电路保存到文件并加载
本示例展示如何将 OriginIR 或 QASM 字符串写入文件并读回:
import os
from pyqpanda3.core import QProg, H, CNOT, measure
from pyqpanda3.intermediate_compiler import (
convert_qprog_to_originir,
convert_qprog_to_qasm,
convert_originir_file_to_qprog,
convert_qasm_file_to_qprog,
)
# Build a circuit
prog = QProg()
prog << H(0)
prog << CNOT(0, 1)
prog << measure([0, 1], [0, 1])
# --- Save as OriginIR ---
originir_str = convert_qprog_to_originir(prog)
originir_path = "/tmp/bell_circuit.txt"
with open(originir_path, "w") as f:
f.write(originir_str)
print(f"Saved OriginIR to {originir_path}")
# --- Save as QASM ---
qasm_str = convert_qprog_to_qasm(prog)
qasm_path = "/tmp/bell_circuit.qasm"
with open(qasm_path, "w") as f:
f.write(qasm_str)
print(f"Saved QASM to {qasm_path}")
# --- Load back from files ---
prog_from_oir = convert_originir_file_to_qprog(originir_path)
prog_from_qasm = convert_qasm_file_to_qprog(qasm_path)
# Verify both loaded circuits produce the same OriginIR
print("\nOriginIR from file:")
print(convert_qprog_to_originir(prog_from_oir))
print("\nQASM from file:")
print(convert_qprog_to_qasm(prog_from_qasm))
# Clean up
os.remove(originir_path)
os.remove(qasm_path)示例 6:处理受控和求逆操作
OriginIR 原生支持 CONTROL/ENDCONTROL 块和 DAGGER/ENDDAGGER 块。本示例演示这些在 QProg API 和 IR 之间的映射关系:
from pyqpanda3.core import QProg, H, RX, X
from pyqpanda3.intermediate_compiler import convert_qprog_to_originir
prog = QProg()
prog << H(0)
prog << H(1)
prog << H(2)
# Apply RX on qubit 2, controlled by qubit 1
prog << RX(2, -3.141593).control([1])
# Apply RX on qubit 2, controlled by qubit 0 (twice, effectively 2x the angle)
prog << RX(2, -3.141593).control([0])
prog << RX(2, -3.141593).control([0])
# Apply the dagger (inverse) of H(1) followed by H(0)
prog << H(1).dagger()
prog << H(0).dagger()
originir_str = convert_qprog_to_originir(prog)
print(originir_str)输出将包含 CONTROL/ENDCONTROL 和 DAGGER/ENDDAGGER 块:
QINIT 3
CREG 0
H q[0]
H q[1]
H q[2]
CONTROL q[1]
RX q[2],(-3.141593)
ENDCONTROL
CONTROL q[0]
RX q[2],(-3.141593)
RX q[2],(-3.141593)
ENDCONTROL
DAGGER
H q[1]
H q[0]
ENDDAGGER示例 7:OriginIR 中的自定义门定义
OriginIR 通过 QGATE/ENDQGATE 语法支持用户定义的门。你可以定义带参数的可复用门块:
from pyqpanda3.core import CPUQVM
from pyqpanda3.intermediate_compiler import convert_originir_string_to_qprog
originir_str = """
QINIT 2
CREG 2
H q
X q[0]
Y q[1]
QGATE new_H a,b
Y a
Z b
ENDQGATE
QGATE new_RX a,b,(d,e)
H a
RX b,(PI/2+d+e)
new_H a,b
ENDQGATE
new_RX q[1],q[0],(PI/2,3)
new_RX q,(1,2)
MEASURE q[0],c[0]
MEASURE q[1],c[1]
"""
prog = convert_originir_string_to_qprog(originir_str)
machine = CPUQVM()
machine.run(prog=prog, shots=1000)
counts = machine.result().get_counts()
print("Counts:", counts)上面的 QGATE 块将 new_H 定义为对两个量子比特施加 Y 和 Z 的复合门,new_RX 定义为使用 PI 作为内置常量并引用参数 d 和 e 的参数化门。
示例 8:OriginIR 中的动态电路(QIF / QWHILE)
OriginIR 支持动态电路构造——条件执行(QIF/QELSE/QELSEIF/QENDIF)和电路中途循环(QWHILE/QENDWHILE)。这些对于后续操作依赖于先前测量结果的电路至关重要:
from pyqpanda3.core import QProg, CPUQVM, X, Y, Z, H, measure, qif, qwhile
from pyqpanda3.intermediate_compiler import (
convert_qprog_to_originir,
convert_originir_string_to_qprog,
)
# Build a dynamic circuit using the pyqpanda3 API
prog = QProg()
inner_loop = QProg()
inner_loop << Y(2) << Y(1) << measure(2, 2)
if_body = QProg()
if_body << Y(0) << H(1)
if_body << qwhile([2]).loop(inner_loop)
prog << X(1)
prog << qif([1]).then(if_body).qendif()
prog << measure(0, 0)
prog << measure(1, 1)
# Export to OriginIR to see the dynamic circuit representation
originir_str = convert_qprog_to_originir(prog)
print("Dynamic circuit as OriginIR:")
print(originir_str)
# Parse it back and verify the round-trip
prog2 = convert_originir_string_to_qprog(originir_str)
originir_str2 = convert_qprog_to_originir(prog2)
print("\nRound-trip OriginIR:")
print(originir_str2)
# Run on a simulator
machine = CPUQVM()
machine.run(prog=prog, shots=100)
state = machine.result().get_state_vector()
print("\nState vector (first 4 amplitudes):")
for i, v in enumerate(state[:4]):
print(f" |{i:02b}>: ({v.real:.6f}, {v.imag:.6f})")解析
OriginIR 语法概述
OriginIR 是面向行的文本 IR。每行包含一条指令或一个块分隔符。一般结构为:
QINIT <n> -- Declare n qubits
CREG <m> -- Declare m classical bits
<gate> q[<idx>] -- Single-qubit gate
<gate> q[<i>],q[<j>] -- Two-qubit gate
<gate> q[<i>],(<angle>) -- Parameterized gate with angle in radians头部行(Header Lines)(QINIT 和 CREG)是必需的。它们声明量子比特数和经典比特数。量子比特索引范围为 QINIT 的值。
门指令(Gate Instructions)遵循模式 GATE_NAME target_qubit(s),(parameter(s))。例如:
| OriginIR 行 | 含义 |
|---|---|
H q[0] | 对量子比特 0 施加 Hadamard |
X q[1] | 对量子比特 1 施加 Pauli-X |
RX q[0],(1.570796) | 绕 X 轴旋转 |
CNOT q[0],q[1] | CNOT,控制=0,目标=1 |
MEASURE q[0],c[0] | 测量量子比特 0 存入经典比特 0 |
控制块(Control Blocks)使用 CONTROL/ENDCONTROL:
CONTROL q[0],q[1]
X q[2]
Z q[3]
ENDCONTROL仅当量子比特 0 和 1 都处于
求逆块(Dagger Blocks)使用 DAGGER/ENDDAGGER 来施加包含操作的逆操作:
DAGGER
H q[0]
RX q[1],(1.570796)
ENDDAGGER自定义门(Custom Gates)使用 QGATE/ENDQGATE 配合可选参数:
QGATE my_gate a,b,(theta,phi)
RX a,(theta)
RY b,(phi)
CNOT a,b
ENDQGATE这里 a 和 b 是形式量子比特参数,theta 和 phi 是形式参数名。内置常量 PI 表示
条件执行(Conditional Execution)使用 QIF/QELSE/QELSEIF/QENDIF:
QIF c[0],c[1]
X q[2]
QELSEIF c[2]
Y q[2]
QELSE
Z q[2]
QENDIF条件检查指定的经典比特被解释为小端整数时是否等于 1。可以列出多个经典比特。
循环构造(Loop Constructs)使用 QWHILE/QENDWHILE:
QWHILE c[0]
X q[1]
MEASURE q[1],c[0]
QENDWHILE只要条件经典比特评估为 1,循环体就重复执行。
注释(Comments)是以 // 开头的单行注释:
H q[0] // Apply Hadamard
// This is a full-line commentQASM 2.0 语法概述
QASM 2.0 是 IBM 定义的标准量子汇编格式。QASM 2.0 程序的结构如下:
OPENQASM 2.0;
include "qelib1.inc";
qreg q[<n>];
creg c[<m>];
<gate> q[<i>];
<gate> q[<i>],q[<j>];
measure q[<i>] -> c[<j>];与 OriginIR 的主要区别:
- 头部为
OPENQASM 2.0;后跟include "qelib1.inc";。 - 量子比特寄存器使用
qreg q[n];而非QINIT n。 - 经典寄存器使用
creg c[m];而非CREG m。 - 测量语法使用
->而非逗号:measure q[0] -> c[0]。 - 门名称为小写:
h、cx、cz、rx、ry、rz等。 - QASM 通过
gate关键字支持自定义门定义。 - QASM 通过
if(c==<val>)语法支持条件执行。
表示之间的门映射
下表展示常见门在 pyqpanda3、OriginIR 和 QASM 2.0 之间的映射:
| pyqpanda3 API | OriginIR | QASM 2.0 |
|---|---|---|
H(q) | H q[i] | h q[i] |
X(q) | X q[i] | x q[i] |
Y(q) | Y q[i] | y q[i] |
Z(q) | Z q[i] | z q[i] |
S(q) | S q[i] | s q[i] |
T(q) | T q[i] | t q[i] |
RX(q, angle) | RX q[i],(angle) | rx(angle) q[i] |
RY(q, angle) | RY q[i],(angle) | ry(angle) q[i] |
RZ(q, angle) | RZ q[i],(angle) | rz(angle) q[i] |
P(q, angle) | P q[i],(angle) | p(angle) q[i] |
CNOT(c, t) | CNOT q[c],q[t] | cx q[c],q[t] |
CZ(c, t) | CZ q[c],q[t] | cz q[c],q[t] |
SWAP(a, b) | SWAP q[a],q[b] | swap q[a],q[b] |
TOFFOLI(a, b, t) | TOFFOLI q[a],q[b],q[t] | ccx q[a],q[b],q[t] |
U1(q, lam) | U1 q[i],(lam) | u1(lam) q[i] |
U2(q, phi, lam) | U2 q[i],(phi,lam) | u2(phi,lam) q[i] |
U3(q, theta, phi, lam) | U3 q[i],(theta,phi,lam) | u3(theta,phi,lam) q[i] |
CU(c, t, theta, phi, lam, gamma) | CU q[c],q[t],(theta,phi,lam,gamma) | cu(theta,phi,lam,gamma) q[c],q[t] |
measure(q, c) | MEASURE q[i],c[j] | measure q[i] -> c[j] |
barrier(qubits) | BARRIER q[i],q[j],... | barrier q[i],q[j],... |
限制与格式选择
每种格式都有特定的优势和限制:
何时使用 OriginIR:
- 序列化 pyqpanda3 电路用于存储和后续检索。
- 包含动态控制流(
QIF、QWHILE)的电路。 - 使用
RPHI、ISWAP、SQISWAP或其他 QPanda 原生门的电路。 - 在 pyqpanda3 生态系统内进行完整保真度的往返转换。
- 使用
QProg(ir_string)快速构建电路。
何时使用 QASM 2.0:
- 与 Qiskit、Cirq 或其他框架交换电路。
- 从公共仓库或教科书导入电路。
- 以广泛理解的格式发布电路。
- 提交到接受 QASM 的量子云服务。
需要注意的主要限制:
- QASM 2.0 不支持
QWHILE循环。如果你将包含qwhile构造的电路导出为 QASM,循环结构将不会被保留。 - 某些 QPanda 原生门(如
ISWAP、RPHI)没有直接的 QASM 2.0 等价物。将这些门导出为 QASM 可能会产生错误或分解为受支持的门。 precision参数影响浮点保真度。对于包含许多旋转门的电路,使用precision=15或更高值以确保往返准确性。- OriginIR 和 QASM 对
measure语法使用不同的约定:OriginIR 使用MEASURE q[i],c[j],而 QASM 使用measure q[i] -> c[j]。
便捷功能:QProg OriginIR 构造函数
除了 convert_originir_string_to_qprog 函数外,你还可以使用 QProg 构造函数直接从 OriginIR 字符串构造 QProg:
from pyqpanda3.core import QProg, CPUQVM
# Direct construction from OriginIR string
prog = QProg("""
QINIT 2
CREG 2
H q[0]
CNOT q[0],q[1]
MEASURE q[0],c[0]
MEASURE q[1],c[1]
""")
# The program is ready to run
machine = CPUQVM()
machine.run(prog=prog, shots=1000)
counts = machine.result().get_counts()
print(counts)类似地,QProg 实例上的 .originir() 方法无需使用模块级函数即可返回 OriginIR 字符串:
prog = QProg()
prog << H(0) << CNOT(0, 1)
# These two calls are equivalent:
ir1 = prog.originir()
# ir1 = convert_qprog_to_originir(prog)
print(ir1)精度与往返保真度
默认精度 8 位小数对大多数实际电路足够。然而,在执行往返转换(先导出再导入)时,对于包含许多参数化门的电路,浮点舍入误差可能累积。原始电路和往返电路酉矩阵之间的平方矩阵距离应满足:
其中 precision=15 以保持
实用的验证模式:
from pyqpanda3.quantum_info import Unitary
import numpy as np
def verify_round_trip(prog, precision=15, tolerance=1e-6):
"""Verify that export-import round-trip preserves circuit unitary."""
qasm_str = convert_qprog_to_qasm(prog, precision=precision)
prog2 = convert_qasm_string_to_qprog(qasm_str)
mat1 = Unitary(prog.to_circuit()).ndarray()
mat2 = Unitary(prog2.to_circuit()).ndarray()
# Account for global phase by comparing squared distances
diff = np.abs(mat1 - mat2) ** 2
max_error = diff.max()
if max_error > tolerance:
raise AssertionError(
f"Round-trip error {max_error:.2e} exceeds tolerance {tolerance:.2e}"
)
return True电路序列化模式
常见的工作流是以编程方式构建电路、将其序列化以进行存储或传输,之后反序列化:
模式 1:OriginIR 用于内部存储(完整保真度)
# Serialize
originir_str = convert_qprog_to_originir(prog, precision=15)
with open("circuit_cache.txt", "w") as f:
f.write(originir_str)
# Deserialize
prog = convert_originir_file_to_qprog("circuit_cache.txt")模式 2:QASM 用于框架互操作性
# Serialize for Qiskit consumption
qasm_str = convert_qprog_to_qasm(prog, precision=15)
with open("circuit_for_qiskit.qasm", "w") as f:
f.write(qasm_str)
# In Qiskit:
# from qiskit import QuantumCircuit
# qc = QuantumCircuit.from_qasm_file("circuit_for_qiskit.qasm")模式 3:批量转换
当你需要在格式之间转换许多电路时,使用带错误处理的循环:
from pyqpanda3.intermediate_compiler import (
convert_qasm_string_to_qprog,
convert_qprog_to_originir,
)
qasm_circuits = ["<QASM 1>", "<QASM 2>", "<QASM 3>"] # your QASM strings
for i, qasm_str in enumerate(qasm_circuits):
try:
prog = convert_qasm_string_to_qprog(qasm_str)
originir_str = convert_qprog_to_originir(prog)
with open(f"circuit_{i:04d}.txt", "w") as f:
f.write(originir_str)
except Exception as e:
print(f"Failed to convert circuit {i}: {e}")常见陷阱
OriginIR 缺少头部行:每个 OriginIR 字符串必须以
QINIT和CREG声明开头。省略它们会导致解析错误。往返转换使用错误精度:默认精度 8 位小数可能在包含许多旋转门的电路中丢失有效数字。进行往返转换时始终使用
precision=15。QASM 中不支持的门:
ISWAP、SQISWAP和RPHI等门没有 QASM 2.0 等价物。将包含这些门的电路导出为 QASM 会失败或产生不正确结果。改用 OriginIR。测量语法混淆:记住 OriginIR 使用
MEASURE q[i],c[j](逗号),而 QASM 使用measure q[i] -> c[j](箭头)。QASM 中的动态电路:QASM 2.0 的
if(c==val)语法仅支持有限形式的条件执行。包含QWHILE循环的复杂动态电路无法导出为 QASM。完整动态电路支持请使用 OriginIR。门名称大小写敏感:OriginIR 门名称为大写(
H、CNOT、RX)。QASM 门名称为小写(h、cx、rx)。混合使用会导致解析错误。
API 参考摘要
所有函数从 pyqpanda3.intermediate_compiler 导入:
from pyqpanda3.intermediate_compiler import (
convert_originir_string_to_qprog, # str -> QProg
convert_originir_file_to_qprog, # filepath -> QProg
convert_qasm_string_to_qprog, # str -> QProg
convert_qasm_file_to_qprog, # filepath -> QProg
convert_qprog_to_originir, # QProg -> str
convert_qprog_to_qasm, # QProg -> str
)函数签名:
convert_qprog_to_originir(prog: QProg, precision: int = 8) -> str
convert_qprog_to_qasm(prog: QProg, precision: int = 8) -> str
convert_originir_string_to_qprog(ir_string: str) -> QProg
convert_originir_file_to_qprog(file_path: str) -> QProg
convert_qasm_string_to_qprog(qasm_string: str) -> QProg
convert_qasm_file_to_qprog(file_path: str) -> QProgprecision 参数控制导出 IR 字符串中浮点值的小数位数。它必须是非负整数。更高的值保留更多准确性,但会产生更长的字符串输出。