Skip to content

Conversation

BichengYing
Copy link
Collaborator

In order to keep using unit-style input, I have hacked the resolve_parameters function a little bit. Assume all inputs should either be tunit value or sympy.Symbol. (I.e. no sympy expression is allowed). I have to add this since we don't have SymbolFunc or ExprFunc in cirq world.

@github-actions github-actions bot added the size: L 250< lines changed <1000 label Jun 20, 2025
@BichengYing BichengYing marked this pull request as ready for review June 21, 2025 04:51
@BichengYing BichengYing requested review from wcourtney, vtomole, verult and a team as code owners June 21, 2025 04:51
Copy link

codecov bot commented Jun 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.70%. Comparing base (c9839bf) to head (9f6c862).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7430   +/-   ##
=======================================
  Coverage   98.69%   98.70%           
=======================================
  Files        1112     1114    +2     
  Lines       98214    98301   +87     
=======================================
+ Hits        96937    97024   +87     
  Misses       1277     1277           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

"w": 5,
"target_freq": 8,
"prev_freq": null,
"neighbor_coupler_g_dict": null,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we provide values for these parameters in the json test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should but The expression must eval correctly when only cirq, pandas as pd, numpy as np and sympy have been imported. Maybe it is good to add tunits as import dependency in future PR? wdyt?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. This is fine for now then.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be worth adding tunits to the import list eventually in the import setup for json, but that can be done later.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, add a TODO in the json_serialization_test.py to mark this taks.


@cirq.value_equality(approximate=True)
class AnalogDetuneQubit(cirq.ops.Gate):
"""A step function that steup a qubit to the freq according to analog model.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: avoid abbreviations in the docstring if possible (freq => frequency)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

| |---length --|
|
--------------------------(calculated from previous qubit freq using analog model)
Because the step hold at amp with inifinite length. You need prev_freq to compensate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence needs to be adjusted "Because the step hold at amp with inifinite length.". I am not quite sure what you mean. Is it "Because the step is held at amp with infinite length, you need prev_freq ..."
(Also infinite is a typo)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusing. Behind it is DetuneStepUp logic, that DAC amp is always on).

Update it into this:

Note that the step is held at a constant amplitude indefinitely. This gate is typically used by concatenating multiple instances. To ensure the curve is continuous and avoids sudden jumps, you need prev_freq to compensate for the previous Detune gate.

# A shortcut for value resolution to avoid tu.unit compare with float issue.
def _direct_symbol_replacement(x, resolver: cirq.ParamResolver):
if isinstance(x, sympy.Symbol):
value = resolver.param_dict.get(x.name, "__NOT_FOUND__")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should "NOT_FOUND" be a constant?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still make this a string constant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


def __init__(
self,
length: ValueOrSymbol,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: I wonder if it will be easier to just make it length_ns and float rather than fight against cirq's typing. Sweeps etc are all defined as floats.

Copy link
Collaborator Author

@BichengYing BichengYing Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is an important question. Yes, it should be easier in that way. The main reason I keep units is because of user's behavior. Trond: can you chime in on this? (Doug: can you help to add Trond as reviewer? I cannot do it)

Sweeps etc are all defined as floats: this is not true for example cirq.Points("a", [1,2,3]*tu.ns) is commonly used in pyle.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we managed to make it so that all the sweeps are with units, and it feels like this could make the user's life easier! :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean that the type is defined as floats in cirq. It works with things other than floats some of the time.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe I misunderstand the comment. Which line of code are you referring to? Here the type is ValueOrSymbol, which is tu.Value | Symbol and type checking is okay.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I mean is this https://quantumai.google/reference/python/cirq/TParamVal
cirq itself defines a parameter value as a float, which is used in sweeps all over:
https://github.com/quantumlib/Cirq/blob/v1.5.0/cirq-core/cirq/study/sweeps.py#L41

Not much of the code actually depends that this is a float, but some of it (like gate implementations) does, so we are always going to be fighting against the typing system if we are trying to support sweeps with units.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yeah, i also feel there is always a fighting with value versus float convention. I think for this analog_experiment one, we will not have code about sweep to check-in.

In cirq-google sweep, we have expanded the proto definition to support tunits.

// A list of explicit values.
message Points {
// The values.
repeated float points = 1;
tunits.Value unit = 2;
}
// A range of evenly-spaced values.
//
// Example: if the first_point is 1.0, the last_point is 2.0 ,
// and the num_points is 5, thi corresponds to the points
// 1.0, 1.25, 1.5, 1.75, 2.0
message Linspace {
// The start of the range.
float first_point = 1;
// The end of the range.
float last_point = 2;
// The number of points in the range (including first and last). Must be
// greater than zero. If it is 1, the first_point and last_point must be
// the same.
int64 num_points = 3;
tunits.Value unit = 4;
}

So running the experiment with tunit is okay and we don't need to check-in code to fight with type system. But happy to find a middle ground if we do encounter type checking issues.

@BichengYing BichengYing requested a review from dstrain115 June 24, 2025 20:05
"w": 5,
"target_freq": 8,
"prev_freq": null,
"neighbor_coupler_g_dict": null,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be worth adding tunits to the import list eventually in the import setup for json, but that can be done later.

# A shortcut for value resolution to avoid tu.unit compare with float issue.
def _direct_symbol_replacement(x, resolver: cirq.ParamResolver):
if isinstance(x, sympy.Symbol):
value = resolver.param_dict.get(x.name, "__NOT_FOUND__")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would still make this a string constant.

@BichengYing BichengYing added this pull request to the merge queue Jun 25, 2025
Merged via the queue into quantumlib:main with commit 66b582f Jun 25, 2025
94 of 97 checks passed
@BichengYing BichengYing deleted the u/ybc/analog_detune branch June 25, 2025 20:28
BichengYing added a commit to BichengYing/Cirq that referenced this pull request Jun 25, 2025
In order to keep using unit-style input, I have hacked the
_resolve_parameters_ function a little bit. Assume all inputs should
either be tunit value or sympy.Symbol. (I.e. no sympy expression is
allowed). I have to add this since we don't have SymbolFunc or ExprFunc
in cirq world.
BichengYing added a commit to BichengYing/Cirq that referenced this pull request Jun 25, 2025
In order to keep using unit-style input, I have hacked the
_resolve_parameters_ function a little bit. Assume all inputs should
either be tunit value or sympy.Symbol. (I.e. no sympy expression is
allowed). I have to add this since we don't have SymbolFunc or ExprFunc
in cirq world.
BichengYing added a commit to BichengYing/Cirq that referenced this pull request Jun 25, 2025
In order to keep using unit-style input, I have hacked the
_resolve_parameters_ function a little bit. Assume all inputs should
either be tunit value or sympy.Symbol. (I.e. no sympy expression is
allowed). I have to add this since we don't have SymbolFunc or ExprFunc
in cirq world.
ddddddanni pushed a commit to ddddddanni/Cirq that referenced this pull request Jul 15, 2025
In order to keep using unit-style input, I have hacked the
_resolve_parameters_ function a little bit. Assume all inputs should
either be tunit value or sympy.Symbol. (I.e. no sympy expression is
allowed). I have to add this since we don't have SymbolFunc or ExprFunc
in cirq world.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants