-
Notifications
You must be signed in to change notification settings - Fork 288
Implement cudax::demangle
#4996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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) 2025 NVIDIA CORPORATION & AFFILIATES. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef _CUDAX___BINUTILS_DEMANGLE_CUH | ||
| #define _CUDAX___BINUTILS_DEMANGLE_CUH | ||
|
|
||
| #include <cuda/std/detail/__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 | ||
|
|
||
| #if _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC) | ||
|
|
||
| # include <cuda/std/__cstddef/types.h> | ||
| # include <cuda/std/__exception/throw_error.h> | ||
| # include <cuda/std/__new/bad_alloc.h> | ||
| # include <cuda/std/__type_traits/always_false.h> | ||
| # include <cuda/std/cstdlib> | ||
| # include <cuda/std/string_view> | ||
|
|
||
| # include <string> | ||
|
|
||
| # if _CCCL_HAS_INCLUDE(<nv_decode.h>) | ||
| # include <nv_decode.h> | ||
| # endif // _CCCL_HAS_INCLUDE(<nv_decode.h>) | ||
|
|
||
| # include <cuda/std/__cccl/prologue.h> | ||
|
|
||
| namespace cuda::experimental | ||
| { | ||
|
|
||
| // todo: make this function take cuda::std::cstring_view once P3655 is merged to C++29 and implemented in libcu++ | ||
|
|
||
| //! @brief Demangles a CUDA C++ mangled name. | ||
| //! | ||
| //! @param __name The mangled name to demangle. | ||
| //! | ||
| //! @return A `std::string` containing the demangled name. | ||
| //! | ||
| //! @throws std::bad_alloc if memory allocation fails. | ||
| //! @throws std::runtime_error if the passed \c __name is not a valid mangled symbol. | ||
| template <class _Dummy = void> | ||
| [[nodiscard]] _CCCL_HOST_API ::std::string demangle(::cuda::std::string_view __name) | ||
| { | ||
| # if !_CCCL_HAS_INCLUDE(<nv_decode.h>) | ||
| static_assert(__always_false_v<_Dummy>, "cuda::demangle requires the `cuxxfilt` package from the CUDA Toolkit."); | ||
| # else // ^^^ no cuxxfilt ^^^ / vvv has cuxxfilt vvv | ||
| // input must be zero-terminated, so we convert string_view to std::string | ||
| ::std::string __name_in{__name.begin(), __name.end()}; | ||
|
|
||
| int __status{}; | ||
| char* __dname = ::__cu_demangle(__name_in.c_str(), nullptr, nullptr, &__status); | ||
|
|
||
| try | ||
| { | ||
| switch (__status) | ||
| { | ||
| case 0: { | ||
| ::std::string __ret{__dname}; | ||
| ::cuda::std::free(__dname); | ||
| return __ret; | ||
| } | ||
| case -1: | ||
| ::cuda::std::__throw_bad_alloc(); | ||
| case -2: | ||
| ::cuda::std::__throw_runtime_error("invalid mangled name passed to cuda::demangle function"); | ||
| case -3: | ||
| _CCCL_ASSERT(false, "cccl internal error - invalid argument passed to __cu_demangle"); | ||
| [[fallthrough]]; | ||
| default: | ||
| _CCCL_UNREACHABLE(); | ||
| } | ||
| } | ||
| catch (...) | ||
| { | ||
| // If an exception is thrown, free the allocated memory and rethrow the exception | ||
| ::cuda::std::free(__dname); | ||
| throw; | ||
| } | ||
| # endif // ^^^ has cuxxfilt ^^^ | ||
| } | ||
|
|
||
| } // namespace cuda::experimental | ||
|
|
||
| # include <cuda/std/__cccl/epilogue.h> | ||
|
|
||
| #endif // _CCCL_HAS_CTK() && !_CCCL_COMPILER(NVRTC) | ||
|
|
||
| #endif // _CUDAX___BINUTILS_DEMANGLE_CUH |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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) 2025 NVIDIA CORPORATION & AFFILIATES. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef _CUDAX_BINUTILS | ||
| #define _CUDAX_BINUTILS | ||
|
|
||
| #include <cuda/std/detail/__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/experimental/__binutils/demangle.cuh> | ||
|
|
||
| #endif // _CUDAX_BINUTILS |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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) 2025 NVIDIA CORPORATION & AFFILIATES. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| // This test uses assert(...) for checking results | ||
| #undef NDEBUG | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer to see something more robust than relying on |
||
|
|
||
| #include <cuda/std/cassert> | ||
| #include <cuda/std/string_view> | ||
| #include <cuda/std/type_traits> | ||
|
|
||
| #include <cuda/experimental/binutils.cuh> | ||
|
|
||
| #include <stdexcept> | ||
| #include <string> | ||
|
|
||
| namespace cudax = cuda::experimental; | ||
|
|
||
| bool test() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return value is unused, omit? |
||
| { | ||
| // 1. Test signature | ||
| static_assert(cuda::std::is_same_v<std::string, decltype(cudax::demangle(cuda::std::string_view{}))>); | ||
| static_assert(!noexcept(cudax::demangle(cuda::std::string_view{}))); | ||
|
|
||
| // 2. Test positive case | ||
| { | ||
| constexpr auto real_mangled_name = "_ZN8clstmp01I5cls01E13clstmp01_mf01Ev"; | ||
| const auto demangled = cudax::demangle(real_mangled_name); | ||
| assert(demangled == "clstmp01<cls01>::clstmp01_mf01()"); | ||
| } | ||
|
|
||
| // 3. Test error case | ||
| { | ||
| #if _CCCL_HAS_EXCEPTIONS() | ||
| constexpr auto fake_mangled_name = "B@d_iDentiFier"; | ||
| try | ||
| { | ||
| auto demangled = cudax::demangle(fake_mangled_name); | ||
| assert(false); | ||
| } | ||
| catch (const std::runtime_error&) | ||
| { | ||
| assert(true); | ||
| } | ||
| catch (...) | ||
| { | ||
| assert(false); | ||
| } | ||
| #endif // _CCCL_HAS_EXCEPTIONS() | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| int main(int, char**) | ||
| { | ||
| NV_IF_TARGET(NV_IS_HOST, (test();)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't needed in cudax tests. |
||
| return 0; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.