Skip to content

Fixes to benchmark test code due to missing updates in dependency methods#1035

Open
kenya-sk wants to merge 9 commits intotensorflow:masterfrom
kenya-sk:fix-benchmarks-test
Open

Fixes to benchmark test code due to missing updates in dependency methods#1035
kenya-sk wants to merge 9 commits intotensorflow:masterfrom
kenya-sk:fix-benchmarks-test

Conversation

@kenya-sk
Copy link
Copy Markdown
Contributor

@kenya-sk kenya-sk commented Apr 6, 2026

This PR fixes benchmark breakages in benchmarks/scripts and restores Bazel test coverage for the benchmark targets.

Changes

  • Fixed missing Bazel deps in benchmarks/scripts/BUILD and made random_clifford_circuit importable by switching to py_library in benchmarks/scripts/models/BUILD.
  • Fixed TFQ gradient benchmark input handling in benchmark_op_gradients.py by passing symbol_names as a tensor.
  • Replaced removed Cirq API usage in benchmark_random_circuit.py with an in-file implementation based on ReCirq’s google_v2_beyond_classical.py logic (with source attribution), while preserving existing benchmark behavior (fixed-depth output).

Note
Direct ReCirq adoption was intentionally deferred in this PR because it introduces a broader dependency migration than needed for a benchmark-fix change. In this repo, adding ReCirq as a required dependency impacts Python lockfile resolution and Bazel external dependency wiring, and we hit dependency-resolution conflicts while trying to make it mandatory. To keep this PR focused, low-risk, and test-stable, we inlined the minimal circuit-generation logic with source attribution, and left full ReCirq integration as follow-up work once dependency constraints are aligned.

Results
All benchmark tests have passed.

$ bash scripts/test_benchmarks.sh 
Testing all Benchmarks.
Loading: 0 packages loaded
Loading: 0 packages loaded
INFO: Analyzed 6 targets (21 packages loaded, 225 targets configured).
INFO: Found 2 targets and 4 test targets...
INFO: Elapsed time: 5.054s, Critical Path: 4.64s
INFO: 2 processes: 1 internal, 1 local.
INFO: Build completed successfully, 2 total actions
//benchmarks/scripts:benchmark_clifford_circuit                 (cached) PASSED in 6.9s
//benchmarks/scripts:benchmark_op_gradients                     (cached) PASSED in 8.9s
//benchmarks/scripts:benchmark_util_test                        (cached) PASSED in 4.3s
//benchmarks/scripts:benchmark_random_circuit                            PASSED in 4.6s

Executed 1 out of 4 tests: 4 tests pass.
There were tests whose specified size is too big. Use the --test_verbose_timeout_warnings command line option to see which ones these are.
Testing Complete!

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the benchmarking infrastructure by refining build dependencies, optimizing tensor conversions in gradient benchmarks, and implementing a custom random circuit generator. The changes include converting symbol_names to a TensorFlow tensor to avoid repeated conversions during benchmarking and replacing a library-dependent circuit generator with a manual implementation. Feedback suggests simplifying the redundant logic for determining circuit interaction orientation and improving the connectivity of the generated random circuits to ensure they are more representative for benchmarking purposes.

Comment thread benchmarks/scripts/benchmark_random_circuit.py Outdated
Comment thread benchmarks/scripts/benchmark_random_circuit.py Outdated
@mhucka mhucka added the area/tests Involves tests and testing of the TFQ codebase label Apr 16, 2026

def _choice(rand_gen: float, sequence: Sequence[T]) -> T:
"""Choose a pseudo-random element from a non-empty sequence."""
return sequence[int(rand_gen * len(sequence))]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you check that the Python function random.choice(sequence) does not already do what this _choice() does?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I checked random.choice(sequence), and it is not fully equivalent here. _choice() is intentionally aligned with the original ReCirq implementation: it uses the random.Random(seed).random float stream directly to preserve the same seeded circuit generation behavior.
random.choice() uses a different internal mechanism (_randbelow/getrandbits), which can change the selected gates even with the same seed.

To preserve reproducibility relative to the source implementation, I’ll keep _choice() and add a comment explaining why it is used instead of random.choice().

@mhucka
Copy link
Copy Markdown
Member

mhucka commented May 4, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request updates the benchmarking suite by implementing a local version of the Boixo 2018 random circuit generator and refining build configurations. In benchmark_op_gradients.py, symbol names are now converted to tensors to optimize execution. Feedback suggests renaming the rand_gen parameter in _choice to better reflect its type and recommends passing a pre-defined qubit list to _add_cz_layer to avoid the overhead and non-determinism associated with circuit.all_qubits().

Comment on lines +40 to +42
def _choice(rand_gen: float, sequence: Sequence[T]) -> T:
"""Choose a pseudo-random element from a non-empty sequence."""
return sequence[int(rand_gen * len(sequence))]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The parameter name rand_gen is misleading as it represents a single float value (the result of a random generation) rather than a generator function or object. While functional, renaming it to something like rand_val or r would improve clarity and align with standard naming conventions for values.

Suggested change
def _choice(rand_gen: float, sequence: Sequence[T]) -> T:
"""Choose a pseudo-random element from a non-empty sequence."""
return sequence[int(rand_gen * len(sequence))]
def _choice(rand_val: float, sequence: Sequence[T]) -> T:
"""Choose a pseudo-random element from a non-empty sequence."""
return sequence[int(rand_val * len(sequence))]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated _choice() to match the original ReCirq pattern by passing the RNG callable itself, which makes rand_gen accurate here and keeps the seeded circuit-generation behavior explicit.

"""Add the next non-empty CZ layer and return the updated layer index."""
cz_layer = None
while not cz_layer:
qubits = cast(Iterable[cirq.GridQubit], circuit.all_qubits())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Iterating over circuit.all_qubits() inside a loop can be inefficient as it reconstructs the qubit set each time. Additionally, since all_qubits() returns a FrozenSet, the iteration order is not guaranteed to be stable across different Python environments due to hash randomization. For a benchmark, using the pre-defined and ordered qubits list from the caller would be more efficient and ensure deterministic circuit generation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated _add_cz_layer() to take the ordered qubits sequence from the caller instead of reconstructing circuit.all_qubits() each time. That makes the data flow clearer, avoids repeated set construction.

@mhucka
Copy link
Copy Markdown
Member

mhucka commented May 4, 2026

@kenya-sk I made one suggestion about the _choice function; in addition, the comments from Gemini Code Assist seem reasonable too. If you could update the branch and consider the suggestions, then I'll give it another quick review and I think it will be good to go.

@mhucka mhucka self-assigned this May 4, 2026
@mhucka mhucka added the area/benchmarks Involves benchmarks label May 4, 2026
@kenya-sk
Copy link
Copy Markdown
Contributor Author

kenya-sk commented May 6, 2026

@mhucka
Thank you for your review.
I replied your comment and fixed suggestion. Please review this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/benchmarks Involves benchmarks area/tests Involves tests and testing of the TFQ codebase

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants