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

Divergent behaviour of controlled: GateWithRegisters.controlled vs. Bloq.controlled #686

Closed
anurudhp opened this issue Feb 18, 2024 · 5 comments · Fixed by #879
Closed
Assignees
Labels
bug Something isn't working

Comments

@anurudhp
Copy link
Contributor

Ran into this issue while testing GQSP's call graph. Minimal code to reproduce:

import numpy as np
from qualtran.bloqs.generalized_qsp_test import RandomGate

U = RandomGate.create(bitsize=1, random_state=np.random.RandomState(42))
print(U.call_graph()) # works
print(U.controlled().call_graph()) # fails

output:

(<networkx.classes.digraph.DiGraph object at 0x7fc8491550d0>, {RandomGate(bitsize=1, matrix=array([[ 0.27702459-0.13059069j, -0.76350488+0.56856287j],
       [ 0.36122517+0.88074958j,  0.1700831 +0.25469254j]])): 1})

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    print(U.controlled().call_graph())
          ^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'ControlledGate' object has no attribute 'call_graph'
@mpharrigan
Copy link
Collaborator

I'll look at this. Since cirq.Gate and Bloqboth have a method named controlled we have to pick the most useful default.

A workaround if you have access to the source code for the problematic gate is to call the correct one

class MyGWR(GateWithRegisters):
  ...

  def controlled(self, *args, **kwargs):
    return Bloq.controlled(*args, **kwargs)

@mpharrigan mpharrigan added the bug Something isn't working label Feb 22, 2024
@mpharrigan mpharrigan self-assigned this Feb 22, 2024
@anurudhp
Copy link
Contributor Author

Thanks!

So I was using this for Hamiltonian simulation by GQSP, which uses QubitizationWalkOperator. @tanujkhattar, I believe it would be a major refactor to make it and all its dependencies Bloqs?

@fpapa250
Copy link
Contributor

fpapa250 commented Mar 12, 2024

Running into this error in #780. Specifically with MontgomeryModInv() bloq whose call graph involves Add().controlled() and LinearDepthGreaterThan().controlled().

Code to reproduce:

from qualtran.drawing import show_call_graph
from qualtran.bloqs.factoring.mod_mul import MontgomeryModInv

bloq = MontgomeryModInv(bitsize=5, p=6)

graph, sigma = bloq.call_graph()
show_call_graph(graph)

@mpharrigan
Copy link
Collaborator

reflecting on this, we should probably change the default GateWithRegisters.controlled to be the bloqs one and then use the workaround for cases when we need the cirq behavior

@tanujkhattar
Copy link
Collaborator

We should ideally never need the cirq behavior now that we have a mapping from the Controlled bloq to cirq.ControlledGate and Controlled bloq supports simulations.

For convenience with cirq and bloq APIs and to avoid potential performance regressions; I'd suggest we make Controlled bloq a GateWithRegisters (eg: this would be useful to directly use the unitary of the subbloq when subbloq is GateWithRegisters)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants