blob: c8b847b3fbe67222440fcd0d3fb54194af71e5ed [file] [log] [blame]
/*
* Copyright (c) 2018, 2021, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @modules jdk.incubator.vector java.base/jdk.internal.vm.annotation
* @run testng/othervm -XX:-TieredCompilation Float128VectorLoadStoreTests
*
*/
// -- This file was mechanically generated: Do not edit! -- //
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorMask;
import jdk.incubator.vector.VectorSpecies;
import jdk.incubator.vector.VectorShuffle;
import jdk.internal.vm.annotation.DontInline;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.ByteOrder;
import java.nio.ReadOnlyBufferException;
import java.util.List;
import java.util.function.*;
@Test
public class Float128VectorLoadStoreTests extends AbstractVectorTest {
static final VectorSpecies<Float> SPECIES =
FloatVector.SPECIES_128;
static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 10);
static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 128);
static final int BUFFER_SIZE = Integer.getInteger("jdk.incubator.vector.test.buffer-size", BUFFER_REPS * (128 / 8));
static void assertArraysEquals(float[] r, float[] a, boolean[] mask) {
int i = 0;
try {
for (; i < a.length; i++) {
Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (float) 0);
}
} catch (AssertionError e) {
Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? a[i] : (float) 0, "at index #" + i);
}
}
static void assertArraysEquals(byte[] r, byte[] a, boolean[] mask) {
int i = 0;
try {
for (; i < a.length; i++) {
Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0);
}
} catch (AssertionError e) {
Assert.assertEquals(r[i], mask[(i*8/SPECIES.elementSize()) % SPECIES.length()] ? a[i] : (byte) 0, "at index #" + i);
}
}
static final List<IntFunction<float[]>> FLOAT_GENERATORS = List.of(
withToString("float[i * 5]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (float)(i * 5));
}),
withToString("float[i + 1]", (int s) -> {
return fill(s * BUFFER_REPS,
i -> (((float)(i + 1) == 0) ? 1 : (float)(i + 1)));
})
);
// Relative to array.length
static final List<IntFunction<Integer>> INDEX_GENERATORS = List.of(
withToString("-1", (int l) -> {
return -1;
}),
withToString("l", (int l) -> {
return l;
}),
withToString("l - 1", (int l) -> {
return l - 1;
}),
withToString("l + 1", (int l) -> {
return l + 1;
}),
withToString("l - speciesl + 1", (int l) -> {
return l - SPECIES.length() + 1;
}),
withToString("l + speciesl - 1", (int l) -> {
return l + SPECIES.length() - 1;
}),
withToString("l + speciesl", (int l) -> {
return l + SPECIES.length();
}),
withToString("l + speciesl + 1", (int l) -> {
return l + SPECIES.length() + 1;
})
);
// Relative to byte[] array.length or ByteBuffer.limit()
static final List<IntFunction<Integer>> BYTE_INDEX_GENERATORS = List.of(
withToString("-1", (int l) -> {
return -1;
}),
withToString("l", (int l) -> {
return l;
}),
withToString("l - 1", (int l) -> {
return l - 1;
}),
withToString("l + 1", (int l) -> {
return l + 1;
}),
withToString("l - speciesl*ebsize + 1", (int l) -> {
return l - SPECIES.vectorByteSize() + 1;
}),
withToString("l + speciesl*ebsize - 1", (int l) -> {
return l + SPECIES.vectorByteSize() - 1;
}),
withToString("l + speciesl*ebsize", (int l) -> {
return l + SPECIES.vectorByteSize();
}),
withToString("l + speciesl*ebsize + 1", (int l) -> {
return l + SPECIES.vectorByteSize() + 1;
})
);
@DataProvider
public Object[][] floatProvider() {
return FLOAT_GENERATORS.stream().
map(f -> new Object[]{f}).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] maskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
map(f -> new Object[]{f}).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatProviderForIOOBE() {
var f = FLOAT_GENERATORS.get(0);
return INDEX_GENERATORS.stream().map(fi -> {
return new Object[] {f, fi};
}).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> FLOAT_GENERATORS.stream().map(fa -> {
return new Object[] {fa, fm};
})).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatMaskProviderForIOOBE() {
var f = FLOAT_GENERATORS.get(0);
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> INDEX_GENERATORS.stream().map(fi -> {
return new Object[] {f, fi, fm};
})).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatIndexMapProvider() {
return INDEX_GENERATORS.stream().
flatMap(fim -> FLOAT_GENERATORS.stream().map(fa -> {
return new Object[] {fa, fim};
})).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatIndexMapMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> INDEX_GENERATORS.stream().
flatMap(fim -> FLOAT_GENERATORS.stream().map(fa -> {
return new Object[] {fa, fim, fm};
}))).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteBufferProvider() {
return FLOAT_GENERATORS.stream().
flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
return new Object[]{fa, fb, bo};
}))).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteBufferMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> FLOAT_GENERATORS.stream().
flatMap(fa -> BYTE_BUFFER_GENERATORS.stream().
flatMap(fb -> BYTE_ORDER_VALUES.stream().map(bo -> {
return new Object[]{fa, fb, fm, bo};
})))).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteArrayProvider() {
return FLOAT_GENERATORS.stream().
flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
return new Object[]{fa, bo};
})).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteArrayMaskProvider() {
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> FLOAT_GENERATORS.stream().
flatMap(fa -> BYTE_ORDER_VALUES.stream().map(bo -> {
return new Object[]{fa, fm, bo};
}))).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteProviderForIOOBE() {
var f = FLOAT_GENERATORS.get(0);
return BYTE_INDEX_GENERATORS.stream().map(fi -> {
return new Object[] {f, fi};
}).
toArray(Object[][]::new);
}
@DataProvider
public Object[][] floatByteMaskProviderForIOOBE() {
var f = FLOAT_GENERATORS.get(0);
return BOOLEAN_MASK_GENERATORS.stream().
flatMap(fm -> BYTE_INDEX_GENERATORS.stream().map(fi -> {
return new Object[] {f, fi, fm};
})).
toArray(Object[][]::new);
}
static ByteBuffer toBuffer(float[] a, IntFunction<ByteBuffer> fb) {
ByteBuffer bb = fb.apply(a.length * SPECIES.elementSize() / 8);
for (float v : a) {
bb.putFloat(v);
}
return bb.clear();
}
static float[] bufferToArray(ByteBuffer bb) {
FloatBuffer db = bb.asFloatBuffer();
float[] d = new float[db.capacity()];
db.get(0, d);
return d;
}
static byte[] toByteArray(float[] a, IntFunction<byte[]> fb, ByteOrder bo) {
byte[] b = fb.apply(a.length * SPECIES.elementSize() / 8);
FloatBuffer bb = ByteBuffer.wrap(b, 0, b.length).order(bo).asFloatBuffer();
for (float v : a) {
bb.put(v);
}
return b;
}
interface ToFloatF {
float apply(int i);
}
static float[] fill(int s , ToFloatF f) {
return fill(new float[s], f);
}
static float[] fill(float[] a, ToFloatF f) {
for (int i = 0; i < a.length; i++) {
a[i] = f.apply(i);
}
return a;
}
@DontInline
static FloatVector fromArray(float[] a, int i) {
return FloatVector.fromArray(SPECIES, a, i);
}
@DontInline
static FloatVector fromArray(float[] a, int i, VectorMask<Float> m) {
return FloatVector.fromArray(SPECIES, a, i, m);
}
@DontInline
static void intoArray(FloatVector v, float[] a, int i) {
v.intoArray(a, i);
}
@DontInline
static void intoArray(FloatVector v, float[] a, int i, VectorMask<Float> m) {
v.intoArray(a, i, m);
}
@DontInline
static FloatVector fromByteArray(byte[] a, int i, ByteOrder bo) {
return FloatVector.fromByteArray(SPECIES, a, i, bo);
}
@DontInline
static FloatVector fromByteArray(byte[] a, int i, ByteOrder bo, VectorMask<Float> m) {
return FloatVector.fromByteArray(SPECIES, a, i, bo, m);
}
@DontInline
static void intoByteArray(FloatVector v, byte[] a, int i, ByteOrder bo) {
v.intoByteArray(a, i, bo);
}
@DontInline
static void intoByteArray(FloatVector v, byte[] a, int i, ByteOrder bo, VectorMask<Float> m) {
v.intoByteArray(a, i, bo, m);
}
@DontInline
static FloatVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo) {
return FloatVector.fromByteBuffer(SPECIES, a, i, bo);
}
@DontInline
static FloatVector fromByteBuffer(ByteBuffer a, int i, ByteOrder bo, VectorMask<Float> m) {
return FloatVector.fromByteBuffer(SPECIES, a, i, bo, m);
}
@DontInline
static void intoByteBuffer(FloatVector v, ByteBuffer a, int i, ByteOrder bo) {
v.intoByteBuffer(a, i, bo);
}
@DontInline
static void intoByteBuffer(FloatVector v, ByteBuffer a, int i, ByteOrder bo, VectorMask<Float> m) {
v.intoByteBuffer(a, i, bo, m);
}
@Test(dataProvider = "floatProvider")
static void loadStoreArray(IntFunction<float[]> fa) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
av.intoArray(r, i);
}
}
Assert.assertEquals(r, a);
}
@Test(dataProvider = "floatProviderForIOOBE")
static void loadArrayIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = fromArray(a, i);
av.intoArray(r, i);
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
try {
fromArray(a, index);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatProviderForIOOBE")
static void storeArrayIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
intoArray(av, r, i);
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBounds(SPECIES.length(), index, a.length);
try {
FloatVector av = FloatVector.fromArray(SPECIES, a, 0);
intoArray(av, r, index);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatMaskProvider")
static void loadStoreMaskArray(IntFunction<float[]> fa,
IntFunction<boolean[]> fm) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i, vmask);
av.intoArray(r, i);
}
}
assertArraysEquals(r, a, mask);
r = new float[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
av.intoArray(r, i, vmask);
}
}
assertArraysEquals(r, a, mask);
}
@Test(dataProvider = "floatMaskProviderForIOOBE")
static void loadArrayMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = fromArray(a, i, vmask);
av.intoArray(r, i);
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
try {
fromArray(a, index, vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatMaskProviderForIOOBE")
static void storeArrayMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
float[] a = fa.apply(SPECIES.length());
float[] r = new float[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
FloatVector av = FloatVector.fromArray(SPECIES, a, i);
intoArray(av, r, i, vmask);
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length);
try {
FloatVector av = FloatVector.fromArray(SPECIES, a, 0);
intoArray(av, a, index, vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatMaskProvider")
static void loadStoreMask(IntFunction<float[]> fa,
IntFunction<boolean[]> fm) {
boolean[] mask = fm.apply(SPECIES.length());
boolean[] r = new boolean[mask.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < mask.length; i += SPECIES.length()) {
VectorMask<Float> vmask = VectorMask.fromArray(SPECIES, mask, i);
vmask.intoArray(r, i);
}
}
Assert.assertEquals(r, mask);
}
@Test(dataProvider = "floatByteBufferProvider")
static void loadStoreByteBuffer(IntFunction<float[]> fa,
IntFunction<ByteBuffer> fb,
ByteOrder bo) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb);
ByteBuffer r = fb.apply(a.limit());
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, i, bo);
av.intoByteBuffer(r, i, bo);
}
}
Assert.assertEquals(a.position(), 0, "Input buffer position changed");
Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
Assert.assertEquals(r.position(), 0, "Result buffer position changed");
Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
Assert.assertEquals(r, a, "Buffers not equal");
}
@Test(dataProvider = "floatByteProviderForIOOBE")
static void loadByteBufferIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder());
av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.limit());
boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
try {
fromByteBuffer(a, index, ByteOrder.nativeOrder());
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteProviderForIOOBE")
static void storeByteBufferIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
intoByteBuffer(av, r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.limit());
boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.limit());
try {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
intoByteBuffer(av, r, index, ByteOrder.nativeOrder());
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteBufferMaskProvider")
static void loadStoreByteBufferMask(IntFunction<float[]> fa,
IntFunction<ByteBuffer> fb,
IntFunction<boolean[]> fm,
ByteOrder bo) {
float[] _a = fa.apply(SPECIES.length());
ByteBuffer a = toBuffer(_a, fb);
ByteBuffer r = fb.apply(a.limit());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, i, bo, vmask);
av.intoByteBuffer(r, i, bo);
}
}
Assert.assertEquals(a.position(), 0, "Input buffer position changed");
Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
Assert.assertEquals(r.position(), 0, "Result buffer position changed");
Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
assertArraysEquals(bufferToArray(r), _a, mask);
r = fb.apply(a.limit());
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, i, bo);
av.intoByteBuffer(r, i, bo, vmask);
}
}
Assert.assertEquals(a.position(), 0, "Input buffer position changed");
Assert.assertEquals(a.limit(), l, "Input buffer limit changed");
Assert.assertEquals(r.position(), 0, "Result buffer position changed");
Assert.assertEquals(r.limit(), l, "Result buffer limit changed");
assertArraysEquals(bufferToArray(r), _a, mask);
}
@Test(dataProvider = "floatByteMaskProviderForIOOBE")
static void loadByteBufferMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = fromByteBuffer(a, i, ByteOrder.nativeOrder(), vmask);
av.intoByteBuffer(r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.limit());
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
try {
fromByteBuffer(a, index, ByteOrder.nativeOrder(), vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteMaskProviderForIOOBE")
static void storeByteBufferMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), ByteBuffer::allocateDirect);
ByteBuffer r = ByteBuffer.allocateDirect(a.limit());
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int l = a.limit();
int s = SPECIES.vectorByteSize();
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, i, ByteOrder.nativeOrder());
intoByteBuffer(av, r, i, ByteOrder.nativeOrder(), vmask);
}
}
int index = fi.apply(a.limit());
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.limit(), SPECIES.elementSize() / 8);
try {
FloatVector av = FloatVector.fromByteBuffer(SPECIES, a, 0, ByteOrder.nativeOrder());
intoByteBuffer(av, a, index, ByteOrder.nativeOrder(), vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteBufferProvider")
static void loadStoreReadonlyByteBuffer(IntFunction<float[]> fa,
IntFunction<ByteBuffer> fb,
ByteOrder bo) {
ByteBuffer a = toBuffer(fa.apply(SPECIES.length()), fb).asReadOnlyBuffer();
try {
SPECIES.zero().intoByteBuffer(a, 0, bo);
Assert.fail("ReadOnlyBufferException expected");
} catch (ReadOnlyBufferException e) {
}
try {
SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(true));
Assert.fail("ReadOnlyBufferException expected");
} catch (ReadOnlyBufferException e) {
}
try {
SPECIES.zero().intoByteBuffer(a, 0, bo, SPECIES.maskAll(false));
Assert.fail("ReadOnlyBufferException expected");
} catch (ReadOnlyBufferException e) {
}
try {
VectorMask<Float> m = SPECIES.shuffleFromOp(i -> i % 2 == 0 ? 1 : -1)
.laneIsValid();
SPECIES.zero().intoByteBuffer(a, 0, bo, m);
Assert.fail("ReadOnlyBufferException expected");
} catch (ReadOnlyBufferException e) {
}
}
@Test(dataProvider = "floatByteArrayProvider")
static void loadStoreByteArray(IntFunction<float[]> fa,
ByteOrder bo) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
byte[] r = new byte[a.length];
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, i, bo);
av.intoByteArray(r, i, bo);
}
}
Assert.assertEquals(r, a, "Byte arrays not equal");
}
@Test(dataProvider = "floatByteProviderForIOOBE")
static void loadByteArrayIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
byte[] r = new byte[a.length];
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = fromByteArray(a, i, ByteOrder.nativeOrder());
av.intoByteArray(r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
try {
fromByteArray(a, index, ByteOrder.nativeOrder());
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteProviderForIOOBE")
static void storeByteArrayIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
byte[] r = new byte[a.length];
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
intoByteArray(av, r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBounds(SPECIES.vectorByteSize(), index, a.length);
try {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
intoByteArray(av, r, index, ByteOrder.nativeOrder());
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteArrayMaskProvider")
static void loadStoreByteArrayMask(IntFunction<float[]> fa,
IntFunction<boolean[]> fm,
ByteOrder bo) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, bo);
byte[] r = new byte[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, i, bo, vmask);
av.intoByteArray(r, i, bo);
}
}
assertArraysEquals(r, a, mask);
r = new byte[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, i, bo);
av.intoByteArray(r, i, bo, vmask);
}
}
assertArraysEquals(r, a, mask);
}
@Test(dataProvider = "floatByteMaskProviderForIOOBE")
static void loadByteArrayMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
byte[] r = new byte[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = fromByteArray(a, i, ByteOrder.nativeOrder(), vmask);
av.intoByteArray(r, i, ByteOrder.nativeOrder());
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
try {
fromByteArray(a, index, ByteOrder.nativeOrder(), vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "floatByteMaskProviderForIOOBE")
static void storeByteArrayMaskIOOBE(IntFunction<float[]> fa, IntFunction<Integer> fi, IntFunction<boolean[]> fm) {
byte[] a = toByteArray(fa.apply(SPECIES.length()), byte[]::new, ByteOrder.nativeOrder());
byte[] r = new byte[a.length];
boolean[] mask = fm.apply(SPECIES.length());
VectorMask<Float> vmask = VectorMask.fromValues(SPECIES, mask);
int s = SPECIES.vectorByteSize();
int l = a.length;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < l; i += s) {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, i, ByteOrder.nativeOrder());
intoByteArray(av, r, i, ByteOrder.nativeOrder(), vmask);
}
}
int index = fi.apply(a.length);
boolean shouldFail = isIndexOutOfBoundsForMask(mask, index, a.length, SPECIES.elementSize() / 8);
try {
FloatVector av = FloatVector.fromByteArray(SPECIES, a, 0, ByteOrder.nativeOrder());
intoByteArray(av, a, index, ByteOrder.nativeOrder(), vmask);
if (shouldFail) {
Assert.fail("Failed to throw IndexOutOfBoundsException");
}
} catch (IndexOutOfBoundsException e) {
if (!shouldFail) {
Assert.fail("Unexpected IndexOutOfBoundsException");
}
}
}
@Test(dataProvider = "maskProvider")
static void loadStoreMask(IntFunction<boolean[]> fm) {
boolean[] a = fm.apply(SPECIES.length());
boolean[] r = new boolean[a.length];
for (int ic = 0; ic < INVOC_COUNT; ic++) {
for (int i = 0; i < a.length; i += SPECIES.length()) {
VectorMask<Float> vmask = SPECIES.loadMask(a, i);
vmask.intoArray(r, i);
}
}
Assert.assertEquals(r, a);
}
@Test
static void loadStoreShuffle() {
IntUnaryOperator fn = a -> a + 5;
for (int ic = 0; ic < INVOC_COUNT; ic++) {
var shuffle = VectorShuffle.fromOp(SPECIES, fn);
int [] r = shuffle.toArray();
int [] a = expectedShuffle(SPECIES.length(), fn);
Assert.assertEquals(r, a);
}
}
}