qml.capture

该模块实现了PennyLane的捕获机制,用于混合量子-经典程序。

警告

该模块是实验性的,未来将会有重大变化。

disable()

在PennyLane程序表示(plxpr)中禁用混合量子-经典程序的捕获机制。

enable()

在PennyLane程序表示(plxpr)中启用混合量子-经典程序的捕获机制。

enabled()

返回PennyLane程序表示(plxpr)中混合量子-经典程序的捕获机制是否启用。

create_operator_primitive(operator_type)

创建一个与运算符类型对应的原语。

create_measurement_obs_primitive(...)

创建一个与输入类型对应的原始类型,其中抽象输入是一个运算符。

create_measurement_wires_primitive(...)

创建一个对应于输入类型的原始类型,其中抽象输入是导线。

create_measurement_mcm_primitive(...)

创建一个对应于输入类型的原语,其中抽象输入是经典的中间电路测量结果。

expand_plxpr_transforms(f)

将变换应用于plxpr的函数。

run_autograph(fn)

将给定函数转换为图形形式的装饰器。

make_plxpr(func[, static_argnums, autograph])

接受一个函数并返回一个 Callable,在调用时产生一个表示给定参数的函数的PLxPR。

PlxprInterpreter()

用于定义plxpr解释器的基类。

FlatFn(f[, in_tree])

包装一个函数,以便将输出的pytree形状缓存在out_tree属性中,以便后续可以重新打包结果。

primitives子模块提供了对具有jax依赖关系的对象的便捷访问,如基本操作和抽象类型。它不能通过import pennylane访问,但可以通过手动导入from pennylane.capture.primitives import *访问其内容。

AbstractOperator()

一个运算符被捕获到 plxpr 中。

AbstractMeasurement(抽象评估[, ...])

一个抽象的测量。

adjoint_transform_prim

JAX的Primitive的一个子类,在评估JVPTracers和BatchTracers时表现得像一个Python函数。

cond_prim

JAX的Primitive的一个子类,在评估JVPTracers和BatchTracers时像Python函数一样工作。

ctrl_transform_prim

JAX的Primitive的一个子类,在评估JVPTracers和BatchTracers时表现得像一个Python函数。

for_loop_prim

一个JAX的Primitive子类,当评估JVPTracers和BatchTracers时,表现得像一个Python函数。

qnode_prim

while_loop_prim

JAX的Primitive的一个子类,在评估JVPTracers和BatchTracers时表现得像一个Python函数。

另请参见:

plxpr_to_tape(plxpr, consts, *args[, shots])

将 plxpr 转换为 tape。

要激活和停用新的PennyLane程序捕获机制,请使用开关 qml.capture.enableqml.capture.disable。当前是否正在使用捕获机制可以通过 qml.capture.enabled 查询。默认情况下,机制是禁用的:

>>> import pennylane as qml
>>> qml.capture.enabled()
False
>>> qml.capture.enable()
>>> qml.capture.enabled()
True
>>> qml.capture.disable()
>>> qml.capture.enabled()
False

自定义操作符行为

任何继承自 Operator 的操作符都自动获得被捕获到 Jaxpr 中的能力。任何位置参数都被绑定为一个跟踪器,连接线被处理为单独的跟踪器,任何关键字参数作为关键字元数据传递。

class MyOp1(qml.operation.Operator):

    def __init__(self, arg1, wires, key=None):
        super().__init__(arg1, wires=wires)

def qfunc(a):
    MyOp1(a, wires=(0,1), key="a")

qml.capture.enable()
print(jax.make_jaxpr(qfunc)(0.1))
{ lambda ; a:f32[]. let
    _:AbstractOperator() = MyOp1[key=a n_wires=2] a 0 1
in () }

但是一个操作符开发者可能需要覆盖调用 cls._primitive.bind 的自定义行为(其中 cls 表示类),如果:

在这种情况下,运算符开发者可以重写 cls._primitive_bind_call,它将在构造新类实例时被调用,而不是 type.__call__。例如,

class JustMetadataOp(qml.operation.Operator):

    def __init__(self, metadata):
        super().__init__(wires=[])
        self._metadata = metadata

    @classmethod
    def _primitive_bind_call(cls, metadata):
        return cls._primitive.bind(metadata=metadata)


def qfunc():
    JustMetadataOp("Y")

qml.capture.enable()
print(jax.make_jaxpr(qfunc)())
{ lambda ; . let _:AbstractOperator() = JustMetadataOp[metadata=Y]  in () }

正如您所见,输入 "Y" 在作为位置参数传递时,会在自定义 _primitive_bind_call 方法内转换为元数据。

如果需要,开发者也可以覆盖原始方法的实现,就像对 Controlled 所做的那样。Controlled 需要这样做以处理控制线的打包和解包。

class MyCustomOp(qml.operation.Operator):
    pass

@MyCustomOp._primitive.def_impl
def _(*args, **kwargs):
    return type.__call__(MyCustomOp, *args, **kwargs)