diff --git a/build.sh b/build.sh index 81bcff971..6dd250c51 100755 --- a/build.sh +++ b/build.sh @@ -351,10 +351,12 @@ if (( ${NUMARGS} == 0 )) || hasArg libcuvs || hasArg docs || hasArg tests || has -DCMAKE_CUDA_ARCHITECTURES=${CUVS_CMAKE_CUDA_ARCHITECTURES} \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ -DCUVS_COMPILE_LIBRARY=${COMPILE_LIBRARY} \ + -DBUILD_C_LIBRARY=${COMPILE_LIBRARY} \ -DCUVS_NVTX=${NVTX} \ -DCUDA_LOG_COMPILE_TIME=${LOG_COMPILE_TIME} \ -DDISABLE_DEPRECATION_WARNINGS=${DISABLE_DEPRECATION_WARNINGS} \ -DBUILD_TESTS=${BUILD_TESTS} \ + -DBUILD_C_TESTS=${BUILD_TESTS} \ -DBUILD_CPU_ONLY=${BUILD_CPU_ONLY} \ -DCMAKE_MESSAGE_LOG_LEVEL=${CMAKE_LOG_LEVEL} \ ${CACHE_ARGS} \ diff --git a/cpp/include/cuvs/neighbors/cagra_c.h b/cpp/include/cuvs/neighbors/cagra_c.h index 105f4f1b9..2d6ce74b6 100644 --- a/cpp/include/cuvs/neighbors/cagra_c.h +++ b/cpp/include/cuvs/neighbors/cagra_c.h @@ -46,15 +46,22 @@ enum cagraGraphBuildAlgo { */ struct cagraIndexParams { /** Degree of input graph for pruning. */ - size_t intermediate_graph_degree = 128; + size_t intermediate_graph_degree; /** Degree of output graph. */ - size_t graph_degree = 64; + size_t graph_degree; /** ANN algorithm to build knn graph. */ - cagraGraphBuildAlgo build_algo = IVF_PQ; + enum cagraGraphBuildAlgo build_algo; /** Number of Iterations to run if building with NN_DESCENT */ - size_t nn_descent_niter = 20; + size_t nn_descent_niter; }; +typedef struct cagraIndexParams cagraIndexParams; + +/** + * @brief Default cagraIndexParams to use + */ +extern const cagraIndexParams cagraDefaultIndexParams; + /** * @brief Enum to denote algorithm used to search CAGRA Index * @@ -78,49 +85,55 @@ enum cagraHashMode { HASH, SMALL, AUTO_HASH }; * @brief Supplemental parameters to search CAGRA index * */ -typedef struct { +struct cagraSearchParams { /** Maximum number of queries to search at the same time (batch size). Auto select when 0.*/ - size_t max_queries = 0; + size_t max_queries; /** Number of intermediate search results retained during the search. * * This is the main knob to adjust trade off between accuracy and search speed. * Higher values improve the search accuracy. */ - size_t itopk_size = 64; + size_t itopk_size; /** Upper limit of search iterations. Auto select when 0.*/ - size_t max_iterations = 0; + size_t max_iterations; // In the following we list additional search parameters for fine tuning. // Reasonable default values are automatically chosen. /** Which search implementation to use. */ - cagraSearchAlgo algo = AUTO; + enum cagraSearchAlgo algo; /** Number of threads used to calculate a single distance. 4, 8, 16, or 32. */ - size_t team_size = 0; + size_t team_size; /** Number of graph nodes to select as the starting point for the search in each iteration. aka * search width?*/ - size_t search_width = 1; + size_t search_width; /** Lower limit of search iterations. */ - size_t min_iterations = 0; + size_t min_iterations; /** Thread block size. 0, 64, 128, 256, 512, 1024. Auto selection when 0. */ - size_t thread_block_size = 0; + size_t thread_block_size; /** Hashmap type. Auto selection when AUTO. */ - cagraHashMode hashmap_mode = AUTO_HASH; + enum cagraHashMode hashmap_mode; /** Lower limit of hashmap bit length. More than 8. */ - size_t hashmap_min_bitlen = 0; + size_t hashmap_min_bitlen; /** Upper limit of hashmap fill rate. More than 0.1, less than 0.9.*/ - float hashmap_max_fill_rate = 0.5; + float hashmap_max_fill_rate; /** Number of iterations of initial random seed node selection. 1 or more. */ - uint32_t num_random_samplings = 1; + uint32_t num_random_samplings; /** Bit mask used for initial random seed node selection. */ - uint64_t rand_xor_mask = 0x128394; -} cagraSearchParams; + uint64_t rand_xor_mask; +}; +typedef struct cagraSearchParams cagraSearchParams; + +/** + * @brief Default cagraSearchParams to use + */ +extern const cagraSearchParams cagraDefaultSearchParams; /** * @brief Struct to hold address of cuvs::neighbors::cagra::index and its active trained dtype @@ -187,7 +200,7 @@ cuvsError_t cagraIndexDestroy(cagraIndex_t index); * @return cuvsError_t */ cuvsError_t cagraBuild(cuvsResources_t res, - cagraIndexParams params, + struct cagraIndexParams params, DLManagedTensor* dataset, cagraIndex_t index); diff --git a/cpp/src/neighbors/cagra_c.cpp b/cpp/src/neighbors/cagra_c.cpp index 1c9403efe..eaaf3cc98 100644 --- a/cpp/src/neighbors/cagra_c.cpp +++ b/cpp/src/neighbors/cagra_c.cpp @@ -201,3 +201,14 @@ extern "C" cuvsError_t cagraSearch(cuvsResources_t res, return CUVS_ERROR; } } + +extern "C" const cagraSearchParams cagraDefaultSearchParams = {.itopk_size = 64, + .search_width = 1, + .hashmap_max_fill_rate = 0.5, + .num_random_samplings = 1, + .rand_xor_mask = 0x128394}; + +extern "C" const cagraIndexParams cagraDefaultIndexParams = {.intermediate_graph_degree = 128, + .graph_degree = 64, + .build_algo = IVF_PQ, + .nn_descent_niter = 20}; diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt index e5880797a..609bc2d4e 100644 --- a/cpp/test/CMakeLists.txt +++ b/cpp/test/CMakeLists.txt @@ -117,6 +117,8 @@ if(BUILD_C_TESTS) enable_language(C) add_executable(cuvs_c_test test/core/c_api.c) - target_link_libraries(cuvs_c_test PUBLIC cuvs::c_api) + + add_executable(cuvs_c_neighbors_test test/neighbors/c_api.c) + target_link_libraries(cuvs_c_neighbors_test PUBLIC cuvs::c_api) endif() diff --git a/cpp/test/neighbors/ann_cagra_c.cu b/cpp/test/neighbors/ann_cagra_c.cu index 1a8dc920f..b866c4df1 100644 --- a/cpp/test/neighbors/ann_cagra_c.cu +++ b/cpp/test/neighbors/ann_cagra_c.cu @@ -60,7 +60,7 @@ TEST(CagraC, BuildSearch) cagraIndexCreate(&index); // build index - cagraIndexParams build_params; + cagraIndexParams build_params = cagraDefaultIndexParams; cagraBuild(res, build_params, &dataset_tensor, index); // create queries DLTensor @@ -110,7 +110,7 @@ TEST(CagraC, BuildSearch) distances_tensor.dl_tensor.strides = nullptr; // search index - cagraSearchParams search_params; + cagraSearchParams search_params = cagraDefaultSearchParams; cagraSearch(res, search_params, index, &queries_tensor, &neighbors_tensor, &distances_tensor); // verify output diff --git a/cpp/test/neighbors/c_api.c b/cpp/test/neighbors/c_api.c new file mode 100644 index 000000000..d4f5ad08e --- /dev/null +++ b/cpp/test/neighbors/c_api.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024, NVIDIA CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +int main() +{ + // simple smoke test to make sure that we can compile the cagra_c.h API + // using a c compiler. This isn't aiming to be a full test, just checking + // that the exposed C-API is valid C code and doesn't contain C++ features + cagraIndex_t index; + cagraIndexCreate(&index); + cagraIndexDestroy(index); + return 0; +}