slient overflow occurs in tf.range leading to incorrect result, here is a possible fix
Issue type
Bug
Have you reproduced the bug with TensorFlow Nightly?
Yes
Source
source
TensorFlow version
2.15.0
Custom code
Yes
OS platform and distribution
No response
Mobile device
No response
Python version
No response
Bazel version
No response
GCC/compiler version
No response
CUDA/cuDNN version
No response
GPU model and memory
No response
Current behavior?
Following the documentation https://www.tensorflow.org/api_docs/python/tf/range, tf.range should have consistent result with np.arange.
However, given the following inputs, tf.range outputs tf.Tensor([1136033460], shape=(1,), dtype=int32), which is incorrect
The correct result is np.arange's output [1136033460 -713794229].
I did some analysis and find the root cause lies in here: https://github.com/tensorflow/tensorflow/blob/06e37b8d7f2ba0338efd0f588f068122414f0722/tensorflow/core/kernels/sequence_ops.cc#L100
When computing the limit - start, the actual value overflows.
To solve this problem, we can change the original code to a new one by applying the division first
origin:
Eigen::numext::ceil(Eigen::numext::abs((limit - start) / delta));
new:
Eigen::numext::ceil(Eigen::numext::abs(limit / delta - start / delta);
Standalone code to reproduce the issue
import numpy as np
import tensorflow as tf
start = 1136033460
end = -2110457150
step = -1849827689
out = tf.range(start, end, step)
print(out)
out_np = np.arange(start, end, step)
print(out_np)
### Relevant log output
_No response_
Your analysis and solution seem valid. Open a PR if you'd like, otherwise I can handle it
I am afraid I don't have time in these few days, I would appreciate it if you can help me to open one.
Hi @QuantumCoder4 , @Aloqeely
I acknowledge the issue of overflow and attached gist for reference.The proposed fix might work it seems. Please feel free to raise a PR.
Hi @Aloqeely ,
I have a question. What happens if the value of delta =1 here keeping other two params same. It still might cause overflow ?
Line 83 in sequence_ops.cc:
if (delta > 0) {
OP_REQUIRES(
context, start <= limit,
errors::InvalidArgument(
"Requires start <= limit when delta > 0: ", start, "/", limit));
}
In that case, this if statement would get triggered since delta = 1, and then start <= limit would get evaluated to false so the function will raise an error
The proposed fix above won't work - it leads to different behavior. See the discussion in the (now closed) PR #64144.
Someone can pick that up if they like.