Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
47c1430
cuvs-lucene__139: This code allows us to construct the HNSW graph on GPU
Apr 29, 2026
04df750
Consolidate duplicated HNSW graph and field-writing methods
nvzm123 Jul 2, 2026
d5b6aa7
Add example: chunked sequential ingestion of large .fbin files
jamxia155 Jul 14, 2026
288f854
Parallelize level-0 HNSW graph serialization in writeGraph
jamxia155 Jul 14, 2026
198e682
Add native flat buffering for single-segment CAGRA_HNSW builds
jamxia155 Jul 15, 2026
1976027
Parallelize CAGRA-to-HNSW conversion in GPUBuiltHnswGraph
jamxia155 Jul 15, 2026
7275ed5
Add prefetching + reused-array to the fbin ingest example
jamxia155 Jul 31, 2026
ae37031
Honor cagraGraphBuildAlgo override in HEURISTIC strategy
jamxia155 Jul 31, 2026
5b96005
Expand the fbin ingest example into a full optimized CAGRA-HNSW build
jamxia155 Jul 31, 2026
bc3e921
Expand OptimizedCagraHnswBuildExample and add early index-sort check
jamxia155 Aug 13, 2026
3bdeab9
Fix merge errors
jamxia155 Aug 13, 2026
c942646
Add a Lucene-version tripwire and round-trip test for NativeFlatVecto…
jamxia155 Aug 13, 2026
48e0ad7
Add equivalence test for writerThreads-parallelized graph constructio…
jamxia155 Aug 13, 2026
5f20ffd
Add functional coverage for native flat buffering (numInputVectors)
jamxia155 Aug 13, 2026
1fc5d79
Fix merge-time vector-count bug causing intermittent EOF during search
jamxia155 Aug 14, 2026
42fd98a
Restore unintended M-derivation change in createMultiLayerHnswGraph
jamxia155 Aug 14, 2026
5f48c40
Restore unnecessary removals
jamxia155 Aug 14, 2026
82de634
Fix inconsistent handling of explicit CuVSIvfPqParams under HEURISTIC…
jamxia155 Aug 14, 2026
c3db2f8
Guard against native flat buffering with quantized fields
jamxia155 Aug 14, 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
14 changes: 14 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ To run the Index and Search on GPU example do:
```sh
mvn clean install && java -Djava.util.logging.config.file=src/main/resources/logging.properties -cp target/examples-26.10.0-jar-with-merged-services.jar com.nvidia.cuvs.lucene.examples.IndexAndSearchonGPUExample
```

To run the optimized CAGRA-HNSW build example (reference pattern for efficiently building an
accelerated HNSW index from a large `.fbin` with every ingest-side knob on — open the file once and
stream sequential prefetched chunks that overlap the disk read with indexing, hold at most two chunks
in memory, reuse a single vector array, size a native flat buffer per segment, auto-select the CAGRA
graph-build algorithm, and optionally partition into K segments built sequentially or overlapped) do:

```sh
mvn clean install && java -Djava.util.logging.config.file=src/main/resources/logging.properties -cp target/examples-26.10.0-jar-with-merged-services.jar com.nvidia.cuvs.lucene.examples.OptimizedCagraHnswBuildExample
```

With no arguments it generates and indexes a small demo `.fbin` as a single segment; pass a real file,
chunk size, segment count, and overlap flag as
`... OptimizedCagraHnswBuildExample <path-to.fbin> <chunkSizeMB> <numSegments> <overlap:true|false>`.
5 changes: 5 additions & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@
<artifactId>lucene-backward-codecs</artifactId>
<version>10.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-misc</artifactId>
<version>10.2.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
Expand Down

Large diffs are not rendered by default.

65 changes: 62 additions & 3 deletions src/main/java/com/nvidia/cuvs/lucene/AcceleratedHNSWParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,14 @@ public static enum Strategy {
public static final int DEFAULT_MAX_CONN = 32;
public static final int DEFAULT_BEAM_WIDTH = 32;
public static final CagraGraphBuildAlgo DEFAULT_CAGRA_GRAPH_BUILD_ALGO =
CagraGraphBuildAlgo.NN_DESCENT;
CagraGraphBuildAlgo.AUTO_SELECT;
public static final int DEFAULT_NUM_MERGE_WORKERS = 1;
public static final Strategy DEFAULT_STRATEGY = Strategy.HEURISTIC;
public static final CuvsDistanceType DEFAULT_CUVS_DISTANCE_TYPE = CuvsDistanceType.L2Expanded;
public static final int DEFAULT_NN_DESCENT_NUM_ITERATIONS = 20;
public static final HnswHeuristicType DEFAULT_HNSW_HEURISTIC_TYPE =
HnswHeuristicType.SAME_GRAPH_FOOTPRINT;
public static final int DEFAULT_NUM_INPUT_VECTORS = 0;

public static final Supplier<CuVSIvfPqParams> DEFAULT_IVF_PQ_PARAMS =
() -> {
Expand All @@ -85,12 +86,14 @@ public static enum Strategy {
private final int beamWidth;
private final CagraGraphBuildAlgo cagraGraphBuildAlgo;
private final CuVSIvfPqParams cuVSIvfPqParams;
private final boolean cuVSIvfPqParamsExplicit;
private final int numMergeWorkers;
private final ExecutorService mergeExec;
private final Strategy strategy;
private final CuvsDistanceType cuvsDistanceType;
private final int nnDescentNumIterations;
private final HnswHeuristicType hnswHeuristicType;
private final int numInputVectors;

/**
* Constructs an instance of {@link AcceleratedHNSWParams} with specific parameter values.
Expand All @@ -103,12 +106,16 @@ public static enum Strategy {
* @param beamWidth The beam width parameter used when building HNSW index with the fallback mechanism.
* @param cagraGraphBuildAlgo The CAGRA graph build algorithm to use [NN_DESCENT, IVF_PQ].
* @param cuVSIvfPqParams An instance of CuVSIvfPqParams containing IVF_PQ specific parameters.
* @param cuVSIvfPqParamsExplicit whether cuVSIvfPqParams was set explicitly by the caller, as
* opposed to defaulted; consulted under HEURISTIC with an explicit IVF_PQ override so a
* caller-supplied value is honored instead of silently replaced by the auto-tuned one.
* @param numMergeWorkers The number of merge workers to use with the fallback mechanism.
* @param mergeExec The instance of {@link ExecutorService} to use with the fallback mechanism.
* @param strategy either HEURISTIC [Default] that delegates the CAGRA build parameters to cuVS (derived from the HNSW-equivalent maxConn and beamWidth) or CUSTOM that uses the parameters passed through this class.
* @param cuvsDistanceType the cuvsDistanceType. The default option is L2Expanded.
* @param nnDescentNumIterations the number of Iterations to run if building with NN_DESCENT.
* @param hnswHeuristicType the heuristic cuVS applies when deriving the CAGRA build parameters from maxConn and beamWidth under the HEURISTIC strategy.
* @param numInputVectors exact number of vectors to be indexed, used to pre-size the native flat buffer (0 = disabled).
*/
private AcceleratedHNSWParams(
int writerThreads,
Expand All @@ -119,12 +126,14 @@ private AcceleratedHNSWParams(
int beamWidth,
CagraGraphBuildAlgo cagraGraphBuildAlgo,
CuVSIvfPqParams cuVSIvfPqParams,
boolean cuVSIvfPqParamsExplicit,
int numMergeWorkers,
ExecutorService mergeExec,
Strategy strategy,
CuvsDistanceType cuvsDistanceType,
int nnDescentNumIterations,
HnswHeuristicType hnswHeuristicType) {
HnswHeuristicType hnswHeuristicType,
int numInputVectors) {
super();
this.writerThreads = writerThreads;
this.intermediateGraphDegree = intermediateGraphDegree;
Expand All @@ -134,12 +143,14 @@ private AcceleratedHNSWParams(
this.beamWidth = beamWidth;
this.cagraGraphBuildAlgo = cagraGraphBuildAlgo;
this.cuVSIvfPqParams = cuVSIvfPqParams;
this.cuVSIvfPqParamsExplicit = cuVSIvfPqParamsExplicit;
this.numMergeWorkers = numMergeWorkers;
this.mergeExec = mergeExec;
this.strategy = strategy;
this.cuvsDistanceType = cuvsDistanceType;
this.nnDescentNumIterations = nnDescentNumIterations;
this.hnswHeuristicType = hnswHeuristicType;
this.numInputVectors = numInputVectors;
}

/**
Expand Down Expand Up @@ -214,6 +225,16 @@ public CuVSIvfPqParams getCuVSIvfPqParams() {
return cuVSIvfPqParams;
}

/**
* Whether {@link #getCuVSIvfPqParams()} was set explicitly via {@link
* Builder#withCuVSIvfPqParams(CuVSIvfPqParams)}, as opposed to defaulted.
*
* @return true if the caller explicitly set cuVSIvfPqParams
*/
public boolean isCuVSIvfPqParamsExplicit() {
return cuVSIvfPqParamsExplicit;
}

/**
* Get the number of merge workers set to be used in the fallback mechanism
*
Expand Down Expand Up @@ -272,6 +293,17 @@ public HnswHeuristicType getHnswHeuristicType() {
return hnswHeuristicType;
}

/**
* Get the number of input vectors used to pre-size the native flat buffer. A value of
* {@value DEFAULT_NUM_INPUT_VECTORS} means unset (the writer uses the default heap-buffered
* flat path).
*
* @return the number of vectors to be indexed, or 0 if unset
*/
public int getNumInputVectors() {
return numInputVectors;
}

@Override
public String toString() {
return "AcceleratedHNSWParams [writerThreads="
Expand Down Expand Up @@ -302,6 +334,8 @@ public String toString() {
+ nnDescentNumIterations
+ ", hnswHeuristicType="
+ hnswHeuristicType
+ ", numInputVectors="
+ numInputVectors
+ "]";
}

Expand All @@ -319,11 +353,13 @@ public static class Builder {
private CagraGraphBuildAlgo cagraGraphBuildAlgo = DEFAULT_CAGRA_GRAPH_BUILD_ALGO;
private int numMergeWorkers = DEFAULT_NUM_MERGE_WORKERS;
private CuVSIvfPqParams cuVSIvfPqParams = null;
private boolean cuVSIvfPqParamsExplicit = false;
private ExecutorService mergeExec = null;
private Strategy strategy = DEFAULT_STRATEGY;
private CuvsDistanceType cuvsDistanceType = DEFAULT_CUVS_DISTANCE_TYPE;
private int nnDescentNumIterations = DEFAULT_NN_DESCENT_NUM_ITERATIONS;
private HnswHeuristicType hnswHeuristicType = DEFAULT_HNSW_HEURISTIC_TYPE;
private int numInputVectors = DEFAULT_NUM_INPUT_VECTORS;

/**
* Set the number of cuVS writer threads while building the index
Expand Down Expand Up @@ -423,6 +459,7 @@ public Builder withCagraGraphBuildAlgo(CagraGraphBuildAlgo cagraGraphBuildAlgo)
*/
public Builder withCuVSIvfPqParams(CuVSIvfPqParams cuVSIvfPqParams) {
this.cuVSIvfPqParams = cuVSIvfPqParams;
this.cuVSIvfPqParamsExplicit = true;
return this;
}

Expand Down Expand Up @@ -507,6 +544,23 @@ public Builder withHnswHeuristicType(HnswHeuristicType hnswHeuristicType) {
return this;
}

/**
* Set the exact number of vectors to be indexed, used to pre-allocate a single contiguous
* native flat buffer (avoiding the on-heap {@code List<float[]>} and the extra host-matrix
* copy). The native buffer is sized for exactly this many rows, so the value MUST equal the
* number of vectors actually added; the writer fails fast otherwise. Only supported for the
* unsorted single-segment CAGRA_HNSW build (no merges). Not yet supported for the
* binary/scalar quantized writers. A value of {@value DEFAULT_NUM_INPUT_VECTORS} (the
* default) disables it and uses the default heap-buffered flat path.
*
* @param numInputVectors the exact number of vectors to be indexed, or 0 to disable
* @return instance of {@link Builder}
*/
public Builder withNumInputVectors(int numInputVectors) {
this.numInputVectors = numInputVectors;
return this;
}

/**
* Validates the input parameters.
*
Expand Down Expand Up @@ -591,6 +645,9 @@ private void validate() throws IllegalArgumentException {
+ MAX_NN_DESCENT_NUM_ITERATIONS
+ "]");
}
if (numInputVectors < 0) {
throw new IllegalArgumentException("numInputVectors cannot be negative.");
}
}

/**
Expand All @@ -615,12 +672,14 @@ public AcceleratedHNSWParams build() {
beamWidth,
cagraGraphBuildAlgo,
cuVSIvfPqParams,
cuVSIvfPqParamsExplicit,
numMergeWorkers,
mergeExec,
strategy,
cuvsDistanceType,
nnDescentNumIterations,
hnswHeuristicType);
hnswHeuristicType,
numInputVectors);
}
}
}
Loading