Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
54 lines
2.3 KiB
Java
54 lines
2.3 KiB
Java
import jdk.incubator.vector.FloatVector;
|
|
import jdk.incubator.vector.VectorOperators;
|
|
import jdk.incubator.vector.VectorSpecies;
|
|
|
|
/**
|
|
* JEP 537, Vector API (twelfth incubator). The same source and the same class file run on JDK 26
|
|
* (eleventh incubator, JEP 529) and JDK 27, because the public API did not change between them:
|
|
* docs/output/50-vector-api-surface.txt is the javap diff that shows it. For what the API is and
|
|
* how to use it well, see the companion guide to JEP 537 on ankurm.com.
|
|
* Run with --add-modules jdk.incubator.vector.
|
|
*/
|
|
public class VectorDemo {
|
|
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
|
|
|
|
static float scalarDot(float[] a, float[] b) {
|
|
float sum = 0;
|
|
for (int i = 0; i < a.length; i++) {
|
|
sum += a[i] * b[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
static float vectorDot(float[] a, float[] b) {
|
|
int i = 0;
|
|
FloatVector acc = FloatVector.zero(SPECIES);
|
|
int bound = SPECIES.loopBound(a.length);
|
|
for (; i < bound; i += SPECIES.length()) {
|
|
acc = FloatVector.fromArray(SPECIES, a, i).fma(FloatVector.fromArray(SPECIES, b, i), acc);
|
|
}
|
|
float sum = acc.reduceLanes(VectorOperators.ADD);
|
|
for (; i < a.length; i++) { // the tail the vector loop could not cover
|
|
sum += a[i] * b[i];
|
|
}
|
|
return sum;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println("java.version = " + System.getProperty("java.version"));
|
|
System.out.println("preferred species = " + SPECIES + " (" + SPECIES.length() + " float lanes, machine dependent)");
|
|
int n = 1_000_003; // deliberately not a multiple of the lane count
|
|
float[] a = new float[n], b = new float[n];
|
|
for (int i = 0; i < n; i++) {
|
|
a[i] = (i % 7) * 0.5f;
|
|
b[i] = (i % 5) * 0.25f;
|
|
}
|
|
float scalar = scalarDot(a, b);
|
|
float vector = vectorDot(a, b);
|
|
System.out.println("scalar dot = " + scalar);
|
|
System.out.println("vector dot = " + vector);
|
|
// Floating-point addition is not associative, so the two sums differ in the last bits; compare with a tolerance.
|
|
Check.that(Math.abs(scalar - vector) / Math.abs(scalar) < 1e-3, "vector and scalar dot products agree to within 0.1%");
|
|
}
|
|
}
|