-
Notifications
You must be signed in to change notification settings - Fork 70
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CAGRA C example and DlPack docs (#51)
Authors: - Divye Gala (https://github.com/divyegala) - Corey J. Nolet (https://github.com/cjnolet) - Kyle Edwards (https://github.com/KyleFromNVIDIA) - Bradley Dice (https://github.com/bdice) - Ben Frederickson (https://github.com/benfred) Approvers: - Dante Gama Dessavre (https://github.com/dantegd) - Corey J. Nolet (https://github.com/cjnolet) URL: #51
- Loading branch information
Showing
12 changed files
with
372 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#!/bin/bash | ||
|
||
# Copyright (c) 2023-2024, NVIDIA CORPORATION. | ||
|
||
# cuvs empty project template build script | ||
|
||
# Abort script on first error | ||
set -e | ||
|
||
PARALLEL_LEVEL=${PARALLEL_LEVEL:=`nproc`} | ||
|
||
BUILD_TYPE=Release | ||
BUILD_DIR=build/ | ||
|
||
CUVS_REPO_REL="" | ||
EXTRA_CMAKE_ARGS="" | ||
set -e | ||
|
||
# Root of examples | ||
EXAMPLES_DIR=$(dirname "$(realpath "$0")") | ||
|
||
if [[ ${CUVS_REPO_REL} != "" ]]; then | ||
CUVS_REPO_PATH="`readlink -f \"${CUVS_REPO_REL}\"`" | ||
EXTRA_CMAKE_ARGS="${EXTRA_CMAKE_ARGS} -DCPM_cuvs_SOURCE=${CUVS_REPO_PATH}" | ||
else | ||
LIB_BUILD_DIR=${LIB_BUILD_DIR:-$(readlink -f "${EXAMPLES_DIR}/../cpp/build")} | ||
EXTRA_CMAKE_ARGS="${EXTRA_CMAKE_ARGS} -Dcuvs_ROOT=${LIB_BUILD_DIR}" | ||
fi | ||
|
||
if [ "$1" == "clean" ]; then | ||
rm -rf build | ||
exit 0 | ||
fi | ||
|
||
################################################################################ | ||
# Add individual libcudf examples build scripts down below | ||
|
||
build_example() { | ||
example_dir=${1} | ||
example_dir="${EXAMPLES_DIR}/${example_dir}" | ||
build_dir="${example_dir}/build" | ||
|
||
# Configure | ||
cmake -S ${example_dir} -B ${build_dir} \ | ||
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ | ||
-DCUVS_NVTX=OFF \ | ||
-DCMAKE_CUDA_ARCHITECTURES="native" \ | ||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ | ||
${EXTRA_CMAKE_ARGS} | ||
# Build | ||
cmake --build ${build_dir} -j${PARALLEL_LEVEL} | ||
} | ||
|
||
build_example c | ||
build_example cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# ============================================================================= | ||
# Copyright (c) 2023-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. | ||
|
||
cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR) | ||
|
||
# ------------- configure rapids-cmake --------------# | ||
|
||
include(../cmake/thirdparty/fetch_rapids.cmake) | ||
include(rapids-cmake) | ||
include(rapids-cpm) | ||
include(rapids-export) | ||
include(rapids-find) | ||
|
||
# ------------- configure project --------------# | ||
|
||
project(test_cuvs_c LANGUAGES C CXX CUDA) | ||
|
||
# ------------- configure cuvs -----------------# | ||
|
||
rapids_cpm_init() | ||
set(BUILD_CUVS_C_LIBRARY ON) | ||
include(../cmake/thirdparty/get_dlpack.cmake) | ||
include(../cmake/thirdparty/get_cuvs.cmake) | ||
|
||
add_executable(CAGRA_C_EXAMPLE src/cagra_c_example.c) | ||
target_include_directories(CAGRA_C_EXAMPLE PUBLIC "$<BUILD_INTERFACE:${DLPACK_INCLUDE_DIR}>") | ||
target_link_libraries(CAGRA_C_EXAMPLE PRIVATE cuvs::c_api $<TARGET_NAME_IF_EXISTS:conda_env>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright (c) 2022-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 <cuvs/core/c_api.h> | ||
#include <cuvs/neighbors/cagra.h> | ||
|
||
#include <dlpack/dlpack.h> | ||
|
||
#include <cuda_runtime.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
float dataset[4][2] = {{0.74021935, 0.9209938}, | ||
{0.03902049, 0.9689629}, | ||
{0.92514056, 0.4463501}, | ||
{0.6673192, 0.10993068}}; | ||
float queries[4][2] = {{0.48216683, 0.0428398}, | ||
{0.5084142, 0.6545497}, | ||
{0.51260436, 0.2643005}, | ||
{0.05198065, 0.5789965}}; | ||
|
||
void cagra_build_search_simple() { | ||
|
||
int64_t n_rows = 4; | ||
int64_t n_cols = 2; | ||
int64_t topk = 2; | ||
int64_t n_queries = 4; | ||
|
||
// Create a cuvsResources_t object | ||
cuvsResources_t res; | ||
cuvsResourcesCreate(&res); | ||
|
||
// Use DLPack to represent `dataset` as a tensor | ||
DLManagedTensor dataset_tensor; | ||
dataset_tensor.dl_tensor.data = dataset; | ||
dataset_tensor.dl_tensor.device.device_type = kDLCPU; | ||
dataset_tensor.dl_tensor.ndim = 2; | ||
dataset_tensor.dl_tensor.dtype.code = kDLFloat; | ||
dataset_tensor.dl_tensor.dtype.bits = 32; | ||
dataset_tensor.dl_tensor.dtype.lanes = 1; | ||
int64_t dataset_shape[2] = {n_rows, n_cols}; | ||
dataset_tensor.dl_tensor.shape = dataset_shape; | ||
dataset_tensor.dl_tensor.strides = NULL; | ||
|
||
// Build the CAGRA index | ||
cuvsCagraIndexParams_t index_params; | ||
cuvsCagraIndexParamsCreate(&index_params); | ||
|
||
cuvsCagraIndex_t index; | ||
cuvsCagraIndexCreate(&index); | ||
|
||
cuvsCagraBuild(res, index_params, &dataset_tensor, index); | ||
|
||
// Allocate memory for `queries`, `neighbors` and `distances` output | ||
uint32_t *neighbors; | ||
float *distances, *queries_d; | ||
cuvsRMMAlloc(res, (void**) &queries_d, sizeof(float) * n_queries * n_cols); | ||
cuvsRMMAlloc(res, (void**) &neighbors, sizeof(uint32_t) * n_queries * topk); | ||
cuvsRMMAlloc(res, (void**) &distances, sizeof(float) * n_queries * topk); | ||
|
||
// Use DLPack to represent `queries`, `neighbors` and `distances` as tensors | ||
cudaMemcpy(queries_d, queries, sizeof(float) * 4 * 2, cudaMemcpyDefault); | ||
|
||
DLManagedTensor queries_tensor; | ||
queries_tensor.dl_tensor.data = queries_d; | ||
queries_tensor.dl_tensor.device.device_type = kDLCUDA; | ||
queries_tensor.dl_tensor.ndim = 2; | ||
queries_tensor.dl_tensor.dtype.code = kDLFloat; | ||
queries_tensor.dl_tensor.dtype.bits = 32; | ||
queries_tensor.dl_tensor.dtype.lanes = 1; | ||
int64_t queries_shape[2] = {n_queries, n_cols}; | ||
queries_tensor.dl_tensor.shape = queries_shape; | ||
queries_tensor.dl_tensor.strides = NULL; | ||
|
||
DLManagedTensor neighbors_tensor; | ||
neighbors_tensor.dl_tensor.data = neighbors; | ||
neighbors_tensor.dl_tensor.device.device_type = kDLCUDA; | ||
neighbors_tensor.dl_tensor.ndim = 2; | ||
neighbors_tensor.dl_tensor.dtype.code = kDLUInt; | ||
neighbors_tensor.dl_tensor.dtype.bits = 32; | ||
neighbors_tensor.dl_tensor.dtype.lanes = 1; | ||
int64_t neighbors_shape[2] = {n_queries, topk}; | ||
neighbors_tensor.dl_tensor.shape = neighbors_shape; | ||
neighbors_tensor.dl_tensor.strides = NULL; | ||
|
||
DLManagedTensor distances_tensor; | ||
distances_tensor.dl_tensor.data = distances; | ||
distances_tensor.dl_tensor.device.device_type = kDLCUDA; | ||
distances_tensor.dl_tensor.ndim = 2; | ||
distances_tensor.dl_tensor.dtype.code = kDLFloat; | ||
distances_tensor.dl_tensor.dtype.bits = 32; | ||
distances_tensor.dl_tensor.dtype.lanes = 1; | ||
int64_t distances_shape[2] = {n_queries, topk}; | ||
distances_tensor.dl_tensor.shape = distances_shape; | ||
distances_tensor.dl_tensor.strides = NULL; | ||
|
||
// Search the CAGRA index | ||
cuvsCagraSearchParams_t search_params; | ||
cuvsCagraSearchParamsCreate(&search_params); | ||
|
||
cuvsCagraSearch(res, search_params, index, &queries_tensor, &neighbors_tensor, | ||
&distances_tensor); | ||
|
||
// print results | ||
uint32_t *neighbors_h = | ||
(uint32_t *)malloc(sizeof(uint32_t) * n_queries * topk); | ||
float *distances_h = (float *)malloc(sizeof(float) * n_queries * topk); | ||
cudaMemcpy(neighbors_h, neighbors, sizeof(uint32_t) * n_queries * topk, | ||
cudaMemcpyDefault); | ||
cudaMemcpy(distances_h, distances, sizeof(float) * n_queries * topk, | ||
cudaMemcpyDefault); | ||
printf("Query 0 neighbor indices: =[%d, %d]\n", neighbors_h[0], | ||
neighbors_h[1]); | ||
printf("Query 0 neighbor distances: =[%f, %f]\n", distances_h[0], | ||
distances_h[1]); | ||
|
||
// Free or destroy all allocations | ||
free(neighbors_h); | ||
free(distances_h); | ||
|
||
cuvsCagraSearchParamsDestroy(search_params); | ||
|
||
cuvsRMMFree(res, distances, sizeof(float) * n_queries * topk); | ||
cuvsRMMFree(res, neighbors, sizeof(uint32_t) * n_queries * topk); | ||
cuvsRMMFree(res, queries_d, sizeof(float) * n_queries * n_cols); | ||
|
||
cuvsCagraIndexDestroy(index); | ||
cuvsCagraIndexParamsDestroy(index_params); | ||
cuvsResourcesDestroy(res); | ||
} | ||
|
||
int main() { | ||
// Simple build and search example. | ||
cagra_build_search_simple(); | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# ============================================================================= | ||
# 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. | ||
# ============================================================================= | ||
|
||
# This function finds dlpack and sets any additional necessary environment variables. | ||
function(find_and_configure_dlpack VERSION) | ||
|
||
include(${rapids-cmake-dir}/find/generate_module.cmake) | ||
rapids_find_generate_module(DLPACK HEADER_NAMES dlpack.h) | ||
|
||
rapids_cpm_find( | ||
dlpack ${VERSION} | ||
GIT_REPOSITORY https://github.com/dmlc/dlpack.git | ||
GIT_TAG v${VERSION} | ||
GIT_SHALLOW TRUE | ||
DOWNLOAD_ONLY TRUE | ||
OPTIONS "BUILD_MOCK OFF" | ||
) | ||
|
||
if(DEFINED dlpack_SOURCE_DIR) | ||
# otherwise find_package(DLPACK) will set this variable | ||
set(DLPACK_INCLUDE_DIR | ||
"${dlpack_SOURCE_DIR}/include" | ||
PARENT_SCOPE | ||
) | ||
endif() | ||
endfunction() | ||
|
||
set(CUVS_MIN_VERSION_dlpack 0.8) | ||
|
||
find_and_configure_dlpack(${CUVS_MIN_VERSION_dlpack}) |
Oops, something went wrong.