-
Notifications
You must be signed in to change notification settings - Fork 51
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
Support arbitrary CtrlSpec
to single qubit control
#1137
Merged
tanujkhattar
merged 15 commits into
quantumlib:main
from
anurudhp:2024/07/12-ctrl-spec-bloq
Jul 17, 2024
Merged
Changes from 11 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
5b91097
CtrlSpec to single-qubit control
anurudhp 420b201
add bloq notebook
anurudhp 8f551ab
more examples
anurudhp a49eef4
mypy, lint
anurudhp 0bf2585
regenerate notebook
anurudhp ef49432
make `bits_to_ints` return `np.uint` (instead of `np.float`)
anurudhp eeef698
add classical sim test
anurudhp fa9bed2
rename to `CtrlSpecAnd`, elaborate constraints in docstring
anurudhp 56f9f1e
Merge branch 'main' into 2024/07/12-ctrl-spec-bloq
anurudhp 927a897
notebook: fix import
anurudhp 0d7c985
Merge branch 'main' into 2024/07/12-ctrl-spec-bloq
anurudhp b5567e1
revert changes to Partition
anurudhp 55d87c4
only support integer types for now (as QFxp classical sim isn't fully…
anurudhp 2c190e1
Merge branch 'main' into 2024/07/12-ctrl-spec-bloq
anurudhp 9acb352
Merge branch 'main' into 2024/07/12-ctrl-spec-bloq
tanujkhattar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"id": "0beec492", | ||
"metadata": { | ||
"cq.autogen": "title_cell" | ||
}, | ||
"source": [ | ||
"# Control Specification (And)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "4d31094e", | ||
"metadata": { | ||
"cq.autogen": "top_imports" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register\n", | ||
"from qualtran import QBit, QInt, QUInt, QAny\n", | ||
"from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma\n", | ||
"from typing import *\n", | ||
"import numpy as np\n", | ||
"import sympy\n", | ||
"import cirq" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "12aba876", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.bloq_doc.md" | ||
}, | ||
"source": [ | ||
"## `CtrlSpecAnd`\n", | ||
"Computes a single qubit which is `1` iff the CtrlSpec of And clauses is satisfied.\n", | ||
"\n", | ||
"This reduces an arbitrary 'And' clause control spec to a single qubit, which can be used\n", | ||
"to then control a bloq. Therefore, a bloq author is only required to implement a\n", | ||
"single-controlled version of their bloq, and can be generalized to arbitrary controls.\n", | ||
"\n", | ||
"The control registers are passed through as-is. If the same control bit is required for\n", | ||
"multiple bloqs, the user can use the `target` qubit of this bloq multiple times, and only\n", | ||
"uncompute at the very end. For more custom strategies and trade-offs, see Ref. [1].\n", | ||
"\n", | ||
".. note::\n", | ||
"\n", | ||
" This only applies to CtrlSpec being a logical AND of all registers, and each register\n", | ||
" being equal to a constant. See documentation for :class:`CtrlSpec` for more details.\n", | ||
"\n", | ||
"#### Parameters\n", | ||
" - `ctrl_spec`: The control specification. \n", | ||
"\n", | ||
"#### Registers\n", | ||
" - `ctrl_i`: The control register for the i-th ctrl dtype in the `ctrl_spec`.\n", | ||
" - `junk [right]`: `ctrl_spec.num_qubits - 2` qubits that can be cleaned up by the inverse. Only present if the above size is non-zero.\n", | ||
" - `target [right]`: The output bit storing the result of the `ctrl_spec`. \n", | ||
"\n", | ||
"#### References\n", | ||
" - [Unqomp: synthesizing uncomputation in Quantum circuits](https://dl.acm.org/doi/10.1145/3453483.3454040). Paradis et. al. 2021.\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "842307af", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.bloq_doc.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.bloqs.mcmt import CtrlSpecAnd" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "76f2965f", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.example_instances.md" | ||
}, | ||
"source": [ | ||
"### Example Instances" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "68a43214", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.ctrl_on_int" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran import CtrlSpec, QUInt\n", | ||
"\n", | ||
"ctrl_on_int = CtrlSpecAnd(CtrlSpec(qdtypes=QUInt(4), cvs=[0b0101]))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "945fa4a4", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.ctrl_on_bits" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran import CtrlSpec, QBit\n", | ||
"\n", | ||
"ctrl_on_bits = CtrlSpecAnd(CtrlSpec(qdtypes=QBit(), cvs=[0, 1, 0, 1]))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "5e6374b2", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.ctrl_on_nd_bits" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"import numpy as np\n", | ||
"\n", | ||
"from qualtran import CtrlSpec, QBit\n", | ||
"\n", | ||
"ctrl_on_nd_bits = CtrlSpecAnd(CtrlSpec(qdtypes=QBit(), cvs=np.array([[0, 1], [1, 0]])))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "2047fccf", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.ctrl_on_multiple_values" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran import CtrlSpec, QInt, QUInt\n", | ||
"\n", | ||
"ctrl_on_multiple_values = CtrlSpecAnd(\n", | ||
" CtrlSpec(qdtypes=(QUInt(4), QInt(4)), cvs=([0b0101, 0b1100], [2, -2]))\n", | ||
")" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "55581cc0", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.graphical_signature.md" | ||
}, | ||
"source": [ | ||
"#### Graphical Signature" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "5ea9e6e5", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.graphical_signature.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.drawing import show_bloqs\n", | ||
"show_bloqs([ctrl_on_int, ctrl_on_bits, ctrl_on_nd_bits, ctrl_on_multiple_values],\n", | ||
" ['`ctrl_on_int`', '`ctrl_on_bits`', '`ctrl_on_nd_bits`', '`ctrl_on_multiple_values`'])" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"id": "3f5bb7d6", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.call_graph.md" | ||
}, | ||
"source": [ | ||
"### Call Graph" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"id": "f83e1715", | ||
"metadata": { | ||
"cq.autogen": "CtrlSpecAnd.call_graph.py" | ||
}, | ||
"outputs": [], | ||
"source": [ | ||
"from qualtran.resource_counting.generalizers import ignore_split_join\n", | ||
"ctrl_on_int_g, ctrl_on_int_sigma = ctrl_on_int.call_graph(max_depth=1, generalizer=ignore_split_join)\n", | ||
"show_call_graph(ctrl_on_int_g)\n", | ||
"show_counts_sigma(ctrl_on_int_sigma)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"name": "python" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 5 | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why this change? Also, why this change only in the
_classical_unpartition
and not in_classical_partition
? Was the previous logic wrong for certain cases? Can you please add tests which pass with the new version and fail with the original one?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'm using this to convert the
cvs
to bits inCtrlSpecAnd
which allows any dtype. But the current classical simulation protocol only supports integer values inClassicalValT
, so seems like it worked either way.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.
Also
bits_to_ints
/ints_to_bits
are faster than manually callingto_bits
/from_bits
on each element. (similar to #1072). So only changed the part I'm using for now.We should port
ints_to_bits
andbits_to_ints
intoQDType
: #811There 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.
Sorry, I don't understand. What was the part which was failing earlier and now gets fixed? I presume even now,
CtrlSpecAnd
would support onlyQUInt
,QInt
andQAny
types (or, types for whichbits_to_ints
works correctly) since the classical bits need to be partitioned correctly (right now, partitioning is still based onbits_to_ints
but unpartitioning usesdtype.to_bits()
) ?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.
CtrlSpecAnd
also works forQFxp
as it's just bitwise equalityThere 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.
The decomposition of
CtrlSpecAnd
isunpartition -> MultiAnd -> partition
. ForQFxp
, you had to updateunpartition
to correctly convert aQFxp
object to bits; and you are suggesting that you don't need to updatepartition
? The partition needs to correctly combine the bits such that the result is aQFxp
object. That would not happen right now and you would get an incorrect result.Can you add a test for
QFxp
and try to figure out why it's working (if it's working) because technically it shouldn'tThere 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'm using this only for extracting the classical control bits in
CtrlSpecAnd
(i.e._flat_cvs
), so I never merge these bits back to get the constants.But this would break the classical simulator, but as the classical sim only supports ints now, we don't have any tests that use Fxp.
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 think for now, it's better to say that
CtrlSpecAnd
does not supportQFxp
, because in reality it does not. The decomposition would be incorrect becausePartition
andUnpartition
doesn't supportQFxp
. So it's fine to fail early at_flat_cvs
instead of having a wrong decomposition.The alternative would be to compute the
_flat_cvs
without invokingPartition
so that the computation of_flat_cvs
works for all data types and updatePartition
bloq for_classical_unpartition
and_classical_partition
whenever we are ready to do so.The current logic leaves the state of things in a complicatedly broken way where one direction works (maybe) but the other doesn't.
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 reverted these changes. For now CtrlSpecAnd only supports integer types (checked in post_init).
Will add more support after the classical sim for QFxp is merged.