编译工作流¶
除了 量子电路转换,PennyLane 还支持通过 qjit() 装饰器和各种混合编译器进行全混合即时编译(JIT),这些编译器可以单独安装。
最受支持和默认的编译器是Catalyst混合编译器。Catalyst允许您编译整个量子-经典工作流,包括任何优化循环。这最大限度地提高了性能,并使您能够在加速设备上运行整个工作流。
此外,PennyLane还支持通过CUDA Quantum编译受限程序;有关更多详细信息,请参见下面的CUDA Quantum部分。
安装编译器¶
目前,Catalyst 必须单独安装,并且仅支持 JAX 接口和特定设备。Catalyst 支持的后端设备包括 lightning.qubit、lightning.kokkos、lightning.gpu 和 braket.aws.qubit,但是 不支持 default.qubit。有关支持的设备的完整列表,请参阅 支持的设备。
在 MacOS 和 Linux 上,可以使用 pip 安装 Catalyst:
pip install pennylane-catalyst
查看Catalyst文档以获取 安装说明.
即时编译¶
使用Catalyst与PennyLane一样简单,只需使用@qjit装饰器来编译您的混合工作流:
from jax import numpy as jnp
dev = qml.device("lightning.qubit", wires=2, shots=1000)
@qml.qjit
@qml.qnode(dev)
def circuit(params):
qml.Hadamard(0)
qml.RX(jnp.sin(params[0]) ** 2, wires=1)
qml.CRY(params[0], wires=[0, 1])
qml.RX(jnp.sqrt(params[1]), wires=1)
return qml.expval(qml.Z(1))
qjit() 装饰器也可以用于混合函数 - 也就是说,同时包含 QNodes 和经典处理的函数。
@qml.qjit
def hybrid_function(params, x):
grad = qml.grad(circuit)(params)
return jnp.abs(grad - x) ** 2
此外,使用 @jax.jit 编译的函数可以包含对 qjit 编译函数的调用。比如,下面我们使用 @jax.jit 编译一个完整的优化循环:
import jaxopt
@jax.jit
def optimization():
# initial parameter
params = jnp.array([0.54, 0.3154])
# define the optimizer using a qjit-decorated function
opt = jaxopt.GradientDescent(circuit, stepsize=0.4)
update = lambda i, args: tuple(opt.update(*args))
# perform optimization loop
state = opt.init_state(params)
(params, _) = jax.lax.fori_loop(0, 100, update, (params, state))
return params
使用 @qml.qjit 编译整个混合工作流将会带来更好的性能。有关更多详细信息,请参见
Catalyst 文档。
控制流¶
Catalyst编译器还支持在编译程序中捕获命令式Python控制流,这使得控制流在运行时而不是在编译时在Python中被解释。您可以通过autograph=True关键字参数启用此功能。
@qml.qjit(autograph=True)
@qml.qnode(dev)
def circuit(x: int):
if x < 5:
qml.Hadamard(wires=0)
else:
qml.T(wires=0)
return qml.expval(qml.Z(0))
>>> circuit(3)
array(0.)
>>> circuit(5)
array(1.)
请注意,AutoGraph 结果会导致额外的限制,特别是在涉及全局状态时。请参考AutoGraph 指南以获取支持和不支持的使用案例的完整讨论。
CUDA Quantum¶
PennyLane qjit() 装饰器也可以用于编译使用 CUDA Quantum 的程序,
这是NVIDIA的一个混合编译工具链。
首先,需要安装Catalyst和CUDA Quantum:
pip install pennylane-catalyst cuda_quantum
然后,只需在 @qjit 装饰器中指定 compiler="cuda_quantum" :
dev = qml.device("softwareq.qpp", wires=2)
@qml.qjit(compiler="cuda_quantum")
@qml.qnode(dev)
def circuit(x):
qml.RX(x[0], wires=0)
qml.RY(x[1], wires=1)
qml.CNOT(wires=[0, 1])
return qml.expval(qml.Y(0))
>>> circuit(jnp.array([0.5, 1.4]))
-0.47244976756708373
编译时可用的设备如下,当使用CUDA Quantum时:
softwareq.qpp: 现代C++状态向量模拟器nvidia.custatevec: NVIDIA CuStateVec GPU模拟器(支持多GPU)nvidia.cutensornet: NVIDIA CuTensorNet GPU 仿真器(支持矩阵乘积态)
请注意,CUDA Quantum 编译目前与 Catalyst 编译没有功能对等;特别是,自动图、控制流、微分以及各种测量统计(例如概率和方差)尚不支持。