From 6844a63c64ce416de2dc2be606edcaaf73e5445d Mon Sep 17 00:00:00 2001 From: Bhaskar Ghosh Dastidar Date: Thu, 22 Jun 2023 02:20:45 +0530 Subject: [PATCH] [BAEL-6090] vector api examples (#14274) Co-authored-by: Bhaskar --- core-java-modules/core-java-19/pom.xml | 1 + .../baeldung/vectors/VectorAPIExamples.java | 100 ++++++++++++++++++ .../baeldung/vectors/VectorAPIUnitTest.java | 48 +++++++++ 3 files changed, 149 insertions(+) create mode 100644 core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java create mode 100644 core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java diff --git a/core-java-modules/core-java-19/pom.xml b/core-java-modules/core-java-19/pom.xml index 930b37391c..11ae8cc224 100644 --- a/core-java-modules/core-java-19/pom.xml +++ b/core-java-modules/core-java-19/pom.xml @@ -21,6 +21,7 @@ 19 19 --enable-preview + --add-modules=jdk.incubator.vector diff --git a/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java b/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java new file mode 100644 index 0000000000..eda36dbfde --- /dev/null +++ b/core-java-modules/core-java-19/src/main/java/com/baeldung/vectors/VectorAPIExamples.java @@ -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 SPECIES = IntVector.SPECIES_PREFERRED; + static final VectorSpecies 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; + } +} diff --git a/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java b/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java new file mode 100644 index 0000000000..22b37a2b28 --- /dev/null +++ b/core-java-modules/core-java-19/src/test/java/com/baeldung/vectors/VectorAPIUnitTest.java @@ -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)); + } +}