Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REVIEW] install cmake config file with RMM #580

Merged
merged 19 commits into from
Oct 2, 2020
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- PR #529 Add debug logging and fix multithreaded replay benchmark
- PR #560 Remove deprecated `get/set_default_resource` APIs
- PR #543 Add an arena-based memory resource
- PR #580 Install CMake config with RMM

## Improvements

Expand Down
43 changes: 32 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ option(CUDA_STATIC_RUNTIME "Statically link the CUDA runtime" OFF)

option(PER_THREAD_DEFAULT_STREAM "Build with per-thread default stream" OFF)

option(USE_NVTX "Build with NVTX support" OFF)

###################################################################################################
# find packages we depend on

Expand Down Expand Up @@ -91,18 +89,13 @@ endif(PER_THREAD_DEFAULT_STREAM)
# library targets

add_library(rmm INTERFACE)
add_library(rmm::rmm ALIAS rmm)

target_include_directories(rmm INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:include>"
)

if(USE_NVTX)
message(STATUS "Using Nvidia Tools Extension")
else()
target_compile_definitions(rmm INTERFACE NVTX_DISABLE)
endif(USE_NVTX)

if(CUDA_STATIC_RUNTIME)
message(STATUS "Enabling static linking of cudart")
target_link_libraries(rmm INTERFACE CUDA::cudart_static)
Expand Down Expand Up @@ -140,12 +133,40 @@ endif(BUILD_BENCHMARKS)
###################################################################################################
# install targets

include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/rmm)

install(TARGETS rmm
DESTINATION lib)
EXPORT rmm-targets)

install(DIRECTORY include/rmm
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/rmm
DESTINATION include)
include(CMakePackageConfigHelpers)
configure_package_config_file(
cmake/rmm-config.cmake.in
${RMM_BINARY_DIR}/rmm-config.cmake
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)

write_basic_package_version_file(
${RMM_BINARY_DIR}/rmm-config-version.cmake
COMPATIBILITY SameMinorVersion
)

install(EXPORT rmm-targets
FILE rmm-targets.cmake
NAMESPACE rmm::
DESTINATION ${INSTALL_CONFIGDIR}
)

install(FILES
${RMM_BINARY_DIR}/rmm-config.cmake
${RMM_BINARY_DIR}/rmm-config-version.cmake
${RMM_SOURCE_DIR}/cmake/install/FindThrust.cmake
DESTINATION ${INSTALL_CONFIGDIR}
)

###################################################################################################
# make documentation

Expand Down
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,43 @@ $ pytest -v

Done! You are ready to develop for the RMM OSS project.

### Caching third-party dependencies

RMM uses [CPM.cmake](https://github.com/TheLartians/CPM.cmake) to
handle third-party dependencies like spdlog, Thrust, GoogleTest,
GoogleBenchmark. In general you won't have to worry about it. If CMake
finds an appropriate version on your system, it uses it (you can
help it along by setting `CMAKE_PREFIX_PATH` to point to the
installed location). Otherwise those dependencies will be downloaded as
part of the build.

If you frequently start new builds from scratch, consider setting the
environment variable `CPM_SOURCE_CACHE` to an external download
directory to avoid repeated downloads of the third-party dependencies.

## Using RMM in a downstream CMake project

The installed RMM library provides a set of config files that makes it easy to
integrate RMM into your own CMake project. In your `CMakeLists.txt`, just add

```cmake
find_package(rmm [VERSION])
# ...
target_link_libraries(<your-target> (PRIVATE|PUBLIC) rmm::rmm)
```

Since RMM is a header-only library, this does not actually link RMM,
but it makes the headers available and pulls in transitive dependencies.
If RMM is not installed in a default location, use
`CMAKE_PREFIX_PATH` or `rmm_ROOT` to point to its location.

One of RMM's dependencies is the Thrust library, so the above
automatically pulls in `Thrust` by means of a dependency on the
`rmm::Thrust` target. By default it uses the standard configuration of
Thrust. If you want to customize it, you can set the variables
`THRUST_HOST_SYSTEM` and `THRUST_DEVICE_SYSTEM`; see
[Thrust's CMake documentation](https://github.com/NVIDIA/thrust/blob/main/thrust/cmake/README.md).

# Using RMM in C++

The first goal of RMM is to provide a common interface for device and host memory allocation.
Expand Down
14 changes: 13 additions & 1 deletion cmake/RMM_thirdparty.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,34 @@ include(FetchContent)
###################################################################################################
# - spdlog ----------------------------------------------------------------------------------------

set(RMM_MIN_VERSION_spdlog 1.7.0)

CPMFindPackage(
NAME spdlog
GITHUB_REPOSITORY gabime/spdlog
VERSION 1.7.0
VERSION ${RMM_MIN_VERSION_spdlog}
GIT_SHALLOW TRUE
OPTIONS
# If there is no pre-installed spdlog we can use, we'll install our fetched copy
# together with RMM
"SPDLOG_INSTALL TRUE"
)

###################################################################################################
# - thrust/cub ------------------------------------------------------------------------------------

set(RMM_MIN_VERSION_Thrust 1.9.0)

CPMFindPackage(
NAME Thrust
GITHUB_REPOSITORY NVIDIA/thrust
GIT_TAG 1.10.0
VERSION 1.10.0
GIT_SHALLOW TRUE
OPTIONS
# If there is no pre-installed thrust we can use, we'll install our fetched copy
# together with RMM
"THRUST_INSTALL TRUE"
)

thrust_create_target(rmm::Thrust FROM_OPTIONS)
Expand Down
76 changes: 76 additions & 0 deletions cmake/install/FindThrust.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.
## See LICENSE.txt for details.
## This software is distributed WITHOUT ANY WARRANTY; without even
## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
## PURPOSE. See the above copyright notice for more information.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the license for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good point. I guess it's this: https://gitlab.kitware.com/vtk/vtk-m/-/blob/783867eeb05e0a6538f9c520af02c3615651b4ed/LICENSE.txt. It does say

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the
   distribution.

 * Neither the name of Kitware nor the names of any contributors may
   be used to endorse or promote products derived from this software
   without specific prior written permission.

So it seems pretty permissive, but IANAL.

I can write a custom one from scratch if this causes issues. Chances are it would look very similar, though, since really, the only thing that is not boilerplate in there is the version parsing, and that comes from Nvidia.

Copy link
Member

@harrism harrism Oct 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the BSD 3-clause license plus extra non-exclusive licenses from US govt labs and extra copyrights. That is one of the licenses we can easily use. We still have a process we need to follow to add a new piece of software. I will check if RAPIDS already has done this for CMake code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, we have approval, but before we can merge we need the complete license for this file included (ideally in this file).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so I copied in the full text from the LICENSE.txt above.

##
## Copyright 2014 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014 Los Alamos National Security.
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## the U.S. Government retains certain rights in this software.
##
## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.
##============================================================================

#
# FindThrust
#
# This module finds the Thrust header files and extrats their version. It
# sets the following variables.
#
# THRUST_INCLUDE_DIR - Include directory for thrust header files. (All header
# files will actually be in the thrust subdirectory.)
# THRUST_VERSION - Version of thrust in the form "major.minor.patch".
#

find_path( THRUST_INCLUDE_DIR
HINTS
/usr/include/cuda
/usr/local/include
/usr/local/cuda/include
${CUDA_INCLUDE_DIRS}
${CUDA_TOOLKIT_ROOT_DIR}
${CUDA_SDK_ROOT_DIR}
NAMES thrust/version.h
DOC "Thrust headers"
)
if( THRUST_INCLUDE_DIR )
list( REMOVE_DUPLICATES THRUST_INCLUDE_DIR )
endif( THRUST_INCLUDE_DIR )

# Find thrust version
if (THRUST_INCLUDE_DIR)
file( STRINGS ${THRUST_INCLUDE_DIR}/thrust/version.h
version
REGEX "#define THRUST_VERSION[ \t]+([0-9x]+)"
)
string( REGEX REPLACE
"#define THRUST_VERSION[ \t]+"
""
version
"${version}"
)

math(EXPR major "${version} / 100000")
math(EXPR minor "(${version} / 100) % 1000")
math(EXPR version "${version} % 100")
set( THRUST_VERSION "${major}.${minor}.${version}")
set( THRUST_MAJOR_VERSION "${major}")
set( THRUST_MINOR_VERSION "${minor}")
endif()

# Check for required components
include( FindPackageHandleStandardArgs )
find_package_handle_standard_args( Thrust
REQUIRED_VARS THRUST_INCLUDE_DIR
VERSION_VAR THRUST_VERSION
)

set(THRUST_INCLUDE_DIRS ${THRUST_INCLUDE_DIR})
mark_as_advanced(THRUST_INCLUDE_DIR)
40 changes: 40 additions & 0 deletions cmake/rmm-config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

@PACKAGE_INIT@

cmake_minimum_required(VERSION 3.17)

include(CMakeFindDependencyMacro)
find_dependency(CUDAToolkit)
find_dependency(spdlog @RMM_MIN_VERSION_spdlog@)

# Try to find newer Thrust via config first
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE)
set(_save_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH})
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}")

find_dependency(Thrust @RMM_MIN_VERSION_Thrust@)

set(CMAKE_MODULE_PATH ${_save_CMAKE_MODULE_PATH})

if (Thrust_CONFIG)
# we can use the new way of creating a target
thrust_create_target(rmm::Thrust FROM_OPTIONS)
else()
# otherwise we have to do it ourselves
if (NOT TARGET Thrust)
add_library(Thrust INTERFACE)
set_target_properties(Thrust PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${THRUST_INCLUDE_DIR}")
endif()
add_library(rmm::Thrust ALIAS Thrust)
endif()

include("${CMAKE_CURRENT_LIST_DIR}/rmm-targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/rmm-config-version.cmake")

check_required_components(rmm)

set(${CMAKE_FIND_PACKAGE_NAME}_CONFIG "${CMAKE_CURRENT_LIST_FILE}")

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(${CMAKE_FIND_PACKAGE_NAME} CONFIG_MODE)