Skip to content

Optimize recall calculation and enhance CAGRA search features - #2502

Open
sherylll wants to merge 4 commits into
NVIDIA:mainfrom
sherylll:improve-cagra-heuristic
Open

Optimize recall calculation and enhance CAGRA search features#2502
sherylll wants to merge 4 commits into
NVIDIA:mainfrom
sherylll:improve-cagra-heuristic

Conversation

@sherylll

@sherylll sherylll commented Aug 25, 2026

Copy link
Copy Markdown
  • Enable auto search_width selection.

current default at 1 can be too weak for large itopk, e.g. itopk=512, width=1, graph_degree=64, and does not introduce enough diversity by each expansion. Support search_width=0 now, which select width to be ceildiv(itopk,graph_degree)

  • Adjust hashmap_min_bitlen based on shared memory size.

The current default (min_bitlen=8) can be too conservative, and often limits the hash reset interval to just 1 (reset every iteration). For later GPU architectures SMEM is usually larger and we can afford a larger hashmap size. I did experiments on a B300 with 228KB SMEM and min_bitlen=11 is consistently best performing for itopk <=256 (for itopk=512 12 bits wins).
compare_bitlen

  • Improve auto max_iterations for multi-CTA algo. Previous fixed base_iteration=32 is too conservative and the QPS-recall curve is way below the actual pareto curve. Added a search_quality parameter to adjust the search budget. This parameter is fixed to 3 for the moment.
compare_quality_k10_nq1,pareto

Decoupes work assignment in recall calculatoin loop from batch size (n_queries) used for search.
This prevents each worker from having very little to do when batch size is small.
@sherylll
sherylll requested review from a team as code owners August 25, 2026 11:34
@copy-pr-bot

copy-pr-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@sherylll

sherylll commented Aug 25, 2026

Copy link
Copy Markdown
Author

A sample run with the new defaults, varying itopk and n_queries:

Run on (224 X 3985.15 MHz CPU s)
CPU Caches:
  L1 Data 48 KiB (x112)
  L1 Instruction 32 KiB (x112)
  L2 Unified 2048 KiB (x112)
  L3 Unified 307200 KiB (x2)
Load Average: 4.84, 5.48, 5.66
command_line: /home/scratch.yuxsun_gpu/workspace/cuvs/cpp/build/bench/ann/CUVS_CAGRA_ANN_BENCH --search --data_prefix=/tmp/data --index_prefix=/tmp/data --mode=latency --benchmark_counters_tabular=true --benchmark_min_warmup_time=0.2 --benchmark_min_time=1000x --override_kv=k:10 --override_kv=n_queries:1:100:1000:10000 --override_kv=itopk:64:128:256 --override_kv=search_width:0 my_tests/pareto/configs/wiki_all_1m_cagra.json
dataset: wiki_all_1m_cagra_pareto
dim: 768
distance: euclidean
gpu_driver_version: 13.3
gpu_gpuDirectRDMASupported: 1
gpu_hostNativeAtomicSupported: 0
gpu_mem_bus_width: 7680
gpu_mem_freq: 3996000000.000000
gpu_mem_global_size: 287416123392
gpu_mem_shared_size: 233472
gpu_name: NVIDIA B300 SXM6 AC
gpu_pageableMemoryAccess: 1
gpu_pageableMemoryAccessUsesHostPageTables: 0
gpu_runtime_version: 13.3
gpu_sm_count: 148
gpu_sm_freq: 2032000000.000000
host_cores_used: 14
host_cpu_freq_max: 4000000000
host_cpu_freq_min: 800000000
host_pagesize: 4096
host_processors_sysconf: 224
host_processors_used: 28
host_total_ram_size: 2164172869632
host_total_swap_size: 0
max_k: 100
max_n_queries: 10000
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Benchmark                                                      Time             CPU   Iterations        GPU    Latency     Recall end_to_end items_per_second      itopk          k max_iterations  n_queries search_width total_queries
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cuvs_cagra_wiki_all_1m_g64/0/0/process_time/real_time      0.323 ms        0.323 ms         1000   313.108u   322.779u      0.967   0.322779       3.09812k/s         64         10              0          1            0            1k
cuvs_cagra_wiki_all_1m_g64/1/0/process_time/real_time      0.293 ms        0.293 ms         1000    283.29u   292.833u     0.9865   0.292833       3.41494k/s        128         10              0          1            0            1k
cuvs_cagra_wiki_all_1m_g64/2/0/process_time/real_time      0.291 ms        0.291 ms         1000   280.864u   291.289u     0.9955   0.291289       3.43305k/s        256         10              0          1            0            1k
cuvs_cagra_wiki_all_1m_g64/0/1/process_time/real_time      0.496 ms        0.496 ms         1000   485.453u   496.023u    0.96489   0.496023       201.605k/s         64         10              0        100            0          100k
cuvs_cagra_wiki_all_1m_g64/1/1/process_time/real_time      0.658 ms        0.658 ms         1000   647.788u   657.634u    0.98698   0.657634       152.061k/s        128         10              0        100            0          100k
cuvs_cagra_wiki_all_1m_g64/2/1/process_time/real_time       1.04 ms         1.04 ms         1000   1.02958m   1.03945m     0.9963    1.03945       96.2052k/s        256         10              0        100            0          100k
cuvs_cagra_wiki_all_1m_g64/0/2/process_time/real_time       2.97 ms         2.97 ms         1000   2.95663m   2.96652m    0.97845    2.96652       337.095k/s         64         10              0         1k            0            1M
cuvs_cagra_wiki_all_1m_g64/1/2/process_time/real_time       5.72 ms         5.72 ms         1000   5.71205m   5.72209m    0.99426    5.72209       174.762k/s        128         10              0         1k            0            1M
cuvs_cagra_wiki_all_1m_g64/2/2/process_time/real_time       11.5 ms         11.5 ms         1000  0.0114725  0.0114824    0.99849    11.4824       87.0895k/s        256         10              0         1k            0            1M
cuvs_cagra_wiki_all_1m_g64/0/3/process_time/real_time       24.9 ms         24.9 ms         1000     0.0249    0.02491    0.97845      24.91       401.445k/s         64         10              0        10k            0           10M
cuvs_cagra_wiki_all_1m_g64/1/3/process_time/real_time       48.1 ms         48.1 ms         1000  0.0480594  0.0480702    0.99425    48.0702       208.029k/s        128         10              0        10k            0           10M
cuvs_cagra_wiki_all_1m_g64/2/3/process_time/real_time       96.9 ms         97.0 ms         1000  0.0969007  0.0969111    0.99849    96.9111       103.187k/s        256         10              0        10k            0           10M

With the new defaults we shouldn't observe recall drop across multi- to single-CTA algorithm change, as observed in #1187 . In contrary, the recalls even increase mildly... If we want a very smooth transition we could play with search_quality, but for this PR I think it suffices to keep it 3.

@cjnolet

cjnolet commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Hi @sherylll, please also make sure any relevant configured parameters/options are also being proposed through the Python scripts where necessary (users always go through the Python scripts).

I haven't looked at this PR, just pointing this out, since I know you're onboarding to cuVS.

@sherylll
sherylll marked this pull request as draft August 26, 2026 02:09
Allow search_width=0 to scale exploration with itopk and graph degree, avoiding overly narrow SINGLE_CTA searches at large itopk while preserving MULTI_CTA's existing CTA floor.
At low batch sizes, increasing itopk adds parallel CTAs cheaply, so reduce local iterations as itopk grows. Larger candidate pools tolerate shallower traversal while retaining a fixed quality baseline.
Expose the hashmap bit-length floor to benchmarks and select the automatic default from the GPU's shared-memory capacity for SINGLE_CTA searches while preserving the MULTI_CTA default.
@sherylll
sherylll force-pushed the improve-cagra-heuristic branch from 3ef607a to 885c056 Compare August 27, 2026 02:11
@sherylll
sherylll marked this pull request as ready for review August 27, 2026 03:09
@sherylll

Copy link
Copy Markdown
Author

Hi @cjnolet thanks for the reminder. I undid the quality knob for now, which we might add in a later PR, so that we can keep the scope of this PR to fixing the defaults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recall calculation is very slow for small batch

2 participants