Skip to content

Lucene: define and validate CAGRA parameter boundaries - #2516

Open
shaunakkapur wants to merge 10 commits into
NVIDIA:mainfrom
shaunakkapur:codex/lucene-parameter-boundaries
Open

Lucene: define and validate CAGRA parameter boundaries#2516
shaunakkapur wants to merge 10 commits into
NVIDIA:mainfrom
shaunakkapur:codex/lucene-parameter-boundaries

Conversation

@shaunakkapur

@shaunakkapur shaunakkapur commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Define and document boundaries for all five Lucene CAGRA parameter families: writer threads, intermediate graph degree, graph degree, iTopK, and search width.

Validate individual build parameter ranges when public builder setters are called. Validate at build time that graphDegree does not exceed intermediateGraphDegree, independent of setter order.

Validate search parameters when GPUKnnFloatVectorQuery is constructed, including the native SINGLE_CTA iTopK limit and the numeric safety limit for search width.

Add focused minimum, maximum, invalid range, cross field relationship, and search algorithm coverage.

Testing

  • TestAcceleratedHNSWParams
  • TestGPUSearchParams
  • TestGPUKnnFloatVectorQueryParameters
  • TestSegmentMaxConnConsistency.testSingleVectorSegmentDoesNotUseConfiguredGraphDegree
  • 29 tests passed with zero failures, errors, or skips
  • Spotless check passed
  • git diff check passed

Closes #2450

@copy-pr-bot

copy-pr-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@shaunakkapur

Copy link
Copy Markdown
Contributor Author

/ok to test efb837a

@cjnolet cjnolet added improvement Improves an existing functionality non-breaking Introduces a non-breaking change labels Aug 27, 2026
@cjnolet cjnolet moved this to In Progress in Unstructured Data Processing Aug 27, 2026
@shaunakkapur shaunakkapur changed the title Lucene: define CAGRA parameter boundaries Lucene: define and validate CAGRA parameter boundaries Aug 27, 2026
@shaunakkapur

Copy link
Copy Markdown
Contributor Author

/ok to test a405e39

@shaunakkapur

Copy link
Copy Markdown
Contributor Author

/ok to test 9bdd04b

1 similar comment
@shaunakkapur

Copy link
Copy Markdown
Contributor Author

/ok to test 9bdd04b

@shaunakkapur

Copy link
Copy Markdown
Contributor Author

/ok to test 558635f

@shaunakkapur
shaunakkapur marked this pull request as ready for review August 28, 2026 02:12
@shaunakkapur
shaunakkapur requested a review from a team as a code owner August 28, 2026 02:12

@dantegd dantegd left a comment

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.

Great to see this PR! Just had a few comments

Comment thread java/cuvs-lucene/src/main/java/com/nvidia/cuvs/lucene/GPUKnnFloatVectorQuery.java Outdated
Comment on lines +74 to +90
/** Smallest supported CAGRA intermediate-result count. */
public static final int MIN_ITOPK = 1;

/** Largest intermediate-result count representable by the public Java API. */
public static final int MAX_ITOPK = Integer.MAX_VALUE;

/** Largest intermediate-result count supported by CAGRA's SINGLE_CTA search algorithm. */
public static final int MAX_SINGLE_CTA_ITOPK = 512;

/** Smallest supported number of CAGRA search entry points. */
public static final int MIN_SEARCH_WIDTH = 1;

/**
* Largest search width that keeps CAGRA's result buffer within its unsigned 32-bit indexing
* limit at the maximum graph degree and aligned {@link #MAX_ITOPK}.
*/
public static final int MAX_SEARCH_WIDTH = 4_194_303;

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.

I wonder if we should reconsider how these upper bounds are derived? MAX_SEARCH_WIDTH appears to protect the unsigned result-buffer calculation, but that isn’t the limiting calculation for the MULTI_CTA path that a normal one-query AUTO search uses.

MULTI_CTA sizes its hash from max(searchWidth, ceil(iTopK / 32)) * max(32, maxIterations). With MAX_SEARCH_WIDTH, that requires at least a 28-bit hash table, while native CAGRA hard-limits it to 25. MAX_ITOPK is even larger and would require a 32-bit table, beyond the range of the native 1U << bitlen sizing.

Since the current test only constructs the Java query, it doesn’t exercise these native constraints. What do you think about validating after the algorithm is resolved and adding a test that actually creates the native search plan?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, these were presented as more universal than they are. The oversized searchWidth test now goes through a normal one-query AUTO search and asserts the native failure names the hash_bitlen 25-bit limit, and the README/javadoc now say only the minimum of 1 and the SINGLE_CTA max of 512 are real native limits.

One open item: I couldn't add equivalent coverage for MAX_ITOPK. With iTopK = Integer.MAX_VALUE the native call doesn't return an error, it leaks and stays stuck past the test's own timeout, so asserting on it isn't CI-safe. I documented that in the test. Since the real limit depends on the resolved algorithm and other settings, would you rather we enforce an algorithm-specific limit in the Lucene API, or fix the native calculation to reject it safely first?

- Scope graphDegree <= intermediateGraphDegree validation to CUSTOM
  strategy in AcceleratedHNSWParams/GPUSearchParams; HEURISTIC derives
  both degrees and ignores the configured pair, so previously a valid
  HEURISTIC config could fail to build over values that were never
  used. Remove the resulting workaround setter from
  TestSegmentMaxConnConsistency and add regression tests for both the
  CUSTOM enforcement and the HEURISTIC no-op case.

- Re-validate the SINGLE_CTA effective iTopK limit against the value
  actually sent to native CAGRA in CuVS2510GPUVectorsReader, not just
  the value checked at GPUKnnFloatVectorQuery construction time: the
  filtered per-segment fallback path can raise topK further based on
  filter cardinality after construction, so a config valid at
  construction could still send an out-of-range value to native CAGRA.
  Add a regression test reproducing this exact scenario.

- Stop presenting GPUKnnFloatVectorQuery's MAX_ITOPK/MAX_SEARCH_WIDTH
  as universally valid native ranges in the README and tests. Only the
  lower bound of 1 and the SINGLE_CTA iTopK maximum of 512 are genuine
  native limits; other upper bounds depend on the resolved algorithm,
  max_iterations, graph degree, and dataset size, none of which are
  known at query-construction time. Document that native CAGRA rejects
  unsupported combinations itself (e.g. MULTI_CTA's 25-bit traversal
  hash-table limit), and add a test that builds a real native search
  plan to confirm this for an oversized MULTI_CTA searchWidth. Also
  correct the README's HEURISTIC description: AcceleratedHNSWParams
  derives both degrees from maxConn/beamWidth, while GPUSearchParams
  passes the configured graphDegree into the dataset heuristic and
  derives the rest from it.

Signed-off-by: Shaunak Kapur <shaunakk@nvidia.com>
- TestNativeSearchPlanBoundaryRejection: exercise AUTO (not an
  explicit MULTI_CTA) for the oversized searchWidth case, matching
  the reviewer's exact "normal one-query AUTO search resolves to
  MULTI_CTA" scenario, and assert the native exception message names
  the hash_bitlen/25 limit so an unrelated native/CUDA failure can't
  make the test pass. Also document why this class deliberately does
  not add an equivalent MAX_ITOPK case: empirically, iTopK =
  Integer.MAX_VALUE does not fail fast like an oversized searchWidth
  -- it hangs indefinitely inside the native call instead, which
  would make a test asserting on it unsafe to run in CI.

- TestFilteredSingleCtaITopKValidation: assert the rejection message
  names SINGLE_CTA and the specific 512/513 values, confirming the
  post-filter re-validation fired rather than some unrelated argument
  check.

- README: clarify that most parameter checks run at construction
  time but the SINGLE_CTA iTopK limit is additionally re-checked at
  search time, and that only intermediateGraphDegree is ignored under
  HEURISTIC for GPUSearchParams (graphDegree is passed into the
  dataset-size heuristic, not ignored).

Verified locally: full compile, 34/34 relevant tests pass (including
both native GPU-backed integration tests), spotless clean.

Signed-off-by: Shaunak Kapur <shaunakk@nvidia.com>
The javadoc and README claimed native CAGRA rejects any oversized
itopk_size/searchWidth combination with a clear exception. Measurement
shows that only holds below a threshold: above roughly iTopK 1e9 the
native hash-table sizing loop fails to terminate and the search hangs
instead of erroring. Correct that claim, stop implying MAX_ITOPK is a
usable maximum, and point at NVIDIA#2523 which tracks the native defect.

Documentation only; no behaviour change.

Signed-off-by: Shaunak Kapur <shaunakk@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality non-breaking Introduces a non-breaking change

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Lucene: Define and implement parameter boundaries

3 participants