Cirq icon indicating copy to clipboard operation
Cirq copied to clipboard

Allow cirq.resolve_parameter compatible with t-units

Open BichengYing opened this issue 4 months ago • 5 comments

Is your feature request related to a use case or problem? Please explain

Minimal example:

import cirq
import cirq_google as cg
import tunits as tu
import sympy

q = cirq.q(0, 0)
c = cirq.Circuit(cirq.X(q)** sympy.Symbol("a"))
# !!!!! I know this is not a valid usage case. The point is just for showing the error.!!!
cirq.resolve_parameters(c, {"a": 10*tu.ns}) 

We will get the following error see that line f = lambda x: x if symbolic(x) else float(x)

File ~/.virtualenvs/pyle3/lib/python3.12/site-packages/cirq/ops/eigen_gate.py:316, in EigenGate._value_equality_values_.<locals>.<lambda>(x)
    307 """The phases by which we multiply the eigenspaces.
    308 
    309 The default implementation assumes that the eigenspaces are constant
   (...)
    313 fields that affect the eigenspaces.
    314 """
    315 symbolic = lambda x: isinstance(x, sympy.Expr) and x.free_symbols
--> 316 f = lambda x: x if symbolic(x) else float(x)
    317 shifts = (f(self._exponent) * f(self._global_shift + e) for e in self._eigen_shifts())
    318 return tuple(s if symbolic(s) else value.PeriodicValue(f(s), 2) for s in shifts)

File ~/.virtualenvs/pyle3/lib/python3.12/site-packages/tunits/core/cython/with_unit.pyx:399, in tunits_core.WithUnit.__float__()

UnitMismatchError: '10 ns' can't be stripped into a float; not dimensionless. 

Describe the solution you would prefer

Is that possible that we can avoid this casting to float and allow tunit.Value as another possible case? This can unblock lots of internal gate usages.

How urgent is this for you? Is it blocking important work?

P2 – we should do it in the next couple of quarters

BichengYing avatar Jul 31 '25 18:07 BichengYing

In the example you gave, the problem is not with cirq.resolve_parameters, rather the issue is that EigenGate can't be exponentiated with a time (just doing X**(10 * tu.ns) with no paramount resolution will show the same issue). Do you have a case where a tunits value is allowed if used directly, but fails with parameter resolution?

maffoo avatar Aug 01 '25 20:08 maffoo

Yeah, that is not a good example. Let's use the wait gate as example:

https://github.com/quantumlib/Cirq/blob/17c4e95dae4eedb8ea22bc8abee3e03c6fbef4ca/cirq-google/cirq_google/ops/wait_gate.py#L60-L66

Let we replace the line 64 as _duration = cirq.resolve_parameters(self._duration, resolver) instead, running the test, we will encounter the following error:

    def test_wait_gate_with_units_resolving() -> None:
        gate = wg.WaitGateWithUnit(sympy.Symbol("d"))
    
>       resolved_gate = cirq.resolve_parameters(gate, {"d": 10 * tu.ns})
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

cirq-google/cirq_google/ops/wait_gate_test.py:45: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/cirq/protocols/resolve_parameters.py:190: in resolve_parameters
    result = getter(param_resolver, recursive)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
cirq-google/cirq_google/ops/wait_gate.py:64: in _resolve_parameters_
    _duration = cirq.resolve_parameters(self._duration, resolver)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/cirq/protocols/resolve_parameters.py:176: in resolve_parameters
    return cast(T, param_resolver.value_of(val, recursive))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/cirq/study/resolver.py:133: in value_of
    v = _resolve_value(param_value)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/cirq/study/resolver.py:288: in _resolve_value
    if val == sympy.pi:
       ^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/sympy/core/numbers.py:3458: in __eq__
    other = _sympify(other)
            ^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/sympy/core/sympify.py:505: in _sympify
    return sympify(a, strict=True)
           ^^^^^^^^^^^^^^^^^^^^^^^
../.virtualenvs/cirq-py3/lib/python3.12/site-packages/sympy/core/sympify.py:428: in sympify
    return sympify(coerce(a))
                   ^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???
E   tunits_core.UnitMismatchError: '10 ns' can't be stripped into a float; not dimensionless.

tunits/core/cython/with_unit.pyx:399: UnitMismatchError

BichengYing avatar Aug 05 '25 22:08 BichengYing

One potential issue is that we would need to add tunits as a dependency for cirq-core. I am reluctant to allow more dependencies that are largely Google-specific to cirq-core.

dstrain115 avatar Aug 06 '25 13:08 dstrain115

Discussed in cirq cync: we do not want to add this dependency to cirq-core if we can avoid it, since this will include compiled code and cython dependencies for all cirq users. If there is a way to duck-type it without importing, we could consider a change to cirq-core.

dstrain115 avatar Aug 06 '25 17:08 dstrain115

This issue has been automatically labeled as stale because 90 days have passed without comments or other activity. If no further activity occurs on this issue and the status/stale label is not removed by a maintainer within 60 days, this issue will be closed. If you would like to restore its status, please leave a comment here; doing so will cause the staleness handler to remove the label.

If you have questions or feedback about this process, we welcome your input. You can open a new issue to let us know (please also reference this issue there, for continuity), or reach out to the project maintainers at [email protected].

github-actions[bot] avatar Nov 30 '25 00:11 github-actions[bot]