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

Permutation Bloq #1110

Merged
merged 18 commits into from
Jul 17, 2024
Merged

Conversation

anurudhp
Copy link
Contributor

@anurudhp anurudhp commented Jul 4, 2024

Implements a simple circuit that permutes basis states in O(N logN), and O(d logN) for a d-prefix (used to prepare d-sparse states).

Comment on lines 969 to 973
if self.val == 0:
x = bb.add(XGate(), q=x)
x, target = bb.add(CNOT(), ctrl=x, target=target)
if self.val == 0:
x = bb.add(XGate(), q=x)
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 add a note that this is just a negative-control CNOT so that in the future, if and when we add a cv attribute to CNOT we can replace it

bloq_counts[CNOT()] += 1
return set(bloq_counts.items())

return super().build_call_graph(ssa)
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: I generally prefer inverting this so the method isn't as indented

if not self.is_symbolic():
  return super().build_call_graph

op = ...
return bloq_counts

That being said --- my original design for the call graph protocol was always to provide the counts you'd expect to find in e.g. a paper, which would use the is_symbolic path even for concrete numbers. Then you can reconcile them in e.g. the unit test by using the generalizer argument and built-in generalizer functions. Maybe I'll open an issue because I know this sort of thing has come up in other places

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Inverted the method.

anurudhp and others added 2 commits July 8, 2024 16:13
use `x` instead of `q`
invert code in `build_call_graph`
add note for neg-ctrl CNOT
Copy link
Collaborator

@tanujkhattar tanujkhattar left a comment

Choose a reason for hiding this comment

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

LGTM % comments

Comment on lines 416 to 418
bit_flip_bloq = MultiControlX(cvs=self.cvs) if len(self.cvs) > 0 else XGate()
num_flips = self.bitsize if self.is_symbolic() else sum(self.dtype.to_bits(self.k))
return {(bit_flip_bloq, num_flips)}
Copy link
Collaborator

Choose a reason for hiding this comment

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

We shouldn't do n MCX gates to do n bit flips when number of controls > 1

Instead, divide it into 3 cases:

  1. Num controls == 0 : Simply do an XGate()
  2. Num controls == 1 : Simply do CNOT() gates
  3. Num controls > 1 : Use a temporary ancilla and do a MultiAnd(cvs=self.cvs) with the temporary ancilla as the target. Then reduce to Case(2) with the temporary ancilla as control.

Copy link
Collaborator

Choose a reason for hiding this comment

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

In fact, I'd suggest we only support Case (1) and (2) and reducing Case (3) to Case (1) is a general strategy used for all multi controlled bloq so we can add a separate Bloq that does this reduction (maybe at a later point)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I simplified this to only support a single control_val, as #1131 will handle the CtrlSpec -> QBit part.

qualtran/bloqs/arithmetic/addition.py Outdated Show resolved Hide resolved
Comment on lines 378 to 379
dtype: QDType
k: SymbolicInt
Copy link
Collaborator

Choose a reason for hiding this comment

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

If k is a SymbolicInt should we restrict dtype to be QUInt / QInt ? Looking at the implementation below, it seems like this would also work for other types when k is not necessarily an integer.

qualtran/bloqs/arithmetic/comparison.py Outdated Show resolved Hide resolved
qualtran/bloqs/arithmetic/comparison.py Outdated Show resolved Hide resolved
qualtran/bloqs/arithmetic/permutation.py Show resolved Hide resolved
Comment on lines +89 to +91
@cached_property
def bitsize(self):
return bit_length(self.N - 1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Will there ever be a case when the user wants to specify the bitsize instead of the default log2(N) ? We can make it an attribute and use this as a default value if the user doesn't specify anything; if you think that's relevant.

Comment on lines 153 to 154
Decomposes a permutation into cycles and applies them in order.
See :meth:`from_dense_permutation` to construct this bloq from a permutation.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ditto: Please add a latex equation describing the action of the unitary on an input state.

qualtran/bloqs/arithmetic/permutation.py Outdated Show resolved Hide resolved
Comment on lines +82 to +83
and for every $x \not\in C$.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this incomplete?

@tanujkhattar
Copy link
Collaborator

LGTM!

@tanujkhattar tanujkhattar merged commit d807b72 into quantumlib:main Jul 17, 2024
7 checks passed
@anurudhp anurudhp deleted the 2024-06-permutation-bloq branch July 17, 2024 16:06
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.

3 participants