Skip to content

Commit 9e3d44f

Browse files
committed
Merge branch 'c-add-memory-pool' of https://github.com/ajit283/cuvs into c-add-memory-pool
2 parents aa5f7f5 + e6a4226 commit 9e3d44f

36 files changed

Lines changed: 2209 additions & 2 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,4 @@ cagra_index
7474
ivf_flat_index
7575
ivf_pq_index
7676

77+
.aider*

build.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@ ARGS=$*
1818
# scripts, and that this script resides in the repo dir!
1919
REPODIR=$(cd $(dirname $0); pwd)
2020

21-
VALIDARGS="clean libcuvs python rust docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-nvtx --show_depr_warn --incl-cache-stats --time -h"
21+
VALIDARGS="clean libcuvs python rust go docs tests bench-ann examples --uninstall -v -g -n --compile-static-lib --allgpuarch --no-nvtx --show_depr_warn --incl-cache-stats --time -h"
2222
HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<tool>] [--limit-tests=<targets>] [--limit-bench-ann=<targets>] [--build-metrics=<filename>]
2323
where <target> is:
2424
clean - remove all existing build artifacts and configuration (start over)
2525
libcuvs - build the cuvs C++ code only. Also builds the C-wrapper library
2626
around the C++ code.
2727
python - build the cuvs Python package
2828
rust - build the cuvs Rust bindings
29+
go - build the cuvs Go bindings
2930
docs - build the documentation
3031
tests - build the tests
3132
bench-ann - build end-to-end ann benchmarks
@@ -426,6 +427,13 @@ if (( ${NUMARGS} == 0 )) || hasArg rust; then
426427
cargo test
427428
fi
428429

430+
# Build the cuvs Go bindings
431+
if (( ${NUMARGS} == 0 )) || hasArg go; then
432+
cd ${REPODIR}/go
433+
go build ./...
434+
go test ./...
435+
fi
436+
429437
export RAPIDS_VERSION="$(sed -E -e 's/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}).*$/\1.\2.\3/' "${REPODIR}/VERSION")"
430438
export RAPIDS_VERSION_MAJOR_MINOR="$(sed -E -e 's/^([0-9]{2})\.([0-9]{2})\.([0-9]{2}).*$/\1.\2/' "${REPODIR}/VERSION")"
431439

ci/build_go.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# Copyright (c) 2024, NVIDIA CORPORATION.
3+
4+
set -euo pipefail
5+
6+
rapids-logger "Create test conda environment"
7+
. /opt/conda/etc/profile.d/conda.sh
8+
9+
10+
rapids-mamba-retry env create --yes -n go
11+
12+
# seeing failures on activating the environment here on unbound locals
13+
# apply workaround from https://github.com/conda/conda/issues/8186#issuecomment-532874667
14+
set +eu
15+
conda activate go
16+
set -eu
17+
18+
rapids-print-env
19+
20+
export CGO_CFLAGS="-I$CONDA_PREFIX/include -I/usr/local/cuda/include -I/usr/local/include"
21+
export CGO_LDFLAGS="-L$CONDA_PREFIX/lib -L/usr/local/cuda/lib64 -lcuvs_c -lcudart -Wl,-rpath,$CONDA_PREFIX/lib-Wl,-rpath,/usr/local/cuda/lib64"
22+
23+
rapids-logger "Downloading artifacts from previous jobs"
24+
CPP_CHANNEL=$(rapids-download-conda-from-s3 cpp)
25+
26+
# installing libcuvs/libraft will speed up the rust build substantially
27+
rapids-mamba-retry install \
28+
--channel "${CPP_CHANNEL}" \
29+
libcuvs \
30+
libraft \
31+
cuvs
32+
33+
bash ./build.sh go

cpp/include/cuvs/core/c_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ cuvsError_t cuvsRMMFree(cuvsResources_t res, void* ptr, size_t bytes);
140140
* available memory
141141
* @return cuvsError_t
142142
*/
143+
143144
cuvsError_t cuvsRMMPoolMemoryResourceEnable(int initial_pool_size_percent,
144145
int max_pool_size_percent,
145146
int managed);
@@ -149,6 +150,7 @@ cuvsError_t cuvsRMMPoolMemoryResourceEnable(int initial_pool_size_percent,
149150
*/
150151
cuvsError_t cuvsRMMMemoryResourceReset();
151152

153+
152154
/** @} */
153155

154156
#ifdef __cplusplus

cpp/include/cuvs/neighbors/cagra.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,42 @@ cuvsError_t cuvsCagraCompressionParamsCreate(cuvsCagraCompressionParams_t* param
137137
*/
138138
cuvsError_t cuvsCagraCompressionParamsDestroy(cuvsCagraCompressionParams_t params);
139139

140+
/**
141+
* @}
142+
*/
143+
144+
/**
145+
* @defgroup cagra_c_extend_params C API for CUDA ANN Graph-based nearest neighbor search
146+
* @{
147+
*/
148+
/**
149+
* @brief Supplemental parameters to extend CAGRA Index
150+
*
151+
*/
152+
struct cuvsCagraExtendParams {
153+
/** Degree of input graph for pruning. */
154+
uint32_t max_chunk_size;
155+
/** Degree of output graph. */
156+
};
157+
158+
typedef struct cuvsCagraExtendParams* cuvsCagraExtendParams_t;
159+
160+
/**
161+
* @brief Allocate CAGRA Extend params, and populate with default values
162+
*
163+
* @param[in] params cuvsCagraExtendParams_t to allocate
164+
* @return cuvsError_t
165+
*/
166+
cuvsError_t cuvsCagraExtendParamsCreate(cuvsCagraExtendParams_t* params);
167+
168+
/**
169+
* @brief De-allocate CAGRA Extend params
170+
*
171+
* @param[in] params
172+
* @return cuvsError_t
173+
*/
174+
cuvsError_t cuvsCagraExtendParamsDestroy(cuvsCagraExtendParams_t params);
175+
140176
/**
141177
* @}
142178
*/
@@ -327,6 +363,34 @@ cuvsError_t cuvsCagraBuild(cuvsResources_t res,
327363
* @}
328364
*/
329365

366+
/**
367+
* @defgroup cagra_c_extend_params C API for CUDA ANN Graph-based nearest neighbor search
368+
* @{
369+
*/
370+
371+
/**
372+
* @brief Extend a CAGRA index with a `DLManagedTensor` which has underlying
373+
* `DLDeviceType` equal to `kDLCUDA`, `kDLCUDAHost`, `kDLCUDAManaged`,
374+
* or `kDLCPU`. Also, acceptable underlying types are:
375+
* 1. `kDLDataType.code == kDLFloat` and `kDLDataType.bits = 32`
376+
* 2. `kDLDataType.code == kDLInt` and `kDLDataType.bits = 8`
377+
* 3. `kDLDataType.code == kDLUInt` and `kDLDataType.bits = 8`
378+
*
379+
* @param[in] res cuvsResources_t opaque C handle
380+
* @param[in] params cuvsCagraExtendParams_t used to extend CAGRA index
381+
* @param[in] additional_dataset DLManagedTensor* additional dataset
382+
* @param[out] index cuvsCagraIndex_t Extended CAGRA index
383+
* @return cuvsError_t
384+
*/
385+
cuvsError_t cuvsCagraExtend(cuvsResources_t res,
386+
cuvsCagraExtendParams_t params,
387+
DLManagedTensor* additional_dataset,
388+
cuvsCagraIndex_t index);
389+
390+
/**
391+
* @}
392+
*/
393+
330394
/**
331395
* @defgroup cagra_c_index_search C API for CUDA ANN Graph-based nearest neighbor search
332396
* @{

cpp/src/core/c_api.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
#include <rmm/mr/device/owning_wrapper.hpp>
2727
#include <rmm/mr/device/per_device_resource.hpp>
2828
#include <rmm/mr/device/pool_memory_resource.hpp>
29-
3029
#include <thread>
3130

3231
extern "C" cuvsError_t cuvsResourcesCreate(cuvsResources_t* res)
@@ -69,6 +68,8 @@ extern "C" cuvsError_t cuvsStreamSync(cuvsResources_t res)
6968
});
7069
}
7170

71+
thread_local std::unique_ptr<rmm::mr::pool_memory_resource<rmm::mr::cuda_memory_resource>> pool_mr;
72+
7273
extern "C" cuvsError_t cuvsRMMAlloc(cuvsResources_t res, void** ptr, size_t bytes)
7374
{
7475
return cuvs::core::translate_exceptions([=] {
@@ -87,6 +88,7 @@ extern "C" cuvsError_t cuvsRMMFree(cuvsResources_t res, void* ptr, size_t bytes)
8788
});
8889
}
8990

91+
9092
thread_local std::shared_ptr<
9193
rmm::mr::owning_wrapper<rmm::mr::pool_memory_resource<rmm::mr::device_memory_resource>,
9294
rmm::mr::device_memory_resource>>
@@ -104,6 +106,7 @@ extern "C" cuvsError_t cuvsRMMPoolMemoryResourceEnable(int initial_pool_size_per
104106
throw std::runtime_error("Current memory resource is not a cuda_memory_resource");
105107
}
106108

109+
107110
auto initial_size = rmm::percent_of_free_device_memory(initial_pool_size_percent);
108111
auto max_size = rmm::percent_of_free_device_memory(max_pool_size_percent);
109112

@@ -119,10 +122,12 @@ extern "C" cuvsError_t cuvsRMMPoolMemoryResourceEnable(int initial_pool_size_per
119122
pool_mr =
120123
rmm::mr::make_owning_wrapper<rmm::mr::pool_memory_resource>(mr, initial_size, max_size);
121124

125+
122126
rmm::mr::set_current_device_resource(pool_mr.get());
123127
});
124128
}
125129

130+
126131
extern "C" cuvsError_t cuvsRMMMemoryResourceReset()
127132
{
128133
return cuvs::core::translate_exceptions([=] {

cpp/src/neighbors/cagra_c.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,34 @@ void* _build(cuvsResources_t res, cuvsCagraIndexParams params, DLManagedTensor*
8383
return index;
8484
}
8585

86+
template <typename T>
87+
void _extend(cuvsResources_t res,
88+
cuvsCagraExtendParams params,
89+
cuvsCagraIndex index,
90+
DLManagedTensor* additional_dataset_tensor)
91+
{
92+
auto dataset = additional_dataset_tensor->dl_tensor;
93+
auto index_ptr = reinterpret_cast<cuvs::neighbors::cagra::index<T, uint32_t>*>(index.addr);
94+
auto res_ptr = reinterpret_cast<raft::resources*>(res);
95+
96+
auto extend_params = cuvs::neighbors::cagra::extend_params();
97+
extend_params.max_chunk_size = params.max_chunk_size;
98+
99+
if (cuvs::core::is_dlpack_device_compatible(dataset)) {
100+
using mdspan_type = raft::device_matrix_view<T const, int64_t, raft::row_major>;
101+
auto mds = cuvs::core::from_dlpack<mdspan_type>(additional_dataset_tensor);
102+
cuvs::neighbors::cagra::extend(*res_ptr, extend_params, mds, *index_ptr);
103+
} else if (cuvs::core::is_dlpack_host_compatible(dataset)) {
104+
using mdspan_type = raft::host_matrix_view<T const, int64_t, raft::row_major>;
105+
auto mds = cuvs::core::from_dlpack<mdspan_type>(additional_dataset_tensor);
106+
cuvs::neighbors::cagra::extend(*res_ptr, extend_params, mds, *index_ptr);
107+
} else {
108+
RAFT_FAIL("Unsupported dataset DLtensor dtype: %d and bits: %d",
109+
dataset.dtype.code,
110+
dataset.dtype.bits);
111+
}
112+
}
113+
86114
template <typename T>
87115
void _search(cuvsResources_t res,
88116
cuvsCagraSearchParams params,
@@ -190,6 +218,29 @@ extern "C" cuvsError_t cuvsCagraBuild(cuvsResources_t res,
190218
});
191219
}
192220

221+
extern "C" cuvsError_t cuvsCagraExtend(cuvsResources_t res,
222+
cuvsCagraExtendParams_t params,
223+
DLManagedTensor* additional_dataset_tensor,
224+
cuvsCagraIndex_t index_c_ptr)
225+
{
226+
return cuvs::core::translate_exceptions([=] {
227+
auto dataset = additional_dataset_tensor->dl_tensor;
228+
auto index = *index_c_ptr;
229+
230+
if ((dataset.dtype.code == kDLFloat) && (dataset.dtype.bits == 32)) {
231+
_extend<float>(res, *params, index, additional_dataset_tensor);
232+
} else if (dataset.dtype.code == kDLInt && dataset.dtype.bits == 8) {
233+
_extend<int8_t>(res, *params, index, additional_dataset_tensor);
234+
} else if (dataset.dtype.code == kDLUInt && dataset.dtype.bits == 8) {
235+
_extend<uint8_t>(res, *params, index, additional_dataset_tensor);
236+
} else {
237+
RAFT_FAIL("Unsupported dataset DLtensor dtype: %d and bits: %d",
238+
dataset.dtype.code,
239+
dataset.dtype.bits);
240+
}
241+
});
242+
}
243+
193244
extern "C" cuvsError_t cuvsCagraSearch(cuvsResources_t res,
194245
cuvsCagraSearchParams_t params,
195246
cuvsCagraIndex_t index_c_ptr,
@@ -265,6 +316,17 @@ extern "C" cuvsError_t cuvsCagraCompressionParamsDestroy(cuvsCagraCompressionPar
265316
return cuvs::core::translate_exceptions([=] { delete params; });
266317
}
267318

319+
extern "C" cuvsError_t cuvsCagraExtendParamsCreate(cuvsCagraExtendParams_t* params)
320+
{
321+
return cuvs::core::translate_exceptions(
322+
[=] { *params = new cuvsCagraExtendParams{.max_chunk_size = 0}; });
323+
}
324+
325+
extern "C" cuvsError_t cuvsCagraExtendParamsDestroy(cuvsCagraExtendParams_t params)
326+
{
327+
return cuvs::core::translate_exceptions([=] { delete params; });
328+
}
329+
268330
extern "C" cuvsError_t cuvsCagraSearchParamsCreate(cuvsCagraSearchParams_t* params)
269331
{
270332
return cuvs::core::translate_exceptions([=] {

cpp/test/core/c_api.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ int main()
5555
if (free_error_pool == CUVS_ERROR) { exit(EXIT_FAILURE); }
5656

5757
// Reset pool memory resource
58+
5859
cuvsError_t reset_error = cuvsRMMMemoryResourceReset();
5960
if (reset_error == CUVS_ERROR) { exit(EXIT_FAILURE); }
6061

cpp/test/neighbors/ann_cagra_c.cu

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,20 @@ TEST(CagraC, BuildSearch)
5757
dataset_tensor.dl_tensor.shape = dataset_shape;
5858
dataset_tensor.dl_tensor.strides = nullptr;
5959

60+
// create additional dataset DLTensor
61+
rmm::device_uvector<float> additional_d(4 * 2, stream);
62+
raft::copy(additional_d.data(), (float*)dataset, 4 * 2, stream);
63+
DLManagedTensor additional_dataset_tensor;
64+
additional_dataset_tensor.dl_tensor.data = additional_d.data();
65+
additional_dataset_tensor.dl_tensor.device.device_type = kDLCUDA;
66+
additional_dataset_tensor.dl_tensor.ndim = 2;
67+
additional_dataset_tensor.dl_tensor.dtype.code = kDLFloat;
68+
additional_dataset_tensor.dl_tensor.dtype.bits = 32;
69+
additional_dataset_tensor.dl_tensor.dtype.lanes = 1;
70+
int64_t additional_dataset_shape[2] = {4, 2};
71+
additional_dataset_tensor.dl_tensor.shape = additional_dataset_shape;
72+
additional_dataset_tensor.dl_tensor.strides = nullptr;
73+
6074
// create index
6175
cuvsCagraIndex_t index;
6276
cuvsCagraIndexCreate(&index);
@@ -66,6 +80,11 @@ TEST(CagraC, BuildSearch)
6680
cuvsCagraIndexParamsCreate(&build_params);
6781
cuvsCagraBuild(res, build_params, &dataset_tensor, index);
6882

83+
cuvsCagraExtendParams_t extend_params;
84+
cuvsCagraExtendParamsCreate(&extend_params);
85+
extend_params->max_chunk_size = 100;
86+
cuvsCagraExtend(res, extend_params, &additional_dataset_tensor, index);
87+
6988
// create queries DLTensor
7089
rmm::device_uvector<float> queries_d(4 * 2, stream);
7190
raft::copy(queries_d.data(), (float*)queries, 4 * 2, stream);
@@ -122,6 +141,7 @@ TEST(CagraC, BuildSearch)
122141

123142
// de-allocate index and res
124143
cuvsCagraSearchParamsDestroy(search_params);
144+
cuvsCagraExtendParamsDestroy(extend_params);
125145
cuvsCagraIndexParamsDestroy(build_params);
126146
cuvsCagraIndexDestroy(index);
127147
cuvsResourcesDestroy(res);

examples/c/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR)
1515

16+
set(CMAKE_CUDA_ARCHITECTURES 89)
17+
1618
# ------------- configure rapids-cmake --------------#
1719

1820
include(../cmake/thirdparty/fetch_rapids.cmake)

0 commit comments

Comments
 (0)