Skip to content

Commit

Permalink
8315024: Vector API FP reduction tests should not test for exact equa…
Browse files Browse the repository at this point in the history
…lity

Reviewed-by: mdoerr
Backport-of: e6f23a90d4a53339a3c9c2b76fc5d317940e4472
  • Loading branch information
Amos Shi committed Aug 26, 2024
1 parent ba98d8b commit 5fef984
Show file tree
Hide file tree
Showing 13 changed files with 417 additions and 120 deletions.
47 changes: 35 additions & 12 deletions test/jdk/jdk/incubator/vector/Double128VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class Double128VectorTests extends AbstractVectorTest {

static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);

// for floating point reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR = (double)0.000001;

static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 128);

Expand Down Expand Up @@ -118,15 +120,21 @@ interface FReductionAllOp {

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa) {
assertReductionArraysEquals(r, rc, a, f, fa, (double)0.0);
}

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a));
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i));
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand All @@ -140,15 +148,22 @@ interface FReductionAllMaskedOp {

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa) {
assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, (double)0.0);
}

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a, mask));
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i, mask));
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand Down Expand Up @@ -986,6 +1001,14 @@ static long bits(double e) {
return fill(s * BUFFER_REPS,
i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
}),
withToString("double[0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> i % 17 == 0 ? cornerCaseValue(i) : (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[cornerCaseValue(i)]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> cornerCaseValue(i));
Expand Down Expand Up @@ -2135,7 +2158,7 @@ static void ADDReduceDouble128VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double128VectorTests::ADDReduce, Double128VectorTests::ADDReduceAll);
Double128VectorTests::ADDReduce, Double128VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
Expand Down Expand Up @@ -2179,7 +2202,7 @@ static void ADDReduceDouble128VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double128VectorTests::ADDReduceMasked, Double128VectorTests::ADDReduceAllMasked);
Double128VectorTests::ADDReduceMasked, Double128VectorTests::ADDReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MULReduce(double[] a, int idx) {
double res = 1;
Expand Down Expand Up @@ -2220,7 +2243,7 @@ static void MULReduceDouble128VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double128VectorTests::MULReduce, Double128VectorTests::MULReduceAll);
Double128VectorTests::MULReduce, Double128VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
Expand Down Expand Up @@ -2264,7 +2287,7 @@ static void MULReduceDouble128VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double128VectorTests::MULReduceMasked, Double128VectorTests::MULReduceAllMasked);
Double128VectorTests::MULReduceMasked, Double128VectorTests::MULReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
Expand Down
47 changes: 35 additions & 12 deletions test/jdk/jdk/incubator/vector/Double256VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class Double256VectorTests extends AbstractVectorTest {

static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);

// for floating point reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR = (double)0.000001;

static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 256);

Expand Down Expand Up @@ -118,15 +120,21 @@ interface FReductionAllOp {

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa) {
assertReductionArraysEquals(r, rc, a, f, fa, (double)0.0);
}

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a));
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i));
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand All @@ -140,15 +148,22 @@ interface FReductionAllMaskedOp {

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa) {
assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, (double)0.0);
}

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a, mask));
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i, mask));
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand Down Expand Up @@ -986,6 +1001,14 @@ static long bits(double e) {
return fill(s * BUFFER_REPS,
i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
}),
withToString("double[0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> i % 17 == 0 ? cornerCaseValue(i) : (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[cornerCaseValue(i)]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> cornerCaseValue(i));
Expand Down Expand Up @@ -2135,7 +2158,7 @@ static void ADDReduceDouble256VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double256VectorTests::ADDReduce, Double256VectorTests::ADDReduceAll);
Double256VectorTests::ADDReduce, Double256VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
Expand Down Expand Up @@ -2179,7 +2202,7 @@ static void ADDReduceDouble256VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double256VectorTests::ADDReduceMasked, Double256VectorTests::ADDReduceAllMasked);
Double256VectorTests::ADDReduceMasked, Double256VectorTests::ADDReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MULReduce(double[] a, int idx) {
double res = 1;
Expand Down Expand Up @@ -2220,7 +2243,7 @@ static void MULReduceDouble256VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double256VectorTests::MULReduce, Double256VectorTests::MULReduceAll);
Double256VectorTests::MULReduce, Double256VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
Expand Down Expand Up @@ -2264,7 +2287,7 @@ static void MULReduceDouble256VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double256VectorTests::MULReduceMasked, Double256VectorTests::MULReduceAllMasked);
Double256VectorTests::MULReduceMasked, Double256VectorTests::MULReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
Expand Down
47 changes: 35 additions & 12 deletions test/jdk/jdk/incubator/vector/Double512VectorTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public class Double512VectorTests extends AbstractVectorTest {

static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);

// for floating point reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR = (double)0.000001;

static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 512);

Expand Down Expand Up @@ -118,15 +120,21 @@ interface FReductionAllOp {

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa) {
assertReductionArraysEquals(r, rc, a, f, fa, (double)0.0);
}

static void assertReductionArraysEquals(double[] r, double rc, double[] a,
FReductionOp f, FReductionAllOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a));
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i));
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand All @@ -140,15 +148,22 @@ interface FReductionAllMaskedOp {

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa) {
assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, (double)0.0);
}

static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
FReductionMaskedOp f, FReductionAllMaskedOp fa,
double relativeError) {
int i = 0;
try {
Assert.assertEquals(rc, fa.apply(a, mask));
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
for (; i < a.length; i += SPECIES.length()) {
Assert.assertEquals(r[i], f.apply(a, i, mask));
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
relativeError));
}
} catch (AssertionError e) {
Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
}
}

Expand Down Expand Up @@ -986,6 +1001,14 @@ static long bits(double e) {
return fill(s * BUFFER_REPS,
i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
}),
withToString("double[0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> i % 17 == 0 ? cornerCaseValue(i) : (double)0.01 + ((double)i / (i + 1)));
}),
withToString("double[cornerCaseValue(i)]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> cornerCaseValue(i));
Expand Down Expand Up @@ -2135,7 +2158,7 @@ static void ADDReduceDouble512VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double512VectorTests::ADDReduce, Double512VectorTests::ADDReduceAll);
Double512VectorTests::ADDReduce, Double512VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
Expand Down Expand Up @@ -2179,7 +2202,7 @@ static void ADDReduceDouble512VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double512VectorTests::ADDReduceMasked, Double512VectorTests::ADDReduceAllMasked);
Double512VectorTests::ADDReduceMasked, Double512VectorTests::ADDReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MULReduce(double[] a, int idx) {
double res = 1;
Expand Down Expand Up @@ -2220,7 +2243,7 @@ static void MULReduceDouble512VectorTests(IntFunction<double[]> fa) {
}

assertReductionArraysEquals(r, ra, a,
Double512VectorTests::MULReduce, Double512VectorTests::MULReduceAll);
Double512VectorTests::MULReduce, Double512VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR);
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
Expand Down Expand Up @@ -2264,7 +2287,7 @@ static void MULReduceDouble512VectorTestsMasked(IntFunction<double[]> fa, IntFun
}

assertReductionArraysEqualsMasked(r, ra, a, mask,
Double512VectorTests::MULReduceMasked, Double512VectorTests::MULReduceAllMasked);
Double512VectorTests::MULReduceMasked, Double512VectorTests::MULReduceAllMasked, RELATIVE_ROUNDING_ERROR);
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
Expand Down
Loading

0 comments on commit 5fef984

Please sign in to comment.