-
Notifications
You must be signed in to change notification settings - Fork 50
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
Permutation Bloq #1110
Conversation
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inverted the method.
use `x` instead of `q` invert code in `build_call_graph` add note for neg-ctrl CNOT
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM % comments
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)} |
There was a problem hiding this comment.
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:
- Num controls == 0 : Simply do an XGate()
- Num controls == 1 : Simply do CNOT() gates
- 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.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
dtype: QDType | ||
k: SymbolicInt |
There was a problem hiding this comment.
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.
@cached_property | ||
def bitsize(self): | ||
return bit_length(self.N - 1) |
There was a problem hiding this comment.
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.
Decomposes a permutation into cycles and applies them in order. | ||
See :meth:`from_dense_permutation` to construct this bloq from a permutation. |
There was a problem hiding this comment.
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.
and for every $x \not\in C$. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this incomplete?
LGTM! |
Implements a simple circuit that permutes basis states in
O(N logN)
, andO(d logN)
for a d-prefix (used to prepare d-sparse states).