1. 从execute到run:Qiskit 1.0.0的“新世界”
如果你最近刚把Qiskit升级到1.0.0或更高版本,然后兴冲冲地跑起以前的量子计算脚本,大概率会迎面撞上一个熟悉的错误:NameError: name 'execute' is not defined。别慌,你不是一个人。我刚开始也懵了一下,心想这用了好多年的execute函数怎么说没就没了?这感觉就像你习惯去家门口那家老店吃早餐,结果有一天它突然升级成智能餐厅,点餐流程全变了。
其实,这是Qiskit走向成熟和模块化的重要一步。在1.0.0之前的版本里,execute函数是个“大管家”,它几乎包办了一切:把你的量子电路(QuantumCircuit)送到后端(Backend,比如模拟器或真机)去执行,中间还默认帮你做了电路转换(transpile)这个关键步骤。听起来很方便对吧?但问题也出在这里。这种“黑箱”操作让很多开发者,尤其是想深入优化性能的朋友,感到有点束手束脚。你不知道它内部到底用了什么转换策略,参数怎么调的,当结果不如预期时,调试起来就像在迷宫里找路。
所以,Qiskit团队在1.0.0版本做了一个大胆而明智的决定:拆解这个“大管家”。他们把execute的功能清晰地分成了两个独立的步骤:transpile(电路转换) 和 run(运行)。transpile函数专门负责把你在逻辑层面设计的、通用的量子电路,翻译成特定后端硬件能理解和执行的具体指令集。而run函数则专注于一件事:把转换好的电路丢给后端去执行,并拿回结果。这样做的好处太多了,最直接的就是透明度和控制力。你现在可以清清楚楚地看到电路在运行前被改成了什么样子,可以精细地调整转换参数来提升性能或保真度,调试的时候也终于有了明确的抓手。
简单来说,以前是“一键傻瓜式”的execute(circuit, backend),现在是“手动挡”的transpiled_circuit = transpile(circuit, backend),然后job = backend.run(transpiled_circuit)。别担心,这个“手动挡”开起来并不难,而且一旦习惯,你会发现对量子程序的控制力上了一个新台阶。接下来,我们就手把手把这套新流程摸透。
2. 核心第一步:深入理解transpile函数
在Qiskit的新世界里,transpile是你运行任何量子程序前几乎无法绕开的一步。你可以把它想象成一位专业的“翻译官”兼“架构师”。你的原始电路是用Qiskit通用“语言”写的,但不同的量子计算机硬件(比如IBM的ibm_brisbane,或是模拟器aer_simulator)有自己独特的“方言”(称为基础门集,basis_gates)和“建筑规范”(比如量子比特的连通拓扑)。transpile的工作,就是把你的通用设计稿,精准地适配到目标硬件的具体蓝图上。
我们先来看看它的基本用法,这和你以前用execute的第一感觉会很像:
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
# 1. 创建一个简单的量子电路
circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()
# 2. 选择一个后端(这里用Aer模拟器)
backend = AerSimulator()
# 3. 使用transpile进行电路转换
transpiled_circuit = transpile(circuit, backend=backend)
print("原始电路深度:", circuit.depth())
print("转换后电路深度:", transpiled_circuit.depth())
运行一下,你会发现transpiled_circuit的深度可能和原始电路不同。这是因为AerSimulator默认的基础门集可能包含u1、u2、u3、cx等,transpile自动将你的h门等分解成了这些基础门。这仅仅是冰山一角,transpile真正的威力在于它丰富的转换通道和优化等级。
优化等级是你第一个要关注的参数。通过optimization_level来设置,它直接决定了转换器在优化电路上花多少“心思”:


1145

被折叠的 条评论
为什么被折叠?



