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

Fix custom controlled versions of SelectOracles and QubitizationWalkOperators #904

Merged
merged 11 commits into from
May 9, 2024

Conversation

anurudhp
Copy link
Contributor

@anurudhp anurudhp commented Apr 28, 2024

On top of #903

fixes #886

@anurudhp anurudhp force-pushed the 2024-04-fix-custom-controlled branch 2 times, most recently from ecb0d82 to 308b60e Compare May 2, 2024 20:57
def get_ctrl_system(
self, ctrl_spec: Optional['CtrlSpec'] = None
) -> Tuple['Bloq', 'AddControlledT']:
from qualtran._infra.gate_with_registers import get_ctrl_system_for_single_qubit_controlled
Copy link
Collaborator

@fdmalone fdmalone May 6, 2024

Choose a reason for hiding this comment

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

Why is the import happening inside the function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, this should be at top level.

I haven't yet decided if this is the proper way to implement this. Somehow the control_val interface is a bit ad-hoc and can't be type-checked properly. I'm open to suggestions for this interface.

with an API that has `control_val` and `control_registers`.
Add the `get_ctrl_system` implementation as shown below:

.. code:: python
Copy link
Collaborator

Choose a reason for hiding this comment

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

we actually render all this as markdown, so this directive won't work properly. I think the indented section should be rendered as code; you might need backticks if you want to say "python"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops, fixed now

"""Wrapper to correctly wire a custom implementation of a single-qubit controlled version of a gate.

For any gate that supports a single-qubit controlled version
with an API that has `control_val` and `control_registers`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

can you be more specific than "with an api that has..."

I think you require that the bloq has attributes named control_val and control_registers, right? Does this need to be a GateWithRegisters like the annotation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

updated the design to use a mixin class


if bloq.control_val is None and ctrl_spec.shapes in [((),), ((1,),)]:
cbloq = attrs.evolve(bloq, control_val=int(ctrl_spec.cvs[0].item()))
(ctrl_reg,) = cbloq.control_registers
Copy link
Collaborator

Choose a reason for hiding this comment

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

so this assumes that control_registers is actually a property that depends on the control_val attribute, right? please document and/or code this more defensively

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added a check that raises TypeError

Copy link
Collaborator

@mpharrigan mpharrigan left a comment

Choose a reason for hiding this comment

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

This is a good idea. The current PR needs a little polish

Comment on lines 579 to 580
assert hasattr(bloq, 'control_val')
assert hasattr(bloq, 'control_registers')
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know if this is a better or worse idea, but: did you consider making this a mixin?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this does make the code cleaner, and enables type-checking. I made a class SpecializedSingleQubitControlledGate (similar to the design of UnaryIterationGate), please have a look

@anurudhp anurudhp force-pushed the 2024-04-fix-custom-controlled branch from d0731d0 to f14990d Compare May 7, 2024 15:17
@anurudhp anurudhp requested a review from mpharrigan May 7, 2024 19:11
@anurudhp anurudhp force-pushed the 2024-04-fix-custom-controlled branch from 0148f42 to 3f0855f Compare May 8, 2024 17:00
Copy link
Collaborator

@mpharrigan mpharrigan left a comment

Choose a reason for hiding this comment

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

cool

@mpharrigan
Copy link
Collaborator

@dstrain115 can you advise on how to fix the type issues

@dstrain115
Copy link
Contributor

I think you can add "#type: ignore" to all of them. The first is because it doesn't know whether it is an attrs class, so it can't attrs.evolve it.

The others are because qualtran and cirq disagree on the definition of "controlled" and the classes inherit from both. The current order should prefer Qualtran's definition to cirq's which seems fine to me.

@anurudhp
Copy link
Contributor Author

anurudhp commented May 8, 2024

The others are because qualtran and cirq disagree on the definition of "controlled" and the classes inherit from both. The current order should prefer Qualtran's definition to cirq's which seems fine to me.

I added type: ignore to the class definition line. It's strange that the issue does not show up in GateWithRegisters, but only here. For example:

class SpecializedSingleQubitControlledGate(GateWithRegisters):
  ...

class QubitizationWalkOperator(SpecializedSingleQubitControlledGate, GateWithRegisters): # <- type check fails here
  ...

Example usage:

@attrs.frozen
class MyGate(SpecializedSingleQubitControlledGate, GateWithRegisters):
Copy link
Collaborator

Choose a reason for hiding this comment

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

SpecializedSingleQubitControlledGate already derives from GateWithRegisters so we don't need both the classes in the list. If you want to make it a mixin, you shouldn't derive from GateWithRegisters here; or keep it as is and do not include GateWithRegisters as a parent class in bloqs that derive from SpecializedSingleQubitControlledGate

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed - used the second suggestion

@dstrain115
Copy link
Contributor

I'm not totally sure. It's something with the multiple inheritance and the function definitions not matching.

@mpharrigan mpharrigan enabled auto-merge (squash) May 9, 2024 17:29
@mpharrigan mpharrigan merged commit 1b8b449 into quantumlib:main May 9, 2024
7 checks passed
@anurudhp anurudhp deleted the 2024-04-fix-custom-controlled branch May 9, 2024 18:01
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.

Should not override .controlled for custom controlled implementations
5 participants