-
Notifications
You must be signed in to change notification settings - Fork 44
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
SelectSwapQROM
revamp and upgrades
#986
Conversation
…ire_symbol_to_cirq_diagram_info
|
||
@cirq.value_equality(distinct_child_types=True) | ||
@attrs.frozen | ||
class QROMABC(abc.ABC): |
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.
QROMInterface or something else, I'm not mad on ABC
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.
BaseQROM or _BaseQROM or QROMBase
@cirq.value_equality(distinct_child_types=True) | ||
@attrs.frozen | ||
class QROMABC(abc.ABC): | ||
r"""Bloq to load `data[l]` in the target register when the selection stores an index `l`. |
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.
See #988 for including the abstract base class docs in a notebook somewhere.
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.
done
|d_L[s_1, s_2, \dots, s_k]\rangle | ||
$$ | ||
|
||
There two high level parameters that control the behavior of a QROM are - |
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: There -> The
|
||
There two high level parameters that control the behavior of a QROM are - | ||
|
||
1. Shape of the classical dataset to be loaded ($\text{data.shape} = (S_1, S_2, ..., S_K)$). |
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: The shape, The number
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: datasets
to build the QROM. | ||
|
||
### Shape of the classical dataset to be loaded. | ||
QROM bloq supports loading multidimensional classical datasets. In order to load a data |
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.
Not The or A
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 clarify?
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 not sure anymore lol. I think it's was meant to be nit: The (or A) QROM bloq supports...
registers with bitsizes $(p, q, r, s)$ where | ||
$p,q,r,s=\log_2{P}, \log_2{Q}, \log_2{R}, \log_2{S}$. | ||
|
||
In general, to load K dimensional data, we use K named selection registers `(selection0, |
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:
|
||
If you have multiple classical datasets `(data_1, data_2, data_3, ..., data_L)` to be loaded | ||
and each of them has the same shape `(data_1.shape == data_2.shape == ... == data_L.shape)` | ||
and different target bitsizes `(b_1, b_2, ..., b_L)`, then one construct a single classical |
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: constructs
- `data.shape == data_1.shape == data_2.shape == ... == data_L` and | ||
- `data[idx] = f'{data_1[idx]!0{b_1}b}' + f'{data_2[idx]!0{b_2}b}' + ... + f'{data_L[idx]!0{b_L}b}'` | ||
|
||
Thus, the target bitsize of the merged dataset is $b = b_1 + b_2 + \dots + b_L$ and clifford |
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: the clifford cost
- `data[idx] = f'{data_1[idx]!0{b_1}b}' + f'{data_2[idx]!0{b_2}b}' + ... + f'{data_L[idx]!0{b_L}b}'` | ||
|
||
Thus, the target bitsize of the merged dataset is $b = b_1 + b_2 + \dots + b_L$ and clifford | ||
cost of loading merged dataset scales as |
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: the merged
|
||
|
||
@bloq_example | ||
def _qroam_symb_dirty() -> SelectSwapQROM: |
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 the purposes of exposition it would be helpful to add a 1D example with the symbols matching those from the screenshotted costs.
) | ||
for didx, data in enumerate([[[1, 2, 3, 4, 5]], [[1, 2, 3], [3, 2, 1]]]) | ||
for block_size in [None, 1, 2, 3] | ||
for block_size in [None, 0, 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.
Did this get slower?
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.
no, the different is that we now specify log_block_size instead of block_size; where block_size = 2**log_block_size
.
"\n", | ||
"The `SelectSwapQROM` is a hybrid of the following two existing primitives:\n", | ||
"\n", | ||
" * Unary Iteration based `QROM` requires O(N) T-gates to load `N` data\n", |
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.
This doesn't format well in the notebook.
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.
fixed
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.
Awesome! Should we just rename it QROAM at this point?
qualtran/bloqs/data_loading/qrom.py
Outdated
@@ -54,7 +52,7 @@ def _to_tuple(x: Iterable[NDArray]) -> Sequence[NDArray]: | |||
|
|||
@cirq.value_equality() | |||
@attrs.frozen | |||
class QROM(UnaryIterationGate): | |||
class QROM(QROMABC, UnaryIterationGate): |
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.
Would it make sense to ever just have a single QROM bloq where you'd get QROAM if block_size > 1, or would it make things more complicated.
from qualtran.simulation.classical_sim import ClassicalValT | ||
from qualtran.symbolics import bit_length, is_symbolic, shape, Shaped, SymbolicInt | ||
|
||
QROMT = TypeVar('QROMT', bound='QROMABC') |
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.
QROM_T?
related #699 |
I've rewritten the docs on qrom base and derived classes and used the docs from base class in the notebooks for derived classes. I think we can still continue to improve the docs, but I'll go ahead and merge this for now. |
@tanujkhattar I remember discussing this at the time, but what's the origin in the factor of 2 difference between the ceiling term when comparing Theorem 1 and 2, I think this is not related to the inverse right? |
Cost for the dirty ancilla case (Theorem 1) matches the Appendix A formula (2 QROMs + 4 SwapWithZero's) Cost for the clean ancilla case is different because we need
Our implementation assumes that the clean ancilla are freed up as part of the decomposition. In their implementation, they only count the cost of computing the table lookup; and measure the clean ancilla in X basis and keep the measurement results around as part of a deferred uncomputation strategy. Once the QROM needs to be uncomputed, these measurement results are used along with measurement based uncomputation of table lookup described in Appendix C. Therefore, they essentially don't incur any cost for |
Thank you! |
Fixes #108
Partially addresses #368
Fixes #78
We still need an adjoint bloq for QROMs to make the complexity for clean ancilla version match that of the paper, and I haven't implemented the optimization to save one target register from https://quantum-journal.org/papers/q-2019-12-02-208/pdf/
This PR introduces major revamp to
SelectSwapQROM
and some upgrades toQROM
. I'll add more detailed description soon@fdmalone