From ec87a2fd466669bb99141a98d1238c26de84843c Mon Sep 17 00:00:00 2001 From: "Vivek, Kale" Date: Mon, 20 Jul 2026 22:10:26 +0000 Subject: [PATCH 1/6] refactor(rocprofiler-sdk): migrate PC sampling off the per-queue callback registry Isolates the PC-sampling slice of the callback-removal effort (reference PRs #8730 / #8586) into a small, single-service change, per review guidance to land callback removal one service at a time. Independent of kernel replay. PC sampling no longer registers a queue_callbacks_t with the HSA queue controller in pc_sampling_service_finish_configuration. Instead: - pc_sampling::signal_completion_hook (new pc_sampling/queue_hooks.{hpp,cpp}) delivers kernel completion to the CID manager; it is called explicitly from the HSA async signal handler in hsa/queue.cpp. kernel_completion_cb is moved out of the anonymous namespace and declared in hsa_adapter.hpp. - pc_sampling::is_configured_on_agent replaces the queue.get_notifiers() signal the old registration used to provide, so the write interceptor still injects the marker packet for PC-only runs. It is always linkable (guarded by ROCPROFILER_SDK_HSA_PC_SAMPLING) and compiled before the pc_sampling CMake early-return so it links even without HSA PC sampling support. The marker packet injection in the write interceptor is unchanged (it was never registry-based). Removes the now-unused intercept_cb_id from PCSAgentSession and adds a queue_hooks unit test. The per-queue callback registry is retained for the remaining service (thread-trace/spm/counters migrate in their own PRs). Co-authored-by: Cursor --- .../source/lib/rocprofiler-sdk/hsa/queue.cpp | 11 +++ .../pc_sampling/CMakeLists.txt | 6 ++ .../pc_sampling/hsa_adapter.cpp | 41 ++++------- .../pc_sampling/hsa_adapter.hpp | 8 +++ .../pc_sampling/queue_hooks.cpp | 68 +++++++++++++++++++ .../pc_sampling/queue_hooks.hpp | 58 ++++++++++++++++ .../pc_sampling/tests/CMakeLists.txt | 3 +- .../pc_sampling/tests/queue_hooks_test.cpp | 40 +++++++++++ .../lib/rocprofiler-sdk/pc_sampling/types.hpp | 1 - 9 files changed, 205 insertions(+), 31 deletions(-) create mode 100644 projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp create mode 100644 projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp create mode 100644 projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp index 63561e628687..03d33873b7bb 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp @@ -38,6 +38,7 @@ #include "lib/rocprofiler-sdk/kernel_dispatch/profiling_time.hpp" #include "lib/rocprofiler-sdk/kernel_dispatch/tracing.hpp" #include "lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp" +#include "lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp" #include "lib/rocprofiler-sdk/pc_sampling/service.hpp" #include "lib/rocprofiler-sdk/registration.hpp" #include "lib/rocprofiler-sdk/tracing/tracing.hpp" @@ -168,6 +169,15 @@ AsyncSignalHandler(hsa_signal_value_t /*signal_v*/, void* data) } }); + // PC sampling completion is no longer routed through the per-queue + // callback registry; invoke its hook explicitly. + pc_sampling::signal_completion_hook(queue_info_session.queue, + packet.kernel_packet, + _session, + packet, + packet.instrumentation_packets, + dispatch_time); + if(packet.is_serialized) { CHECK_NOTNULL(hsa::get_queue_controller()) @@ -307,6 +317,7 @@ WriteInterceptor(const void* packets, const bool graph_launch_active = (gls != nullptr); const bool no_real_consumers = (queue.get_notifiers() == 0 && + !pc_sampling::is_configured_on_agent(queue.get_agent().get_rocp_agent()->id) && context::get_active_contexts(full_packet_instrumentation_context_filter).empty()); if(pkt_count == 0 || (no_real_consumers && !graph_launch_active)) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/CMakeLists.txt b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/CMakeLists.txt index 2f86982bfe42..415eae53d721 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/CMakeLists.txt +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/CMakeLists.txt @@ -4,6 +4,12 @@ # add_subdirectory(parser) +# queue_hooks provides always-linkable shims (is_configured_on_agent / +# signal_completion_hook) that the HSA queue interceptor calls unconditionally, so it must +# compile even when PC sampling HSA support is unavailable (its body is guarded by +# ROCPROFILER_SDK_HSA_PC_SAMPLING). Add it before the early return. +target_sources(rocprofiler-sdk-object-library PRIVATE queue_hooks.cpp queue_hooks.hpp) + if(hsa-runtime64_VERSION AND hsa-runtime64_VERSION VERSION_LESS 1.14.0) return() endif() diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp index fe2052d12c0e..90c3416a780e 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp @@ -123,8 +123,12 @@ amd_intercept_marker_handler_callback(const struct amd_aql_intercept_marker_s* p parser->newDispatch(dispatch_pkt); } +} // namespace + /** - * Callback called by HSA interceptor when the kernel has completed. + * Callback called by HSA interceptor when the kernel has completed. Declared in + * hsa_adapter.hpp and invoked from pc_sampling::signal_completion_hook (see + * pc_sampling/queue_hooks.cpp), so it lives outside the anonymous namespace. */ void kernel_completion_cb(const rocprofiler_agent_t* rocp_agent, @@ -145,6 +149,8 @@ kernel_completion_cb(const rocprofiler_agent_t* rocp_agent, agent_session->cid_manager->cid_async_activity_completed(session.correlation_id); } +namespace +{ void data_ready_callback(void* client_callback_data, size_t data_size, @@ -345,34 +351,11 @@ pc_sampling_service_finish_configuration(context::pc_sampling_service* service) } } - using external_corr_id_map_t = ::rocprofiler::hsa::queue_info_session_t::external_corr_id_map_t; - - // Register callbacks for the HSA's queue interceptor. - // TODO: should we store callback ID in the service? - rocprofiler::hsa::get_queue_controller()->add_callback( - std::nullopt, - ::rocprofiler::hsa::queue_callbacks_t{ - .batch_packets = []() { return true; }, - .write_interceptor = - [](const rocprofiler::hsa::Queue&, - const rocprofiler::hsa::rocprofiler_packet&, - rocprofiler_kernel_id_t /*kernel_id*/, - rocprofiler_dispatch_id_t /*dispatch_id*/, - rocprofiler_user_data_t*, - const external_corr_id_map_t&, - const context::correlation_id*) { - return rocprofiler::hsa::write_packet_t{nullptr, false}; - }, - // Completion CB - .signal_completion = - [](const rocprofiler::hsa::Queue& q, - rocprofiler::hsa::rocprofiler_packet kern_pkt, - std::shared_ptr& session, - rocprofiler::hsa::packet_data_t& /*packet*/, - rocprofiler::hsa::inst_pkt_t&, - kernel_dispatch::profiling_time) { - kernel_completion_cb(q.get_agent().get_rocp_agent(), kern_pkt, *session); - }}); + // PC sampling no longer registers a per-queue callback with the HSA queue + // controller. Kernel completion is delivered explicitly via + // pc_sampling::signal_completion_hook, called from the HSA async signal + // handler (see hsa/queue.cpp). The marker packet is still injected directly + // in the write interceptor, gated by pc_sampling::is_configured_on_agent. } rocprofiler_status_t diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp index 06010bdb0718..b3312bb357ad 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp @@ -54,6 +54,14 @@ pc_sampling_service_stop(context::pc_sampling_service* service); void pc_sampling_service_finish_configuration(context::pc_sampling_service* service); +// Notifies the CID manager that the kernel's correlation ID has completed. +// Invoked from pc_sampling::signal_completion_hook (pc_sampling/queue_hooks.cpp), +// which is called by the HSA async signal handler in hsa/queue.cpp. +void +kernel_completion_cb(const rocprofiler_agent_t* rocp_agent, + rocprofiler::hsa::rocprofiler_packet& kernel_pkt, + const rocprofiler::hsa::queue_info_session_t& session); + rocprofiler_status_t flush_internal_agent_buffers(const PCSAgentSession* agent_session); } // namespace hsa diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp new file mode 100644 index 000000000000..3797fa002628 --- /dev/null +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp @@ -0,0 +1,68 @@ +// MIT License +// +// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp" + +#include "lib/rocprofiler-sdk/pc_sampling/defines.hpp" + +#if ROCPROFILER_SDK_HSA_PC_SAMPLING > 0 +# include "lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp" +# include "lib/rocprofiler-sdk/pc_sampling/service.hpp" +#endif + +namespace rocprofiler +{ +namespace pc_sampling +{ +bool +is_configured_on_agent(rocprofiler_agent_id_t agent_id) +{ +#if ROCPROFILER_SDK_HSA_PC_SAMPLING > 0 + return is_pc_sample_service_configured(agent_id); +#else + (void) agent_id; + return false; +#endif +} + +void +signal_completion_hook(const ::rocprofiler::hsa::Queue& queue, + const ::rocprofiler::hsa::rocprofiler_packet& kernel_packet, + std::shared_ptr<::rocprofiler::hsa::queue_info_session_t>& session, + ::rocprofiler::hsa::packet_data_t& /*packet*/, + ::rocprofiler::hsa::inst_pkt_t& /*inst_pkt*/, + kernel_dispatch::profiling_time /*dispatch_time*/) +{ +#if ROCPROFILER_SDK_HSA_PC_SAMPLING > 0 + if(!session) return; + // kernel_completion_cb takes a mutable reference to the kernel packet even + // though it does not modify it; copy to bind a non-const lvalue. + auto kern_pkt = kernel_packet; + hsa::kernel_completion_cb(queue.get_agent().get_rocp_agent(), kern_pkt, *session); +#else + (void) queue; + (void) kernel_packet; + (void) session; +#endif +} +} // namespace pc_sampling +} // namespace rocprofiler diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp new file mode 100644 index 000000000000..55dcef38bef3 --- /dev/null +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp @@ -0,0 +1,58 @@ +// MIT License +// +// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "lib/rocprofiler-sdk/hsa/queue.hpp" +#include "lib/rocprofiler-sdk/hsa/queue_info_session.hpp" +#include "lib/rocprofiler-sdk/hsa/rocprofiler_packet.hpp" +#include "lib/rocprofiler-sdk/kernel_dispatch/profiling_time.hpp" + +#include + +#include + +namespace rocprofiler +{ +namespace pc_sampling +{ +// True if the PC sampling service is configured on the given agent. Always +// linkable: returns false when PC sampling HSA support is unavailable. Used by +// the HSA write interceptor gate (in place of the per-queue callback that used +// to keep queue.get_notifiers() > 0) to decide whether a marker packet must be +// injected for this dispatch. +bool +is_configured_on_agent(rocprofiler_agent_id_t agent_id); + +// Explicit replacement for the PC-sampling per-queue completion callback that +// used to be registered with the HSA queue controller. Notifies the CID manager +// that the kernel's correlation ID has completed. No-op when PC sampling HSA +// support is unavailable or when the service is not configured on the agent. +void +signal_completion_hook(const ::rocprofiler::hsa::Queue& queue, + const ::rocprofiler::hsa::rocprofiler_packet& kernel_packet, + std::shared_ptr<::rocprofiler::hsa::queue_info_session_t>& session, + ::rocprofiler::hsa::packet_data_t& packet, + ::rocprofiler::hsa::inst_pkt_t& inst_pkt, + kernel_dispatch::profiling_time dispatch_time); +} // namespace pc_sampling +} // namespace rocprofiler diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/CMakeLists.txt b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/CMakeLists.txt index 63c87def7239..18569d3d7c9a 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/CMakeLists.txt +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/CMakeLists.txt @@ -8,7 +8,8 @@ set(ROCPROFILER_LIB_PC_SAMPLING_TEST_SOURCES # samples_processing.cpp pc_sampling_vs_counter_collection.cpp query_configuration.cpp - multiple_contexts_one_per_agent.cpp) + multiple_contexts_one_per_agent.cpp + queue_hooks_test.cpp) set(ROCPROFILER_LIB_PC_SAMPLING_TEST_HEADERS pc_sampling_internals.hpp) add_executable(pcs-test) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp new file mode 100644 index 000000000000..337c8d05fa62 --- /dev/null +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp @@ -0,0 +1,40 @@ +// MIT License +// +// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include "lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp" + +#include + +namespace +{ +// is_configured_on_agent replaces the queue.get_notifiers() signal that the old +// per-queue callback registration used to provide to the HSA write interceptor +// gate. With no PC sampling service configured, any agent id must report as not +// configured. This is always linkable regardless of HSA PC sampling support and +// requires no GPU / HSA runtime. +TEST(pc_sampling_queue_hooks, is_configured_on_agent_unconfigured) +{ + rocprofiler_agent_id_t agent_id; + agent_id.handle = 123456; + EXPECT_FALSE(rocprofiler::pc_sampling::is_configured_on_agent(agent_id)); +} +} // namespace diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/types.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/types.hpp index dbcc558bbff9..75922c2dea70 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/types.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/types.hpp @@ -57,7 +57,6 @@ struct PCSAgentSession #if ROCPROFILER_SDK_HSA_PC_SAMPLING > 0 hsa_ven_amd_pcs_t hsa_pc_sampling = {}; #endif - hsa::ClientID intercept_cb_id = -1; // ioctl relevant information uint32_t ioctl_pcs_id = 0; // PC sampling parser From 959b1dac8279363277bb20e861e0016e986c6ddb Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 19 Aug 2026 20:28:31 +0000 Subject: [PATCH 2/6] test(rocprofiler-sdk): PC sampling completion hook null-session safety Co-authored-by: Vivek Kale --- .../pc_sampling/tests/queue_hooks_test.cpp | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp index 337c8d05fa62..ea420c7fa5b6 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp @@ -17,8 +17,8 @@ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. #include "lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp" @@ -37,4 +37,22 @@ TEST(pc_sampling_queue_hooks, is_configured_on_agent_unconfigured) agent_id.handle = 123456; EXPECT_FALSE(rocprofiler::pc_sampling::is_configured_on_agent(agent_id)); } + +TEST(pc_sampling_queue_hooks, signal_completion_hook_null_session_is_noop) +{ + rocprofiler::hsa::rocprofiler_packet kern_pkt{}; + std::shared_ptr null_session; + rocprofiler::hsa::packet_data_t packet{}; + rocprofiler::hsa::inst_pkt_t inst_pkt{}; + + rocprofiler::pc_sampling::signal_completion_hook( + *reinterpret_cast(nullptr), + kern_pkt, + null_session, + packet, + inst_pkt, + rocprofiler::kernel_dispatch::profiling_time{}); + + SUCCEED(); +} } // namespace From 062e4c393d92cacccf74d2a20d816bdf78e3f7ed Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 18 Sep 2026 05:49:28 +0000 Subject: [PATCH 3/6] docs(rocprofiler-sdk): explain why the PC sampling compile gate stays at the shim Review asked whether the ROCPROFILER_SDK_HSA_PC_SAMPLING guard could move into is_pc_sample_service_configured instead of living in a separate wrapper. It cannot: queue_hooks.cpp is added to the object library before the early return in CMakeLists.txt so it is always built, while service.cpp defines that function after the early return and is not built when PC sampling is compiled out. Moving the guard would leave the write interceptor with an undefined symbol in that configuration. Record the constraint at the shim so the next reader does not retry the change, and bump the copyright year on the new files to 2026. (cherry picked from commit fa38a0168e7e8c389daba2251fd66785775a14cd) --- .../source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp | 7 ++++++- .../source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp | 2 +- .../rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp index 3797fa002628..ca39d14b5ffa 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -33,6 +33,11 @@ namespace rocprofiler { namespace pc_sampling { +// The compile gate cannot move into is_pc_sample_service_configured: this file is +// added to the object library before the early return in CMakeLists.txt, so it is +// always built, while service.cpp (which defines that function) is added after and +// is absent from the build when PC sampling is compiled out. The guard has to stay +// at the call site to keep the write interceptor linkable in that configuration. bool is_configured_on_agent(rocprofiler_agent_id_t agent_id) { diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp index 55dcef38bef3..97f817c59ee0 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp index ea420c7fa5b6..a71625105318 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp @@ -1,6 +1,6 @@ // MIT License // -// Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +// Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal From 1164d5bf5a4f88ec74753014394f72d14fd9ea5d Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Fri, 18 Sep 2026 05:58:02 +0000 Subject: [PATCH 4/6] fix(rocprofiler-sdk): avoid UB and redundant work in the PC sampling completion hook Three review findings on the completion path: The hook took the queue by reference, so the unit test covering the null-session early return had to synthesize one by dereferencing a null pointer. That is undefined behaviour at argument construction even though the hook returns before touching the queue. Take the queue by pointer instead, which lets the test pass nullptr honestly and documents that the callee must not assume a queue exists. kernel_completion_cb took a mutable reference to a packet it never modifies, forcing the hook to copy the kernel packet on every completion. Make the parameter const and drop the copy. The configured-agent check lived inside kernel_completion_cb, after that copy, so a process with any interceptor active paid the cost on every dispatch even when PC sampling was never configured. The registry-based path cost nothing until a callback was registered. Check is_pc_sample_service_configured in the hook before doing any work, restoring that property; kernel_completion_cb has one caller, so the check is not lost. Also drops a stale kernel_completion_cb declaration in pc_sampling_internals.hpp that still described the removed registry signature, and corrects two comments that referred to the old callback mechanism. (cherry picked from commit c93f8dd646e9059e07e2b12bf115c5da433ccdc9) --- .../source/lib/rocprofiler-sdk/hsa/queue.cpp | 6 +++--- .../lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp | 8 +++----- .../lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp | 2 +- .../lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp | 11 ++++++----- .../lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp | 2 +- .../pc_sampling/tests/pc_sampling_internals.hpp | 8 -------- .../pc_sampling/tests/queue_hooks_test.cpp | 4 ++-- 7 files changed, 16 insertions(+), 25 deletions(-) diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp index 03d33873b7bb..c0f25f2ad492 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/hsa/queue.cpp @@ -171,7 +171,7 @@ AsyncSignalHandler(hsa_signal_value_t /*signal_v*/, void* data) // PC sampling completion is no longer routed through the per-queue // callback registry; invoke its hook explicitly. - pc_sampling::signal_completion_hook(queue_info_session.queue, + pc_sampling::signal_completion_hook(&queue_info_session.queue, packet.kernel_packet, _session, packet, @@ -367,8 +367,8 @@ WriteInterceptor(const void* packets, return; } - // these are for the services (dispatch counter collection, pc sampling, ATT) which use - // the queue/queue_controller callback mechanism + // Services that attach packet instrumentation or need dispatch correlation data. Some are + // still routed through queue-controller callbacks while migrated services use explicit hooks. const auto queue_callback_context_filter = [](const context::context* ctx) { return (ctx->dispatch_counter_collection || ctx->pc_sampler || ctx->dispatch_thread_trace || ctx->dispatch_spm); diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp index 90c3416a780e..f9baa3ce6c91 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.cpp @@ -132,15 +132,13 @@ amd_intercept_marker_handler_callback(const struct amd_aql_intercept_marker_s* p */ void kernel_completion_cb(const rocprofiler_agent_t* rocp_agent, - rocprofiler::hsa::rocprofiler_packet& /*kernel_pkt*/, + const rocprofiler::hsa::rocprofiler_packet& /*kernel_pkt*/, const rocprofiler::hsa::queue_info_session_t& session) { // No internal correlation IDs, meaning there is no need to call CID manager. if(!session.correlation_id) return; - // Check if the PC sampling service is configured on this agent. - if(!is_pc_sample_service_configured(rocp_agent->id)) return; - + // signal_completion_hook verifies that the service is configured before forwarding here. auto* agent_session = get_agent_session(rocp_agent->id); ROCP_FATAL_IF(agent_session == nullptr) << "No PC sampling sessions configured for the agent where kernel completion " @@ -355,7 +353,7 @@ pc_sampling_service_finish_configuration(context::pc_sampling_service* service) // controller. Kernel completion is delivered explicitly via // pc_sampling::signal_completion_hook, called from the HSA async signal // handler (see hsa/queue.cpp). The marker packet is still injected directly - // in the write interceptor, gated by pc_sampling::is_configured_on_agent. + // in the write interceptor, gated by is_pc_sample_service_configured. } rocprofiler_status_t diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp index b3312bb357ad..e290b3ac782c 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/hsa_adapter.hpp @@ -59,7 +59,7 @@ pc_sampling_service_finish_configuration(context::pc_sampling_service* service); // which is called by the HSA async signal handler in hsa/queue.cpp. void kernel_completion_cb(const rocprofiler_agent_t* rocp_agent, - rocprofiler::hsa::rocprofiler_packet& kernel_pkt, + const rocprofiler::hsa::rocprofiler_packet& kernel_pkt, const rocprofiler::hsa::queue_info_session_t& session); rocprofiler_status_t diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp index ca39d14b5ffa..9f6624ce9596 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.cpp @@ -50,7 +50,7 @@ is_configured_on_agent(rocprofiler_agent_id_t agent_id) } void -signal_completion_hook(const ::rocprofiler::hsa::Queue& queue, +signal_completion_hook(const ::rocprofiler::hsa::Queue* queue, const ::rocprofiler::hsa::rocprofiler_packet& kernel_packet, std::shared_ptr<::rocprofiler::hsa::queue_info_session_t>& session, ::rocprofiler::hsa::packet_data_t& /*packet*/, @@ -59,10 +59,11 @@ signal_completion_hook(const ::rocprofiler::hsa::Queue& { #if ROCPROFILER_SDK_HSA_PC_SAMPLING > 0 if(!session) return; - // kernel_completion_cb takes a mutable reference to the kernel packet even - // though it does not modify it; copy to bind a non-const lvalue. - auto kern_pkt = kernel_packet; - hsa::kernel_completion_cb(queue.get_agent().get_rocp_agent(), kern_pkt, *session); + CHECK(queue); + const auto* agent = queue->get_agent().get_rocp_agent(); + CHECK(agent); + if(!is_pc_sample_service_configured(agent->id)) return; + hsa::kernel_completion_cb(agent, kernel_packet, *session); #else (void) queue; (void) kernel_packet; diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp index 97f817c59ee0..d694e7e4c247 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/queue_hooks.hpp @@ -48,7 +48,7 @@ is_configured_on_agent(rocprofiler_agent_id_t agent_id); // that the kernel's correlation ID has completed. No-op when PC sampling HSA // support is unavailable or when the service is not configured on the agent. void -signal_completion_hook(const ::rocprofiler::hsa::Queue& queue, +signal_completion_hook(const ::rocprofiler::hsa::Queue* queue, const ::rocprofiler::hsa::rocprofiler_packet& kernel_packet, std::shared_ptr<::rocprofiler::hsa::queue_info_session_t>& session, ::rocprofiler::hsa::packet_data_t& packet, diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_internals.hpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_internals.hpp index ef63c3b4440f..032698012395 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_internals.hpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/pc_sampling_internals.hpp @@ -40,14 +40,6 @@ amd_intercept_marker_handler_callback(const struct amd_aql_intercept_marker_s* p hsa_queue_t* queue, uint64_t packet_id); -extern void -kernel_completion_cb(const std::shared_ptr& info, - const rocprofiler_agent_t* rocp_agent, - rocprofiler::hsa::ClientID client_id, - const rocprofiler::hsa::rocprofiler_packet& kernel_pkt, - const rocprofiler::hsa::queue_info_session_t& session, - std::unique_ptr pkt); - extern void data_ready_callback(void* client_callback_data, size_t data_size, diff --git a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp index a71625105318..0384abb92559 100644 --- a/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp +++ b/projects/rocprofiler-sdk/source/lib/rocprofiler-sdk/pc_sampling/tests/queue_hooks_test.cpp @@ -40,13 +40,13 @@ TEST(pc_sampling_queue_hooks, is_configured_on_agent_unconfigured) TEST(pc_sampling_queue_hooks, signal_completion_hook_null_session_is_noop) { - rocprofiler::hsa::rocprofiler_packet kern_pkt{}; + rocprofiler::hsa::rocprofiler_packet kern_pkt{}; std::shared_ptr null_session; rocprofiler::hsa::packet_data_t packet{}; rocprofiler::hsa::inst_pkt_t inst_pkt{}; rocprofiler::pc_sampling::signal_completion_hook( - *reinterpret_cast(nullptr), + nullptr, kern_pkt, null_session, packet, From 9c3795513ab0f8505d42e08af3a7da36c7b77203 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 21 Sep 2026 05:54:33 +0000 Subject: [PATCH 5/6] ci(rocprofiler-sdk): repair code coverage and ROCm release compatibility jobs Both workflows failed before compiling any rocprofiler-sdk source. Code coverage died installing ROCR-Runtime with 'CMake 3.25 or higher is required. You are running version 3.22.1', and release compatibility died resolving find_dependency(NUMA) from hsakmt-config.cmake on the 'latest' ROCm container. This branch predates the fixes for both on develop, so take develop's versions of the two workflows and of the rocprofiler-sdk-util action they depend on. The action change is additive -- python-venv-path defaults to empty and is guarded -- so the continuous integration workflow, which does not pass it, is unaffected. The pinned CMake is held at 3.25 rather than develop's 4.x. The external submodules on this branch (json, pybind11, sqlite, yaml-cpp) still declare cmake_minimum_required below 3.5, which CMake 4 rejects outright, so 4.x would trade one configure failure for another. Co-authored-by: Vivek Kale --- .../actions/rocprofiler-sdk-util/action.yml | 61 +++- .../resolve-ci-config/action.yml | 58 +++- .../resolve-ci-config/resolve_ci_config.py | 82 +++-- .../test_resolve_ci_config.py | 326 ++++++++++++++++++ .../rocprofiler-sdk-code_coverage.yml | 34 +- ...rofiler-sdk-rocm_release_compatibility.yml | 12 +- 6 files changed, 531 insertions(+), 42 deletions(-) create mode 100644 .github/actions/rocprofiler-sdk-util/resolve-ci-config/test_resolve_ci_config.py diff --git a/.github/actions/rocprofiler-sdk-util/action.yml b/.github/actions/rocprofiler-sdk-util/action.yml index a34f2b51ea44..7dd1e0a8bf64 100644 --- a/.github/actions/rocprofiler-sdk-util/action.yml +++ b/.github/actions/rocprofiler-sdk-util/action.yml @@ -6,6 +6,10 @@ inputs: description: 'Path to ROCm installation' required: false default: '/opt/rocm' + python-venv-path: + description: 'Python virtual environment with the pinned cmake, relative to the workspace' + required: false + default: '' gpu-target: description: 'GPU target (e.g., gfx94X, gfx110X, gfx120X)' required: true @@ -37,6 +41,10 @@ inputs: description: 'Enable ROCJPEG build' required: false default: 'false' + enable-hipfile-build: + description: 'Enable hipFILE build' + required: false + default: 'false' enable-rocprof-trace-decoder-build: description: 'Enable rocprof-trace-decoder build' required: false @@ -70,13 +78,6 @@ inputs: runs: using: 'composite' steps: - - name: Setup environment variables - shell: bash - run: | - echo "PKG_CONFIG_PATH=/opt/amdgpu/lib64/pkgconfig:/opt/amdgpu/lib/pkgconfig:/opt/amdgpu/lib/$(uname -p)-linux-gnu/pkgconfig:${PKG_CONFIG_PATH}" >> $GITHUB_ENV - echo "LD_LIBRARY_PATH=${{ inputs.rocm-path }}/lib64:${{ inputs.rocm-path }}/lib:${{ inputs.rocm-path }}/llvm/lib:${LD_LIBRARY_PATH}" >> $GITHUB_ENV - echo "PATH=${{ inputs.rocm-path }}/bin:${{ inputs.rocm-path }}/llvm/bin:$HOME/.local/bin:${PATH}" >> $GITHUB_ENV - - name: Setup ccache if: ${{ inputs.enable-ccache == 'true' }} uses: hendrikmuhs/ccache-action@63069e3931dedbf3b63792097479563182fe70d1 # v1.2.18 @@ -98,6 +99,16 @@ runs: echo "Warning: Compiler launcher ${{ inputs.compiler-launcher }} not found or not executable" fi + - name: Setup environment variables + shell: bash + run: | + if [ -n "${{ inputs.python-venv-path }}" ]; then + echo "${GITHUB_WORKSPACE}/${{ inputs.python-venv-path }}/bin" >> $GITHUB_PATH + fi + echo "PKG_CONFIG_PATH=/opt/amdgpu/lib64/pkgconfig:/opt/amdgpu/lib/pkgconfig:/opt/amdgpu/lib/$(uname -p)-linux-gnu/pkgconfig:${PKG_CONFIG_PATH}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${{ inputs.rocm-path }}/lib64:${{ inputs.rocm-path }}/lib:${{ inputs.rocm-path }}/llvm/lib:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + echo "PATH=${{ inputs.rocm-path }}/bin:${{ inputs.rocm-path }}/llvm/bin:$HOME/.local/bin:${PATH}" >> $GITHUB_ENV + - name: Build and Install ROCR-Runtime if: ${{ inputs.enable-rocr-build == 'true' }} shell: bash @@ -149,7 +160,7 @@ runs: shell: bash working-directory: projects/rocprofiler-register run: | - export PATH=${{ inputs.rocm-path }}/bin:${{ inputs.rocm-path }}/llvm/bin:/usr/local/bin:~/.local/bin:$PATH + export PATH=${{ inputs.rocm-path }}/bin:${{ inputs.rocm-path }}/llvm/bin:${PATH}:/usr/local/bin echo "Install ROCProfiler-Register" cmake -B build-rocprofiler-register \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ @@ -163,6 +174,40 @@ runs: cmake --build build-rocprofiler-register --target install echo "✅ ROCProfiler-Register Installation complete!" + - name: Build and Install hipFILE + if: ${{ inputs.enable-hipfile-build == 'true' }} + shell: bash + working-directory: projects/hipfile + run: | + export ROCM_PATH=${{ inputs.rocm-path }} + export HIP_PLATFORM=amd + export LD_LIBRARY_PATH=${{ inputs.rocm-path }}/lib:${{ inputs.rocm-path }}/lib/rocm_sysdeps/lib:${{ inputs.rocm-path }}/llvm/lib:$LD_LIBRARY_PATH + export PATH=${{ inputs.rocm-path }}/bin:${{ inputs.rocm-path }}/llvm/bin:${PATH}:/usr/local/bin + # Temporary workaround until hipFILE adds the ROCm sysdeps include path for libmount. + if [ -f "${ROCM_PATH}/lib/rocm_sysdeps/include/libmount/libmount.h" ]; then + install -D -m 0644 \ + "${ROCM_PATH}/lib/rocm_sysdeps/include/libmount/libmount.h" \ + "${ROCM_PATH}/include/libmount/libmount.h" + fi + echo "Install hipFILE..." + cmake -B build-hipfile \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCMAKE_CXX_COMPILER=${{ inputs.rocm-path }}/llvm/bin/amdclang++ \ + -DCMAKE_HIP_PLATFORM=amd \ + -DCMAKE_PREFIX_PATH='${{ inputs.rocm-path }};${{ inputs.rocm-path }}/llvm;${{ inputs.rocm-path }}/lib/rocm_sysdeps' \ + -DCMAKE_LIBRARY_PATH=${{ inputs.rocm-path }}/lib/rocm_sysdeps/lib \ + -DCMAKE_INCLUDE_PATH=${{ inputs.rocm-path }}/lib/rocm_sysdeps/include \ + -DCMAKE_INSTALL_PREFIX=${{ inputs.rocm-path }} \ + -DCMAKE_C_COMPILER_LAUNCHER=${{ inputs.compiler-launcher }} \ + -DCMAKE_CXX_COMPILER_LAUNCHER=${{ inputs.compiler-launcher }} \ + -DBUILD_TESTING=OFF \ + -DAIS_INSTALL_EXAMPLES=OFF \ + -DAIS_INSTALL_TOOLS=OFF \ + . + cmake --build build-hipfile --target hipfile --parallel ${{ inputs.build-jobs }} + cmake --build build-hipfile --target install + echo "✅ hipFILE Installation complete!" + - name: Build and Install Aqlprofile if: ${{ inputs.enable-aqlprofile-build == 'true' }} shell: bash diff --git a/.github/actions/rocprofiler-sdk-util/resolve-ci-config/action.yml b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/action.yml index 6060d1560c7b..a5a878ceed99 100644 --- a/.github/actions/rocprofiler-sdk-util/resolve-ci-config/action.yml +++ b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/action.yml @@ -1,5 +1,5 @@ name: Resolve CI config -description: Resolve runner labels from ROCm/therock-ci-config +description: Resolve build and GPU runner labels from ROCm/therock-ci-config inputs: config-path: @@ -14,14 +14,63 @@ inputs: description: Sandbox runner label to use if the shared CI config cannot be loaded required: false default: linux-mi325-gpu-rocm-cpu-sandbox + fallback-gfx950-runner: + description: Runner label for gfx950 if the shared CI config cannot be loaded + required: false + default: linux-gfx950-1gpu-ccs-ossci-rocm + fallback-gfx90a-runner: + description: Runner label for gfx90a if the shared CI config cannot be loaded + required: false + default: linux-gfx90a-gpu-rocm + fallback-gfx103x-runner: + description: Runner label for gfx103x if the shared CI config cannot be loaded + required: false + default: linux-gfx1030-gpu-rocm + fallback-gfx110x-runner: + description: Runner label for gfx110x if the shared CI config cannot be loaded + required: false + default: linux-gfx110X-gpu-rocm + fallback-gfx120x-runner: + description: Runner label for gfx120x if the shared CI config cannot be loaded + required: false + default: linux-gfx120X-gpu-rocm + fallback-gfx1151-runner: + description: Runner label for gfx1151 if the shared CI config cannot be loaded + required: false + default: linux-gfx1151-gpu-rocm + fallback-linux-build-runner: + description: Linux build runner label if the shared CI config cannot be loaded + required: false + default: aws-linux-scale-rocm-prod outputs: + linux_build_runner: + description: Linux CPU build runner label + value: ${{ steps.runner.outputs.linux_build_runner }} + gfx90a_runner: + description: Linux gfx90a test runner label + value: ${{ steps.runner.outputs.gfx90a_runner }} gfx94x_runner: description: Linux gfx94x test runner label value: ${{ steps.runner.outputs.gfx94x_runner }} gfx94x_sandbox_runner: description: Linux gfx94x sandbox test runner label value: ${{ steps.runner.outputs.gfx94x_sandbox_runner }} + gfx950_runner: + description: Linux gfx950 test runner label + value: ${{ steps.runner.outputs.gfx950_runner }} + gfx103x_runner: + description: Linux gfx103x (Navi 2x) test runner label + value: ${{ steps.runner.outputs.gfx103x_runner }} + gfx110x_runner: + description: Linux gfx110x (Navi 3x) test runner label + value: ${{ steps.runner.outputs.gfx110x_runner }} + gfx120x_runner: + description: Linux gfx120x (Navi 4x) test runner label + value: ${{ steps.runner.outputs.gfx120x_runner }} + gfx1151_runner: + description: Linux gfx1151 test runner label + value: ${{ steps.runner.outputs.gfx1151_runner }} runs: using: composite @@ -41,4 +90,11 @@ runs: CI_CONFIG_PATH: ${{ inputs.config-path }} FALLBACK_GFX94X_RUNNER: ${{ inputs.fallback-gfx94x-runner }} FALLBACK_GFX94X_SANDBOX_RUNNER: ${{ inputs.fallback-gfx94x-sandbox-runner }} + FALLBACK_GFX950_RUNNER: ${{ inputs.fallback-gfx950-runner }} + FALLBACK_GFX90A_RUNNER: ${{ inputs.fallback-gfx90a-runner }} + FALLBACK_GFX103X_RUNNER: ${{ inputs.fallback-gfx103x-runner }} + FALLBACK_GFX110X_RUNNER: ${{ inputs.fallback-gfx110x-runner }} + FALLBACK_GFX120X_RUNNER: ${{ inputs.fallback-gfx120x-runner }} + FALLBACK_GFX1151_RUNNER: ${{ inputs.fallback-gfx1151-runner }} + FALLBACK_LINUX_BUILD_RUNNER: ${{ inputs.fallback-linux-build-runner }} run: python3 "${GITHUB_ACTION_PATH}/resolve_ci_config.py" diff --git a/.github/actions/rocprofiler-sdk-util/resolve-ci-config/resolve_ci_config.py b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/resolve_ci_config.py index 2247dd81a99d..4dba6c129615 100644 --- a/.github/actions/rocprofiler-sdk-util/resolve-ci-config/resolve_ci_config.py +++ b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/resolve_ci_config.py @@ -7,29 +7,58 @@ from pathlib import Path from typing import Any +GPU_FAMILIES = [ + "gfx94x", + "gfx950", + "gfx90a", + "gfx103x", + "gfx110x", + "gfx120x", + "gfx1151", +] +TRIGGER_TYPES = ["presubmit", "postsubmit", "nightly"] + def warn(message: str) -> None: print(f"::warning::{message}") -def load_gfx94x_linux_config(config_path: Path) -> dict[str, Any]: +def load_ci_configs( + config_path: Path, +) -> tuple[dict[str, dict[str, Any]], dict[str, Any]]: if not config_path.exists(): warn("CI config checkout missing. Using fallback runner labels.") - return {} + return {}, {} sys.path.insert(0, str(config_path)) try: from ci_config_api import load_config_v1 config = load_config_v1(config_path) - return ( - config.get_gpu_families(["presubmit"]) - .get("gfx94x", {}) - .get("linux", {}) - ) + all_families = config.get_gpu_families(TRIGGER_TYPES) + gpu_configs = { + family: all_families.get(family, {}).get("linux", {}) + for family in GPU_FAMILIES + } + return gpu_configs, config.build_runners except Exception as exc: warn(f"Failed to load CI config: {exc}. Using fallback runner labels.") - return {} + return {}, {} + + +def load_gpu_configs(config_path: Path) -> dict[str, dict[str, Any]]: + return load_ci_configs(config_path)[0] + + +def get_linux_build_runner(build_runners: dict[str, Any], fallback: str) -> str: + return next( + ( + runner["label"] + for runner in build_runners.get("linux", {}).get("default", []) + if runner.get("label") and runner.get("weight", 0) > 0 + ), + fallback, + ) def set_outputs(outputs: dict[str, str]) -> None: @@ -40,23 +69,32 @@ def set_outputs(outputs: dict[str, str]) -> None: def main() -> None: config_path = Path(os.environ["CI_CONFIG_PATH"]) - fallback_runner = os.environ["FALLBACK_GFX94X_RUNNER"] - fallback_sandbox_runner = os.environ["FALLBACK_GFX94X_SANDBOX_RUNNER"] + gpu_configs, build_runners = load_ci_configs(config_path) - gfx94x_linux_config = load_gfx94x_linux_config(config_path) - runner = gfx94x_linux_config.get("test-runs-on") or fallback_runner - sandbox_runner = ( - gfx94x_linux_config.get("test-runs-on-sandbox") or fallback_sandbox_runner + outputs: dict[str, str] = {} + fallback_linux_build_runner = os.environ.get("FALLBACK_LINUX_BUILD_RUNNER", "") + linux_build_runner = get_linux_build_runner( + build_runners, fallback_linux_build_runner ) - - print(f"Using gfx94x runner: {runner}") + outputs["linux_build_runner"] = linux_build_runner + print(f"Using Linux build runner: {linux_build_runner}") + + for family in GPU_FAMILIES: + linux_config = gpu_configs.get(family, {}) + fallback_env = f"FALLBACK_{family.upper()}_RUNNER" + fallback = os.environ.get(fallback_env, "") + + runner = linux_config.get("test-runs-on") or fallback + outputs[f"{family}_runner"] = runner + print(f"Using {family} runner: {runner}") + + fallback_sandbox = os.environ.get("FALLBACK_GFX94X_SANDBOX_RUNNER", "") + gfx94x_config = gpu_configs.get("gfx94x", {}) + sandbox_runner = gfx94x_config.get("test-runs-on-sandbox") or fallback_sandbox + outputs["gfx94x_sandbox_runner"] = sandbox_runner print(f"Using gfx94x sandbox runner: {sandbox_runner}") - set_outputs( - { - "gfx94x_runner": runner, - "gfx94x_sandbox_runner": sandbox_runner, - } - ) + + set_outputs(outputs) if __name__ == "__main__": diff --git a/.github/actions/rocprofiler-sdk-util/resolve-ci-config/test_resolve_ci_config.py b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/test_resolve_ci_config.py new file mode 100644 index 000000000000..ac4fb1db4808 --- /dev/null +++ b/.github/actions/rocprofiler-sdk-util/resolve-ci-config/test_resolve_ci_config.py @@ -0,0 +1,326 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import json +import os +import tempfile +import textwrap +import unittest +from pathlib import Path +from unittest.mock import patch + +from resolve_ci_config import GPU_FAMILIES, TRIGGER_TYPES, load_gpu_configs, main + +SAMPLE_RUNNER_CONFIG = { + "version": "1", + "build_runners": { + "linux": { + "default": [ + {"label": "disabled-linux-runner", "weight": 0.0}, + {"label": "configured-linux-runner", "weight": 1.0}, + ] + } + }, + "gpu_families": { + "presubmit": { + "gfx94x": { + "linux": { + "test-runs-on": "linux-gfx942-1gpu-ccs-csp-ossci-rocm", + "test-runs-on-sandbox": "linux-mi325-gpu-rocm-cpu-sandbox", + "family": "gfx94X-dcgpu", + "fetch-gfx-targets": ["gfx942"], + } + }, + "gfx110x": { + "linux": { + "test-runs-on": "linux-gfx110X-gpu-rocm", + "family": "gfx110X-all", + "fetch-gfx-targets": [], + } + }, + "gfx120x": { + "linux": { + "test-runs-on": "linux-gfx120X-gpu-rocm", + "family": "gfx120X-all", + "fetch-gfx-targets": ["gfx1200", "gfx1201"], + } + }, + "gfx1151": { + "linux": { + "test-runs-on": "linux-gfx1151-gpu-rocm", + "family": "gfx1151", + "fetch-gfx-targets": ["gfx1151"], + } + }, + }, + "postsubmit": { + "gfx950": { + "linux": { + "test-runs-on": "linux-gfx950-1gpu-ccs-ossci-rocm", + "family": "gfx950-dcgpu", + "fetch-gfx-targets": ["gfx950"], + } + } + }, + "nightly": { + "gfx90a": { + "linux": { + "test-runs-on": "linux-gfx90a-gpu-rocm", + "family": "gfx90a", + "fetch-gfx-targets": ["gfx90a"], + } + }, + "gfx103x": { + "linux": { + "test-runs-on": "linux-gfx1030-gpu-rocm", + "family": "gfx103X-all", + "fetch-gfx-targets": ["gfx1030"], + } + }, + }, + }, +} + + +def _write_config(tmpdir: Path, config: dict) -> None: + (tmpdir / "runner-config.json").write_text(json.dumps(config)) + ci_api = textwrap.dedent("""\ + import json + from pathlib import Path + from dataclasses import dataclass + from typing import Any + + @dataclass + class ConfigV1: + build_runners: dict + gpu_families: dict + _raw: dict + def get_gpu_families(self, trigger_types): + result = {} + for tt in trigger_types: + if tt in self.gpu_families: + for name, cfg in self.gpu_families[tt].items(): + result[name] = cfg + return result + + def load_config_v1(config_path=None): + if config_path is None: + config_path = Path(__file__).parent + with open(config_path / "runner-config.json") as f: + raw = json.load(f) + return ConfigV1( + build_runners=raw["build_runners"], + gpu_families=raw["gpu_families"], + _raw=raw, + ) + """) + (tmpdir / "ci_config_api.py").write_text(ci_api) + + +class TestLoadGpuConfigs(unittest.TestCase): + def test_returns_empty_when_path_missing(self): + result = load_gpu_configs(Path("/nonexistent/path")) + self.assertEqual(result, {}) + + def test_loads_all_families_from_config(self): + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + _write_config(tmpdir, SAMPLE_RUNNER_CONFIG) + result = load_gpu_configs(tmpdir) + + self.assertEqual( + result["gfx94x"]["test-runs-on"], + "linux-gfx942-1gpu-ccs-csp-ossci-rocm", + ) + self.assertEqual( + result["gfx950"]["test-runs-on"], + "linux-gfx950-1gpu-ccs-ossci-rocm", + ) + self.assertEqual( + result["gfx90a"]["test-runs-on"], + "linux-gfx90a-gpu-rocm", + ) + self.assertEqual( + result["gfx103x"]["test-runs-on"], + "linux-gfx1030-gpu-rocm", + ) + self.assertEqual( + result["gfx110x"]["test-runs-on"], + "linux-gfx110X-gpu-rocm", + ) + self.assertEqual( + result["gfx120x"]["test-runs-on"], + "linux-gfx120X-gpu-rocm", + ) + self.assertEqual( + result["gfx1151"]["test-runs-on"], + "linux-gfx1151-gpu-rocm", + ) + + def test_missing_family_returns_empty_dict(self): + config = { + "version": "1", + "build_runners": {}, + "gpu_families": { + "presubmit": { + "gfx94x": { + "linux": { + "test-runs-on": "some-runner", + "family": "f", + "fetch-gfx-targets": [], + } + } + } + }, + } + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + _write_config(tmpdir, config) + result = load_gpu_configs(tmpdir) + + self.assertEqual(result["gfx94x"]["test-runs-on"], "some-runner") + self.assertEqual(result["gfx950"], {}) + self.assertEqual(result["gfx90a"], {}) + self.assertEqual(result["gfx103x"], {}) + self.assertEqual(result["gfx110x"], {}) + self.assertEqual(result["gfx120x"], {}) + self.assertEqual(result["gfx1151"], {}) + + def test_returns_empty_on_import_error(self): + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + (tmpdir / "ci_config_api.py").write_text("raise ImportError('broken')") + (tmpdir / "runner-config.json").write_text("{}") + result = load_gpu_configs(tmpdir) + self.assertEqual(result, {}) + + def test_sandbox_runner_available(self): + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + _write_config(tmpdir, SAMPLE_RUNNER_CONFIG) + result = load_gpu_configs(tmpdir) + self.assertEqual( + result["gfx94x"]["test-runs-on-sandbox"], + "linux-mi325-gpu-rocm-cpu-sandbox", + ) + + +class TestMain(unittest.TestCase): + def _run_main(self, config=None, env_overrides=None): + with tempfile.TemporaryDirectory() as tmpdir: + tmpdir = Path(tmpdir) + output_file = tmpdir / "github_output" + output_file.write_text("") + + if config is not None: + config_dir = tmpdir / "ci-config" + config_dir.mkdir() + _write_config(config_dir, config) + else: + config_dir = tmpdir / "no-config" + + env = { + "CI_CONFIG_PATH": str(config_dir), + "GITHUB_OUTPUT": str(output_file), + "FALLBACK_GFX94X_RUNNER": "fallback-gfx94x", + "FALLBACK_GFX94X_SANDBOX_RUNNER": "fallback-gfx94x-sandbox", + "FALLBACK_GFX950_RUNNER": "fallback-gfx950", + "FALLBACK_GFX90A_RUNNER": "fallback-gfx90a", + "FALLBACK_GFX103X_RUNNER": "fallback-gfx103x", + "FALLBACK_GFX110X_RUNNER": "fallback-gfx110x", + "FALLBACK_GFX120X_RUNNER": "fallback-gfx120x", + "FALLBACK_GFX1151_RUNNER": "fallback-gfx1151", + "FALLBACK_LINUX_BUILD_RUNNER": "fallback-linux-runner", + } + if env_overrides: + env.update(env_overrides) + + with patch.dict(os.environ, env, clear=False): + main() + + outputs = {} + for line in output_file.read_text().strip().splitlines(): + key, _, value = line.partition("=") + outputs[key] = value + return outputs + + def test_uses_config_values_when_available(self): + outputs = self._run_main(config=SAMPLE_RUNNER_CONFIG) + + self.assertEqual(outputs["linux_build_runner"], "configured-linux-runner") + self.assertEqual( + outputs["gfx94x_runner"], "linux-gfx942-1gpu-ccs-csp-ossci-rocm" + ) + self.assertEqual(outputs["gfx950_runner"], "linux-gfx950-1gpu-ccs-ossci-rocm") + self.assertEqual(outputs["gfx90a_runner"], "linux-gfx90a-gpu-rocm") + self.assertEqual(outputs["gfx103x_runner"], "linux-gfx1030-gpu-rocm") + self.assertEqual(outputs["gfx110x_runner"], "linux-gfx110X-gpu-rocm") + self.assertEqual(outputs["gfx120x_runner"], "linux-gfx120X-gpu-rocm") + self.assertEqual(outputs["gfx1151_runner"], "linux-gfx1151-gpu-rocm") + self.assertEqual( + outputs["gfx94x_sandbox_runner"], "linux-mi325-gpu-rocm-cpu-sandbox" + ) + + def test_falls_back_to_env_when_config_missing(self): + outputs = self._run_main(config=None) + + self.assertEqual(outputs["linux_build_runner"], "fallback-linux-runner") + self.assertEqual(outputs["gfx94x_runner"], "fallback-gfx94x") + self.assertEqual(outputs["gfx950_runner"], "fallback-gfx950") + self.assertEqual(outputs["gfx90a_runner"], "fallback-gfx90a") + self.assertEqual(outputs["gfx103x_runner"], "fallback-gfx103x") + self.assertEqual(outputs["gfx110x_runner"], "fallback-gfx110x") + self.assertEqual(outputs["gfx120x_runner"], "fallback-gfx120x") + self.assertEqual(outputs["gfx1151_runner"], "fallback-gfx1151") + self.assertEqual(outputs["gfx94x_sandbox_runner"], "fallback-gfx94x-sandbox") + + def test_partial_config_uses_fallback_for_missing_families(self): + partial_config = { + "version": "1", + "build_runners": {}, + "gpu_families": { + "presubmit": { + "gfx94x": { + "linux": { + "test-runs-on": "configured-gfx94x", + "test-runs-on-sandbox": "configured-sandbox", + "family": "f", + "fetch-gfx-targets": [], + } + } + } + }, + } + outputs = self._run_main(config=partial_config) + + self.assertEqual(outputs["linux_build_runner"], "fallback-linux-runner") + self.assertEqual(outputs["gfx94x_runner"], "configured-gfx94x") + self.assertEqual(outputs["gfx94x_sandbox_runner"], "configured-sandbox") + self.assertEqual(outputs["gfx950_runner"], "fallback-gfx950") + self.assertEqual(outputs["gfx90a_runner"], "fallback-gfx90a") + self.assertEqual(outputs["gfx103x_runner"], "fallback-gfx103x") + self.assertEqual(outputs["gfx110x_runner"], "fallback-gfx110x") + self.assertEqual(outputs["gfx120x_runner"], "fallback-gfx120x") + self.assertEqual(outputs["gfx1151_runner"], "fallback-gfx1151") + + def test_all_gpu_families_have_output(self): + outputs = self._run_main(config=SAMPLE_RUNNER_CONFIG) + for family in GPU_FAMILIES: + self.assertIn(f"{family}_runner", outputs, f"Missing output for {family}") + self.assertTrue(outputs[f"{family}_runner"], f"Empty output for {family}") + self.assertIn("gfx94x_sandbox_runner", outputs) + + +class TestConstants(unittest.TestCase): + def test_gpu_families_not_empty(self): + self.assertTrue(len(GPU_FAMILIES) > 0) + + def test_trigger_types_cover_all_scopes(self): + self.assertIn("presubmit", TRIGGER_TYPES) + self.assertIn("postsubmit", TRIGGER_TYPES) + self.assertIn("nightly", TRIGGER_TYPES) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/workflows/rocprofiler-sdk-code_coverage.yml b/.github/workflows/rocprofiler-sdk-code_coverage.yml index c7f713dfb38a..6f0b1e5b2451 100644 --- a/.github/workflows/rocprofiler-sdk-code_coverage.yml +++ b/.github/workflows/rocprofiler-sdk-code_coverage.yml @@ -10,6 +10,7 @@ on: - develop paths: - 'projects/rocprofiler-sdk/**' + - '.github/actions/rocprofiler-sdk-util/**' - '.github/workflows/rocprofiler-sdk-code_coverage.yml' - '.github/actions/rocprofiler-sdk-util/action.yml' - '.github/actions/rocprofiler-sdk-util/resolve-ci-config/**' @@ -25,6 +26,7 @@ on: pull_request: paths: - 'projects/rocprofiler-sdk/**' + - '.github/actions/rocprofiler-sdk-util/**' - '.github/workflows/rocprofiler-sdk-code_coverage.yml' - '.github/actions/rocprofiler-sdk-util/action.yml' - '.github/actions/rocprofiler-sdk-util/resolve-ci-config/**' @@ -45,6 +47,11 @@ concurrency: env: # TODO(jrmadsen): replace LD_RUNPATH_FLAG, GPU_TARGETS, etc. with internal handling in cmake ROCM_PATH: "/opt/rocm" + PYTHON_VENV_PATH: ".venv-rocprofiler-sdk" + # Held at 3.25 rather than develop's 4.x: this branch's external submodules + # (json, pybind11, sqlite, yaml-cpp) still declare cmake_minimum_required + # below 3.5, which CMake 4 rejects outright. + CMAKE_VERSION_DEB: "3.25.0" GPU_TARGETS: "gfx906 gfx908 gfx90a gfx942 gfx950 gfx1030 gfx1100 gfx1101 gfx1102 gfx1201" PATH: "/usr/bin:$PATH" SUBMODULE_PATHS: "projects/rocprofiler-sdk projects/aqlprofile projects/rocprofiler-register projects/rocr-runtime projects/clr projects/hip" @@ -74,6 +81,7 @@ env: ENABLE_AQLPROFILE_BUILD: "true" ENABLE_ROCDECODE_BUILD: "true" ENABLE_ROCJPEG_BUILD: "true" + ENABLE_HIPFILE_BUILD: "true" jobs: ci_config: @@ -137,6 +145,8 @@ jobs: projects/rocr-runtime projects/clr projects/hip + projects/hrr + projects/hipfile submodules: false set-safe-directory: true @@ -163,6 +173,8 @@ jobs: submods-scoped-v1-${{ runner.os }}- - name: Init/Update submodules + timeout-minutes: 15 + continue-on-error: true run: git submodule update --init --recursive --jobs 16 -- ${SUBMODULE_PATHS} - name: Clone ROCDecode @@ -195,12 +207,6 @@ jobs: run: | if [ -d .codecov ]; then cp -r .codecov .codecov.ref; fi - - name: Configure Env - shell: bash - run: | - echo "${PATH}:/usr/local/bin:${HOME}/.local/bin" >> $GITHUB_PATH - echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib:${HOME}/.local/lib" >> $GITHUB_ENV - - name: Install requirements timeout-minutes: 10 shell: bash @@ -208,9 +214,12 @@ jobs: run: | git config --global --add safe.directory '*' apt-get update - apt-get install -y build-essential ccache python3-pip gcovr wkhtmltopdf xvfb xfonts-base xfonts-75dpi xfonts-100dpi xfonts-utils xfonts-encodings libfontconfig libdw-dev libsqlite3-dev libdrm-dev file autoconf pkg-config rpm libzstd-dev - python3 -m pip install -U --user cmake==3.25.0 - python3 -m pip install -U --user -r requirements.txt + apt-get install -y build-essential ccache cmake python3-pip python3-venv gcovr wkhtmltopdf xvfb xfonts-base xfonts-75dpi xfonts-100dpi xfonts-utils xfonts-encodings libfontconfig libdw-dev libsqlite3-dev libdrm-dev file autoconf pkg-config rpm libzstd-dev + python3 -m venv --system-site-packages ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }} + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate + python3 -m pip install --upgrade pip + python3 -m pip install --upgrade -r requirements.txt + python3 -m pip install --upgrade cmake==${{ env.CMAKE_VERSION_DEB }} - name: Sync gcov with compilers timeout-minutes: 10 @@ -233,6 +242,7 @@ jobs: uses: ./.github/actions/rocprofiler-sdk-util with: rocm-path: ${{ env.ROCM_PATH }} + python-venv-path: ${{ env.PYTHON_VENV_PATH }} gpu-target: ${{ matrix.system.gpu-target }} compiler-launcher: /usr/bin/ccache enable-rocr-build: ${{ env.ENABLE_ROCR_BUILD }} @@ -241,6 +251,7 @@ jobs: enable-aqlprofile-build: ${{ env.ENABLE_AQLPROFILE_BUILD }} enable-rocdecode-build: ${{ env.ENABLE_ROCDECODE_BUILD }} enable-rocjpeg-build: ${{ env.ENABLE_ROCJPEG_BUILD }} + enable-hipfile-build: ${{ env.ENABLE_HIPFILE_BUILD }} ccache-key: ccache-${{ matrix.system.os }}-${{ needs.ci_config.outputs.gfx94x_runner }}-${{ matrix.system.gpu }} ccache-variant: ccache @@ -249,6 +260,7 @@ jobs: shell: bash working-directory: projects/rocprofiler-sdk run: + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate && python3 ./source/scripts/run-ci.py -B build --name ${{ github.repository }}-${{ github.ref_name }}-${{ matrix.system.os }}-${{ matrix.system.gpu }}-codecov --build-jobs 16 @@ -270,6 +282,7 @@ jobs: shell: bash working-directory: projects/rocprofiler-sdk run: + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate && find build -type f | egrep '\.gcda$' | xargs rm && python3 ./source/scripts/run-ci.py -B build --name ${{ github.repository }}-${{ github.ref_name }}-${{ matrix.system.os }}-${{ matrix.system.gpu }}-codecov-tests @@ -292,6 +305,7 @@ jobs: working-directory: projects/rocprofiler-sdk shell: bash run: + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate && find build -type f | egrep '\.gcda$' | xargs rm && python3 ./source/scripts/run-ci.py -B build --name ${{ github.repository }}-${{ github.ref_name }}-${{ matrix.system.os }}-${{ matrix.system.gpu }}-codecov-samples @@ -324,6 +338,7 @@ jobs: working-directory: projects/rocprofiler-sdk shell: bash run: | + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate echo "PWD: ${PWD}" ls -la @@ -424,6 +439,7 @@ jobs: shell: bash working-directory: projects/rocprofiler-sdk run: | + source ${GITHUB_WORKSPACE}/${{ env.PYTHON_VENV_PATH }}/bin/activate pushd build # # if following fails, there is a test that does not have diff --git a/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml b/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml index fe7df53d01b9..2619d7f29c4a 100644 --- a/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml +++ b/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml @@ -41,6 +41,7 @@ concurrency: env: ROCM_PATH: "/opt/rocm" PATH: "/usr/bin:$PATH" + CMAKE_PREFIX_PATH: "/opt/rocm/lib/rocm_sysdeps:/opt/rocm" jobs: rocm-release-compatibility: @@ -80,7 +81,7 @@ jobs: cd projects/rocprofiler-sdk git config --global --add safe.directory '*' apt update - apt install -y wget build-essential cmake g++-11 g++-12 python3-pip libdw-dev libsqlite3-dev libdrm-dev pkg-config + apt install -y wget build-essential g++-11 g++-12 python3-pip libdw-dev libsqlite3-dev libdrm-dev pkg-config # Older ROCm versions don't provide these packages. apt install -y rccl-dev rccl-unittests || true @@ -89,6 +90,14 @@ jobs: update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 10 --slave /usr/bin/g++ g++ /usr/bin/g++-11 --slave /usr/bin/gcov gcov /usr/bin/gcov-11 update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 20 --slave /usr/bin/g++ g++ /usr/bin/g++-12 --slave /usr/bin/gcov gcov /usr/bin/gcov-12 python3 -m pip install -U --user -r requirements.txt + # Held at 3.25 rather than the 4.x that requirements.txt resolves to: this + # branch's external submodules (json, pybind11, sqlite, yaml-cpp) still declare + # cmake_minimum_required below 3.5, which CMake 4 rejects outright. This must + # run after requirements.txt so the pin is not upgraded away. + python3 -m pip install -U --user cmake==3.25.0 + + # Add pip packages to path + echo "$HOME/.local/bin" >> "$GITHUB_PATH" - name: List Files shell: bash @@ -117,7 +126,6 @@ jobs: -- -DROCPROFILER_DEP_ROCMCORE=ON -DROCPROFILER_BUILD_{TESTS,SAMPLES,DOCS}=OFF - -DROCPROFILER_DISABLE_ATT_QUICK_SCAN=ON -DROCPROFILER_BUILD_AQLPROFILE=${{ matrix.aqlprofile == 'internal' && 'ON' || 'OFF' }} -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_INSTALL_PREFIX="$(realpath /opt/rocm)" From 301d089e3c5f7cc23cde42a213bfff654b3563e0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 21 Sep 2026 06:07:10 +0000 Subject: [PATCH 6/6] ci(rocprofiler-sdk): keep ATT quick scan disabled in release compatibility Develop dropped -DROCPROFILER_DISABLE_ATT_QUICK_SCAN=ON because it builds rocprof-trace-decoder, but this branch does not, so rocprofiler-sdk-tool's find_package(rocprof-trace-decoder REQUIRED) fails to configure against every ROCm release container. Restore the flag. Co-authored-by: Vivek Kale --- .github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml b/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml index 2619d7f29c4a..cb4bbf6667c7 100644 --- a/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml +++ b/.github/workflows/rocprofiler-sdk-rocm_release_compatibility.yml @@ -126,6 +126,7 @@ jobs: -- -DROCPROFILER_DEP_ROCMCORE=ON -DROCPROFILER_BUILD_{TESTS,SAMPLES,DOCS}=OFF + -DROCPROFILER_DISABLE_ATT_QUICK_SCAN=ON -DROCPROFILER_BUILD_AQLPROFILE=${{ matrix.aqlprofile == 'internal' && 'ON' || 'OFF' }} -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DCMAKE_INSTALL_PREFIX="$(realpath /opt/rocm)"