Skip to content

Conversation

@abheesht17
Copy link
Collaborator

@abheesht17 abheesht17 commented Oct 9, 2025

Resolves #21708

On the TensorFlow backend, ops.histogram converts a tensor to a Python list [here], which won't work in graph mode with symbolic tensors. The current piece of code uses tf.raw_ops.Bucketize which necessarily requires boundaries to be a Python list [see documentation].

This PR:

  • Replaces tf.raw_ops.Bucketize with tf.searchsorted;
  • Adds a unit test to make sure the op runs with predict;
  • Also adds a missing test (unrelated to the specific issue linked above), which ensures we are assigning values which are "on the boundaries" to the correct bucket. This is an important unit test to have.

We should probably add a unit test which tests model.predict for every op at some point.

Note: Skipping the NumPy test for predict. Seems to be an unrelated issue. We can solve it separately.

@codecov-commenter
Copy link

codecov-commenter commented Oct 9, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.59%. Comparing base (4e1edcf) to head (ec9fa13).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #21729   +/-   ##
=======================================
  Coverage   82.59%   82.59%           
=======================================
  Files         572      572           
  Lines       58535    58535           
  Branches     9158     9158           
=======================================
  Hits        48345    48345           
  Misses       7853     7853           
  Partials     2337     2337           
Flag Coverage Δ
keras 82.39% <100.00%> (ø)
keras-jax 63.19% <0.00%> (ø)
keras-numpy 57.56% <0.00%> (+<0.01%) ⬆️
keras-openvino 34.33% <0.00%> (ø)
keras-tensorflow 63.94% <100.00%> (ø)
keras-torch 63.49% <0.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@abheesht17 abheesht17 requested a review from hertschuh October 9, 2025 07:18
@abheesht17 abheesht17 marked this pull request as ready for review October 9, 2025 07:19
@abheesht17
Copy link
Collaborator Author

Works with jit_compile = False, but does not work with jit_compile = True. Trying to figure out another way

FAILED keras/src/ops/numpy_test.py::HistogramTest::test_histogram_predict - tensorflow.python.framework.errors_impl.InvalidArgumentError: Graph execution error:

Detected at node functional_1/histogram_layer_1/bincount/DenseBincount defined at (most recent call last):
<stack traces unavailable>
Input 1 to node `functional_1/histogram_layer_1/bincount/DenseBincount` with op DenseBincount must be a compile-time constant.

XLA compilation requires that operator arguments that represent shapes or dimensions be evaluated to concrete values at compile time. This error means that a shape or dimension argument could not be evaluated at compile time, usually because the value of the argument depends on a parameter to the computation, on a variable, or on a stateful operation such as a random number generator.

@abheesht17
Copy link
Collaborator Author

abheesht17 commented Oct 9, 2025

Works with jit_compile = False, but does not work with jit_compile = True. Trying to figure out another way

FAILED keras/src/ops/numpy_test.py::HistogramTest::test_histogram_predict - tensorflow.python.framework.errors_impl.InvalidArgumentError: Graph execution error:

Detected at node functional_1/histogram_layer_1/bincount/DenseBincount defined at (most recent call last):
<stack traces unavailable>
Input 1 to node `functional_1/histogram_layer_1/bincount/DenseBincount` with op DenseBincount must be a compile-time constant.

XLA compilation requires that operator arguments that represent shapes or dimensions be evaluated to concrete values at compile time. This error means that a shape or dimension argument could not be evaluated at compile time, usually because the value of the argument depends on a parameter to the computation, on a variable, or on a stateful operation such as a random number generator.

Alright, played some ops golf here, and replaced bincount with scatter_nd_add. Seems to work now

@abheesht17 abheesht17 requested a review from mattdangerw October 9, 2025 16:24

# tf.math.bincount does not work with XLA in this case. So, we use
# `tensor_scatter_nd_add`.
bin_counts = tf.tensor_scatter_nd_add(
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like you can just use tf.scatter_nd:

  • it creates a new tensor with zeros
  • it also sums in the case of duplicate indices

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, done!

@abheesht17 abheesht17 requested a review from hertschuh October 9, 2025 17:17
@google-ml-butler google-ml-butler bot added kokoro:force-run ready to pull Ready to be merged into the codebase labels Oct 9, 2025
@hertschuh hertschuh merged commit ca4e6c5 into keras-team:master Oct 9, 2025
11 checks passed
@google-ml-butler google-ml-butler bot removed awaiting review ready to pull Ready to be merged into the codebase labels Oct 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TF backend: keras.ops.histogram calls .numpy() in graph mode and crashes with AttributeError on symbolic tensors

5 participants