PennyLane QASM 使用示例
In [1]:
Copied!
import pennylane as qml
print(qml.__version__)
# 预期输出:0.3x.x 或更高
import pennylane as qml
print(qml.__version__)
# 预期输出:0.3x.x 或更高
0.43.2
In [2]:
Copied!
import pennylane as qml
from pennylane import numpy as np
import sys
# 1. 环境审计
print(f"System Version: {sys.version}")
print(f"PennyLane Version: {qml.__version__}")
# 确保版本匹配,防止 API 变动导致的误判
if "0.43" not in qml.__version__:
print("⚠️ Warning: This audit script is optimized for PennyLane 0.43.x")
class PennyLaneAuditor:
"""
PennyLane OpenQASM 导出能力审计器 (针对 v0.43.2 API)。
"""
@staticmethod
def inspect_export(qnode, args=(), kwargs={}, description=""):
"""
审计 QNode 的 OpenQASM 导出行为。
Args:
qnode (QNode): 定义好的 PennyLane QNode。
args (tuple): 传递给 QNode 的位置参数。
kwargs (dict): 传递给 QNode 的关键字参数。
"""
print(f"\n{'='*10} [Audit: {description}] {'='*10}")
try:
# API 引用: pennylane.to_openqasm(qnode, wires=None, measure_all=True)
# PennyLane 的导出是基于"变换(Transform)"的。
# qml.to_openqasm(qnode) 返回一个新的函数,该函数在被调用时返回 QASM 字符串。
qasm_fn = qml.to_openqasm(qnode, measure_all=False)
qasm_str = qasm_fn(*args, **kwargs)
# 打印前 10 行以供检查
print(">>> Export Snippet:")
print('\n'.join(qasm_str.splitlines()[:15]))
if len(qasm_str.splitlines()) > 15:
print("... (truncated)")
# 核心特征审计
analysis = []
# 1. 版本检查
if "OPENQASM 2.0" in qasm_str:
analysis.append("Format: OpenQASM 2.0 (Legacy)")
elif "OPENQASM 3" in qasm_str:
analysis.append("Format: OpenQASM 3.0 (Modern)")
else:
analysis.append("Format: Unknown")
# 2. 参数绑定检查
# 检查具体的数值是否出现在代码中 (硬编码)
is_hardcoded = False
for arg in args:
if isinstance(arg, (int, float, np.ndarray)):
# 简单的启发式检查:看参数的字符串形式是否出现在 QASM 中
val_str = str(np.round(arg, 4)) if isinstance(arg, float) else str(arg)
# 去除 rx(0.5) 这种可能匹配的情况
if val_str in qasm_str:
is_hardcoded = True
break
if is_hardcoded:
analysis.append("Parameters: Hardcoded (Bound)")
elif "input " in qasm_str:
analysis.append("Parameters: Runtime Input (Unbound)")
# 3. 控制流检查
if "if (" in qasm_str and "c_if" not in qasm_str: # QASM 2 的 if 是 c_if 语法糖
analysis.append("Logic: Native 'if' (QASM 3)")
elif "if(" in qasm_str or "if " in qasm_str:
analysis.append("Logic: Legacy 'if' (QASM 2 style)")
else:
analysis.append("Logic: Linearized (No control flow)")
print(f"\n[Analysis Result] -> {', '.join(analysis)}")
except Exception as e:
print(f"[Analysis] ❌ Export Failed: {e}")
print("Auditor Ready.")
import pennylane as qml
from pennylane import numpy as np
import sys
# 1. 环境审计
print(f"System Version: {sys.version}")
print(f"PennyLane Version: {qml.__version__}")
# 确保版本匹配,防止 API 变动导致的误判
if "0.43" not in qml.__version__:
print("⚠️ Warning: This audit script is optimized for PennyLane 0.43.x")
class PennyLaneAuditor:
"""
PennyLane OpenQASM 导出能力审计器 (针对 v0.43.2 API)。
"""
@staticmethod
def inspect_export(qnode, args=(), kwargs={}, description=""):
"""
审计 QNode 的 OpenQASM 导出行为。
Args:
qnode (QNode): 定义好的 PennyLane QNode。
args (tuple): 传递给 QNode 的位置参数。
kwargs (dict): 传递给 QNode 的关键字参数。
"""
print(f"\n{'='*10} [Audit: {description}] {'='*10}")
try:
# API 引用: pennylane.to_openqasm(qnode, wires=None, measure_all=True)
# PennyLane 的导出是基于"变换(Transform)"的。
# qml.to_openqasm(qnode) 返回一个新的函数,该函数在被调用时返回 QASM 字符串。
qasm_fn = qml.to_openqasm(qnode, measure_all=False)
qasm_str = qasm_fn(*args, **kwargs)
# 打印前 10 行以供检查
print(">>> Export Snippet:")
print('\n'.join(qasm_str.splitlines()[:15]))
if len(qasm_str.splitlines()) > 15:
print("... (truncated)")
# 核心特征审计
analysis = []
# 1. 版本检查
if "OPENQASM 2.0" in qasm_str:
analysis.append("Format: OpenQASM 2.0 (Legacy)")
elif "OPENQASM 3" in qasm_str:
analysis.append("Format: OpenQASM 3.0 (Modern)")
else:
analysis.append("Format: Unknown")
# 2. 参数绑定检查
# 检查具体的数值是否出现在代码中 (硬编码)
is_hardcoded = False
for arg in args:
if isinstance(arg, (int, float, np.ndarray)):
# 简单的启发式检查:看参数的字符串形式是否出现在 QASM 中
val_str = str(np.round(arg, 4)) if isinstance(arg, float) else str(arg)
# 去除 rx(0.5) 这种可能匹配的情况
if val_str in qasm_str:
is_hardcoded = True
break
if is_hardcoded:
analysis.append("Parameters: Hardcoded (Bound)")
elif "input " in qasm_str:
analysis.append("Parameters: Runtime Input (Unbound)")
# 3. 控制流检查
if "if (" in qasm_str and "c_if" not in qasm_str: # QASM 2 的 if 是 c_if 语法糖
analysis.append("Logic: Native 'if' (QASM 3)")
elif "if(" in qasm_str or "if " in qasm_str:
analysis.append("Logic: Legacy 'if' (QASM 2 style)")
else:
analysis.append("Logic: Linearized (No control flow)")
print(f"\n[Analysis Result] -> {', '.join(analysis)}")
except Exception as e:
print(f"[Analysis] ❌ Export Failed: {e}")
print("Auditor Ready.")
System Version: 3.12.12 | packaged by Anaconda, Inc. | (main, Oct 21 2025, 20:05:38) [MSC v.1929 64 bit (AMD64)] PennyLane Version: 0.43.2 Auditor Ready.
In [3]:
Copied!
# 定义设备
dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def circuit_param(x, y):
# 在 PennyLane 中,x 和 y 通常是具体的数值张量,而不是符号
qml.RX(x, wires=0)
qml.RY(y, wires=1)
qml.CNOT(wires=[0, 1])
return qml.expval(qml.Z(0))
def test_parameters():
# 传入具体数值
params = (0.543, 1.234)
PennyLaneAuditor.inspect_export(
circuit_param,
args=params,
description="Parameterized Circuit (Expect Hardcoding)"
)
test_parameters()
# 定义设备
dev = qml.device("default.qubit", wires=2)
@qml.qnode(dev)
def circuit_param(x, y):
# 在 PennyLane 中,x 和 y 通常是具体的数值张量,而不是符号
qml.RX(x, wires=0)
qml.RY(y, wires=1)
qml.CNOT(wires=[0, 1])
return qml.expval(qml.Z(0))
def test_parameters():
# 传入具体数值
params = (0.543, 1.234)
PennyLaneAuditor.inspect_export(
circuit_param,
args=params,
description="Parameterized Circuit (Expect Hardcoding)"
)
test_parameters()
========== [Audit: Parameterized Circuit (Expect Hardcoding)] ========== >>> Export Snippet: OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; creg c[2]; rx(0.543) q[0]; ry(1.234) q[1]; cx q[0],q[1]; measure q[0] -> c[0]; [Analysis Result] -> Format: OpenQASM 2.0 (Legacy), Parameters: Hardcoded (Bound), Logic: Linearized (No control flow)
In [4]:
Copied!
@qml.qnode(dev)
def circuit_cond(measure_val):
qml.Hadamard(wires=0)
# 定义受控逻辑: 如果 measure_val > 0 (即为 1),则执行 X
# 注意:PennyLane 0.43 支持将测量值传递给 qml.cond
m = qml.measure(0)
def true_branch():
qml.X(1)
# 这里的条件是基于“中途测量结果 m”
qml.cond(m == 1, true_branch)()
return qml.probs(wires=1)
def test_conditional():
# 这里的参数其实不影响电路结构,因为条件是内部测量产生的
PennyLaneAuditor.inspect_export(
circuit_cond,
args=(0,),
description="Conditional Logic (qml.cond)"
)
test_conditional()
@qml.qnode(dev)
def circuit_cond(measure_val):
qml.Hadamard(wires=0)
# 定义受控逻辑: 如果 measure_val > 0 (即为 1),则执行 X
# 注意:PennyLane 0.43 支持将测量值传递给 qml.cond
m = qml.measure(0)
def true_branch():
qml.X(1)
# 这里的条件是基于“中途测量结果 m”
qml.cond(m == 1, true_branch)()
return qml.probs(wires=1)
def test_conditional():
# 这里的参数其实不影响电路结构,因为条件是内部测量产生的
PennyLaneAuditor.inspect_export(
circuit_cond,
args=(0,),
description="Conditional Logic (qml.cond)"
)
test_conditional()
========== [Audit: Conditional Logic (qml.cond)] ========== [Analysis] ❌ Export Failed: to_openqasm does not support translating Conditionals with measurement postprocessing.
PennyLane 的原生 to_openqasm 功能极弱,不可用于导出含控制流的电路。它仅适用于简单的、线性的量子门序列导出。一旦涉及到基于测量的反馈(Feedback)或条件执行,导出器就会因无法处理中间测量值的逻辑映射而崩溃。