[BAEL-6090] vector api examples (#14274)

Co-authored-by: Bhaskar <bhaskar.dastidar@freshworks.com>
This commit is contained in:
Bhaskar Ghosh Dastidar 2023-06-22 02:20:45 +05:30 committed by GitHub
parent 68f6c19109
commit 6844a63c64
3 changed files with 149 additions and 0 deletions

View File

@ -21,6 +21,7 @@
<source>19</source>
<target>19</target>
<compilerArgs>--enable-preview</compilerArgs>
<compilerArgs>--add-modules=jdk.incubator.vector</compilerArgs>
</configuration>
</plugin>
</plugins>

View File

@ -0,0 +1,100 @@
package com.baeldung.vectors;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.IntVector;
import jdk.incubator.vector.VectorOperators;
import jdk.incubator.vector.VectorSpecies;
/**
* This class contains examples of the Vector API in Java, more specifically the fourth incubator to the Vector API.
* There are scalar and vector methods written here and the method names will specify the type.
* Note that, the code is written without any benchmarking done and without any assumption of it being run on
* a SIMD processor, or any specific compiler.
*/
public class VectorAPIExamples {
static final VectorSpecies<Integer> SPECIES = IntVector.SPECIES_PREFERRED;
static final VectorSpecies<Float> PREFERRED_SPECIES = FloatVector.SPECIES_PREFERRED;
public int[] addTwoScalarArrays(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length];
for (int i = 0; i < arr1.length; i++) {
result[i] = arr1[i] + arr2[i];
}
return result;
}
public int[] addTwoVectorArrays(int[] arr1, int[] arr2) {
var v1 = IntVector.fromArray(SPECIES, arr1, 0);
var v2 = IntVector.fromArray(SPECIES, arr2, 0);
var result = v1.add(v2);
return result.toArray();
}
public int[] addTwoVectorsWIthHigherShape(int[] arr1, int[] arr2) {
int[] finalResult = new int[arr1.length];
for (int i = 0; i < arr1.length; i += SPECIES.length()) {
var v1 = IntVector.fromArray(SPECIES, arr1, i);
var v2 = IntVector.fromArray(SPECIES, arr2, i);
var result = v1.add(v2);
result.intoArray(finalResult, i);
}
return finalResult;
}
public int[] addTwoVectorsWithMasks(int[] arr1, int[] arr2) {
int[] finalResult = new int[arr1.length];
int i = 0;
for (; i < SPECIES.loopBound(arr1.length); i += SPECIES.length()) {
var mask = SPECIES.indexInRange(i, arr1.length);
var v1 = IntVector.fromArray(SPECIES, arr1, i, mask);
var v2 = IntVector.fromArray(SPECIES, arr2, i, mask);
var result = v1.add(v2, mask);
result.intoArray(finalResult, i, mask);
}
// tail cleanup loop
for (; i < arr1.length; i++) {
finalResult[i] = arr1[i] + arr2[i];
}
return finalResult;
}
public float[] scalarNormOfTwoArrays(float[] arr1, float[] arr2) {
float[] finalResult = new float[arr1.length];
for (int i = 0; i < arr1.length; i++) {
finalResult[i] = (arr1[i] * arr1[i] + arr2[i] * arr2[i]) * -1.0f;
}
return finalResult;
}
public float[] vectorNormalForm(float[] arr1, float[] arr2) {
float[] finalResult = new float[arr1.length];
int i = 0;
int upperBound = SPECIES.loopBound(arr1.length);
for (; i < upperBound; i += SPECIES.length()) {
var va = FloatVector.fromArray(PREFERRED_SPECIES, arr1, i);
var vb = FloatVector.fromArray(PREFERRED_SPECIES, arr2, i);
var vc = va.mul(va)
.add(vb.mul(vb))
.neg();
vc.intoArray(finalResult, i);
}
// tail cleanup
for (; i < arr1.length; i++) {
finalResult[i] = (arr1[i] * arr1[i] + arr2[i] * arr2[i]) * -1.0f;
}
return finalResult;
}
public double averageOfaVector(int[] arr) {
double sum = 0;
for (int i = 0; i < arr.length; i += SPECIES.length()) {
var mask = SPECIES.indexInRange(i, arr.length);
var V = IntVector.fromArray(SPECIES, arr, i, mask);
sum += V.reduceLanes(VectorOperators.ADD, mask);
}
return sum / arr.length;
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.vectors;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
public class VectorAPIUnitTest {
VectorAPIExamples vector = new VectorAPIExamples();
@Test
public void whenTwoArraysProvided_thenVerifyScalarAdd() {
int[] arr1 = { 1, 2, 3, 4 };
int[] arr2 = { 100, 200, 300, 400 };
int[] result = { 101, 202, 303, 404 };
assertArrayEquals(result, vector.addTwoScalarArrays(arr1, arr2));
}
@Test
public void whenTwoArraysProvided_thenVerifyVectorAdd() {
int[] arr1 = { 1, 2, 3, 4 };
int[] arr2 = { 100, 200, 300, 400 };
int[] result = { 101, 202, 303, 404 };
assertArrayEquals(result, vector.addTwoVectorsWithMasks(arr1, arr2));
}
@Test
public void whenTwoValuesProvided_thenComputeScalarNorm() {
float[] arr1 = { 1, 2.3f };
float[] arr2 = { 1.3f, 2.0f };
float[] result = { -2.6899998f, -9.29f };
Assertions.assertArrayEquals(result, vector.scalarNormOfTwoArrays(arr1, arr2));
}
@Test
public void whenTwoValuesProvided_thenComputeVectorNorm() {
float[] arr1 = { 1, 2.3f };
float[] arr2 = { 1.3f, 2.0f };
float[] result = { -2.6899998f, -9.29f };
Assertions.assertArrayEquals(result, vector.vectorNormalForm(arr1, arr2));
}
@Test
public void whenArrayProvided_thenComputeVectorAverage() {
int[] arr = { 100, 200, 300, 400 };
Assertions.assertEquals(250.0, vector.averageOfaVector(arr));
}
}