quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.28k stars 1.02k forks source link

`cirq.decompose_once` fails when called on `cirq.CZ` #6667

Open maffoo opened 4 months ago

maffoo commented 4 months ago

Calling cirq.decomponse_once on cirq.CZ raises an error:

In [4]: cirq.decompose(cirq.CZ(cirq.q(0), cirq.q(1)))
Out[4]: [cirq.CZ(cirq.LineQubit(0), cirq.LineQubit(1))]

In [5]: cirq.decompose_once(cirq.CZ(cirq.q(0), cirq.q(1)))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[5], line 1
----> 1 cirq.decompose_once(cirq.CZ(cirq.q(0), cirq.q(1)))

File ~/.virtualenvs/pyle/lib/python3.11/site-packages/cirq/protocols/decompose_protocol.py:388, in decompose_once(val, default, flatten, context, *args, **kwargs)
    383 if method is None:
    384     raise TypeError(
    385         f"object of type '{type(val)}' has no _decompose_with_context_ or "
    386         f"_decompose_ method."
    387     )
--> 388 raise TypeError(
    389     f"object of type {type(val)} does have a _decompose_ method, "
    390     "but it returned NotImplemented or None."
    391 )

TypeError: object of type <class 'cirq.ops.gate_operation.GateOperation'> does have a _decompose_ method, but it returned NotImplemented or None.
NoureldinYosri commented 4 months ago

what is the desired behaviour here? I think cirq.CZ is treated as a native gate so operations decompose into it but it doesn't have its own decomposition

maffoo commented 4 months ago

I don't know what the expected behavior is; I guess maybe the idea here is that if an op can't be decomposed this is supposed to raise? The docs for decompose_once are not very clear on this, and obviously the behavior of decompose is different. Maybe decompose_once is intended to be something like "decompose exactly once" versus "decompose at most once".

dstrain115 commented 4 months ago

cirq cync: The root cause which spawned this issue could be a problem with multiprocessing, since there is global state keeping track of this table. This global state is only in the calling code, not in cirq itself.

Conclusion is that this is intended behavior, since decompose_once should return exception denoting that you are at the base case.

The sole action item here is to document the behavior of decompose_once when you specify a "base gate".
Nice to have would be to have a specialized exception type (or a more helpful message).

pavoljuhas commented 2 months ago

TODO @pavoljuhas - verify if this still happens after #6674.