Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 19 additions & 2 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ jobs:
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.pre-commit-config.yaml'
- '!.shellcheckrc'
- '!CODEOWNERS'
- '!Dockerfile'
- '!README.md'
- '!SECURITY.md'
- '!ci/build_docs.sh'
- '!ci/build_go.sh'
- '!ci/build_python.sh'
Expand All @@ -171,14 +175,19 @@ jobs:
- '!ci/test_python.sh'
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!Dockerfile'
- '!conda/environments/**'
- '!conda/recipes/cuvs/**'
- '!conda/recipes/cuvs-bench/**'
- '!conda/recipes/cuvs-bench-cpu/**'
- '!docs/**'
- '!examples/**'
- '!fern/**'
- '!go/**'
- '!img/**'
- '!notebooks/**'
- '!pyproject.toml'
- '!python/**'
- '!rust/**'
- '!go/**'
- '!thirdparty/LICENSES/**'
test_python_conda:
- '**'
Expand All @@ -192,8 +201,12 @@ jobs:
- '!.github/labeler.yml'
- '!.github/ops-bot.yaml'
- '!.github/release.yml'
- '!.github/workflows/check-c-abi.yaml'
- '!.github/workflows/labeler.yml'
- '!.github/workflows/publish-rust.yaml'
- '!.github/workflows/store-c-abi-baseline.yaml'
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.github/workflows/update-c-abi-baseline.yaml'
- '!.pre-commit-config.yaml'
- '!.shellcheckrc'
- '!ci/build_go.sh'
Expand All @@ -210,6 +223,7 @@ jobs:
- '!cpp/.clang-format'
- '!cpp/.clang-tidy'
- '!cpp/doxygen/**'
- '!CODEOWNERS'
- '!Dockerfile'
- '!README.md'
- '!SECURITY.md'
Expand Down Expand Up @@ -252,6 +266,7 @@ jobs:
- '!ci/test_python.sh'
- '!ci/test_standalone_c.sh'
- '!ci/validate_wheel.sh'
- '!CODEOWNERS'
- '!Dockerfile'
- '!README.md'
- '!SECURITY.md'
Expand Down Expand Up @@ -283,6 +298,7 @@ jobs:
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.pre-commit-config.yaml'
- '!.shellcheckrc'
- '!CODEOWNERS'
- '!Dockerfile'
- '!README.md'
- '!SECURITY.md'
Expand Down Expand Up @@ -324,6 +340,7 @@ jobs:
- '!.github/workflows/trigger-breaking-change-alert.yaml'
- '!.pre-commit-config.yaml'
- '!.shellcheckrc'
- '!CODEOWNERS'
- '!Dockerfile'
- '!README.md'
- '!SECURITY.md'
Expand Down
3 changes: 2 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: check-json
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-symlinks
- id: check-xml
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
Expand Down
8 changes: 6 additions & 2 deletions java/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# cuVS Java API


cuVS Java API provides a Java based simple, efficient, and a robust vector search API.

> [!CAUTION]
Expand All @@ -13,7 +12,6 @@ cuVS Java API provides a Java based simple, efficient, and a robust vector searc
- [JDK 22](https://openjdk.org/projects/jdk/22/)
- [jextract for JDK 22](https://jdk.java.net/jextract/) (If not already installed, the build script downloads it)


## Building

The libcuvs C and C++ libraries are needed for this API. If libcuvs libraries have not been built and installed, use `./build.sh libcuvs java` in the top level directory to build this API.
Expand All @@ -26,17 +24,22 @@ do `./build.sh java` in the top level directory or just do `./build.sh` in this
Run `./build.sh --run-java-tests` from this directory.

To run a single test suite:

```sh
cd cuvs-java/
mvn clean integration-test -Dit.test=com.nvidia.cuvs.CagraBuildAndSearchIT
```

or, for a single test:

```sh
mvn clean integration-test -Dit.test=com.nvidia.cuvs.CagraBuildAndSearchIT#testMergeStrategies
```

Be sure to set (manually, if needed) your `LD_LIBRARY_PATH` to include the directory with the appropriate (matching)
version of `libcuvs.so`.
Also, ensure that your panama bindings are up-to-date. They can be re-generated by running:

```sh
./panama-bindings/generate-bindings.sh
```
Expand All @@ -45,6 +48,7 @@ Tests run using a randomized runner. Specific failures can be reproduced running
by passing `-Dtests.seed=42FC5CC6B4C6BA8E` (where `42FC5CC6B4C6BA8E` has to be
replaced with your specific seed). It also possible to re-run a single test, but
in this case it's necessary to pass the extended seed (suite:method), e.g.

```shell
mvn integration-test -Dit.test=com.nvidia.cuvs.CagraBuildAndSearchIT#testFloatIndexing -Dtests.seed=66039A8CAFB9D3C9:449B6310296799E0
```
Expand Down
7 changes: 7 additions & 0 deletions java/benchmarks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,32 @@
This maven project contains JMH benchmarks for the CAGRA Java API.

## Prerequisites

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these whitespace changes are intentional. I was reading these docs and found that all the lines being smooshed together made it slightly harder to find what I was looking for.

This can also prevent some renderers from formatting them correctly, see https://yihui.org/en/2021/06/markdown-breath/

Happy to revert these style changes if reviewers disagree with them.

- [CuVS libraries](https://docs.rapids.ai/api/cuvs/stable/build/#build-from-source)
- Build the CuVS-Java API (`./build.sh` from the parent directory)

## Run benchmarks

Build:

```shell
mvn clean verify
```

Run:

```shell
export RAFT_DEBUG_LOG_FILE=/dev/null
java -jar target/benchmarks.jar
```

The environment variable is needed to silence RAFT logging; RAFT emits some logs at INFO level when
building indices and queries, and writing them to stdout (the default) influences benchmark results.

It is possible to change the dataset size and the vectors dimension via 2 parameters:

```shell
java -jar target/benchmarks.jar -p size=4 -p dims=4
```

Use `java -jar target/benchmarks.jar -h` for details on the options to fine-tune your benchmark runs.
78 changes: 54 additions & 24 deletions java/benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,60 @@

<name>cuvs-java-benchmarks</name>

<repositories>
<!-- Prefer Google Cloud mirror, which has higher rate limits -->
<repository>
<id>gcs-maven-central-mirror</id>
<name>GCS Maven Central mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Fall back to Maven upstream for packages not found in GCS mirror -->
<repository>
<id>central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

<pluginRepositories>
<!-- Prefer Google Cloud mirror, which has higher rate limits -->
<pluginRepository>
<id>gcs-maven-central-mirror</id>
<name>GCS Maven Central mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<!-- Fall back to Maven upstream for packages not found in GCS mirror -->
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
Expand Down Expand Up @@ -104,38 +158,14 @@
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
</plugin>
</plugins>
</pluginManagement>
</build>
Expand Down
6 changes: 6 additions & 0 deletions java/cuvs-java/.mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
-e
-B
-Daether.connector.basic.downstreamThreads=1
-Daether.transport.http.retryHandler.count=5
-Daether.transport.http.retryHandler.interval=10000
-Dmaven.wagon.http.retryHandler.count=5

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will affect every mvn {something} call from the cuvs-java directory. There are several, so using a shared config file seemed preferable to supplying these as CLI arguments.

In short, this is basically "loudly report errors, and make requests to package repositories more slowly"

Explanations:

  • -e
    • print stacktrace on failures (this would have helped us identify the rate-limiting issue much sooner!)
  • -B
    • "batch" mode, basically "don't print thousands of lines of progress bars"
  • -Daether.connector.basic.downstreamThreads=1
    • only download 1 package at a time
  • -Daether.transport.http.retryHandler.interval=10000
  • -Daether.transport.http.retryHandler.count=5 and -Dmaven.wagon.http.retryHandler.count=5

75 changes: 54 additions & 21 deletions java/cuvs-java/pom.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<!--
/*
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
* SPDX-License-Identifier: Apache-2.0
*/
SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand Down Expand Up @@ -54,13 +52,59 @@
<native.build.path>${project.build.directory}/../../../cpp/build</native.build.path>
</properties>

<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppose the deploy/distribute cuvs-java JARs do not depend on this part? If yes, good to remove it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's right, as of now we don't pull or publish snapshots.

As Corey pointed out in #2253 (comment) we may do that in the future, but for now this is unused.

</snapshotRepository>
</distributionManagement>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project doesn't distributed any snapshots... you'll only see releases at https://central.sonatype.com/artifact/com.nvidia.cuvs/cuvs-java/versions

And it doesn't rely on downloading any snapshots of dependencies.

So this configuration is totally unnecessary. As more evidence of that... it references a repo (https://oss.sonatype.org/) that doesn't even exist any more.

$ curl -I https://oss.sonatype.org
HTTP/2 404

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This project doesn't distributed any snapshots... you'll only see releases at

We are actualy shortly going to be deploying nightly snapshos. I know this doesn't change much in this PR (and we still need to ditch the oss.sonatype.org), but I want to point this out because we have several customers asking us to distriute snapshots (some of them cannot build our code).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep makes sense, whatever configuration is needed can be added as part of the work of publishing snapshots.

<repositories>
<!-- Prefer Google Cloud mirror, which has higher rate limits -->
<repository>
<id>gcs-maven-central-mirror</id>
<name>GCS Maven Central mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2/</url>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This read-only mirror of Maven Central faces much higher (or no?) rate limits.

Its docs at https://storage-download.googleapis.com/maven-central/index.html say "This is not an officially supported Google product.", but I think we can trust it... it was first set up back in 2015 by the creator of Maven (http://takari.io/2015/10/28/google-maven-central.html) with enough official Google backing that it was announced on GCP's tech blog: https://cloudplatform.googleblog.com/2015/11/faster-builds-for-Java-developers-with-Maven-Central-mirror.html

It is used by big, high-profile Java projects like Apache Beam, Gluten, Lucene, Orc, and Spark: https://github.com/search?q=org%3Aapache%20%22maven-central.storage-download.googleapis.com%22&type=code

And was recently adopted by cuDF: rapidsai/cudf#22875

<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<!-- Fall back to Maven upstream for packages not found in GCS mirror -->
<repository>
<id>central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

<pluginRepositories>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This configuration has to be duplicated, once for regular dependencies and once for plugins.

See https://maven.apache.org/pom.html#plugin-repositories

<!-- Prefer Google Cloud mirror, which has higher rate limits -->
<pluginRepository>
<id>gcs-maven-central-mirror</id>
<name>GCS Maven Central mirror</name>
<url>https://maven-central.storage-download.googleapis.com/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<!-- Fall back to Maven upstream for packages not found in GCS mirror -->
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>https://repo.maven.apache.org/maven2</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

<dependencies>

Expand Down Expand Up @@ -204,17 +248,6 @@
</execution>
</executions>
</plugin>
<plugin>

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mvn verify attempts to download any dependencies involved in the build "lifecycle" up to but not including deploy (https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#usual-command-line-calls).

It also will try to download and check any dependencies for any stage that have <extensions>true</extensions>.

That's why the original build failures we saw mentioned this nexus-staging-maven-plugin package.

We can just remove this... the release process for cuvs-java doesn't use mvn deploy, it directly hits the Sonatype API with a command similar to this:

curl \
  -XPOST \
  -F bundle=@com.nvidia.cuvs:cuvs-java:26.06.0.zip \
  https://central.sonatype.com/api/v1/publisher/upload

As described at https://central.sonatype.org/publish/publish-portal-api/#uploading-a-deployment-bundle

(publishing code is private, but can link offline for reviewers)

<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<groupId>com.diffplug.spotless</groupId>
<artifactId>spotless-maven-plugin</artifactId>
Expand Down
Loading
Loading