Skip to content

Commit efe7c97

Browse files
authored
Automatic Partition Count Derivation for ACE (rapidsai#1603)
This PR adds automatic partition count derivation for ACE (Augmented Core Extraction) graph builds based on available system memory. Previously, users had to manually calculate and specify the number of partitions based on their dataset size and available memory. This was error-prone and required understanding the internal memory requirements of the ACE algorithm. With auto-derivation, users get optimal partitioning out of the box while still having the option to override if needed. **Changes** - When `npartitions` is set to `0` (new default), ACE automatically calculates the optimal number of partitions based on available host and GPU memory. - When `npartitions` is set to a positive value, the specified count is used but may be automatically increased if it would exceed memory limits. - Added `max_host_memory_gb` and `max_gpu_memory_gb` parameters to allow users to constrain memory usage (useful for shared systems or testing). This builds on top of PR rapidsai#1597, which should be merged first. Authors: - Julian Miller (https://github.com/julianmi) - Tamas Bela Feher (https://github.com/tfeher) Approvers: - Kyle Edwards (https://github.com/KyleFromNVIDIA) - Tamas Bela Feher (https://github.com/tfeher) - Ben Frederickson (https://github.com/benfred) URL: rapidsai#1603
1 parent 0cae1a6 commit efe7c97

File tree

22 files changed

+897
-153
lines changed

22 files changed

+897
-153
lines changed

c/include/cuvs/neighbors/cagra.h

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,20 @@ struct cuvsAceParams {
137137
/**
138138
* Number of partitions for ACE (Augmented Core Extraction) partitioned build.
139139
*
140+
* When set to 0 (default), the number of partitions is automatically derived
141+
* based on available host and GPU memory to maximize partition size while
142+
* ensuring the build fits in memory.
143+
*
140144
* Small values might improve recall but potentially degrade performance and
141145
* increase memory usage. Partitions should not be too small to prevent issues
142-
* in KNN graph construction. 100k - 5M vectors per partition is recommended
143-
* depending on the available host and GPU memory. The partition size is on
144-
* average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the
145-
* core and augmented vectors. Please account for imbalance in the partition
146-
* sizes (up to 3x in our tests).
146+
* in KNN graph construction. The partition size is on average 2 * (n_rows /
147+
* npartitions) * dim * sizeof(T). 2 is because of the core and augmented
148+
* vectors. Please account for imbalance in the partition sizes (up to 3x in
149+
* our tests).
150+
*
151+
* If the specified number of partitions results in partitions that exceed
152+
* available memory, the value will be automatically increased to fit memory
153+
* constraints and a warning will be issued.
147154
*/
148155
size_t npartitions;
149156
/**
@@ -167,6 +174,22 @@ struct cuvsAceParams {
167174
* When true, enables disk-based operations for memory-efficient graph construction.
168175
*/
169176
bool use_disk;
177+
/**
178+
* Maximum host memory to use for ACE build in GiB.
179+
*
180+
* When set to 0 (default), uses available host memory.
181+
* When set to a positive value, limits host memory usage to the specified amount.
182+
* Useful for testing or when running alongside other memory-intensive processes.
183+
*/
184+
double max_host_memory_gb;
185+
/**
186+
* Maximum GPU memory to use for ACE build in GiB.
187+
*
188+
* When set to 0 (default), uses available GPU memory.
189+
* When set to a positive value, limits GPU memory usage to the specified amount.
190+
* Useful for testing or when running alongside other memory-intensive processes.
191+
*/
192+
double max_gpu_memory_gb;
170193
};
171194

172195
typedef struct cuvsAceParams* cuvsAceParams_t;

c/include/cuvs/neighbors/hnsw.h

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,20 @@ enum cuvsHnswHierarchy {
4646
struct cuvsHnswAceParams {
4747
/**
4848
* Number of partitions for ACE partitioned build.
49+
*
50+
* When set to 0 (default), the number of partitions is automatically derived
51+
* based on available host and GPU memory to maximize partition size while
52+
* ensuring the build fits in memory.
53+
*
4954
* Small values might improve recall but potentially degrade performance and
50-
* increase memory usage. 100k - 5M vectors per partition is recommended.
55+
* increase memory usage. The partition size is on average 2 * (n_rows /
56+
* npartitions) * dim * sizeof(T). 2 is because of the core and augmented
57+
* vectors. Please account for imbalance in the partition sizes (up to 3x in
58+
* our tests).
59+
*
60+
* If the specified number of partitions results in partitions that exceed
61+
* available memory, the value will be automatically increased to fit memory
62+
* constraints and a warning will be issued.
5163
*/
5264
size_t npartitions;
5365
/**
@@ -60,6 +72,18 @@ struct cuvsHnswAceParams {
6072
* When true, enables disk-based operations for memory-efficient graph construction.
6173
*/
6274
bool use_disk;
75+
/**
76+
* Maximum host memory to use for ACE build in GiB.
77+
* When set to 0 (default), uses available host memory.
78+
* Useful for testing or when running alongside other memory-intensive processes.
79+
*/
80+
double max_host_memory_gb;
81+
/**
82+
* Maximum GPU memory to use for ACE build in GiB.
83+
* When set to 0 (default), uses available GPU memory.
84+
* Useful for testing or when running alongside other memory-intensive processes.
85+
*/
86+
double max_gpu_memory_gb;
6387
};
6488

6589
typedef struct cuvsHnswAceParams* cuvsHnswAceParams_t;

c/src/neighbors/cagra.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION.
2+
* SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -88,10 +88,12 @@ static void _set_graph_build_params(
8888
cuvs::neighbors::cagra::graph_build_params::ace_params ace_p;
8989
if (params.graph_build_params) {
9090
auto ace_params_c = static_cast<cuvsAceParams*>(params.graph_build_params);
91-
ace_p.npartitions = ace_params_c->npartitions;
92-
ace_p.ef_construction = ace_params_c->ef_construction;
93-
ace_p.build_dir = std::string(ace_params_c->build_dir);
94-
ace_p.use_disk = ace_params_c->use_disk;
91+
ace_p.npartitions = ace_params_c->npartitions;
92+
ace_p.ef_construction = ace_params_c->ef_construction;
93+
ace_p.build_dir = std::string(ace_params_c->build_dir);
94+
ace_p.use_disk = ace_params_c->use_disk;
95+
ace_p.max_host_memory_gb = ace_params_c->max_host_memory_gb;
96+
ace_p.max_gpu_memory_gb = ace_params_c->max_gpu_memory_gb;
9597
}
9698
out_params = ace_p;
9799
break;
@@ -778,10 +780,12 @@ extern "C" cuvsError_t cuvsAceParamsCreate(cuvsAceParams_t* params)
778780
// Allocate and copy the build directory string
779781
const char* build_dir = strdup(ps.build_dir.c_str());
780782

781-
*params = new cuvsAceParams{.npartitions = ps.npartitions,
782-
.ef_construction = ps.ef_construction,
783-
.build_dir = build_dir,
784-
.use_disk = ps.use_disk};
783+
*params = new cuvsAceParams{.npartitions = ps.npartitions,
784+
.ef_construction = ps.ef_construction,
785+
.build_dir = build_dir,
786+
.use_disk = ps.use_disk,
787+
.max_host_memory_gb = ps.max_host_memory_gb,
788+
.max_gpu_memory_gb = ps.max_gpu_memory_gb};
785789
});
786790
}
787791

c/src/neighbors/hnsw.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ void _build(cuvsResources_t res,
4343
ace_params.npartitions = params->ace_params->npartitions;
4444
ace_params.build_dir = params->ace_params->build_dir ? params->ace_params->build_dir : "/tmp/hnsw_ace_build";
4545
ace_params.use_disk = params->ace_params->use_disk;
46+
ace_params.max_host_memory_gb = params->ace_params->max_host_memory_gb;
47+
ace_params.max_gpu_memory_gb = params->ace_params->max_gpu_memory_gb;
4648
cpp_params.graph_build_params = ace_params;
4749

4850
using dataset_mdspan_type = raft::host_matrix_view<T const, int64_t, raft::row_major>;
@@ -151,9 +153,11 @@ void* _deserialize(cuvsResources_t res,
151153
extern "C" cuvsError_t cuvsHnswAceParamsCreate(cuvsHnswAceParams_t* params)
152154
{
153155
return cuvs::core::translate_exceptions([=] {
154-
*params = new cuvsHnswAceParams{.npartitions = 1,
155-
.build_dir = "/tmp/hnsw_ace_build",
156-
.use_disk = false};
156+
*params = new cuvsHnswAceParams{.npartitions = 0,
157+
.build_dir = "/tmp/hnsw_ace_build",
158+
.use_disk = false,
159+
.max_host_memory_gb = 0,
160+
.max_gpu_memory_gb = 0};
157161
});
158162
}
159163

cpp/include/cuvs/neighbors/graph_build_types.hpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION.
2+
* SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

@@ -99,15 +99,21 @@ struct ace_params {
9999
/**
100100
* Number of partitions for ACE (Augmented Core Extraction) partitioned build.
101101
*
102+
* When set to 0 (default), the number of partitions is automatically derived
103+
* based on available host and GPU memory to maximize partition size while
104+
* ensuring the build fits in memory.
105+
*
102106
* Small values might improve recall but potentially degrade performance and
103107
* increase memory usage. Partitions should not be too small to prevent issues
104-
* in KNN graph construction. 100k - 5M vectors per partition is recommended
105-
* depending on the available host and GPU memory. The partition size is on
106-
* average 2 * (n_rows / npartitions) * dim * sizeof(T). 2 is because of the
107-
* core and augmented vectors. Please account for imbalance in the partition
108-
* sizes (up to 3x in our tests).
108+
* in KNN graph construction. The partition size is on average 2 * (n_rows / npartitions) * dim *
109+
* sizeof(T). 2 is because of the core and augmented vectors. Please account for imbalance in the
110+
* partition sizes (up to 3x in our tests).
111+
*
112+
* If the specified number of partitions results in partitions that exceed
113+
* available memory, the value will be automatically increased to fit memory
114+
* constraints and a warning will be issued.
109115
*/
110-
size_t npartitions = 1;
116+
size_t npartitions = 0;
111117
/**
112118
* The index quality for the ACE build.
113119
*
@@ -129,6 +135,22 @@ struct ace_params {
129135
* When true, enables disk-based operations for memory-efficient graph construction.
130136
*/
131137
bool use_disk = false;
138+
/**
139+
* Maximum host memory to use for ACE build in GiB.
140+
*
141+
* When set to 0 (default), uses available host memory.
142+
* When set to a positive value, limits host memory usage to the specified amount.
143+
* Useful for testing or when running alongside other memory-intensive processes.
144+
*/
145+
double max_host_memory_gb = 0;
146+
/**
147+
* Maximum GPU memory to use for ACE build in GiB.
148+
*
149+
* When set to 0 (default), uses available GPU memory.
150+
* When set to a positive value, limits GPU memory usage to the specified amount.
151+
* Useful for testing or when running alongside other memory-intensive processes.
152+
*/
153+
double max_gpu_memory_gb = 0;
132154

133155
ace_params() = default;
134156
};

0 commit comments

Comments
 (0)