Skip to content

Commit

Permalink
Iniital monorepo setup.
Browse files Browse the repository at this point in the history
  • Loading branch information
Allison Vacanti authored and alliepiper committed May 16, 2023
1 parent 7b03706 commit 5c84765
Show file tree
Hide file tree
Showing 14 changed files with 402 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea/
*build*/
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "libcudacxx"]
path = libcudacxx
url = ../libcudacxx.git
[submodule "cub"]
path = cub
url = ../cub
[submodule "thrust"]
path = thrust
url = ../thrust
55 changes: 55 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 3.15 is the minimum for including the project with add_subdirectory.
# 3.21 is the minimum for the developer build.
cmake_minimum_required(VERSION 3.15)

# Determine whether CCCL is the top-level project or included into
# another project via add_subdirectory()
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_LIST_DIR}")
set(CCCL_TOPLEVEL_PROJECT ON)
else()
set(CCCL_TOPLEVEL_PROJECT OFF)
endif()

# TODO find_package for add_subdir usecases, use components for subprojects.

project(CCCL NONE)

# Optionally include installation rules for non-top-level builds:
option(CCCL_ENABLE_INSTALL_RULES "Enable installation of CCCL." ${CCCL_TOPLEVEL_PROJECT})
if (CCCL_ENABLE_INSTALL_RULES)
include(cmake/CCCLInstallRules.cmake)
endif()

# Support adding Thrust to a parent project via add_subdirectory.
# See examples/cmake/add_subdir/CMakeLists.txt for details.
if (NOT CCCL_TOPLEVEL_PROJECT)
include(cmake/CCCLAddSubdir.cmake)
return()
endif()

# We require a higher cmake version for dev builds
cmake_minimum_required(VERSION 3.21)

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)

include(CTest)
enable_testing()

if (CCCL_ENABLE_LIBCUDACXX)
add_subdirectory(libcudacxx)
endif()

if (CCCL_ENABLE_CUB)
add_subdirectory(cub)
endif()

if (CCCL_ENABLE_THRUST)
add_subdirectory(thrust)
endif()

if (CCCL_ENABLE_TESTING)
add_subdirectory(test)
endif()
6 changes: 6 additions & 0 deletions cmake/CCCLAddSubdir.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
find_package(CCCL REQUIRED CONFIG
NO_DEFAULT_PATH # Only check the explicit path in HINTS:
HINTS "${CCCL_SOURCE_DIR}"
COMPONENTS ${CCCL_REQUIRED_COMPONENTS}
OPTIONAL_COMPONENTS ${CCCL_OPTIONAL_COMPONENTS}
)
10 changes: 10 additions & 0 deletions cmake/CCCLInstallRules.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Bring in CMAKE_INSTALL_LIBDIR
include(GNUInstallDirs)

# CCCL has no installable binaries, no need to build before installing:
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY TRUE)

install(DIRECTORY "${CCCL_SOURCE_DIR}/share/cmake/cccl"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/"
PATTERN *.cmake.in EXCLUDE
)
1 change: 1 addition & 0 deletions cub
Submodule cub added at d46f51
1 change: 1 addition & 0 deletions libcudacxx
Submodule libcudacxx added at ab5a25
13 changes: 13 additions & 0 deletions share/cmake/cccl/cccl-config-version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# TODO we should parse this from a header, and update to CalVer if that's still POR
set(CCCL_VERSION_MAJOR 2)
set(CCCL_VERSION_MINOR 1)
set(CCCL_VERSION_PATCH 0)
set(CCCL_VERSION_TWEAK 0)

set(CCCL_VERSION "${CCCL_VERSION_MAJOR}.${CCCL_VERSION_MINOR}.${CCCL_VERSION_PATCH}.${CCCL_VERSION_TWEAK}")

# TODO decide and implement versioning logic.
set(PACKAGE_VERSION ${CCCL_VERSION})
set(PACKAGE_VERSION_COMPATIBLE TRUE)
set(PACKAGE_VERSION_EXACT TRUE)
set(PACKAGE_VERSION_UNSUITABLE FALSE)
59 changes: 59 additions & 0 deletions share/cmake/cccl/cccl-config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# find_package(CCCL) config file.
#
# Imports the Thrust, CUB, and libcudacxx components of the NVIDIA
# CUDA/C++ Core Libraries.

unset(cccl_version) # TODO

set(cccl_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")

if (${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY)
set(cccl_quiet_flag "QUIET")
else()
set(cccl_quiet_flag "")
endif()

foreach(component ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS})
unset(req)
if (${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED_${component})
set(cccl_comp_required_flag "REQUIRED")
endif()

if(component STREQUAL "libcudacxx")
find_package(libcudacxx ${cccl_version} CONFIG
${cccl_quiet_flag}
${cccl_comp_required_flag}
NO_DEFAULT_PATH # Only check the explicit HINTS below:
HINTS
"${cccl_cmake_dir}/../../../libcudacxx/lib/cmake/" # Source layout (GitHub)
"${cccl_cmake_dir}/.." # Install layout
)
elseif(component STREQUAL "CUB")
find_package(CUB ${cccl_version} CONFIG
${cccl_quiet_flag}
${cccl_comp_required_flag}
NO_DEFAULT_PATH # Only check the explicit HINTS below:
HINTS
"${cccl_cmake_dir}/../../../cub/cub/cmake/" # Source layout (GitHub)
"${cccl_cmake_dir}/.." # Install layout
)
elseif(component STREQUAL "Thrust")
find_package(Thrust ${cccl_version} CONFIG
${cccl_quiet_flag}
${cccl_comp_required_flag}
NO_DEFAULT_PATH # Only check the explicit HINTS below:
HINTS
"${cccl_cmake_dir}/../../../thrust/thrust/cmake/" # Source layout (GitHub)
"${cccl_cmake_dir}/.." # Install layout
)
else()
message(FATAL_ERROR "Invalid CCCL component requested: '${component}'")
endif()
endforeach()

include(FindPackageHandleStandardArgs)
if (NOT CCCL_CONFIG)
set(CCCL_CONFIG "${CMAKE_CURRENT_LIST_FILE}")
endif()
find_package_handle_standard_args(CCCL CONFIG_MODE)
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(cmake)
81 changes: 81 additions & 0 deletions test/cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
set(cmake_opts
-D "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
-D "CMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
-D "CMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
)

# Temporary installation prefix for tests against installed project:
set(tmp_install_prefix "${CMAKE_CURRENT_BINARY_DIR}/test_install")

# 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
${cmake_opts}
${ARGN}
--test-command "${CMAKE_CTEST_COMMAND}" --output-on-failure
)
set(${full_test_name_var} ${test_name} PARENT_SCOPE)
endfunction()

foreach (root_type IN ITEMS SOURCE INSTALL)
if (root_type STREQUAL "INSTALL")
set(cccl_root "${tmp_install_prefix}")
else()
set(cccl_root "${CCCL_SOURCE_DIR}")
endif()

foreach (components IN ITEMS DEFAULT Thrust CUB libcudacxx)
set(package_types CCCL)
if (NOT components STREQUAL "DEFAULT")
list(APPEND package_types NATIVE)
endif()
if (root_type STREQUAL "SOURCE")
list(APPEND package_types SUBDIR)
endif()
foreach (package_type IN LISTS package_types)
string(TOLOWER "${root_type}.${package_type}.${components}" suffix)
cccl_add_compile_test(test_name
test_export
"${suffix}"
-D "CCCL_ROOT=${cccl_root}"
-D "ROOT_TYPE=${root_type}"
-D "COMPONENTS=${components}"
-D "PACKAGE_TYPE=${package_type}"
)

if (root_type STREQUAL "INSTALL")
set_tests_properties(${test_name} PROPERTIES FIXTURES_REQUIRED install_tree)
endif()
endforeach() # package_type
endforeach() # components
endforeach() # root_type

################################################################################
# Install tree fixtures
add_test(NAME cccl.test.cmake.install_tree.install
COMMAND "${CMAKE_COMMAND}"
--install "${CCCL_BINARY_DIR}"
--prefix "${tmp_install_prefix}"
)
set_tests_properties(cccl.test.cmake.install_tree.install PROPERTIES
FIXTURES_SETUP install_tree
)

add_test(NAME cccl.test.cmake.install_tree.cleanup
COMMAND "${CMAKE_COMMAND}" -E rm -rf "${tmp_install_prefix}"
)
set_tests_properties(cccl.test.cmake.install_tree.cleanup PROPERTIES
FIXTURES_CLEANUP install_tree
)
143 changes: 143 additions & 0 deletions test/cmake/test_export/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# Test the CMake packages for CCCL and all subprojects.
#
# Parameters:
# - CCCL_ROOT [Path] Root of the CCCL repo, or an installation root.
# - ROOT_TYPE [String] {SOURCE | INSTALL} Whether CCCL_ROOT is an
# installation prefix or the source root.
# - COMPONENTS [StringList] {Thrust CUB libcudacxx} Which CCCL subprojects
# should be found.
# - PACKAGE_TYPE [String] {CCCL | NATIVE | SUBDIR}:
# - CCCL -> `find_package(CCCL COMPONENTS <subproject>)`
# - NATIVE -> `find_package(<subproject>)`
# - SUBDIR -> `set(CCCL_REQUIRED_COMPONENTS <subproject>)`
# `add_subdirectory(${cccl_root})`


cmake_minimum_required(VERSION 3.21)
project(CCCLTestExport CXX)

include(CTest)
enable_testing()

set(CCCL_ROOT "" CACHE PATH
"Root of the CCCL repo, or an installation root.")
set(ROOT_TYPE "" CACHE STRING
"{SOURCE | INSTALL} Whether CCCL_ROOT is an install prefix or source root.")
set_property(CACHE ROOT_TYPE PROPERTY STRINGS SOURCE INSTALL)
set(COMPONENTS "" CACHE STRING
"DEFAULT for no components, or semi-colon delimited list of Thrust, CUB, and/or libcudacxx.")
set(PACKAGE_TYPE "" CACHE STRING
"CCCL: Find CCCL with subpackages as components; NATIVE: Find subpackages directly; SUBDIR: add_subdirectory(${CCCL_ROOT}")
set_property(CACHE PACKAGE_TYPE PROPERTY STRINGS CCCL NATIVE SUBDIR)

message(STATUS "CCCL_ROOT=${CCCL_ROOT}")
message(STATUS "ROOT_TYPE=${ROOT_TYPE}")
message(STATUS "COMPONENTS=${COMPONENTS}")
message(STATUS "PACKAGE_TYPE=${PACKAGE_TYPE}")

# TODO `ROOT_TYPE` probably won't be needed after the configs are all moved
# to the CCCL repo.
if (ROOT_TYPE STREQUAL "SOURCE")
cmake_path(APPEND CCCL_ROOT thrust OUTPUT_VARIABLE Thrust_ROOT)
cmake_path(APPEND CCCL_ROOT cub OUTPUT_VARIABLE CUB_ROOT)
cmake_path(APPEND CCCL_ROOT libcudacxx OUTPUT_VARIABLE libcudacxx_ROOT)
elseif (ROOT_TYPE STREQUAL "INSTALL")
set(Thrust_ROOT "${CCCL_ROOT}")
set(CUB_ROOT "${CCCL_ROOT}")
set(libcudacxx_ROOT "${CCCL_ROOT}")
else()
message(FATAL_ERROR "Invalid ROOT_TYPE: ${ROOT_TYPE}")
endif()

message(STATUS "Thrust_ROOT=${Thrust_ROOT}")
message(STATUS "CUB_ROOT=${CUB_ROOT}")
message(STATUS "libcudacxx_ROOT=${libcudacxx_ROOT}")

function(do_find_package pkg_name pkg_prefix)
list(APPEND arg_list
REQUIRED
${ARGN}
NO_DEFAULT_PATH
HINTS "${pkg_prefix}"
)
list(JOIN arg_list " " arg_str)
message(STATUS "Executing: find_package(${pkg_name} ${arg_str})")
find_package(${pkg_name} ${arg_list})
if (NOT ${pkg_name}_FOUND)
message(FATAL_ERROR "Failed: find_package(${pkg_name} ${arg_str})")
endif()
endfunction()

# Run find package with the requested configuration:
if (PACKAGE_TYPE STREQUAL "CCCL")
if (COMPONENTS STREQUAL "DEFAULT")
do_find_package(CCCL "${CCCL_ROOT}")
else()
do_find_package(CCCL "${CCCL_ROOT}" COMPONENTS ${COMPONENTS})
endif()
elseif(PACKAGE_TYPE STREQUAL "NATIVE")
if (COMPONENTS STREQUAL "DEFAULT")
message(FATAL_ERROR "COMPONENTS=DEFAULT incompatible with PACKAGE_TYPE=NATIVE")
endif()
foreach (component IN LISTS COMPONENTS)
do_find_package(${component} "${${component}_ROOT}")
endforeach()
elseif(PACKAGE_TYPE STREQUAL "SUBDIR")
if (COMPONENTS STREQUAL "DEFAULT")
set(CCCL_REQUIRED_COMPONENTS)
else()
set(CCCL_REQUIRED_COMPONENTS ${COMPONENTS})
endif()
add_subdirectory("${CCCL_ROOT}" "${CMAKE_CURRENT_BINARY_DIR}/subdir")
else()
message(FATAL_ERROR "Invalid PACKAGE_TYPE: ${PACKAGE_TYPE}")
endif()

if (COMPONENTS STREQUAL "DEFAULT")
set(COMPONENTS libcudacxx CUB Thrust)
endif()

foreach (component IN LISTS COMPONENTS)
set(test_target version_check.${component})
set(component_target "${component}::${component}")
add_executable(${test_target} version_check.cxx)
target_link_libraries(${test_target} PRIVATE ${component_target})
add_test(NAME ${test_target} COMMAND ${test_target})

if (component STREQUAL "libcudacxx")
find_package(libcudacxx) # Make sure version vars are in scope
# TODO Should this be a genex? Will these stay correct as versions change?
math(EXPR component_cmake_version
"(${libcudacxx_VERSION_MAJOR} * 1000000) +
${libcudacxx_VERSION_MINOR} * 1000 +
${libcudacxx_VERSION_PATCH}")
target_compile_definitions(${test_target} PRIVATE
"VERSION_HEADER=cuda/std/version"
"VERSION_MACRO=_LIBCUDACXX_CUDA_API_VERSION"
"EXPECTED_VERSION=${component_cmake_version}")
elseif (component STREQUAL "CUB")
find_package(CUB) # Make sure version vars are in scope
# TODO Should this be a genex? Will these stay correct as versions change?
math(EXPR component_cmake_version
"(${CUB_VERSION_MAJOR} * 100000) +
${CUB_VERSION_MINOR} * 100 +
${CUB_VERSION_PATCH}")
target_compile_definitions(${test_target} PRIVATE
"VERSION_HEADER=cub/version.cuh"
"VERSION_MACRO=CUB_VERSION"
"EXPECTED_VERSION=${component_cmake_version}")
elseif (component STREQUAL "Thrust")
find_package(Thrust) # Make sure version vars are in scope
# TODO Should this be a genex? Will these stay correct as versions change?
math(EXPR component_cmake_version
"(${THRUST_VERSION_MAJOR} * 100000) +
${THRUST_VERSION_MINOR} * 100 +
${THRUST_VERSION_PATCH}")
target_compile_definitions(${test_target} PRIVATE
"VERSION_HEADER=thrust/version.h"
"VERSION_MACRO=THRUST_VERSION"
"EXPECTED_VERSION=${component_cmake_version}")
else()
message(FATAL_ERROR "Valid COMPONENTS are (case-sensitive): Thrust;CUB;libcudacxx")
endif()
endforeach()
Loading

0 comments on commit 5c84765

Please sign in to comment.