From e53c63568669d30ef8dc5850083fcd36d9d3fc07 Mon Sep 17 00:00:00 2001 From: Eyal Rozenberg Date: Fri, 27 Sep 2024 11:35:15 +0300 Subject: [PATCH] Regards #679: Added demangling support using NVIDIA's (nearly-hidden) libcufilt --- CMakeLists.txt | 16 +++++- src/cuda/api.hpp | 1 + src/cuda/api/demangle.hpp | 76 +++++++++++++++++++++++++++++ src/cuda/api/detail/unique_span.hpp | 7 +++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/cuda/api/demangle.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 43be50b1..a7d29ff2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,9 +32,14 @@ if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.4) endif() endforeach() endif() +if (NOT TARGET CUDA::cufilt) + _CUDAToolkit_find_and_add_import_lib(cufilt) +endif() + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + set(targets runtime-and-driver nvtx rtc fatbin) set(prefixed-targets "") set(caw_namespace "cuda-api-wrappers") @@ -75,7 +80,7 @@ foreach(wrapper_lib ${targets}) WINDOWS_EXPORT_ALL_SYMBOLS ON ) endforeach() -add_library("${caw_namespace}::driver-and-runtime" ALIAS caw_runtime-and-driver) +add_library("cuda-api-wrappers::driver-and-runtime" ALIAS caw_runtime-and-driver) target_link_libraries(caw_rtc INTERFACE cuda-api-wrappers::runtime-and-driver CUDA::nvrtc) if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.1) if (TARGET CUDA::nvptxcompiler) @@ -99,6 +104,15 @@ if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.4) else() message(WARNING "Could not locate a valid NVIDIA fatbin creator target or library file") endif() + + if (TARGET CUDA::cufilt) + target_link_libraries(caw_runtime-and-driver INTERFACE CUDA::cufilt) + elseif(EXISTS "${CUDA_cufilt_LIBRARY}") + target_link_libraries(caw_runtime-and-driver INTERFACE "${CUDA_cufilt_LIBRARY}") + else() + message(WARNING "Could not locate the cufilt demangling library") + endif() + endif() target_link_libraries(caw_fatbin INTERFACE cuda-api-wrappers::runtime-and-driver) diff --git a/src/cuda/api.hpp b/src/cuda/api.hpp index 51af11f0..35d3c44e 100644 --- a/src/cuda/api.hpp +++ b/src/cuda/api.hpp @@ -36,6 +36,7 @@ #include "api/event.hpp" #include "api/kernel.hpp" #include "api/module.hpp" +#include "api/demangle.hpp" #if CUDA_VERSION >= 12000 #include "api/library.hpp" #include "api/kernels/in_library.hpp" diff --git a/src/cuda/api/demangle.hpp b/src/cuda/api/demangle.hpp new file mode 100644 index 00000000..52a07554 --- /dev/null +++ b/src/cuda/api/demangle.hpp @@ -0,0 +1,76 @@ +/** + * @file + * + * @brief Functions related to mangling & demangling identifiers + * + */ +#ifndef CUDA_API_WRAPPERS_MANGLING_HPP_ +#define CUDA_API_WRAPPERS_MANGLING_HPP_ + +#include "detail/span.hpp" +#include "detail/unique_span.hpp" +#include + +namespace cuda { + +namespace detail_ { + +using mangle_status_t = int; + +void validate_mangling_status(int status) +{ + switch (status) { + // 0 is fine + case -1: throw ::std::runtime_error("Memory allocation failure by __cu_demangle for a demangled CUDA identifier"); + case -2: throw ::std::invalid_argument("Mangled identifier passed for demangling was invalid"); + case -3: throw ::std::invalid_argument("Validation of one of the input arguments for a __cu_demangle() call failed"); + } + return; +} + +// TODO: Assuming the length _does_ include the trailing '\0' +inline char* demangle(const char* mangled_identifier, char* buffer, size_t& allocated_size) +{ + int status; + char* result = __cu_demangle(mangled_identifier, buffer, &allocated_size, &status); + validate_mangling_status(status); + return result; +} + +inline unique_span demangle(const char* mangled_identifier) +{ + size_t allocated_size { 0 }; + auto demangled = demangle(mangled_identifier, nullptr, allocated_size); +#ifndef NDEBUG + if (allocated_size <= 1) { + throw std::logic_error("Invalid allocation size returned by __cu_demangle()"); + } +#endif + return unique_span{demangled, allocated_size - 1, c_free_deleter }; +} + + +} // namespace detail_ + +inline unique_span demangle(const char* mangled_identifier) +{ + return detail_::demangle(mangled_identifier); +} + +template +T demangle_as(const char* mangled_identifier) +{ + auto demangled = detail_::demangle(mangled_identifier); + return { demangled.data(), demangled.data() + demangled.size() }; +} + +template<> +inline ::std::string demangle_as<::std::string>(const char* mangled_identifier) +{ + auto demangled = detail_::demangle(mangled_identifier); + return { demangled.data(), demangled.size() }; +} + +} // namespace cuda + +#endif // CUDA_API_WRAPPERS_MANGLING_HPP_ diff --git a/src/cuda/api/detail/unique_span.hpp b/src/cuda/api/detail/unique_span.hpp index f04b60d1..65c0d5e0 100644 --- a/src/cuda/api/detail/unique_span.hpp +++ b/src/cuda/api/detail/unique_span.hpp @@ -177,6 +177,13 @@ inline void default_span_deleter(span sp) delete[] sp.data(); } +template +inline void c_free_deleter(span sp) +{ + ::std::free(sp.data()); +} + + } // namespace detail_