From b65fdf5af0a5e1cf0d66d7551c6df63e8d07c5fa Mon Sep 17 00:00:00 2001 From: Ian Graves Date: Tue, 15 Jul 2025 14:33:37 +0000 Subject: [PATCH] 8358768: [vectorapi] Make VectorOperators.SUADD an Associative Reviewed-by: psandoz --- .../jdk/incubator/vector/VectorOperators.java | 2 +- .../incubator/vector/Byte128VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Byte256VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Byte512VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Byte64VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/ByteMaxVectorTests.java | 128 ++++++++++++++++++ .../vector/Double128VectorTests.java | 46 +++++++ .../vector/Double256VectorTests.java | 46 +++++++ .../vector/Double512VectorTests.java | 46 +++++++ .../incubator/vector/Double64VectorTests.java | 46 +++++++ .../vector/DoubleMaxVectorTests.java | 46 +++++++ .../incubator/vector/Float128VectorTests.java | 46 +++++++ .../incubator/vector/Float256VectorTests.java | 46 +++++++ .../incubator/vector/Float512VectorTests.java | 46 +++++++ .../incubator/vector/Float64VectorTests.java | 46 +++++++ .../incubator/vector/FloatMaxVectorTests.java | 46 +++++++ .../incubator/vector/Int128VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Int256VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Int512VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Int64VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/IntMaxVectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Long128VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Long256VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Long512VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Long64VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/LongMaxVectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Short128VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Short256VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Short512VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/Short64VectorTests.java | 128 ++++++++++++++++++ .../incubator/vector/ShortMaxVectorTests.java | 128 ++++++++++++++++++ test/jdk/jdk/incubator/vector/gen-template.sh | 9 ++ ...atingBinary-Masked-op-associative.template | 18 +++ ...l-SaturatingBinary-op-associative.template | 15 ++ ...atingBinary-Masked-op-associative.template | 7 + ...t-SaturatingBinary-op-associative.template | 5 + .../vector/templates/Unit-header.template | 83 ++++++++++++ 37 files changed, 3158 insertions(+), 1 deletion(-) create mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-Masked-op-associative.template create mode 100644 test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-op-associative.template create mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-Masked-op-associative.template create mode 100644 test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-op-associative.template diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java index 0e231bd5174..f4da4f42934 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorOperators.java @@ -577,7 +577,7 @@ public abstract class VectorOperators { /** Produce saturating unsigned {@code a+b}. Integral only. * @see VectorMath#addSaturatingUnsigned(int, int) */ - public static final Binary SUADD = binary("SUADD", "+", VectorSupport.VECTOR_OP_SUADD, VO_NOFP); + public static final Associative SUADD = assoc("SUADD", "+", VectorSupport.VECTOR_OP_SUADD, VO_NOFP+VO_ASSOC); /** Produce saturating {@code a-b}. Integral only. * @see VectorMath#subSaturating(int, int) */ diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java index 5ead28c47f0..fd017ce183b 100644 --- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java @@ -405,6 +405,52 @@ public class Byte128VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(byte[] r, byte[] a, byte[] b, FBinOp f) { int i = 0; try { @@ -1016,6 +1062,21 @@ public class Byte128VectorTests extends AbstractVectorTest { }) ); + static final List> BYTE_SATURATING_GENERATORS_ASSOC = List.of( + withToString("byte[Byte.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE)); + }), + withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE - 100)); + }), + withToString("byte[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> BYTE_GENERATOR_PAIRS = @@ -1028,6 +1089,12 @@ public class Byte128VectorTests extends AbstractVectorTest { flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> BYTE_SATURATING_GENERATOR_TRIPLETS = + Stream.of(BYTE_GENERATORS.get(1)) + .flatMap(fa -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1064,6 +1131,22 @@ public class Byte128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocProvider() { + return BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] byteIndexedOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3420,6 +3503,51 @@ public class Byte128VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Byte128VectorTests::max); } + @Test(dataProvider = "byteSaturatingBinaryOpAssocProvider") + static void SUADDAssocByte128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Byte128VectorTests::SUADD); + } + + @Test(dataProvider = "byteSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocByte128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Byte128VectorTests::SUADD); + } static byte ANDReduce(byte[] a, int idx) { byte res = -1; diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java index 22d645b2502..17ab56f2540 100644 --- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java @@ -405,6 +405,52 @@ public class Byte256VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(byte[] r, byte[] a, byte[] b, FBinOp f) { int i = 0; try { @@ -1016,6 +1062,21 @@ public class Byte256VectorTests extends AbstractVectorTest { }) ); + static final List> BYTE_SATURATING_GENERATORS_ASSOC = List.of( + withToString("byte[Byte.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE)); + }), + withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE - 100)); + }), + withToString("byte[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> BYTE_GENERATOR_PAIRS = @@ -1028,6 +1089,12 @@ public class Byte256VectorTests extends AbstractVectorTest { flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> BYTE_SATURATING_GENERATOR_TRIPLETS = + Stream.of(BYTE_GENERATORS.get(1)) + .flatMap(fa -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1064,6 +1131,22 @@ public class Byte256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocProvider() { + return BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] byteIndexedOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3420,6 +3503,51 @@ public class Byte256VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Byte256VectorTests::max); } + @Test(dataProvider = "byteSaturatingBinaryOpAssocProvider") + static void SUADDAssocByte256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Byte256VectorTests::SUADD); + } + + @Test(dataProvider = "byteSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocByte256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Byte256VectorTests::SUADD); + } static byte ANDReduce(byte[] a, int idx) { byte res = -1; diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java index 738d6898374..4c43b995c2f 100644 --- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java @@ -405,6 +405,52 @@ public class Byte512VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(byte[] r, byte[] a, byte[] b, FBinOp f) { int i = 0; try { @@ -1016,6 +1062,21 @@ public class Byte512VectorTests extends AbstractVectorTest { }) ); + static final List> BYTE_SATURATING_GENERATORS_ASSOC = List.of( + withToString("byte[Byte.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE)); + }), + withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE - 100)); + }), + withToString("byte[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> BYTE_GENERATOR_PAIRS = @@ -1028,6 +1089,12 @@ public class Byte512VectorTests extends AbstractVectorTest { flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> BYTE_SATURATING_GENERATOR_TRIPLETS = + Stream.of(BYTE_GENERATORS.get(1)) + .flatMap(fa -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1064,6 +1131,22 @@ public class Byte512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocProvider() { + return BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] byteIndexedOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3420,6 +3503,51 @@ public class Byte512VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Byte512VectorTests::max); } + @Test(dataProvider = "byteSaturatingBinaryOpAssocProvider") + static void SUADDAssocByte512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Byte512VectorTests::SUADD); + } + + @Test(dataProvider = "byteSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocByte512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Byte512VectorTests::SUADD); + } static byte ANDReduce(byte[] a, int idx) { byte res = -1; diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java index 6d80672f3eb..d30afe30fe2 100644 --- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java @@ -405,6 +405,52 @@ public class Byte64VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(byte[] r, byte[] a, byte[] b, FBinOp f) { int i = 0; try { @@ -1016,6 +1062,21 @@ public class Byte64VectorTests extends AbstractVectorTest { }) ); + static final List> BYTE_SATURATING_GENERATORS_ASSOC = List.of( + withToString("byte[Byte.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE)); + }), + withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE - 100)); + }), + withToString("byte[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> BYTE_GENERATOR_PAIRS = @@ -1028,6 +1089,12 @@ public class Byte64VectorTests extends AbstractVectorTest { flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> BYTE_SATURATING_GENERATOR_TRIPLETS = + Stream.of(BYTE_GENERATORS.get(1)) + .flatMap(fa -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1064,6 +1131,22 @@ public class Byte64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocProvider() { + return BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] byteIndexedOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3420,6 +3503,51 @@ public class Byte64VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Byte64VectorTests::max); } + @Test(dataProvider = "byteSaturatingBinaryOpAssocProvider") + static void SUADDAssocByte64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Byte64VectorTests::SUADD); + } + + @Test(dataProvider = "byteSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocByte64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Byte64VectorTests::SUADD); + } static byte ANDReduce(byte[] a, int idx) { byte res = -1; diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java index 276ee98fd62..8738191f5ca 100644 --- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java @@ -410,6 +410,52 @@ public class ByteMaxVectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(byte[] rl, byte[] rr, byte[] a, byte[] b, byte[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(byte[] r, byte[] a, byte[] b, FBinOp f) { int i = 0; try { @@ -1021,6 +1067,21 @@ public class ByteMaxVectorTests extends AbstractVectorTest { }) ); + static final List> BYTE_SATURATING_GENERATORS_ASSOC = List.of( + withToString("byte[Byte.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE)); + }), + withToString("byte[Byte.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(Byte.MAX_VALUE - 100)); + }), + withToString("byte[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (byte)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> BYTE_GENERATOR_PAIRS = @@ -1033,6 +1094,12 @@ public class ByteMaxVectorTests extends AbstractVectorTest { flatMap(fa -> BYTE_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> BYTE_SATURATING_GENERATOR_TRIPLETS = + Stream.of(BYTE_GENERATORS.get(1)) + .flatMap(fa -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> BYTE_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1069,6 +1136,22 @@ public class ByteMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocProvider() { + return BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] byteSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> BYTE_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] byteIndexedOpProvider() { return BYTE_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3425,6 +3508,51 @@ public class ByteMaxVectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, ByteMaxVectorTests::max); } + @Test(dataProvider = "byteSaturatingBinaryOpAssocProvider") + static void SUADDAssocByteMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, ByteMaxVectorTests::SUADD); + } + + @Test(dataProvider = "byteSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocByteMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + byte[] a = fa.apply(SPECIES.length()); + byte[] b = fb.apply(SPECIES.length()); + byte[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + byte[] rl = fr.apply(SPECIES.length()); + byte[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ByteVector av = ByteVector.fromArray(SPECIES, a, i); + ByteVector bv = ByteVector.fromArray(SPECIES, b, i); + ByteVector cv = ByteVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, ByteMaxVectorTests::SUADD); + } static byte ANDReduce(byte[] a, int idx) { byte res = -1; diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java index 9aea4137a3c..f15ce88ddb8 100644 --- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java index b0d9825fa9d..e6c3662e0ad 100644 --- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java index 672c943bae2..7c37c9878e8 100644 --- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java index 415763c5882..85b96288b37 100644 --- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java index 992f16006db..7245990d66c 100644 --- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java @@ -428,6 +428,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java index 4fc6d1bdb45..c4f4ed1b966 100644 --- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(float[] r, float[] a, float[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java index 59104c40b9e..87cbc165d59 100644 --- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(float[] r, float[] a, float[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java index 3cc45a88e84..beb9561d882 100644 --- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(float[] r, float[] a, float[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java index 70aaeb134a6..ee630abd8e0 100644 --- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java @@ -423,6 +423,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(float[] r, float[] a, float[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java index c22b2d329f1..41e4d6e4a5d 100644 --- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java @@ -428,6 +428,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(float[] rl, float[] rr, float[] a, float[] b, float[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(float[] r, float[] a, float[] b, FBinOp f) { int i = 0; try { diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java index a88dcf27888..0bd77cc1008 100644 --- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java @@ -405,6 +405,52 @@ public class Int128VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(int[] r, int[] a, int[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Int128VectorTests extends AbstractVectorTest { }) ); + static final List> INT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("int[Integer.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE)); + }), + withToString("int[Integer.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE - 100)); + }), + withToString("int[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> INT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Int128VectorTests extends AbstractVectorTest { flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> INT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(INT_GENERATORS.get(1)) + .flatMap(fa -> INT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> INT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Int128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSaturatingBinaryOpAssocProvider() { + return INT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] intSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] intIndexedOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3464,6 +3547,51 @@ public class Int128VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Int128VectorTests::max); } + @Test(dataProvider = "intSaturatingBinaryOpAssocProvider") + static void SUADDAssocInt128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Int128VectorTests::SUADD); + } + + @Test(dataProvider = "intSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocInt128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Int128VectorTests::SUADD); + } static int ANDReduce(int[] a, int idx) { int res = -1; diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java index 1b88adf9c21..a4a0a2bd88e 100644 --- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java @@ -405,6 +405,52 @@ public class Int256VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(int[] r, int[] a, int[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Int256VectorTests extends AbstractVectorTest { }) ); + static final List> INT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("int[Integer.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE)); + }), + withToString("int[Integer.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE - 100)); + }), + withToString("int[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> INT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Int256VectorTests extends AbstractVectorTest { flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> INT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(INT_GENERATORS.get(1)) + .flatMap(fa -> INT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> INT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Int256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSaturatingBinaryOpAssocProvider() { + return INT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] intSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] intIndexedOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3464,6 +3547,51 @@ public class Int256VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Int256VectorTests::max); } + @Test(dataProvider = "intSaturatingBinaryOpAssocProvider") + static void SUADDAssocInt256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Int256VectorTests::SUADD); + } + + @Test(dataProvider = "intSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocInt256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Int256VectorTests::SUADD); + } static int ANDReduce(int[] a, int idx) { int res = -1; diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java index a9da97d66ce..0679b410e59 100644 --- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java @@ -405,6 +405,52 @@ public class Int512VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(int[] r, int[] a, int[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Int512VectorTests extends AbstractVectorTest { }) ); + static final List> INT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("int[Integer.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE)); + }), + withToString("int[Integer.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE - 100)); + }), + withToString("int[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> INT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Int512VectorTests extends AbstractVectorTest { flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> INT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(INT_GENERATORS.get(1)) + .flatMap(fa -> INT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> INT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Int512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSaturatingBinaryOpAssocProvider() { + return INT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] intSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] intIndexedOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3464,6 +3547,51 @@ public class Int512VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Int512VectorTests::max); } + @Test(dataProvider = "intSaturatingBinaryOpAssocProvider") + static void SUADDAssocInt512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Int512VectorTests::SUADD); + } + + @Test(dataProvider = "intSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocInt512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Int512VectorTests::SUADD); + } static int ANDReduce(int[] a, int idx) { int res = -1; diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java index b41bf7b95d5..c77e246473b 100644 --- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java @@ -405,6 +405,52 @@ public class Int64VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(int[] r, int[] a, int[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Int64VectorTests extends AbstractVectorTest { }) ); + static final List> INT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("int[Integer.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE)); + }), + withToString("int[Integer.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE - 100)); + }), + withToString("int[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> INT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Int64VectorTests extends AbstractVectorTest { flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> INT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(INT_GENERATORS.get(1)) + .flatMap(fa -> INT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> INT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Int64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSaturatingBinaryOpAssocProvider() { + return INT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] intSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] intIndexedOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3464,6 +3547,51 @@ public class Int64VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Int64VectorTests::max); } + @Test(dataProvider = "intSaturatingBinaryOpAssocProvider") + static void SUADDAssocInt64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Int64VectorTests::SUADD); + } + + @Test(dataProvider = "intSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocInt64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Int64VectorTests::SUADD); + } static int ANDReduce(int[] a, int idx) { int res = -1; diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java index d2b910ba8ae..4f7338c50cb 100644 --- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java @@ -410,6 +410,52 @@ public class IntMaxVectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(int[] rl, int[] rr, int[] a, int[] b, int[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(int[] r, int[] a, int[] b, FBinOp f) { int i = 0; try { @@ -1011,6 +1057,21 @@ public class IntMaxVectorTests extends AbstractVectorTest { }) ); + static final List> INT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("int[Integer.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE)); + }), + withToString("int[Integer.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(Integer.MAX_VALUE - 100)); + }), + withToString("int[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (int)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> INT_GENERATOR_PAIRS = @@ -1023,6 +1084,12 @@ public class IntMaxVectorTests extends AbstractVectorTest { flatMap(fa -> INT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> INT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(INT_GENERATORS.get(1)) + .flatMap(fa -> INT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> INT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1059,6 +1126,22 @@ public class IntMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] intSaturatingBinaryOpAssocProvider() { + return INT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] intSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> INT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] intIndexedOpProvider() { return INT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3469,6 +3552,51 @@ public class IntMaxVectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, IntMaxVectorTests::max); } + @Test(dataProvider = "intSaturatingBinaryOpAssocProvider") + static void SUADDAssocIntMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, IntMaxVectorTests::SUADD); + } + + @Test(dataProvider = "intSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocIntMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + int[] a = fa.apply(SPECIES.length()); + int[] b = fb.apply(SPECIES.length()); + int[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + int[] rl = fr.apply(SPECIES.length()); + int[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + IntVector av = IntVector.fromArray(SPECIES, a, i); + IntVector bv = IntVector.fromArray(SPECIES, b, i); + IntVector cv = IntVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, IntMaxVectorTests::SUADD); + } static int ANDReduce(int[] a, int idx) { int res = -1; diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java index 5bc29f498ba..01cac6a505e 100644 --- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java @@ -362,6 +362,52 @@ public class Long128VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(long[] r, long[] a, long[] b, FBinOp f) { int i = 0; try { @@ -996,6 +1042,21 @@ public class Long128VectorTests extends AbstractVectorTest { }) ); + static final List> LONG_SATURATING_GENERATORS_ASSOC = List.of( + withToString("long[Long.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE)); + }), + withToString("long[Long.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE - 100)); + }), + withToString("long[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> LONG_GENERATOR_PAIRS = @@ -1008,6 +1069,12 @@ public class Long128VectorTests extends AbstractVectorTest { flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> LONG_SATURATING_GENERATOR_TRIPLETS = + Stream.of(LONG_GENERATORS.get(1)) + .flatMap(fa -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1044,6 +1111,22 @@ public class Long128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSaturatingBinaryOpAssocProvider() { + return LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] longSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] longIndexedOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3486,6 +3569,51 @@ public class Long128VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Long128VectorTests::max); } + @Test(dataProvider = "longSaturatingBinaryOpAssocProvider") + static void SUADDAssocLong128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Long128VectorTests::SUADD); + } + + @Test(dataProvider = "longSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocLong128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Long128VectorTests::SUADD); + } static long ANDReduce(long[] a, int idx) { long res = -1; diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java index 25a73d1916e..9e571c3cbe9 100644 --- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java @@ -362,6 +362,52 @@ public class Long256VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(long[] r, long[] a, long[] b, FBinOp f) { int i = 0; try { @@ -996,6 +1042,21 @@ public class Long256VectorTests extends AbstractVectorTest { }) ); + static final List> LONG_SATURATING_GENERATORS_ASSOC = List.of( + withToString("long[Long.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE)); + }), + withToString("long[Long.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE - 100)); + }), + withToString("long[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> LONG_GENERATOR_PAIRS = @@ -1008,6 +1069,12 @@ public class Long256VectorTests extends AbstractVectorTest { flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> LONG_SATURATING_GENERATOR_TRIPLETS = + Stream.of(LONG_GENERATORS.get(1)) + .flatMap(fa -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1044,6 +1111,22 @@ public class Long256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSaturatingBinaryOpAssocProvider() { + return LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] longSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] longIndexedOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3486,6 +3569,51 @@ public class Long256VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Long256VectorTests::max); } + @Test(dataProvider = "longSaturatingBinaryOpAssocProvider") + static void SUADDAssocLong256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Long256VectorTests::SUADD); + } + + @Test(dataProvider = "longSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocLong256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Long256VectorTests::SUADD); + } static long ANDReduce(long[] a, int idx) { long res = -1; diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java index dab8ac0621a..5cb3cc32a68 100644 --- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java @@ -362,6 +362,52 @@ public class Long512VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(long[] r, long[] a, long[] b, FBinOp f) { int i = 0; try { @@ -996,6 +1042,21 @@ public class Long512VectorTests extends AbstractVectorTest { }) ); + static final List> LONG_SATURATING_GENERATORS_ASSOC = List.of( + withToString("long[Long.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE)); + }), + withToString("long[Long.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE - 100)); + }), + withToString("long[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> LONG_GENERATOR_PAIRS = @@ -1008,6 +1069,12 @@ public class Long512VectorTests extends AbstractVectorTest { flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> LONG_SATURATING_GENERATOR_TRIPLETS = + Stream.of(LONG_GENERATORS.get(1)) + .flatMap(fa -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1044,6 +1111,22 @@ public class Long512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSaturatingBinaryOpAssocProvider() { + return LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] longSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] longIndexedOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3486,6 +3569,51 @@ public class Long512VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Long512VectorTests::max); } + @Test(dataProvider = "longSaturatingBinaryOpAssocProvider") + static void SUADDAssocLong512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Long512VectorTests::SUADD); + } + + @Test(dataProvider = "longSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocLong512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Long512VectorTests::SUADD); + } static long ANDReduce(long[] a, int idx) { long res = -1; diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java index f62ffc6554c..d5595395b0a 100644 --- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java @@ -362,6 +362,52 @@ public class Long64VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(long[] r, long[] a, long[] b, FBinOp f) { int i = 0; try { @@ -996,6 +1042,21 @@ public class Long64VectorTests extends AbstractVectorTest { }) ); + static final List> LONG_SATURATING_GENERATORS_ASSOC = List.of( + withToString("long[Long.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE)); + }), + withToString("long[Long.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE - 100)); + }), + withToString("long[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> LONG_GENERATOR_PAIRS = @@ -1008,6 +1069,12 @@ public class Long64VectorTests extends AbstractVectorTest { flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> LONG_SATURATING_GENERATOR_TRIPLETS = + Stream.of(LONG_GENERATORS.get(1)) + .flatMap(fa -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1044,6 +1111,22 @@ public class Long64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSaturatingBinaryOpAssocProvider() { + return LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] longSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] longIndexedOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3486,6 +3569,51 @@ public class Long64VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Long64VectorTests::max); } + @Test(dataProvider = "longSaturatingBinaryOpAssocProvider") + static void SUADDAssocLong64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Long64VectorTests::SUADD); + } + + @Test(dataProvider = "longSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocLong64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Long64VectorTests::SUADD); + } static long ANDReduce(long[] a, int idx) { long res = -1; diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java index 70441d0d763..cec3e0756b2 100644 --- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java @@ -367,6 +367,52 @@ public class LongMaxVectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(long[] rl, long[] rr, long[] a, long[] b, long[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(long[] r, long[] a, long[] b, FBinOp f) { int i = 0; try { @@ -1001,6 +1047,21 @@ public class LongMaxVectorTests extends AbstractVectorTest { }) ); + static final List> LONG_SATURATING_GENERATORS_ASSOC = List.of( + withToString("long[Long.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE)); + }), + withToString("long[Long.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(Long.MAX_VALUE - 100)); + }), + withToString("long[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (long)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> LONG_GENERATOR_PAIRS = @@ -1013,6 +1074,12 @@ public class LongMaxVectorTests extends AbstractVectorTest { flatMap(fa -> LONG_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> LONG_SATURATING_GENERATOR_TRIPLETS = + Stream.of(LONG_GENERATORS.get(1)) + .flatMap(fa -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> LONG_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1049,6 +1116,22 @@ public class LongMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] longSaturatingBinaryOpAssocProvider() { + return LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] longSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> LONG_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] longIndexedOpProvider() { return LONG_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3491,6 +3574,51 @@ public class LongMaxVectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, LongMaxVectorTests::max); } + @Test(dataProvider = "longSaturatingBinaryOpAssocProvider") + static void SUADDAssocLongMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, LongMaxVectorTests::SUADD); + } + + @Test(dataProvider = "longSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocLongMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + long[] a = fa.apply(SPECIES.length()); + long[] b = fb.apply(SPECIES.length()); + long[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + long[] rl = fr.apply(SPECIES.length()); + long[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + LongVector av = LongVector.fromArray(SPECIES, a, i); + LongVector bv = LongVector.fromArray(SPECIES, b, i); + LongVector cv = LongVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, LongMaxVectorTests::SUADD); + } static long ANDReduce(long[] a, int idx) { long res = -1; diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java index b4240dabc87..1ce486eb709 100644 --- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java @@ -405,6 +405,52 @@ public class Short128VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(short[] r, short[] a, short[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Short128VectorTests extends AbstractVectorTest { }) ); + static final List> SHORT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("short[Short.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE)); + }), + withToString("short[Short.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE - 100)); + }), + withToString("short[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> SHORT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Short128VectorTests extends AbstractVectorTest { flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> SHORT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(SHORT_GENERATORS.get(1)) + .flatMap(fa -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Short128VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocProvider() { + return SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] shortIndexedOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3411,6 +3494,51 @@ public class Short128VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Short128VectorTests::max); } + @Test(dataProvider = "shortSaturatingBinaryOpAssocProvider") + static void SUADDAssocShort128VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Short128VectorTests::SUADD); + } + + @Test(dataProvider = "shortSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocShort128VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Short128VectorTests::SUADD); + } static short ANDReduce(short[] a, int idx) { short res = -1; diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java index 902cac11eb6..8361c59923f 100644 --- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java @@ -405,6 +405,52 @@ public class Short256VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(short[] r, short[] a, short[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Short256VectorTests extends AbstractVectorTest { }) ); + static final List> SHORT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("short[Short.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE)); + }), + withToString("short[Short.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE - 100)); + }), + withToString("short[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> SHORT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Short256VectorTests extends AbstractVectorTest { flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> SHORT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(SHORT_GENERATORS.get(1)) + .flatMap(fa -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Short256VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocProvider() { + return SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] shortIndexedOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3411,6 +3494,51 @@ public class Short256VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Short256VectorTests::max); } + @Test(dataProvider = "shortSaturatingBinaryOpAssocProvider") + static void SUADDAssocShort256VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Short256VectorTests::SUADD); + } + + @Test(dataProvider = "shortSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocShort256VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Short256VectorTests::SUADD); + } static short ANDReduce(short[] a, int idx) { short res = -1; diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java index 39ab2da2925..a9c1a5eb7ed 100644 --- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java @@ -405,6 +405,52 @@ public class Short512VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(short[] r, short[] a, short[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Short512VectorTests extends AbstractVectorTest { }) ); + static final List> SHORT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("short[Short.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE)); + }), + withToString("short[Short.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE - 100)); + }), + withToString("short[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> SHORT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Short512VectorTests extends AbstractVectorTest { flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> SHORT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(SHORT_GENERATORS.get(1)) + .flatMap(fa -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Short512VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocProvider() { + return SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] shortIndexedOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3411,6 +3494,51 @@ public class Short512VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Short512VectorTests::max); } + @Test(dataProvider = "shortSaturatingBinaryOpAssocProvider") + static void SUADDAssocShort512VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Short512VectorTests::SUADD); + } + + @Test(dataProvider = "shortSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocShort512VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Short512VectorTests::SUADD); + } static short ANDReduce(short[] a, int idx) { short res = -1; diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java index ff3cea2e051..d10b4ca7196 100644 --- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java +++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java @@ -405,6 +405,52 @@ public class Short64VectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(short[] r, short[] a, short[] b, FBinOp f) { int i = 0; try { @@ -1006,6 +1052,21 @@ public class Short64VectorTests extends AbstractVectorTest { }) ); + static final List> SHORT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("short[Short.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE)); + }), + withToString("short[Short.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE - 100)); + }), + withToString("short[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> SHORT_GENERATOR_PAIRS = @@ -1018,6 +1079,12 @@ public class Short64VectorTests extends AbstractVectorTest { flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> SHORT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(SHORT_GENERATORS.get(1)) + .flatMap(fa -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1054,6 +1121,22 @@ public class Short64VectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocProvider() { + return SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] shortIndexedOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3411,6 +3494,51 @@ public class Short64VectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, Short64VectorTests::max); } + @Test(dataProvider = "shortSaturatingBinaryOpAssocProvider") + static void SUADDAssocShort64VectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, Short64VectorTests::SUADD); + } + + @Test(dataProvider = "shortSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocShort64VectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, Short64VectorTests::SUADD); + } static short ANDReduce(short[] a, int idx) { short res = -1; diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java index 25b219f8abc..cca15c4e941 100644 --- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java +++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java @@ -410,6 +410,52 @@ public class ShortMaxVectorTests extends AbstractVectorTest { } } + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative(short[] rl, short[] rr, short[] a, short[] b, short[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals(short[] r, short[] a, short[] b, FBinOp f) { int i = 0; try { @@ -1011,6 +1057,21 @@ public class ShortMaxVectorTests extends AbstractVectorTest { }) ); + static final List> SHORT_SATURATING_GENERATORS_ASSOC = List.of( + withToString("short[Short.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE)); + }), + withToString("short[Short.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(Short.MAX_VALUE - 100)); + }), + withToString("short[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> (short)(-1)); + }) + ); + // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 static final List>> SHORT_GENERATOR_PAIRS = @@ -1023,6 +1084,12 @@ public class ShortMaxVectorTests extends AbstractVectorTest { flatMap(fa -> SHORT_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> SHORT_SATURATING_GENERATOR_TRIPLETS = + Stream.of(SHORT_GENERATORS.get(1)) + .flatMap(fa -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> SHORT_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + @DataProvider public Object[][] boolUnaryOpProvider() { return BOOL_ARRAY_GENERATORS.stream(). @@ -1059,6 +1126,22 @@ public class ShortMaxVectorTests extends AbstractVectorTest { toArray(Object[][]::new); } + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocProvider() { + return SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] shortSaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> SHORT_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + @DataProvider public Object[][] shortIndexedOpProvider() { return SHORT_GENERATOR_PAIRS.stream().map(List::toArray). @@ -3416,6 +3499,51 @@ public class ShortMaxVectorTests extends AbstractVectorTest { assertBroadcastArraysEquals(r, a, b, ShortMaxVectorTests::max); } + @Test(dataProvider = "shortSaturatingBinaryOpAssocProvider") + static void SUADDAssocShortMaxVectorTests(IntFunction fa, IntFunction fb, IntFunction fc) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, ShortMaxVectorTests::SUADD); + } + + @Test(dataProvider = "shortSaturatingBinaryOpAssocMaskProvider") + static void SUADDAssocShortMaxVectorTestsMasked(IntFunction fa, IntFunction fb, + IntFunction fc, IntFunction fm) { + short[] a = fa.apply(SPECIES.length()); + short[] b = fb.apply(SPECIES.length()); + short[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + short[] rl = fr.apply(SPECIES.length()); + short[] rr = fr.apply(SPECIES.length()); + + VectorMask vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + ShortVector av = ShortVector.fromArray(SPECIES, a, i); + ShortVector bv = ShortVector.fromArray(SPECIES, b, i); + ShortVector cv = ShortVector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } + + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, ShortMaxVectorTests::SUADD); + } static short ANDReduce(short[] a, int idx) { short res = -1; diff --git a/test/jdk/jdk/incubator/vector/gen-template.sh b/test/jdk/jdk/incubator/vector/gen-template.sh index da5585b1305..71dc4a1ef0a 100644 --- a/test/jdk/jdk/incubator/vector/gen-template.sh +++ b/test/jdk/jdk/incubator/vector/gen-template.sh @@ -46,6 +46,8 @@ binary_memop="Binary-mem-op" binary_masked_memop="Binary-Masked-mem-op" saturating_binary="SaturatingBinary-op" saturating_binary_masked="SaturatingBinary-Masked-op" +saturating_binary_assocative="SaturatingBinary-op-associative" +saturating_binary_assocative_masked="SaturatingBinary-Masked-op-associative" binary_broadcast="Binary-Broadcast-op" binary_broadcast_masked="Binary-Broadcast-Masked-op" binary_broadcast_long="Binary-Broadcast-Long-op" @@ -326,6 +328,12 @@ function gen_saturating_binary_op { gen_op_tmpl $saturating_binary_masked "$@" } +function gen_saturating_binary_op_associative { + echo "Generating saturating binary associative op $1 ($2)..." + gen_op_tmpl $saturating_binary_assocative "$@" + gen_op_tmpl $saturating_binary_assocative_masked "$@" +} + function gen_binary_op_no_masked { echo "Generating binary op $1 ($2)..." # gen_op_tmpl $binary_scalar "$@" @@ -487,6 +495,7 @@ gen_saturating_binary_op "SUADD" "VectorMath.addSaturatingUnsigned(a, b)" "BITWI gen_saturating_binary_op "SUSUB" "VectorMath.subSaturatingUnsigned(a, b)" "BITWISE" gen_binary_bcst_op_no_masked "MIN+min" "Math.min(a, b)" gen_binary_bcst_op_no_masked "MAX+max" "Math.max(a, b)" +gen_saturating_binary_op_associative "SUADD" "VectorMath.addSaturatingUnsigned(a, b)" "BITWISE" # Reductions. gen_reduction_op "AND" "\&" "BITWISE" "-1" diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-Masked-op-associative.template b/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-Masked-op-associative.template new file mode 100644 index 00000000000..c79a8937f2c --- /dev/null +++ b/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-Masked-op-associative.template @@ -0,0 +1,18 @@ + $type$[] a = fa.apply(SPECIES.length()); + $type$[] b = fb.apply(SPECIES.length()); + $type$[] c = fc.apply(SPECIES.length()); + boolean[] mask = fm.apply(SPECIES.length()); + $type$[] rl = fr.apply(SPECIES.length()); + $type$[] rr = fr.apply(SPECIES.length()); + + VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i); + $abstractvectortype$ bv = $abstractvectortype$.fromArray(SPECIES, b, i); + $abstractvectortype$ cv = $abstractvectortype$.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv, vmask).lanewise(VectorOperators.SUADD, cv, vmask).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv, vmask), vmask).intoArray(rr, i); + } + } diff --git a/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-op-associative.template b/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-op-associative.template new file mode 100644 index 00000000000..a5b42239e4c --- /dev/null +++ b/test/jdk/jdk/incubator/vector/templates/Kernel-SaturatingBinary-op-associative.template @@ -0,0 +1,15 @@ + $type$[] a = fa.apply(SPECIES.length()); + $type$[] b = fb.apply(SPECIES.length()); + $type$[] c = fc.apply(SPECIES.length()); + $type$[] rl = fr.apply(SPECIES.length()); + $type$[] rr = fr.apply(SPECIES.length()); + + for (int ic = 0; ic < INVOC_COUNT; ic++) { + for (int i = 0; i < a.length; i += SPECIES.length()) { + $Type$Vector av = $Type$Vector.fromArray(SPECIES, a, i); + $Type$Vector bv = $Type$Vector.fromArray(SPECIES, b, i); + $Type$Vector cv = $Type$Vector.fromArray(SPECIES, c, i); + av.lanewise(VectorOperators.SUADD, bv).lanewise(VectorOperators.SUADD, cv).intoArray(rl, i); + av.lanewise(VectorOperators.SUADD, bv.lanewise(VectorOperators.SUADD, cv)).intoArray(rr, i); + } + } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-Masked-op-associative.template b/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-Masked-op-associative.template new file mode 100644 index 00000000000..8670e39e60d --- /dev/null +++ b/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-Masked-op-associative.template @@ -0,0 +1,7 @@ + + @Test(dataProvider = "$type$SaturatingBinaryOpAssocMaskProvider") + static void [[TEST]]Assoc$vectorteststype$Masked(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb, + IntFunction<$type$[]> fc, IntFunction fm) { +[[KERNEL]] + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, $vectorteststype$::[[TEST]]); + } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-op-associative.template b/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-op-associative.template new file mode 100644 index 00000000000..f4c7e5f74a4 --- /dev/null +++ b/test/jdk/jdk/incubator/vector/templates/Unit-SaturatingBinary-op-associative.template @@ -0,0 +1,5 @@ + @Test(dataProvider = "$type$SaturatingBinaryOpAssocProvider") + static void [[TEST]]Assoc$vectorteststype$(IntFunction<$type$[]> fa, IntFunction<$type$[]> fb, IntFunction<$type$[]> fc) { +[[KERNEL]] + assertArraysEqualsAssociative(rl, rr, a, b, c, $vectorteststype$::[[TEST]]); + } diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template index 66646b15918..d50267318f5 100644 --- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template +++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template @@ -502,6 +502,52 @@ relativeError)); } } + static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, FBinOp f) { + int i = 0; + try { + for (; i < a.length; i++) { + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i])); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i]))); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + + static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FBinOp f) { + assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f)); + } + + static void assertArraysEqualsAssociative($type$[] rl, $type$[] rr, $type$[] a, $type$[] b, $type$[] c, boolean[] mask, FBinMaskOp f) { + int i = 0; + boolean mask_bit = false; + try { + for (; i < a.length; i++) { + mask_bit = mask[i % SPECIES.length()]; + //Left associative + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit)); + + //Right associative + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit)); + + //Results equal sanity check + Assert.assertEquals(rl[i], rr[i]); + } + } catch (AssertionError e) { + Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit); + Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]); + } + } + static void assertArraysEquals($type$[] r, $type$[] a, $type$[] b, FBinOp f) { int i = 0; try { @@ -1278,6 +1324,21 @@ relativeError)); }) ); + static final List> $TYPE$_SATURATING_GENERATORS_ASSOC = List.of( + withToString("$type$[$Boxtype$.MAX_VALUE]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> ($type$)($Boxtype$.MAX_VALUE)); + }), + withToString("$type$[$Boxtype$.MAX_VALUE - 100]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> ($type$)($Boxtype$.MAX_VALUE - 100)); + }), + withToString("$type$[-1]", (int s) -> { + return fill(s * BUFFER_REPS, + i -> ($type$)(-1)); + }) + ); + #end[!FP] // Create combinations of pairs // @@@ Might be sensitive to order e.g. div by 0 @@ -1292,6 +1353,12 @@ relativeError)); flatMap(fa -> $TYPE$_SATURATING_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))). collect(Collectors.toList()); + static final List>> $TYPE$_SATURATING_GENERATOR_TRIPLETS = + Stream.of($TYPE$_GENERATORS.get(1)) + .flatMap(fa -> $TYPE$_SATURATING_GENERATORS_ASSOC.stream().map(fb -> List.of(fa, fb))) + .flatMap(pair -> $TYPE$_SATURATING_GENERATORS_ASSOC.stream().map(f -> List.of(pair.get(0), pair.get(1), f))) + .collect(Collectors.toList()); + #end[!FP] @DataProvider public Object[][] boolUnaryOpProvider() { @@ -1330,6 +1397,22 @@ relativeError)); toArray(Object[][]::new); } + @DataProvider + public Object[][] $type$SaturatingBinaryOpAssocProvider() { + return $TYPE$_SATURATING_GENERATOR_TRIPLETS.stream().map(List::toArray). + toArray(Object[][]::new); + } + + @DataProvider + public Object[][] $type$SaturatingBinaryOpAssocMaskProvider() { + return BOOLEAN_MASK_GENERATORS.stream(). + flatMap(fm -> $TYPE$_SATURATING_GENERATOR_TRIPLETS.stream().map(lfa -> { + return Stream.concat(lfa.stream(), Stream.of(fm)).toArray(); + })). + toArray(Object[][]::new); + } + + #end[!FP] @DataProvider public Object[][] $type$IndexedOpProvider() {