From 99b6dd354bb422c99c779fa378c6d424fa49a716 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Sat, 22 Jan 2022 22:37:34 -0500 Subject: [PATCH] Simplify raft component CMake logic, and allow compilation without FAISS (#428) The previous logic didn't allow for developers to build raft without FAISS as `raft_nn` was always required to be built. Authors: - Robert Maynard (https://github.com/robertmaynard) - Paul Taylor (https://github.com/trxcllnt) - Corey J. Nolet (https://github.com/cjnolet) - Ashwin Srinath (https://github.com/shwina) Approvers: - Corey J. Nolet (https://github.com/cjnolet) - Dante Gama Dessavre (https://github.com/dantegd) - AJ Schmidt (https://github.com/ajschmidt8) URL: https://github.com/rapidsai/raft/pull/428 --- build.sh | 6 +- cpp/CMakeLists.txt | 240 ++++++++++++++++++++------- cpp/cmake/modules/config.cmake.in | 120 ++++++++++++++ cpp/cmake/modules/raft_export.cmake | 238 ++++++++++++++++++++++++++ cpp/cmake/thirdparty/get_cuco.cmake | 3 +- cpp/cmake/thirdparty/get_faiss.cmake | 70 +++++--- cpp/cmake/thirdparty/get_gtest.cmake | 14 +- cpp/cmake/versions.json | 9 + cpp/test/CMakeLists.txt | 9 +- cpp/test/distance/distance_base.cuh | 2 + cpp/test/sparse/knn_graph.cu | 2 + cpp/test/spatial/ball_cover.cu | 4 +- cpp/test/spatial/knn.cu | 2 + cpp/test/spatial/selection.cu | 2 + 14 files changed, 624 insertions(+), 97 deletions(-) create mode 100644 cpp/cmake/modules/config.cmake.in create mode 100644 cpp/cmake/modules/raft_export.cmake create mode 100644 cpp/cmake/versions.json diff --git a/build.sh b/build.sh index 5b9a1c4ba0..94d0b5e812 100755 --- a/build.sh +++ b/build.sh @@ -44,6 +44,7 @@ PYTHON_DEPS_CLONE=${REPODIR}/python/external_repositories BUILD_DIRS="${CPP_RAFT_BUILD_DIR} ${PY_RAFT_BUILD_DIR} ${PYTHON_DEPS_CLONE}" # Set defaults for vars modified by flags to this script +CMAKE_LOG_LEVEL="" VERBOSE_FLAG="" BUILD_ALL_GPU_ARCH=0 BUILD_GTEST=OFF @@ -85,6 +86,7 @@ fi # Process flags if hasArg -v; then VERBOSE_FLAG=-v + CMAKE_LOG_LEVEL="--log-level=VERBOSE" set -x fi if hasArg -g; then @@ -144,13 +146,13 @@ if (( ${NUMARGS} == 0 )) || hasArg cppraft || hasArg docs; then echo "Building for *ALL* supported GPU architectures..." fi - cmake -S ${REPODIR}/cpp -B ${CPP_RAFT_BUILD_DIR} \ + cmake -S ${REPODIR}/cpp -B ${CPP_RAFT_BUILD_DIR} ${CMAKE_LOG_LEVEL} \ -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ -DCMAKE_CUDA_ARCHITECTURES=${RAFT_CMAKE_CUDA_ARCHITECTURES} \ -DNVTX=${NVTX} \ -DDISABLE_DEPRECATION_WARNING=${BUILD_DISABLE_DEPRECATION_WARNING} \ -DBUILD_GTEST=${BUILD_GTEST} \ - -DBUILD_STATIC_FAISS=${BUILD_STATIC_FAISS} + -DRAFT_USE_FAISS_STATIC=${BUILD_STATIC_FAISS} if hasArg cppraft; then # Run all c++ targets at once diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 9387589f73..f3a0f2d554 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -49,6 +49,11 @@ option(DISABLE_DEPRECATION_WARNINGS "Disable depreaction warnings " ON) option(DISABLE_OPENMP "Disable OpenMP" OFF) option(NVTX "Enable nvtx markers" OFF) +option(RAFT_COMPILE_LIBRARIES "Enable building raft shared library instantiations" ON) +option(RAFT_ENABLE_NN_DEPENDENCIES "Search for raft::nn dependencies like faiss" ${RAFT_COMPILE_LIBRARIES}) +include(CMakeDependentOption) +cmake_dependent_option(RAFT_USE_FAISS_STATIC "Build and statically link the FAISS library for nearest neighbors search on GPU" ON RAFT_COMPILE_LIBRARIES OFF) + message(VERBOSE "RAFT: Build RAFT unit-tests: ${BUILD_TESTS}") message(VERBOSE "RAFT: Enable detection of conda environment for dependencies: ${DETECT_CONDA_ENV}") message(VERBOSE "RAFT: Disable depreaction warnings " ${DISABLE_DEPRECATION_WARNINGS}) @@ -100,96 +105,143 @@ endif() # add third party dependencies using CPM rapids_cpm_init() -# thrust and libcudacxx need to be before cuco! +# thrust before rmm/cuco so we get the right version of thrust/cub include(cmake/thirdparty/get_thrust.cmake) include(cmake/thirdparty/get_rmm.cmake) -include(cmake/thirdparty/get_libcudacxx.cmake) include(cmake/thirdparty/get_cuco.cmake) +include(cmake/thirdparty/get_libcudacxx.cmake) +include(cmake/thirdparty/get_faiss.cmake) if(BUILD_TESTS) - include(cmake/thirdparty/get_faiss.cmake) include(cmake/thirdparty/get_gtest.cmake) include(cmake/thirdparty/get_nccl.cmake) include(cmake/thirdparty/get_ucx.cmake) endif() ############################################################################## -# - install targets----------------------------------------------------------- -rapids_cmake_install_lib_dir( lib_dir ) - -include(CPack) - -file(GLOB_RECURSE RAFT_DISTANCE_SOURCES "src/distance/specializations/*.cu") -file(GLOB_RECURSE RAFT_NN_SOURCES "src/nn/specializations/*.cu" ) - -add_library(raft_distance SHARED ${RAFT_DISTANCE_SOURCES}) -add_library(raft::raft_distance ALIAS raft_distance) - -add_library(raft_nn SHARED ${RAFT_NN_SOURCES}) -add_library(raft::raft_nn ALIAS raft_nn) +# - raft --------------------------------------------------------------------- add_library(raft INTERFACE) add_library(raft::raft ALIAS raft) -target_include_directories(raft INTERFACE "$" - "$") -target_include_directories(raft_distance PUBLIC "$" +target_include_directories(raft INTERFACE + "$" "$") -target_include_directories(raft_nn PUBLIC "$" - "$") +target_link_libraries(raft INTERFACE + raft::Thrust + CUDA::cublas + CUDA::curand + CUDA::cusolver + CUDA::cudart + CUDA::cusparse + $<$:CUDA::nvToolsExt> + rmm::rmm + cuco::cuco) + +target_compile_definitions(raft INTERFACE $<$:NVTX_ENABLED>) +target_compile_features(raft INTERFACE cxx_std_17 $) -set(RAFT_LINK_LIBRARIES - CUDA::cublas - CUDA::curand - CUDA::cusolver - CUDA::cudart - CUDA::cusparse - $<$:CUDA::nvToolsExt> - rmm::rmm - cuco::cuco - ) +############################################################################## +# - raft_distance ------------------------------------------------------------ +add_library(raft_distance INTERFACE) -target_link_libraries(raft INTERFACE ${RAFT_LINK_LIBRARIES}) -target_link_libraries(raft_distance PUBLIC ${RAFT_LINK_LIBRARIES}) -target_link_libraries(raft_nn PUBLIC ${RAFT_LINK_LIBRARIES} FAISS::FAISS) +if(TARGET raft_distance AND (NOT TARGET raft::distance)) + add_library(raft::distance ALIAS raft_distance) +endif() -set(RAFT_COMPILE_DEFINITIONS - $<$:NVTX_ENABLED> - ) +set_target_properties(raft_distance PROPERTIES EXPORT_NAME distance) + +if(RAFT_COMPILE_LIBRARIES) + add_library(raft_distance_lib SHARED + src/distance/specializations/detail + src/distance/specializations/detail/canberra.cu + src/distance/specializations/detail/chebyshev.cu + src/distance/specializations/detail/correlation.cu + src/distance/specializations/detail/cosine.cu + src/distance/specializations/detail/hamming_unexpanded.cu + src/distance/specializations/detail/hellinger_expanded.cu + src/distance/specializations/detail/jensen_shannon.cu + src/distance/specializations/detail/kl_divergence.cu + src/distance/specializations/detail/l1.cu + src/distance/specializations/detail/l2_expanded.cu + src/distance/specializations/detail/l2_sqrt_expanded.cu + src/distance/specializations/detail/l2_sqrt_unexpanded.cu + src/distance/specializations/detail/l2_unexpanded.cu + src/distance/specializations/detail/lp_unexpanded.cu + ) + set_target_properties(raft_distance_lib PROPERTIES OUTPUT_NAME raft_distance) + + target_link_libraries(raft_distance_lib PRIVATE raft::raft) + target_compile_options(raft_distance_lib + PRIVATE "$<$:${RAFT_CXX_FLAGS}>" + "$<$:${RAFT_CUDA_FLAGS}>" + ) + target_compile_definitions(raft_distance_lib + INTERFACE "RAFT_DISTANCE_COMPILED") + + install(TARGETS raft_distance_lib + DESTINATION ${lib_dir} + EXPORT raft-distance-exports) +endif() -target_compile_definitions(raft INTERFACE ${RAFT_COMPILE_DEFINITIONS}) -target_compile_definitions(raft_distance PRIVATE ${RAFT_COMPILE_DEFINITIONS}) -target_compile_definitions(raft_nn PRIVATE ${RAFT_COMPILE_DEFINITIONS}) +target_link_libraries(raft_distance INTERFACE raft::raft + $ + $) -target_compile_options(raft_distance - PRIVATE "$<$:${RAFT_CXX_FLAGS}>" - "$<$:${RAFT_CUDA_FLAGS}>" - ) +############################################################################## +# - raft_nn ------------------------------------------------------------------ +add_library(raft_nn INTERFACE) +if(TARGET raft_nn AND (NOT TARGET raft::nn)) + add_library(raft::nn ALIAS raft_nn) +endif() -target_compile_options(raft_nn - PRIVATE "$<$:${RAFT_CXX_FLAGS}>" - "$<$:${RAFT_CUDA_FLAGS}>" - ) +set_target_properties(raft_nn PROPERTIES EXPORT_NAME nn) + +if(RAFT_COMPILE_LIBRARIES) + add_library(raft_nn_lib SHARED + src/nn/specializations/ball_cover.cu + src/nn/specializations/detail/ball_cover_lowdim.cu + src/nn/specializations/fused_l2_knn.cu + src/nn/specializations/knn.cu + ) + set_target_properties(raft_nn_lib PROPERTIES OUTPUT_NAME raft_nn) + + target_link_libraries(raft_nn_lib PRIVATE raft::raft faiss::faiss) + target_compile_options(raft_nn_lib + PRIVATE "$<$:${RAFT_CXX_FLAGS}>" + "$<$:${RAFT_CUDA_FLAGS}>" + ) + target_compile_definitions(raft_nn_lib + INTERFACE "RAFT_NN_COMPILED") + + install(TARGETS raft_nn_lib + DESTINATION ${lib_dir} + EXPORT raft-nn-exports) +endif() -target_compile_features(raft_distance PUBLIC cxx_std_17 $) -target_compile_features(raft_nn PUBLIC cxx_std_17 $) -target_compile_features(raft INTERFACE cxx_std_17 $) +target_link_libraries(raft_nn INTERFACE raft::raft faiss::faiss + $ + $) -install(TARGETS raft_distance +############################################################################## +# - install targets----------------------------------------------------------- +rapids_cmake_install_lib_dir( lib_dir ) +include(GNUInstallDirs) +include(CPack) + +install(TARGETS raft DESTINATION ${lib_dir} EXPORT raft-exports) - +install(TARGETS raft_distance + DESTINATION ${lib_dir} + EXPORT raft-distance-exports) install(TARGETS raft_nn DESTINATION ${lib_dir} - EXPORT raft-exports) + EXPORT raft-nn-exports) -install(TARGETS raft - DESTINATION ${lib_dir} - EXPORT raft-exports) -include(GNUInstallDirs) install(DIRECTORY include/raft/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/raft ) @@ -207,26 +259,88 @@ Provide targets for the RAFT: RAPIDS Analytics Framework Toolkit. RAPIDS Analytics Framework Toolkit contains shared representations, mathematical computational primitives, and utilities that accelerate building analytics and data science algorithms in the RAPIDS ecosystem. + +Optional Components: + - nn + - distance + +Imported Targets: + - raft::raft + - raft::nn brought in by the `nn` optional component + - raft::distance brought in by the `distance` optional component + ]=]) - rapids_export(INSTALL raft +set(code_string +[=[ +thrust_create_target(raft::Thrust FROM_OPTIONS) + +if(distance IN_LIST raft_FIND_COMPONENTS) + enable_language(CUDA) +endif() + +if(nn IN_LIST raft_FIND_COMPONENTS) + enable_language(CUDA) + + if(TARGET faiss AND (NOT TARGET faiss::faiss)) + add_library(faiss::faiss ALIAS faiss) + elseif(TARGET faiss::faiss AND (NOT TARGET faiss)) + add_library(faiss ALIAS faiss::faiss) + endif() +endif() +]=] +) + +# Use `rapids_export` for 22.04 as it will have COMPONENT support +include(cmake/modules/raft_export.cmake) +raft_export(INSTALL raft EXPORT_SET raft-exports - GLOBAL_TARGETS raft raft_distance# since we can't hook into EXPORT SETS + COMPONENTS nn distance + GLOBAL_TARGETS raft nn distance NAMESPACE raft:: DOCUMENTATION doc_string + FINAL_CODE_BLOCK code_string ) ############################################################################## # - build export ------------------------------------------------------------- -rapids_export(BUILD raft +raft_export(BUILD raft EXPORT_SET raft-exports - GLOBAL_TARGETS raft raft_distance raft_nn# since we can't hook into EXPORT SETS - LANGUAGES CUDA + COMPONENTS nn distance + GLOBAL_TARGETS raft raft_distance raft_nn DOCUMENTATION doc_string NAMESPACE raft:: + FINAL_CODE_BLOCK code_string ) +############################################################################## +# - export/install optional components -------------------------------------- + +include("${rapids-cmake-dir}/export/write_dependencies.cmake") + +set(raft_components distance nn) +foreach(comp IN LISTS raft_components) + install( + EXPORT raft-${comp}-exports + FILE raft-${comp}-targets.cmake + NAMESPACE raft:: + DESTINATION "${lib_dir}/cmake/raft" + ) + export( + EXPORT raft-${comp}-exports + FILE ${RAFT_BINARY_DIR}/raft-${comp}-targets.cmake + NAMESPACE raft:: + ) + rapids_export_write_dependencies( + BUILD raft-${comp}-exports "${PROJECT_BINARY_DIR}/raft-${comp}-dependencies.cmake" + ) + rapids_export_write_dependencies( + INSTALL raft-${comp}-exports "${PROJECT_BINARY_DIR}/rapids-cmake/raft/export/raft-${comp}-dependencies.cmake" + ) + +endforeach() + ############################################################################## # - build test executable ---------------------------------------------------- diff --git a/cpp/cmake/modules/config.cmake.in b/cpp/cmake/modules/config.cmake.in new file mode 100644 index 0000000000..bfafe3555a --- /dev/null +++ b/cpp/cmake/modules/config.cmake.in @@ -0,0 +1,120 @@ +#============================================================================= +# Copyright (c) 2021, 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. +#============================================================================= + +#[=======================================================================[ + +@RAPIDS_PROJECT_DOCUMENTATION@ + +Result Variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables:: + + @project_name_uppercase@_FOUND + @project_name_uppercase@_VERSION + @project_name_uppercase@_VERSION_MAJOR + @project_name_uppercase@_VERSION_MINOR + +#]=======================================================================] + +@PACKAGE_INIT@ + +cmake_minimum_required(VERSION @CMAKE_MINIMUM_REQUIRED_VERSION@) + +set(rapids_global_languages @RAPIDS_LANGUAGES@) +foreach(lang IN LISTS rapids_global_languages) + include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-${lang}-language.cmake") +endforeach() +unset(rapids_global_languages) + +set(rapids_allowed_components @RAPIDS_COMPONENTS@) + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@project_name@-dependencies.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-dependencies.cmake") +endif() +foreach(comp IN LISTS rapids_allowed_components) + # find dependencies before creating targets that use them + # this way if a dependency can't be found we fail + if(${comp} IN_LIST @project_name@_FIND_COMPONENTS) + include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-${comp}-dependencies.cmake" OPTIONAL) + endif() +endforeach() + +include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-targets.cmake" OPTIONAL) + +foreach(comp IN LISTS rapids_allowed_components) + if(${comp} IN_LIST @project_name@_FIND_COMPONENTS) + include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-${comp}-targets.cmake" OPTIONAL) + set(@project_name@_${comp}_FOUND TRUE) + endif() +endforeach() + +unset(rapids_allowed_components) + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@project_name@-config-version.cmake") + include("${CMAKE_CURRENT_LIST_DIR}/@project_name@-config-version.cmake") +endif() + +# Set our version variables +set(@project_name_uppercase@_VERSION_MAJOR @rapids_orig_major_version@) +set(@project_name_uppercase@_VERSION_MINOR @rapids_orig_minor_version@) +set(@project_name_uppercase@_VERSION_PATCH @rapids_orig_patch_version@) +set(@project_name_uppercase@_VERSION @rapids_orig_version@) + + +set(rapids_global_targets @RAPIDS_GLOBAL_TARGETS@) +set(rapids_namespaced_global_targets @RAPIDS_GLOBAL_TARGETS@) +if(rapids_namespaced_global_targets) + list(TRANSFORM rapids_namespaced_global_targets PREPEND @RAPIDS_NAMESPACE@ ) +endif() + +foreach(target IN LISTS rapids_namespaced_global_targets) + if(TARGET ${target}) + get_target_property(_is_imported ${target} IMPORTED) + get_target_property(_already_global ${target} IMPORTED_GLOBAL) + if(_is_imported AND NOT _already_global) + set_target_properties(${target} PROPERTIES IMPORTED_GLOBAL TRUE) + endif() + endif() +endforeach() + +# For backwards compat +if("rapids_config_@type@" STREQUAL "rapids_config_build") + foreach(target IN LISTS rapids_global_targets) + if(TARGET ${target}) + get_target_property(_is_imported ${target} IMPORTED) + get_target_property(_already_global ${target} IMPORTED_GLOBAL) + if(_is_imported AND NOT _already_global) + set_target_properties(${target} PROPERTIES IMPORTED_GLOBAL TRUE) + endif() + if(NOT TARGET @RAPIDS_NAMESPACE@${target}) + add_library(@RAPIDS_NAMESPACE@${target} ALIAS ${target}) + endif() + endif() + endforeach() +endif() + +unset(rapids_global_targets) +unset(rapids_namespaced_global_targets) + +check_required_components(@project_name@) + +set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG "${CMAKE_CURRENT_LIST_FILE}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(${CMAKE_FIND_PACKAGE_NAME} CONFIG_MODE HANDLE_COMPONENTS) + +@RAPIDS_PROJECT_FINAL_CODE_BLOCK@ diff --git a/cpp/cmake/modules/raft_export.cmake b/cpp/cmake/modules/raft_export.cmake new file mode 100644 index 0000000000..4411433336 --- /dev/null +++ b/cpp/cmake/modules/raft_export.cmake @@ -0,0 +1,238 @@ +#============================================================================= +# Copyright (c) 2021, 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_guard(GLOBAL) + +#[=======================================================================[.rst: +raft_export +--------------------- + +Generate a projects -Config.cmake module and all related information + +.. code-block:: cmake + + raft_export( (BUILD|INSTALL) + EXPORT_SET + [ COMPONENTS ] + [ GLOBAL_TARGETS ] + [ VERSION ] + [ NAMESPACE ] + [ DOCUMENTATION ] + [ FINAL_CODE_BLOCK ] + [ LANGUAGES ] + ) + +The :cmake:command:`raft_export` function allow projects to easily generate a fully +correct build and install tree `Project-Config.cmake` module including any necessary +calls to :cmake:command:`find_dependency`, or :cmake:command:`CPMFindPackage`. + +.. note:: + :cmake:command:`raft_export` always installs to `lib` and doesn't use GNUInstallDirs + + The files generated by :cmake:command:`raft_export` are completly standalone + and don't require the consuming package to use `rapids-cmake` + +``project_name`` + Name of the project, to be used by consumers when using `find_package` + +``GLOBAL_TARGETS`` + Explicitly list what targets should be made globally visibile to + the consuming project. + +``VERSION`` + Explicitly list the version of the package being exported. By + default :cmake:command:`raft_export` uses the version specified by the + root level :cmake:command:`project` call. If no version has been specified + either way or `OFF` is provided as the `VERSION` value, no version compatibility + checks will be generated. + + Depending on the version string different compatibility modes will be used. + + +------------------+---------------------+ + | Version String | Compatiblity Type | + +==================+=====================+ + | None | No checks perfomed | + +------------------+---------------------+ + | X | SameMajorVersion | + +------------------+---------------------+ + | X.Y | SameMinorVersion | + +------------------+---------------------+ + | X.Y.Z | SameMinorVersion | + +------------------+---------------------+ + +.. note:: + It can be useful to explicitly specify a version string when generating + export rules for a sub-component of alarger project, or an external + project that doesn't have export rules. + +``NAMESPACE`` + Optional value to specify what namespace all targets from the + EXPORT_SET will be placed into. When provided must match the pattern + of `::`. + If not provided all targets will be placed in the `::` + namespace + + Note: When exporting with `BUILD` type, only `GLOBAL_TARGETS` will + be placed in the namespace. + +``DOCUMENTATION`` + Optional value of the variable that holds the documentation + for this config file. + + Note: This requires the documentation variable instead of the contents + so we can handle having CMake code inside the documentation + +``FINAL_CODE_BLOCK`` + Optional value of the variable that holds a string of code that will + be executed at the last step of this config file. + + Note: This requires the code block variable instead of the contents + so that we can properly insert CMake code + +``LANGUAGES`` + Non default languages, such as CUDA that are required by consumers + of your package. This makes sure all consumers properly setup these + languages correctly. + + This is required as CMake's :cmake:command:`enable_language` only supports + enabling languages for the current directory scope, and doesn't support + being called from within functions. Marking languages here overcomes + these limitations and makes it possible for packages included via + `CPM` to enable languages. + + +#]=======================================================================] +# cmake-lint: disable=R0912,R0915,W0105 +function(raft_export type project_name) + include(CMakePackageConfigHelpers) + + list(APPEND CMAKE_MESSAGE_CONTEXT "raft.export") + string(TOLOWER ${type} type) + + set(options "") + set(one_value EXPORT_SET VERSION NAMESPACE DOCUMENTATION FINAL_CODE_BLOCK) + set(multi_value COMPONENTS GLOBAL_TARGETS LANGUAGES) + cmake_parse_arguments(RAPIDS "${options}" "${one_value}" "${multi_value}" ${ARGN}) + + set(rapids_version_set ON) + if(DEFINED RAPIDS_VERSION AND NOT RAPIDS_VERSION) + # We need to capture `VERSION OFF` so we need to make sure it has an off value, and not just + # undefined + set(rapids_version_set OFF) + unset(RAPIDS_VERSION) # unset this so we don't export a version value of `OFF` + elseif(NOT DEFINED RAPIDS_VERSION AND NOT DEFINED PROJECT_VERSION) + set(rapids_version_set OFF) + elseif(DEFINED PROJECT_VERSION AND NOT DEFINED RAPIDS_VERSION) + # Choose the project version when an explicit version isn't provided + set(RAPIDS_VERSION "${PROJECT_VERSION}") + endif() + + if(rapids_version_set) + include("${rapids-cmake-dir}/export/detail/parse_version.cmake") + rapids_export_parse_version(${RAPIDS_VERSION} rapids_orig rapids_project_version) + endif() + + set(RAPIDS_PROJECT_VERSION "${project_name}::") + if(DEFINED RAPIDS_NAMESPACE) + set(RAPIDS_PROJECT_VERSION ${RAPIDS_NAMESPACE}) + endif() + + set(RAPIDS_PROJECT_DOCUMENTATION "Generated ${project_name}-config module") + if(DEFINED RAPIDS_DOCUMENTATION) + if(NOT DEFINED ${RAPIDS_DOCUMENTATION}) + message(FATAL_ERROR "DOCUMENTATION variable `${RAPIDS_DOCUMENTATION}` doesn't exist") + endif() + set(RAPIDS_PROJECT_DOCUMENTATION "${${RAPIDS_DOCUMENTATION}}") + endif() + + if(DEFINED RAPIDS_FINAL_CODE_BLOCK) + if(NOT DEFINED ${RAPIDS_FINAL_CODE_BLOCK}) + message(FATAL_ERROR "FINAL_CODE_BLOCK variable `${RAPIDS_FINAL_CODE_BLOCK}` doesn't exist") + endif() + set(RAPIDS_PROJECT_FINAL_CODE_BLOCK "${${RAPIDS_FINAL_CODE_BLOCK}}") + endif() + + # Write configuration and version files + string(TOLOWER ${project_name} project_name) + string(TOUPPER ${project_name} project_name_uppercase) + if(type STREQUAL "install") + include("${rapids-cmake-dir}/cmake/install_lib_dir.cmake") + rapids_cmake_install_lib_dir(install_location) + set(install_location "${install_location}/cmake/${project_name}") + + set(scratch_dir "${PROJECT_BINARY_DIR}/rapids-cmake/${project_name}/export") + + configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/config.cmake.in" + "${scratch_dir}/${project_name}-config.cmake" + INSTALL_DESTINATION "${install_location}") + + if(rapids_version_set) + write_basic_package_version_file( + "${scratch_dir}/${project_name}-config-version.cmake" VERSION ${rapids_project_version} + COMPATIBILITY ${rapids_project_version_compat}) + endif() + + install(EXPORT ${RAPIDS_EXPORT_SET} FILE ${project_name}-targets.cmake + NAMESPACE ${RAPIDS_PROJECT_VERSION} DESTINATION "${install_location}") + + if(TARGET rapids_export_install_${RAPIDS_EXPORT_SET}) + include("${rapids-cmake-dir}/export/write_dependencies.cmake") + set(destination "${scratch_dir}/${project_name}-dependencies.cmake") + rapids_export_write_dependencies(INSTALL ${RAPIDS_EXPORT_SET} "${destination}") + endif() + + if(DEFINED RAPIDS_LANGUAGES) + include("${rapids-cmake-dir}/export/write_language.cmake") + foreach(lang IN LISTS RAPIDS_LANGUAGES) + set(destination "${scratch_dir}/${project_name}-${lang}-language.cmake") + rapids_export_write_language(INSTALL ${lang} "${destination}") + endforeach() + endif() + + # Install everything we have generated + install(DIRECTORY "${scratch_dir}/" DESTINATION "${install_location}") + + else() + set(install_location "${PROJECT_BINARY_DIR}") + configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/config.cmake.in" + "${install_location}/${project_name}-config.cmake" + INSTALL_DESTINATION "${install_location}") + + if(rapids_version_set) + write_basic_package_version_file( + "${install_location}/${project_name}-config-version.cmake" VERSION ${rapids_project_version} + COMPATIBILITY ${rapids_project_version_compat}) + endif() + + export(EXPORT ${RAPIDS_EXPORT_SET} NAMESPACE ${RAPIDS_PROJECT_VERSION} + FILE "${install_location}/${project_name}-targets.cmake") + + if(TARGET rapids_export_build_${RAPIDS_EXPORT_SET}) + include("${rapids-cmake-dir}/export/write_dependencies.cmake") + rapids_export_write_dependencies(BUILD ${RAPIDS_EXPORT_SET} + "${install_location}/${project_name}-dependencies.cmake") + endif() + + if(DEFINED RAPIDS_LANGUAGES) + include("${rapids-cmake-dir}/export/write_language.cmake") + foreach(lang IN LISTS RAPIDS_LANGUAGES) + rapids_export_write_language(BUILD ${lang} + "${install_location}/${project_name}-${lang}-language.cmake") + endforeach() + endif() + + endif() + +endfunction() diff --git a/cpp/cmake/thirdparty/get_cuco.cmake b/cpp/cmake/thirdparty/get_cuco.cmake index aaedb0ccc5..381addb03c 100644 --- a/cpp/cmake/thirdparty/get_cuco.cmake +++ b/cpp/cmake/thirdparty/get_cuco.cmake @@ -30,4 +30,5 @@ function(find_and_configure_cuco VERSION) endfunction() -find_and_configure_cuco(0.0.1) +# cuCollections doesn't have a version yet +find_and_configure_cuco(0.0) diff --git a/cpp/cmake/thirdparty/get_faiss.cmake b/cpp/cmake/thirdparty/get_faiss.cmake index a65401579c..1079db3294 100644 --- a/cpp/cmake/thirdparty/get_faiss.cmake +++ b/cpp/cmake/thirdparty/get_faiss.cmake @@ -15,39 +15,59 @@ #============================================================================= function(find_and_configure_faiss) - set(oneValueArgs VERSION PINNED_TAG) + set(oneValueArgs VERSION PINNED_TAG BUILD_STATIC_LIBS) cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) - rapids_find_generate_module(FAISS - HEADER_NAMES faiss/IndexFlat.h - LIBRARY_NAMES faiss - ) - - rapids_cpm_find(FAISS ${PKG_VERSION} - GLOBAL_TARGETS faiss - CPM_ARGS - GIT_REPOSITORY https://github.com/facebookresearch/faiss.git - GIT_TAG ${PKG_PINNED_TAG} - OPTIONS - "FAISS_ENABLE_PYTHON OFF" - "BUILD_SHARED_LIBS OFF" - "CUDAToolkit_ROOT ${CUDAToolkit_LIBRARY_DIR}" - "FAISS_ENABLE_GPU ON" - "BUILD_TESTING OFF" - "CMAKE_MESSAGE_LOG_LEVEL VERBOSE" - ) - - if(FAISS_ADDED) - set(FAISS_GPU_HEADERS ${FAISS_SOURCE_DIR} PARENT_SCOPE) - endif() + if(RAFT_ENABLE_NN_DEPENDENCIES OR RAFT_COMPILE_LIBRARIES) + rapids_find_generate_module(faiss + HEADER_NAMES faiss/IndexFlat.h + LIBRARY_NAMES faiss + ) + + set(BUILD_SHARED_LIBS OFF) + if (NOT PKG_BUILD_STATIC_LIBS) + set(BUILD_SHARED_LIBS ON) + endif() + + rapids_cpm_find(faiss ${PKG_VERSION} + GLOBAL_TARGETS faiss::faiss + INSTALL_EXPORT_SET raft-nn-exports + CPM_ARGS + GIT_REPOSITORY https://github.com/facebookresearch/faiss.git + GIT_TAG ${PKG_PINNED_TAG} + EXCLUDE_FROM_ALL TRUE + OPTIONS + "FAISS_ENABLE_PYTHON OFF" + "CUDAToolkit_ROOT ${CUDAToolkit_LIBRARY_DIR}" + "FAISS_ENABLE_GPU ON" + "BUILD_TESTING OFF" + "CMAKE_MESSAGE_LOG_LEVEL VERBOSE" + ) - if(TARGET faiss AND NOT TARGET FAISS::FAISS) - add_library(FAISS::FAISS ALIAS faiss) + if(TARGET faiss AND NOT TARGET faiss::faiss) + add_library(faiss::faiss ALIAS faiss) + endif() + + if(faiss_ADDED) + rapids_export(BUILD faiss + EXPORT_SET faiss-targets + GLOBAL_TARGETS faiss + NAMESPACE faiss::) + endif() endif() + # We generate the faiss-config files when we built faiss locally, so always do `find_dependency` + rapids_export_package(BUILD OpenMP raft-nn-exports) # faiss uses openMP but doesn't export a need for it + rapids_export_package(BUILD faiss raft-nn-exports) + rapids_export_package(INSTALL faiss raft-nn-exports) + + # Tell cmake where it can find the generated faiss-config.cmake we wrote. + include("${rapids-cmake-dir}/export/find_package_root.cmake") + rapids_export_find_package_root(BUILD faiss [=[${CMAKE_CURRENT_LIST_DIR}]=] raft-nn-exports) endfunction() find_and_configure_faiss(VERSION 1.7.0 PINNED_TAG bde7c0027191f29c9dadafe4f6e68ca0ee31fb30 + BUILD_STATIC_LIBS ${RAFT_USE_FAISS_STATIC} ) diff --git a/cpp/cmake/thirdparty/get_gtest.cmake b/cpp/cmake/thirdparty/get_gtest.cmake index 7c234283d5..72fb0e18c6 100644 --- a/cpp/cmake/thirdparty/get_gtest.cmake +++ b/cpp/cmake/thirdparty/get_gtest.cmake @@ -17,7 +17,19 @@ function(find_and_configure_gtest ) include(${rapids-cmake-dir}/cpm/gtest.cmake) - rapids_cpm_gtest() + rapids_cpm_gtest(BUILD_EXPORT_SET raft-exports + EXCLUDE_FROM_ALL TRUE) + + if(GTest_ADDED) + rapids_export(BUILD GTest + VERSION ${GTest_VERSION} + EXPORT_SET GTestTargets + GLOBAL_TARGETS gtest gmock gtest_main gmock_main + NAMESPACE GTest::) + + include("${rapids-cmake-dir}/export/find_package_root.cmake") + rapids_export_find_package_root(BUILD GTest [=[${CMAKE_CURRENT_LIST_DIR}]=] raft-exports) + endif() endfunction() diff --git a/cpp/cmake/versions.json b/cpp/cmake/versions.json new file mode 100644 index 0000000000..cca2dd8859 --- /dev/null +++ b/cpp/cmake/versions.json @@ -0,0 +1,9 @@ +{ + "packages" : { + "Thrust" : { + "version" : "1.15.0", + "git_url" : "https://github.com/NVIDIA/thrust.git", + "git_tag" : "${version}" + } + } +} diff --git a/cpp/test/CMakeLists.txt b/cpp/test/CMakeLists.txt index 72dae50643..07f04ad2ab 100644 --- a/cpp/test/CMakeLists.txt +++ b/cpp/test/CMakeLists.txt @@ -121,15 +121,16 @@ target_compile_options(test_raft target_include_directories(test_raft PUBLIC "$" - "${FAISS_GPU_HEADERS}" ) target_link_libraries(test_raft PRIVATE - raft # transitively links all CUDA libs, etc - raft_distance - raft_nn + raft::raft + raft::distance + raft::nn + NCCL::NCCL + faiss::faiss GTest::gtest GTest::gtest_main Threads::Threads diff --git a/cpp/test/distance/distance_base.cuh b/cpp/test/distance/distance_base.cuh index 475202137b..8f0de29eed 100644 --- a/cpp/test/distance/distance_base.cuh +++ b/cpp/test/distance/distance_base.cuh @@ -20,7 +20,9 @@ #include #include #include +#if defined RAFT_DISTANCE_COMPILED #include +#endif #include namespace raft { diff --git a/cpp/test/sparse/knn_graph.cu b/cpp/test/sparse/knn_graph.cu index df9bb4e3e4..88a3f24df6 100644 --- a/cpp/test/sparse/knn_graph.cu +++ b/cpp/test/sparse/knn_graph.cu @@ -23,7 +23,9 @@ #include #include +#if defined RAFT_NN_COMPILED #include +#endif #include diff --git a/cpp/test/spatial/ball_cover.cu b/cpp/test/spatial/ball_cover.cu index 7b44c477aa..257950e4d7 100644 --- a/cpp/test/spatial/ball_cover.cu +++ b/cpp/test/spatial/ball_cover.cu @@ -20,9 +20,11 @@ #include #include #include +#if defined RAFT_NN_COMPILED #include -#include +#endif +#include #include #include diff --git a/cpp/test/spatial/knn.cu b/cpp/test/spatial/knn.cu index 5681f66e25..8af1505bcd 100644 --- a/cpp/test/spatial/knn.cu +++ b/cpp/test/spatial/knn.cu @@ -19,7 +19,9 @@ #include #include +#if defined RAFT_NN_COMPILED #include +#endif #include diff --git a/cpp/test/spatial/selection.cu b/cpp/test/spatial/selection.cu index 4409f893a8..8ccf3b6b73 100644 --- a/cpp/test/spatial/selection.cu +++ b/cpp/test/spatial/selection.cu @@ -21,7 +21,9 @@ #include #include +#if defined RAFT_NN_COMPILED #include +#endif namespace raft { namespace spatial {