diff --git a/CMakeLists.txt b/CMakeLists.txt index d04685919781..8278178430e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1207,25 +1207,7 @@ if(HPX_WITH_APEX AND NOT HPX_WITH_DISTRIBUTED_RUNTIME) hpx_error("HPX_WITH_DISTRIBUTED_RUNTIME=OFF requires HPX_WITH_APEX=OFF") endif() -set(_hpx_tracing_backends "") -if(HPX_WITH_APEX) - list(APPEND _hpx_tracing_backends "HPX_WITH_APEX") -endif() -if(HPX_WITH_ITTNOTIFY) - list(APPEND _hpx_tracing_backends "HPX_WITH_ITTNOTIFY") -endif() -if(HPX_TRACY_WITH_TRACY) - list(APPEND _hpx_tracing_backends "HPX_TRACY_WITH_TRACY") -endif() - -list(LENGTH _hpx_tracing_backends _hpx_tracing_backends_count) -if(_hpx_tracing_backends_count GREATER 1) - hpx_error( - "Only one tracing backend can be active. Disable all but one of: HPX_WITH_APEX, HPX_WITH_ITTNOTIFY, HPX_TRACY_WITH_TRACY." - ) -endif() -unset(_hpx_tracing_backends) -unset(_hpx_tracing_backends_count) +include(HPX_SetupTracing) if(HPX_WITH_NETWORKING) hpx_add_config_define(HPX_HAVE_NETWORKING) diff --git a/cmake/HPX_SetupAllocator.cmake b/cmake/HPX_SetupAllocator.cmake index 4770573eef5a..b2d3af91c3a2 100644 --- a/cmake/HPX_SetupAllocator.cmake +++ b/cmake/HPX_SetupAllocator.cmake @@ -131,20 +131,6 @@ if(NOT TARGET hpx_dependencies_allocator) hpx_info("Using ${HPX_WITH_MALLOC} allocator.") - # Setup Intel amplifier - if((NOT HPX_WITH_APEX) AND HPX_WITH_ITTNOTIFY) - - find_package(Amplifier) - if(NOT Amplifier_FOUND) - hpx_error( - "Intel Amplifier could not be found and HPX_WITH_ITTNOTIFY=On, please specify Amplifier_ROOT to point to the root of your Amplifier installation" - ) - endif() - - hpx_add_config_define(HPX_HAVE_ITTNOTIFY 1) - hpx_add_config_define(HPX_HAVE_THREAD_DESCRIPTION) - endif() - # convey selected allocator type to the build configuration hpx_add_config_define(HPX_HAVE_MALLOC "\"${HPX_WITH_MALLOC}\"") if(${HPX_WITH_MALLOC} STREQUAL "jemalloc") diff --git a/cmake/HPX_SetupApex.cmake b/cmake/HPX_SetupApex.cmake index 35852a5ca949..3704de5871fa 100644 --- a/cmake/HPX_SetupApex.cmake +++ b/cmake/HPX_SetupApex.cmake @@ -126,6 +126,5 @@ if(HPX_WITH_APEX AND NOT TARGET APEX::apex) ITTNotify::ittnotify SYSTEM INTERFACE ${Ittnotify_SOURCE_DIR} ) target_link_libraries(APEX::apex INTERFACE ITTNotify::ittnotify) - hpx_add_config_define(HPX_HAVE_ITTNOTIFY 1) endif() endif() diff --git a/cmake/HPX_SetupTracing.cmake b/cmake/HPX_SetupTracing.cmake new file mode 100644 index 000000000000..c24f3c72cd0d --- /dev/null +++ b/cmake/HPX_SetupTracing.cmake @@ -0,0 +1,51 @@ +# Copyright (c) 2026 The STE||AR Group +# Copyright (c) 2026 Vansh Dobhal +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +include(HPX_AddDefinitions) + +set(_hpx_tracing_backends "") +if(HPX_WITH_APEX) + list(APPEND _hpx_tracing_backends "HPX_WITH_APEX") +endif() +if(HPX_WITH_ITTNOTIFY) + list(APPEND _hpx_tracing_backends "HPX_WITH_ITTNOTIFY") +endif() +if(HPX_TRACY_WITH_TRACY) + list(APPEND _hpx_tracing_backends "HPX_TRACY_WITH_TRACY") +endif() + +list(LENGTH _hpx_tracing_backends _hpx_tracing_backends_count) +if(_hpx_tracing_backends_count GREATER 1) + hpx_error( + "Only one tracing backend can be active. Disable all but one of: HPX_WITH_APEX, HPX_WITH_ITTNOTIFY, HPX_TRACY_WITH_TRACY." + ) +endif() +unset(_hpx_tracing_backends) +unset(_hpx_tracing_backends_count) + +# Setup Intel amplifier for ITTNotify when APEX is not used. +if(HPX_WITH_ITTNOTIFY AND NOT HPX_WITH_APEX) + find_package(Amplifier) + if(NOT Amplifier_FOUND) + hpx_error( + "Intel Amplifier could not be found and HPX_WITH_ITTNOTIFY=On, please specify Amplifier_ROOT to point to the root of your Amplifier installation" + ) + endif() + + hpx_add_config_define(HPX_HAVE_THREAD_DESCRIPTION) +endif() + +if(HPX_WITH_ITTNOTIFY) + hpx_add_config_define(HPX_HAVE_ITTNOTIFY 1) +endif() + +if(HPX_WITH_APEX + OR HPX_WITH_ITTNOTIFY + OR HPX_TRACY_WITH_TRACY +) + hpx_add_config_define(HPX_HAVE_TRACING) +endif() diff --git a/libs/core/concurrency/CMakeLists.txt b/libs/core/concurrency/CMakeLists.txt index bcaf6ca6b6bd..630d7cbe4784 100644 --- a/libs/core/concurrency/CMakeLists.txt +++ b/libs/core/concurrency/CMakeLists.txt @@ -76,6 +76,7 @@ add_hpx_module( hpx_itt_notify hpx_lock_registration hpx_thread_support + hpx_tracing hpx_type_support hpx_version ${additional_dependencies} diff --git a/libs/core/concurrency/include/hpx/concurrency/spinlock.hpp b/libs/core/concurrency/include/hpx/concurrency/spinlock.hpp index 5222e7d0f1ea..a4f05e26d2a1 100644 --- a/libs/core/concurrency/include/hpx/concurrency/spinlock.hpp +++ b/libs/core/concurrency/include/hpx/concurrency/spinlock.hpp @@ -12,9 +12,7 @@ #include #include #include -#if defined(HPX_HAVE_MODULE_TRACY) -#include -#endif +#include #include #include @@ -32,50 +30,36 @@ namespace hpx::util { private: hpx::util::detail::spinlock m; -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_data context_; -#endif + HPX_NO_UNIQUE_ADDRESS hpx::tracing::lock_context context_; public: spinlock() noexcept + : context_("hpx::spinlock") { HPX_ITT_SYNC_CREATE(this, "util::spinlock", nullptr); -#if defined(HPX_HAVE_MODULE_TRACY) - context_ = hpx::tracy::create("hpx::spinlock"); -#endif } explicit spinlock(char const* desc) noexcept + : context_("util::spinlock#", desc) { HPX_ITT_SYNC_CREATE(this, "util::spinlock", desc); -#if defined(HPX_HAVE_MODULE_TRACY) - context_ = - hpx::tracy::create(std::string("util::spinlock#") + desc); -#endif } ~spinlock() { HPX_ITT_SYNC_DESTROY(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::destroy(context_); -#endif } void lock() noexcept( noexcept(util::register_lock(std::declval()))) { HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); m.lock(); HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_); -#endif + context_.after_lock(); util::register_lock(this); } @@ -83,25 +67,19 @@ namespace hpx::util { noexcept(util::register_lock(std::declval()))) { HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); if (m.try_lock()) { HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, true); -#endif + context_.after_try_lock(true); util::register_lock(this); return true; } HPX_ITT_SYNC_CANCEL(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, false); -#endif + context_.after_try_lock(false); return false; } @@ -113,9 +91,7 @@ namespace hpx::util { m.unlock(); HPX_ITT_SYNC_RELEASED(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_released(context_); -#endif + context_.after_unlock(); util::unregister_lock(this); } }; diff --git a/libs/core/synchronization/CMakeLists.txt b/libs/core/synchronization/CMakeLists.txt index cffec573e779..ba59e20229fe 100644 --- a/libs/core/synchronization/CMakeLists.txt +++ b/libs/core/synchronization/CMakeLists.txt @@ -95,6 +95,7 @@ add_hpx_module( hpx_thread_support hpx_timing hpx_topology + hpx_tracing hpx_type_support ${additional_dependencies} CMAKE_SUBDIRS examples tests diff --git a/libs/core/synchronization/include/hpx/synchronization/mutex.hpp b/libs/core/synchronization/include/hpx/synchronization/mutex.hpp index d83ec421cffc..b77c69bade30 100644 --- a/libs/core/synchronization/include/hpx/synchronization/mutex.hpp +++ b/libs/core/synchronization/include/hpx/synchronization/mutex.hpp @@ -16,11 +16,9 @@ #include #include #include +#include #include #include -#if defined(HPX_HAVE_MODULE_TRACY) -#include -#endif namespace hpx::threads { @@ -89,7 +87,7 @@ namespace hpx { /// /// \param description description of the \a mutex. /// -#if HPX_HAVE_ITTNOTIFY != 0 || defined(HPX_HAVE_MODULE_TRACY) +#if defined(HPX_HAVE_TRACING) HPX_CORE_EXPORT mutex(char const* const description = ""); #else HPX_HOST_DEVICE_CONSTEXPR mutex(char const* const = "") noexcept @@ -245,9 +243,7 @@ namespace hpx { mutable mutex_type mtx_; threads::thread_id_type owner_id_; hpx::lcos::local::detail::condition_variable cond_; -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_data context_; -#endif + HPX_NO_UNIQUE_ADDRESS hpx::tracing::lock_context context_; /// \endcond NOPROTECTED }; diff --git a/libs/core/synchronization/include/hpx/synchronization/spinlock.hpp b/libs/core/synchronization/include/hpx/synchronization/spinlock.hpp index ce1b4ec1244d..07a92d95d080 100644 --- a/libs/core/synchronization/include/hpx/synchronization/spinlock.hpp +++ b/libs/core/synchronization/include/hpx/synchronization/spinlock.hpp @@ -22,9 +22,7 @@ #include #include #include -#if defined(HPX_HAVE_MODULE_TRACY) -#include -#endif +#include #include #include @@ -50,37 +48,27 @@ namespace hpx { private: std::atomic v_; -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_data context_; -#endif + HPX_NO_UNIQUE_ADDRESS hpx::tracing::lock_context context_; public: -#if HPX_HAVE_ITTNOTIFY != 0 || defined(HPX_HAVE_MODULE_TRACY) +#if defined(HPX_HAVE_TRACING) spinlock() noexcept : v_(false) + , context_("hpx::spinlock") { HPX_ITT_SYNC_CREATE(this, "hpx::spinlock", nullptr); -#if defined(HPX_HAVE_MODULE_TRACY) - context_ = hpx::tracy::create("hpx::spinlock"); -#endif } explicit spinlock(char const* const desc) noexcept : v_(false) + , context_("hpx::spinlock#", desc) { HPX_ITT_SYNC_CREATE(this, "hpx::spinlock", desc); -#if defined(HPX_HAVE_MODULE_TRACY) - context_ = - hpx::tracy::create(std::string("hpx::spinlock#") + desc); -#endif } ~spinlock() { HPX_ITT_SYNC_DESTROY(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::destroy(context_); -#endif } #else constexpr spinlock() noexcept @@ -99,9 +87,7 @@ namespace hpx { void lock() { HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); // Checking for the value in is_locked() ensures that // acquire_lock is only called when is_locked computes to false. @@ -132,10 +118,8 @@ namespace hpx { } HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_); -#endif + context_.after_lock(); util::register_lock(this); } @@ -143,26 +127,20 @@ namespace hpx { noexcept(util::register_lock(std::declval()))) { HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); if (acquire_lock()) { HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, true); -#endif + context_.after_try_lock(true); util::register_lock(this); return true; } HPX_ITT_SYNC_CANCEL(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, false); -#endif + context_.after_try_lock(false); return false; } @@ -174,9 +152,7 @@ namespace hpx { relinquish_lock(); HPX_ITT_SYNC_RELEASED(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_released(context_); -#endif + context_.after_unlock(); util::unregister_lock(this); } diff --git a/libs/core/synchronization/src/mutex.cpp b/libs/core/synchronization/src/mutex.cpp index 72ebbedc3e0b..4bc7710f21fb 100644 --- a/libs/core/synchronization/src/mutex.cpp +++ b/libs/core/synchronization/src/mutex.cpp @@ -12,12 +12,10 @@ #include #include #include +#include #include #include #include -#if defined(HPX_HAVE_MODULE_TRACY) -#include -#endif #include #include @@ -26,24 +24,19 @@ namespace hpx { /////////////////////////////////////////////////////////////////////////// -#if HPX_HAVE_ITTNOTIFY != 0 || defined(HPX_HAVE_MODULE_TRACY) +#if defined(HPX_HAVE_TRACING) mutex::mutex(char const* const description) : owner_id_(threads::invalid_thread_id) + , context_("hpx::mutex#", description) { HPX_ITT_SYNC_CREATE(this, "hpx::mutex", description); -#if defined(HPX_HAVE_MODULE_TRACY) - context_ = hpx::tracy::create(std::string("hpx::mutex") + description); -#endif } #endif -#if HPX_HAVE_ITTNOTIFY != 0 || defined(HPX_HAVE_MODULE_TRACY) +#if defined(HPX_HAVE_TRACING) mutex::~mutex() { HPX_ITT_SYNC_DESTROY(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::destroy(context_); -#endif } #else mutex::~mutex() = default; @@ -54,9 +47,7 @@ namespace hpx { HPX_ASSERT(threads::get_self_ptr() != nullptr); HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); { std::unique_lock l(mtx_); @@ -86,10 +77,8 @@ namespace hpx { } HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_); -#endif + context_.after_lock(); } bool mutex::try_lock(char const* /* description */, error_code& /* ec */) @@ -97,9 +86,7 @@ namespace hpx { HPX_ASSERT(threads::get_self_ptr() != nullptr); HPX_ITT_SYNC_PREPARE(this); -#if defined(HPX_HAVE_MODULE_TRACY) - bool const run_after = hpx::tracy::lock_prepare(context_); -#endif + bool const run_after = context_.before_lock(); { std::unique_lock l(mtx_); @@ -107,10 +94,8 @@ namespace hpx { if (owner_id_ != threads::invalid_thread_id) { HPX_ITT_SYNC_CANCEL(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, false); -#endif + context_.after_try_lock(false); return false; } @@ -119,10 +104,8 @@ namespace hpx { } HPX_ITT_SYNC_ACQUIRED(this); -#if defined(HPX_HAVE_MODULE_TRACY) if (run_after) - hpx::tracy::lock_acquired(context_, true); -#endif + context_.after_try_lock(true); return true; } @@ -148,9 +131,7 @@ namespace hpx { owner_id_ = threads::invalid_thread_id; HPX_ITT_SYNC_RELEASED(this); -#if defined(HPX_HAVE_MODULE_TRACY) - hpx::tracy::lock_released(context_); -#endif + context_.after_unlock(); { [[maybe_unused]] util::ignore_while_checking il(&l); diff --git a/libs/core/tracing/include/hpx/tracing/tracing.hpp b/libs/core/tracing/include/hpx/tracing/tracing.hpp index e508917f862f..f41ccf74f24e 100644 --- a/libs/core/tracing/include/hpx/tracing/tracing.hpp +++ b/libs/core/tracing/include/hpx/tracing/tracing.hpp @@ -93,6 +93,26 @@ namespace hpx::tracing { hpx::tracy::fiber_suspend_region impl; }; + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct HPX_CORE_EXPORT [[maybe_unused]] lock_context + { + explicit lock_context(char const* name = nullptr) noexcept; + explicit lock_context(char const* prefix, char const* suffix) noexcept; + + ~lock_context(); + + lock_context(lock_context const&) = delete; + lock_context& operator=(lock_context const&) = delete; + + bool before_lock() const noexcept; + void after_lock() const noexcept; + void after_try_lock(bool acquired) const noexcept; + void after_unlock() const noexcept; + + private: + hpx::tracy::lock_data impl; + }; + //////////////////////////////////////////////////////////////////////////// HPX_CXX_CORE_EXPORT HPX_CORE_EXPORT void set_thread_name( char const* name) noexcept; @@ -178,6 +198,24 @@ namespace hpx::tracing { constexpr explicit fiber_suspend_region(char const*) noexcept {} }; + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] lock_context + { + constexpr explicit lock_context(char const* = nullptr) noexcept {} + constexpr explicit lock_context(char const*, char const*) noexcept {} + + constexpr bool before_lock() const noexcept + { + return false; + } + + constexpr void after_lock() const noexcept {} + + constexpr void after_try_lock(bool) const noexcept {} + + constexpr void after_unlock() const noexcept {} + }; + //////////////////////////////////////////////////////////////////////////// HPX_CXX_CORE_EXPORT constexpr void set_thread_name(char const*) noexcept {} @@ -245,6 +283,24 @@ namespace hpx::tracing { constexpr explicit fiber_suspend_region(char const*) noexcept {} }; + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] lock_context + { + constexpr explicit lock_context(char const* = nullptr) noexcept {} + constexpr explicit lock_context(char const*, char const*) noexcept {} + + constexpr bool before_lock() const noexcept + { + return false; + } + + constexpr void after_lock() const noexcept {} + + constexpr void after_try_lock(bool) const noexcept {} + + constexpr void after_unlock() const noexcept {} + }; + //////////////////////////////////////////////////////////////////////////// HPX_CXX_CORE_EXPORT constexpr void set_thread_name(char const*) noexcept {} diff --git a/libs/core/tracing/src/tracing.cpp b/libs/core/tracing/src/tracing.cpp index ea15872ed6ef..4d10c41ff16f 100644 --- a/libs/core/tracing/src/tracing.cpp +++ b/libs/core/tracing/src/tracing.cpp @@ -8,6 +8,7 @@ #include #include +#include #if defined(HPX_HAVE_MODULE_TRACY) @@ -77,6 +78,44 @@ namespace hpx::tracing { fiber_suspend_region::~fiber_suspend_region() = default; + //////////////////////////////////////////////////////////////////////////// + // lock_context + + lock_context::lock_context(char const* name) noexcept + : impl(hpx::tracy::create(name)) + { + } + + lock_context::lock_context(char const* prefix, char const* suffix) noexcept + : impl(hpx::tracy::create(std::string(prefix) + suffix)) + { + } + + lock_context::~lock_context() + { + hpx::tracy::destroy(impl); + } + + bool lock_context::before_lock() const noexcept + { + return hpx::tracy::lock_prepare(impl); + } + + void lock_context::after_lock() const noexcept + { + hpx::tracy::lock_acquired(impl); + } + + void lock_context::after_try_lock(bool acquired) const noexcept + { + hpx::tracy::lock_acquired(impl, acquired); + } + + void lock_context::after_unlock() const noexcept + { + hpx::tracy::lock_released(impl); + } + //////////////////////////////////////////////////////////////////////////// // set_thread_name