diff --git a/.github/workflows/configure-test-combination.yml b/.github/workflows/configure-test-combination.yml index 06bc8fe7712..3549b04c2df 100644 --- a/.github/workflows/configure-test-combination.yml +++ b/.github/workflows/configure-test-combination.yml @@ -82,6 +82,23 @@ jobs: -DHPX_WITH_EXAMPLES=On rm -rf * + - name: Running CMake with invalid tracing combination (should fail) + working-directory: build + run: | + if cmake \ + .. \ + -G "Ninja" \ + -DHPX_WITH_MALLOC=system \ + -DHPX_WITH_FETCH_ASIO=Off \ + -DHPX_WITH_APEX=On \ + -DHPX_WITH_FETCH_APEX=ON \ + -DHPX_TRACY_WITH_TRACY=On \ + -DHPX_TRACY_WITH_FETCH_TRACY=ON; then + echo "CMake succeeded when it should have failed!" + exit 1 + fi + echo "CMake failed as expected." + rm -rf * - name: Upload build directory uses: actions/upload-artifact@v7 with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 11825c8de80..d0468591978 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1207,6 +1207,26 @@ 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) + if(HPX_WITH_NETWORKING) hpx_add_config_define(HPX_HAVE_NETWORKING) diff --git a/libs/core/thread_pools/include/hpx/thread_pools/scheduling_loop.hpp b/libs/core/thread_pools/include/hpx/thread_pools/scheduling_loop.hpp index b154fd145d4..d7e78fac0e8 100644 --- a/libs/core/thread_pools/include/hpx/thread_pools/scheduling_loop.hpp +++ b/libs/core/thread_pools/include/hpx/thread_pools/scheduling_loop.hpp @@ -18,11 +18,6 @@ #include #include -#if defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 && \ - !defined(HPX_HAVE_APEX) -#include -#endif - #include #include #include @@ -87,16 +82,7 @@ namespace hpx::threads::detail { scheduling_counters& counters, scheduling_callbacks& params) { std::atomic& this_state = scheduler.get_state(num_thread); - -#if defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 && \ - !defined(HPX_HAVE_APEX) - util::itt::stack_context ctx; // helper for itt support - util::itt::thread_domain const thread_domain; - util::itt::id threadid(thread_domain, &scheduler); - util::itt::string_handle const task_id("task_id"); - util::itt::string_handle const task_phase("task_phase"); - // util::itt::frame_context fctx(thread_domain); -#endif + hpx::tracing::loop_context trace_ctx; std::int64_t& idle_loop_count = counters.idle_loop_count_; std::int64_t& busy_loop_count = counters.busy_loop_count_; @@ -217,19 +203,7 @@ namespace hpx::threads::detail { is_active = false; }); -#if defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 && \ - !defined(HPX_HAVE_APEX) - util::itt::caller_context cctx( - ctx, !thrdptr->is_stackless()); - // util::itt::undo_frame_context undoframe(fctx); - util::itt::task task = - thrdptr->get_description().get_task_itt( - thread_domain); - task.add_metadata(task_id, thrdptr); - task.add_metadata( - task_phase, thrdptr->get_thread_phase()); -#endif - hpx::tracing::region rctx( + hpx::tracing::region rctx(trace_ctx, threads::get_region_init_data(thrdptr), num_thread); diff --git a/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp b/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp index 2f4025c1eb3..9eebd75a474 100644 --- a/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp +++ b/libs/core/threading_base/include/hpx/threading_base/thread_data.hpp @@ -677,6 +677,15 @@ namespace hpx::threads { HPX_CXX_CORE_EXPORT HPX_CORE_EXPORT tracing::fiber_region_init_data get_fiber_region_init_data(thread_data const* thrdptr); +#elif defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 + HPX_CXX_CORE_EXPORT HPX_CORE_EXPORT tracing::region_init_data + get_region_init_data(thread_data const* thrdptr); + + HPX_CXX_CORE_EXPORT constexpr tracing::fiber_region_init_data + get_fiber_region_init_data(thread_data const*) noexcept + { + return {}; + } #else HPX_CXX_CORE_EXPORT constexpr tracing::region_init_data get_region_init_data(thread_data const*) noexcept diff --git a/libs/core/threading_base/src/thread_data.cpp b/libs/core/threading_base/src/thread_data.cpp index c3bd7c90866..986f2797fbd 100644 --- a/libs/core/threading_base/src/thread_data.cpp +++ b/libs/core/threading_base/src/thread_data.cpp @@ -554,6 +554,19 @@ namespace hpx::threads { return {thrdptr->get_description().get_description(), thrdptr->get_tracy_fiber_name(), thrdptr->is_stackless()}; } +#elif defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 + tracing::region_init_data get_region_init_data(thread_data const* thrdptr) + { + threads::thread_description const desc = thrdptr->get_description(); + if (desc.kind() == threads::thread_description::data_type::description) + { + return {desc.get_description(), thrdptr->get_thread_phase(), + thrdptr, thrdptr->is_stackless(), 0, false, + desc.get_description_itt().handle_}; + } + return {"address", thrdptr->get_thread_phase(), thrdptr, + thrdptr->is_stackless(), desc.get_address(), true, nullptr}; + } #endif } // namespace hpx::threads diff --git a/libs/core/tracing/CMakeLists.txt b/libs/core/tracing/CMakeLists.txt index 8e1e48b668b..b86660a8e2f 100644 --- a/libs/core/tracing/CMakeLists.txt +++ b/libs/core/tracing/CMakeLists.txt @@ -12,6 +12,9 @@ set(tracing_module_dependencies hpx_config) if(HPX_TRACY_WITH_TRACY) list(APPEND tracing_module_dependencies hpx_tracy) endif() +if(HPX_WITH_ITTNOTIFY) + list(APPEND tracing_module_dependencies hpx_itt_notify) +endif() include(HPX_AddModule) add_hpx_module( diff --git a/libs/core/tracing/include/hpx/tracing/tracing.hpp b/libs/core/tracing/include/hpx/tracing/tracing.hpp index 5aefb847783..f67bad06c26 100644 --- a/libs/core/tracing/include/hpx/tracing/tracing.hpp +++ b/libs/core/tracing/include/hpx/tracing/tracing.hpp @@ -24,10 +24,22 @@ namespace hpx::tracing { bool is_stackless = false; }; + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct HPX_CORE_EXPORT [[maybe_unused]] loop_context + { + constexpr explicit loop_context() noexcept {} + + ~loop_context() = default; + + loop_context(loop_context const&) = delete; + loop_context& operator=(loop_context const&) = delete; + }; + + //////////////////////////////////////////////////////////////////////////// HPX_CXX_CORE_EXPORT struct HPX_CORE_EXPORT region { - explicit region( - region_init_data const& init_data, std::size_t num_thread) noexcept; + explicit region(loop_context&, region_init_data const& init_data, + std::size_t num_thread) noexcept; ~region(); @@ -87,6 +99,86 @@ namespace hpx::tracing { } // namespace hpx::tracing +#elif defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 +#include + +namespace hpx::tracing { + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct region_init_data + { + char const* name = nullptr; + std::size_t thread_phase = 0; + void const* thread_ptr = nullptr; + bool is_stackless = false; + std::size_t address = 0; + bool is_address_type = false; + void* itt_string_handle = nullptr; + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct HPX_CORE_EXPORT loop_context + { + explicit loop_context() noexcept; + ~loop_context(); + + loop_context(loop_context const&) = delete; + loop_context& operator=(loop_context const&) = delete; + + util::itt::stack_context stack_ctx; + util::itt::thread_domain thread_domain; + util::itt::string_handle task_id; + util::itt::string_handle task_phase; + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct HPX_CORE_EXPORT region + { + explicit region( + loop_context& ctx, region_init_data const& data, std::size_t); + ~region(); + + region(region const&) = delete; + region& operator=(region const&) = delete; + + private: + static util::itt::task make_task( + loop_context& ctx, region_init_data const& data); + + util::itt::caller_context cctx; + util::itt::task task; + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] mark_event + { + constexpr explicit mark_event(char const*) noexcept {} + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct fiber_region_init_data + { + }; + + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] fiber_region + { + constexpr explicit fiber_region( + fiber_region_init_data const&, std::size_t) noexcept + { + } + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] fiber_suspend_region + { + constexpr explicit fiber_suspend_region(char const*) noexcept {} + }; + + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT constexpr void set_thread_name(char const*) noexcept {} + +} // namespace hpx::tracing + #else namespace hpx::tracing { @@ -96,9 +188,22 @@ namespace hpx::tracing { { }; + //////////////////////////////////////////////////////////////////////////// + HPX_CXX_CORE_EXPORT struct [[maybe_unused]] loop_context + { + constexpr explicit loop_context() noexcept {} + + ~loop_context() = default; + + loop_context(loop_context const&) = delete; + loop_context& operator=(loop_context const&) = delete; + }; + + //////////////////////////////////////////////////////////////////////////// HPX_CXX_CORE_EXPORT struct [[maybe_unused]] region { - constexpr explicit region(region_init_data const&, std::size_t) noexcept + constexpr explicit region( + loop_context&, region_init_data const&, std::size_t) noexcept { } }; diff --git a/libs/core/tracing/src/tracing.cpp b/libs/core/tracing/src/tracing.cpp index c586b128261..808786d10d5 100644 --- a/libs/core/tracing/src/tracing.cpp +++ b/libs/core/tracing/src/tracing.cpp @@ -24,8 +24,8 @@ namespace hpx::tracing { data.name, num_thread, data.thread_phase, enabled); } - region::region( - region_init_data const& data, std::size_t const num_thread) noexcept + region::region(loop_context&, region_init_data const& data, + std::size_t const num_thread) noexcept : impl(create_tracy_region(data, num_thread)) { } @@ -87,4 +87,52 @@ namespace hpx::tracing { } // namespace hpx::tracing +#elif defined(HPX_HAVE_ITTNOTIFY) && HPX_HAVE_ITTNOTIFY != 0 + +namespace hpx::tracing { + + //////////////////////////////////////////////////////////////////////////// + // loop_context + + loop_context::loop_context() noexcept + : task_id("task_id") + , task_phase("task_phase") + { + } + + loop_context::~loop_context() = default; + + //////////////////////////////////////////////////////////////////////////// + // region + + util::itt::task region::make_task( + loop_context& ctx, region_init_data const& data) + { + if (data.is_address_type) + { + return util::itt::task(ctx.thread_domain, + util::itt::string_handle("address"), data.address); + } + if (data.itt_string_handle != nullptr) + { + return util::itt::task(ctx.thread_domain, + util::itt::string_handle(static_cast<___itt_string_handle*>( + data.itt_string_handle))); + } + return util::itt::task( + ctx.thread_domain, util::itt::string_handle(data.name)); + } + + region::region(loop_context& ctx, region_init_data const& data, std::size_t) + : cctx(ctx.stack_ctx, !data.is_stackless) + , task(make_task(ctx, data)) + { + task.add_metadata(ctx.task_id, data.thread_ptr); + task.add_metadata(ctx.task_phase, data.thread_phase); + } + + region::~region() = default; + +} // namespace hpx::tracing + #endif