Skip to content

Commit

Permalink
CUDA vector_add sample project (#2160)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: pciolkosz <[email protected]>
Co-authored-by: Michael Schellenberger Costa <[email protected]>
  • Loading branch information
3 people committed Aug 9, 2024
1 parent 7473934 commit a3a5f9c
Show file tree
Hide file tree
Showing 11 changed files with 589 additions and 6 deletions.
13 changes: 12 additions & 1 deletion cudax/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ if (cudax_TOPLEVEL_PROJECT)
cmake_minimum_required(VERSION 3.21)
endif()

project(cudax LANGUAGES CUDA)
project(cudax LANGUAGES CUDA CXX)

option(cudax_ENABLE_INSTALL_RULES "Enable installation of CUDA Experimental." ${cudax_TOPLEVEL_PROJECT})
if (cudax_ENABLE_INSTALL_RULES)
Expand All @@ -25,6 +25,7 @@ endif()

option(cudax_ENABLE_HEADER_TESTING "Test that CUDA Experimental's public headers compile." ON)
option(cudax_ENABLE_TESTING "Build CUDA Experimental's tests." ON)
option(cudax_ENABLE_SAMPLES "Build CUDA Experimental's samples." ON)

include(cmake/cudaxBuildCompilerTargets.cmake)
include(cmake/cudaxBuildTargetList.cmake)
Expand All @@ -41,3 +42,13 @@ if (cudax_ENABLE_TESTING)
enable_testing() # Must be in root directory
add_subdirectory(test)
endif()

if (cudax_ENABLE_SAMPLES)
include(ExternalProject)
ExternalProject_Add(cudax_samples
PREFIX samples
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/samples"
BUILD_ALWAYS ON
INSTALL_COMMAND cmake -E echo "Skipping install step.")
add_dependencies(cudax.all cudax_samples)
endif()
2 changes: 1 addition & 1 deletion cudax/cmake/cudaxBuildCompilerTargets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
include("${cudax_SOURCE_DIR}/cmake/AppendOptionIfAvailable.cmake")

function(cudax_build_compiler_targets)
set(cxx_compile_definitions)
set(cxx_compile_definitions LIBCUDACXX_ENABLE_EXCEPTIONS)
set(cxx_compile_options)
set(cuda_compile_options)

Expand Down
1 change: 1 addition & 0 deletions cudax/cmake/cudaxBuildTargetList.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ function(cudax_build_target_list)
file(GLOB_RECURSE all_sources
RELATIVE "${CMAKE_CURRENT_LIST_DIR}"
"${cudax_SOURCE_DIR}/include/cuda/experimental/*.hpp"
"${cudax_SOURCE_DIR}/include/cuda/experimental/*.cuh"
)
add_custom_target(cudax.all SOURCES ${all_sources})

Expand Down
19 changes: 15 additions & 4 deletions cudax/include/cuda/experimental/__detail/utility.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,31 @@ namespace cuda::experimental
{
namespace detail
{
struct __ignore
// This is a helper type that can be used to ignore function arguments.
struct [[maybe_unused]] __ignore
{
template <typename... Args>
_CCCL_HOST_DEVICE constexpr __ignore(Args&&...) noexcept
__ignore() = default;

template <typename _Arg>
_CCCL_HOST_DEVICE constexpr __ignore(_Arg&&) noexcept
{}
};

// Classes can inherit from this type to become immovable.
struct __immovable
{
__immovable() = default;
__immovable(__immovable&&) = delete;
__immovable& operator=(__immovable&&) = delete;
};
} // namespace detail

struct uninit_t
{
explicit uninit_t() = default;
};

inline constexpr uninit_t uninit{};
_CCCL_GLOBAL_CONSTANT uninit_t uninit{};
} // namespace cuda::experimental

#endif // __CUDAX_DETAIL_UTILITY_H
85 changes: 85 additions & 0 deletions cudax/include/cuda/experimental/__launch/param_kind.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

#ifndef _CUDAX__LAUNCH_PARAM_KIND
#define _CUDAX__LAUNCH_PARAM_KIND

#include <cuda/__cccl_config>

#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
# pragma GCC system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
# pragma clang system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
# pragma system_header
#endif // no system header

#include <cuda/std/__type_traits/maybe_const.h>

#include <cuda/experimental/__detail/utility.cuh>

namespace cuda::experimental
{
namespace detail
{
enum class __param_kind : unsigned
{
_in = 1,
_out = 2,
_inout = 3
};

_CCCL_NODISCARD _CCCL_HOST_DEVICE inline constexpr __param_kind operator&(__param_kind __a, __param_kind __b) noexcept
{
return __param_kind(unsigned(__a) & unsigned(__b));
}

template <typename _Ty, __param_kind _Kind>
struct _CCCL_NODISCARD __box
{
::cuda::std::__maybe_const<_Kind == __param_kind::_in, _Ty>& __val;
};

struct __in_t
{
template <class _Ty>
__box<_Ty, __param_kind::_in> operator()(const _Ty& __v) const noexcept
{
return {__v};
}
};

struct __out_t
{
template <class _Ty>
__box<_Ty, __param_kind::_out> operator()(_Ty& __v) const noexcept
{
return {__v};
}
};

struct __inout_t
{
template <class _Ty>
__box<_Ty, __param_kind::_inout> operator()(_Ty& __v) const noexcept
{
return {__v};
}
};

} // namespace detail

_CCCL_GLOBAL_CONSTANT detail::__in_t in{};
_CCCL_GLOBAL_CONSTANT detail::__out_t out{};
_CCCL_GLOBAL_CONSTANT detail::__inout_t inout{};

} // namespace cuda::experimental

#endif // _CUDAX__LAUNCH_PARAM_KIND
3 changes: 3 additions & 0 deletions cudax/include/cuda/experimental/launch.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#ifndef __CUDAX_LAUNCH___
#define __CUDAX_LAUNCH___

#include <cuda/experimental/__launch/configuration.cuh>
#include <cuda/experimental/__launch/launch.cuh>
#include <cuda/experimental/__launch/launch_transform.cuh>
#include <cuda/experimental/__launch/param_kind.cuh>

#endif // __CUDAX_LAUNCH___
76 changes: 76 additions & 0 deletions cudax/samples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# 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.

cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(CUDAX_SAMPLES CUDA CXX)

# 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}
GIT_SHALLOW ON
OPTIONS "CCCL_ENABLE_UNSTABLE ON"
)

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

# Creates a cmake executable target for the main program
add_executable(vector_add vector_add/vector_add.cu)

# "Links" the CCCL::cudax CMake target to the `vector_add` executable. This
# configures everything needed to use CCCL's headers, including setting up
# include paths, compiler flags, etc.
target_link_libraries(vector_add
PUBLIC
CCCL::cudax
CCCL::CCCL
CCCL::Thrust
CCCL::libcudacxx
INTERFACE cudax.compiler_interface
)

# TODO: These are temporary until the main branch catches up with the latest changes
target_compile_definitions(vector_add PUBLIC LIBCUDACXX_ENABLE_EXCEPTIONS)

if ("MSVC" STREQUAL "${CMAKE_CXX_COMPILER_ID}")
# mdspan on windows only works in C++20 mode
target_compile_features(vector_add PUBLIC cxx_std_20)

# cudax requires dim3 to be usable from a constexpr context, and the CUDART headers require
# __cplusplus to be defined for this to work:
target_compile_options(vector_add PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus /Zc:preprocessor>
$<$<COMPILE_LANG_AND_ID:CUDA,NVIDIA>:-Xcompiler=/Zc:__cplusplus -Xcompiler=/Zc:preprocessor>
)
endif()

# This is only relevant for internal testing and not needed by end users.
include(CTest)
enable_testing()
add_test(NAME vector_add COMMAND vector_add)
33 changes: 33 additions & 0 deletions cudax/samples/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})
85 changes: 85 additions & 0 deletions cudax/samples/vector_add/param_kind.cuh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===----------------------------------------------------------------------===//
//
// Part of CUDA Experimental in CUDA C++ Core Libraries,
// under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
//
//===----------------------------------------------------------------------===//

#ifndef _CUDAX__LAUNCH_PARAM_KIND
#define _CUDAX__LAUNCH_PARAM_KIND

#include <cuda/__cccl_config>

#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
# pragma GCC system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
# pragma clang system_header
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
# pragma system_header
#endif // no system header

#include <cuda/std/__type_traits/maybe_const.h>

#include <cuda/experimental/__detail/utility.cuh>

namespace cuda::experimental
{
namespace detail
{
enum class __param_kind : unsigned
{
_in = 1,
_out = 2,
_inout = 3
};

_CCCL_NODISCARD _CCCL_HOST_DEVICE inline constexpr __param_kind operator&(__param_kind __a, __param_kind __b) noexcept
{
return __param_kind(unsigned(__a) & unsigned(__b));
}

template <typename _Ty, __param_kind _Kind>
struct _CCCL_NODISCARD __box
{
::cuda::std::__maybe_const<_Kind == __param_kind::_in, _Ty>& __val;
};

struct __in_t
{
template <class _Ty>
__box<_Ty, __param_kind::_in> operator()(const _Ty& __v) const noexcept
{
return {__v};
}
};

struct __out_t
{
template <class _Ty>
__box<_Ty, __param_kind::_out> operator()(_Ty& __v) const noexcept
{
return {__v};
}
};

struct __inout_t
{
template <class _Ty>
__box<_Ty, __param_kind::_inout> operator()(_Ty& __v) const noexcept
{
return {__v};
}
};

} // namespace detail

_CCCL_GLOBAL_CONSTANT detail::__in_t in{};
_CCCL_GLOBAL_CONSTANT detail::__out_t out{};
_CCCL_GLOBAL_CONSTANT detail::__inout_t inout{};

} // namespace cuda::experimental

#endif // _CUDAX__LAUNCH_PARAM_KIND
Loading

0 comments on commit a3a5f9c

Please sign in to comment.