Enhanced JEP 338: Vector API (Incubator)

The Vector API introduced as part of JEP 338 aims to provide a platform-independent API to express vector operations in Java. It was first incubated in Java 16 and enhanced in subsequent releases. This API allows developers to write high-performance vectorized code that can take advantage of SIMD (Single Instruction, Multiple Data) capabilities provided by modern CPUs, without relying on specific hardware details or compiler optimizations.

This API allows Java programs to express data-parallel computations using vector operations such as addition, subtraction, multiplication, and other element-wise operations in a more efficient and readable way. It’s particularly useful in scenarios requiring heavy numerical computations like scientific computing, image processing, and machine learning.

Why Vector API?

Vector operations have been crucial in enhancing performance for numerical and scientific computing. Traditionally, Java did not provide a direct way to write efficient vectorized operations, leaving developers to rely on lower-level optimizations or external libraries. The introduction of JEP 338 addresses this gap by providing an API to express such operations in a higher-level, platform-independent manner.

With the Vector API, developers can:

  • Express vector operations in a concise and readable way.
  • Benefit from SIMD capabilities available in modern processors for high-performance computing.
  • Write hardware-agnostic code, relying on JVM optimizations and hardware-level SIMD support.

Core Features of the Vector API

  1. SIMD-Based Operations: The Vector API provides a way to perform operations on vectors of data (arrays of numbers or similar types) using SIMD instructions. These operations allow multiple data points to be processed simultaneously, drastically improving performance compared to scalar operations.
  2. Vector Classes: The API provides specialized vector classes such as Vector, IntVector, FloatVector, etc. These classes represent data packed into vectorized format and can be manipulated using standard operations.
  3. Platform Independence: The Vector API is designed to abstract away the details of SIMD instructions, allowing code to be portable across different hardware platforms while still benefiting from SIMD where available.
  4. Operations Supported: The API supports various vectorized operations like:
  • Arithmetic operations (addition, subtraction, etc.)
  • Element-wise comparisons (greater than, equal to, etc.)
  • Trigonometric operations
  • Reinterpretation and conversion between different types (like converting between int and float).

Key Classes and Methods in the Vector API (Java 17)

1. VectorSpecies

  • Purpose: Describes the characteristics of a vector type (such as the element type and the vector size).
  • Methods:
    • VectorSpecies<T> of(Class<T> type, int length):

  • Creates a VectorSpecies that defines a vector of a specified element type and length.

2. Vector

  • Purpose: Represents a vector that holds multiple values of a specific type (e.g., int, float) for SIMD operations.
  • Methods:
    • static <T> Vector<T> fromArray(VectorSpecies<T> species, T[] array, int offset):

      • Loads data from an array into a vector.

      • Example: Vector<Integer> vec = Vector.fromArray(intSpecies, array, 0);

    • Vector<T> add(Vector<T> other):

      • Adds the corresponding elements of two vectors.

    • Vector<T> sub(Vector<T> other):

      • Subtracts the corresponding elements of two vectors.

    • Vector<T> mul(Vector<T> other):

      • Multiplies the corresponding elements of two vectors.

    • Vector<T> div(Vector<T> other):

      • Divides the corresponding elements of two vectors.

    • Vector<T> max(Vector<T> other):

      • Returns a vector of the element-wise maximum of two vectors.

    • Vector<T> min(Vector<T> other):

      • Returns a vector of the element-wise minimum of two vectors.

    • Vector<T> compare(Vector.Operator op, Vector<T> other):

      • Compares corresponding elements of two vectors using a specific comparison operator (e.g., GT, LT).

3. Vector.Operator

  • Purpose: Defines comparison operators for vectors.
  • Methods:
    • GT (greater than)

    • LT (less than)

    • EQ (equal to)

    • NEQ (not equal to)

4. VectorMask

  • Purpose: Represents a mask that can be used to select elements from a vector.
  • Methods:
    • boolean test(int index):

  • Tests if the element at the given index is part of the mask.

Vector API Overview in Java 17

Class/Interface Description Key Methods
Vector Represents a vector of elements of a specific type (SIMD operations) add, sub, mul, div, compare, max, min
VectorSpecies Describes the type and length of a vector (e.g., 4 integers) of (creates a new VectorSpecies)
Vector.Operator Defines comparison operators for vector comparisons GT, LT, EQ, NEQ
VectorMask Represents a mask used for filtering elements in vector operations test (tests elements in the mask)
import jdk.incubator.vector.*;

public class VectorAPIDemo {

    public static void main(String[] args) {
        // Arrays to perform operations on
        int[] array1 = {1, 2, 3, 4};
        int[] array2 = {5, 6, 7, 8};

        // Create VectorSpecies (defining vector of 4 integers)
        VectorSpecies<Integer> species = VectorSpecies.of(Integer.class, 4);

        // Load arrays into vectors
        Vector<Integer> vec1 = Vector.fromArray(species, array1, 0);
        Vector<Integer> vec2 = Vector.fromArray(species, array2, 0);

        // Perform operations on vectors
        Vector<Integer> sum = vec1.add(vec2);
        Vector<Integer> diff = vec1.sub(vec2);
        Vector<Integer> max = vec1.max(vec2);

        // Output results
        System.out.println("Sum: " + sum);
        System.out.println("Difference: " + diff);
        System.out.println("Maximum: " + max);
    }
}Code language: JavaScript (javascript)

The Vector API in Java 17 provides an efficient mechanism for performing data-parallel operations on arrays using SIMD instructions. The key classes (Vector, VectorSpecies, Vector.Operator, VectorMask) allow you to define and manipulate vectors with parallel operations, which can significantly improve performance for data-heavy tasks.

Scroll to Top