Skip to content
Draft
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
11 changes: 11 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ jobs:
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!docs/**'
- '!examples/**'
- 'examples/build.sh'
- 'examples/c/**'
- 'examples/cmake/**'
- 'examples/cpp/**'
- '!fern/**'
- '!go/**'
- '!img/**'
Expand Down Expand Up @@ -211,6 +216,7 @@ jobs:
- '!conda/recipes/cuvs-bench-cpu/**'
- '!docs/**'
- '!examples/**'
- 'examples/java/**'
- '!fern/**'
- '!go/**'
- '!img/**'
Expand Down Expand Up @@ -263,6 +269,7 @@ jobs:
- '!README.md'
- '!SECURITY.md'
- '!docs/**'
- '!examples/**'
- '!fern/**'
- '!go/**'
- '!img/**'
Expand Down Expand Up @@ -319,6 +326,7 @@ jobs:
- '!cpp/.clang-tidy'
- '!cpp/doxygen/**'
- '!docs/**'
- '!examples/**'
- '!fern/**'
- '!java/**'
- '!go/**'
Expand Down Expand Up @@ -370,6 +378,7 @@ jobs:
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!docs/**'
- '!examples/**'
- '!fern/**'
- '!go/**'
- '!img/**'
Expand Down Expand Up @@ -422,6 +431,8 @@ jobs:
- '!ci/test_wheel_cuvs.sh'
- '!ci/validate_wheel.sh'
- '!docs/**'
- '!examples/**'
- 'examples/go/**'
- '!fern/**'
- '!img/**'
- '!java/**'
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ repos:
name: spotless-fmt
entry: ci/checks/run_spotless.sh
pass_filenames: false
files: ^java/(cuvs-java|cuvs-lucene)/([^/]+/)?src/.*\.java$
files: ^(java|examples/java)/(cuvs-java|cuvs-lucene)/([^/]+/)?src/.*\.java$
exclude: .*/panama/.*
language: script
verbose: true
Expand Down
22 changes: 15 additions & 7 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ARGS=$*
# scripts, and that this script resides in the repo dir!
REPODIR=$(cd "$(dirname "$0")"; pwd)

VALIDARGS="clean libcuvs python rust go java lucene docs tests bench-ann examples --uninstall -v -g -n --allgpuarch --no-mg --mnmg-tests --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h --run-java-tests"
VALIDARGS="clean libcuvs python rust go java lucene docs tests bench-ann examples --uninstall -v -g -n --allgpuarch --no-mg --mnmg-tests --no-cpu --cpu-only --no-shared-libs --no-nvtx --show_depr_warn --incl-cache-stats --time -h --run-java-tests --build-java-examples"
HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<tool>] [--limit-tests=<targets>] [--limit-bench-ann=<targets>] [--build-metrics=<filename>]
where <target> is:
clean - remove all existing build artifacts and configuration (start over)
Expand Down Expand Up @@ -57,6 +57,8 @@ HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<to
--no-shared-libs - build without shared libraries
--show_depr_warn - show cmake deprecation warnings
--run-java-tests - run Java tests after building
--build-java-examples - also build the examples/java/cuvs-java and examples/java/cuvs-lucene
projects against the jars just built (with the 'java'/'lucene' targets)
--build-metrics - filename for generating build metrics report for libcuvs
--incl-cache-stats - include cache statistics in build metrics report
--cmake-args=\\\"<args>\\\" - pass arbitrary list of CMake configuration options (escape all quotes in argument)
Expand Down Expand Up @@ -560,11 +562,14 @@ if (( NUMARGS == 0 )) || hasArg java; then
echo "Please add 'libcuvs' to this script's arguments (ex. './build.sh libcuvs java') if libcuvs libraries are not already built"
fi
cd "${REPODIR}"/java
JAVA_BUILD_ARGS=()
if hasArg --run-java-tests; then
./build.sh --run-java-tests
else
./build.sh
JAVA_BUILD_ARGS+=("--run-java-tests")
fi
if hasArg --build-java-examples; then
JAVA_BUILD_ARGS+=("--build-java-examples")
fi
./build.sh "${JAVA_BUILD_ARGS[@]}"
fi

# Build the cuvs-lucene codecs
Expand All @@ -573,11 +578,14 @@ if (( NUMARGS == 0 )) || hasArg lucene; then
echo "Please add 'java' to this script's arguments (ex. './build.sh libcuvs java lucene') if the cuvs Java bindings are not already built"
fi
cd "${REPODIR}"/java/cuvs-lucene
LUCENE_BUILD_ARGS=()
if hasArg --run-java-tests; then
./build.sh --run-java-tests
else
./build.sh
LUCENE_BUILD_ARGS+=("--run-java-tests")
fi
if hasArg --build-java-examples; then
LUCENE_BUILD_ARGS+=("--build-java-examples")
fi
./build.sh "${LUCENE_BUILD_ARGS[@]}"
fi

RAPIDS_VERSION="$(sed -E -e 's/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}).*$/\1.\2.\3/' "${REPODIR}/VERSION")"
Expand Down
2 changes: 1 addition & 1 deletion ci/build_java.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export SCCACHE_S3_USE_PREPROCESSOR_CACHE_MODE=true
# TODO: Remove this argument-handling when build and test workflows are separated,
# and test_java.sh no longer calls build_java.sh
# ref: https://github.com/nvidia/cuvs/issues/868
EXTRA_BUILD_ARGS=()
EXTRA_BUILD_ARGS=("--build-java-examples")
if [[ "${1:-}" == "--run-java-tests" ]]; then
EXTRA_BUILD_ARGS+=("--run-java-tests")
fi
Expand Down
2 changes: 1 addition & 1 deletion ci/build_lucene.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set -euo pipefail
# TODO: Remove the flag handling when build and test workflows are separated,
# and test_lucene.sh no longer calls build_lucene.sh
# ref: https://github.com/rapidsai/cuvs/issues/868
EXTRA_BUILD_ARGS=()
EXTRA_BUILD_ARGS=("--build-java-examples")
CUVS_JAVA_ARTIFACT=""
for arg in "$@"; do
case "${arg}" in
Expand Down
9 changes: 5 additions & 4 deletions ci/checks/run_spotless.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# SPDX-License-Identifier: Apache-2.0

# pre-commit hook wrapper that runs 'spotless:apply' to format the Java sources of every Maven
# project under java/.
# project under java/ and examples/java/.
#
# Most cuvs contributors do not work on the Java client and do not have Maven installed. For them,
# running 'pre-commit run --all-files' matches every Java source file in the repo regardless of
Expand All @@ -15,11 +15,11 @@ set -euo pipefail

# Keep these in sync with the spotless-fmt hook's 'files'/'exclude' entries in
# .pre-commit-config.yaml.
JAVA_SRC_PATTERN='^java/(cuvs-java|cuvs-lucene)/([^/]+/)?src/.*\.java$'
JAVA_SRC_PATTERN='^(java|examples/java)/(cuvs-java|cuvs-lucene)/([^/]+/)?src/.*\.java$'
JAVA_SRC_EXCLUDE='.*/panama/.*'

java_sources_modified() {
git status --porcelain --untracked-files=all -- java/cuvs-java java/cuvs-lucene |
git status --porcelain --untracked-files=all -- java/cuvs-java java/cuvs-lucene examples/java |
cut -c4- |
grep -Ev "${JAVA_SRC_EXCLUDE}" |
grep -Eq "${JAVA_SRC_PATTERN}"
Expand All @@ -42,7 +42,8 @@ POMS=(
java/cuvs-java/pom.xml
java/cuvs-lucene/pom.xml
java/cuvs-lucene/bench/pom.xml
java/cuvs-lucene/examples/pom.xml
examples/java/cuvs-java/pom.xml
examples/java/cuvs-lucene/pom.xml
)

for pom in "${POMS[@]}"; do
Expand Down
8 changes: 4 additions & 4 deletions ci/release/update-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,16 +172,16 @@ done
NEXT_FULL_JAVA_TAG="${NEXT_SHORT_TAG}.${PATCH_PEP440}"
sed_runner "s/VERSION=\".*\"/VERSION=\"${NEXT_FULL_JAVA_TAG}\"/g" java/build.sh
sed_runner "s/VERSION=\".*\"/VERSION=\"${NEXT_FULL_JAVA_TAG}\"/g" java/cuvs-lucene/build.sh
for FILE in java/*/pom.xml java/cuvs-lucene/bench/pom.xml java/cuvs-lucene/examples/pom.xml; do
for FILE in java/*/pom.xml java/cuvs-lucene/bench/pom.xml examples/java/cuvs-java/pom.xml examples/java/cuvs-lucene/pom.xml; do
sed_runner "/<!--CUVS_JAVA#VERSION_UPDATE_MARKER_START-->.*<!--CUVS_JAVA#VERSION_UPDATE_MARKER_END-->/s//<!--CUVS_JAVA#VERSION_UPDATE_MARKER_START--><version>${NEXT_FULL_JAVA_TAG}<\/version><!--CUVS_JAVA#VERSION_UPDATE_MARKER_END-->/g" "${FILE}"
done

sed_runner "s| CuVS [[:digit:]]\{2\}\.[[:digit:]]\{2\} | CuVS ${NEXT_SHORT_TAG} |g" java/README.md
sed_runner "s|-[[:digit:]]\{2\}\.[[:digit:]]\{2\}\.[[:digit:]]\{1,2\}\.jar|-${NEXT_FULL_JAVA_TAG}\.jar|g" java/examples/README.md
sed_runner "s|/[[:digit:]]\{2\}\.[[:digit:]]\{2\}\.[[:digit:]]\{1,2\}/|/${NEXT_FULL_JAVA_TAG}/|g" java/examples/README.md
sed_runner "s|-[[:digit:]]\{2\}\.[[:digit:]]\{2\}\.[[:digit:]]\{1,2\}\.jar|-${NEXT_FULL_JAVA_TAG}\.jar|g" examples/java/cuvs-java/README.md
sed_runner "s|/[[:digit:]]\{2\}\.[[:digit:]]\{2\}\.[[:digit:]]\{1,2\}/|/${NEXT_FULL_JAVA_TAG}/|g" examples/java/cuvs-java/README.md

# This pattern is deliberately narrow: java/cuvs-lucene/README.md also links to a blog post whose
# title contains a release number, and that reference must not be rewritten.
sed_runner "s|<version>[[:digit:]]\{2\}\.[[:digit:]]\{2\}\.[[:digit:]]\{1,2\}</version>|<version>${NEXT_FULL_JAVA_TAG}</version>|g" java/cuvs-lucene/README.md

sed_runner "s|target/examples-[\.0-9]*-jar|target/examples-${NEXT_FULL_JAVA_TAG}-jar|g" java/cuvs-lucene/examples/README.md
sed_runner "s|target/examples-[\.0-9]*-jar|target/examples-${NEXT_FULL_JAVA_TAG}-jar|g" examples/java/cuvs-lucene/README.md
8 changes: 8 additions & 0 deletions examples/java/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
*.iml
hs_err*.log
target/

# serialized indexes written by the cuvs-java examples
*.cag
*.hnsw
*.bf
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.nvidia.cuvs.examples;
Expand Down Expand Up @@ -41,7 +41,7 @@ public static void main(String[] args) throws Throwable {

// Create a query object with the query vectors
BruteForceQuery cuvsQuery =
new BruteForceQuery.Builder().withTopK(3).withQueryVectors(queries).build();
new BruteForceQuery.Builder(resources).withTopK(3).withQueryVectors(queries).build();

// Set index parameters
BruteForceIndexParams indexParams = new BruteForceIndexParams.Builder().build();
Expand Down Expand Up @@ -75,8 +75,8 @@ public static void main(String[] args) throws Throwable {
log.info(results.getResults().toString());

// Cleanup
index.destroyIndex();
loadedIndex.destroyIndex();
index.close();
loadedIndex.close();

if (indexFile.exists()) {
indexFile.delete();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.nvidia.cuvs.examples;
Expand All @@ -10,6 +10,7 @@
import com.nvidia.cuvs.CagraIndexParams.CuvsDistanceType;
import com.nvidia.cuvs.CagraQuery;
import com.nvidia.cuvs.CagraSearchParams;
import com.nvidia.cuvs.CuVSMatrix;
import com.nvidia.cuvs.CuVSResources;
import com.nvidia.cuvs.SearchResults;
import java.io.File;
Expand Down Expand Up @@ -66,33 +67,45 @@ public static void main(String[] args) throws Throwable {
CagraIndex loadedIndex = CagraIndex.newBuilder(resources).from(inputStream).build();

// Configure search parameters
CagraSearchParams searchParams = new CagraSearchParams.Builder(resources).build();

// Create a query object with the query vectors
CagraQuery cuvsQuery =
new CagraQuery.Builder()
.withTopK(3)
.withSearchParams(searchParams)
.withQueryVectors(queries)
.build();

// Perform the search
SearchResults results = index.search(cuvsQuery);

// Check results
log.info(results.getResults().toString());

// Search from deserialized index
results = loadedIndex.search(cuvsQuery);

// Check results
log.info(results.getResults().toString());
CagraSearchParams searchParams = new CagraSearchParams.Builder().build();

// A host-built index and a graph-only deserialized index both leave the index without the
// device-padded vectors CAGRA search needs, so give each index its own padded copy.
try (CuVSMatrix queryVectors = CuVSMatrix.ofArray(queries);
CuVSMatrix hostVectors = CuVSMatrix.ofArray(vectors);
CuVSMatrix deviceVectors = hostVectors.toDevice(resources);
var indexDataset = index.makePaddedDataset(deviceVectors);
var loadedDataset = loadedIndex.makePaddedDataset(deviceVectors)) {
index.updateDataset(indexDataset);
loadedIndex.updateDataset(loadedDataset);

// Create a query object with the query vectors
CagraQuery cuvsQuery =
new CagraQuery.Builder(resources)
.withTopK(3)
.withSearchParams(searchParams)
.withQueryVectors(queryVectors)
.build();

// Perform the search
SearchResults results = index.search(cuvsQuery);

// Check results
log.info(results.getResults().toString());

// Search from deserialized index
results = loadedIndex.search(cuvsQuery);

// Check results
log.info(results.getResults().toString());
}

// Cleanup
if (indexFile.exists()) {
indexFile.delete();
}
index.destroyIndex();
index.close();
loadedIndex.close();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package com.nvidia.cuvs.examples;
Expand All @@ -14,6 +14,7 @@
import com.nvidia.cuvs.CuVSResources;
import com.nvidia.cuvs.HnswIndex;
import com.nvidia.cuvs.HnswIndexParams;
import com.nvidia.cuvs.HnswIndexParams.HnswHierarchy;
import com.nvidia.cuvs.HnswQuery;
import com.nvidia.cuvs.HnswSearchParams;
import com.nvidia.cuvs.SearchResults;
Expand Down Expand Up @@ -79,8 +80,12 @@ public static void main(String[] args) throws Throwable {
String hnswIndexFileName = UUID.randomUUID().toString() + ".hnsw";
index.serializeToHNSW(new FileOutputStream(hnswIndexFileName));

// Use NONE hierarchy since serializeToHNSW creates a base-layer-only index
HnswIndexParams hnswIndexParams =
new HnswIndexParams.Builder().withVectorDimension(2).build();
new HnswIndexParams.Builder()
.withVectorDimension(2)
.withHierarchy(HnswHierarchy.NONE)
.build();
InputStream inputStreamHNSW = new FileInputStream(hnswIndexFileName);
File hnswIndexFile = new File(hnswIndexFileName);

Expand All @@ -93,7 +98,7 @@ public static void main(String[] args) throws Throwable {
HnswSearchParams hnswSearchParams = new HnswSearchParams.Builder().build();

HnswQuery hnswQuery =
new HnswQuery.Builder()
new HnswQuery.Builder(resources)
.withQueryVectors(queries)
.withSearchParams(hnswSearchParams)
.withTopK(3)
Expand All @@ -108,8 +113,8 @@ public static void main(String[] args) throws Throwable {
if (hnswIndexFile.exists()) {
hnswIndexFile.delete();
}
index.destroyIndex();
hnswIndex.destroyIndex();
index.close();
hnswIndex.close();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ This maven project contains basic examples that showcase how `cuvs-lucene` can b

## Prerequisites

- The [`cuvs-lucene` prerequisites](../README.md#prerequisites)
- The [`cuvs-lucene` prerequisites](../../../java/cuvs-lucene/README.md#prerequisites)

## Steps

First build `cuvs-lucene` and install it into your local Maven repository, as described in
[Building from source](../README.md#building-from-source). From the cuVS repository root:
[Building from source](../../../java/cuvs-lucene/README.md#building-from-source). From the cuVS repository root:

```sh
./build.sh libcuvs java lucene
Expand All @@ -18,7 +18,7 @@ First build `cuvs-lucene` and install it into your local Maven repository, as de
Then return to this directory:

```sh
cd java/cuvs-lucene/examples
cd examples/java/cuvs-lucene
```

To run Accelerated HNSW example do:
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ This process-wide setting is independent of any host-side filter cache and is di

## Examples

A few starter examples of CAGRA, HNSW, and Bruteforce indexing and searching are provided in the `examples` directory.
A few starter examples of CAGRA, HNSW, and Bruteforce indexing and searching are provided in the [`examples/`](../examples/java/cuvs-java) directory.
6 changes: 6 additions & 0 deletions java/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,9 @@ mvn clean verify "${MAVEN_VERIFY_ARGS[@]}" -P "$BUILD_PROFILE" \
&& mvn install:install-file -Dfile=./target/cuvs-java-$VERSION.jar -DgroupId=$GROUP_ID -DartifactId=cuvs-java -Dversion=$VERSION -Dpackaging=jar \
&& mvn install:install-file -Dfile=./target/cuvs-java-$VERSION-"$BUILD_PROFILE".jar -DgroupId=$GROUP_ID -DartifactId=cuvs-java -Dversion=$VERSION -Dclassifier="$BUILD_PROFILE" -Dpackaging=jar \
&& cp pom.xml ./target/

# Build the cuvs-java examples against the jar just installed above, to catch drift between the
# examples and the cuvs-java API.
if hasArg --build-java-examples; then
mvn -f ../../examples/java/cuvs-java/pom.xml package
fi
Loading
Loading