Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3c7b38f
Port native SIMD to Google Highway: C++ infrastructure
r-devulap May 15, 2026
f108a4c
Port native SIMD to Google Highway: FP32 kernels
r-devulap May 15, 2026
6238715
Port native SIMD to Google Highway: PQ kernels
r-devulap May 15, 2026
d4ed0f9
Port native SIMD to Google Highway: NVQ kernels
r-devulap May 15, 2026
397f712
Always prefer native dp, l2 and cosine
r-devulap May 18, 2026
ced7519
Add new calculatePartialSelfSum
r-devulap May 18, 2026
6510a11
Add Meson and Ninja installation to GitHub Actions workflows
r-devulap May 26, 2026
4190499
Add git submodule initialization to GitHub Actions workflows
r-devulap May 26, 2026
e381500
Exclude .gitmodules from RAT checks
r-devulap May 26, 2026
18a90ce
Remove recursive submodule init from unit tests workflow
r-devulap May 27, 2026
887c4b3
Use DataStax license headers and exclude native build artifacts from RAT
r-devulap May 27, 2026
82d9d17
Remove unnecessary file and duplicate gcc version check
r-devulap May 27, 2026
e0106f5
Fix Shuffle2301/Shuffle1032 comments: diagrams and semantics were swa…
r-devulap May 27, 2026
c2e5068
Fix RAT excludes: add module-relative paths for build/ and third_party/
r-devulap May 27, 2026
00b5eef
Use snake case consistently
r-devulap Jun 8, 2026
18b1b5d
Use --auto-install-deps instead of --auto-install-gcc
r-devulap Jun 8, 2026
1edff51
Configure maven-clean-plugin to remove meson build artifacts
r-devulap Jun 25, 2026
80f3229
Mode meson build directory to jvector-native/target
r-devulap Jun 25, 2026
32a0565
Revert "Configure maven-clean-plugin to remove meson build artifacts"
r-devulap Jun 25, 2026
d940c55
Rename jvector-native/src/main/c -> jvector-native/src/main/native
r-devulap Jun 25, 2026
398caeb
ci: add meson/ninja install and submodule init to run-compaction work…
r-devulap Jun 25, 2026
2053dcb
Adding release notes for PR #668
r-devulap Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/run-bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ jobs:
- name: Set up GCC
run: |
sudo apt install -y gcc
- name: Install Meson and Ninja
run: |
sudo apt update && sudo apt install -y meson ninja-build
Comment thread
tlwillke marked this conversation as resolved.
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v3
Expand Down Expand Up @@ -126,6 +129,9 @@ jobs:
ref: ${{ matrix.branch }}
fetch-depth: 0

- name: Initialize Git Submodules
run: git submodule update --init
Comment thread
r-devulap marked this conversation as resolved.

# ==========================================
# Decode and write the protected dataset catalog
#
Expand Down Expand Up @@ -241,9 +247,15 @@ jobs:
needs: test-avx512
runs-on: ubuntu-latest
steps:
- name: Install Meson and Ninja
Comment thread
r-devulap marked this conversation as resolved.
run: |
sudo apt update && sudo apt install -y meson ninja-build
- name: Checkout repository
uses: actions/checkout@v4

- name: Initialize Git Submodules
run: git submodule update --init

- name: Download all benchmark results
uses: actions/download-artifact@v4
with:
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/run-compaction.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ jobs:
steps:
- name: Set up GCC
run: sudo apt install -y gcc
- name: Install Meson and Ninja
run: |
sudo apt update && sudo apt install -y meson ninja-build
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v3
Expand All @@ -70,6 +73,9 @@ jobs:
ref: ${{ matrix.branch }}
fetch-depth: 0

- name: Initialize Git Submodules
run: git submodule update --init

- name: Build branch
run: mvn -B -Punix-amd64-profile package --file pom.xml

Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/unit-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@ jobs:
- name: Set up GCC
run: |
sudo apt install -y gcc
- name: Install Meson and Ninja
run: |
sudo apt update && sudo apt install -y meson ninja-build
- uses: actions/checkout@v4
- name: Initialize Git Submodules
run: git submodule update --init
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v3
with:
Expand Down Expand Up @@ -102,6 +107,8 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Initialize Git Submodules
run: git submodule update --init
- name: Set up JDK
uses: actions/setup-java@v3
with:
Expand All @@ -112,6 +119,10 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt install -y gcc
- name: Install Meson and Ninja
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt update && sudo apt install -y meson ninja-build
- name: Compile, run tests, and package (JDK 22)
run: mvn -B verify
if: matrix.jdk == '22'
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "jvector-native/src/main/native/third_party/highway"]
path = jvector-native/src/main/native/third_party/highway
url = https://github.com/google/highway.git
Comment thread
r-devulap marked this conversation as resolved.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ a dependency from any Java 11 code. When run on a Java 20+ JVM with the Vector m
providers will be used. In general, the project is structured to be built with JDK 20+, but when `JAVA_HOME` is set to
Java 11 -> Java 19, certain build features will still be available.

### Cloning

This repository uses a Git submodule for [Google Highway](https://github.com/google/highway), located at
`jvector-native/src/main/native/third_party/highway`. After cloning, initialise it with:

```bash
git submodule update --init
```

Or clone with submodules in one step:

```bash
git clone --recurse-submodules <repo-url>
```

### Building native libraries

The native SIMD library (`libjvector.so`) requires **g++ 11+** and is built by the script
Comment thread
r-devulap marked this conversation as resolved.
`jvector-native/src/main/native/jextract_vector_simd.sh`. To build and auto-install `g++` on Ubuntu:

```bash
./jvector-native/src/main/native/jextract_vector_simd.sh --auto-install-g++
```

Base code is in [jvector-base](./jvector-base) and will be built for Java 11 releases, restricting language features and APIs
appropriately. Code in [jvector-twenty](./jvector-twenty) will be compiled for Java 20 language features/APIs and included in the final
multirelease jar targeting supported JVMs. [jvector-multirelease](./jvector-multirelease) packages [jvector-base](./jvector-base) and [jvector-twenty](./jvector-twenty) as a
Expand Down
80 changes: 80 additions & 0 deletions docs/release notes/4.1.0/668.performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
### Native SIMD Acceleration via Google Highway

**Description**

This PR introduces a comprehensive native SIMD backend to JVector, porting
**all** Panama Vector API kernels to native code backed by [Google
Highway](https://github.com/google/highway), a portable, header-only C++
library for SIMD operations. Previously, only two kernels in `jvector-native`
were implemented natively; all other SIMD operations relied on the Panama
Vector API as a fallback. Google Highway is currently enabled on all x86-64
platforms. The native shared library (`libjvector.so`) is built as a single
binary containing three ISA-specific variants: AVX-512 (Skylake), AVX2
(Haswell), and SSE4.2. At JVM startup, the most suitable ISA is automatically
selected via CPUID detection. SSE4.2 serves as the minimum supported baseline;
CPUs lacking this capability will trigger a `SIGILL` at runtime.

The ported kernels cover all hot paths:

- **FP32 similarity** — `dot_product`, `cosine`, `euclidean`
- **Product Quantization (PQ)** — `assemble_and_sum`, `calculate_partial_sums`,
`pq_decoded_cosine_similarity`
- **Non-uniform Vector Quantization (NVQ)** — `nvq_quantize_8bit`, `nvq_loss`,
`nvq_square_l2_distance_8bit`, and related helpers
- **Element-wise arithmetic** — `add_in_place`, `sub_in_place`, `max`,
`min_in_place`, and others

A new `calculatePartialSelfSum` kernel was also added. On x86-64, when native
vectorization is enabled, the Google Highway backend is used **exclusively**
for all similarity and quantization operations — the Panama Vector API path is
bypassed almost entirely. On other architectures (ARM, RISC-V, etc.), the
Panama Vector API continues to provide SIMD acceleration as before; native
Highway support for these platforms is planned for a future release if required.

**Purpose / Impact**

- Consistent, portable SIMD coverage across AVX-512, AVX2, and SSE4.2
without per-target intrinsic duplication
- Automatic ISA selection at startup based on CPUID — no manual configuration
needed
- Eliminates reliance on Panama Vector API for similarity kernels, removing
JDK-version sensitivity for the fast path
- Runtime ISA can be capped for testing via the `JVECTOR_MAX_ISA` environment
variable (`avx3`, `avx2`, or `sse42`)
- **Minimum requirement:** SSE4.2-capable x86-64 CPU; older CPUs will crash
with `SIGILL`

**How to Enable**

Native vectorization is opt-in. Add the following JVM flags to enable it:

```bash
java --enable-native-access=ALL-UNNAMED \
-Djvector.experimental.enable_native_vectorization=true \
-jar your-app.jar
```

Once enabled, `NativeVectorizationProvider` loads `libjvector.so` and the
Highway-backed kernels are used automatically for all similarity and
quantization operations.

To additionally cap the ISA for debugging or benchmarking:

```bash
JVECTOR_MAX_ISA=avx2 java --enable-native-access=ALL-UNNAMED \
-Djvector.experimental.enable_native_vectorization=true \
-jar your-app.jar
```

**Notes**

- The build now uses [Meson](https://mesonbuild.com/) + Ninja to compile the
three ISA variants; see
`jvector-native/src/main/native/jextract_vector_simd.sh` for build and
`jextract` binding-regeneration instructions.
- Google Highway is vendored as a Git submodule under
`jvector-native/src/main/native/third_party/highway` at commit
[`16f5f5c7`](https://github.com/google/highway/commit/16f5f5c768064d0bb52952888a14236bec75c104)
(v1.4.0+15).
- CI workflows (unit tests and compaction) were updated to install Meson/Ninja
and initialise the Highway submodule before building.
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ public CosineDecoder(PQVectors cv, VectorFloat<?> query) {
for (int m = 0; m < pq.getSubspaceCount(); ++m) {
int size = pq.subvectorSizesAndOffsets[m][0];
var codebook = pq.codebooks[m];
for (int j = 0; j < pq.getClusterCount(); ++j) {
partialMagnitudes.set((m * pq.getClusterCount()) + j, VectorUtil.dotProduct(codebook, j * size, codebook, j * size, size));
}
VectorUtil.calculatePartialSelfMagnitudes(codebook, m, size, pq.getClusterCount(), partialMagnitudes);
}
return partialMagnitudes;
});
Expand All @@ -117,9 +115,7 @@ public CosineDecoder(PQVectors cv, VectorFloat<?> query) {
int offset = pq.subvectorSizesAndOffsets[m][1];
int size = pq.subvectorSizesAndOffsets[m][0];
var codebook = pq.codebooks[m];
for (int j = 0; j < pq.getClusterCount(); ++j) {
partialSums.set((m * pq.getClusterCount()) + j, VectorUtil.dotProduct(codebook, j * size, centeredQuery, offset, size));
}
VectorUtil.calculatePartialSums(codebook, m, size, pq.getClusterCount(), centeredQuery, offset, VectorSimilarityFunction.DOT_PRODUCT, partialSums);
}

this.bMagnitude = VectorUtil.dotProduct(centeredQuery, centeredQuery);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ public static void calculatePartialSums(VectorFloat<?> codebook, int codebookInd
impl.calculatePartialSums(codebook, codebookIndex, size, clusterCount, query, offset, vsf, partialSums);
}

public static void calculatePartialSelfMagnitudes(VectorFloat<?> codebook, int codebookIndex, int size, int clusterCount, VectorFloat<?> partialMagnitudes) {
impl.calculatePartialSelfMagnitudes(codebook, codebookIndex, size, clusterCount, partialMagnitudes);
}

/**
* Calculates the maximum value in the vector.
* @param v vector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ public interface VectorUtilSupport {

void calculatePartialSums(VectorFloat<?> codebook, int codebookIndex, int size, int clusterCount, VectorFloat<?> query, int offset, VectorSimilarityFunction vsf, VectorFloat<?> partialSums);

default void calculatePartialSelfMagnitudes(VectorFloat<?> codebook, int codebookIndex, int size, int clusterCount, VectorFloat<?> partialMagnitudes) {
int codebookBase = codebookIndex * clusterCount;
for (int i = 0; i < clusterCount; i++) {
partialMagnitudes.set(codebookBase + i, dotProduct(codebook, i * size, codebook, i * size, size));
}
}

float max(VectorFloat<?> v);
float min(VectorFloat<?> v);

Expand Down
2 changes: 1 addition & 1 deletion jvector-native/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<configuration>
<executable>./jextract_vector_simd.sh</executable>
<skip>false</skip>
<workingDirectory>${project.basedir}/src/main/c/</workingDirectory>
<workingDirectory>${project.basedir}/src/main/native/</workingDirectory>
</configuration>
</execution>
</executions>
Expand Down
80 changes: 0 additions & 80 deletions jvector-native/src/main/c/jextract_vector_simd.sh

This file was deleted.

Loading
Loading