Skip to content

Commit

Permalink
Add end-to-end CUDA ann-benchmarks to raft (#1304)
Browse files Browse the repository at this point in the history
New `bench/ann` artifact for comparing (C++ APIs for) GPU-acclerated algorithms end-to-end. Working on this w/ @tfeher but had to squash the original commits into a single commit.

Things left to do:
- [x] Separate `benchmarks` executables for each different algorithm
- [x] Separate build targets for `ggnn` and `hnswlib`
- [x] Revise `bench/ann` docs
- [x] Break `factory.cuh` abd `benchmark.cu` / `benchmark.cpp` into individual files for each different algorithm to make it easier to plug in new algorithms. 
- [x] Separate into its own conda package

closes #1211

Authors:
  - Corey J. Nolet (https://github.com/cjnolet)

Approvers:
  - Ray Douglass (https://github.com/raydouglass)
  - Ben Frederickson (https://github.com/benfred)
  - Tamas Bela Feher (https://github.com/tfeher)

URL: #1304
  • Loading branch information
cjnolet authored Mar 28, 2023
1 parent 0d3bd3d commit 22ebc72
Show file tree
Hide file tree
Showing 103 changed files with 8,371 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ repos:
entry: ./cpp/scripts/run-cmake-format.sh cmake-format
language: python
types: [cmake]
exclude: .*/thirdparty/.*
exclude: .*/thirdparty/.*|.*FindAVX.cmake.*
# Note that pre-commit autoupdate does not update the versions
# of dependencies, so we'll have to update this manually.
additional_dependencies:
Expand Down
68 changes: 45 additions & 23 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Copyright (c) 2020-2023, NVIDIA CORPORATION.

# raft build script
# raft build scripts

# This script is used to build the component(s) in this repo from
# source, and can be called with various options to customize the
Expand All @@ -15,11 +15,11 @@ NUMARGS=$#
ARGS=$*

# NOTE: ensure all dir changes are relative to the location of this
# script, and that this script resides in the repo dir!
# scripts, and that this script resides in the repo dir!
REPODIR=$(cd $(dirname $0); pwd)

VALIDARGS="clean libraft pylibraft raft-dask docs tests bench template clean --uninstall -v -g -n --compile-lib --allgpuarch --no-nvtx --show_depr_warn -h"
HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<tool>] [--limit-tests=<targets>] [--limit-bench=<targets>]
VALIDARGS="clean libraft pylibraft raft-dask docs tests template bench-prims bench-ann clean --uninstall -v -g -n --compile-lib --allgpuarch --no-nvtx --show_depr_warn -h"
HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<tool>] [--limit-tests=<targets>] [--limit-bench-prims=<targets>] [--limit-bench-ann=<targets>]
where <target> is:
clean - remove all existing build artifacts and configuration (start over)
libraft - build the raft C++ code only. Also builds the C-wrapper library
Expand All @@ -28,7 +28,8 @@ HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<to
raft-dask - build the raft-dask Python package. this also requires pylibraft.
docs - build the documentation
tests - build the tests
bench - build the benchmarks
bench-prims - build micro-benchmarks for primitives
bench-ann - build end-to-end ann benchmarks
template - build the example RAFT application template
and <flag> is:
Expand All @@ -39,7 +40,8 @@ HELP="$0 [<target> ...] [<flag> ...] [--cmake-args=\"<args>\"] [--cache-tool=<to
--compile-lib - compile shared libraries for all components
can be useful for a pure header-only install
--limit-tests - semicolon-separated list of test executables to compile (e.g. NEIGHBORS_TEST;CLUSTER_TEST)
--limit-bench - semicolon-separated list of benchmark executables to compute (e.g. NEIGHBORS_BENCH;CLUSTER_BENCH)
--limit-bench-prims - semicolon-separated list of prims benchmark executables to compute (e.g. NEIGHBORS_PRIMS_BENCH;CLUSTER_PRIMS_BENCH)
--limit-bench-ann - semicolon-separated list of ann benchmark executables to compute (e.g. HNSWLIB_ANN_BENCH;RAFT_IVF_PQ_ANN_BENCH)
--allgpuarch - build for all supported GPU architectures
--no-nvtx - disable nvtx (profiling markers), but allow enabling it in downstream projects
--show_depr_warn - show cmake deprecation warnings
Expand All @@ -63,7 +65,8 @@ VERBOSE_FLAG=""
BUILD_ALL_GPU_ARCH=0
BUILD_TESTS=OFF
BUILD_TYPE=Release
BUILD_BENCH=OFF
BUILD_PRIMS_BENCH=OFF
BUILD_ANN_BENCH=OFF
COMPILE_LIBRARY=OFF
INSTALL_TARGET=install

Expand Down Expand Up @@ -151,15 +154,30 @@ function limitTests {

function limitBench {
# Check for option to limit the set of test binaries to build
if [[ -n $(echo $ARGS | { grep -E "\-\-limit\-bench" || true; } ) ]]; then
if [[ -n $(echo $ARGS | { grep -E "\-\-limit\-bench-prims" || true; } ) ]]; then
# There are possible weird edge cases that may cause this regex filter to output nothing and fail silently
# the true pipe will catch any weird edge cases that may happen and will cause the program to fall back
# on the invalid option error
LIMIT_BENCH_TARGETS=$(echo $ARGS | sed -e 's/.*--limit-bench=//' -e 's/ .*//')
if [[ -n ${LIMIT_BENCH_TARGETS} ]]; then
LIMIT_PRIMS_BENCH_TARGETS=$(echo $ARGS | sed -e 's/.*--limit-bench-prims=//' -e 's/ .*//')
if [[ -n ${LIMIT_PRIMS_BENCH_TARGETS} ]]; then
# Remove the full LIMIT_PRIMS_BENCH_TARGETS argument from list of args so that it passes validArgs function
ARGS=${ARGS//--limit-bench-prims=$LIMIT_PRIMS_BENCH_TARGETS/}
PRIMS_BENCH_TARGETS=${LIMIT_PRIMS_BENCH_TARGETS}
fi
fi
}

function limitAnnBench {
# Check for option to limit the set of test binaries to build
if [[ -n $(echo $ARGS | { grep -E "\-\-limit\-bench-ann" || true; } ) ]]; then
# There are possible weird edge cases that may cause this regex filter to output nothing and fail silently
# the true pipe will catch any weird edge cases that may happen and will cause the program to fall back
# on the invalid option error
LIMIT_ANN_BENCH_TARGETS=$(echo $ARGS | sed -e 's/.*--limit-bench-ann=//' -e 's/ .*//')
if [[ -n ${LIMIT_ANN_BENCH_TARGETS} ]]; then
# Remove the full LIMIT_TEST_TARGETS argument from list of args so that it passes validArgs function
ARGS=${ARGS//--limit-bench=$LIMIT_BENCH_TARGETS/}
BENCH_TARGETS=${LIMIT_BENCH_TARGETS}
ARGS=${ARGS//--limit-bench-ann=$LIMIT_ANN_BENCH_TARGETS/}
ANN_BENCH_TARGETS=${LIMIT_ANN_BENCH_TARGETS}
fi
fi
}
Expand All @@ -175,6 +193,7 @@ if (( ${NUMARGS} != 0 )); then
cacheTool
limitTests
limitBench
limitAnnBench
for a in ${ARGS}; do
if ! (echo " ${VALIDARGS} " | grep -q " ${a} "); then
echo "Invalid option: ${a}"
Expand Down Expand Up @@ -281,18 +300,23 @@ if hasArg tests || (( ${NUMARGS} == 0 )); then
fi
fi

if hasArg bench || (( ${NUMARGS} == 0 )); then
BUILD_BENCH=ON
CMAKE_TARGET="${CMAKE_TARGET};${BENCH_TARGETS}"
if hasArg bench-prims || (( ${NUMARGS} == 0 )); then
BUILD_PRIMS_BENCH=ON
CMAKE_TARGET="${CMAKE_TARGET};${PRIMS_BENCH_TARGETS}"

# Force compile library when needed benchmark targets are specified
if [[ $CMAKE_TARGET == *"CLUSTER_BENCH"* || \
$CMAKE_TARGET == *"MATRIX_BENCH"* || \
$CMAKE_TARGET == *"NEIGHBORS_BENCH"* ]]; then
if [[ $CMAKE_TARGET == *"CLUSTER_PRIMS_BENCH"* || \
$CMAKE_TARGET == *"MATRIX_PRIMS_BENCH"* || \
$CMAKE_TARGET == *"NEIGHBORS_PRIMS_BENCH"* ]]; then
echo "-- Enabling compiled lib for benchmarks"
COMPILE_LIBRARY=ON
fi
fi

if hasArg bench-ann || (( ${NUMARGS} == 0 )); then
BUILD_ANN_BENCH=ON
CMAKE_TARGET="${CMAKE_TARGET};${ANN_BENCH_TARGETS}"
COMPILE_LIBRARY=ON
fi

if hasArg --no-nvtx; then
Expand All @@ -305,8 +329,6 @@ if hasArg clean; then
CLEAN=1
fi



if [[ ${CMAKE_TARGET} == "" ]]; then
CMAKE_TARGET="all"
fi
Expand Down Expand Up @@ -340,7 +362,7 @@ fi

################################################################################
# Configure for building all C++ targets
if (( ${NUMARGS} == 0 )) || hasArg libraft || hasArg docs || hasArg tests || hasArg bench; then
if (( ${NUMARGS} == 0 )) || hasArg libraft || hasArg docs || hasArg tests || hasArg bench-prims || hasArg bench-ann; then
if (( ${BUILD_ALL_GPU_ARCH} == 0 )); then
RAFT_CMAKE_CUDA_ARCHITECTURES="NATIVE"
echo "Building for the architecture of the GPU in the system..."
Expand All @@ -359,7 +381,8 @@ if (( ${NUMARGS} == 0 )) || hasArg libraft || hasArg docs || hasArg tests || has
-DRAFT_NVTX=${NVTX} \
-DDISABLE_DEPRECATION_WARNINGS=${DISABLE_DEPRECATION_WARNINGS} \
-DBUILD_TESTS=${BUILD_TESTS} \
-DBUILD_BENCH=${BUILD_BENCH} \
-DBUILD_PRIMS_BENCH=${BUILD_PRIMS_BENCH} \
-DBUILD_ANN_BENCH=${BUILD_ANN_BENCH} \
-DCMAKE_MESSAGE_LOG_LEVEL=${CMAKE_LOG_LEVEL} \
${CACHE_ARGS} \
${EXTRA_CMAKE_ARGS}
Expand All @@ -380,7 +403,6 @@ if (( ${NUMARGS} == 0 )) || hasArg pylibraft; then
if [[ "${EXTRA_CMAKE_ARGS}" != *"DFIND_RAFT_CPP"* ]]; then
EXTRA_CMAKE_ARGS="${EXTRA_CMAKE_ARGS} -DFIND_RAFT_CPP=ON"
fi

cd ${REPODIR}/python/pylibraft
python setup.py build_ext --inplace -- -DCMAKE_PREFIX_PATH="${RAFT_DASK_BUILD_DIR};${INSTALL_PREFIX}" -DCMAKE_LIBRARY_PATH=${LIBRAFT_BUILD_DIR} ${EXTRA_CMAKE_ARGS} -- -j${PARALLEL_LEVEL:-1}
if [[ ${INSTALL_TARGET} != "" ]]; then
Expand Down
3 changes: 2 additions & 1 deletion ci/checks/copyright.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ def checkCopyright_main():
action="append",
required=False,
default=["python/cuml/_thirdparty/",
"cpp/include/raft/thirdparty/"],
"cpp/include/raft/thirdparty/",
"cpp/cmake/modules/FindAVX.cmake"],
help=("Exclude the paths specified (regexp). "
"Can be specified multiple times."))

Expand Down
37 changes: 37 additions & 0 deletions conda/environments/bench_ann_cuda-118_arch-x86_64.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This file is generated by `rapids-dependency-file-generator`.
# To make changes, edit ../../dependencies.yaml and run `rapids-dependency-file-generator`.
channels:
- rapidsai
- rapidsai-nightly
- dask/label/dev
- conda-forge
- nvidia
dependencies:
- c-compiler
- clang-tools=11.1.0
- clang=11.1.0
- cmake>=3.23.1,!=3.25.0
- cuda-profiler-api=11.8.86
- cudatoolkit=11.8
- cxx-compiler
- cython>=0.29,<0.30
- faiss-proc=*=cuda
- gcc_linux-64=11.*
- glog>=0.6.0
- h5py>=3.8.0
- hnswlib=0.7.0
- libcublas-dev=11.11.3.6
- libcublas=11.11.3.6
- libcurand-dev=10.3.0.86
- libcurand=10.3.0.86
- libcusolver-dev=11.4.1.48
- libcusolver=11.4.1.48
- libcusparse-dev=11.7.5.86
- libcusparse=11.7.5.86
- libfaiss>=1.7.1
- nccl>=2.9.9
- ninja
- nlohmann_json>=3.11.2
- scikit-build>=0.13.1
- sysroot_linux-64==2.17
name: bench_ann_cuda-118_arch-x86_64
5 changes: 5 additions & 0 deletions conda/recipes/libraft/build_libraft_nn_bench.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Copyright (c) 2023, NVIDIA CORPORATION.

./build.sh tests bench-ann --allgpuarch --no-nvtx
cmake --install cpp/build --component ann_bench
2 changes: 1 addition & 1 deletion conda/recipes/libraft/build_libraft_tests.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Copyright (c) 2022-2023, NVIDIA CORPORATION.

./build.sh tests bench --allgpuarch --no-nvtx
./build.sh tests bench-prims --allgpuarch --no-nvtx
cmake --install cpp/build --component testing
12 changes: 12 additions & 0 deletions conda/recipes/libraft/conda_build_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ nccl_version:
gtest_version:
- "=1.10.0"

glog_version:
- ">=0.6.0"

faiss_version:
- ">=1.7.1"

h5py_version:
- ">=3.8.0"

nlohmann_json_version:
- ">=3.11.2"

# The CTK libraries below are missing from the conda-forge::cudatoolkit
# package. The "*_host_*" version specifiers correspond to `11.8` packages and the
# "*_run_*" version specifiers correspond to `11.x` packages.
Expand Down
44 changes: 44 additions & 0 deletions conda/recipes/libraft/meta.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,47 @@ outputs:
home: https://rapids.ai/
license: Apache-2.0
summary: libraft template
- name: libraft-ann-bench
version: {{ version }}
script: build_libraft_nn_bench.sh
build:
script_env: *script_env
number: {{ GIT_DESCRIBE_NUMBER }}
string: cuda{{ cuda_major }}_{{ date_string }}_{{ GIT_DESCRIBE_HASH }}_{{ GIT_DESCRIBE_NUMBER }}
ignore_run_exports_from:
- {{ compiler('cuda') }}
requirements:
build:
- {{ compiler('c') }}
- {{ compiler('cuda') }} {{ cuda_version }}
- {{ compiler('cxx') }}
- cmake {{ cmake_version }}
- ninja
- sysroot_{{ target_platform }} {{ sysroot_version }}
host:
- {{ pin_subpackage('libraft', exact=True) }}
- {{ pin_subpackage('libraft-headers', exact=True) }}
- cuda-profiler-api {{ cuda_profiler_api_host_version }}
- libcublas {{ libcublas_host_version }}
- libcublas-dev {{ libcublas_host_version }}
- libcurand {{ libcurand_host_version }}
- libcurand-dev {{ libcurand_host_version }}
- libcusolver {{ libcusolver_host_version }}
- libcusolver-dev {{ libcusolver_host_version }}
- libcusparse {{ libcusparse_host_version }}
- libcusparse-dev {{ libcusparse_host_version }}
- glog {{ glog_version }}
- nlohmann_json {{ nlohmann_json_version }}
- libfaiss>=1.7.1
- faiss-proc=*=cuda
run:
- {{ pin_subpackage('libraft', exact=True) }}
- {{ pin_subpackage('libraft-headers', exact=True) }}
- glog {{ glog_version }}
- faiss-proc=*=cuda
- libfaiss {{ faiss_version }}
- h5py {{ h5py_version }}
about:
home: https://rapids.ai/
license: Apache-2.0
summary: libraft ann bench
30 changes: 22 additions & 8 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

option(BUILD_SHARED_LIBS "Build raft shared libraries" ON)
option(BUILD_TESTS "Build raft unit-tests" ON)
option(BUILD_BENCH "Build raft C++ benchmark tests" OFF)
option(BUILD_PRIMS_BENCH "Build raft C++ benchmark tests" OFF)
option(BUILD_ANN_BENCH "Build raft ann benchmarks" OFF)
option(CUDA_ENABLE_KERNELINFO "Enable kernel resource usage info" OFF)
option(CUDA_ENABLE_LINEINFO
"Enable the -lineinfo option for nvcc (useful for cuda-memcheck / profiler)" OFF
Expand All @@ -58,14 +59,20 @@ option(DISABLE_OPENMP "Disable OpenMP" OFF)
option(RAFT_NVTX "Enable nvtx markers" OFF)

set(RAFT_COMPILE_LIBRARY_DEFAULT OFF)
if(BUILD_TESTS OR BUILD_BENCH)
if(BUILD_TESTS
OR BUILD_PRIMS_BENCH
OR BUILD_ANN_BENCH
)
set(RAFT_COMPILE_LIBRARY_DEFAULT ON)
endif()
option(RAFT_COMPILE_LIBRARY "Enable building raft shared library instantiations"
${RAFT_COMPILE_LIBRARY_DEFAULT}
)

if(BUILD_TESTS OR BUILD_BENCH)
if(BUILD_TESTS
OR BUILD_PRIMS_BENCH
OR BUILD_ANN_BENCH
)
# Needed because GoogleBenchmark changes the state of FindThreads.cmake, causing subsequent runs
# to have different values for the `Threads::Threads` target. Setting this flag ensures
# `Threads::Threads` is the same value in first run and subsequent runs.
Expand All @@ -78,7 +85,7 @@ include(CMakeDependentOption)

message(VERBOSE "RAFT: Building optional components: ${raft_FIND_COMPONENTS}")
message(VERBOSE "RAFT: Build RAFT unit-tests: ${BUILD_TESTS}")
message(VERBOSE "RAFT: Building raft C++ benchmarks: ${BUILD_BENCH}")
message(VERBOSE "RAFT: Building raft C++ benchmarks: ${BUILD_PRIMS_BENCH}")
message(VERBOSE "RAFT: Enable detection of conda environment for dependencies: ${DETECT_CONDA_ENV}")
message(VERBOSE "RAFT: Disable depreaction warnings " ${DISABLE_DEPRECATION_WARNINGS})
message(VERBOSE "RAFT: Disable OpenMP: ${DISABLE_OPENMP}")
Expand Down Expand Up @@ -159,7 +166,7 @@ if(BUILD_TESTS)
include(cmake/thirdparty/get_gtest.cmake)
endif()

if(BUILD_BENCH)
if(BUILD_PRIMS_BENCH)
include(${rapids-cmake-dir}/cpm/gbench.cmake)
rapids_cpm_gbench()
endif()
Expand Down Expand Up @@ -647,7 +654,7 @@ raft_export(
# ##################################################################################################
# * shared test/bench headers ------------------------------------------------

if(BUILD_TESTS OR BUILD_BENCH)
if(BUILD_TESTS OR BUILD_PRIMS_BENCH)
include(internal/CMakeLists.txt)
endif()

Expand All @@ -661,6 +668,13 @@ endif()
# ##################################################################################################
# * build benchmark executable -----------------------------------------------

if(BUILD_BENCH)
include(bench/CMakeLists.txt)
if(BUILD_PRIMS_BENCH)
include(bench/prims/CMakeLists.txt)
endif()

# ##################################################################################################
# * build ann benchmark executable -----------------------------------------------

if(BUILD_ANN_BENCH)
include(bench/ann/CMakeLists.txt)
endif()
Loading

0 comments on commit 22ebc72

Please sign in to comment.