-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8373722: [TESTBUG] compiler/vectorapi/TestVectorOperationsWithPartialSize.java fails intermittently #28960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…Size.java fails intermittently
|
👋 Welcome back xgong! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
|
@XiaohongGong The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
|
Shall we change the calculation of tolerance? e.g. |
Thanks for looking at this issue. It's really a good question about the definition of a more reasonable For a floating‑point reduction test, the goal is to check that the API is implemented correctly. And what we really care about is how close the reduction result is to the mathematically expected value. In other words, the tolerance should be derived from the expected sum itself. For example, if the float array is Using |
Understood. However, (1.0, 5.0) the test range is really too small. |
FYI: the current sum based tolerance may be also bigger than max_abs based. |
We used the |
What I really want to avoid in this case is generating values that are near the extreme maximum or minimum of float. Expanding the value range would probably still be acceptable with the current tolerance, which is derived not only from the cross‑lane sum but also includes a rounding‑error factor of 10. BTW, consider that there are already enough API tests under |
The question here is what do you mean by Just consider the following case The sequential scalar floating add will result 0.0f. |
I think we should refer to the java ref spec, that calculates the values in sequential order, right? |
I'm not sure. Did you find related description in the spec? If that is true, the current sum-based |
| random.fill(random.uniformFloats(1.0f, 5.0f), fa); | ||
| random.fill(random.uniformDoubles(1.0, 5.0), da); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally our tolerance window should be narrow, and increasing the tolerance range to accomodate outliers as you mentioned in your issue description may defeat the purpose.
Unlike auto-vectorization which adhears strict ordering JLS semantics, vectorAPI relaxes the reduction order to give backends leeway to use parallel reduction not strictly following the sequential order.
There are multiple considerations involed, fallback implimentation performs reduction sequentially, inline expander always relaxes the strict ordering, intrinsification of Add/Mul reductions are only supported by Aarch64, X86 and riscv.
Computing expected value using parallel reduction can be other alternative but then we may face similar problems on targets which does not intrinsify unordered reductions.
Tolerance modeling is a complex topic and involves relative and absolute error, current 10ULP absolute limit is not generic enough to handle entier spectrum of values, what you have enforced now is a range based tolerance did you try widening the input value range and confirm if 10ULP tolerance limit is sufficient ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm trying to extend the value range to 1~3000. The tests are still running... Since the result largely depends on the random values, I run this test 500 times on SVE/NEON/X86 machines respectively (1500 times totally), and have not observed failure now. Is that fine to you? I will update the test once all tests pass. Thanks for looking at this change!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm trying to extend the value range to
1~3000. The tests are still running... Since the result largely depends on the random values, I run this test500times on SVE/NEON/X86 machines respectively (1500 times totally), and have not observed failure now. Is that fine to you? I will update the test once all tests pass. Thanks for looking at this change!
As with range 1~3000, we may still see failures even with 1000ULP according to the following program, right?
class T {
public static void main(String[] args) {
float ROUNDING_ERROR_FACTOR_ADD = 1000.0f;
Float a = 1.0f + (ROUNDING_ERROR_FACTOR_ADD + 1) * Math.ulp(1.0f);
Float b = 3000.0f;
Float expected = a + b - b;
Float actual = a + (b - b);
float tolerance = Math.ulp(expected) * ROUNDING_ERROR_FACTOR_ADD;
if (Math.abs(expected - actual) > tolerance) {
System.out.println("Error: Out of tolerance!");
}
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm trying to extend the value range to
1~3000. The tests are still running... Since the result largely depends on the random values, I run this test500times on SVE/NEON/X86 machines respectively (1500 times totally), and have not observed failure now. Is that fine to you? I will update the test once all tests pass. Thanks for looking at this change!As with range
1~3000, we may still see failures even with 1000ULP according to the following program, right?class T { public static void main(String[] args) { float ROUNDING_ERROR_FACTOR_ADD = 1000.0f; Float a = 1.0f + (ROUNDING_ERROR_FACTOR_ADD + 1) * Math.ulp(1.0f); Float b = 3000.0f; Float expected = a + b - b; Float actual = a + (b - b); float tolerance = Math.ulp(expected) * ROUNDING_ERROR_FACTOR_ADD; if (Math.abs(expected - actual) > tolerance) { System.out.println("Error: Out of tolerance!"); } } }
Oops, if the range is 1~3000, there is no negative float, so the above program should not happen.
Just ignore it.
I found the reference here: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.7.1 . I used the Java Playground, and see the result:
So that's just the issue that I want to avoid. We didn't have a more reasonable golden value as we do not know the calculation order in Vector API, right? |
Agreed. I would suggest the testing range also covers negative floats, not only positives. |
|
Here is an example which shows that the tolerance may be still not big enough even with Note: the test range of class T {
public static void main(String[] args) {
float ROUNDING_ERROR_FACTOR_ADD = 10000000.0f;
Float a = 0.0f + (ROUNDING_ERROR_FACTOR_ADD + 1) * Math.ulp(0.0f);
Float b = 1.0f;
Float expected = a + b - b;
Float actual = a + (b - b);
float tolerance = Math.ulp(expected) * ROUNDING_ERROR_FACTOR_ADD;
if (Math.abs(expected - actual) > tolerance) {
System.out.println("Error: Out of tolerance!");
}
}
}So I'm afraid the sum-based tolerance should be improved. |
The range is |

The test fails intermittently with the following error:
The root cause is that the Vector API
reduceLanes()does not guarantee a specific calculation order for floating-point reduction operations [1]. When the array contains extreme values, this can produce results outside the tolerance range compared to sequential scalar addition.For example, given array elements:
Sequential scalar addition produces:
However,
reduceLanes()might compute:The difference of the two times of calculation is
Float.MIN_NORMAL(1.1754945E-38), which exceeds the tolerance ofMath.ulp(0.0f) * 10.0f = 1.4E-44. Even with a 10x rounding error factor, the tolerance is insufficient for such edge cases.Since
reduceLanes()does not require a specific calculation order, differences from scalar results can be significantly larger when special or extreme maximum/minimum values are present. Using a fixed tolerance is inappropriate for such corner cases.This patch fixes the issue by initializing the float array in test with random normal values within a specified range, ensuring the result gap stays within the defined tolerance.
Tested locally on my AArch64 and X86_64 machines 500 times, and I didn't observe the failure again.
[1] https://docs.oracle.com/en/java/javase/25/docs/api/jdk.incubator.vector/jdk/incubator/vector/FloatVector.html#reduceLanes(jdk.incubator.vector.VectorOperators.Associative)
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28960/head:pull/28960$ git checkout pull/28960Update a local copy of the PR:
$ git checkout pull/28960$ git pull https://git.openjdk.org/jdk.git pull/28960/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 28960View PR using the GUI difftool:
$ git pr show -t 28960Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28960.diff
Using Webrev
Link to Webrev Comment