From b67c618f49061744f1750fd5ece48d2829c0d8b5 Mon Sep 17 00:00:00 2001 From: Laurent Morichetti Date: Mon, 23 May 2022 22:04:26 -0700 Subject: [PATCH] Remove the tracer tool's constructor and destructor functions Change-Id: I12d88af726074fb15f8159580c85c12888f72172 [ROCm/roctracer commit: e9b3b7c9a065f7c0ba16cd9dc315683d55d892e1] --- .../roctracer/src/tracer_tool/trace_buffer.h | 18 +- .../roctracer/src/tracer_tool/tracer_tool.cpp | 255 ++++++++---------- projects/roctracer/test/CMakeLists.txt | 4 + .../load_unload_reload_trace.txt | 24 ++ .../golden_traces/tests_trace_cmp_levels.txt | 1 + .../roctracer/test/hsa/load_unload_reload.cpp | 50 ++++ projects/roctracer/test/run.sh | 3 + 7 files changed, 209 insertions(+), 146 deletions(-) create mode 100644 projects/roctracer/test/golden_traces/load_unload_reload_trace.txt create mode 100644 projects/roctracer/test/hsa/load_unload_reload.cpp diff --git a/projects/roctracer/src/tracer_tool/trace_buffer.h b/projects/roctracer/src/tracer_tool/trace_buffer.h index 57aa7cc5a7..6f5ffef712 100644 --- a/projects/roctracer/src/tracer_tool/trace_buffer.h +++ b/projects/roctracer/src/tracer_tool/trace_buffer.h @@ -45,7 +45,7 @@ class TraceBufferBase { trace_buffer->Flush(); } - static void Push(TraceBufferBase* elem) { + static void Register(TraceBufferBase* elem) { std::lock_guard lock(mutex_); auto** prev_ptr = &head_; @@ -56,12 +56,24 @@ class TraceBufferBase { *prev_ptr = elem; } + static void Unregister(TraceBufferBase* elem) { + std::lock_guard lock(mutex_); + + auto** prev_ptr = &head_; + while (*prev_ptr != nullptr && *prev_ptr != elem) prev_ptr = &(*prev_ptr)->next_; + + assert(*prev_ptr != nullptr && "elem is not in the list"); + *prev_ptr = elem->next_; + } + TraceBufferBase(std::string name, int priority) : name_(std::move(name)), priority_(priority), next_(nullptr) {} TraceBufferBase(const TraceBufferBase&) = delete; TraceBufferBase& operator=(const TraceBufferBase&) = delete; + virtual ~TraceBufferBase() { Unregister(this); } + virtual void Flush() = 0; std::string name() && { return std::move(name_); } @@ -99,10 +111,10 @@ class TraceBuffer : protected TraceBufferBase { AllocateFreeBuffer(); // Add this instance to the link list of all trace buffers in the process. - TraceBufferBase::Push(this); + Register(this); } - ~TraceBuffer() { + ~TraceBuffer() override { // Flush the remaining records. After flushing, there should not be any records left in the // trace buffer. Flush(); diff --git a/projects/roctracer/src/tracer_tool/tracer_tool.cpp b/projects/roctracer/src/tracer_tool/tracer_tool.cpp index 7c77afafc8..72745212a7 100644 --- a/projects/roctracer/src/tracer_tool/tracer_tool.cpp +++ b/projects/roctracer/src/tracer_tool/tracer_tool.cpp @@ -45,17 +45,6 @@ #include "trace_buffer.h" #include "evt_stats.h" -#define CONSTRUCTOR_API __attribute__((constructor)) -#define DESTRUCTOR_API __attribute__((destructor)) - -#if !defined(ROCTRACER_TOOL_EXPORT) -#if defined(__GNUC__) -#define ROCTRACER_TOOL_EXPORT __attribute__((visibility("default"))) -#elif defined(_MSC_VER) -#define ROCTRACER_TOOL_EXPORT __declspec(dllexport) -#endif /* defined (_MSC_VER) */ -#endif /* !defined (ROCTRACER_TOOL_EXPORT) */ - // Macro to check ROC-tracer calls status #define CHECK_ROCTRACER(call) \ do { \ @@ -115,22 +104,8 @@ bool trace_hip_api = false; bool trace_hip_activity = false; bool trace_pcs = false; -// The below getter functions have been written intentionally to fix an issue -// with constructor ordering. Previously when hip_api_vec and hsa_api_vec -// were left as simple global variables, whenever the tool_load() function -// was called from CONSTRUCTOR_API void constructor()" of libroctracer_tool.so -// the ordering of std::vector constructor becomes undefined. This meant that you could assign -// hip_api_vec and hsa_api_vec with a value in tool_load() and once the function returns, the -// std::vector default constructor would execute later, causing the values to be lost. - -static std::vector& hsa_api_vec() { - static std::vector hsa_api_vec; - return hsa_api_vec; -} -static std::vector& hip_api_vec() { - static std::vector hip_api_vec; - return hip_api_vec; -} +std::vector hsa_api_vec; +std::vector hip_api_vec; LOADER_INSTANTIATE(); TRACE_BUFFER_INSTANTIATE(); @@ -230,25 +205,6 @@ struct roctx_trace_entry_t { const char* message; }; -roctracer::TraceBuffer* roctx_trace_buffer = NULL; - -// rocTX callback function -void roctx_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, - void* /* user_arg */) { - const roctx_api_data_t* data = reinterpret_cast(callback_data); - - roctx_trace_entry_t* entry = roctx_trace_buffer->GetEntry(); - entry->cid = cid; - entry->time = util::timestamp_ns(); - entry->pid = GetPid(); - entry->tid = GetTid(); - entry->rid = data->args.id; - entry->message = (data->args.message != NULL) - ? strdup(data->args.message) /* FIXME: Who frees the message? */ - : NULL; - entry->valid.store(roctracer::TRACE_ENTRY_COMPLETE, std::memory_order_release); -} - // rocTX buffer flush function void roctx_flush_cb(roctx_trace_entry_t* entry) { std::ostringstream os; @@ -262,6 +218,26 @@ void roctx_flush_cb(roctx_trace_entry_t* entry) { fflush(roctx_file_handle); } +roctracer::TraceBuffer roctx_trace_buffer("rocTX API", 0x200000, + roctx_flush_cb); + +// rocTX callback function +void roctx_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, + void* /* user_arg */) { + const roctx_api_data_t* data = reinterpret_cast(callback_data); + + roctx_trace_entry_t* entry = roctx_trace_buffer.GetEntry(); + entry->cid = cid; + entry->time = util::timestamp_ns(); + entry->pid = GetPid(); + entry->tid = GetTid(); + entry->rid = data->args.id; + entry->message = (data->args.message != NULL) + ? strdup(data->args.message) /* FIXME: Who frees the message? */ + : NULL; + entry->valid.store(roctracer::TRACE_ENTRY_COMPLETE, std::memory_order_release); +} + /////////////////////////////////////////////////////////////////////////////////////////////////////// // HSA API tracing @@ -275,7 +251,16 @@ struct hsa_api_trace_entry_t { hsa_api_data_t data; }; -roctracer::TraceBuffer* hsa_api_trace_buffer = NULL; +void hsa_api_flush_cb(hsa_api_trace_entry_t* entry) { + std::ostringstream os; + os << entry->begin << ":" << entry->end << " " << entry->pid << ":" << entry->tid << " " + << hsa_api_data_pair_t(entry->cid, entry->data); + fprintf(hsa_api_file_handle, "%s\n", os.str().c_str()); + fflush(hsa_api_file_handle); +} + +roctracer::TraceBuffer hsa_api_trace_buffer("HSA API", 0x200000, + hsa_api_flush_cb); // HSA API callback function @@ -287,7 +272,7 @@ void hsa_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, } else { const timestamp_t end_timestamp = (cid == HSA_API_ID_hsa_shut_down) ? hsa_begin_timestamp : util::timestamp_ns(); - hsa_api_trace_entry_t* entry = hsa_api_trace_buffer->GetEntry(); + hsa_api_trace_entry_t* entry = hsa_api_trace_buffer.GetEntry(); entry->cid = cid; entry->begin = hsa_begin_timestamp; entry->end = end_timestamp; @@ -298,14 +283,6 @@ void hsa_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, } } -void hsa_api_flush_cb(hsa_api_trace_entry_t* entry) { - std::ostringstream os; - os << entry->begin << ":" << entry->end << " " << entry->pid << ":" << entry->tid << " " - << hsa_api_data_pair_t(entry->cid, entry->data); - fprintf(hsa_api_file_handle, "%s\n", os.str().c_str()); - fflush(hsa_api_file_handle); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////// // HIP API tracing @@ -322,7 +299,9 @@ struct hip_api_trace_entry_t { void* ptr; }; -roctracer::TraceBuffer* hip_api_trace_buffer = NULL; +typedef std::map hip_kernel_map_t; +hip_kernel_map_t* hip_kernel_map = NULL; +std::mutex hip_kernel_mutex; static inline bool is_hip_kernel_launch_api(const uint32_t& cid) { bool ret = (cid == HIP_API_ID_hipLaunchKernel) || (cid == HIP_API_ID_hipExtLaunchKernel) || @@ -334,6 +313,56 @@ static inline bool is_hip_kernel_launch_api(const uint32_t& cid) { return ret; } +void hip_api_flush_cb(hip_api_trace_entry_t* entry) { + const uint32_t domain = entry->domain; + const uint32_t cid = entry->cid; + const hip_api_data_t* data = &(entry->data); + const uint64_t correlation_id = data->correlation_id; + const timestamp_t begin_timestamp = entry->begin; + const timestamp_t end_timestamp = entry->end; + std::ostringstream rec_ss; + std::ostringstream oss; + + const char* str = + (domain != ACTIVITY_DOMAIN_EXT_API) ? roctracer_op_string(domain, cid, 0) : strdup("MARK"); + rec_ss << std::dec << begin_timestamp << ":" << end_timestamp << " " << entry->pid << ":" + << entry->tid; + oss << std::dec << rec_ss.str() << " " << str; + + DEBUG_TRACE( + "hip_api_flush_cb(\"%s\"): domain(%u) cid(%u) entry(%p) name(\"%s\" correlation_id(%lu) " + "beg(%lu) end(%lu))\n", + roctracer_op_string(entry->domain, entry->cid, 0), entry->domain, entry->cid, entry, + entry->name, correlation_id, begin_timestamp, end_timestamp); + + if (domain == ACTIVITY_DOMAIN_HIP_API) { + if (hip_api_stats != NULL) { + hip_api_stats->add_event(cid, end_timestamp - begin_timestamp); + if (is_hip_kernel_launch_api(cid)) { + hip_kernel_mutex.lock(); + (*hip_kernel_map)[correlation_id] = entry->name; + hip_kernel_mutex.unlock(); + } + } else { + const char* str = hipApiString((hip_api_id_t)cid, data); + rec_ss << " " << str; + if (is_hip_kernel_launch_api(cid) && entry->name) { + const char* kernel_name = cxx_demangle(entry->name); + rec_ss << " kernel=" << kernel_name; + } + rec_ss << " :" << correlation_id; + fprintf(hip_api_file_handle, "%s\n", rec_ss.str().c_str()); + } + } else { + fprintf(hip_api_file_handle, "%s(name(%s))\n", oss.str().c_str(), entry->name); + } + + fflush(hip_api_file_handle); +} + +roctracer::TraceBuffer hip_api_trace_buffer("HIP API", 0x200000, + hip_api_flush_cb); + void hip_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, void* arg) { (void)arg; const hip_api_data_t* data = reinterpret_cast(callback_data); @@ -346,7 +375,7 @@ void hip_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, // Post init of HIP APU args hipApiArgsInit((hip_api_id_t)cid, const_cast(data)); - entry = hip_api_trace_buffer->GetEntry(); + entry = hip_api_trace_buffer.GetEntry(); entry->cid = cid; entry->domain = domain; entry->begin = hip_begin_timestamp; @@ -415,7 +444,7 @@ void mark_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, const char* name = reinterpret_cast(callback_data); const timestamp_t timestamp = util::timestamp_ns(); - hip_api_trace_entry_t* entry = hip_api_trace_buffer->GetEntry(); + hip_api_trace_entry_t* entry = hip_api_trace_buffer.GetEntry(); entry->cid = 0; entry->domain = domain; entry->begin = timestamp; @@ -428,57 +457,6 @@ void mark_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, entry->valid.store(roctracer::TRACE_ENTRY_COMPLETE, std::memory_order_release); } -typedef std::map hip_kernel_map_t; -hip_kernel_map_t* hip_kernel_map = NULL; -std::mutex hip_kernel_mutex; - -void hip_api_flush_cb(hip_api_trace_entry_t* entry) { - const uint32_t domain = entry->domain; - const uint32_t cid = entry->cid; - const hip_api_data_t* data = &(entry->data); - const uint64_t correlation_id = data->correlation_id; - const timestamp_t begin_timestamp = entry->begin; - const timestamp_t end_timestamp = entry->end; - std::ostringstream rec_ss; - std::ostringstream oss; - - const char* str = - (domain != ACTIVITY_DOMAIN_EXT_API) ? roctracer_op_string(domain, cid, 0) : strdup("MARK"); - rec_ss << std::dec << begin_timestamp << ":" << end_timestamp << " " << entry->pid << ":" - << entry->tid; - oss << std::dec << rec_ss.str() << " " << str; - - DEBUG_TRACE( - "hip_api_flush_cb(\"%s\"): domain(%u) cid(%u) entry(%p) name(\"%s\" correlation_id(%lu) " - "beg(%lu) end(%lu))\n", - roctracer_op_string(entry->domain, entry->cid, 0), entry->domain, entry->cid, entry, - entry->name, correlation_id, begin_timestamp, end_timestamp); - - if (domain == ACTIVITY_DOMAIN_HIP_API) { - if (hip_api_stats != NULL) { - hip_api_stats->add_event(cid, end_timestamp - begin_timestamp); - if (is_hip_kernel_launch_api(cid)) { - hip_kernel_mutex.lock(); - (*hip_kernel_map)[correlation_id] = entry->name; - hip_kernel_mutex.unlock(); - } - } else { - const char* str = hipApiString((hip_api_id_t)cid, data); - rec_ss << " " << str; - if (is_hip_kernel_launch_api(cid) && entry->name) { - const char* kernel_name = cxx_demangle(entry->name); - rec_ss << " kernel=" << kernel_name; - } - rec_ss << " :" << correlation_id; - fprintf(hip_api_file_handle, "%s\n", rec_ss.str().c_str()); - } - } else { - fprintf(hip_api_file_handle, "%s(name(%s))\n", oss.str().c_str(), entry->name); - } - - fflush(hip_api_file_handle); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////// // HSA API tracing @@ -489,8 +467,6 @@ struct hip_act_trace_entry_t { uint64_t correlation_id; }; -roctracer::TraceBuffer* hip_act_trace_buffer = NULL; - // HIP ACT trace buffer flush callback void hip_act_flush_cb(hip_act_trace_entry_t* entry) { const uint32_t domain = ACTIVITY_DOMAIN_HIP_OPS; @@ -518,6 +494,9 @@ void hip_act_flush_cb(hip_act_trace_entry_t* entry) { } } +roctracer::TraceBuffer hip_act_trace_buffer("HIP ACT", 0x200000, + hip_act_flush_cb, 1); + // Activity tracing callback // hipMalloc id(3) correlation_id(1): begin_ns(1525888652762640464) end_ns(1525888652762877067) void pool_activity_callback(const char* begin, const char* end, void* arg) { @@ -535,7 +514,7 @@ void pool_activity_callback(const char* begin, const char* end, void* arg) { switch (record->domain) { case ACTIVITY_DOMAIN_HIP_OPS: if (hip_memcpy_stats != NULL) { - hip_act_trace_entry_t* entry = hip_act_trace_buffer->GetEntry(); + hip_act_trace_entry_t* entry = hip_act_trace_buffer.GetEntry(); entry->kind = record->kind; entry->dur = record->end_ns - record->begin_ns; entry->correlation_id = record->correlation_id; @@ -803,7 +782,7 @@ void tool_load() { if (name == "HSA") { found = true; trace_hsa_api = true; - hsa_api_vec() = api_vec; + hsa_api_vec = api_vec; } if (name == "GPU") { found = true; @@ -813,7 +792,7 @@ void tool_load() { found = true; trace_hip_api = true; trace_hip_activity = true; - hip_api_vec() = api_vec; + hip_api_vec = api_vec; } } @@ -879,11 +858,18 @@ void tool_load() { } // HSA-runtime tool on-load method -extern "C" ROCTRACER_TOOL_EXPORT bool OnLoad(HsaApiTable* table, uint64_t runtime_version, - uint64_t failed_tool_count, - const char* const* failed_tool_names) { +extern "C" ROCTRACER_EXPORT bool OnLoad(HsaApiTable* table, uint64_t runtime_version, + uint64_t failed_tool_count, + const char* const* failed_tool_names) { ONLOAD_TRACE_BEG(); + roctracer::hip_support::HIP_depth_max = 0; + tool_load(); + + // OnUnload may not be called if the ROC runtime is not shutdown by the client + // application before exiting, so register an atexit handler to unload the tool. + std::atexit(tool_unload); + const char* output_prefix = getenv("ROCP_OUTPUT_DIR"); // Dumping HSA handles for agents @@ -923,10 +909,10 @@ extern "C" ROCTRACER_TOOL_EXPORT bool OnLoad(HsaApiTable* table, uint64_t runtim fprintf(stdout, " HSA-trace("); fflush(stdout); - if (hsa_api_vec().size() != 0) { - for (unsigned i = 0; i < hsa_api_vec().size(); ++i) { + if (hsa_api_vec.size() != 0) { + for (unsigned i = 0; i < hsa_api_vec.size(); ++i) { uint32_t cid = HSA_API_ID_NUMBER; - const char* api = hsa_api_vec()[i].c_str(); + const char* api = hsa_api_vec[i].c_str(); CHECK_ROCTRACER(roctracer_op_code(ACTIVITY_DOMAIN_HSA_API, api, &cid, NULL)); CHECK_ROCTRACER( roctracer_enable_op_callback(ACTIVITY_DOMAIN_HSA_API, cid, hsa_api_callback, NULL)); @@ -974,10 +960,10 @@ extern "C" ROCTRACER_TOOL_EXPORT bool OnLoad(HsaApiTable* table, uint64_t runtim // Enable tracing if (trace_hip_api) { hip_api_file_handle = open_output_file(output_prefix, "hip_api_trace.txt"); - if (hip_api_vec().size() != 0) { - for (unsigned i = 0; i < hip_api_vec().size(); ++i) { + if (hip_api_vec.size() != 0) { + for (unsigned i = 0; i < hip_api_vec.size(); ++i) { uint32_t cid = HIP_API_ID_NONE; - const char* api = hip_api_vec()[i].c_str(); + const char* api = hip_api_vec[i].c_str(); CHECK_ROCTRACER(roctracer_op_code(ACTIVITY_DOMAIN_HIP_API, api, &cid, NULL)); CHECK_ROCTRACER( roctracer_enable_op_callback(ACTIVITY_DOMAIN_HIP_API, cid, hip_api_callback, NULL)); @@ -1028,25 +1014,8 @@ extern "C" ROCTRACER_TOOL_EXPORT bool OnLoad(HsaApiTable* table, uint64_t runtim } // HSA-runtime on-unload method -extern "C" ROCTRACER_TOOL_EXPORT void OnUnload() { ONLOAD_TRACE(""); } - -extern "C" CONSTRUCTOR_API void constructor() { - ONLOAD_TRACE_BEG(); - roctracer::hip_support::HIP_depth_max = 0; - roctx_trace_buffer = - new roctracer::TraceBuffer("rocTX API", 0x200000, roctx_flush_cb); - hip_api_trace_buffer = - new roctracer::TraceBuffer("HIP API", 0x200000, hip_api_flush_cb); - hip_act_trace_buffer = - new roctracer::TraceBuffer("HIP ACT", 0x200000, hip_act_flush_cb, 1); - hsa_api_trace_buffer = - new roctracer::TraceBuffer("HSA API", 0x200000, hsa_api_flush_cb); - tool_load(); - std::atexit(tool_unload); - ONLOAD_TRACE_END(); -} - -extern "C" DESTRUCTOR_API void destructor() { +extern "C" ROCTRACER_EXPORT void OnUnload() { ONLOAD_TRACE_BEG(); + tool_unload(); ONLOAD_TRACE_END(); } diff --git a/projects/roctracer/test/CMakeLists.txt b/projects/roctracer/test/CMakeLists.txt index 48398c9c75..6efbf3e987 100644 --- a/projects/roctracer/test/CMakeLists.txt +++ b/projects/roctracer/test/CMakeLists.txt @@ -116,6 +116,10 @@ add_executable(backward_compat_test EXCLUDE_FROM_ALL app/backward_compat_test.cp target_link_libraries(backward_compat_test roctracer) add_dependencies(mytest backward_compat_test) +add_executable(load_unload_reload_test EXCLUDE_FROM_ALL hsa/load_unload_reload.cpp) +target_link_libraries(load_unload_reload_test hsa-runtime64::hsa-runtime64) +add_dependencies(mytest load_unload_reload_test) + ## Copy the golden traces and test scripts configure_file(run.sh ${PROJECT_BINARY_DIR} COPYONLY) execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink run.sh ${PROJECT_BINARY_DIR}/run_ci.sh) diff --git a/projects/roctracer/test/golden_traces/load_unload_reload_trace.txt b/projects/roctracer/test/golden_traces/load_unload_reload_trace.txt new file mode 100644 index 0000000000..a902501de5 --- /dev/null +++ b/projects/roctracer/test/golden_traces/load_unload_reload_trace.txt @@ -0,0 +1,24 @@ +ROCTracer (pid=202688): +0x55a6e1bfa280 agent cpu +0x55a6e1bf9470 agent gpu +0x55a6e1c34d10 agent gpu +169339419628779 + HSA-trace() + HSA-activity-trace() +169339419776888:169339419781697 202688:202688 hsa_amd_profiling_async_copy_enable(1) = 0 +169339420102142:169339420102703 202688:202688 hsa_agent_get_info({handle=94175240364672}, 17, 0x7ffe818aff34) = 0 +169339420104075:169339420104606 202688:202688 hsa_agent_get_info({handle=94175240361072}, 17, 0x7ffe818aff34) = 0 +169339420105568:169339420106049 202688:202688 hsa_agent_get_info({handle=94175240604944}, 17, 0x7ffe818aff34) = 0 +169339420105568:169339420106941 202688:202688 hsa_iterate_agents(1, 0) = 0 +ROCTracer (pid=202688): +0x55a6e1bfa280 agent cpu +0x55a6e1c99260 agent gpu +0x55a6e1c95d50 agent gpu +169339843452619 + HSA-trace() + HSA-activity-trace() +169339843601029:169339843605668 202688:202688 hsa_amd_profiling_async_copy_enable(1) = 0 +169339843768255:169339843768816 202688:202688 hsa_agent_get_info({handle=94175240364672}, 17, 0x7ffe818aff34) = 0 +169339843770028:169339843770549 202688:202688 hsa_agent_get_info({handle=94175241015904}, 17, 0x7ffe818aff34) = 0 +169339843771491:169339843771962 202688:202688 hsa_agent_get_info({handle=94175241002320}, 17, 0x7ffe818aff34) = 0 +169339843771491:169339843772854 202688:202688 hsa_iterate_agents(1, 0) = 0 diff --git a/projects/roctracer/test/golden_traces/tests_trace_cmp_levels.txt b/projects/roctracer/test/golden_traces/tests_trace_cmp_levels.txt index 6fb420f4e3..0355a16c72 100644 --- a/projects/roctracer/test/golden_traces/tests_trace_cmp_levels.txt +++ b/projects/roctracer/test/golden_traces/tests_trace_cmp_levels.txt @@ -13,6 +13,7 @@ MatrixTranspose_kfd_trace --check-events .* MatrixTranspose_hip_input_trace --check-events .* copy_hsa_trace --check-events .* copy_hsa_input_trace --check-events .* +load_unload_reload_trace --check-order .* hsa_co_trace --check-none code_obj_trace --check-none trace_buffer_trace --check-none diff --git a/projects/roctracer/test/hsa/load_unload_reload.cpp b/projects/roctracer/test/hsa/load_unload_reload.cpp new file mode 100644 index 0000000000..4c49f1d492 --- /dev/null +++ b/projects/roctracer/test/hsa/load_unload_reload.cpp @@ -0,0 +1,50 @@ +/* Copyright (c) 2022 Advanced Micro Devices, Inc. + + 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 + +#include +#include + +#define CHECK(x) \ + do { \ + if ((x) != HSA_STATUS_SUCCESS) { \ + assert(false); \ + abort(); \ + } \ + } while (false); + +int main() { + // Run 2 loops of {hsa_init(); hsa_iterate_agents(); hsa_shut_down()} to test that the + // tracer tool correctly unloaded after the 1st iteration and then reloaded for the 2nd + // iteration. + for (int i = 0; i < 2; ++i) { + hsa_init(); + + CHECK(hsa_iterate_agents( + [](hsa_agent_t agent, void*) { + hsa_device_type_t type; + return hsa_agent_get_info(agent, HSA_AGENT_INFO_DEVICE, &type); + }, + nullptr)); + + hsa_shut_down(); + } +} \ No newline at end of file diff --git a/projects/roctracer/test/run.sh b/projects/roctracer/test/run.sh index d06c7ebc3a..baebac067f 100755 --- a/projects/roctracer/test/run.sh +++ b/projects/roctracer/test/run.sh @@ -172,6 +172,9 @@ export ROCP_INPUT=test/input.xml eval_test "tool HSA test input" ./test/copy copy_hsa_input_trace unset ROCP_INPUT +# Check that the tracer tool can be unloaded and then reloaded. +eval_test "Load/Unload/Reload the tracer tool" ./test/load_unload_reload_test load_unload_reload_trace + export HSA_TOOLS_LIB="$ROCTRACER_LIB_PATH/libroctracer64.so ./test/libhsaco_test.so" eval_test "tool HSA codeobj" ./test/MatrixTranspose hsa_co_trace