8372978: [VectorAPI] Fix incorrect identity values in UMIN/UMAX reductions

Reviewed-by: psandoz, qamai, xgong
This commit is contained in:
Eric Fang 2026-01-14 06:17:04 +00:00 committed by Xiaohong Gong
parent b082a390b7
commit 56d7b524b3
48 changed files with 10315 additions and 6432 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2873,9 +2873,9 @@ public abstract class ByteVector extends AbstractVector<Byte> {
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (byte) VectorMath.minUnsigned(a, b)));
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> (byte) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (byte) VectorMath.maxUnsigned(a, b)));
toBits(v.rOp(UMIN_VALUE, m, (i, a, b) -> (byte) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_SUADD: return (v, m) ->
toBits(v.rOp((byte)0, m, (i, a, b) -> (byte) VectorMath.addSaturatingUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
@ -2890,6 +2890,8 @@ public abstract class ByteVector extends AbstractVector<Byte> {
private static final byte MIN_OR_INF = Byte.MIN_VALUE;
private static final byte MAX_OR_INF = Byte.MAX_VALUE;
private static final byte UMIN_VALUE = (byte)0; // Minimum unsigned value
private static final byte UMAX_VALUE = (byte)-1; // Maximum unsigned value
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2858,9 +2858,9 @@ public abstract class IntVector extends AbstractVector<Integer> {
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (int) VectorMath.minUnsigned(a, b)));
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> (int) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (int) VectorMath.maxUnsigned(a, b)));
toBits(v.rOp(UMIN_VALUE, m, (i, a, b) -> (int) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_SUADD: return (v, m) ->
toBits(v.rOp((int)0, m, (i, a, b) -> (int) VectorMath.addSaturatingUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
@ -2875,6 +2875,8 @@ public abstract class IntVector extends AbstractVector<Integer> {
private static final int MIN_OR_INF = Integer.MIN_VALUE;
private static final int MAX_OR_INF = Integer.MAX_VALUE;
private static final int UMIN_VALUE = (int)0; // Minimum unsigned value
private static final int UMAX_VALUE = (int)-1; // Maximum unsigned value
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2724,9 +2724,9 @@ public abstract class LongVector extends AbstractVector<Long> {
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) VectorMath.minUnsigned(a, b)));
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> (long) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) VectorMath.maxUnsigned(a, b)));
toBits(v.rOp(UMIN_VALUE, m, (i, a, b) -> (long) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_SUADD: return (v, m) ->
toBits(v.rOp((long)0, m, (i, a, b) -> (long) VectorMath.addSaturatingUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
@ -2741,6 +2741,8 @@ public abstract class LongVector extends AbstractVector<Long> {
private static final long MIN_OR_INF = Long.MIN_VALUE;
private static final long MAX_OR_INF = Long.MAX_VALUE;
private static final long UMIN_VALUE = (long)0; // Minimum unsigned value
private static final long UMAX_VALUE = (long)-1; // Maximum unsigned value
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2874,9 +2874,9 @@ public abstract class ShortVector extends AbstractVector<Short> {
case VECTOR_OP_MAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) Math.max(a, b)));
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) VectorMath.minUnsigned(a, b)));
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> (short) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) VectorMath.maxUnsigned(a, b)));
toBits(v.rOp(UMIN_VALUE, m, (i, a, b) -> (short) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_SUADD: return (v, m) ->
toBits(v.rOp((short)0, m, (i, a, b) -> (short) VectorMath.addSaturatingUnsigned(a, b)));
case VECTOR_OP_AND: return (v, m) ->
@ -2891,6 +2891,8 @@ public abstract class ShortVector extends AbstractVector<Short> {
private static final short MIN_OR_INF = Short.MIN_VALUE;
private static final short MAX_OR_INF = Short.MAX_VALUE;
private static final short UMIN_VALUE = (short)0; // Minimum unsigned value
private static final short UMAX_VALUE = (short)-1; // Maximum unsigned value
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -3448,9 +3448,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) Math.max(a, b)));
#if[!FP]
case VECTOR_OP_UMIN: return (v, m) ->
toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> ($type$) VectorMath.minUnsigned(a, b)));
toBits(v.rOp(UMAX_VALUE, m, (i, a, b) -> ($type$) VectorMath.minUnsigned(a, b)));
case VECTOR_OP_UMAX: return (v, m) ->
toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> ($type$) VectorMath.maxUnsigned(a, b)));
toBits(v.rOp(UMIN_VALUE, m, (i, a, b) -> ($type$) VectorMath.maxUnsigned(a, b)));
case VECTOR_OP_SUADD: return (v, m) ->
toBits(v.rOp(($type$)0, m, (i, a, b) -> ($type$) VectorMath.addSaturatingUnsigned(a, b)));
#end[!FP]
@ -3472,6 +3472,8 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
#else[FP]
private static final $type$ MIN_OR_INF = $Boxtype$.MIN_VALUE;
private static final $type$ MAX_OR_INF = $Boxtype$.MAX_VALUE;
private static final $type$ UMIN_VALUE = ($type$)0; // Minimum unsigned value
private static final $type$ UMAX_VALUE = ($type$)-1; // Maximum unsigned value
#end[FP]
public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Double128VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final double ADD_IDENTITY = (double)0;
private static final double FIRST_NONZERO_IDENTITY = (double)0;
private static final double MAX_IDENTITY = Double.NEGATIVE_INFINITY;
private static final double MIN_IDENTITY = Double.POSITIVE_INFINITY;
private static final double MUL_IDENTITY = (double)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
@ -2384,7 +2390,7 @@ relativeError));
}
static double ADDReduce(double[] a, int idx) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2393,7 +2399,7 @@ relativeError));
}
static double ADDReduceAll(double[] a) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2408,17 +2414,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
double v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2426,8 +2427,31 @@ relativeError));
Double128VectorTests::ADDReduce, Double128VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = ADD_IDENTITY;
Assert.assertEquals((double) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id + x), x);
Assert.assertEquals((double) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2437,7 +2461,7 @@ relativeError));
}
static double ADDReduceAllMasked(double[] a, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2454,17 +2478,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
double v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2473,7 +2492,7 @@ relativeError));
}
static double MULReduce(double[] a, int idx) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2482,7 +2501,7 @@ relativeError));
}
static double MULReduceAll(double[] a) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2494,20 +2513,15 @@ relativeError));
static void MULReduceDouble128VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
double v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2515,8 +2529,31 @@ relativeError));
Double128VectorTests::MULReduce, Double128VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MUL_IDENTITY;
Assert.assertEquals((double) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id * x), x);
Assert.assertEquals((double) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2526,7 +2563,7 @@ relativeError));
}
static double MULReduceAllMasked(double[] a, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2540,20 +2577,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
double v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2562,7 +2594,7 @@ relativeError));
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.min(res, a[i]);
}
@ -2571,7 +2603,7 @@ relativeError));
}
static double MINReduceAll(double[] a) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduce(a, i));
}
@ -2583,20 +2615,15 @@ relativeError));
static void MINReduceDouble128VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
double v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2604,8 +2631,31 @@ relativeError));
Double128VectorTests::MINReduce, Double128VectorTests::MINReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MIN_IDENTITY;
Assert.assertEquals((double) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.min(id, x), x);
Assert.assertEquals((double) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.min(res, a[i]);
@ -2615,7 +2665,7 @@ relativeError));
}
static double MINReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2629,20 +2679,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
double v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2651,7 +2696,7 @@ relativeError));
}
static double MAXReduce(double[] a, int idx) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.max(res, a[i]);
}
@ -2660,7 +2705,7 @@ relativeError));
}
static double MAXReduceAll(double[] a) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduce(a, i));
}
@ -2672,20 +2717,15 @@ relativeError));
static void MAXReduceDouble128VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
double v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2693,8 +2733,31 @@ relativeError));
Double128VectorTests::MAXReduce, Double128VectorTests::MAXReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MAX_IDENTITY;
Assert.assertEquals((double) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.max(id, x), x);
Assert.assertEquals((double) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.max(res, a[i]);
@ -2704,7 +2767,7 @@ relativeError));
}
static double MAXReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2718,20 +2781,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
double v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2740,7 +2798,7 @@ relativeError));
}
static double FIRST_NONZEROReduce(double[] a, int idx) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2749,7 +2807,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAll(double[] a) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2761,20 +2819,15 @@ relativeError));
static void FIRST_NONZEROReduceDouble128VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2782,8 +2835,31 @@ relativeError));
Double128VectorTests::FIRST_NONZEROReduce, Double128VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2793,7 +2869,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2807,20 +2883,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Double256VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final double ADD_IDENTITY = (double)0;
private static final double FIRST_NONZERO_IDENTITY = (double)0;
private static final double MAX_IDENTITY = Double.NEGATIVE_INFINITY;
private static final double MIN_IDENTITY = Double.POSITIVE_INFINITY;
private static final double MUL_IDENTITY = (double)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
@ -2384,7 +2390,7 @@ relativeError));
}
static double ADDReduce(double[] a, int idx) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2393,7 +2399,7 @@ relativeError));
}
static double ADDReduceAll(double[] a) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2408,17 +2414,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
double v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2426,8 +2427,31 @@ relativeError));
Double256VectorTests::ADDReduce, Double256VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = ADD_IDENTITY;
Assert.assertEquals((double) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id + x), x);
Assert.assertEquals((double) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2437,7 +2461,7 @@ relativeError));
}
static double ADDReduceAllMasked(double[] a, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2454,17 +2478,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
double v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2473,7 +2492,7 @@ relativeError));
}
static double MULReduce(double[] a, int idx) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2482,7 +2501,7 @@ relativeError));
}
static double MULReduceAll(double[] a) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2494,20 +2513,15 @@ relativeError));
static void MULReduceDouble256VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
double v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2515,8 +2529,31 @@ relativeError));
Double256VectorTests::MULReduce, Double256VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MUL_IDENTITY;
Assert.assertEquals((double) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id * x), x);
Assert.assertEquals((double) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2526,7 +2563,7 @@ relativeError));
}
static double MULReduceAllMasked(double[] a, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2540,20 +2577,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
double v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2562,7 +2594,7 @@ relativeError));
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.min(res, a[i]);
}
@ -2571,7 +2603,7 @@ relativeError));
}
static double MINReduceAll(double[] a) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduce(a, i));
}
@ -2583,20 +2615,15 @@ relativeError));
static void MINReduceDouble256VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
double v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2604,8 +2631,31 @@ relativeError));
Double256VectorTests::MINReduce, Double256VectorTests::MINReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MIN_IDENTITY;
Assert.assertEquals((double) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.min(id, x), x);
Assert.assertEquals((double) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.min(res, a[i]);
@ -2615,7 +2665,7 @@ relativeError));
}
static double MINReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2629,20 +2679,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
double v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2651,7 +2696,7 @@ relativeError));
}
static double MAXReduce(double[] a, int idx) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.max(res, a[i]);
}
@ -2660,7 +2705,7 @@ relativeError));
}
static double MAXReduceAll(double[] a) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduce(a, i));
}
@ -2672,20 +2717,15 @@ relativeError));
static void MAXReduceDouble256VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
double v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2693,8 +2733,31 @@ relativeError));
Double256VectorTests::MAXReduce, Double256VectorTests::MAXReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MAX_IDENTITY;
Assert.assertEquals((double) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.max(id, x), x);
Assert.assertEquals((double) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.max(res, a[i]);
@ -2704,7 +2767,7 @@ relativeError));
}
static double MAXReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2718,20 +2781,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
double v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2740,7 +2798,7 @@ relativeError));
}
static double FIRST_NONZEROReduce(double[] a, int idx) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2749,7 +2807,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAll(double[] a) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2761,20 +2819,15 @@ relativeError));
static void FIRST_NONZEROReduceDouble256VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2782,8 +2835,31 @@ relativeError));
Double256VectorTests::FIRST_NONZEROReduce, Double256VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2793,7 +2869,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2807,20 +2883,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Double512VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final double ADD_IDENTITY = (double)0;
private static final double FIRST_NONZERO_IDENTITY = (double)0;
private static final double MAX_IDENTITY = Double.NEGATIVE_INFINITY;
private static final double MIN_IDENTITY = Double.POSITIVE_INFINITY;
private static final double MUL_IDENTITY = (double)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
@ -2384,7 +2390,7 @@ relativeError));
}
static double ADDReduce(double[] a, int idx) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2393,7 +2399,7 @@ relativeError));
}
static double ADDReduceAll(double[] a) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2408,17 +2414,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
double v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2426,8 +2427,31 @@ relativeError));
Double512VectorTests::ADDReduce, Double512VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = ADD_IDENTITY;
Assert.assertEquals((double) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id + x), x);
Assert.assertEquals((double) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2437,7 +2461,7 @@ relativeError));
}
static double ADDReduceAllMasked(double[] a, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2454,17 +2478,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
double v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2473,7 +2492,7 @@ relativeError));
}
static double MULReduce(double[] a, int idx) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2482,7 +2501,7 @@ relativeError));
}
static double MULReduceAll(double[] a) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2494,20 +2513,15 @@ relativeError));
static void MULReduceDouble512VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
double v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2515,8 +2529,31 @@ relativeError));
Double512VectorTests::MULReduce, Double512VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MUL_IDENTITY;
Assert.assertEquals((double) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id * x), x);
Assert.assertEquals((double) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2526,7 +2563,7 @@ relativeError));
}
static double MULReduceAllMasked(double[] a, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2540,20 +2577,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
double v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2562,7 +2594,7 @@ relativeError));
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.min(res, a[i]);
}
@ -2571,7 +2603,7 @@ relativeError));
}
static double MINReduceAll(double[] a) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduce(a, i));
}
@ -2583,20 +2615,15 @@ relativeError));
static void MINReduceDouble512VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
double v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2604,8 +2631,31 @@ relativeError));
Double512VectorTests::MINReduce, Double512VectorTests::MINReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MIN_IDENTITY;
Assert.assertEquals((double) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.min(id, x), x);
Assert.assertEquals((double) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.min(res, a[i]);
@ -2615,7 +2665,7 @@ relativeError));
}
static double MINReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2629,20 +2679,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
double v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2651,7 +2696,7 @@ relativeError));
}
static double MAXReduce(double[] a, int idx) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.max(res, a[i]);
}
@ -2660,7 +2705,7 @@ relativeError));
}
static double MAXReduceAll(double[] a) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduce(a, i));
}
@ -2672,20 +2717,15 @@ relativeError));
static void MAXReduceDouble512VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
double v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2693,8 +2733,31 @@ relativeError));
Double512VectorTests::MAXReduce, Double512VectorTests::MAXReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MAX_IDENTITY;
Assert.assertEquals((double) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.max(id, x), x);
Assert.assertEquals((double) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.max(res, a[i]);
@ -2704,7 +2767,7 @@ relativeError));
}
static double MAXReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2718,20 +2781,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
double v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2740,7 +2798,7 @@ relativeError));
}
static double FIRST_NONZEROReduce(double[] a, int idx) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2749,7 +2807,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAll(double[] a) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2761,20 +2819,15 @@ relativeError));
static void FIRST_NONZEROReduceDouble512VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2782,8 +2835,31 @@ relativeError));
Double512VectorTests::FIRST_NONZEROReduce, Double512VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2793,7 +2869,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2807,20 +2883,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Double64VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final double ADD_IDENTITY = (double)0;
private static final double FIRST_NONZERO_IDENTITY = (double)0;
private static final double MAX_IDENTITY = Double.NEGATIVE_INFINITY;
private static final double MIN_IDENTITY = Double.POSITIVE_INFINITY;
private static final double MUL_IDENTITY = (double)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
@ -2384,7 +2390,7 @@ relativeError));
}
static double ADDReduce(double[] a, int idx) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2393,7 +2399,7 @@ relativeError));
}
static double ADDReduceAll(double[] a) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2408,17 +2414,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
double v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2426,8 +2427,31 @@ relativeError));
Double64VectorTests::ADDReduce, Double64VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = ADD_IDENTITY;
Assert.assertEquals((double) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id + x), x);
Assert.assertEquals((double) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2437,7 +2461,7 @@ relativeError));
}
static double ADDReduceAllMasked(double[] a, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2454,17 +2478,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
double v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2473,7 +2492,7 @@ relativeError));
}
static double MULReduce(double[] a, int idx) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2482,7 +2501,7 @@ relativeError));
}
static double MULReduceAll(double[] a) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2494,20 +2513,15 @@ relativeError));
static void MULReduceDouble64VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
double v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2515,8 +2529,31 @@ relativeError));
Double64VectorTests::MULReduce, Double64VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MUL_IDENTITY;
Assert.assertEquals((double) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id * x), x);
Assert.assertEquals((double) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2526,7 +2563,7 @@ relativeError));
}
static double MULReduceAllMasked(double[] a, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2540,20 +2577,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
double v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2562,7 +2594,7 @@ relativeError));
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.min(res, a[i]);
}
@ -2571,7 +2603,7 @@ relativeError));
}
static double MINReduceAll(double[] a) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduce(a, i));
}
@ -2583,20 +2615,15 @@ relativeError));
static void MINReduceDouble64VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
double v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2604,8 +2631,31 @@ relativeError));
Double64VectorTests::MINReduce, Double64VectorTests::MINReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MIN_IDENTITY;
Assert.assertEquals((double) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.min(id, x), x);
Assert.assertEquals((double) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.min(res, a[i]);
@ -2615,7 +2665,7 @@ relativeError));
}
static double MINReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2629,20 +2679,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
double v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2651,7 +2696,7 @@ relativeError));
}
static double MAXReduce(double[] a, int idx) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.max(res, a[i]);
}
@ -2660,7 +2705,7 @@ relativeError));
}
static double MAXReduceAll(double[] a) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduce(a, i));
}
@ -2672,20 +2717,15 @@ relativeError));
static void MAXReduceDouble64VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
double v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2693,8 +2733,31 @@ relativeError));
Double64VectorTests::MAXReduce, Double64VectorTests::MAXReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MAX_IDENTITY;
Assert.assertEquals((double) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.max(id, x), x);
Assert.assertEquals((double) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.max(res, a[i]);
@ -2704,7 +2767,7 @@ relativeError));
}
static double MAXReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2718,20 +2781,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
double v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2740,7 +2798,7 @@ relativeError));
}
static double FIRST_NONZEROReduce(double[] a, int idx) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2749,7 +2807,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAll(double[] a) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2761,20 +2819,15 @@ relativeError));
static void FIRST_NONZEROReduceDouble64VectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2782,8 +2835,31 @@ relativeError));
Double64VectorTests::FIRST_NONZEROReduce, Double64VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2793,7 +2869,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2807,20 +2883,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -68,6 +68,13 @@ public class DoubleMaxVectorTests extends AbstractVectorTest {
private static final int Max = 256; // juts so we can do N/Max
// Identity values for reduction operations
private static final double ADD_IDENTITY = (double)0;
private static final double FIRST_NONZERO_IDENTITY = (double)0;
private static final double MAX_IDENTITY = Double.NEGATIVE_INFINITY;
private static final double MIN_IDENTITY = Double.POSITIVE_INFINITY;
private static final double MUL_IDENTITY = (double)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
@ -2389,7 +2396,7 @@ relativeError));
}
static double ADDReduce(double[] a, int idx) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2398,7 +2405,7 @@ relativeError));
}
static double ADDReduceAll(double[] a) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2413,17 +2420,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
double v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2431,8 +2433,31 @@ relativeError));
DoubleMaxVectorTests::ADDReduce, DoubleMaxVectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = ADD_IDENTITY;
Assert.assertEquals((double) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id + x), x);
Assert.assertEquals((double) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2442,7 +2467,7 @@ relativeError));
}
static double ADDReduceAllMasked(double[] a, boolean[] mask) {
double res = 0;
double res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2459,17 +2484,12 @@ relativeError));
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
double v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2478,7 +2498,7 @@ relativeError));
}
static double MULReduce(double[] a, int idx) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2487,7 +2507,7 @@ relativeError));
}
static double MULReduceAll(double[] a) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2499,20 +2519,15 @@ relativeError));
static void MULReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
double v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2520,8 +2535,31 @@ relativeError));
DoubleMaxVectorTests::MULReduce, DoubleMaxVectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MUL_IDENTITY;
Assert.assertEquals((double) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) (id * x), x);
Assert.assertEquals((double) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2531,7 +2569,7 @@ relativeError));
}
static double MULReduceAllMasked(double[] a, boolean[] mask) {
double res = 1;
double res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2545,20 +2583,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = 1;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
double v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2567,7 +2600,7 @@ relativeError));
}
static double MINReduce(double[] a, int idx) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.min(res, a[i]);
}
@ -2576,7 +2609,7 @@ relativeError));
}
static double MINReduceAll(double[] a) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduce(a, i));
}
@ -2588,20 +2621,15 @@ relativeError));
static void MINReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
double v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2609,8 +2637,31 @@ relativeError));
DoubleMaxVectorTests::MINReduce, DoubleMaxVectorTests::MINReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MIN_IDENTITY;
Assert.assertEquals((double) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.min(id, x), x);
Assert.assertEquals((double) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.min(res, a[i]);
@ -2620,7 +2671,7 @@ relativeError));
}
static double MINReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.POSITIVE_INFINITY;
double res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2634,20 +2685,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.POSITIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
double v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (double) Math.min(ra, v);
}
}
@ -2656,7 +2702,7 @@ relativeError));
}
static double MAXReduce(double[] a, int idx) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (double) Math.max(res, a[i]);
}
@ -2665,7 +2711,7 @@ relativeError));
}
static double MAXReduceAll(double[] a) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduce(a, i));
}
@ -2677,20 +2723,15 @@ relativeError));
static void MAXReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
double v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2698,8 +2739,31 @@ relativeError));
DoubleMaxVectorTests::MAXReduce, DoubleMaxVectorTests::MAXReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = MAX_IDENTITY;
Assert.assertEquals((double) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((double) Math.max(id, x), x);
Assert.assertEquals((double) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((double) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((double) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (double) Math.max(res, a[i]);
@ -2709,7 +2773,7 @@ relativeError));
}
static double MAXReduceAllMasked(double[] a, boolean[] mask) {
double res = Double.NEGATIVE_INFINITY;
double res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2723,20 +2787,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = Double.NEGATIVE_INFINITY;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Double.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
double v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (double) Math.max(ra, v);
}
}
@ -2745,7 +2804,7 @@ relativeError));
}
static double FIRST_NONZEROReduce(double[] a, int idx) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2754,7 +2813,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAll(double[] a) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2766,20 +2825,15 @@ relativeError));
static void FIRST_NONZEROReduceDoubleMaxVectorTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double[] r = fr.apply(SPECIES.length());
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2787,8 +2841,31 @@ relativeError));
DoubleMaxVectorTests::FIRST_NONZEROReduce, DoubleMaxVectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "doubleUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<double[]> fa) {
double[] a = fa.apply(SPECIES.length());
double id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
double x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2798,7 +2875,7 @@ relativeError));
}
static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
double res = (double) 0;
double res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2812,20 +2889,15 @@ relativeError));
double[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
double ra = (double) 0;
double ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (double) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
double v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Float128VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final float ADD_IDENTITY = (float)0;
private static final float FIRST_NONZERO_IDENTITY = (float)0;
private static final float MAX_IDENTITY = Float.NEGATIVE_INFINITY;
private static final float MIN_IDENTITY = Float.POSITIVE_INFINITY;
private static final float MUL_IDENTITY = (float)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final float RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (float)10.0;
@ -2395,7 +2401,7 @@ relativeError));
}
static float ADDReduce(float[] a, int idx) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2404,7 +2410,7 @@ relativeError));
}
static float ADDReduceAll(float[] a) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2419,17 +2425,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
float v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2437,8 +2438,31 @@ relativeError));
Float128VectorTests::ADDReduce, Float128VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = ADD_IDENTITY;
Assert.assertEquals((float) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id + x), x);
Assert.assertEquals((float) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static float ADDReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2448,7 +2472,7 @@ relativeError));
}
static float ADDReduceAllMasked(float[] a, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2465,17 +2489,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
float v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2484,7 +2503,7 @@ relativeError));
}
static float MULReduce(float[] a, int idx) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2493,7 +2512,7 @@ relativeError));
}
static float MULReduceAll(float[] a) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2505,20 +2524,15 @@ relativeError));
static void MULReduceFloat128VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
float v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2526,8 +2540,31 @@ relativeError));
Float128VectorTests::MULReduce, Float128VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MUL_IDENTITY;
Assert.assertEquals((float) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id * x), x);
Assert.assertEquals((float) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static float MULReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2537,7 +2574,7 @@ relativeError));
}
static float MULReduceAllMasked(float[] a, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2551,20 +2588,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
float v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2573,7 +2605,7 @@ relativeError));
}
static float MINReduce(float[] a, int idx) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.min(res, a[i]);
}
@ -2582,7 +2614,7 @@ relativeError));
}
static float MINReduceAll(float[] a) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduce(a, i));
}
@ -2594,20 +2626,15 @@ relativeError));
static void MINReduceFloat128VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
float v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2615,8 +2642,31 @@ relativeError));
Float128VectorTests::MINReduce, Float128VectorTests::MINReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MIN_IDENTITY;
Assert.assertEquals((float) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.min(id, x), x);
Assert.assertEquals((float) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static float MINReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.min(res, a[i]);
@ -2626,7 +2676,7 @@ relativeError));
}
static float MINReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2640,20 +2690,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
float v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2662,7 +2707,7 @@ relativeError));
}
static float MAXReduce(float[] a, int idx) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.max(res, a[i]);
}
@ -2671,7 +2716,7 @@ relativeError));
}
static float MAXReduceAll(float[] a) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduce(a, i));
}
@ -2683,20 +2728,15 @@ relativeError));
static void MAXReduceFloat128VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
float v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2704,8 +2744,31 @@ relativeError));
Float128VectorTests::MAXReduce, Float128VectorTests::MAXReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MAX_IDENTITY;
Assert.assertEquals((float) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.max(id, x), x);
Assert.assertEquals((float) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static float MAXReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.max(res, a[i]);
@ -2715,7 +2778,7 @@ relativeError));
}
static float MAXReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2729,20 +2792,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
float v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2751,7 +2809,7 @@ relativeError));
}
static float FIRST_NONZEROReduce(float[] a, int idx) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2760,7 +2818,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAll(float[] a) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2772,20 +2830,15 @@ relativeError));
static void FIRST_NONZEROReduceFloat128VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2793,8 +2846,31 @@ relativeError));
Float128VectorTests::FIRST_NONZEROReduce, Float128VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2804,7 +2880,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2818,20 +2894,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Float256VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final float ADD_IDENTITY = (float)0;
private static final float FIRST_NONZERO_IDENTITY = (float)0;
private static final float MAX_IDENTITY = Float.NEGATIVE_INFINITY;
private static final float MIN_IDENTITY = Float.POSITIVE_INFINITY;
private static final float MUL_IDENTITY = (float)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final float RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (float)10.0;
@ -2395,7 +2401,7 @@ relativeError));
}
static float ADDReduce(float[] a, int idx) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2404,7 +2410,7 @@ relativeError));
}
static float ADDReduceAll(float[] a) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2419,17 +2425,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
float v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2437,8 +2438,31 @@ relativeError));
Float256VectorTests::ADDReduce, Float256VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = ADD_IDENTITY;
Assert.assertEquals((float) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id + x), x);
Assert.assertEquals((float) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static float ADDReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2448,7 +2472,7 @@ relativeError));
}
static float ADDReduceAllMasked(float[] a, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2465,17 +2489,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
float v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2484,7 +2503,7 @@ relativeError));
}
static float MULReduce(float[] a, int idx) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2493,7 +2512,7 @@ relativeError));
}
static float MULReduceAll(float[] a) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2505,20 +2524,15 @@ relativeError));
static void MULReduceFloat256VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
float v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2526,8 +2540,31 @@ relativeError));
Float256VectorTests::MULReduce, Float256VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MUL_IDENTITY;
Assert.assertEquals((float) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id * x), x);
Assert.assertEquals((float) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static float MULReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2537,7 +2574,7 @@ relativeError));
}
static float MULReduceAllMasked(float[] a, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2551,20 +2588,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
float v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2573,7 +2605,7 @@ relativeError));
}
static float MINReduce(float[] a, int idx) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.min(res, a[i]);
}
@ -2582,7 +2614,7 @@ relativeError));
}
static float MINReduceAll(float[] a) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduce(a, i));
}
@ -2594,20 +2626,15 @@ relativeError));
static void MINReduceFloat256VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
float v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2615,8 +2642,31 @@ relativeError));
Float256VectorTests::MINReduce, Float256VectorTests::MINReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MIN_IDENTITY;
Assert.assertEquals((float) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.min(id, x), x);
Assert.assertEquals((float) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static float MINReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.min(res, a[i]);
@ -2626,7 +2676,7 @@ relativeError));
}
static float MINReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2640,20 +2690,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
float v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2662,7 +2707,7 @@ relativeError));
}
static float MAXReduce(float[] a, int idx) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.max(res, a[i]);
}
@ -2671,7 +2716,7 @@ relativeError));
}
static float MAXReduceAll(float[] a) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduce(a, i));
}
@ -2683,20 +2728,15 @@ relativeError));
static void MAXReduceFloat256VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
float v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2704,8 +2744,31 @@ relativeError));
Float256VectorTests::MAXReduce, Float256VectorTests::MAXReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MAX_IDENTITY;
Assert.assertEquals((float) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.max(id, x), x);
Assert.assertEquals((float) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static float MAXReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.max(res, a[i]);
@ -2715,7 +2778,7 @@ relativeError));
}
static float MAXReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2729,20 +2792,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
float v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2751,7 +2809,7 @@ relativeError));
}
static float FIRST_NONZEROReduce(float[] a, int idx) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2760,7 +2818,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAll(float[] a) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2772,20 +2830,15 @@ relativeError));
static void FIRST_NONZEROReduceFloat256VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2793,8 +2846,31 @@ relativeError));
Float256VectorTests::FIRST_NONZEROReduce, Float256VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2804,7 +2880,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2818,20 +2894,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Float512VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final float ADD_IDENTITY = (float)0;
private static final float FIRST_NONZERO_IDENTITY = (float)0;
private static final float MAX_IDENTITY = Float.NEGATIVE_INFINITY;
private static final float MIN_IDENTITY = Float.POSITIVE_INFINITY;
private static final float MUL_IDENTITY = (float)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final float RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (float)10.0;
@ -2395,7 +2401,7 @@ relativeError));
}
static float ADDReduce(float[] a, int idx) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2404,7 +2410,7 @@ relativeError));
}
static float ADDReduceAll(float[] a) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2419,17 +2425,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
float v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2437,8 +2438,31 @@ relativeError));
Float512VectorTests::ADDReduce, Float512VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = ADD_IDENTITY;
Assert.assertEquals((float) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id + x), x);
Assert.assertEquals((float) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static float ADDReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2448,7 +2472,7 @@ relativeError));
}
static float ADDReduceAllMasked(float[] a, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2465,17 +2489,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
float v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2484,7 +2503,7 @@ relativeError));
}
static float MULReduce(float[] a, int idx) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2493,7 +2512,7 @@ relativeError));
}
static float MULReduceAll(float[] a) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2505,20 +2524,15 @@ relativeError));
static void MULReduceFloat512VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
float v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2526,8 +2540,31 @@ relativeError));
Float512VectorTests::MULReduce, Float512VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MUL_IDENTITY;
Assert.assertEquals((float) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id * x), x);
Assert.assertEquals((float) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static float MULReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2537,7 +2574,7 @@ relativeError));
}
static float MULReduceAllMasked(float[] a, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2551,20 +2588,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
float v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2573,7 +2605,7 @@ relativeError));
}
static float MINReduce(float[] a, int idx) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.min(res, a[i]);
}
@ -2582,7 +2614,7 @@ relativeError));
}
static float MINReduceAll(float[] a) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduce(a, i));
}
@ -2594,20 +2626,15 @@ relativeError));
static void MINReduceFloat512VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
float v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2615,8 +2642,31 @@ relativeError));
Float512VectorTests::MINReduce, Float512VectorTests::MINReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MIN_IDENTITY;
Assert.assertEquals((float) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.min(id, x), x);
Assert.assertEquals((float) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static float MINReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.min(res, a[i]);
@ -2626,7 +2676,7 @@ relativeError));
}
static float MINReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2640,20 +2690,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
float v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2662,7 +2707,7 @@ relativeError));
}
static float MAXReduce(float[] a, int idx) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.max(res, a[i]);
}
@ -2671,7 +2716,7 @@ relativeError));
}
static float MAXReduceAll(float[] a) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduce(a, i));
}
@ -2683,20 +2728,15 @@ relativeError));
static void MAXReduceFloat512VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
float v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2704,8 +2744,31 @@ relativeError));
Float512VectorTests::MAXReduce, Float512VectorTests::MAXReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MAX_IDENTITY;
Assert.assertEquals((float) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.max(id, x), x);
Assert.assertEquals((float) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static float MAXReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.max(res, a[i]);
@ -2715,7 +2778,7 @@ relativeError));
}
static float MAXReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2729,20 +2792,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
float v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2751,7 +2809,7 @@ relativeError));
}
static float FIRST_NONZEROReduce(float[] a, int idx) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2760,7 +2818,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAll(float[] a) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2772,20 +2830,15 @@ relativeError));
static void FIRST_NONZEROReduceFloat512VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2793,8 +2846,31 @@ relativeError));
Float512VectorTests::FIRST_NONZEROReduce, Float512VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2804,7 +2880,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2818,20 +2894,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -62,6 +62,12 @@ public class Float64VectorTests extends AbstractVectorTest {
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
// Identity values for reduction operations
private static final float ADD_IDENTITY = (float)0;
private static final float FIRST_NONZERO_IDENTITY = (float)0;
private static final float MAX_IDENTITY = Float.NEGATIVE_INFINITY;
private static final float MIN_IDENTITY = Float.POSITIVE_INFINITY;
private static final float MUL_IDENTITY = (float)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final float RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (float)10.0;
@ -2395,7 +2401,7 @@ relativeError));
}
static float ADDReduce(float[] a, int idx) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2404,7 +2410,7 @@ relativeError));
}
static float ADDReduceAll(float[] a) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2419,17 +2425,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
float v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2437,8 +2438,31 @@ relativeError));
Float64VectorTests::ADDReduce, Float64VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = ADD_IDENTITY;
Assert.assertEquals((float) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id + x), x);
Assert.assertEquals((float) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static float ADDReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2448,7 +2472,7 @@ relativeError));
}
static float ADDReduceAllMasked(float[] a, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2465,17 +2489,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
float v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2484,7 +2503,7 @@ relativeError));
}
static float MULReduce(float[] a, int idx) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2493,7 +2512,7 @@ relativeError));
}
static float MULReduceAll(float[] a) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2505,20 +2524,15 @@ relativeError));
static void MULReduceFloat64VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
float v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2526,8 +2540,31 @@ relativeError));
Float64VectorTests::MULReduce, Float64VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MUL_IDENTITY;
Assert.assertEquals((float) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id * x), x);
Assert.assertEquals((float) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static float MULReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2537,7 +2574,7 @@ relativeError));
}
static float MULReduceAllMasked(float[] a, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2551,20 +2588,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
float v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2573,7 +2605,7 @@ relativeError));
}
static float MINReduce(float[] a, int idx) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.min(res, a[i]);
}
@ -2582,7 +2614,7 @@ relativeError));
}
static float MINReduceAll(float[] a) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduce(a, i));
}
@ -2594,20 +2626,15 @@ relativeError));
static void MINReduceFloat64VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
float v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2615,8 +2642,31 @@ relativeError));
Float64VectorTests::MINReduce, Float64VectorTests::MINReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MIN_IDENTITY;
Assert.assertEquals((float) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.min(id, x), x);
Assert.assertEquals((float) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static float MINReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.min(res, a[i]);
@ -2626,7 +2676,7 @@ relativeError));
}
static float MINReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2640,20 +2690,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
float v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2662,7 +2707,7 @@ relativeError));
}
static float MAXReduce(float[] a, int idx) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.max(res, a[i]);
}
@ -2671,7 +2716,7 @@ relativeError));
}
static float MAXReduceAll(float[] a) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduce(a, i));
}
@ -2683,20 +2728,15 @@ relativeError));
static void MAXReduceFloat64VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
float v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2704,8 +2744,31 @@ relativeError));
Float64VectorTests::MAXReduce, Float64VectorTests::MAXReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MAX_IDENTITY;
Assert.assertEquals((float) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.max(id, x), x);
Assert.assertEquals((float) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static float MAXReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.max(res, a[i]);
@ -2715,7 +2778,7 @@ relativeError));
}
static float MAXReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2729,20 +2792,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
float v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2751,7 +2809,7 @@ relativeError));
}
static float FIRST_NONZEROReduce(float[] a, int idx) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2760,7 +2818,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAll(float[] a) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2772,20 +2830,15 @@ relativeError));
static void FIRST_NONZEROReduceFloat64VectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2793,8 +2846,31 @@ relativeError));
Float64VectorTests::FIRST_NONZEROReduce, Float64VectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2804,7 +2880,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2818,20 +2894,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -68,6 +68,13 @@ public class FloatMaxVectorTests extends AbstractVectorTest {
private static final int Max = 256; // juts so we can do N/Max
// Identity values for reduction operations
private static final float ADD_IDENTITY = (float)0;
private static final float FIRST_NONZERO_IDENTITY = (float)0;
private static final float MAX_IDENTITY = Float.NEGATIVE_INFINITY;
private static final float MIN_IDENTITY = Float.POSITIVE_INFINITY;
private static final float MUL_IDENTITY = (float)1;
// for floating point addition reduction ops that may introduce rounding errors
private static final float RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (float)10.0;
@ -2400,7 +2407,7 @@ relativeError));
}
static float ADDReduce(float[] a, int idx) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res += a[i];
}
@ -2409,7 +2416,7 @@ relativeError));
}
static float ADDReduceAll(float[] a) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduce(a, i);
}
@ -2424,17 +2431,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD);
float v = av.reduceLanes(VectorOperators.ADD);
r[i] = v;
ra += v;
}
}
@ -2442,8 +2444,31 @@ relativeError));
FloatMaxVectorTests::ADDReduce, FloatMaxVectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void ADDReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = ADD_IDENTITY;
Assert.assertEquals((float) (id + id), id,
"ADD(ADD_IDENTITY, ADD_IDENTITY) != ADD_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id + x), x);
Assert.assertEquals((float) (x + id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id + x), x,
"ADD(ADD_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x + id), x,
"ADD(" + x + ", ADD_IDENTITY) != " + x);
}
}
static float ADDReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res += a[i];
@ -2453,7 +2478,7 @@ relativeError));
}
static float ADDReduceAllMasked(float[] a, boolean[] mask) {
float res = 0;
float res = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res += ADDReduceMasked(a, i, mask);
}
@ -2470,17 +2495,12 @@ relativeError));
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = ADD_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra += av.reduceLanes(VectorOperators.ADD, vmask);
float v = av.reduceLanes(VectorOperators.ADD, vmask);
r[i] = v;
ra += v;
}
}
@ -2489,7 +2509,7 @@ relativeError));
}
static float MULReduce(float[] a, int idx) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res *= a[i];
}
@ -2498,7 +2518,7 @@ relativeError));
}
static float MULReduceAll(float[] a) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduce(a, i);
}
@ -2510,20 +2530,15 @@ relativeError));
static void MULReduceFloatMaxVectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL);
float v = av.reduceLanes(VectorOperators.MUL);
r[i] = v;
ra *= v;
}
}
@ -2531,8 +2546,31 @@ relativeError));
FloatMaxVectorTests::MULReduce, FloatMaxVectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MULReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MUL_IDENTITY;
Assert.assertEquals((float) (id * id), id,
"MUL(MUL_IDENTITY, MUL_IDENTITY) != MUL_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) (id * x), x);
Assert.assertEquals((float) (x * id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) (id * x), x,
"MUL(MUL_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) (x * id), x,
"MUL(" + x + ", MUL_IDENTITY) != " + x);
}
}
static float MULReduceMasked(float[] a, int idx, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res *= a[i];
@ -2542,7 +2580,7 @@ relativeError));
}
static float MULReduceAllMasked(float[] a, boolean[] mask) {
float res = 1;
float res = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res *= MULReduceMasked(a, i, mask);
}
@ -2556,20 +2594,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = 1;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MUL_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = 1;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra *= av.reduceLanes(VectorOperators.MUL, vmask);
float v = av.reduceLanes(VectorOperators.MUL, vmask);
r[i] = v;
ra *= v;
}
}
@ -2578,7 +2611,7 @@ relativeError));
}
static float MINReduce(float[] a, int idx) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.min(res, a[i]);
}
@ -2587,7 +2620,7 @@ relativeError));
}
static float MINReduceAll(float[] a) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduce(a, i));
}
@ -2599,20 +2632,15 @@ relativeError));
static void MINReduceFloatMaxVectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
float v = av.reduceLanes(VectorOperators.MIN);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2620,8 +2648,31 @@ relativeError));
FloatMaxVectorTests::MINReduce, FloatMaxVectorTests::MINReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MINReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MIN_IDENTITY;
Assert.assertEquals((float) Math.min(id, id), id,
"MIN(MIN_IDENTITY, MIN_IDENTITY) != MIN_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.min(id, x), x);
Assert.assertEquals((float) Math.min(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.min(id, x), x,
"MIN(MIN_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.min(x, id), x,
"MIN(" + x + ", MIN_IDENTITY) != " + x);
}
}
static float MINReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.min(res, a[i]);
@ -2631,7 +2682,7 @@ relativeError));
}
static float MINReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.POSITIVE_INFINITY;
float res = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.min(res, MINReduceMasked(a, i, mask));
}
@ -2645,20 +2696,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.POSITIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MIN_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.POSITIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
float v = av.reduceLanes(VectorOperators.MIN, vmask);
r[i] = v;
ra = (float) Math.min(ra, v);
}
}
@ -2667,7 +2713,7 @@ relativeError));
}
static float MAXReduce(float[] a, int idx) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = (float) Math.max(res, a[i]);
}
@ -2676,7 +2722,7 @@ relativeError));
}
static float MAXReduceAll(float[] a) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduce(a, i));
}
@ -2688,20 +2734,15 @@ relativeError));
static void MAXReduceFloatMaxVectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
float v = av.reduceLanes(VectorOperators.MAX);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2709,8 +2750,31 @@ relativeError));
FloatMaxVectorTests::MAXReduce, FloatMaxVectorTests::MAXReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void MAXReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = MAX_IDENTITY;
Assert.assertEquals((float) Math.max(id, id), id,
"MAX(MAX_IDENTITY, MAX_IDENTITY) != MAX_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals((float) Math.max(id, x), x);
Assert.assertEquals((float) Math.max(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals((float) Math.max(id, x), x,
"MAX(MAX_IDENTITY, " + x + ") != " + x);
Assert.assertEquals((float) Math.max(x, id), x,
"MAX(" + x + ", MAX_IDENTITY) != " + x);
}
}
static float MAXReduceMasked(float[] a, int idx, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = (float) Math.max(res, a[i]);
@ -2720,7 +2784,7 @@ relativeError));
}
static float MAXReduceAllMasked(float[] a, boolean[] mask) {
float res = Float.NEGATIVE_INFINITY;
float res = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = (float) Math.max(res, MAXReduceMasked(a, i, mask));
}
@ -2734,20 +2798,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = Float.NEGATIVE_INFINITY;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = MAX_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = Float.NEGATIVE_INFINITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = (float) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
float v = av.reduceLanes(VectorOperators.MAX, vmask);
r[i] = v;
ra = (float) Math.max(ra, v);
}
}
@ -2756,7 +2815,7 @@ relativeError));
}
static float FIRST_NONZEROReduce(float[] a, int idx) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
res = firstNonZero(res, a[i]);
}
@ -2765,7 +2824,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAll(float[] a) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
}
@ -2777,20 +2836,15 @@ relativeError));
static void FIRST_NONZEROReduceFloatMaxVectorTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = fr.apply(SPECIES.length());
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO);
r[i] = v;
ra = firstNonZero(ra, v);
}
}
@ -2798,8 +2852,31 @@ relativeError));
FloatMaxVectorTests::FIRST_NONZEROReduce, FloatMaxVectorTests::FIRST_NONZEROReduceAll);
}
@Test(dataProvider = "floatUnaryOpProvider")
static void FIRST_NONZEROReduceIdentityValueTests(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float id = FIRST_NONZERO_IDENTITY;
Assert.assertEquals(firstNonZero(id, id), id,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, FIRST_NONZERO_IDENTITY) != FIRST_NONZERO_IDENTITY");
float x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(firstNonZero(id, x), x);
Assert.assertEquals(firstNonZero(x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(firstNonZero(id, x), x,
"FIRST_NONZERO(FIRST_NONZERO_IDENTITY, " + x + ") != " + x);
Assert.assertEquals(firstNonZero(x, id), x,
"FIRST_NONZERO(" + x + ", FIRST_NONZERO_IDENTITY) != " + x);
}
}
static float FIRST_NONZEROReduceMasked(float[] a, int idx, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = idx; i < (idx + SPECIES.length()); i++) {
if (mask[i % SPECIES.length()])
res = firstNonZero(res, a[i]);
@ -2809,7 +2886,7 @@ relativeError));
}
static float FIRST_NONZEROReduceAllMasked(float[] a, boolean[] mask) {
float res = (float) 0;
float res = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
}
@ -2823,20 +2900,15 @@ relativeError));
float[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, 0);
float ra = (float) 0;
float ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = FIRST_NONZERO_IDENTITY;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
}
}
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = (float) 0;
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
float v = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
r[i] = v;
ra = firstNonZero(ra, v);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#!/bin/bash
#
# Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@ -511,23 +511,23 @@ 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"
gen_reduction_op "OR" "|" "BITWISE" "0"
gen_reduction_op "XOR" "^" "BITWISE" "0"
gen_reduction_op "ADD" "+" "" "0"
gen_reduction_op "MUL" "*" "" "1"
gen_reduction_op_func "MIN" "(\$type\$) Math.min" "" "\$Wideboxtype\$.\$MaxValue\$"
gen_reduction_op_func "MAX" "(\$type\$) Math.max" "" "\$Wideboxtype\$.\$MinValue\$"
gen_reduction_op_func "UMIN" "(\$type\$) VectorMath.minUnsigned" "BITWISE" "\$Wideboxtype\$.\$MaxValue\$"
gen_reduction_op_func "UMAX" "(\$type\$) VectorMath.maxUnsigned" "BITWISE" "\$Wideboxtype\$.\$MinValue\$"
gen_reduction_op_func "FIRST_NONZERO" "firstNonZero" "" "(\$type\$) 0"
gen_reduction_op "AND" "\&" "BITWISE" "AND_IDENTITY"
gen_reduction_op "OR" "|" "BITWISE" "OR_IDENTITY"
gen_reduction_op "XOR" "^" "BITWISE" "XOR_IDENTITY"
gen_reduction_op "ADD" "+" "" "ADD_IDENTITY"
gen_reduction_op "MUL" "*" "" "MUL_IDENTITY"
gen_reduction_op_func "MIN" "(\$type\$) Math.min" "" "MIN_IDENTITY"
gen_reduction_op_func "MAX" "(\$type\$) Math.max" "" "MAX_IDENTITY"
gen_reduction_op_func "UMIN" "(\$type\$) VectorMath.minUnsigned" "BITWISE" "UMIN_IDENTITY"
gen_reduction_op_func "UMAX" "(\$type\$) VectorMath.maxUnsigned" "BITWISE" "UMAX_IDENTITY"
gen_reduction_op_func "FIRST_NONZERO" "firstNonZero" "" "FIRST_NONZERO_IDENTITY"
# Boolean reductions.
gen_bool_reduction_op "anyTrue" "|" "BITWISE" "false"
gen_bool_reduction_op "allTrue" "\&" "BITWISE" "true"
# Saturating reductions.
gen_saturating_reduction_op "SUADD" "(\$type\$) VectorMath.addSaturatingUnsigned" "BITWISE" "0"
gen_saturating_reduction_op "SUADD" "(\$type\$) VectorMath.addSaturatingUnsigned" "BITWISE" "SUADD_IDENTITY"
#Insert
gen_with_op "withLane" "" "" ""

View File

@ -2,20 +2,15 @@
$type$[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]], vmask);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]], vmask));
$type$ v = av.reduceLanes(VectorOperators.[[TEST]], vmask);
r[i] = v;
ra = [[TEST_OP]](ra, v);
}
}

View File

@ -2,20 +2,15 @@
$type$[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]], vmask);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra [[TEST_OP]]= av.reduceLanes(VectorOperators.[[TEST]], vmask);
$type$ v = av.reduceLanes(VectorOperators.[[TEST]], vmask);
r[i] = v;
ra [[TEST_OP]]= v;
}
}

View File

@ -1,19 +1,14 @@
$type$[] a = fa.apply(SPECIES.length());
$type$[] r = fr.apply(SPECIES.length());
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]]);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]]));
$type$ v = av.reduceLanes(VectorOperators.[[TEST]]);
r[i] = v;
ra = [[TEST_OP]](ra, v);
}
}

View File

@ -1,19 +1,14 @@
$type$[] a = fa.apply(SPECIES.length());
$type$[] r = fr.apply(SPECIES.length());
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]]);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra [[TEST_OP]]= av.reduceLanes(VectorOperators.[[TEST]]);
$type$ v = av.reduceLanes(VectorOperators.[[TEST]]);
r[i] = v;
ra [[TEST_OP]]= v;
}
}

View File

@ -2,20 +2,15 @@
$type$[] r = fr.apply(SPECIES.length());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<$Wideboxtype$> vmask = VectorMask.fromArray(SPECIES, mask, 0);
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]], vmask);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]], vmask));
$type$ v = av.reduceLanes(VectorOperators.[[TEST]], vmask);
r[i] = v;
ra = [[TEST_OP]](ra, v);
}
}

View File

@ -1,19 +1,14 @@
$type$[] a = fa.apply(SPECIES.length());
$type$[] r = fr.apply(SPECIES.length());
$type$ ra = [[TEST_INIT]];
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);
r[i] = av.reduceLanes(VectorOperators.[[TEST]]);
}
}
$type$ ra = 0;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
ra = [[TEST_INIT]];
for (int i = 0; i < a.length; i += SPECIES.length()) {
$abstractvectortype$ av = $abstractvectortype$.fromArray(SPECIES, a, i);
ra = [[TEST_OP]](ra, av.reduceLanes(VectorOperators.[[TEST]]));
$type$ v = av.reduceLanes(VectorOperators.[[TEST]]);
r[i] = v;
ra = [[TEST_OP]](ra, v);
}
}

View File

@ -5,3 +5,26 @@
assertReductionArraysEquals(r, ra, a,
$vectorteststype$::[[TEST]]Reduce, $vectorteststype$::[[TEST]]ReduceAll);
}
@Test(dataProvider = "$type$UnaryOpProvider")
static void [[TEST]]ReduceIdentityValueTests(IntFunction<$type$[]> fa) {
$type$[] a = fa.apply(SPECIES.length());
$type$ id = [[TEST_INIT]];
Assert.assertEquals([[TEST_OP]](id, id), id,
"[[TEST]]([[TEST_INIT]], [[TEST_INIT]]) != [[TEST_INIT]]");
$type$ x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals([[TEST_OP]](id, x), x);
Assert.assertEquals([[TEST_OP]](x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals([[TEST_OP]](id, x), x,
"[[TEST]]([[TEST_INIT]], " + x + ") != " + x);
Assert.assertEquals([[TEST_OP]](x, id), x,
"[[TEST]](" + x + ", [[TEST_INIT]]) != " + x);
}
}

View File

@ -9,3 +9,26 @@
$vectorteststype$::[[TEST]]Reduce, $vectorteststype$::[[TEST]]ReduceAll);
#end[FP]
}
@Test(dataProvider = "$type$UnaryOpProvider")
static void [[TEST]]ReduceIdentityValueTests(IntFunction<$type$[]> fa) {
$type$[] a = fa.apply(SPECIES.length());
$type$ id = [[TEST_INIT]];
Assert.assertEquals(($type$) (id [[TEST_OP]] id), id,
"[[TEST]]([[TEST_INIT]], [[TEST_INIT]]) != [[TEST_INIT]]");
$type$ x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals(($type$) (id [[TEST_OP]] x), x);
Assert.assertEquals(($type$) (x [[TEST_OP]] id), x);
}
} catch (AssertionError e) {
Assert.assertEquals(($type$) (id [[TEST_OP]] x), x,
"[[TEST]]([[TEST_INIT]], " + x + ") != " + x);
Assert.assertEquals(($type$) (x [[TEST_OP]] id), x,
"[[TEST]](" + x + ", [[TEST_INIT]]) != " + x);
}
}

View File

@ -5,3 +5,26 @@
assertReductionArraysEquals(r, ra, a,
$vectorteststype$::[[TEST]]Reduce, $vectorteststype$::[[TEST]]ReduceAll);
}
@Test(dataProvider = "$type$SaturatingUnaryOpProvider")
static void [[TEST]]ReduceIdentityValueTests(IntFunction<$type$[]> fa) {
$type$[] a = fa.apply(SPECIES.length());
$type$ id = [[TEST_INIT]];
Assert.assertEquals([[TEST_OP]](id, id), id,
"[[TEST]]([[TEST_INIT]], [[TEST_INIT]]) != [[TEST_INIT]]");
$type$ x = 0;
try {
for (int i = 0; i < a.length; i++) {
x = a[i];
Assert.assertEquals([[TEST_OP]](id, x), x);
Assert.assertEquals([[TEST_OP]](x, id), x);
}
} catch (AssertionError e) {
Assert.assertEquals([[TEST_OP]](id, x), x,
"[[TEST]]([[TEST_INIT]], " + x + ") != " + x);
Assert.assertEquals([[TEST_OP]](x, id), x,
"[[TEST]](" + x + ", [[TEST_INIT]]) != " + x);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -86,19 +86,37 @@ public class $vectorteststype$ extends AbstractVectorTest {
#end[MaxBit]
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
#if[MaxBit]
static VectorShape getMaxBit() {
return VectorShape.S_Max_BIT;
}
private static final int Max = 256; // juts so we can do N/$bits$
#end[MaxBit]
#if[BITWISE]
private static final $type$ CONST_SHIFT = $Boxtype$.SIZE / 2;
#end[BITWISE]
// Identity values for reduction operations
private static final $type$ ADD_IDENTITY = ($type$)0;
#if[BITWISE]
private static final $type$ AND_IDENTITY = ($type$)-1;
#end[BITWISE]
private static final $type$ FIRST_NONZERO_IDENTITY = ($type$)0;
private static final $type$ MAX_IDENTITY = $Wideboxtype$.$MinValue$;
private static final $type$ MIN_IDENTITY = $Wideboxtype$.$MaxValue$;
private static final $type$ MUL_IDENTITY = ($type$)1;
#if[BITWISE]
private static final $type$ OR_IDENTITY = ($type$)0;
private static final $type$ SUADD_IDENTITY = ($type$)0;
private static final $type$ UMAX_IDENTITY = ($type$)0; // Minimum unsigned value
private static final $type$ UMIN_IDENTITY = ($type$)-1; // Maximum unsigned value
private static final $type$ XOR_IDENTITY = ($type$)0;
#end[BITWISE]
#if[FP]
// for floating point addition reduction ops that may introduce rounding errors
private static final $type$ RELATIVE_ROUNDING_ERROR_FACTOR_ADD = ($type$)10.0;