Skip to content

Commit 441a98f

Browse files
committed
Allow thrust to be added to CMake projects via add_subdirectory.
See issue NVIDIA#976. Added example in `examples/cmake/add_subdir/CMakeLists.txt` that is used for documentation and regression testing.
1 parent d83ea9f commit 441a98f

File tree

7 files changed

+154
-0
lines changed

7 files changed

+154
-0
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# Support adding Thrust to a parent project via add_subdirectory.
2+
# See examples/cmake/add_subdir/CMakeLists.txt for details.
3+
if (NOT "${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}")
4+
include(cmake/ThrustAddSubdir.cmake)
5+
return()
6+
endif()
7+
18
# 3.15 is the minimum.
29
# 3.17 for nvc++/Feta
310
# 3.18 for C++17 + CUDA

cmake/ThrustAddSubdir.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
find_package(Thrust REQUIRED CONFIG
2+
NO_DEFAULT_PATH # Only check the explicit path in HINTS:
3+
HINTS "${CMAKE_CURRENT_LIST_DIR}/.."
4+
COMPONENTS ${THRUST_REQUIRED_SYSTEMS}
5+
OPTIONAL_COMPONENTS ${THRUST_OPTIONAL_SYSTEMS}
6+
)

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,5 @@ foreach(thrust_target IN LISTS THRUST_TARGETS)
148148
endforeach()
149149
endforeach()
150150

151+
add_subdirectory(cmake)
151152
add_subdirectory(cuda)

examples/cmake/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
thrust_update_system_found_flags()
2+
3+
if (THRUST_CPP_FOUND AND THRUST_CUDA_FOUND)
4+
# Do a basic check of the cmake/ThrustAddSubdir.cmake mechanism:
5+
add_test(
6+
NAME thrust.example.cmake.add_subdir
7+
COMMAND "${CMAKE_COMMAND}"
8+
--log-level=VERBOSE
9+
-S "${CMAKE_CURRENT_SOURCE_DIR}/add_subdir"
10+
-B "${CMAKE_CURRENT_BINARY_DIR}/add_subdir"
11+
-D "THRUST_DIR=${Thrust_SOURCE_DIR}"
12+
-D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
13+
-D "CMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}"
14+
-D "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
15+
)
16+
endif()
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# This example demonstrates / tests adding thrust via a CMake add_subdirectory
2+
# call from a parent project.
3+
#
4+
# The variables THRUST_REQUIRED_SYSTEMS and THRUST_OPTIONAL_SYSTEMS must be
5+
# set prior to add_subdirectory(thrust), and afterwards the thrust_create_target
6+
# function may be used to create targets with the desired systems. See
7+
# thrust/thrust/cmake/README.md for more details on thrust_create_target.
8+
9+
cmake_minimum_required(VERSION 3.15)
10+
11+
# Silence warnings about empty CUDA_ARCHITECTURES properties on example targets:
12+
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18)
13+
cmake_policy(SET CMP0104 OLD)
14+
endif()
15+
16+
project(ThrustAddSubDirExample CXX)
17+
18+
# Add required Thrust systems to THRUST_REQUIRED_SYSTEMS.
19+
# Options are: CPP, CUDA, TBB or OMP.
20+
# Multiple systems may be specified.
21+
# An error is emitted if the system is not found.
22+
set(THRUST_REQUIRED_SYSTEMS CPP)
23+
24+
# Add optional Thrust systems to THRUST_OPTIONAL_SYSTEMS.
25+
# Options are: CPP, CUDA, TBB or OMP.
26+
# Multiple systems may be specified.
27+
# No error is emitted if not found.
28+
set(THRUST_OPTIONAL_SYSTEMS CUDA)
29+
30+
# Use your project's checkout of Thrust here, for most cases
31+
# `add_subdirectory(thrust)` will be sufficient.
32+
add_subdirectory("${THRUST_DIR}" thrust)
33+
34+
# Create a thrust target that only uses the serial CPP backend.
35+
# See thrust/thrust/cmake/README.md for details and additional options:
36+
thrust_create_target(ThrustCPP HOST CPP DEVICE CPP)
37+
38+
# Create an executable that uses the CPP-only thrust target:
39+
add_executable(ExecWithCPP dummy.cpp)
40+
target_link_libraries(ExecWithCPP ThrustCPP)
41+
42+
# To test for optional systems, first call thrust_update_system_found_flags to
43+
# set the THRUST_${system}_FOUND flags in current scope.
44+
# Required due to CMake scoping rules.
45+
thrust_update_system_found_flags()
46+
47+
# Create and use a Thrust target configured to use CUDA acceleration if CUDA
48+
# is available:
49+
if (THRUST_CUDA_FOUND)
50+
enable_language(CUDA)
51+
thrust_create_target(ThrustCUDA HOST CPP DEVICE CUDA)
52+
add_executable(ExecWithCUDA dummy.cu)
53+
target_link_libraries(ExecWithCUDA ThrustCUDA)
54+
endif()
55+
56+
#
57+
# Validation
58+
#
59+
60+
function(assert_boolean var_name expect)
61+
if (expect)
62+
if (NOT ${var_name})
63+
message(FATAL_ERROR "'${var_name}' is false, expected true.")
64+
endif()
65+
else()
66+
if (${var_name})
67+
message(FATAL_ERROR "'${var_name}' is true, expected false.")
68+
endif()
69+
endif()
70+
endfunction()
71+
72+
function(assert_target target_name)
73+
if (NOT TARGET "${target_name}")
74+
message(FATAL_ERROR "Target '${target_name}' not defined.")
75+
endif()
76+
endfunction()
77+
78+
assert_boolean(THRUST_CPP_FOUND TRUE)
79+
assert_boolean(THRUST_CUDA_FOUND TRUE)
80+
assert_boolean(THRUST_OMP_FOUND FALSE)
81+
assert_boolean(THRUST_TBB_FOUND FALSE)
82+
83+
assert_target(ThrustCPP)
84+
assert_target(ThrustCUDA)
85+
assert_target(ExecWithCPP)
86+
assert_target(ExecWithCUDA)
87+
88+
thrust_debug_target(ThrustCPP "")
89+
thrust_debug_target(ThrustCUDA "")
90+
thrust_debug_target(ExecWithCPP "")
91+
thrust_debug_target(ExecWithCUDA "")
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <thrust/detail/config.h>
2+
3+
#include <iostream>
4+
5+
int main()
6+
{
7+
std::cout << "Hello from Thrust version " << THRUST_VERSION << ":\n"
8+
9+
<< "Host system: "
10+
#if THRUST_HOST_SYSTEM == THRUST_HOST_SYSTEM_CPP
11+
<< "CPP\n"
12+
#elif THRUST_HOST_SYSTEM == THRUST_HOST_SYSTEM_OMP
13+
<< "OMP\n"
14+
#elif THRUST_HOST_SYSTEM == THRUST_HOST_SYSTEM_TBB
15+
<< "TBB\n"
16+
#else
17+
<< "Unknown\n"
18+
#endif
19+
20+
<< "Device system: "
21+
#if THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_CPP
22+
<< "CPP\n";
23+
#elif THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_CUDA
24+
<< "CUDA\n";
25+
#elif THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_OMP
26+
<< "OMP\n";
27+
#elif THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_TBB
28+
<< "TBB\n";
29+
#else
30+
<< "Unknown\n";
31+
#endif
32+
}

examples/cmake/add_subdir/dummy.cu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "dummy.cpp"

0 commit comments

Comments
 (0)