6eb06cf201
Squashed commit of the following: commit f029195705a15700380c6f832ba5d15d46fd6de7 Author: Jonathan R. Madsen <jrmadsen@users.noreply.github.com> Date: Thu Jul 13 14:38:56 2023 -0500 Formatting workflows for source (clang-format) and cmake (cmake-format) (#4) * Add .cmake-format.yaml file * Add formatting workflow * provide base input for creating PR * Update scheme for extracting branch name - disable running formatting on push to amd-staging branch * patch .cmake-format.yaml for find_package signature - apparently cmake-format doesn't format the full signature of find_package * run formatting (clang-format v11) (#7) Co-authored-by: jrmadsen <jrmadsen@users.noreply.github.com> * run cmake formatting (cmake-format) (#6) Co-authored-by: jrmadsen <jrmadsen@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> commit bc4d135fdd8a1a9e51235f18a5d575fd2b3735e6 Author: Ammar ELWazir <aelwazir@amd.com> Date: Thu Jul 13 12:55:17 2023 -0500 Removing Build cache for potential issues with auto-generated header files (#5) Change-Id: I9e2319f4335e2f88585ffa6fac2bd88a1c952e6e commit ce86dea6a311d44d880fa684eb78f3329295e2a4 Author: Jonathan R. Madsen <jrmadsen@users.noreply.github.com> Date: Thu Jul 13 11:08:58 2023 -0500 Fix decltype(<hsa-function>) function pointer usage (#3) - the following is done in several places: decltype(hsa_memory_allocate)* hsa_memory_allocate - above can cause compiler errors - replace decltype(<hsa-function>) with decltype(::<hsa-function>) - this ensures that the type within the decltype is recognized as the global scope HSA function, not the variable - in many places, the variable has a "_fn" suffix to prevent this issue but added '::' anyway for consistency commit ac49fdd92a72e9c99394253a02da413a6c2e3b3a Merge: a07946a 03a0855 Author: Ammar ELWazir <aelwazir@amd.com> Date: Wed Jul 12 11:36:24 2023 -0500 Merge pull request #2 from ROCm-Developer-Tools/gerrit-amd-staging Pull from gerrit commit 03a085588cffe863e8f466de67be1cfb205b675a Merge:c26b32ba07946a Author: Ammar ELWazir <aelwazir@amd.com> Date: Wed Jul 12 10:57:30 2023 -0500 Merge branch 'amd-staging' into gerrit-amd-staging commit a07946a5cd4c670c83c27ad1a076a9d4567ce6d7 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 15:46:04 2023 +0000 Enabling Cached Builds commit 525e494a7f13941077a8fd4ad6840904db4d27d4 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 04:53:54 2023 +0000 Updating missed GPU Targets commit 42c75862f628c9bee7cfb7dc04dff2619430efbc Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 04:43:02 2023 +0000 Adding V1 Testing commit 9d72fd4aee85e4b0c12e717060d2730fa5b73be1 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:34:31 2023 +0000 Fixing Artifacts directory path commit f4000cc558b3b2e4676f7994f7ce8c8e6f94518e Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:27:26 2023 +0000 Fixing CMake for test build job commit 2ce8115d4c33948c3c8f957f545a95a04e1d6cd2 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 03:16:18 2023 +0000 Fixing Ubuntu CMake for ubuntu test build commit 6d0ed439191be900748d0c025157f9d689a73ec7 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 01:28:41 2023 +0000 Removing Navi21 commit e349a7642e5ae5eb03ab9fcd0a0f74f09f78cab5 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 01:14:14 2023 +0000 Removing Navi21 commit fefd02fe68d2a4bca7ec2e381960ad004ee9fc5b Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:42:48 2023 +0000 Fixing CMake Job commit 2ea46abf7bf92643efa8c549fa70346ffbd79d65 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:35:13 2023 +0000 Fixing CMake Job commit d99d681ed1999c5fcf291dc678b11a77205fb0f3 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Wed Jul 12 00:32:13 2023 +0000 Fixing Pull Latest Dockers and CMake Jobs commit dfc4498072d13b4a1df3a63047d34c682c3d9a29 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 23:54:21 2023 +0000 Fixing CMake job commit 919efe04de707f7c702031be15c3e2c5f8442cbb Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 23:52:13 2023 +0000 Adding Pull Last dockers job commit be1b1256e8b0e05308e8f7e7e69bee3acca55281 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:25:40 2023 -0500 Update cmake.yml commit 212299fa4355ae6ec18f9aaacbb79c51ea6c6f97 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:23:35 2023 -0500 Update cmake.yml commit 7c2c1327086a61466cc6cac39f70865c051a8bc7 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 18:18:53 2023 -0500 Update cmake.yml commit 191b5ce007e612e814c1d7a3afb4ad398f3852e1 Author: Ammar ELWazir <aelwazir@amd.com> Date: Tue Jul 11 16:03:22 2023 -0500 Update cmake.yml commit 8824113d95f3e13c7ce4d0af8e0d9d8f522a6c4a Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 16:28:09 2023 +0000 Fixing Pull from Gerrit job name Change-Id: I9e7ed9a27a13ca49d62c93bdadb30f0057e4d385 commit cc3d5e4b02ffb439e8cc2b3efa53527c376f9982 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 16:21:43 2023 +0000 Adding Staging sync job Change-Id: I0551f43878b0678ce4b3e74e27d62357cf95ad95 commit b9be2eee71380a2e6dd34d520e92d0c4209277a0 Author: Ammar ELWazir <Ammar.ELWazir@amd.com> Date: Tue Jul 11 15:57:11 2023 +0000 Fixing build.sh Change-Id: Ia987b0244f0875370d5fe69907b3f5e9cea914de commit 9eee33a95a1abd656a7ac5ca10a9f245e9825431 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:39:46 2023 -0500 Update cmake.yml commit 7093b85a78497140e8b52632ca2a002bdaeacd62 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:33:29 2023 -0500 Update cmake.yml commit f54697172c72a67740f9fdfa0c217b6ea6931576 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 21:01:26 2023 -0500 Update cmake.yml commit 1b6620e16f8940386b0f4f04e69e2410d21c0e26 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 20:21:02 2023 -0500 Update cmake.yml commit a94bec740c6b42c4b79c87bca20fa87b99bf060d Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:46:35 2023 -0500 Update cmake.yml commit 85d6b29d4375a69d575c18ece8542c50f2ddfcc3 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:34:39 2023 -0500 Update cmake.yml commit 8c004887cf1435f1a6214c3d2455299a8a27bd4c Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:31:17 2023 -0500 Update cmake.yml commit a14a9168e17d9348a53c6e9c9a47ba1edb4c4509 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:25:46 2023 -0500 Update cmake.yml commit 000f2f40b84e6a2f7d4becdbf5aed01436ca4c83 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:08:18 2023 -0500 Update cmake.yml commit a28a53d56731cad848fa9133d1c4dbaa8fc7afa7 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 19:03:39 2023 -0500 Update cmake.yml commit a6a2db01027f0b01fdfbb5997ddb772c7f51b649 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 18:21:53 2023 -0500 Update cmake.yml commit 118ef2a88b2d44e3207c31c343da3e5e5ec6f176 Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 17:55:57 2023 -0500 Update cmake.yml commit 03c4c232396440cd0be6d2dd7baf4ceea1c2589d Author: Ammar ELWazir <aelwazir@amd.com> Date: Mon Jul 10 17:48:49 2023 -0500 Create cmake.yml Change-Id: I77992f15694e77cbae49c56f9ff02f4f9079235d [ROCm/rocprofiler commit:d4a33cf33a]
673 řádky
27 KiB
C++
673 řádky
27 KiB
C++
/******************************************************************************
|
|
Copyright (c) 2018 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.
|
|
*******************************************************************************/
|
|
|
|
#ifndef _SRC_CORE_INTERCEPT_QUEUE_H
|
|
#define _SRC_CORE_INTERCEPT_QUEUE_H
|
|
|
|
#include <hsa/amd_hsa_kernel_code.h>
|
|
#include <dlfcn.h>
|
|
#include <sys/syscall.h>
|
|
|
|
#include <atomic>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <mutex>
|
|
|
|
#include "core/context.h"
|
|
#include "core/proxy_queue.h"
|
|
#include "core/tracker.h"
|
|
#include "core/types.h"
|
|
#include "rocprofiler.h"
|
|
#include "util/hsa_rsrc_factory.h"
|
|
|
|
namespace rocprofiler {
|
|
enum { K_CONC_OFF = 0, K_CONC_PMC = 1, K_CONC_TRACE = 2 };
|
|
|
|
extern decltype(::hsa_queue_create)* hsa_queue_create_fn;
|
|
extern decltype(::hsa_queue_destroy)* hsa_queue_destroy_fn;
|
|
|
|
static inline void print_packet(const void* in_p, const uint32_t& in_n,
|
|
const uint32_t& w_n = UINT32_MAX) {
|
|
const uint32_t size32 = util::HsaRsrcFactory::CMD_SLOT_SIZE_B / 4;
|
|
const uint32_t* beg = (const uint32_t*)in_p;
|
|
const uint32_t* end = beg + (in_n * size32);
|
|
const uint32_t p_n = (w_n != UINT32_MAX) ? w_n : size32;
|
|
|
|
printf("Packets(%p, %u):\n", beg, in_n);
|
|
const uint32_t* p = beg;
|
|
while (p < end) {
|
|
const uint32_t ind = (p - beg) / size32;
|
|
printf("%u, packet(%p):\n", ind, p);
|
|
const uint32_t p_size = (*p == 0) ? size32 : p_n;
|
|
for (const uint32_t* u = p; u < p + p_size; ++u) {
|
|
printf(" %p: 0x%08x\n", u, *u);
|
|
}
|
|
p += size32;
|
|
}
|
|
fflush(stdout);
|
|
}
|
|
|
|
static std::mutex ctx_a_mutex;
|
|
typedef std::map<Context*, bool> ctx_a_map_t;
|
|
static ctx_a_map_t* ctx_a_map = NULL;
|
|
static bool ck_ctx_inactive(Context* context) {
|
|
std::lock_guard<std::mutex> lock(ctx_a_mutex);
|
|
if (ctx_a_map == NULL) ctx_a_map = new ctx_a_map_t;
|
|
auto ret = ctx_a_map->insert({context, true});
|
|
if (ret.second == false) ctx_a_map->erase(context);
|
|
return ret.second;
|
|
}
|
|
|
|
class InterceptQueue {
|
|
public:
|
|
typedef std::recursive_mutex mutex_t;
|
|
typedef std::map<uint64_t, InterceptQueue*> obj_map_t;
|
|
typedef hsa_status_t (*queue_callback_t)(hsa_queue_t*, void* data);
|
|
typedef void (*queue_event_callback_t)(hsa_status_t status, hsa_queue_t* queue, void* arg);
|
|
typedef uint32_t queue_id_t;
|
|
|
|
static void HsaIntercept(HsaApiTable* table);
|
|
|
|
static hsa_status_t InterceptQueueCreate(
|
|
hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
|
void (*callback)(hsa_status_t status, hsa_queue_t* source, void* data), void* data,
|
|
uint32_t private_segment_size, uint32_t group_segment_size, hsa_queue_t** queue,
|
|
const bool& tracker_on) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
hsa_status_t status = HSA_STATUS_ERROR;
|
|
|
|
if (in_create_call_) EXC_ABORT(status, "recursive InterceptQueueCreate()");
|
|
in_create_call_ = true;
|
|
|
|
ProxyQueue* proxy =
|
|
ProxyQueue::Create(agent, size, type, queue_event_callback, data, private_segment_size,
|
|
group_segment_size, queue, &status);
|
|
if (status != HSA_STATUS_SUCCESS) EXC_ABORT(status, "ProxyQueue::Create()");
|
|
|
|
if (tracker_on || tracker_on_) {
|
|
if (tracker_ == NULL) tracker_ = &Tracker::Instance();
|
|
status = rocprofiler::util::HsaRsrcFactory::HsaApi()->hsa_amd_profiling_set_profiler_enabled(
|
|
*queue, true);
|
|
if (status != HSA_STATUS_SUCCESS)
|
|
EXC_ABORT(status, "hsa_amd_profiling_set_profiler_enabled()");
|
|
}
|
|
|
|
InterceptQueue* obj = new InterceptQueue(agent, *queue, proxy);
|
|
obj_map_[(uint64_t)(*queue)] = obj;
|
|
if (k_concurrent_ == K_CONC_TRACE) {
|
|
status = proxy->SetInterceptCB(OnSubmitCB_ctrace, obj);
|
|
} else if (opt_mode_) {
|
|
status = proxy->SetInterceptCB(OnSubmitCB_opt, obj);
|
|
} else {
|
|
status = proxy->SetInterceptCB(OnSubmitCB, obj);
|
|
}
|
|
obj->queue_event_callback_ = callback;
|
|
obj->queue_id = current_queue_id;
|
|
++current_queue_id;
|
|
|
|
if (callbacks_.create != NULL) {
|
|
status = callbacks_.create(*queue, callback_data_);
|
|
}
|
|
|
|
in_create_call_ = false;
|
|
return status;
|
|
}
|
|
|
|
static hsa_status_t QueueCreate(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
|
void (*callback)(hsa_status_t status, hsa_queue_t* source,
|
|
void* data),
|
|
void* data, uint32_t private_segment_size,
|
|
uint32_t group_segment_size, hsa_queue_t** queue) {
|
|
return InterceptQueueCreate(agent, size, type, callback, data, private_segment_size,
|
|
group_segment_size, queue, false);
|
|
}
|
|
|
|
static hsa_status_t QueueCreateTracked(hsa_agent_t agent, uint32_t size, hsa_queue_type32_t type,
|
|
void (*callback)(hsa_status_t status, hsa_queue_t* source,
|
|
void* data),
|
|
void* data, uint32_t private_segment_size,
|
|
uint32_t group_segment_size, hsa_queue_t** queue) {
|
|
return InterceptQueueCreate(agent, size, type, callback, data, private_segment_size,
|
|
group_segment_size, queue, true);
|
|
}
|
|
|
|
static hsa_status_t QueueDestroy(hsa_queue_t* queue) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
hsa_status_t status = HSA_STATUS_SUCCESS;
|
|
|
|
if (GetObj(queue) == nullptr) {
|
|
/* This isn't an intercept queue managed by the rocprofiler, call the original function to
|
|
destroy this queue. */
|
|
return hsa_queue_destroy_fn(queue);
|
|
}
|
|
|
|
if (callbacks_.destroy != NULL) {
|
|
status = callbacks_.destroy(queue, callback_data_);
|
|
}
|
|
|
|
if (status == HSA_STATUS_SUCCESS) {
|
|
status = DelObj(queue);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
static void OnSubmitCB_opt(const void* in_packets, uint64_t count, uint64_t user_que_idx,
|
|
void* data, hsa_amd_queue_intercept_packet_writer writer) {
|
|
const packet_t* packets_arr = reinterpret_cast<const packet_t*>(in_packets);
|
|
InterceptQueue* obj = reinterpret_cast<InterceptQueue*>(data);
|
|
Queue* proxy = obj->proxy_;
|
|
|
|
// Travers input packets
|
|
for (uint64_t j = 0; j < count; ++j) {
|
|
const packet_t* packet = &packets_arr[j];
|
|
bool to_submit = true;
|
|
|
|
// Checking for dispatch packet type
|
|
if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) &&
|
|
(dispatch_callback_.load(std::memory_order_acquire) != NULL)) {
|
|
const hsa_kernel_dispatch_packet_t* dispatch_packet =
|
|
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
|
|
const hsa_signal_t completion_signal = dispatch_packet->completion_signal;
|
|
|
|
rocprofiler_callback_data_t data = {obj->agent_info_->dev_id,
|
|
obj->agent_info_->dev_index,
|
|
obj->queue_,
|
|
user_que_idx,
|
|
obj->queue_id,
|
|
completion_signal,
|
|
dispatch_packet,
|
|
NULL, // kernel_name
|
|
0, // kernel_object
|
|
NULL, // kernel_code
|
|
0, // (uint32_t)syscall(__NR_gettid),
|
|
NULL}; // record
|
|
|
|
// Calling dispatch callback
|
|
rocprofiler_group_t group = {};
|
|
hsa_status_t status = (dispatch_callback_.load())(&data, callback_data_, &group);
|
|
Context* context = reinterpret_cast<Context*>(group.context);
|
|
// Injecting profiling start/stop packets
|
|
if ((status == HSA_STATUS_SUCCESS) && (context != NULL)) {
|
|
if (group.feature_count != 0) {
|
|
if (tracker_ != NULL) {
|
|
Group* context_group = context->GetGroup(group.index);
|
|
const_cast<hsa_kernel_dispatch_packet_t*>(dispatch_packet)->completion_signal =
|
|
context_group->GetDispatchSignal();
|
|
Tracker::Enable_opt(context_group, completion_signal);
|
|
context_group->IncrRefsCount();
|
|
}
|
|
|
|
const pkt_vector_t& start_vector = context->StartPackets(group.index);
|
|
const pkt_vector_t& stop_vector = context->StopPackets(group.index);
|
|
pkt_vector_t packets = start_vector;
|
|
packets.insert(packets.end(), *packet);
|
|
packets.insert(packets.end(), stop_vector.begin(), stop_vector.end());
|
|
if (writer != NULL) {
|
|
writer(&packets[0], packets.size());
|
|
} else {
|
|
proxy->Submit(&packets[0], packets.size());
|
|
}
|
|
to_submit = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Submitting the original packets if profiling was not enabled
|
|
if (to_submit) {
|
|
if (writer != NULL) {
|
|
writer(packet, 1);
|
|
} else {
|
|
proxy->Submit(packet, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void OnSubmitCB(const void* in_packets, uint64_t count, uint64_t user_que_idx, void* data,
|
|
hsa_amd_queue_intercept_packet_writer writer) {
|
|
const packet_t* packets_arr = reinterpret_cast<const packet_t*>(in_packets);
|
|
InterceptQueue* obj = reinterpret_cast<InterceptQueue*>(data);
|
|
Queue* proxy = obj->proxy_;
|
|
|
|
////////////////////////////////////////////////
|
|
#if INTERCEPT_QUEUE_TRACE
|
|
const uint32_t header_val = *(uint32_t*)in_packets;
|
|
const uint32_t pid = syscall(__NR_getpid);
|
|
const uint32_t tid = syscall(__NR_gettid);
|
|
hsa_queue_t* qptr = obj->queue_;
|
|
const void* slot_ptr = util::HsaRsrcFactory::GetSlotPointer(qptr, user_que_idx);
|
|
printf("OnSubmitCB: %u:%u queue(%p:%lu) in(%p, %p, %lu) hdr(%u)\n", pid, tid, qptr,
|
|
user_que_idx, in_packets, slot_ptr, count, header_val);
|
|
fflush(stdout);
|
|
print_packet(in_packets, count);
|
|
abort();
|
|
#endif
|
|
////////////////////////////////////////////////
|
|
|
|
if (submit_callback_fun_) {
|
|
mutex_.lock();
|
|
auto* callback_fun = submit_callback_fun_;
|
|
void* callback_arg = submit_callback_arg_;
|
|
mutex_.unlock();
|
|
|
|
if (callback_fun) {
|
|
for (uint64_t j = 0; j < count; ++j) {
|
|
const packet_t* packet = &packets_arr[j];
|
|
const hsa_kernel_dispatch_packet_t* dispatch_packet =
|
|
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
|
|
|
|
const char* kernel_name = NULL;
|
|
if (GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) {
|
|
uint64_t kernel_object = dispatch_packet->kernel_object;
|
|
const amd_kernel_code_t* kernel_code = GetKernelCode(kernel_object);
|
|
kernel_name = (GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH)
|
|
? QueryKernelName(kernel_object, kernel_code)
|
|
: NULL;
|
|
}
|
|
|
|
// Prepareing submit callback data
|
|
rocprofiler_hsa_callback_data_t data{};
|
|
data.submit.packet = (void*)packet;
|
|
data.submit.kernel_name = kernel_name;
|
|
data.submit.queue = obj->queue_;
|
|
data.submit.device_type = obj->agent_info_->dev_type;
|
|
data.submit.device_id = obj->agent_info_->dev_index;
|
|
|
|
callback_fun(ROCPROFILER_HSA_CB_ID_SUBMIT, &data, callback_arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Travers input packets
|
|
for (uint64_t j = 0; j < count; ++j) {
|
|
const packet_t* packet = &packets_arr[j];
|
|
bool to_submit = true;
|
|
|
|
// Checking for dispatch packet type
|
|
if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) &&
|
|
(dispatch_callback_.load(std::memory_order_acquire) != NULL)) {
|
|
const hsa_kernel_dispatch_packet_t* dispatch_packet =
|
|
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
|
|
const hsa_signal_t completion_signal = dispatch_packet->completion_signal;
|
|
|
|
// Adding kernel timing tracker
|
|
Tracker::entry_t* tracker_entry = NULL;
|
|
|
|
const bool is_serial = (k_concurrent_ == K_CONC_OFF);
|
|
if (tracker_ != NULL) {
|
|
tracker_entry = tracker_->Alloc(obj->agent_info_->dev_id,
|
|
dispatch_packet->completion_signal, is_serial);
|
|
if (is_serial)
|
|
const_cast<hsa_kernel_dispatch_packet_t*>(dispatch_packet)->completion_signal =
|
|
tracker_entry->signal;
|
|
}
|
|
|
|
// Prepareing dispatch callback data
|
|
uint64_t kernel_object = dispatch_packet->kernel_object;
|
|
const amd_kernel_code_t* kernel_code = GetKernelCode(kernel_object);
|
|
const char* kernel_name = QueryKernelName(kernel_object, kernel_code);
|
|
|
|
rocprofiler_callback_data_t data = {obj->agent_info_->dev_id,
|
|
obj->agent_info_->dev_index,
|
|
obj->queue_,
|
|
user_que_idx,
|
|
obj->queue_id,
|
|
completion_signal,
|
|
dispatch_packet,
|
|
kernel_name,
|
|
kernel_object,
|
|
kernel_code,
|
|
(uint32_t)syscall(__NR_gettid),
|
|
(tracker_entry) ? tracker_entry->record : NULL};
|
|
|
|
// Calling dispatch callback
|
|
rocprofiler_group_t group = {};
|
|
hsa_status_t status = (dispatch_callback_.load())(&data, callback_data_, &group);
|
|
// Injecting profiling start/stop/read packets
|
|
if ((status != HSA_STATUS_SUCCESS) || (group.context == NULL)) {
|
|
if (tracker_entry != NULL) {
|
|
if (is_serial)
|
|
const_cast<hsa_kernel_dispatch_packet_t*>(dispatch_packet)->completion_signal =
|
|
tracker_entry->orig;
|
|
tracker_->Delete(tracker_entry);
|
|
}
|
|
} else {
|
|
Context* context = reinterpret_cast<Context*>(group.context);
|
|
|
|
if (group.feature_count != 0) {
|
|
const pkt_vector_t& start_vector = context->StartPackets(group.index);
|
|
const pkt_vector_t& stop_vector = context->StopPackets(group.index);
|
|
const pkt_vector_t& read_vector = context->ReadPackets(group.index);
|
|
pkt_vector_t packets;
|
|
|
|
if (is_serial) { // serial
|
|
packets = start_vector;
|
|
packets.insert(packets.end(), *packet);
|
|
packets.insert(packets.end(), stop_vector.begin(), stop_vector.end());
|
|
} else { // concurrent
|
|
// Insert start packets once
|
|
auto inject_start = [&packets](const pkt_vector_t& starts) mutable {
|
|
packets = starts;
|
|
};
|
|
std::call_once(once_flag_, inject_start, start_vector);
|
|
// Reads at both kernel start and end (also with barriers)
|
|
assert(read_vector.size() >= 2 * start_vector.size());
|
|
auto mid = read_vector.begin() + read_vector.size() / 2;
|
|
// Read at kernel start
|
|
packets.insert(packets.end(), read_vector.begin(), mid);
|
|
// Kernel dispatch packet
|
|
assert(tracker_entry != NULL);
|
|
// Bind dispatch and barrier signals with tracker entry
|
|
tracker_->SetHandler(tracker_entry, context->GetGroup(group.index));
|
|
const_cast<hsa_kernel_dispatch_packet_t*>(dispatch_packet)->completion_signal =
|
|
context->GetGroup(group.index)->GetDispatchSignal();
|
|
packets.insert(packets.end(), *packet);
|
|
// Read at kernel end
|
|
packets.insert(packets.end(), mid, read_vector.end());
|
|
}
|
|
|
|
if (tracker_entry != NULL) {
|
|
Group* context_group = context->GetGroup(group.index);
|
|
context_group->IncrRefsCount();
|
|
tracker_->EnableContext(tracker_entry, Context::Handler,
|
|
reinterpret_cast<void*>(context_group));
|
|
}
|
|
|
|
if (writer != NULL) {
|
|
writer(&packets[0], packets.size());
|
|
} else {
|
|
proxy->Submit(&packets[0], packets.size());
|
|
}
|
|
to_submit = false;
|
|
} else {
|
|
if (tracker_entry != NULL) {
|
|
void* context_handler_arg = NULL;
|
|
rocprofiler_handler_t context_handler_fun = context->GetHandler(&context_handler_arg);
|
|
tracker_->EnableDispatch(tracker_entry, context_handler_fun, context_handler_arg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Submitting the original packets if profiling was not enabled
|
|
if (to_submit) {
|
|
if (writer != NULL) {
|
|
writer(packet, 1);
|
|
} else {
|
|
proxy->Submit(packet, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void OnSubmitCB_ctrace(const void* in_packets, uint64_t count, uint64_t user_que_idx,
|
|
void* data, hsa_amd_queue_intercept_packet_writer writer) {
|
|
const packet_t* packets_arr = reinterpret_cast<const packet_t*>(in_packets);
|
|
InterceptQueue* obj = reinterpret_cast<InterceptQueue*>(data);
|
|
Queue* proxy = obj->proxy_;
|
|
|
|
if (submit_callback_fun_) {
|
|
mutex_.lock();
|
|
auto* callback_fun = submit_callback_fun_;
|
|
void* callback_arg = submit_callback_arg_;
|
|
mutex_.unlock();
|
|
|
|
if (callback_fun) {
|
|
for (uint64_t j = 0; j < count; ++j) {
|
|
const packet_t* packet = &packets_arr[j];
|
|
const hsa_kernel_dispatch_packet_t* dispatch_packet =
|
|
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
|
|
|
|
const char* kernel_name = NULL;
|
|
if (GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) {
|
|
uint64_t kernel_object = dispatch_packet->kernel_object;
|
|
const amd_kernel_code_t* kernel_code = GetKernelCode(kernel_object);
|
|
kernel_name = (GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH)
|
|
? QueryKernelName(kernel_object, kernel_code)
|
|
: NULL;
|
|
}
|
|
|
|
// Prepareing submit callback data
|
|
rocprofiler_hsa_callback_data_t data{};
|
|
data.submit.packet = (void*)packet;
|
|
data.submit.kernel_name = kernel_name;
|
|
data.submit.queue = obj->queue_;
|
|
data.submit.device_type = obj->agent_info_->dev_type;
|
|
data.submit.device_id = obj->agent_info_->dev_index;
|
|
|
|
callback_fun(ROCPROFILER_HSA_CB_ID_SUBMIT, &data, callback_arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Travers input packets
|
|
for (uint64_t j = 0; j < count; ++j) {
|
|
const packet_t* packet = &packets_arr[j];
|
|
bool to_submit = true;
|
|
|
|
// Checking for dispatch packet type
|
|
if ((GetHeaderType(packet) == HSA_PACKET_TYPE_KERNEL_DISPATCH) &&
|
|
(dispatch_callback_.load(std::memory_order_acquire) != NULL)) {
|
|
const hsa_kernel_dispatch_packet_t* dispatch_packet =
|
|
reinterpret_cast<const hsa_kernel_dispatch_packet_t*>(packet);
|
|
const hsa_signal_t completion_signal = dispatch_packet->completion_signal;
|
|
|
|
// Prepareing dispatch callback data
|
|
uint64_t kernel_object = dispatch_packet->kernel_object;
|
|
const amd_kernel_code_t* kernel_code = GetKernelCode(kernel_object);
|
|
const char* kernel_name = QueryKernelName(kernel_object, kernel_code);
|
|
|
|
rocprofiler_callback_data_t data = {obj->agent_info_->dev_id,
|
|
obj->agent_info_->dev_index,
|
|
obj->queue_,
|
|
user_que_idx,
|
|
obj->queue_id,
|
|
completion_signal,
|
|
dispatch_packet,
|
|
kernel_name,
|
|
kernel_object,
|
|
kernel_code,
|
|
(uint32_t)syscall(__NR_gettid),
|
|
NULL};
|
|
|
|
// Calling dispatch callback
|
|
rocprofiler_group_t group = {};
|
|
hsa_status_t status = (dispatch_callback_.load())(&data, callback_data_, &group);
|
|
|
|
// Injecting profiling start/stop packets
|
|
if ((status == HSA_STATUS_SUCCESS) && (group.context != NULL)) {
|
|
Context* context = reinterpret_cast<Context*>(group.context);
|
|
const bool ctx_inactive = ck_ctx_inactive(context);
|
|
|
|
const pkt_vector_t& start_vector = context->StartPackets(group.index);
|
|
const pkt_vector_t& stop_vector = context->StopPackets(group.index);
|
|
pkt_vector_t packets;
|
|
if (ctx_inactive) packets = start_vector;
|
|
packets.insert(packets.end(), *packet);
|
|
if (!ctx_inactive) packets.insert(packets.end(), stop_vector.begin(), stop_vector.end());
|
|
if (writer != NULL) {
|
|
writer(&packets[0], packets.size());
|
|
} else {
|
|
proxy->Submit(&packets[0], packets.size());
|
|
}
|
|
to_submit = false;
|
|
}
|
|
}
|
|
|
|
// Submitting the original packets if profiling was not enabled
|
|
if (to_submit) {
|
|
if (writer != NULL) {
|
|
writer(packet, 1);
|
|
} else {
|
|
proxy->Submit(packet, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SetCallbacks(rocprofiler_queue_callbacks_t callbacks, void* data) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
if (callback_data_ != NULL) {
|
|
EXC_ABORT(HSA_STATUS_ERROR, "reassigning queue callbacks - not supported");
|
|
}
|
|
callbacks_ = callbacks;
|
|
callback_data_ = data;
|
|
Start();
|
|
}
|
|
|
|
static void RemoveCallbacks() {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
callbacks_ = {};
|
|
Stop();
|
|
}
|
|
|
|
static inline void Start() {
|
|
dispatch_callback_.store(callbacks_.dispatch, std::memory_order_release);
|
|
}
|
|
static inline void Stop() { dispatch_callback_.store(NULL, std::memory_order_relaxed); }
|
|
|
|
static void SetSubmitCallback(rocprofiler_hsa_callback_fun_t fun, void* arg) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
submit_callback_fun_ = fun;
|
|
submit_callback_arg_ = arg;
|
|
}
|
|
|
|
static void TrackerOn(bool on) { tracker_on_ = on; }
|
|
static bool IsTrackerOn() { return tracker_on_; }
|
|
|
|
static bool opt_mode_;
|
|
static uint32_t k_concurrent_;
|
|
|
|
private:
|
|
static void queue_event_callback(hsa_status_t status, hsa_queue_t* queue, void* arg) {
|
|
if (status != HSA_STATUS_SUCCESS) {
|
|
uint32_t* read_ptr32 = (uint32_t*)util::HsaRsrcFactory::GetReadPointer(queue);
|
|
print_packet(read_ptr32, 1);
|
|
EXC_ABORT(status, "queue(" << queue << ":" << read_ptr32 << ")");
|
|
}
|
|
InterceptQueue* obj = GetObj(queue);
|
|
if (obj->queue_event_callback_) obj->queue_event_callback_(status, obj->queue_, arg);
|
|
}
|
|
|
|
static hsa_packet_type_t GetHeaderType(const packet_t* packet) {
|
|
const packet_word_t* header = reinterpret_cast<const packet_word_t*>(packet);
|
|
return static_cast<hsa_packet_type_t>((*header >> HSA_PACKET_HEADER_TYPE) & header_type_mask);
|
|
}
|
|
|
|
static const amd_kernel_code_t* GetKernelCode(uint64_t kernel_object) {
|
|
const amd_kernel_code_t* kernel_code = NULL;
|
|
hsa_status_t status =
|
|
util::HsaRsrcFactory::Instance().LoaderApi()->hsa_ven_amd_loader_query_host_address(
|
|
reinterpret_cast<const void*>(kernel_object),
|
|
reinterpret_cast<const void**>(&kernel_code));
|
|
if (HSA_STATUS_SUCCESS != status) {
|
|
kernel_code = reinterpret_cast<amd_kernel_code_t*>(kernel_object);
|
|
}
|
|
return kernel_code;
|
|
}
|
|
|
|
static const char* GetKernelName(const uint64_t kernel_symbol) {
|
|
amd_runtime_loader_debug_info_t* dbg_info =
|
|
reinterpret_cast<amd_runtime_loader_debug_info_t*>(kernel_symbol);
|
|
return (dbg_info != NULL) ? dbg_info->kernel_name : NULL;
|
|
}
|
|
|
|
static const char* QueryKernelName(uint64_t kernel_object, const amd_kernel_code_t* kernel_code) {
|
|
const uint16_t kernel_object_flag = *((uint64_t*)kernel_code + 1);
|
|
if (kernel_object_flag == 0) {
|
|
if (!util::HsaRsrcFactory::IsExecutableTracking()) {
|
|
EXC_ABORT(HSA_STATUS_ERROR,
|
|
"Error: V3 code object detected - code objects tracking should be enabled\n");
|
|
}
|
|
}
|
|
const char* kernel_symname = (util::HsaRsrcFactory::IsExecutableTracking())
|
|
? util::HsaRsrcFactory::GetKernelNameRef(kernel_object)
|
|
: GetKernelName(kernel_code->runtime_loader_kernel_symbol);
|
|
return kernel_symname;
|
|
}
|
|
|
|
// method to get an intercept queue object
|
|
static InterceptQueue* GetObj(const hsa_queue_t* queue) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
InterceptQueue* obj = NULL;
|
|
obj_map_t::const_iterator it = obj_map_.find((uint64_t)queue);
|
|
if (it != obj_map_.end()) {
|
|
obj = it->second;
|
|
assert(queue == obj->queue_);
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
// method to delete an intercept queue object
|
|
static hsa_status_t DelObj(const hsa_queue_t* queue) {
|
|
std::lock_guard<mutex_t> lck(mutex_);
|
|
hsa_status_t status = HSA_STATUS_ERROR;
|
|
obj_map_t::const_iterator it = obj_map_.find((uint64_t)queue);
|
|
if (it != obj_map_.end()) {
|
|
const InterceptQueue* obj = it->second;
|
|
assert(queue == obj->queue_);
|
|
delete obj;
|
|
obj_map_.erase(it);
|
|
status = HSA_STATUS_SUCCESS;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
InterceptQueue(const hsa_agent_t& agent, hsa_queue_t* const queue, ProxyQueue* proxy)
|
|
: queue_(queue), proxy_(proxy) {
|
|
agent_info_ = util::HsaRsrcFactory::Instance().GetAgentInfo(agent);
|
|
queue_event_callback_ = NULL;
|
|
}
|
|
|
|
~InterceptQueue() { ProxyQueue::Destroy(proxy_); }
|
|
|
|
static const packet_word_t header_type_mask = (1ul << HSA_PACKET_HEADER_WIDTH_TYPE) - 1;
|
|
|
|
static mutex_t mutex_;
|
|
static rocprofiler_queue_callbacks_t callbacks_;
|
|
static void* callback_data_;
|
|
static std::atomic<rocprofiler_callback_t> dispatch_callback_;
|
|
|
|
static obj_map_t obj_map_;
|
|
static const char* kernel_none_;
|
|
static Tracker* tracker_;
|
|
static bool tracker_on_;
|
|
static bool in_create_call_;
|
|
static queue_id_t current_queue_id;
|
|
|
|
static rocprofiler_hsa_callback_fun_t submit_callback_fun_;
|
|
static void* submit_callback_arg_;
|
|
|
|
hsa_queue_t* const queue_;
|
|
ProxyQueue* const proxy_;
|
|
const util::AgentInfo* agent_info_;
|
|
queue_event_callback_t queue_event_callback_;
|
|
queue_id_t queue_id;
|
|
|
|
static std::once_flag once_flag_;
|
|
};
|
|
|
|
} // namespace rocprofiler
|
|
|
|
#endif // _SRC_CORE_INTERCEPT_QUEUE_H
|