qml.排队¶
概述¶
警告
除非您是PennyLane开发者,否则您可能不需要直接使用这些类。
该模块包含用于将对象放入队列的类。
描述¶
用户提供 量子函数,PennyLane 需要将其转换为能够被设备执行的电路表示。量子函数是任何可调用的内容:
接受经典输入
构造任意数量的量子
Operator对象返回一个或多个
MeasurementProcess对象。
例如:
def qfunc(x, scale_value=1):
qml.RX(x * scale_value, wires=0)
if (1 != 2):
qml.S(0)
return qml.expval(qml.Z(0)), qml.expval(qml.X(1))
要将量子函数转换为电路的表示,我们使用排队。
一个 可排队对象 是任何可以放入队列中的东西。这些将是 Operator,
MeasurementProcess 和 QuantumTape 对象。 Operator 和
MeasurementProcess 对象通过构造时调用的 queue() 方法实现排队。
请注意,尽管 QuantumTape 是一个可排队对象,但它没有 queue 方法。
当一个对象被排队时,它将自身发送到 QueuingManager。 QueuingManager 是一个全局单例类,用于方便地将对象放入队列。所有 QueuingManager 的方法和属性都是类方法和属性,因此所有实例将访问相同的信息。
active_context() 是放置任何新对象的队列。QueuingManager 如果存在活动上下文,则被称为记录中。
活动上下文是 AnnotatedQueue 实例。它们是 上下文管理器,录制发生在 with 块内。
让我们看一个例子。如果我们在AnnotatedQueue的上下文之外查询QueuingManager,我们会发现没有任何记录,且不存在活动上下文。
>>> print("Are we recording? ", qml.QueuingManager.recording())
Are we recording? False
>>> print("What's the active context? ", qml.QueuingManager.active_context())
What's the active context? None
在一个上下文中,我们可以看到活动的记录上下文:
>>> with qml.queuing.AnnotatedQueue() as q:
... print("Are we recording? ", qml.QueuingManager.recording())
... print("Is q the active queue? ", q is qml.QueuingManager.active_context())
Are we recording? True
Is q the active queue? True
如果我们有嵌套的 AnnotatedQueue 上下文,只有最内层的一个会进行记录。 一旦当前活动的队列退出,任何外层队列将恢复记录。
>>> with qml.queuing.AnnotatedQueue() as q1:
... print("Is q1 recording? ", q1 is qml.QueuingManager.active_context())
... with qml.queuing.AnnotatedQueue() as q2:
... print("Is q1 recording? ", q1 is qml.QueuingManager.active_context())
... print("Is q1 recording? ", q1 is qml.QueuingManager.active_context())
Is q1 recording? True
Is q1 recording? False
Is q1 recording? True
如果我们在录制上下文中构造一个算子,我们可以看到它被添加到队列中:
>>> with qml.queuing.AnnotatedQueue() as q:
... op = qml.X(0)
>>> q.queue
[X(0)]
如果一个运算符是在上下文之外构造的,我们可以通过调用queue()方法手动将其添加到队列中。queue()方法在初始化时会自动调用,但也可以在稍后的时间手动调用。
>>> op = qml.X(0)
>>> with qml.queuing.AnnotatedQueue() as q:
... op.queue()
>>> q.queue
[X(0)]
一个对象在队列中只能存在一次,因此多次调用队列将不会产生任何效果。
>>> op = qml.X(0)
>>> with qml.queuing.AnnotatedQueue() as q:
... op.queue()
... op.queue()
>>> q.queue
[X(0)]
这个 apply() 方法允许将单个对象多次排队到电路中。 如果该对象已经在队列中,函数会排队一个原始对象的副本。
>>> op = qml.X(0)
>>> with qml.queuing.AnnotatedQueue() as q:
... qml.apply(op)
... qml.apply(op)
>>> q.queue
[X(0), X(0)]
>>> q.queue[0] is q.queue[1]
False
在由其他运算符组成的运算符的情况下,比如SymbolicOp和CompositeOp,新的嵌套操作会从队列中移除其组成部分。只会保留最终将进入电路的运算符。
>>> with qml.queuing.AnnotatedQueue() as q:
... base = qml.X(0)
... print(q.queue)
... pow_op = base ** 1.5
... print(q.queue)
[X(0)]
[X(0)**1.5]
一旦队列构建完成,process_queue() 函数将其转换为最终电路中的操作和测量。这个步骤消除了任何有所有者的对象。
>>> with qml.queuing.AnnotatedQueue() as q:
... qml.StatePrep(np.array([1.0, 0]), wires=0)
... base = qml.X(0)
... pow_op = base ** 1.5
... qml.expval(qml.Z(0) @ qml.X(1))
>>> ops, measurements = qml.queuing.process_queue(q)
>>> ops
[StatePrep(tensor([1., 0.], requires_grad=True), wires=[0]), X(0)**1.5]
>>> measurements
[expval(Z(0) @ X(1))]
这些列表可以用来构建一个 QuantumScript:
>>> qml.tape.QuantumScript(ops, measurements)
<QuantumScript: wires=[0, 1], params=1>
为了在录制中构造新的操作符,但不将其排队,请在构造时使用stop_recording()上下文:
>>> with qml.queuing.AnnotatedQueue() as q:
... with qml.QueuingManager.stop_recording():
... qml.Y(1)
>>> q.queue
[]
函数¶
|
将已实例化的算子或测量应用于排队上下文。 |
|
处理标注的队列,创建量子操作和测量过程的列表。 |
类¶
轻量级类,除了元数据注释之外,还维护基本的操作队列。 |
|
当出现排队错误时引发的异常 |
|
管理活动录音上下文的单例全局入口点。 |
|
|
包装一个对象,使其哈希值依赖于其身份 |