Skip to content

Commit 436cde6

Browse files
authored
Add Thrust CMake example with flexible device system, update docs (NVIDIA#4500)
* Bump minimum cmake in examples to match CCCL reqs. * Use local repo / HEAD by default when building CCCL examples. * Actually build the cudastf example. * Add new CCCL+CMake+CPM example that demonstrates how to change device backend. * Update existing Thrust CMake documentation to clarify intended-audience and cross-ref user docs.
1 parent a87ef64 commit 436cde6

File tree

12 files changed

+1514
-14
lines changed

12 files changed

+1514
-14
lines changed

docs/thrust/cmake_options.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
.. _cmake-options:
22

3+
Notice
4+
------
5+
6+
This document details the CMake options used for **developer builds**
7+
of the Thrust tests and examples included in the CCCL repository.
8+
The options presented here are not available when using Thrust as an
9+
end-user via our installed CMake packages, or when using
10+
``add_subdirectory`` / CPM to add CCCL/Thrust to your project's build system.
11+
For details and examples of using Thrust as an end-user, please refer
12+
to the following resources:
13+
14+
- `Thrust + CMake example <https://github.com/NVIDIA/cccl/tree/main/examples/thrust_flexible_device_system>`__
15+
316
CMake Options
417
=============
518

docs/thrust/setup.rst renamed to docs/thrust/developer_build.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.. _thrust-module-setup:
22

3-
Setup
3+
Developer Build
44
==================================================
55

66
.. toctree::

docs/thrust/index.rst

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ Thrust: The C++ Parallel Algorithms Library
88
:maxdepth: 2
99

1010
:ref:`Overview <thrust-module>`
11-
setup
1211
releases
1312
release_process
13+
developer_build
1414
api
1515
${repo_docs_api_path}/thrust_api
1616

@@ -29,6 +29,17 @@ Examples
2929

3030
Thrust is best learned through examples.
3131

32+
-------------
33+
CMake Example
34+
-------------
35+
36+
A complete, standalone example project showing how to write a CMake build system that uses Thrust with any supported
37+
device system is available in the CCCL repository `here <https://github.com/NVIDIA/cccl/tree/main/examples/thrust_flexible_device_system>`__.
38+
39+
------------------
40+
Thrust API Example
41+
------------------
42+
3243
The following example generates random numbers serially and then transfers them
3344
to a parallel device where they are sorted.
3445

examples/CMakeLists.txt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ set(cmake_opts
2424
-D "CMAKE_CUDA_ARCHITECTURES=${arches_escaped}"
2525
)
2626

27-
set(CCCL_EXAMPLE_CPM_REPOSITORY "nvidia/cccl" CACHE STRING "GitHub repository used for CPM examples.")
28-
set(CCCL_EXAMPLE_CPM_TAG "main" CACHE STRING "Git tag/branch used for CPM examples.")
27+
set(CCCL_EXAMPLE_CPM_REPOSITORY "${CCCL_SOURCE_DIR}" CACHE STRING "Git repository used for CPM examples.")
28+
set(CCCL_EXAMPLE_CPM_TAG "HEAD" CACHE STRING "Git tag/branch used for CPM examples.")
2929

3030
set(cmake_cpm_opts
3131
-D "CCCL_REPOSITORY=${CCCL_EXAMPLE_CPM_REPOSITORY}"
@@ -50,4 +50,23 @@ if (CUDAToolkit_VERSION_MAJOR VERSION_GREATER_EQUAL 12)
5050
${cmake_opts}
5151
${cmake_cpm_opts}
5252
)
53-
endif()
53+
54+
cccl_add_compile_test(test_name
55+
cccl.example
56+
cudax_stf
57+
"default"
58+
${cmake_opts}
59+
${cmake_cpm_opts}
60+
)
61+
endif() # CTK > 12.0
62+
63+
foreach (DEVICE_SYSTEM IN ITEMS CUDA OMP TBB CPP)
64+
cccl_add_compile_test(test_name
65+
cccl.example
66+
thrust_flexible_device_system
67+
"${DEVICE_SYSTEM}"
68+
-D "CCCL_THRUST_DEVICE_SYSTEM=${DEVICE_SYSTEM}"
69+
${cmake_opts}
70+
${cmake_cpm_opts}
71+
)
72+
endforeach()

examples/basic/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
16+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
1717

1818
project(CCCLDemo CUDA)
1919

@@ -24,13 +24,13 @@ include(cmake/CPM.cmake)
2424

2525
# We define these as variables so they can be overridden in CI to pull from a PR instead of CCCL `main`
2626
# In your project, these variables are unnecessary and you can just use the values directly
27-
set(CCCL_REPOSITORY "nvidia/cccl" CACHE STRING "GitHub repository to fetch CCCL from")
27+
set(CCCL_REPOSITORY "https://github.com/NVIDIA/cccl" CACHE STRING "Git repository to fetch CCCL from")
2828
set(CCCL_TAG "main" CACHE STRING "Git tag/branch to fetch from CCCL repository")
2929

3030
# This will automatically clone CCCL from GitHub and make the exported cmake targets available
3131
CPMAddPackage(
3232
NAME CCCL
33-
GITHUB_REPOSITORY ${CCCL_REPOSITORY}
33+
GIT_REPOSITORY "${CCCL_REPOSITORY}"
3434
GIT_TAG ${CCCL_TAG}
3535
)
3636

examples/cudax/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
16+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
1717

1818
project(CUDAX_SAMPLES CUDA CXX)
1919

@@ -23,13 +23,13 @@ include(cmake/CPM.cmake)
2323

2424
# We define these as variables so they can be overridden in CI to pull from a PR instead of CCCL `main`
2525
# In your project, these variables are unnecessary and you can just use the values directly
26-
set(CCCL_REPOSITORY "nvidia/cccl" CACHE STRING "GitHub repository to fetch CCCL from")
26+
set(CCCL_REPOSITORY "https://github.com/NVIDIA/cccl" CACHE STRING "Git repository to fetch CCCL from")
2727
set(CCCL_TAG "main" CACHE STRING "Git tag/branch to fetch from CCCL repository")
2828

2929
# This will automatically clone CCCL from GitHub and make the exported cmake targets available
3030
CPMAddPackage(
3131
NAME CCCL
32-
GITHUB_REPOSITORY ${CCCL_REPOSITORY}
32+
GIT_REPOSITORY "${CCCL_REPOSITORY}"
3333
GIT_TAG ${CCCL_TAG}
3434
GIT_SHALLOW ON
3535
# The following is required to make the `CCCL::cudax` target available:

examples/cudax_stf/CMakeLists.txt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,24 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
16+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
1717

1818
project(CUDAX_SAMPLES CUDA CXX)
1919

2020
# This example uses the CMake Package Manager (CPM) to simplify fetching CCCL from GitHub
2121
# For more information, see https://github.com/cpm-cmake/CPM.cmake
2222
include(cmake/CPM.cmake)
2323

24+
# We define these as variables so they can be overridden in CI to pull from a PR instead of CCCL `main`
25+
# In your project, these variables are unnecessary and you can just use the values directly
26+
set(CCCL_REPOSITORY "https://github.com/NVIDIA/cccl" CACHE STRING "Git repository to fetch CCCL from")
27+
set(CCCL_TAG "main" CACHE STRING "Git tag/branch to fetch from CCCL repository")
28+
2429
# This will automatically clone CCCL from GitHub and make the exported cmake targets available
2530
CPMAddPackage(
2631
NAME CCCL
27-
GITHUB_REPOSITORY "nvidia/cccl"
28-
GIT_TAG "main"
32+
GIT_REPOSITORY "${CCCL_REPOSITORY}"
33+
GIT_TAG ${CCCL_TAG}
2934
# The following is required to make the `CCCL::cudax` target available:
3035
OPTIONS "CCCL_ENABLE_UNSTABLE ON"
3136
)
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# This demo provides an example of how to configure a project to use Thrust while selecting
17+
# the device system as a configuration option. The device system is selected by setting the
18+
# CMake option `CCCL_THRUST_DEVICE_SYSTEM={CUDA, OMP, TBB, CPP}` for CUDA, OpenMP, Intel Threading
19+
# Building Blocks (TBB), and serial C++, respectively. If no option is provided, the default is `CUDA`.
20+
#
21+
# See the accompanying README.md for more information and build instructions.
22+
23+
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
24+
25+
project(ThrustFlexibleDeviceSystemDemo CXX)
26+
27+
# This example uses the CMake Package Manager (CPM) to simplify fetching CCCL from GitHub
28+
# For more information, see https://github.com/cpm-cmake/CPM.cmake
29+
include(cmake/CPM.cmake)
30+
31+
# We define these as variables so they can be overridden in CI to pull from a PR instead of CCCL `main`
32+
# In your project, these variables are unnecessary and you can just use the values directly
33+
set(CCCL_REPOSITORY "https://github.com/NVIDIA/cccl" CACHE STRING "GitHub repository to fetch CCCL from")
34+
set(CCCL_TAG "main" CACHE STRING "Git tag/branch to fetch from CCCL repository")
35+
36+
# This will automatically clone CCCL from GitHub and make the exported cmake targets available.
37+
# The default `CCCL::Thrust` target will be configured to use the system device defined by
38+
# `CCCL_THRUST_DEVICE_SYSTEM`.
39+
CPMAddPackage(
40+
NAME CCCL
41+
GIT_REPOSITORY "${CCCL_REPOSITORY}"
42+
GIT_TAG ${CCCL_TAG}
43+
)
44+
45+
# CUDA specific setup
46+
if (CCCL_THRUST_DEVICE_SYSTEM STREQUAL "CUDA")
47+
# Need to explicitly enable the CUDA language for the project.
48+
# Note that the project(...) command earlier only enables CXX by default.
49+
enable_language(CUDA)
50+
51+
# Compile for the native CUDA arch if not specified:
52+
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
53+
set(CMAKE_CUDA_ARCHITECTURES native)
54+
endif()
55+
endif()
56+
57+
# Creates a cmake executable target for the main program
58+
add_executable(example_program example.cpp)
59+
# Thrust requires at least C++17:
60+
target_compile_features(example_program PUBLIC cuda_std_17 cxx_std_17)
61+
62+
# By default, CMake inspects the source file extension to determine whether to use C++ or CUDA
63+
# compilers. We can override this behavior by using source file properties. Here, we tell CMake
64+
# to compile this C++ (.cpp) file with the CUDA compiler when using the CUDA device system:
65+
if (CCCL_THRUST_DEVICE_SYSTEM STREQUAL "CUDA")
66+
set_source_files_properties(example.cpp PROPERTIES LANGUAGE CUDA)
67+
endif()
68+
69+
# "Links" the CCCL Cmake target to the `example_program` executable. This configures everything needed to use
70+
# CCCL headers, including setting up include paths, compiler flags, Thrust host/device configuration, etc.
71+
target_link_libraries(example_program PRIVATE CCCL::CCCL)
72+
73+
# This is only relevant for internal testing and not needed by end users.
74+
include(CTest)
75+
enable_testing()
76+
add_test(NAME example_program COMMAND example_program)
77+
set_tests_properties(example_program PROPERTIES
78+
PASS_REGULAR_EXPRESSION "Detected device system: ${CCCL_THRUST_DEVICE_SYSTEM}"
79+
)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Thrust Flexible Device System Example
2+
3+
This example illustrates best practices for writing generic CMake that supports user-configuration of the Thrust device system via the `CCCL_THRUST_DEVICE_SYSTEM` CMake option.
4+
5+
Valid values for this option are:
6+
7+
- `CUDA`
8+
- `OMP` (OpenMP)
9+
- `TBB` (Intel Thread Building Blocks)
10+
- `CPP` (Serial C++ backend)
11+
12+
The CMakeLists.txt file for this example is annotated to show how to achieve a generic build system that supports any of device system.
13+
14+
## How To Use This Example
15+
16+
Configure and build this example as follows:
17+
18+
```
19+
# Checkout example and prepare build directory:
20+
git clone https://github.com/NVIDIA/cccl.git
21+
cd cccl/thrust_flexible_device_system
22+
mkdir build
23+
cd build
24+
25+
# Configure:
26+
cmake .. -DCCCL_THRUST_DEVICE_SYSTEM=CUDA # or TBB, OMP, CPP
27+
28+
# Build:
29+
cmake --build .
30+
31+
# Run:
32+
ctest -V
33+
```
34+
35+
## Advanced Thrust Usecases
36+
37+
For more control over the Thrust configuration, see the Thrust CMake package's [README.md](../../lib/cmake/thrust/README.md).
38+
This details how to use the `thrust_create_target` function to generate Thrust interface targets in CMake.
39+
40+
If using `thrust_create_target` directly, you may also want to set the CMake option `CCCL_ENABLE_DEFAULT_THRUST_TARGET=OFF` to prevent the default `CCCL::Thrust` target from being initialized.
41+
This will avoid checking for any dependencies required for the default target that may be unnecessary for your project.
42+
43+
## Further Reading About CCCL + CMake
44+
45+
The `basic` example's [README.md](../basic/README.md) has additional information that you may find useful for using CCCL with CPM and CMake.

0 commit comments

Comments
 (0)