qml.estimator.wires_manager.Deallocate

class Deallocate(num_wires)[source]

Bases: _WireAction

Allows freeing any_state work wires through WireResourceManager.

Parameters:

num_wires (int) – number of any_state work wires to be freed.

The Deallocate class is typically used within a decomposition function to track the allocation of auxiliary wires. This allows to accurately determine the wire overhead of a circuit. In this example, we show the decomposition for a 3-controlled X gate, which requires one work wire that is returned in a zeroed state.

First, we define a custom decomposition which allocates the work wire but doesn’t free it.

>>> from pennylane import estimator as qre
>>> from pennylane.estimator import GateCount, resource_rep
>>> def resource_decomp(num_ctrl_wires=3, num_ctrl_values=0, **kwargs):
...     gate_list = []
...     gate_list.append(qre.Allocate(num_wires=1))
...
...     gate_list.append(GateCount(resource_rep(qre.TempAND), 1))
...     gate_list.append(GateCount(resource_rep(qre.Adjoint, {"base_cmpr_op": resource_rep(qre.TempAND)}), 1))
...     gate_list.append(GateCount(resource_rep(qre.Toffoli), 1))
...
...     return gate_list
>>> config = qre.ResourceConfig()
>>> config.set_decomp(qre.MultiControlledX, resource_decomp)
>>> res = qre.estimate(qre.MultiControlledX(3, 0), config)
>>> print(res.WireResourceManager)
WireResourceManager(zeroed wires=0, any_state wires=1, algorithmic wires=4, tight budget=False)

This decomposition uses a total of 4 algorithmic wires and 1 work wire which is returned in an arbitrary state.

We can free this wire using Deallocate, allowing it to be reused with more operations. The decomposition can be redefined as:

>>> from pennylane import estimator as qre
>>> from pennylane.estimator import GateCount, resource_rep
>>> def resource_decomp():
...     gate_list = []
...     gate_list.append(qre.Allocate(num_wires=1))
...
...     gate_list.append(GateCount(resource_rep(qre.TempAND), 1))
...     gate_list.append(GateCount(resource_rep(qre.Adjoint, {"base_cmpr_op": resource_rep(qre.TempAND)}), 1))
...     gate_list.append(GateCount(resource_rep(qre.Toffoli), 1))
...
...     gate_list.append(Deallocate(num_wires=1))
...     return gate_list
>>> config = qre.ResourceConfig()
>>> config.set_decomp(qre.MultiControlledX, resource_decomp)
>>> res = qre.estimate(qre.MultiControlledX(3, 0), config)
>>> print(res.WireResourceManager)
WireResourceManager(zeroed wires=1, any_state wires=0, algorithmic wires=4, tight budget=False)

Now, the auxiliary wire is freed and is returned in the zeroed state after the decomposition, and can be used for other operators which require zeroed auxiliary wires.