From ef36d3a5580869562b7fb28b6ddd809f64661730 Mon Sep 17 00:00:00 2001 From: Allison Vacanti Date: Tue, 19 Oct 2021 17:49:30 -0400 Subject: [PATCH] Port to rapids-cmake. - Add export sets - Add install rules - Remove manual CPM import, port to rapids_cpm_*, etc - Organize CMake code into cmake/*.cmake files. - NVBench is now a shared library. --- CMakeLists.txt | 76 +++++++++------------------------ cmake/NVBenchConfigTarget.cmake | 14 ++++++ cmake/NVBenchDependencies.cmake | 58 +++++++++++++++++++++++++ cmake/NVBenchExports.cmake | 14 ++++++ cmake/NVBenchInstallRules.cmake | 26 +++++++++++ cmake/NVBenchRapidsCMake.cmake | 29 +++++++++++++ cmake/modules/CPM.cmake | 19 --------- examples/CMakeLists.txt | 6 +-- nvbench/CMakeLists.txt | 47 ++++++++++---------- nvbench/git_revision.cuh | 31 ++++++++++++++ nvbench/option_parser.cu | 4 +- nvbench/version.cuh | 36 ++++++++++++++++ testing/CMakeLists.txt | 6 +-- 13 files changed, 257 insertions(+), 109 deletions(-) create mode 100644 cmake/NVBenchConfigTarget.cmake create mode 100644 cmake/NVBenchDependencies.cmake create mode 100644 cmake/NVBenchExports.cmake create mode 100644 cmake/NVBenchInstallRules.cmake create mode 100644 cmake/NVBenchRapidsCMake.cmake delete mode 100644 cmake/modules/CPM.cmake create mode 100644 nvbench/git_revision.cuh create mode 100644 nvbench/version.cuh diff --git a/CMakeLists.txt b/CMakeLists.txt index 850a51a..5c985b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,66 +1,28 @@ -# 3.18.3 is needed for a MSVC + NVCC + C++17 bugfix. -cmake_minimum_required(VERSION 3.18.3) +# 3.20.1 required for rapids-cmake +cmake_minimum_required(VERSION 3.20.1) -# CXX to work around issues with CUDA-only CMake projects. -project(NVBench CUDA CXX) +include(cmake/NVBenchRapidsCMake.cmake) +nvbench_load_rapids_cmake() -option(NVBench_ENABLE_TESTING "Build NVBench testing suite." OFF) -option(NVBench_ENABLE_EXAMPLES "Build NVBench examples." OFF) +project(NVBench + LANGUAGES CUDA CXX # CXX to work around issues with CUDA-only CMake projects. + VERSION 0.1.0 +) -# Setup some vars for CPM packages: -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") +nvbench_init_rapids_cmake() + +include(cmake/NVBenchConfigTarget.cmake) +include(cmake/NVBenchDependencies.cmake) +include(cmake/NVBenchExports.cmake) +include(cmake/NVBenchInstallRules.cmake) + +message(STATUS "NVBench CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") -# NVBench requires C++17. set(CMAKE_CXX_STANDARD 17) set(CMAKE_CUDA_STANDARD 17) -# TODO this probably should use GNUInstallDirs or something. -set(NVBench_LIBRARY_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib") -set(NVBench_EXECUTABLE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin") - -include(CPM) - -CPMAddPackage( - NAME fmt - GITHUB_REPOSITORY fmtlib/fmt - GIT_TAG 7.1.3 -) - -# Following recipe from -# http://github.com/cpm-cmake/CPM.cmake/blob/master/examples/json/CMakeLists.txt -# Download the zips because the repo takes an excessively long time to clone. -CPMAddPackage( - NAME nlohmann_json - - # I'm waiting for https://github.com/nlohmann/json/issues/2676 to be fixed, - # leave this in to simplify testing patches as they come out. Update the - # `nvbench_json` target too when switching branches. - # Development version: -# VERSION develop -# URL https://github.com/nlohmann/json/archive/refs/heads/develop.zip -# OPTIONS JSON_MultipleHeaders ON - - # Latest release headers: - VERSION 3.9.1 - URL https://github.com/nlohmann/json/releases/download/v3.9.1/include.zip - URL_HASH SHA256=6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91 - PATCH_COMMAND - # Work around compiler bug in nvcc 11.0, see NVIDIA/NVBench#18 - ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/cmake/patches/nlohmann_json.hpp" "./include/nlohmann/json.hpp" -) - -# Development branch: -#add_library(nvbench_json INTERFACE) -#target_link_libraries(nvbench_json INTERFACE nlohmann_json) - -# Release headers -add_library(nvbench_json INTERFACE) -target_include_directories(nvbench_json SYSTEM INTERFACE - "${nlohmann_json_SOURCE_DIR}/include" -) - -# Builds all NVBench targets (libs, tests, examples, etc). -add_custom_target(nvbench.all) +option(NVBench_ENABLE_TESTING "Build NVBench testing suite." OFF) +option(NVBench_ENABLE_EXAMPLES "Build NVBench examples." OFF) add_subdirectory(nvbench) @@ -75,3 +37,5 @@ endif() if (NVBench_ENABLE_TESTING) add_subdirectory(testing) endif() + +nvbench_generate_exports() diff --git a/cmake/NVBenchConfigTarget.cmake b/cmake/NVBenchConfigTarget.cmake new file mode 100644 index 0000000..6676bb4 --- /dev/null +++ b/cmake/NVBenchConfigTarget.cmake @@ -0,0 +1,14 @@ +# Builds all NVBench targets (libs, tests, examples, etc). +add_custom_target(nvbench.all) + +set(NVBench_LIBRARY_OUTPUT_DIR "${CMAKE_BINARY_DIR}/lib") +set(NVBench_EXECUTABLE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/bin") + +function(nvbench_config_target target_name) + set_target_properties(${target_name} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" + LIBRARY_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" + RUNTIME_OUTPUT_DIRECTORY "${NVBench_EXECUTABLE_OUTPUT_DIR}" + WINDOWS_EXPORT_ALL_SYMBOLS ON # oooo pretty hammer... + ) +endfunction() diff --git a/cmake/NVBenchDependencies.cmake b/cmake/NVBenchDependencies.cmake new file mode 100644 index 0000000..a13bae7 --- /dev/null +++ b/cmake/NVBenchDependencies.cmake @@ -0,0 +1,58 @@ +################################################################################ +# fmtlib/fmt +rapids_cpm_find(fmt 7.1.3 + CPM_ARGS + GITHUB_REPOSITORY fmtlib/fmt + GIT_TAG 7.1.3 + GIT_SHALLOW TRUE +) + +################################################################################ +# nlohmann/json +# +# Following recipe from +# http://github.com/cpm-cmake/CPM.cmake/blob/master/examples/json/CMakeLists.txt +# Download the zips because the repo takes an excessively long time to clone. +rapids_cpm_find(nlohmann_json 3.9.1 + # Release: + CPM_ARGS + URL https://github.com/nlohmann/json/releases/download/v3.9.1/include.zip + URL_HASH SHA256=6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91 + PATCH_COMMAND + # Work around compiler bug in nvcc 11.0, see NVIDIA/NVBench#18 + ${CMAKE_COMMAND} -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/patches/nlohmann_json.hpp" + "./include/nlohmann/json.hpp" + + # Development version: + # I'm waiting for https://github.com/nlohmann/json/issues/2676 to be fixed, + # leave this in to simplify testing patches as they come out. Update the + # `nvbench_json` target too when switching branches. + # CPM_ARGS + # VERSION develop + # URL https://github.com/nlohmann/json/archive/refs/heads/develop.zip + # OPTIONS JSON_MultipleHeaders ON +) + +# nlohmann_json release headers +add_library(nvbench_json INTERFACE) +target_include_directories(nvbench_json SYSTEM INTERFACE + "${nlohmann_json_SOURCE_DIR}/include" +) + +# nlohmann_json development branch: +#add_library(nvbench_json INTERFACE) +#target_link_libraries(nvbench_json INTERFACE nlohmann_json) + +################################################################################ +# CUDAToolkit +rapids_find_package(CUDAToolkit REQUIRED + BUILD_EXPORT_SET nvbench-targets + INSTALL_EXPORT_SET nvbench-targets +) + +if (CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Shared") + set(ctk_libraries CUDA::cudart) +elseif(CMAKE_CUDA_RUNTIME_LIBRARY STREQUAL "Static") + set(ctk_libraries CUDA::cudart_static) +endif() diff --git a/cmake/NVBenchExports.cmake b/cmake/NVBenchExports.cmake new file mode 100644 index 0000000..240d417 --- /dev/null +++ b/cmake/NVBenchExports.cmake @@ -0,0 +1,14 @@ +macro(nvbench_generate_exports) + rapids_export(BUILD NVBench + EXPORT_SET nvbench-targets + NAMESPACE "nvbench::" + GLOBAL_TARGETS nvbench main + LANGUAGES CUDA CXX + ) + rapids_export(INSTALL NVBench + EXPORT_SET nvbench-targets + NAMESPACE "nvbench::" + GLOBAL_TARGETS nvbench main + LANGUAGES CUDA CXX + ) +endmacro() diff --git a/cmake/NVBenchInstallRules.cmake b/cmake/NVBenchInstallRules.cmake new file mode 100644 index 0000000..dd7e321 --- /dev/null +++ b/cmake/NVBenchInstallRules.cmake @@ -0,0 +1,26 @@ +include(GNUInstallDirs) +rapids_cmake_install_lib_dir(NVBench_INSTALL_LIB_DIR) + +# in-source public headers: +install(DIRECTORY "${NVBench_SOURCE_DIR}/nvbench" + TYPE INCLUDE + FILES_MATCHING + PATTERN "*.cuh" + PATTERN "internal" EXCLUDE +) + +# generated headers from build dir: +install(FILES + "${NVBench_BINARY_DIR}/nvbench/detail/version.cuh" + "${NVBench_BINARY_DIR}/nvbench/detail/git_revision.cuh" + + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/nvbench/detail" +) + +# Call with a list of library targets to generate install rules: +function(nvbench_install_libraries) + install(TARGETS ${ARGN} + DESTINATION "${NVBench_INSTALL_LIB_DIR}" + EXPORT nvbench-targets + ) +endfunction() diff --git a/cmake/NVBenchRapidsCMake.cmake b/cmake/NVBenchRapidsCMake.cmake new file mode 100644 index 0000000..250ef9e --- /dev/null +++ b/cmake/NVBenchRapidsCMake.cmake @@ -0,0 +1,29 @@ +# Called before project(...) +macro(nvbench_load_rapids_cmake) + file(DOWNLOAD + https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-21.12/RAPIDS.cmake + "${CMAKE_BINARY_DIR}/RAPIDS.cmake" + ) + include("${CMAKE_BINARY_DIR}/RAPIDS.cmake") + + include(rapids-cmake) + include(rapids-cpm) + include(rapids-cuda) + include(rapids-export) + include(rapids-find) + + rapids_cuda_init_architectures(NVBench) + # Only sets CMAKE_CUDA_RUNTIME_LIBRARY if it is currently unset: + rapids_cuda_init_runtime(USE_STATIC TRUE) +endmacro() + +# Called after project(...) +macro(nvbench_init_rapids_cmake) + rapids_cmake_build_type(Release) + rapids_cmake_write_version_file("${NVBench_BINARY_DIR}/nvbench/detail/version.cuh") + rapids_cmake_write_git_revision_file( + nvbench_git_revision + "${NVBench_BINARY_DIR}/nvbench/detail/git_revision.cuh" + ) + rapids_cpm_init() +endmacro() diff --git a/cmake/modules/CPM.cmake b/cmake/modules/CPM.cmake deleted file mode 100644 index c2a4347..0000000 --- a/cmake/modules/CPM.cmake +++ /dev/null @@ -1,19 +0,0 @@ -set(CPM_DOWNLOAD_VERSION 0.27.3) - -if(CPM_SOURCE_CACHE) - set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") -elseif(DEFINED ENV{CPM_SOURCE_CACHE}) - set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") -else() - set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") -endif() - -if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) - message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") - file(DOWNLOAD - https://github.com/TheLartians/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake - ${CPM_DOWNLOAD_LOCATION} - ) -endif() - -include(${CPM_DOWNLOAD_LOCATION}) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 32cb4d0..4e15877 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -15,14 +15,10 @@ foreach(example_src IN LISTS example_srcs) get_filename_component(example_name "${example_src}" NAME_WLE) string(PREPEND example_name "nvbench.example.") add_executable(${example_name} "${example_src}") + nvbench_config_target(${example_name}) target_include_directories(${example_name} PRIVATE "${CMAKE_CURRENT_LIST_DIR}") target_link_libraries(${example_name} PRIVATE nvbench::main) set_target_properties(${example_name} PROPERTIES COMPILE_FEATURES cuda_std_17) - set_target_properties(${example_name} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - LIBRARY_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - RUNTIME_OUTPUT_DIRECTORY "${NVBench_EXECUTABLE_OUTPUT_DIR}" - ) add_test(NAME ${example_name} COMMAND "$" --timeout 1 ) diff --git a/nvbench/CMakeLists.txt b/nvbench/CMakeLists.txt index af4ce5c..248c20f 100644 --- a/nvbench/CMakeLists.txt +++ b/nvbench/CMakeLists.txt @@ -39,39 +39,42 @@ endif() # Generate doc strings from md files: include("../cmake/FileToString.cmake") file_to_string("../docs/cli_help.md" - "${CMAKE_CURRENT_BINARY_DIR}/cli_help.cuh" + "${NVBench_BINARY_DIR}/nvbench/internal/cli_help.cuh" "" cli_help_text ) file_to_string("../docs/cli_help_axis.md" - "${CMAKE_CURRENT_BINARY_DIR}/cli_help_axis.cuh" + "${NVBench_BINARY_DIR}/nvbench/internal/cli_help_axis.cuh" "" cli_help_axis_text ) -find_package(CUDAToolkit) - -add_library(nvbench STATIC ${srcs}) -add_library(nvbench::nvbench ALIAS nvbench) -# TODO generator expressions for installed paths -target_include_directories(nvbench PUBLIC "${NVBench_SOURCE_DIR}") -target_include_directories(nvbench PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") -target_include_directories(nvbench PRIVATE "${CUDAToolkit_INCLUDE_DIRS}") -target_link_libraries(nvbench PRIVATE fmt::fmt nvbench_json) -target_compile_features(nvbench PUBLIC cuda_std_17 PRIVATE cxx_std_17) -set_target_properties(nvbench PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - LIBRARY_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - RUNTIME_OUTPUT_DIRECTORY "${NVBench_EXECUTABLE_OUTPUT_DIR}" +# nvbench (nvbench::nvbench) +add_library(nvbench SHARED ${srcs}) +target_include_directories(nvbench PUBLIC + "$" + "$" + "$" ) +target_link_libraries(nvbench PUBLIC ${ctk_libraries}) +target_link_libraries(nvbench PRIVATE + fmt::fmt + nvbench_json + nvbench_git_revision +) +nvbench_config_target(nvbench) +target_compile_features(nvbench PUBLIC cuda_std_17 PRIVATE cxx_std_17) add_dependencies(nvbench.all nvbench) +# nvbench_main (nvbench::main) add_library(nvbench_main OBJECT main.cu) -add_library(nvbench::main ALIAS nvbench_main) +nvbench_config_target(nvbench_main) target_link_libraries(nvbench_main PUBLIC nvbench) -set_target_properties(nvbench PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - LIBRARY_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - RUNTIME_OUTPUT_DIRECTORY "${NVBench_EXECUTABLE_OUTPUT_DIR}" -) +set_target_properties(nvbench_main PROPERTIES EXPORT_NAME main) add_dependencies(nvbench.all nvbench_main) + +# Support add_subdirectory: +add_library(nvbench::nvbench ALIAS nvbench) +add_library(nvbench::main ALIAS nvbench_main) + +nvbench_install_libraries(nvbench nvbench_main) diff --git a/nvbench/git_revision.cuh b/nvbench/git_revision.cuh new file mode 100644 index 0000000..2b29e92 --- /dev/null +++ b/nvbench/git_revision.cuh @@ -0,0 +1,31 @@ +/* +* Copyright 2021 NVIDIA Corporation +* +* Licensed under the Apache License, Version 2.0 with the LLVM exception +* (the "License"); you may not use this file except in compliance with +* the License. +* +* You may obtain a copy of the License at +* +* http://llvm.org/foundation/relicensing/LICENSE.txt +* +* 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. +*/ + +#pragma once + +#include + +// WAR issue rapidsai/rapids-cmake#99: +#define NVBENCH_GIT_BRANCH NVBench_GIT_BRANCH +#define NVBENCH_GIT_SHA1 NVBench_GIT_SHA1 +#define NVBENCH_GIT_VERSION NVBench_GIT_VERSION +#ifdef NVBench_GIT_IS_DIRTY +# define NVBENCH_GIT_IS_DIRTY +#endif + + diff --git a/nvbench/option_parser.cu b/nvbench/option_parser.cu index d1798aa..3f162af 100644 --- a/nvbench/option_parser.cu +++ b/nvbench/option_parser.cu @@ -29,8 +29,8 @@ #include // These are generated from the markdown docs by CMake in the build directory: -#include "cli_help.cuh" -#include "cli_help_axis.cuh" +#include +#include #include diff --git a/nvbench/version.cuh b/nvbench/version.cuh new file mode 100644 index 0000000..69e92e5 --- /dev/null +++ b/nvbench/version.cuh @@ -0,0 +1,36 @@ +/* + * Copyright 2021 NVIDIA Corporation + * + * Licensed under the Apache License, Version 2.0 with the LLVM exception + * (the "License"); you may not use this file except in compliance with + * the License. + * + * You may obtain a copy of the License at + * + * http://llvm.org/foundation/relicensing/LICENSE.txt + * + * 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. + */ + +#pragma once + +#include + +// WAR issue rapidsai/rapids-cmake#99 +#define NVBENCH_VERSION_MAJOR NVBench_VERSION_MAJOR +#define NVBENCH_VERSION_MINOR NVBench_VERSION_MINOR +#define NVBENCH_VERSION_PATCH NVBench_VERSION_PATCH + +// clang-format off + +/// Numeric version as "MMmmpp" +#define NVBENCH_VERSION \ + NVBENCH_VERSION_MAJOR * 10000 + \ + NVBENCH_VERSION_MINOR * 100+ \ + NVBENCH_VERSION_PATCH + +// clang-format on diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index 22f63df..7603bc1 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -29,11 +29,7 @@ foreach(test_src IN LISTS test_srcs) target_include_directories(${test_name} PRIVATE "${CMAKE_CURRENT_LIST_DIR}") target_link_libraries(${test_name} PRIVATE nvbench::nvbench fmt) set_target_properties(${test_name} PROPERTIES COMPILE_FEATURES cuda_std_17) - set_target_properties(${test_name} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - LIBRARY_OUTPUT_DIRECTORY "${NVBench_LIBRARY_OUTPUT_DIR}" - RUNTIME_OUTPUT_DIRECTORY "${NVBench_EXECUTABLE_OUTPUT_DIR}" - ) + nvbench_config_target(${test_name}) add_test(NAME ${test_name} COMMAND "$") add_dependencies(nvbench.test.all ${test_name})