Gbaraldi/threadtrace2 (#724)
* Added first ATT API * Finalizing thread trace API * Fixing more rebase conflicts * Added codeobj disassembly sample * Fixing merge issues with rebase [2] * Adding ATT packets * Implemented thread trace intercept * Moved codeobj parser to same repo as rocprofiler * Moved thread trace to new API * Fixing merge conflicts * Fixing more merge conflicts * Adding thread trace packet reuse * Merged aql_profile_v2 headers * Linked ATT sample to aqlprofile * Updated decoder to include non-loaded codeobjs * Implemented ISA decoder into ATT sample * Added marker_id to vaddr * Updating aql_profile_v2 API to memcpy * Updating thread trace API to include 64bit markers. Using the result of ISA matching. * Added instruction type and cycles summary * Updated sample with selection of kernel by kernel_object * Added option to copy from memory kernels * Moved tool_data in thread_trace to dynamic alloc * Restoring hsa.cpp * Fixed ATT sample crash. General improvements. * Moved codeobj library to outside src/ * Updated license header * Moved codeobj_capture to camelcase * Solving some more merge conflicts * Update samples/advanced_thread_trace/CMakeLists.txt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update samples/advanced_thread_trace/CMakeLists.txt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update samples/code_object_isa_decode/CMakeLists.txt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update source/lib/rocprofiler-sdk/thread_trace/CMakeLists.txt * Removing unused parameter check * Adding const to isEmpty * Removing unused warning * Adding libdw-dev to requirements * Running clang-format * Commenting out new aql calls * Clang format * Unused variable fix * Adding codeobj-decoder coverage * Commenting out threadtrace * Update samples/CMakeLists.txt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * P * WOverloaded * Addressing clang-tidy * Virtual destructor on ttracer class * Corr id * Fixing code source format * Update CMakeLists.txt * Build fixes * Update source/lib/rocprofiler-sdk-codeobj/code_object_track.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Fix shadowing * Update CMakeLists.txt * Update samples/CMakeLists.txt Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Ammar ELWazir <ammar.elwazir@amd.com> Co-authored-by: Ammar ELWazir <aelwazir@amd.com> Co-authored-by: Benjamin Welton <bewelton@amd.com>
This commit is contained in:
committed by
GitHub
parent
d2bad14bf6
commit
69b8a43dc6
@@ -21,14 +21,22 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "lib/rocprofiler-sdk/hsa/aql_packet.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#define CHECK_HSA(fn, message) \
|
||||
if((fn) != HSA_STATUS_SUCCESS) \
|
||||
{ \
|
||||
std::cerr << __FILE__ << ':' << __LINE__ << ' ' << message; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace hsa
|
||||
{
|
||||
AQLPacket::~AQLPacket()
|
||||
CounterAQLPacket::~CounterAQLPacket()
|
||||
{
|
||||
if(!profile.command_buffer.ptr)
|
||||
{
|
||||
@@ -36,7 +44,7 @@ AQLPacket::~AQLPacket()
|
||||
}
|
||||
else if(!command_buf_mallocd)
|
||||
{
|
||||
free_func(profile.command_buffer.ptr);
|
||||
CHECK_HSA(free_func(profile.command_buffer.ptr), "freeing memory");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -49,12 +57,61 @@ AQLPacket::~AQLPacket()
|
||||
}
|
||||
else if(!output_buffer_malloced)
|
||||
{
|
||||
free_func(profile.output_buffer.ptr);
|
||||
CHECK_HSA(free_func(profile.output_buffer.ptr), "freeing memory");
|
||||
}
|
||||
else
|
||||
{
|
||||
::free(profile.output_buffer.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
TraceAQLPacket::~TraceAQLPacket() = default;
|
||||
/*
|
||||
TraceAQLPacket::~TraceAQLPacket()
|
||||
{
|
||||
aqlprofile_att_delete_packets(this->handle);
|
||||
}
|
||||
*/
|
||||
|
||||
hsa_status_t
|
||||
TraceAQLPacket::Alloc(void** ptr, size_t size, aqlprofile_buffer_desc_flags_t flags, void* data)
|
||||
{
|
||||
if(!data) return HSA_STATUS_ERROR;
|
||||
if(!reinterpret_cast<TraceAQLPacket*>(data)->tracepool) return HSA_STATUS_ERROR;
|
||||
|
||||
auto& pool = *reinterpret_cast<TraceAQLPacket*>(data)->tracepool;
|
||||
|
||||
if(!pool.allocate_fn || !pool.free_fn || !pool.allow_access_fn) return HSA_STATUS_ERROR;
|
||||
|
||||
if(flags.host_access)
|
||||
{
|
||||
hsa_status_t status = pool.allocate_fn(pool.cpu_pool_, size, 0, ptr);
|
||||
if(!flags.device_access || status != HSA_STATUS_SUCCESS) return status;
|
||||
return pool.allow_access_fn(1, &pool.gpu_agent, nullptr, *ptr);
|
||||
}
|
||||
return pool.allocate_fn(pool.gpu_pool_, size, 0, ptr);
|
||||
}
|
||||
|
||||
void
|
||||
TraceAQLPacket::Free(void* ptr, void* data)
|
||||
{
|
||||
auto* pool = reinterpret_cast<TraceAQLPacket*>(data)->tracepool.get();
|
||||
if(!pool || !pool->free_fn) return;
|
||||
|
||||
pool->free_fn(ptr);
|
||||
}
|
||||
|
||||
hsa_status_t
|
||||
TraceAQLPacket::Copy(void* dst, const void* src, size_t size, void* data)
|
||||
{
|
||||
auto* pool = reinterpret_cast<TraceAQLPacket*>(data)->tracepool.get();
|
||||
if(!pool || !pool->api_copy_fn) return HSA_STATUS_ERROR;
|
||||
|
||||
return pool->api_copy_fn(dst, src, size);
|
||||
}
|
||||
|
||||
TraceAQLPacket::TraceAQLPacket(std::shared_ptr<TraceMemoryPool>& _tracepool)
|
||||
: tracepool(_tracepool){};
|
||||
|
||||
} // namespace hsa
|
||||
} // namespace rocprofiler
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "lib/common/container/small_vector.hpp"
|
||||
#include "lib/rocprofiler-sdk/aql/aql_profile_v2.h"
|
||||
|
||||
#include <hsa/hsa_ext_amd.h>
|
||||
#include <hsa/hsa_ven_amd_aqlprofile.h>
|
||||
@@ -30,6 +31,12 @@
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace aql
|
||||
{
|
||||
class CounterPacketConstruct;
|
||||
class ThreadTraceAQLPacketFactory;
|
||||
} // namespace aql
|
||||
|
||||
namespace hsa
|
||||
{
|
||||
constexpr hsa_ext_amd_aql_pm4_packet_t null_amd_aql_pm4_packet = {
|
||||
@@ -41,12 +48,11 @@ constexpr hsa_ext_amd_aql_pm4_packet_t null_amd_aql_pm4_packet = {
|
||||
* Struct containing AQL packet information. Including start/stop/read
|
||||
* packets along with allocated buffers
|
||||
*/
|
||||
struct AQLPacket
|
||||
class AQLPacket
|
||||
{
|
||||
using memory_pool_free_func_t = decltype(::hsa_amd_memory_pool_free)*;
|
||||
|
||||
AQLPacket(memory_pool_free_func_t func);
|
||||
~AQLPacket();
|
||||
public:
|
||||
AQLPacket() = default;
|
||||
virtual ~AQLPacket() = default;
|
||||
|
||||
// Keep move constuctors (i.e. std::move())
|
||||
AQLPacket(AQLPacket&& other) = default;
|
||||
@@ -56,20 +62,68 @@ struct AQLPacket
|
||||
AQLPacket(const AQLPacket&) = delete;
|
||||
AQLPacket& operator=(const AQLPacket&) = delete;
|
||||
|
||||
bool command_buf_mallocd = false;
|
||||
bool output_buffer_malloced = false;
|
||||
bool empty = {true};
|
||||
hsa_ven_amd_aqlprofile_profile_t profile = {};
|
||||
hsa_ext_amd_aql_pm4_packet_t start = null_amd_aql_pm4_packet;
|
||||
hsa_ext_amd_aql_pm4_packet_t stop = null_amd_aql_pm4_packet;
|
||||
hsa_ext_amd_aql_pm4_packet_t read = null_amd_aql_pm4_packet;
|
||||
memory_pool_free_func_t free_func = nullptr;
|
||||
hsa_ven_amd_aqlprofile_profile_t profile = {};
|
||||
hsa_ext_amd_aql_pm4_packet_t start = null_amd_aql_pm4_packet;
|
||||
hsa_ext_amd_aql_pm4_packet_t stop = null_amd_aql_pm4_packet;
|
||||
hsa_ext_amd_aql_pm4_packet_t read = null_amd_aql_pm4_packet;
|
||||
|
||||
common::container::small_vector<hsa_ext_amd_aql_pm4_packet_t, 3> before_krn_pkt = {};
|
||||
common::container::small_vector<hsa_ext_amd_aql_pm4_packet_t, 2> after_krn_pkt = {};
|
||||
|
||||
bool isEmpty() const { return empty; }
|
||||
bool empty = true;
|
||||
};
|
||||
|
||||
class CounterAQLPacket : public AQLPacket
|
||||
{
|
||||
friend class rocprofiler::aql::CounterPacketConstruct;
|
||||
using memory_pool_free_func_t = decltype(::hsa_amd_memory_pool_free)*;
|
||||
|
||||
public:
|
||||
CounterAQLPacket(memory_pool_free_func_t func)
|
||||
: free_func{func} {};
|
||||
~CounterAQLPacket() override;
|
||||
|
||||
protected:
|
||||
bool command_buf_mallocd = false;
|
||||
bool output_buffer_malloced = false;
|
||||
memory_pool_free_func_t free_func = nullptr;
|
||||
};
|
||||
|
||||
struct TraceMemoryPool
|
||||
{
|
||||
hsa_agent_t gpu_agent;
|
||||
hsa_amd_memory_pool_t cpu_pool_;
|
||||
hsa_amd_memory_pool_t gpu_pool_;
|
||||
decltype(hsa_amd_memory_pool_allocate)* allocate_fn;
|
||||
decltype(hsa_amd_agents_allow_access)* allow_access_fn;
|
||||
decltype(hsa_amd_memory_pool_free)* free_fn;
|
||||
decltype(hsa_memory_copy)* api_copy_fn;
|
||||
};
|
||||
|
||||
class TraceAQLPacket : public AQLPacket
|
||||
{
|
||||
friend class rocprofiler::aql::ThreadTraceAQLPacketFactory;
|
||||
|
||||
public:
|
||||
TraceAQLPacket(std::shared_ptr<TraceMemoryPool>& _tracepool);
|
||||
TraceMemoryPool& GetPool() const { return *tracepool; }
|
||||
aqlprofile_handle_t GetHandle() const { return handle; }
|
||||
uint64_t GetAgent() const { return tracepool->gpu_agent.handle; }
|
||||
~TraceAQLPacket() override;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TraceMemoryPool> tracepool;
|
||||
aqlprofile_att_control_aql_packets_t packets;
|
||||
aqlprofile_handle_t handle;
|
||||
|
||||
static hsa_status_t Alloc(void** ptr,
|
||||
size_t size,
|
||||
aqlprofile_buffer_desc_flags_t flags,
|
||||
void* data);
|
||||
static void Free(void* ptr, void* data);
|
||||
static hsa_status_t Copy(void* dst, const void* src, size_t size, void* data);
|
||||
};
|
||||
|
||||
inline AQLPacket::AQLPacket(memory_pool_free_func_t func)
|
||||
: free_func{func}
|
||||
{}
|
||||
} // namespace hsa
|
||||
} // namespace rocprofiler
|
||||
|
||||
@@ -672,10 +672,10 @@ code_object_load_callback(hsa_executable_t executable,
|
||||
if(_status != HSA_STATUS_SUCCESS) return _status; \
|
||||
}
|
||||
|
||||
auto& loader_table = get_loader_table();
|
||||
auto code_obj_v = code_object{};
|
||||
auto& data = code_obj_v.rocp_data;
|
||||
int _storage_type = ROCPROFILER_CODE_OBJECT_STORAGE_TYPE_NONE;
|
||||
auto& loader_table = get_loader_table();
|
||||
auto code_obj_v = code_object{};
|
||||
auto& data = code_obj_v.rocp_data;
|
||||
uint32_t _storage_type = ROCPROFILER_CODE_OBJECT_STORAGE_TYPE_NONE;
|
||||
|
||||
LOG_IF(FATAL, data.size == 0) << "code object did not properly initialized the size field upon "
|
||||
"construction (this is likely a compiler bug)";
|
||||
|
||||
@@ -342,8 +342,6 @@ WriteInterceptor(const void* packets,
|
||||
{
|
||||
hsa_barrier_and_packet_t barrier{};
|
||||
barrier.header = HSA_PACKET_TYPE_BARRIER_AND << HSA_PACKET_HEADER_TYPE;
|
||||
// barrier.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCACQUIRE_FENCE_SCOPE;
|
||||
// barrier.header |= HSA_FENCE_SCOPE_SYSTEM << HSA_PACKET_HEADER_SCRELEASE_FENCE_SCOPE;
|
||||
barrier.header |= 1 << HSA_PACKET_HEADER_BARRIER;
|
||||
barrier.completion_signal = original_packet.completion_signal;
|
||||
transformed_packets.emplace_back(barrier);
|
||||
|
||||
@@ -90,6 +90,9 @@ constexpr rocprofiler_agent_t default_agent =
|
||||
void
|
||||
QueueController::add_queue(hsa_queue_t* id, std::unique_ptr<Queue> queue)
|
||||
{
|
||||
for(auto& pre_initialize_fn : pre_initialize)
|
||||
pre_initialize_fn(queue->get_agent(), get_core_table(), get_ext_table());
|
||||
|
||||
CHECK(queue);
|
||||
_callback_cache.wlock([&](auto& callbacks) {
|
||||
_queues.wlock([&](auto& map) {
|
||||
@@ -111,6 +114,11 @@ void
|
||||
QueueController::destroy_queue(hsa_queue_t* id)
|
||||
{
|
||||
if(!id) return;
|
||||
_queues.wlock([&](auto& map) {
|
||||
for(auto& deinitialize_fn : pre_deinitialize)
|
||||
if(map.find(id) != map.end())
|
||||
deinitialize_fn(map.at(id)->get_agent(), get_core_table(), get_ext_table());
|
||||
});
|
||||
|
||||
const auto* queue = get_queue(*id);
|
||||
|
||||
@@ -195,7 +203,8 @@ QueueController::init(CoreApiTable& core_table, AmdExtTable& ext_table)
|
||||
{
|
||||
constexpr auto expected_context_size = 160UL;
|
||||
static_assert(
|
||||
sizeof(context::context) == expected_context_size,
|
||||
sizeof(context::context) ==
|
||||
expected_context_size + sizeof(std::shared_ptr<rocprofiler::ThreadTracer>),
|
||||
"If you added a new field to context struct, make sure there is a check here if it "
|
||||
"requires queue interception. Once you have done so, increment expected_context_size");
|
||||
|
||||
@@ -212,6 +221,20 @@ QueueController::init(CoreApiTable& core_table, AmdExtTable& ext_table)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(itr->thread_trace)
|
||||
{
|
||||
enable_intercepter = true;
|
||||
std::weak_ptr<rocprofiler::ThreadTracer> trace = itr->thread_trace;
|
||||
pre_initialize.emplace_back(
|
||||
[trace](const AgentCache& cache, const CoreApiTable& core, const AmdExtTable& ext) {
|
||||
if(auto locked = trace.lock()) locked->resource_init(cache, core, ext);
|
||||
});
|
||||
pre_deinitialize.emplace_back(
|
||||
[trace](const AgentCache& cache, const CoreApiTable&, const AmdExtTable&) {
|
||||
if(auto locked = trace.lock()) locked->resource_deinit(cache);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(enable_intercepter)
|
||||
|
||||
@@ -103,6 +103,7 @@ public:
|
||||
private:
|
||||
using client_id_map_t = std::unordered_map<ClientID, agent_callback_tuple_t>;
|
||||
using agent_cache_map_t = std::unordered_map<uint32_t, AgentCache>;
|
||||
using resource_alloc_t = void(const AgentCache&, const CoreApiTable&, const AmdExtTable&);
|
||||
|
||||
CoreApiTable _core_table = {};
|
||||
AmdExtTable _ext_table = {};
|
||||
@@ -110,6 +111,9 @@ private:
|
||||
common::Synchronized<client_id_map_t> _callback_cache = {};
|
||||
agent_cache_map_t _supported_agents = {};
|
||||
common::Synchronized<hsa::profiler_serializer> _profiler_serializer;
|
||||
|
||||
std::vector<std::function<resource_alloc_t>> pre_initialize;
|
||||
std::vector<std::function<resource_alloc_t>> pre_deinitialize;
|
||||
};
|
||||
|
||||
QueueController*
|
||||
|
||||
Reference in New Issue
Block a user