quantumlib / Qualtran

Qᴜᴀʟᴛʀᴀɴ is a Python library for expressing and analyzing Fault Tolerant Quantum algorithms.
https://qualtran.readthedocs.io/en/latest/
Apache License 2.0
134 stars 35 forks source link

Move `SelectOracle` and `PrepareOracle` to `qualtran/interfaces/` #1108

Closed charlesyuan314 closed 1 week ago

charlesyuan314 commented 2 weeks ago

Move the definitions of SelectOracle and PrepareOracle to a new directory qualtran/interfaces, so as to remove the unnecessary dependency on block encodings, which become circular with new work on block encoding implementations.

Change the base class of SelectOracle and PrepareOracle to the less restrictive Bloq rather than GateWithRegisters, and update instances appropriately.

tanujkhattar commented 2 weeks ago

What's the cause of the circular dependency? Can you please provide some more context?

I don't think we should have a generic bloqs/interfaces -- we have interfaces for many different types of bloqs (eg: (a) unary iteration (b) QROMs) and will continue to have more (eg: arithmetic bloqs). We should place the interfaces in the directory where they belong. In this case, the SELECT and PREPARE oracles are specific for LCU based block encodings so they should be place appropriately.

charlesyuan314 commented 2 weeks ago

The context for this change is as follows:

When LinearCombination and ApplyLthBloq are added as above, the circular dependency is as follows:

qualtran.bloqs.block_encodings (.linear_combination.LinearCombination) requires qualtran.bloqs.multiplexers (.apply_lth_bloq.ApplyLthBloq) which requires qualtran.bloqs.block_encodings (.lcu_select_and_prepare.SelectOracle).

Would appreciate suggestions on any alternative means to avoid this problem, if the refactor in this PR is not appropriate!

tanujkhattar commented 1 week ago

@charlesyuan314 qualtran.bloqs.block_encodings.linear_combination.LinearCombination can import qualtran.bloqs.multiplexers.apply_lth_bloq.ApplyLthBloq locally in the decompose_bloq method instead of globally at the top level to avoid the circular dependency. Does this solve the problem? If not, there are also other tricks we can use like the LazyLoader from Cirq - https://github.com/quantumlib/Cirq/blob/32d48331fecd5f075c25e8f05c4551380bcd6c45/cirq-core/cirq/_import.py#L176

Once you open a PR, we can look into the technical details of how to avoid the circular dependency but I don't think we should move the LCU Select / Prepare interfaces to a new qualtran/bloqs/<module>.

charlesyuan314 commented 1 week ago

Sounds good, I will try the above approaches!