Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qualtran-pl interoperability #6921

Open
wants to merge 41 commits into
base: master
Choose a base branch
from
Open

Qualtran-pl interoperability #6921

wants to merge 41 commits into from

Conversation

austingmhuang
Copy link
Contributor

@austingmhuang austingmhuang commented Feb 4, 2025

Context:
Qᴜᴀʟᴛʀᴀɴ (quantum algorithms translator) contains a set of abstractions for representing quantum programs and a library of quantum algorithms expressed in that language. It is useful for resource estimation and researchers have expressed interest in its usage but don't have a direct path to make whatever is in qualtran executable on a PL device. (On the other way around, PL users at times want to leverage qualtran's resource counting methods but don't have a convenient solution at hand -- we don't implement this in this PR.) We first implement the Qualtran->PL direction, but leave room for the reverse as well. We also need to pip install from our fork/branch that implements the as_pl_op() functions for various bloqs. (https://github.com/PennyLaneAI/Qualtran-PL/tree/bloq_to_op)

Description of the Change:
This PR implements the adapter class that allows PL users to use Qualtran bloqs as PL operations.

Benefits:
Qualtran-native users can easily export their bloqs/composite bloqs into executable circuits that benefit from PL features. Pennylane-native users can import Qualtran bloqs that may be useful to their workflows.

Possible Drawbacks:
Autodiff might not be well-supported. We might also have trouble with certain edge case bloqs (e.g. bookkeeping bloqs).

Related GitHub Issues:
[sc-81998] [sc-84160]

Code block (for now):

# Composite Bloq & BloqBuilder ~ PL Templates and Circuits:
from qualtran import BloqBuilder
from qualtran.bloqs.basic_gates import XGate, Swap, Ry, YGate, ZGate, Rx, TwoBitSwap, Hadamard, CNOT, Toffoli
from qualtran import Bloq, CompositeBloq

bb = BloqBuilder()  # bb is the circuit like object

w1 = bb.add_register('wire1', 1)
w2 = bb.add_register('wire2', 1)
aux = bb.add_register('aux_wires', 2)  # add wires

aux_wires = bb.split(aux)

w1 = bb.add(Hadamard(), q=w1)
w2 = bb.add(Hadamard(), q=w2)

w1, aux1 = bb.add(CNOT(), ctrl=w1, target=aux_wires[0])
w2, aux2 = bb.add(CNOT(), ctrl=w2, target=aux_wires[1])

ctrl_aux, w1 = bb.add(Toffoli(), ctrl=(aux1, aux2), target=w1)
ctrl_aux, w2 = bb.add(Toffoli(), ctrl=ctrl_aux, target=w2)
aux_wires = bb.join(ctrl_aux)

circuit_bloq = bb.finalize(wire1=w1, wire2=w2, aux_wires=aux_wires)

import pennylane as qml

dev = qml.device("default.qubit")

@qml.qnode(dev)
def foo():
    qml.FromBloq(circuit_bloq, wires=4) # this `wires` is not right; right now we internally determine the wires.
    return qml.expval(qml.Z(wires=0))

foo()

Copy link
Contributor

github-actions bot commented Feb 4, 2025

Hello. You may have forgotten to update the changelog!
Please edit doc/releases/changelog-dev.md with:

  • A one-to-two sentence description of the change. You may include a small working example for new features.
  • A link back to this PR.
  • Your name (or GitHub username) in the contributors section.

@DSGuala DSGuala self-requested a review February 4, 2025 18:48
def __repr__(self):
return f'FromBloq({self._hyperparameters["bloq"]})'

def compute_decomposition(self, wires, **kwargs): # pylint: disable=arguments-differ

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks reasonable to me after a quick skim 👌

@austingmhuang austingmhuang marked this pull request as ready for review February 24, 2025 14:26
Comment on lines +51 to +52
>>> qml.get_bloq_registers_info(Swap(3))
{'x': Wires([0, 1, 2]), 'y': Wires([3, 4, 5])}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit confusing but what does bitsize=3 in this case? Do we get a SWAP on three wires?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Bloq Swap basically swaps N bit registers. So in this case you would get qml.SWAP([0, 3]), qml.SWAP([1. 4]), qml.SWAP([2, 5])

Maybe SWAP is not the best example since the qualtran Swap is different from the QML Swap.

Comment on lines +75 to +76
r"""
A shim for using bloqs as a PennyLane operation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to use an adapter instead of a shim -

Suggested change
r"""
A shim for using bloqs as a PennyLane operation.
r"""An adapter for using Qualtran [bloqs](https://qualtran.readthedocs.io/en/latest/bloqs/index.html) as a PennyLane operation.

@austingmhuang austingmhuang changed the title [WIP] Qualtran-pl interoperability Qualtran-pl interoperability Feb 25, 2025
]
assert qml.FromBloq(cbloq, wires=range(24)).decomposition() == expected

def test_composite_bloq(self):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider adding a test that compares the unitary matrices

  • derived using Bloq.tensor_contract()
  • derived using FromBloq(b).matrix()
  • reference

using a non-atomic bloq b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants