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

Create linear half comparison bloqs #1408

Merged
merged 17 commits into from
Oct 18, 2024

Conversation

NoureldinYosri
Copy link
Contributor

This PR creates all versions of half a comparison operation in $n$ toffoli complexity. The uncomputation of these bloqs has zero cost.

The half comparason operation is needed in the modular inversion bloq.

I also modify the OutOfPlaceAdder to allow it to not compute the extra And when it's not needed


This PR also shows how we can implement all versions of comparison by implementing just one. for example creating a half greater than bloq that use logarithmic depth is enough to implement all the others.

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.

some things are missing docs. Can you simplify some of the complicated inheritance by introducing one or more "has a" relationships instead of relying on "is a"


@cached_property
@abc.abstractmethod
def _half_greater_than_bloq(self) -> Bloq:
Copy link
Collaborator

Choose a reason for hiding this comment

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

why can't this just be an attribute of _HalfComparison[Base]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it will differ between different falvours ... the ones I'm implementing here have linear depth and linear complexity, this is why their names start with LinearDepth.... There is another variant with log depth but nlog complexity which we might want to add later (we already have one instance of it in LessThanEqual)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Got it. For these sorts of things (for future reference) I find it useful to follow the "YAGNI" principle. You can design your abstractions to be easily refactorable when (and only when) you want to support a new configuration. Otherwise the levels of indirection can fester. As a concrete example: when I implemented CtrlSpec I developed it as an AbstractCtrlSpec and a concrete CtrlSpec with the idea that you might want different types of control (other than and-ing bits and ints). But since there was only one implementation, I squished the hierarchy.

Anyways: please provide docstrings for these classes that tell the reader how they're supposed to interact.

e.g.: "_HalfLinearDepthGreaterThan: The actual (half-)circuit for doing greater than. This can be returned by the _HalfComparisonBase._half_greater_than_bloq abstract property"

"_HalfComparisonBase: an adapter to support all comparison ops given one comparison (half-)circuit implmentation. Used to support the LinearDepthHalf{GreaterThan, LessThan, GE, LTE} public bloqs"

You should probably include the note that one could also support LogDepth. I don't know where the best place to put that note would be.

References:
[Halving the cost of quantum addition](https://arxiv.org/abs/1709.06648).
"""
comparison_dtype: str = attrs.field(default='>', init=False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure this is how we want to do this sort of inheritance. It's a little confusing. And presumably this attribute will show up in the repr and when you tab complete on available attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

how is this different from the ZeroState bloq? both set the value of a property of a base class and hide it

Copy link
Collaborator

Choose a reason for hiding this comment

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

well at the time of my comment it wasn't hidden. There's also the secondary level of indirection where the halfcomparisonbase delegates to another class.

Copy link
Collaborator

Choose a reason for hiding this comment

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

but looks good now

@mpharrigan
Copy link
Collaborator

See ZeroState(_ZVector) for an example of how to specialize a private base implementation

@mpharrigan
Copy link
Collaborator

@NoureldinYosri any updates here?

Copy link
Contributor Author

@NoureldinYosri NoureldinYosri left a comment

Choose a reason for hiding this comment

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

@mpharrigan ptal.

as for the ZeroState example. I don't see how it and this implementation differ?


@cached_property
@abc.abstractmethod
def _half_greater_than_bloq(self) -> Bloq:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

it will differ between different falvours ... the ones I'm implementing here have linear depth and linear complexity, this is why their names start with LinearDepth.... There is another variant with log depth but nlog complexity which we might want to add later (we already have one instance of it in LessThanEqual)

References:
[Halving the cost of quantum addition](https://arxiv.org/abs/1709.06648).
"""
comparison_dtype: str = attrs.field(default='>', init=False)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

how is this different from the ZeroState bloq? both set the value of a property of a base class and hide it

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.

Can you provide a short description of the interplay between the private classes in docstrings (see my comments); and a couple small nits. Thanks!!


@cached_property
@abc.abstractmethod
def _half_greater_than_bloq(self) -> Bloq:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Got it. For these sorts of things (for future reference) I find it useful to follow the "YAGNI" principle. You can design your abstractions to be easily refactorable when (and only when) you want to support a new configuration. Otherwise the levels of indirection can fester. As a concrete example: when I implemented CtrlSpec I developed it as an AbstractCtrlSpec and a concrete CtrlSpec with the idea that you might want different types of control (other than and-ing bits and ints). But since there was only one implementation, I squished the hierarchy.

Anyways: please provide docstrings for these classes that tell the reader how they're supposed to interact.

e.g.: "_HalfLinearDepthGreaterThan: The actual (half-)circuit for doing greater than. This can be returned by the _HalfComparisonBase._half_greater_than_bloq abstract property"

"_HalfComparisonBase: an adapter to support all comparison ops given one comparison (half-)circuit implmentation. Used to support the LinearDepthHalf{GreaterThan, LessThan, GE, LTE} public bloqs"

You should probably include the note that one could also support LogDepth. I don't know where the best place to put that note would be.

References:
[Halving the cost of quantum addition](https://arxiv.org/abs/1709.06648).
"""
comparison_dtype: str = attrs.field(default='>', init=False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

well at the time of my comment it wasn't hidden. There's also the secondary level of indirection where the halfcomparisonbase delegates to another class.

@NoureldinYosri NoureldinYosri enabled auto-merge (squash) October 18, 2024 22:44
@NoureldinYosri NoureldinYosri merged commit 7344830 into quantumlib:main Oct 18, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants