Skip to content
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

Implement a c++20 constexpr type demangler #2472

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

fwyzard
Copy link
Contributor

@fwyzard fwyzard commented Feb 1, 2025

Replace the run-time type demangler based on Boost with a constexpr version based on embedding the type name in the compiler generated function name.

Based on https://www.reddit.com/r/cpp/comments/lfi6jt/finally_a_possibly_portable_way_to_convert_types/ and https://rodusek.com/posts/2021/03/09/getting-an-unmangled-type-name-at-compile-time/ .

@fwyzard fwyzard changed the title Implement a c++20 constext type demangler Implement a c++20 constexpr type demangler Feb 1, 2025
@fwyzard fwyzard force-pushed the constexpr_demangle branch from 925d205 to 51449bb Compare February 1, 2025 21:18
@fwyzard fwyzard requested a review from SimeonEhrig February 1, 2025 21:20
@fwyzard fwyzard added this to the 2.0.0 milestone Feb 1, 2025
@fwyzard fwyzard linked an issue Feb 1, 2025 that may be closed by this pull request
@fwyzard fwyzard self-assigned this Feb 1, 2025
@fwyzard fwyzard force-pushed the constexpr_demangle branch from 51449bb to 2ae434c Compare February 1, 2025 21:28
#if BOOST_COMP_CLANG
# pragma clang diagnostic pop
#endif
inline constexpr std::string demangled = std::string(demangle<T>());
Copy link
Contributor Author

@fwyzard fwyzard Feb 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be rewritten using an std::string_view rather than an std::string - but it requires changes in many other places, I'll take care in a second moment.

@fwyzard fwyzard force-pushed the constexpr_demangle branch 3 times, most recently from 6c62bb8 to 5b621d2 Compare February 2, 2025 11:04
@fwyzard
Copy link
Contributor Author

fwyzard commented Feb 2, 2025

Looks like event with -std=c++20 many of the compilers we support did not provide std::format :-(

@fwyzard
Copy link
Contributor Author

fwyzard commented Feb 2, 2025

I really hate clang pointless warnings about perfectly valid C++ being treated as errors:

include/alpaka/acc/AccCpuSerial.hpp:162:42: error: declaration requires an exit-time destructor [-Werror,-Wexit-time-destructors]

@fwyzard fwyzard force-pushed the constexpr_demangle branch 2 times, most recently from 355b6a6 to ffd5c5d Compare February 2, 2025 12:00
@fwyzard
Copy link
Contributor Author

fwyzard commented Feb 2, 2025

Looks like event with -std=c++20 many of the compilers we support did not provide std::format :-(

Same for std::source_location:

2025-02-02T12:02:57.1072996Z /__w/alpaka/alpaka/include/alpaka/core/DemangleTypeNames.hpp:14:10: fatal error: 'source_location' file not found
2025-02-02T12:02:57.1073952Z #include <source_location>
2025-02-02T12:02:57.1074334Z ^~~~~~~~~~~~~~~~~

@fwyzard fwyzard force-pushed the constexpr_demangle branch 3 times, most recently from ebde117 to 2824b49 Compare February 3, 2025 08:08
# ifdef __cpp_lib_format
std::format("AccCpuOmp2Blocks<{},{}>", TDim::value, core::demangled<TIdx>);
# else
"AccCpuOmp2Blocks<"s + std::to_string(TDim::value) + ","s + std::string(core::demangled<TIdx>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is std::stringstream maybe a better solution?

Copy link
Contributor Author

@fwyzard fwyzard Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can give it a try.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, if std::stringstream has a performance disadvantage compare to std::format. I need to check it. But if not, I would suggest it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a little bit searching. std::format should be faster by factors and concatenating std::string should be faster than std::stringstream. The benefit of std::stringstream is the robustness for different data types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work:

                static std::string const accName =
#    ifdef __cpp_lib_format
                    std::format("AccCpuOmp2Blocks<{},{}>", TDim::value, core::demangled<TIdx>);
#    else
                    (std::stringstream() << "AccCpuOmp2Blocks<" << TDim::value << "," << core::demangled<TIdx> << ">").str();
#    endif

Do you prefer to keep the optional use of std::format, or go with std::stringstream in any case ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also thought about this idea, but than the PR does not make sense anymore, because the PR should remove a dependency and not replace it.

Copy link
Contributor Author

@fwyzard fwyzard Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind having boost as a dependency, so for me improvement is the constexpr functionality.

However, unlike boost I think {fmt} is header only, and we could include it directly in alpaka as a third party library like catch and mdspan.

Anyway, it's just an idea, and in case we can follow up in a later PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind having boost as a dependency, so for me improvement is the constexpr functionality.

Ah okay. I thought this PR is pulling out a part of this PR #2409. But this was a misunderstanding from my side (to much different stuff in the morning ;-) ).

However, unlike boost I think {fmt} is header only, and we could include it directly in alpaka as a third party library like catch and mdspan.

Anyway, it's just an idea, and in case we can follow up in a later PR.

Fair enough. We need only to support one specific version, which we can ship via sub directory or via CMake. We can discuss this tomorrow in the VC.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During the VC we discussed, if you should use the fmt library. @psychocoderHPC is against it, because the advantage of using it in a debug function is not big enough for the extra work caused by maintaining a dependency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately gcc 10 does not like the ostringstream-based syntax (it works with gcc 11 and later, and all clang+ versions I tried).

I'll revert to

... = "AccCpuOmp2Blocks<"s + std::to_string(TDim::value) + ","s + std::string(core::demangled<TIdx>);

@fwyzard fwyzard force-pushed the constexpr_demangle branch from 2824b49 to b8b0985 Compare February 3, 2025 09:21
@@ -162,7 +166,21 @@ namespace alpaka
{
ALPAKA_FN_HOST static auto getAccName() -> std::string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR headline mentioned a constexpr type demangler. Is it possible to make the function constexpr or consteval? In this case the performance of std::format and std::stringstream does not matter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't find a way.

The performance doesn't matter much anyway, because the name is computed only once, the first time it's used.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment I play a little bit around with it but it is not easy that compiler really optimize.
But if the performance does not matter, we simply keep the simple implementation and optimize it, if become an bottleneck.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I found a major problem, if we want to make it constexpr. C++23 is required for static variables in constexpr functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's the same issue I had to work around here:

    // Store the demangled type name as a null-terminated array of bytes.
    // Note: this could be a function-static constexpr variable in c++23.
    template<typename T>
    inline constexpr auto storage = demangleAsArray<T>();

Maybe we can use a consteval function and store it as a static constexpr data member.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During the VC today we talked about the subject. It is not performance critical. Therefore we can keep it as it is.

@fwyzard fwyzard removed their assignment Feb 3, 2025
@fwyzard fwyzard force-pushed the constexpr_demangle branch from b8b0985 to fe19cda Compare February 3, 2025 10:16
@psychocoderHPC
Copy link
Member

The fallback source location implementation for demange equal to #2405?

# ifdef __cpp_lib_format
std::format("AccGpu{}Rt<{},{}>", TApi::name, TDim::value, core::demangled<TIdx>);
# else
(std::ostringstream()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To workaround the nvcc error here

error: class "std::basic_ostream<char, std::char_traits<char>>" has no member "str"
                          .str();
                           ^

I would try if std::string(<ostringstream>) works

// Store the demangled type name as a null-terminated array of bytes.
// Note: this could be a function-static constexpr variable in c++23.
template<typename T>
inline constexpr auto storage = demangleAsArray<T>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ci error

/builds/hzdr/crp/alpaka/include/alpaka/core/DemangleTypeNames.hpp(78): error: call to consteval function "<unnamed>::demangleAsArray<T>() [with T=uint32_t]" did not produce a valid constant expression
/builds/hzdr/crp/alpaka/include/alpaka/core/DemangleTypeNames.hpp(72): note #2751-D: access to uninitialized object

Maybe using inline ALPAKA_FN_HOST constexpr auto storage = demangleAsArray<T>(); solve the issue

@fwyzard fwyzard force-pushed the constexpr_demangle branch 3 times, most recently from 29a8abc to 17523d9 Compare February 18, 2025 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

remove boost demangle
3 participants