mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
FindCUDAToolkit: Add sanitizer support
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
findcudatoolkit-sanitizer-api
|
||||
-----------------------------
|
||||
|
||||
* The :module:`FindCUDAToolkit` module now creates a ``CUDA::sanitizer``
|
||||
target for the :ref:`compute-sanitizer <FindCUDAToolkit_sanitizer>`
|
||||
library.
|
||||
@@ -537,6 +537,22 @@ Target Created:
|
||||
|
||||
- ``CUDA::bin2c``
|
||||
|
||||
.. _`FindCUDAToolkit_sanitizer`:
|
||||
|
||||
compute-sanitizer
|
||||
"""""""""""""""""
|
||||
|
||||
.. versionadded:: 4.4
|
||||
|
||||
The `NVIDIA Compute Sanitizer`_ library, which allows the tracing of CUDA
|
||||
runtime and driver calls.
|
||||
|
||||
Target Created:
|
||||
|
||||
- ``CUDA::sanitizer``
|
||||
|
||||
.. _`NVIDIA Compute Sanitizer`: https://docs.nvidia.com/compute-sanitizer
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -1223,7 +1239,11 @@ endif()
|
||||
if(CUDAToolkit_FOUND)
|
||||
|
||||
function(_CUDAToolkit_find_and_add_import_lib lib_name)
|
||||
cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS;ONLY_SEARCH_FOR" ${ARGN})
|
||||
cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS;ONLY_SEARCH_FOR;LIBRARY_SEARCH_DIRS" ${ARGN})
|
||||
|
||||
if(NOT arg_LIBRARY_SEARCH_DIRS)
|
||||
set(arg_LIBRARY_SEARCH_DIRS "${CUDAToolkit_LIBRARY_SEARCH_DIRS}")
|
||||
endif()
|
||||
|
||||
if(arg_ONLY_SEARCH_FOR)
|
||||
set(search_names ${arg_ONLY_SEARCH_FOR})
|
||||
@@ -1233,7 +1253,7 @@ if(CUDAToolkit_FOUND)
|
||||
|
||||
find_library(CUDA_${lib_name}_LIBRARY
|
||||
NAMES ${search_names}
|
||||
HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
|
||||
HINTS ${arg_LIBRARY_SEARCH_DIRS}
|
||||
ENV CUDA_PATH
|
||||
PATH_SUFFIXES nvidia/current lib64 ${_CUDAToolkit_win_search_dirs} lib
|
||||
# Support NVHPC splayed math library layout
|
||||
@@ -1248,7 +1268,7 @@ if(CUDAToolkit_FOUND)
|
||||
if(NOT CUDA_${lib_name}_LIBRARY)
|
||||
find_library(CUDA_${lib_name}_LIBRARY
|
||||
NAMES ${search_names}
|
||||
HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
|
||||
HINTS ${arg_LIBRARY_SEARCH_DIRS}
|
||||
ENV CUDA_PATH
|
||||
PATH_SUFFIXES lib64/stubs ${_CUDAToolkit_win_stub_search_dirs} lib/stubs stubs
|
||||
)
|
||||
@@ -1515,6 +1535,21 @@ if(CUDAToolkit_FOUND)
|
||||
add_executable(CUDA::bin2c IMPORTED)
|
||||
set_property(TARGET CUDA::bin2c PROPERTY IMPORTED_LOCATION "${CUDA_bin2c_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
_CUDAToolkit_find_and_add_import_lib(
|
||||
sanitizer
|
||||
ONLY_SEARCH_FOR sanitizer-public
|
||||
LIBRARY_SEARCH_DIRS
|
||||
"${CUDAToolkit_LIBRARY_ROOT}/compute-sanitizer"
|
||||
"${CUDAToolkit_LIBRARY_ROOT}/Sanitizer"
|
||||
"${CUDAToolkit_LIBRARY_ROOT}/extras/Sanitizer"
|
||||
EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}"
|
||||
)
|
||||
if(TARGET CUDA::sanitizer)
|
||||
get_property(loc TARGET CUDA::sanitizer PROPERTY IMPORTED_LOCATION)
|
||||
get_filename_component(sanitizer_dir "${loc}" DIRECTORY)
|
||||
target_include_directories(CUDA::sanitizer INTERFACE "${sanitizer_dir}/include")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_CUDAToolkit_Pop_ROOT_PATH)
|
||||
|
||||
@@ -32,3 +32,4 @@ endif()
|
||||
|
||||
add_cuda_test_macro(Cuda.WithC CudaWithC)
|
||||
add_cuda_test_macro(Cuda.Bin2C CudaBin2C)
|
||||
add_cuda_test_macro(Cuda.Sanitizer ${CMAKE_CTEST_COMMAND} --output-on-failure)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 4.3)
|
||||
project(Sanitizer CXX)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# Goal for this example:
|
||||
# Validate that we can use CUDAToolkit sanitizer
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
|
||||
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1)
|
||||
add_executable(CudaSanitizer test_sanitizer.cpp)
|
||||
target_link_libraries(CudaSanitizer PRIVATE CUDA::sanitizer CUDA::cudart_static)
|
||||
|
||||
add_test(NAME CudaSanitizer COMMAND CudaSanitizer)
|
||||
if(WIN32)
|
||||
get_property(sanitizer_path TARGET CUDA::sanitizer PROPERTY IMPORTED_LOCATION)
|
||||
get_filename_component(sanitizer_dir "${sanitizer_path}" DIRECTORY)
|
||||
set_property(TEST CudaSanitizer PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:${sanitizer_dir}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,74 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <cuda_runtime.h>
|
||||
#include <sanitizer.h>
|
||||
#include <stddef.h>
|
||||
|
||||
namespace {
|
||||
|
||||
bool malloc_called = false;
|
||||
bool free_called = false;
|
||||
|
||||
void sanitizer_callback(void* userdata, Sanitizer_CallbackDomain domain,
|
||||
Sanitizer_CallbackId cbid, void const* cbdata)
|
||||
{
|
||||
if (domain == SANITIZER_CB_DOMAIN_RESOURCE) {
|
||||
switch (cbid) {
|
||||
case SANITIZER_CBID_RESOURCE_DEVICE_MEMORY_ALLOC:
|
||||
malloc_called = true;
|
||||
break;
|
||||
case SANITIZER_CBID_RESOURCE_DEVICE_MEMORY_FREE:
|
||||
free_called = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define SANITIZER_TRY(call) \
|
||||
do { \
|
||||
SanitizerResult result; \
|
||||
if ((result = (call)) != SANITIZER_SUCCESS) { \
|
||||
const char* result_str; \
|
||||
sanitizerGetResultString(result, &result_str); \
|
||||
std::cerr << __FILE__ << ":" << __LINE__ << ": " << result_str << "\n"; \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CUDA_TRY(call) \
|
||||
do { \
|
||||
cudaError_t result; \
|
||||
if ((result = (call)) != cudaSuccess) { \
|
||||
std::cerr << __FILE__ << ":" << __LINE__ << ": " \
|
||||
<< cudaGetErrorName(result) << "\n"; \
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main()
|
||||
{
|
||||
Sanitizer_SubscriberHandle handle;
|
||||
SANITIZER_TRY(sanitizerSubscribe(&handle, sanitizer_callback, NULL));
|
||||
SANITIZER_TRY(
|
||||
sanitizerEnableDomain(1, handle, SANITIZER_CB_DOMAIN_RESOURCE));
|
||||
|
||||
void* dev_ptr;
|
||||
CUDA_TRY(cudaMalloc(&dev_ptr, 10));
|
||||
if (!malloc_called) {
|
||||
std::cerr << "cudaMalloc() did not invoke callback\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
CUDA_TRY(cudaFree(dev_ptr));
|
||||
if (!free_called) {
|
||||
std::cerr << "cudaFree() did not invoke callback\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
SANITIZER_TRY(sanitizerUnsubscribe(handle));
|
||||
return 0;
|
||||
}
|
||||
@@ -41,6 +41,7 @@ if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
|
||||
endif()
|
||||
|
||||
add_cuda_test_macro(CudaOnly.DeviceLTO CudaOnlyDeviceLTO)
|
||||
add_cuda_test_macro(CudaOnly.Sanitizer ${CMAKE_CTEST_COMMAND} --output-on-failure)
|
||||
|
||||
if(MSVC)
|
||||
# Tests for features that only work with MSVC
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 4.3)
|
||||
project(Sanitizer CUDA)
|
||||
|
||||
enable_testing()
|
||||
|
||||
# Goal for this example:
|
||||
# Validate that we can use CUDAToolkit sanitizer
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
|
||||
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1)
|
||||
add_executable(CudaOnlySanitizer test_sanitizer.cu)
|
||||
target_link_libraries(CudaOnlySanitizer PRIVATE CUDA::sanitizer)
|
||||
|
||||
add_test(NAME CudaOnlySanitizer COMMAND CudaOnlySanitizer)
|
||||
if(WIN32)
|
||||
get_property(sanitizer_path TARGET CUDA::sanitizer PROPERTY IMPORTED_LOCATION)
|
||||
get_filename_component(sanitizer_dir "${sanitizer_path}" DIRECTORY)
|
||||
set_property(TEST CudaOnlySanitizer PROPERTY ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:${sanitizer_dir}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../Cuda/Sanitizer/test_sanitizer.cpp"
|
||||
Reference in New Issue
Block a user