脉冲门
大多数量子算法可以单独用电路操作(circuit operations)实现.当我们对程序的低阶实现需要更多控制时,我们可以使用脉冲门(pulse gates).脉冲门移除了电路执行必须使用基础门的限制,同时也允许我们重写任意基础门的实现.
脉冲门允许我们将一个逻辑电路门映射到一个Qiskit Pulse程序,叫做日程(Schedule).这一映射被叫做校准(calibration).一个高忠诚度(high fidelity)的校准会完完全全“忠诚”地实现它所根据的逻辑操作(例如,无论如何校准X门, ∣ 0 > \left|0\right> ∣0⟩总会被翻转成 ∣ 1 > \left|1\right> ∣1⟩).
一个日程指定了输入信号(input signals)经由所有输入频道(input channels)到达设备的准确时间.通常每个量子比特会有很多频道,例如驱动和测量.日程这种接口(interface)会表现得更为强大,也需要对基础设备中的物理有更深刻的理解.
值得注意的是,Pulse程序是在真实的量子比特上进行操作的.一个操作于量子比特甲的设备脉冲不能施加相同逻辑操作在量子比特乙上.换句话说,门校准在不同量子比特间是不通用的.这和电路层次的处理方式相反,例如电路中的X门是无关于具体量子比特的.
本页面向你展示如何向你的电路中添加校准.
注意:为了执行带有脉冲门的程序,后端应该连带OpenPulse开启.你可以通过输入
backend.configuration().open_pulse
进行检查,如果返回值为True,则OpenPulse已经开启.如果它已经被开启并且你的脉冲门组件未开启,你可以为你的电路制定日程(schedule).
构建电路
让我们从一个十分简单的例子开始——贝尔态电路.
from qiskit import QuantumCircuit
circ = QuantumCircuit(2, 2)
circ.h(0)
circ.cx(0, 1)
circ.measure(0, 0)
circ.measure(1, 1)
circ.draw('mpl')
构建校准
既然我们已经生成了电路,让我们为作用于第0号量子比特上的H门定义一个校准.
实操中,脉冲形状及其参数都会通过一系列拉比实验(Rabi experiments)进行最优化.由上所述,我们的H门会变成一种高斯脉冲.我们会在第0号量子比特的驱动频道上播放我们的脉冲.
不用太过担心构建校准的细节,你可以在以下网页对其进行全部了解:构建脉冲日程
from qiskit import pulse
from qiskit.pulse.library import Gaussian
from qiskit.providers.fake_provider import FakeValencia
backend = FakeValencia()
with pulse.build(backend, name='hadamard') as h_q0:
pulse.play(Gaussian(duration=128, amp=0.1, sigma=16), pulse.drive_channel(0))
让我们画出新的日程,看看我们构建了什么.
h_q0.draw()
将校准链接到你的电路
剩下的就是完成注册.电路方法add_calibration需要有关门的信息和对日程表的引用来完成映射:
QuantumCircuit.add_calibration(gate, qubits, schedule, parameters)
gate参数应是一个circuit.Gate对象或某种门的名字.通常,对于每一组唯一的量子比特和参数,你需要一个不同的日程表。因为H门没有任何参数,所以我们不需要提供任何参数.
circ.add_calibration('h', [0], h_q0)
最后,请注意转译器将尊重您的校准.像往常一样使用它(我们的示例太过简单,以至于转译器无法优化,因此输出是相同的).
from qiskit import transpile
from qiskit.providers.fake_provider import FakeHanoi
backend = FakeHanoi()
circ = transpile(circ, backend)
print(backend.configuration().basis_gates)
circ.draw('mpl', idle_wires=False)
注意h不是模拟后端FakeHanoi的基门。因为我们给它加了一个校准,所以转译器会把我们的门当成基础门;但只是在定义它的量子比特上。应用于不同量子比特的阿达玛将展开到基础门。
就是这样!
自定义门
我们将简要地展示对于非标准的、完全自定义的门的相同过程.这个演示包括一个带参数的门.
from qiskit import QuantumCircuit
from qiskit.circuit import Gate
circ = QuantumCircuit(1, 1)
custom_gate = Gate('my_custom_gate', 1, [3.14, 1])
# 3.14 is an arbitrary parameter for demonstration
circ.append(custom_gate, [0])
circ.measure(0, 0)
circ.draw('mpl')
with pulse.build(backend, name='custom') as my_schedule:
pulse.play(Gaussian(duration=64, amp=0.2, sigma=8), pulse.drive_channel(0))
circ.add_calibration('my_custom_gate', [0], my_schedule, [3.14, 1])
# Alternatively: circ.add_calibration(custom_gate, [0], my_schedule)
如果我们使用Gate实例变量custom_gate来添加校准,则参数是从该实例派生的.记住,参数的顺序是有意义的.
circ = transpile(circ, backend)
circ.draw('mpl', idle_wires=False)
通常,如果我们试图转译我们的电路circ,我们会得到一个错误.没有为“my_custom_gate”提供函数定义,因此转译器不能将其展开到目标设备的基本门集.我们可以通过尝试将“my_custom_gate”添加到另一个尚未校准的量子比特来显示这一点.
circ = QuantumCircuit(2, 2)
circ.append(custom_gate, [1])
from qiskit import QiskitError
try:
circ = transpile(circ, backend)
except QiskitError as e:
print(e)
报错为:
"Cannot unroll the circuit to the given basis, ['id', 'rz', 'sx', 'x', 'cx', 'reset']. Instruction my_custom_gate not found in equivalence library and no rule found to expand."