qml.to_bloq

to_bloq(circuit, map_ops=True, custom_mapping=None, call_graph='estimator', **kwargs)[source]

Converts a PennyLane QNode, Qfunc, or Operation to the corresponding Qualtran Bloq.

Note

This class requires the latest version of Qualtran. We recommend installing the latest release via pip:

pip install qualtran
Parameters:
  • circuit (QNode| Qfunc | Operation) – a PennyLane QNode, Qfunc, or operator to be wrapped as a Qualtran Bloq.

  • map_ops (bool) – Whether to map operations to a Qualtran Bloq. Operations are wrapped as a ToBloq when False. Default is True.

  • custom_mapping (dict | None) – Dictionary to specify a mapping between a PennyLane operator and a Qualtran Bloq. A default mapping is used if not defined.

  • call_graph (str) – Specifies how to build the call graph. If 'estimator', the call graph is built using the resource functionality of the estimator module. If 'decomposition', the call graph is built via the PennyLane decomposition. Default is 'estimator'.

Returns:

The Qualtran Bloq that corresponds to the given circuit or Operation and options.

Return type:

Bloq

Raises:

ValueError – If call_graph is not 'estimator' or 'decomposition'.

See also

ToBloq for the Bloq objects created when no Qualtran equivalent is found

Example

This example shows how to use qml.to_bloq:

>>> from qualtran.resource_counting.generalizers import generalize_rotation_angle
>>> op = qml.QuantumPhaseEstimation(
...     qml.RX(0.2, wires=[0]), estimation_wires=[1, 2]
... )
>>> op_as_bloq = qml.to_bloq(op)
>>> graph, sigma = op_as_bloq.call_graph(generalize_rotation_angle)
>>> sigma
{Allocate(dtype=QFxp(bitsize=2, num_frac=2, signed=False), dirty=False): 1,
Hadamard(): 4,
Controlled(subbloq=Rx(angle=0.2, eps=1e-11), ctrl_spec=CtrlSpec(qdtypes=(QBit(),), cvs=(array(1),))): 3,
And(cv1=1, cv2=1, uncompute=True): 1,
And(cv1=1, cv2=1, uncompute=False): 1,
ZPowGate(exponent=\phi, eps=1e-10): 1,
TwoBitSwap(): 1}

Some PennyLane operators don’t have a direct equivalent in Qualtran. For example, in Qualtran, there are many varieties of Quantum Phase Estimation. When qml.to_bloq is called on QuantumPhaseEstimation, a smart default is chosen.

>>> qml.to_bloq(qml.QuantumPhaseEstimation(
...     unitary=qml.RX(0.1, wires=0), estimation_wires=range(1, 5)
... ))
TextbookQPE(unitary=Rx(angle=0.1, eps=1e-11), ctrl_state_prep=RectangularWindowState(bitsize=4), qft_inv=Adjoint(subbloq=QFTTextBook(bitsize=4, with_reverse=True)))

Note that the chosen Qualtran Bloq may not be an exact equivalent. If an exact equivalent is needed, we recommend setting map_ops to False. This will wrap the input PennyLane operator as a Qualtran Bloq, enabling Qualtran functions such as decompose_bloq or call_graph. To toggle between seeing the decompositions from PennyLane or from the estimator module, set call_graph to either 'decomposition' or 'estimator' respectively.

>>> qml.to_bloq(qml.QuantumPhaseEstimation(
...     unitary=qml.RX(0.1, wires=0), estimation_wires=range(1, 5)
... ), map_ops=False)
ToBloq(QuantumPhaseEstimation)

Alternatively, users can provide a custom mapping that maps a PennyLane operator to a specific Qualtran Bloq. It is recommended to map operators at the high level, rather than attempt to map operators that appear in the operator’s decomposition.

>>> from qualtran.bloqs.phase_estimation import TextbookQPE
>>> from qualtran.bloqs.phase_estimation.lp_resource_state import LPResourceState
>>> op = qml.QuantumPhaseEstimation(
...         unitary=qml.RX(0.1, wires=0), estimation_wires=range(1, 5)
...     )
>>> custom_mapping = {
...     op : TextbookQPE(
...         unitary=qml.to_bloq(qml.RX(0.1, wires=0)),
...         ctrl_state_prep=LPResourceState(4),
...     )
... }
>>> qml.to_bloq(op, custom_mapping=custom_mapping)
TextbookQPE(unitary=Rx(angle=0.1, eps=1e-11), ctrl_state_prep=LPResourceState(bitsize=4), qft_inv=Adjoint(subbloq=QFTTextBook(bitsize=4, with_reverse=True)))