cmake_minimum_required(VERSION 3.21) project(CCCL_C_Parallel LANGUAGES CUDA CXX C) option(CCCL_C_Parallel_ENABLE_TESTING "Build cccl.c.parallel tests." OFF) option( CCCL_C_Parallel_ENABLE_HEADER_TESTING "Build cccl.c.parallel standalone headers." OFF ) # Instrument cccl.c.parallel's host code with ThreadSanitizer for the # free-threaded (3.14t) TSan CI lane. TSan is a host-only tool, so CUDA device # code is never instrumented -- only the host portion of each .cu (via # -Xcompiler). The libtsan runtime is assumed loaded in the process (the TSan # lane LD_PRELOADs it) rather than linked-and-bundled, so the wheel build must # --exclude libtsan from auditwheel repair. option( CCCL_C_PARALLEL_SANITIZE_THREAD "Build cccl.c.parallel host code with ThreadSanitizer (-fsanitize=thread)." OFF ) # FIXME Ideally this would be handled by presets and install rules, but for now # consumers may override this to control the target location of cccl.c.parallel. set( CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY "" CACHE PATH "Override output directory for the cccl.c.parallel library" ) mark_as_advanced(CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY) file( GLOB_RECURSE srcs RELATIVE "${CMAKE_CURRENT_LIST_DIR}" CONFIGURE_DEPENDS "src/*.cu" "src/*.cpp" ) # hostjit sources are built as a separate library; exclude from cccl.c.parallel list(FILTER srcs EXCLUDE REGEX "src/hostjit/") add_library(cccl.c.parallel SHARED ${srcs}) set_property(TARGET cccl.c.parallel PROPERTY POSITION_INDEPENDENT_CODE ON) cccl_configure_target(cccl.c.parallel DIALECT 20) # Override the properties set by cccl_configure_target: if (CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY) set_target_properties( cccl.c.parallel PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY}" ARCHIVE_OUTPUT_DIRECTORY "${CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY}" RUNTIME_OUTPUT_DIRECTORY "${CCCL_C_PARALLEL_LIBRARY_OUTPUT_DIRECTORY}" ) endif() if (CCCL_C_PARALLEL_SANITIZE_THREAD) # Host-only: -fsanitize=thread on C++ TUs, and forwarded to the host compiler # (-Xcompiler, one flag per prefix) for the host side of each .cu. -g1 keeps # file:line frames in TSan reports (minimal debug info -- enough to symbolize # traces, not to attach a debugger); -fno-omit-frame-pointer keeps complete # stack traces through heavily inlined CUB/Thrust code. target_compile_options( cccl.c.parallel PRIVATE $<$:-fsanitize=thread;-fno-omit-frame-pointer;-g1> $<$:-Xcompiler=-fsanitize=thread;-Xcompiler=-fno-omit-frame-pointer;-Xcompiler=-g1> ) target_link_options(cccl.c.parallel PRIVATE -fsanitize=thread) endif() cccl_get_cub() cccl_get_cudatoolkit() cccl_get_thrust() add_subdirectory(src/jit_templates) set_target_properties(cccl.c.parallel PROPERTIES CUDA_RUNTIME_LIBRARY STATIC) target_link_libraries( cccl.c.parallel PRIVATE cccl.compiler_interface CUDA::cudart_static CUDA::nvrtc CUDA::nvJitLink CUDA::cuda_driver cccl.c.parallel.jit_template CUB::CUB Thrust::Thrust ) if (WIN32) # Needed for UnDecorateSymbolName on Windows (used by nvrtc). target_link_libraries(cccl.c.parallel PRIVATE Dbghelp) endif() target_compile_definitions( cccl.c.parallel PUBLIC CCCL_C_EXPERIMENTAL=1 PRIVATE # NVRTC_GET_TYPE_NAME=1 CUB_DISABLE_CDP=1 CUB_DEFINE_RUNTIME_POLICIES ) target_compile_options( cccl.c.parallel PRIVATE $<$:--extended-lambda> ) target_include_directories( cccl.c.parallel # PUBLIC "include" PRIVATE "src" ) if (CCCL_C_Parallel_ENABLE_TESTING) add_subdirectory(test) endif() if (CCCL_C_Parallel_ENABLE_HEADER_TESTING) include(cmake/CParallelHeaderTesting.cmake) endif()