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

Add example cmake project #177

Merged
merged 90 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from 79 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
c0afe64
Add initial skeleton for example cmake project.
jrhemstad Jul 7, 2023
a53d032
Add support for nvcc-specific matrix.
jrhemstad Jul 18, 2023
663e2f4
Remove errnoeous runs-on
jrhemstad Jul 18, 2023
9405359
Fix path to compute-matrix script.
jrhemstad Jul 18, 2023
be00cb2
debug
jrhemstad Jul 18, 2023
18debe3
debug.
jrhemstad Jul 18, 2023
677b8fc
debug.
jrhemstad Jul 18, 2023
ee821cc
lol, use hyphen not underscore.
jrhemstad Jul 18, 2023
597cbc2
Get absolute path for matrix file.
jrhemstad Jul 18, 2023
ba3af68
Fix reference to matrix_file var.
jrhemstad Jul 18, 2023
fdf757b
Remove extraneous matrix_query
jrhemstad Jul 18, 2023
42c4f6f
Use composite action instead of reusable workflow for matrix.
jrhemstad Jul 18, 2023
2cb5703
Fix quotes around composite action inputs.
jrhemstad Jul 18, 2023
c61c78f
Need to checkout repo to get local composite action.
jrhemstad Jul 18, 2023
52de697
Fix quotes.
jrhemstad Jul 18, 2023
ed72001
Add shell to composite action.
jrhemstad Jul 18, 2023
a6df874
Specify shell in step.
jrhemstad Jul 18, 2023
661935f
Correctly use inputs for composite action.
jrhemstad Jul 18, 2023
7205c23
debug
jrhemstad Jul 18, 2023
c098fed
Fix expansion.
jrhemstad Jul 18, 2023
214537d
Remove debug.
jrhemstad Jul 18, 2023
95dfcc9
Remove debug.
jrhemstad Jul 18, 2023
189645c
Fix indention.
alliepiper Jul 19, 2023
64a476f
Add CCCL::CCCL, CCCL::libcudacxx, CCCL::CUB, and CCCL::Thrust targets.
alliepiper Jul 19, 2023
5d420e8
Merge remote-tracking branch 'origin' into example-cmake-project
jrhemstad Jul 19, 2023
b1ad055
Merge branch 'new_cccl_cmake_targets' into example-cmake-project
jrhemstad Jul 19, 2023
aae51ad
(Not working) Update to use new targets.
jrhemstad Jul 19, 2023
4b4efc0
Make CPM point to the PR branch instead.
jrhemstad Jul 19, 2023
bcaef1d
Escape quotes in jq query string.
jrhemstad Jul 19, 2023
9822778
Use underscore instead of hyphen to avoid needing quotes in query.
jrhemstad Jul 19, 2023
c194bfd
Use alternative syntax for jq query.
jrhemstad Jul 19, 2023
8d09b5c
Missing quote.
jrhemstad Jul 19, 2023
27f0e79
Add post processing to set nvcc-specific matrix outputs.
jrhemstad Jul 19, 2023
b7e0fa6
Quotes around matrix output.
jrhemstad Jul 19, 2023
100bdb7
Single quotes.
jrhemstad Jul 19, 2023
2a36423
Make CCCL::CCCL target GLOBAL.
Jul 19, 2023
4cd2f80
Remove old compute-matrix reusable workflow.
jrhemstad Jul 19, 2023
1cd1581
Fix usage message.
jrhemstad Jul 19, 2023
e32fce7
Update devcontainer script to reference nvcc field.
jrhemstad Jul 19, 2023
705207c
Removed unused GITHUB_OUTPUT var.
jrhemstad Jul 19, 2023
468bab7
EOF
jrhemstad Jul 19, 2023
dda1646
Fix quotes.
jrhemstad Jul 20, 2023
0aed220
Add more complete example file.
jrhemstad Jul 20, 2023
4a25011
Add top level cmake file for building/running all the examples.
jrhemstad Jul 20, 2023
8d8aa2a
Merge branch 'example-cmake-project' into examples-job
jrhemstad Jul 20, 2023
39e1287
Enable examples to run via CI.
alliepiper Jul 24, 2023
d333ffe
Add missing newlines.
alliepiper Jul 24, 2023
3850f15
Enable overriding CPM source for CI.
jrhemstad Jul 26, 2023
0451167
Add top level job for running examples.
jrhemstad Jul 26, 2023
347d55a
Add devcontainer_version field to matrix file.
jrhemstad Jul 26, 2023
f7aa4ea
Update make_devcontainers script to read devcontainer_version.
jrhemstad Jul 26, 2023
f29bcb7
Add job to get devcontainer_version and pass to dependent jobs.
jrhemstad Jul 26, 2023
a4d19a6
Add and use input for devcontainer_version.
jrhemstad Jul 26, 2023
9075ea1
Avoid unnecessarily using compute-matrix action.
jrhemstad Jul 26, 2023
ee65f91
Use yaml alias/anchor for cuda versions.
jrhemstad Jul 26, 2023
9919681
[skip tests] Update devcontainer version job name.
jrhemstad Jul 26, 2023
1d085dc
Update to CUDA 12.2 and devcontainer 23.08.
jrhemstad Jul 26, 2023
2ee384c
Update devcontainer.json image versions and update to CUDA 12.2.
jrhemstad Jul 26, 2023
1484da0
Add more docs.
jrhemstad Jul 27, 2023
1a20d54
Merge branch 'main' into update-devcontainer-version
jrhemstad Jul 27, 2023
7d1d86f
Merge branch 'example-cmake-project' into examples-job
jrhemstad Jul 27, 2023
d054fe6
Merge branch 'main' into example-cmake-project
jrhemstad Jul 27, 2023
19a6ddb
Merge branch 'example-cmake-project' into examples-job
jrhemstad Jul 27, 2023
fbd9317
Merge branch 'update-devcontainer-version' into examples-job
jrhemstad Jul 27, 2023
67492f4
Mark the CCCL::Thrust options as advanced.
alliepiper Aug 3, 2023
55790dc
Guard against rebuilding pre-existing targets.
alliepiper Aug 3, 2023
1dec47f
Make the imported `CCCL::CCCL` target global in our CMake package.
alliepiper Aug 3, 2023
5ff3be0
Merge branch 'new_cccl_cmake_targets' into example-cmake-project
jrhemstad Aug 3, 2023
7313db4
Include cmake/CCCLUtilities
jrhemstad Aug 3, 2023
ce955dc
Don't use magic number.
jrhemstad Aug 7, 2023
0f1486d
Merge branch 'main' into example-cmake-project
jrhemstad Aug 7, 2023
aa20ba1
Update CPM to point to cccl/main.
jrhemstad Aug 7, 2023
24919f3
Update README.
jrhemstad Aug 7, 2023
b579747
Add some more comments to the cmakelists.txt.
jrhemstad Aug 7, 2023
03fa106
Update examples/README
jrhemstad Aug 7, 2023
ee32c9a
Merge branch 'examples-job' into example-cmake-project
jrhemstad Aug 7, 2023
1ee5f31
Get devcontainer version from prior job.
jrhemstad Aug 7, 2023
35f562b
Hard code example job to only build/run example_project.
jrhemstad Aug 7, 2023
b1d71c8
Set error handling options in run-as-coder shell.
jrhemstad Aug 7, 2023
c493a73
Add license.
jrhemstad Aug 7, 2023
e13cc7e
Fix spacing.
jrhemstad Aug 7, 2023
6b4fcfd
Add license headers.
jrhemstad Aug 7, 2023
4542b0e
[skip-tests]
jrhemstad Aug 7, 2023
3e7b7f5
Remove accidental submodule?
jrhemstad Aug 7, 2023
58fc9c2
Split cccl tests from examples in naming schemes.
alliepiper Aug 8, 2023
60ddebf
Remove unnecessary include.
alliepiper Aug 8, 2023
bd0425f
Add options to allow configuration of example CPM repo.
alliepiper Aug 8, 2023
a629a33
Add CMakePresets.txt.json with recipe for testing examples.
alliepiper Aug 8, 2023
33ef7b0
Update PR workflow to run examples using presets and new options.
alliepiper Aug 8, 2023
0e51c5d
Specify the CUDA compiler for the example config step.
alliepiper Aug 8, 2023
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
21 changes: 21 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
name: Compute NVCC matrix
runs-on: ubuntu-latest
outputs:
FULL_MATRIX: ${{ steps.set-outputs.outputs.FULL_MATRIX }}
CUDA_VERSIONS: ${{ steps.set-outputs.outputs.CUDA_VERSIONS }}
HOST_COMPILERS: ${{ steps.set-outputs.outputs.HOST_COMPILERS }}
PER_CUDA_COMPILER_MATRIX: ${{ steps.set-outputs.outputs.PER_CUDA_COMPILER_MATRIX }}
Expand All @@ -53,6 +54,7 @@ jobs:
id: set-outputs
run: |
FULL_MATRIX='${{steps.compute-nvcc-matrix.outputs.matrix}}'
echo "FULL_MATRIX=$FULL_MATRIX" | tee -a "$GITHUB_OUTPUT"
CUDA_VERSIONS=$(echo $FULL_MATRIX | jq -c '[.[] | .cuda] | unique')
echo "CUDA_VERSIONS=$CUDA_VERSIONS" | tee -a "$GITHUB_OUTPUT"
HOST_COMPILERS=$(echo $FULL_MATRIX | jq -c '[.[] | .compiler.name] | unique')
Expand Down Expand Up @@ -104,6 +106,24 @@ jobs:
build_script: "./ci/build_libcudacxx.sh"
test_script: "./ci/test_libcudacxx.sh"
devcontainer_version: ${{ needs.get-devcontainer-version.outputs.DEVCONTAINER_VERSION }}

examples:
name: CCCL Examples
needs: [compute-nvcc-matrix, get-devcontainer-version]
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.compute-nvcc-matrix.outputs.FULL_MATRIX) }}
uses: ./.github/workflows/run-as-coder.yml
with:
name: CCCL Examples CUDA${{matrix.cuda}} ${{matrix.compiler.name}}${{matrix.compiler.version}}
runner: linux-${{matrix.cpu}}-gpu-v100-latest-1
image: rapidsai/devcontainers:${{needs.get-devcontainer-version.outputs.DEVCONTAINER_VERSION}}-cpp-${{matrix.compiler.name}}${{matrix.compiler.version}}-cuda${{matrix.cuda}}-${{matrix.os}}
command: |
cd examples/example_project
cmake -S . -B build -DCCCL_TAG="$GITHUB_SHA"
cmake --build build/
ctest --test-dir build/ --output-on-failure

# This job is the final job that runs after all other jobs and is used for branch protection status checks.
# See: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks
Expand All @@ -114,5 +134,6 @@ jobs:
- libcudacxx
- cub
- thrust
- examples
steps:
- run: echo "CI success"
1 change: 1 addition & 0 deletions .github/workflows/run-as-coder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
- name: Run command
shell: su coder {0}
run: |
set -exo pipefail
cd ~/cccl
eval "${{inputs.command}}" || exit_code=$?
if [ ! -z "$exit_code" ]; then
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,13 @@ option(CCCL_ENABLE_LIBCUDACXX "Enable the libcu++ developer build." ON)
option(CCCL_ENABLE_CUB "Enable the CUB developer build." ON)
option(CCCL_ENABLE_THRUST "Enable the Thrust developer build." ON)
option(CCCL_ENABLE_TESTING "Enable CUDA C++ Core Library tests." ON)
option(CCCL_ENABLE_EXAMPLES "Enable CUDA C++ Core Library examples." ON)

include(CTest)
enable_testing()

include(cmake/CCCLUtilities.cmake)

if (CCCL_ENABLE_LIBCUDACXX)
set(LIBCUDACXX_TOPLEVEL_PROJECT ON)
endif()
Expand All @@ -52,3 +55,7 @@ add_subdirectory(thrust)
if (CCCL_ENABLE_TESTING)
add_subdirectory(test)
endif()

if (CCCL_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()
20 changes: 20 additions & 0 deletions cmake/CCCLUtilities.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Add a build-and-test CTest.
# - full_test_name_var will be set to the full name of the test.
# - subdir is the relative path to the test project directory.
# - test_id is used to generate a unique name for this test, allowing the
# subdir to be reused.
# - Any additional args will be passed to the project configure step.
function(cccl_add_compile_test full_test_name_var subdir test_id)
set(test_name cccl.test.cmake.${subdir}.${test_id})
set(src_dir "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
set(build_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}/${test_id}")
add_test(NAME ${test_name}
COMMAND "${CMAKE_CTEST_COMMAND}"
--build-and-test "${src_dir}" "${build_dir}"
--build-generator "${CMAKE_GENERATOR}"
--build-options
${ARGN}
--test-command "${CMAKE_CTEST_COMMAND}" --output-on-failure
)
set(${full_test_name_var} ${test_name} PARENT_SCOPE)
endfunction()
17 changes: 17 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

include(../cmake/CCCLUtilities.cmake)

set(cmake_opts
-D "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
-D "CMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
-D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
-D "CMAKE_CUDA_COMPILER=${CMAKE_CUDA_COMPILER}"
-D "CMAKE_CUDA_HOST_COMPILER=${CMAKE_CUDA_HOST_COMPILER}"
-D "CMAKE_CUDA_ARCHITECTURES=${CMAKE_CUDA_ARCHITECTURES}"
)

cccl_add_compile_test(test_name
example_project
"default"
${cmake_opts}
)
12 changes: 12 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

This directory contains examples of how to use CCCL in your project.

See the `README.md` in each subdirectory for more information.

To build and run only the examples, run the following commands from the root directory of the repository:

```bash
cmake -S . -B build -DCCCL_ENABLE_EXAMPLES=ON -DCCCL_ENABLE_THRUST=OFF -DCCCL_ENABLE_CUB=OFF -DCCCL_ENABLE_LIBCUDACXX=OFF -DCCCL_ENABLE_TESTING=OFF
cmake --build build
ctest --test-dir build --output-on-failure
```
37 changes: 37 additions & 0 deletions examples/example_project/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(CCCLDemo CUDA)

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


# We define these as variables so they can be overriden in CI to pull from a PR instead of CCCL `main`
# In your project, these variables are unncessary and you can just use the values directly
set(CCCL_REPOSITORY "nvidia/cccl" CACHE STRING "GitHub repository to fetch CCCL from")
set(CCCL_TAG "main" CACHE STRING "Git tag/branch to fetch from CCCL repository")

# This will automatically clone CCCL from GitHub and make the exported cmake targets available
CPMAddPackage(
NAME CCCL
GITHUB_REPOSITORY ${CCCL_REPOSITORY}
GIT_TAG ${CCCL_TAG}
)

# Default to building for the GPU on the current system
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES native)
endif()

# Creates a cmake executable target for the main program
add_executable(example_project example.cu)

# "Links" the CCCL Cmake target to the `example_project` executable. This configures everything needed to use
# CCCL headers, including setting up include paths, compiler flags, etc.
target_link_libraries(example_project PRIVATE CCCL::CCCL)

# This is only relevant for internal testing and not needed by end users.
include(CTest)
enable_testing()
add_test(NAME example_project COMMAND example_project)
143 changes: 143 additions & 0 deletions examples/example_project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@

# Example Project Using CCCL From GitHub

Many CUDA C++ users are accustomed to using CCCL headers (Thrust, CUB, libcu++) provided with the [NVIDIA CUDA Toolkit](https://developer.nvidia.com/cuda-toolkit) or [NVIDIA HPC SDK](https://developer.nvidia.com/hpc-sdk).

In addition, we also support using CCCL directly from GitHub.
The primary benefit is that this allows users to use the latest version of CCCL without having to wait for a new release of the CUDA Toolkit or HPC SDK.

This example demonstrates how to use CCCL from GitHub in a CMake project.

## Overview

This is a standalone example of how to use [CCCL](https://github.com/nvidia/cccl) in a CMake project.

This example demonstrates fetching CCCL from GitHub and linking it with a simple example CUDA program ([`example.cu`](example.cu)) that utilizes the headers from CCCL.

This is intended to be a starting point for users who want to use CCCL in their own projects.

## How to Adapt This Example to Your Project

This example is intended to be a starting point for users who want to use CCCL in their own projects.
In order to adapt this example to your project, you will need to do the following:
1. Download `CPM.cmake` into your project's `cmake/` directory ([see below for instructions](#downloading-cpm)).
2. Add the following lines to your project's `CMakeLists.txt` file:
```cmake
include(cmake/CPM.cmake)

# This will automatically clone CCCL from GitHub and make the exported cmake targets available
CPMAddPackage(
NAME CCCL
GITHUB_REPOSITORY nvidia/cccl
GIT_TAG main # Fetches the latest commit on the main branch
)

# If you're building an executable
add_executable(your_executable your_file.cu)
target_link_libraries(your_executable PRIVATE CCCL::CCCL)

# Alternatively, if you're building a library
add_library(your_library your_file.cu)
target_link_libraries(your_library PRIVATE CCCL::CCCL)
```
See the [CMakeLists.txt](CMakeLists.txt) file in this directory for a complete example.
3. Configure and build your project as normal and verify that it builds successfully.

For more information on using CPM, see [below](#using-cmake-package-manager).

## Using CMake Package Manager

This example uses the CMake Package Manager (CPM) to fetch CCCL from GitHub.

See the [CMakeLists.txt](CMakeLists.txt) file in this directory for the complete example.

If you are not familiar with CPM, you can find more information [here](https://github.com/cpm-cmake/CPM.cmake).
In short, CPM is a CMake module that simplifies dependency management for CMake projects.
It automatically downloads and integrates dependencies into your CMake project.

### Downloading CPM

In order to get the latest version of CPM.cmake, you can run the following command in the root directory of your project:

```bash
mkdir -p cmake
wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake
```

This will download and create the file `cmake/CPM.cmake` in your project directory.
Most projects will want to commit this file to their source control system.
You can then use `include(cmake/CPM.cmake)` in your project's `CMakeLists.txt` file to include CPM in your project.

Alternatively, you can add the following logic to your `CMakeLists.txt` to download CPM if it is not already present in your project directory.

```cmake
set(CPM_DOWNLOAD_VERSION 0.34.0)

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})
```

## Building and Running the Example

Most people will want to adapt this example to their own project as described [above](#how-to-adapt-this-example-to-your-project). If you would like to build and run this example as-is, you will need to follow the instructions below.

### Prerequisites

If you would like to build and run this example as-is, you will need:

- A CUDA-capable GPU
- NVIDIA CUDA Toolkit (11.1 or later)
- CMake (3.14 or later)
- A C++14 standard-compliant compiler
- git

### Instructions

1. Clone this repository to your local machine.
```bash
git clone https://github.com/NVIDIA/cccl.git
```

2. Enter the directory of the cloned repository.
```bash
cd cccl/examples/example_project
```

3. Run the CMake configure step
```bash
cmake -S . -B build
```
Alternatively,
```bash
mkdir -p build
cd build
cmake ..
```
4. Run the CMake build step.
```bash
cmake --build .
```

6. Run the executable.
```bash
./build/example_project
```

If everything is configured correctly, the program will execute and print the sum of an array of integers, demonstrating the use of cccl.


33 changes: 33 additions & 0 deletions examples/example_project/cmake/CPM.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
set(CPM_DOWNLOAD_VERSION 0.38.1)

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()

# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)

function(download_cpm)
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION}
)
endfunction()

if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
download_cpm()
else()
# resume download if it previously failed
file(READ ${CPM_DOWNLOAD_LOCATION} check)
if("${check}" STREQUAL "")
download_cpm()
endif()
unset(check)
endif()

include(${CPM_DOWNLOAD_LOCATION})
Loading
Loading