diff --git a/rocclr/runtime/device/device.cpp b/rocclr/runtime/device/device.cpp index 5bd20a07e4..3b5021ccb6 100644 --- a/rocclr/runtime/device/device.cpp +++ b/rocclr/runtime/device/device.cpp @@ -126,7 +126,7 @@ bool Device::BlitProgram::create(amd::Device* device, const char* extraKernels, // Build all kernels std::string opt = "-cl-internal-kernel "; if (!device->settings().useLightning_) { - opt += "-Wf,--force_disable_spir -fno-lib-no-inline -fno-sc-keep-calls "; + opt += "-Wf,--force_disable_spir -fno-lib-no-inline -fno-sc-keep-calls "; } if (extraOptions != nullptr) { @@ -135,7 +135,8 @@ bool Device::BlitProgram::create(amd::Device* device, const char* extraKernels, if (!GPU_DUMP_BLIT_KERNELS) { opt += " -fno-enable-dump"; } - if (CL_SUCCESS != program_->build(devices, opt.c_str(), nullptr, nullptr, GPU_DUMP_BLIT_KERNELS)) { + if (CL_SUCCESS != + program_->build(devices, opt.c_str(), nullptr, nullptr, GPU_DUMP_BLIT_KERNELS)) { return false; } @@ -209,7 +210,8 @@ Device::Device() blitProgram_(nullptr), hwDebugMgr_(nullptr), vaCacheAccess_(nullptr), - vaCacheMap_(nullptr) { + vaCacheMap_(nullptr), + index_(0) { memset(&info_, '\0', sizeof(info_)); } @@ -269,6 +271,13 @@ void Device::registerDevice() { info_.type_ |= CL_DEVICE_TYPE_DEFAULT; } } + if (isOnline()) { + for (const auto& dev : devices()) { + if (dev->isOnline()) { + index_++; + } + } + } devices_->push_back(this); } @@ -417,7 +426,7 @@ char* Device::getExtensionString() { return result; } -#if defined(WITH_LIGHTNING_COMPILER) && ! defined(USE_COMGR_LIBRARY) +#if defined(WITH_LIGHTNING_COMPILER) && !defined(USE_COMGR_LIBRARY) CacheCompilation::CacheCompilation(std::string targetStr, std::string postfix, bool enableCache, bool resetCache) : codeCache_(targetStr, 0, AMD_PLATFORM_BUILD_NUMBER, postfix), @@ -584,7 +593,7 @@ bool CacheCompilation::compileAndLinkExecutable(amd::opencl_driver::Compiler* C, return true; } -#endif // defined(WITH_LIGHTNING_COMPILER) && ! defined(USE_COMGR_LIBRARY) +#endif // defined(WITH_LIGHTNING_COMPILER) && ! defined(USE_COMGR_LIBRARY) } // namespace amd @@ -602,11 +611,15 @@ Settings::Settings() : value_(0) { //!< concurrent Virtual GPUs for default overrideLclSet = (!flagIsDefault(GPU_MAX_WORKGROUP_SIZE)) ? 1 : 0; - overrideLclSet |= (!flagIsDefault(GPU_MAX_WORKGROUP_SIZE_2D_X) || - !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_2D_Y)) ? 2 : 0; - overrideLclSet |= (!flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_X) || - !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_Y) || - !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_Z)) ? 4 : 0; + overrideLclSet |= + (!flagIsDefault(GPU_MAX_WORKGROUP_SIZE_2D_X) || !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_2D_Y)) + ? 2 + : 0; + overrideLclSet |= + (!flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_X) || !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_Y) || + !flagIsDefault(GPU_MAX_WORKGROUP_SIZE_3D_Z)) + ? 4 + : 0; if (amd::IS_HIP) { GPU_SINGLE_ALLOC_PERCENT = 100; @@ -614,8 +627,8 @@ Settings::Settings() : value_(0) { } void Memory::saveMapInfo(const void* mapAddress, const amd::Coord3D origin, - const amd::Coord3D region, uint mapFlags, bool entire, - amd::Image* baseMip) { + const amd::Coord3D region, uint mapFlags, bool entire, + amd::Image* baseMip) { // Map/Unmap must be serialized. amd::ScopedLock lock(owner()->lockMemoryOps()); @@ -640,7 +653,7 @@ void Memory::saveMapInfo(const void* mapAddress, const amd::Coord3D origin, // Insert into the map if it's the first region if (++pInfo->count_ == 1) { - writeMapInfo_.insert({ mapAddress, info }); + writeMapInfo_.insert({mapAddress, info}); } } diff --git a/rocclr/runtime/device/device.hpp b/rocclr/runtime/device/device.hpp index 6ba0fabdd7..9b0d04b008 100644 --- a/rocclr/runtime/device/device.hpp +++ b/rocclr/runtime/device/device.hpp @@ -1052,7 +1052,11 @@ class ThreadTrace : public amd::HeapObject { class VirtualDevice : public amd::HeapObject { public: //! Construct a new virtual device for the given physical device. - VirtualDevice(amd::Device& device) : device_(device), blitMgr_(NULL) {} + VirtualDevice(amd::Device& device) + : device_(device) + , blitMgr_(NULL) + , execution_("Virtual device execution lock", true) + , index_(0) {} //! Destroy this virtual device. virtual ~VirtualDevice() {} @@ -1095,6 +1099,12 @@ class VirtualDevice : public amd::HeapObject { //! Get the blit manager object device::BlitManager& blitMgr() const { return *blitMgr_; } + //! Returns the monitor object for execution access by VirtualGPU + amd::Monitor& execution() { return execution_; } + + //! Returns the virtual device unique index + uint index() const { return index_; } + private: //! Disable default copy constructor VirtualDevice& operator=(const VirtualDevice&); @@ -1107,6 +1117,9 @@ class VirtualDevice : public amd::HeapObject { protected: device::BlitManager* blitMgr_; //!< Blit manager + + amd::Monitor execution_; //!< Lock to serialise access to all device objects + uint index_; //!< The virtual device unique index }; } // namespace device @@ -1377,6 +1390,9 @@ class Device : public RuntimeObject { //! Returns the list of devices that can have access to the current const std::vector& P2PAccessDevices() const { return p2p_access_devices_; } + //! Returns index of current device + uint32_t index() const { return index_; } + protected: //! Enable the specified extension char* getExtensionString(); @@ -1407,6 +1423,7 @@ class Device : public RuntimeObject { Monitor* vaCacheAccess_; //!< Lock to serialize VA caching access std::map* vaCacheMap_; //!< VA cache map + uint32_t index_; //!< Unique device index }; #if defined(WITH_LIGHTNING_COMPILER) && !defined(USE_COMGR_LIBRARY) diff --git a/rocclr/runtime/device/gpu/gpuvirtual.cpp b/rocclr/runtime/device/gpu/gpuvirtual.cpp index 0091a4d18f..6ac0e3ba22 100644 --- a/rocclr/runtime/device/gpu/gpuvirtual.cpp +++ b/rocclr/runtime/device/gpu/gpuvirtual.cpp @@ -365,7 +365,6 @@ VirtualGPU::VirtualGPU(Device& device) engineID_(MainEngine), activeKernelDesc_(NULL), gpuDevice_(static_cast(device)), - execution_("Virtual GPU execution lock", true), printfDbg_(NULL), printfDbgHSA_(NULL), tsCache_(NULL), diff --git a/rocclr/runtime/device/gpu/gpuvirtual.hpp b/rocclr/runtime/device/gpu/gpuvirtual.hpp index cf5ad90ef6..33d94974de 100644 --- a/rocclr/runtime/device/gpu/gpuvirtual.hpp +++ b/rocclr/runtime/device/gpu/gpuvirtual.hpp @@ -318,12 +318,6 @@ class VirtualGPU : public device::VirtualDevice, public CALGSLContext { //! Returns gsl memory object for VM const gslMemObject* vmMems() const { return vmMems_; } - //! Returns the monitor object for execution access by VirtualGPU - amd::Monitor& execution() { return execution_; } - - //! Returns the virtual gpu unique index - uint index() const { return index_; } - //! Get the PrintfDbg object PrintfDbg& printfDbg() const { return *printfDbg_; } @@ -476,8 +470,6 @@ class VirtualGPU : public device::VirtualDevice, public CALGSLContext { GpuEvents gpuEvents_; //!< GPU events Device& gpuDevice_; //!< physical GPU device - amd::Monitor execution_; //!< Lock to serialise access to all device objects - uint index_; //!< The virtual device unique index PrintfDbg* printfDbg_; //!< GPU printf implemenation PrintfDbgHSA* printfDbgHSA_; //!< HSAIL printf implemenation diff --git a/rocclr/runtime/device/pal/palvirtual.cpp b/rocclr/runtime/device/pal/palvirtual.cpp index 0e66799883..b4d0f351ff 100644 --- a/rocclr/runtime/device/pal/palvirtual.cpp +++ b/rocclr/runtime/device/pal/palvirtual.cpp @@ -806,7 +806,6 @@ VirtualGPU::VirtualGPU(Device& device) : device::VirtualDevice(device), engineID_(MainEngine), gpuDevice_(static_cast(device)), - execution_("Virtual GPU execution lock", true), printfDbgHSA_(nullptr), tsCache_(nullptr), dmaFlushMgmt_(device), diff --git a/rocclr/runtime/device/pal/palvirtual.hpp b/rocclr/runtime/device/pal/palvirtual.hpp index 01103ccd77..006251c6b4 100644 --- a/rocclr/runtime/device/pal/palvirtual.hpp +++ b/rocclr/runtime/device/pal/palvirtual.hpp @@ -398,12 +398,6 @@ class VirtualGPU : public device::VirtualDevice { //! Finds if pinned memory is cached amd::Memory* findPinnedMem(void* addr, size_t size); - //! Returns the monitor object for execution access by VirtualGPU - amd::Monitor& execution() { return execution_; } - - //! Returns the virtual gpu unique index - uint index() const { return index_; } - //! Get the PrintfDbgHSA object PrintfDbgHSA& printfDbgHSA() const { return *printfDbgHSA_; } @@ -609,8 +603,6 @@ class VirtualGPU : public device::VirtualDevice { ); Device& gpuDevice_; //!< physical GPU device - amd::Monitor execution_; //!< Lock to serialise access to all device objects - uint index_; //!< The virtual device unique index PrintfDbgHSA* printfDbgHSA_; //!< HSAIL printf implemenation diff --git a/rocclr/runtime/device/rocm/rocvirtual.cpp b/rocclr/runtime/device/rocm/rocvirtual.cpp index fb130dd234..58cb69974e 100644 --- a/rocclr/runtime/device/rocm/rocvirtual.cpp +++ b/rocclr/runtime/device/rocm/rocvirtual.cpp @@ -555,7 +555,6 @@ bool VirtualGPU::releaseGpuMemoryFence() { VirtualGPU::VirtualGPU(Device& device) : device::VirtualDevice(device), - execution_("Virtual GPU execution lock", true), roc_device_(device), virtualQueue_(nullptr), deviceQueueSize_(0), @@ -563,9 +562,9 @@ VirtualGPU::VirtualGPU(Device& device) schedulerThreads_(0), schedulerParam_(nullptr), schedulerQueue_(nullptr), - schedulerSignal_({0}), - index_(device.numOfVgpus_++) // Virtual gpu unique index incrementing + schedulerSignal_({0}) { + index_ = device.numOfVgpus_++; gpu_device_ = device.getBackendDevice(); printfdbg_ = nullptr; diff --git a/rocclr/runtime/device/rocm/rocvirtual.hpp b/rocclr/runtime/device/rocm/rocvirtual.hpp index 80697ef554..821ddc3a52 100644 --- a/rocclr/runtime/device/rocm/rocvirtual.hpp +++ b/rocclr/runtime/device/rocm/rocvirtual.hpp @@ -225,8 +225,6 @@ class VirtualGPU : public device::VirtualDevice { size_t& ldsAddress, //!< LDS usage bool cooperativeGroups //!< Dispatch with cooperative groups ); - // Retun the virtual gpu unique index - uint index() const { return index_; } //! Adds a stage write buffer into a list void addXferWrite(Memory& memory); @@ -245,8 +243,6 @@ class VirtualGPU : public device::VirtualDevice { void enableSyncBlit() const; - //! Returns the monitor object for execution access by VirtualGPU - amd::Monitor& execution() { return execution_; } // } roc OpenCL integration private: @@ -302,7 +298,6 @@ class VirtualGPU : public device::VirtualDevice { * used to synchronized on kernel outputs. */ bool hasPendingDispatch_; - amd::Monitor execution_; //!< Lock to serialise access to all device objects Timestamp* timestamp_; hsa_agent_t gpu_device_; //!< Physical device hsa_queue_t* gpu_queue_; //!< Queue associated with a gpu @@ -328,7 +323,6 @@ class VirtualGPU : public device::VirtualDevice { uint kernarg_pool_cur_offset_; std::vector signal_pool_; //!< Pool of signals for profiling - uint index_; //!< Virtual gpu unique index friend class Timestamp; // PM4 packet for gfx8 performance counter diff --git a/rocclr/runtime/platform/activity.cpp b/rocclr/runtime/platform/activity.cpp new file mode 100644 index 0000000000..d574dc90f4 --- /dev/null +++ b/rocclr/runtime/platform/activity.cpp @@ -0,0 +1,44 @@ +/* +Copyright (c) 2019 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 "platform/activity.hpp" + +ACTIVITY_PROF_INSTANCES(); + +#define CASE_STRING(X, C) case X: case_string = #C ;break; + +const char* getOclCommandKindString(uint32_t op) { + const char* case_string; + + switch(static_cast(op)) { + CASE_STRING(CL_COMMAND_NDRANGE_KERNEL, KernelExecution) + CASE_STRING(CL_COMMAND_READ_BUFFER, CopyDeviceToHost) + CASE_STRING(CL_COMMAND_WRITE_BUFFER, CopyoHostToDevice) + CASE_STRING(CL_COMMAND_COPY_BUFFER, CopyDeviceToDevice) + CASE_STRING(CL_COMMAND_READ_BUFFER_RECT, CopyDeviceToHost2D) + CASE_STRING(CL_COMMAND_WRITE_BUFFER_RECT, CopyoHostToDevice2D) + CASE_STRING(CL_COMMAND_COPY_BUFFER_RECT, CopyDeviceToDevice2D) + CASE_STRING(CL_COMMAND_FILL_BUFFER, FillBuffer) + default: case_string = "Unknown command type"; + }; + return case_string; +}; diff --git a/rocclr/runtime/platform/activity.hpp b/rocclr/runtime/platform/activity.hpp new file mode 100644 index 0000000000..f65769a0c7 --- /dev/null +++ b/rocclr/runtime/platform/activity.hpp @@ -0,0 +1,185 @@ +/* +Copyright (c) 2019 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 +#include +#include + +#include "thread/monitor.hpp" + +#define USE_PROF_API 1 + +#if USE_PROF_API +enum OpId { OP_ID_DISPATCH = 0, OP_ID_COPY = 1, OP_ID_BARRIER = 2, OP_ID_NUMBER = 3 }; + +#include "prof_protocol.h" + +// Statically allocated table of callbacks and global unique ID of each operation +#define ACTIVITY_PROF_INSTANCES() \ + namespace activity_prof { \ + CallbacksTable::table_t CallbacksTable::table_{}; \ + std::atomic ActivityProf::globe_record_id_(0); \ + } // activity_prof + +namespace activity_prof { +typedef activity_correlation_id_t record_id_t; +typedef activity_op_t op_id_t; +typedef uint32_t command_id_t; + +typedef activity_id_callback_t id_callback_fun_t; +typedef activity_async_callback_t callback_fun_t; +typedef void* callback_arg_t; + +// Activity callbacks table +class CallbacksTable { + public: + struct table_t { + id_callback_fun_t id_callback; + callback_fun_t op_callback; + callback_arg_t arg; + std::atomic enabled[OP_ID_NUMBER]; + }; + + // Initialize record id callback and activity callback + static void init(const id_callback_fun_t& id_callback, const callback_fun_t& op_callback, + const callback_arg_t& arg) { + table_.id_callback = id_callback; + table_.op_callback = op_callback; + table_.arg = arg; + } + + static bool SetEnabled(const op_id_t& op_id, const bool& enable) { + bool ret = true; + if (op_id < OP_ID_NUMBER) { + table_.enabled[op_id].store(enable, std::memory_order_release); + } else { + ret = false; + } + return ret; + } + + static bool IsEnabled(const op_id_t& op_id) { + return table_.enabled[op_id].load(std::memory_order_acquire); + } + + static id_callback_fun_t get_id_callback() { return table_.id_callback; } + static callback_fun_t get_op_callback() { return table_.op_callback; } + static callback_arg_t get_arg() { return table_.arg; } + + private: + static table_t table_; +}; + +// Activity profile class +class ActivityProf { + public: + // Domain ID + static const int ACTIVITY_DOMAIN_ID = ACTIVITY_DOMAIN_HIP_VDI; + + ActivityProf() : command_id_(0), queue_id_(0), device_id_(0), record_id_(0), enabled_(false) {} + + // Initialization + void Initialize(const command_id_t command_id, const uint32_t queue_id, + const uint32_t device_id) { + activity_op_t op_id = (command_id == CL_COMMAND_NDRANGE_KERNEL) ? OP_ID_DISPATCH : OP_ID_COPY; + enabled_ = CallbacksTable::IsEnabled(op_id); + if (IsEnabled()) { + command_id_ = command_id; + queue_id_ = queue_id; + device_id_ = device_id; + record_id_ = globe_record_id_.fetch_add(1, std::memory_order_relaxed); + (CallbacksTable::get_id_callback())(record_id_); + } + } + + template inline void ReportEventTimestamps(T& obj, const size_t bytes = 0) { + if (IsEnabled()) { + uint64_t start = obj.profilingInfo().start_; + uint64_t end = obj.profilingInfo().end_; + callback(start, end, bytes); + } + } + + bool IsEnabled() const { return enabled_; } + + private: + // Activity callback routine + void callback(const uint64_t begin_ts, const uint64_t end_ts, const size_t bytes) { + activity_op_t op_id = (command_id_ == CL_COMMAND_NDRANGE_KERNEL) ? OP_ID_DISPATCH : OP_ID_COPY; + activity_record_t record { + ACTIVITY_DOMAIN_ID, // domain id + (activity_kind_t)command_id_, // activity kind + op_id, // operation id + record_id_, // activity correlation id + begin_ts, // begin timestamp, ns + end_ts, // end timestamp, ns + static_cast(device_id_), // device id + queue_id_, // queue id + bytes // copied data size, for memcpy + }; + (CallbacksTable::get_op_callback())(op_id, &record, CallbacksTable::get_arg()); + } + + command_id_t command_id_; //!< Command ID, executed on the queue + uint32_t queue_id_; //!< Queue ID, associated with this command + uint32_t device_id_; //!< Device ID, associated with this command + record_id_t record_id_; //!< Uniqueue execution ID(counter) of this command + bool enabled_; //!< Activity profiling is enabled + + // Global record ID + static std::atomic globe_record_id_; //!< GLobal counter of all executed commands +}; + +} // namespace activity_prof + +#else +#define ACTIVITY_PROF_INSTANCES() + +namespace activity_prof { +typedef uint32_t op_id_t; +typedef uint32_t command_id_t; + +typedef void* id_callback_fun_t; +typedef void* callback_fun_t; +typedef void* callback_arg_t; + +struct CallbacksTable { + static void init(const id_callback_fun_t& id_callback, const callback_fun_t& op_callback, + const callback_arg_t& arg) {} + static bool SetEnabled(const op_id_t& op_id, const bool& enable) { return false; } +}; + +class ActivityProf { + public: + ActivityProf() {} + inline void Initialize(const command_id_t command_id, const uint32_t queue_id, + const uint32_t device_id) {} + template inline void ReportEventTimestamps(T& obj, const size_t bytes = 0) {} + inline bool IsEnabled() { return false; } +}; + +} // namespace activity_prof + +#endif + +const char* getOclCommandKindString(uint32_t op); diff --git a/rocclr/runtime/platform/command.cpp b/rocclr/runtime/platform/command.cpp index a2aff2401d..17520ad683 100644 --- a/rocclr/runtime/platform/command.cpp +++ b/rocclr/runtime/platform/command.cpp @@ -100,6 +100,7 @@ bool Event::setStatus(cl_int status, uint64_t timeStamp) { // status, we release all the resources associated with this instance. releaseResources(); + activity_.ReportEventTimestamps(*this); // Broadcast all the waiters. if (referenceCount() > 1) { signal(); @@ -199,6 +200,7 @@ Command::Command(HostQueue& queue, cl_command_type type, commandWaitBits_(commandWaitBits) { // Retain the commands from the event wait list. std::for_each(eventWaitList.begin(), eventWaitList.end(), std::mem_fun(&Command::retain)); + activity_.Initialize(type, queue.vdev()->index(), queue.device().index()); } void Command::releaseResources() { diff --git a/rocclr/runtime/platform/command.hpp b/rocclr/runtime/platform/command.hpp index 8e043e0809..42d1f7016c 100644 --- a/rocclr/runtime/platform/command.hpp +++ b/rocclr/runtime/platform/command.hpp @@ -25,6 +25,7 @@ #include "platform/memory.hpp" #include "platform/perfctr.hpp" #include "platform/threadtrace.hpp" +#include "platform/activity.hpp" #include "CL/cl_ext.h" @@ -112,6 +113,8 @@ class Event : public RuntimeObject { } profilingInfo_; + activity_prof::ActivityProf activity_; //!< Activity profiling + //! Construct a new event. Event(); diff --git a/rocclr/runtime/platform/prof_protocol.h b/rocclr/runtime/platform/prof_protocol.h new file mode 100644 index 0000000000..69c2f6f3a2 --- /dev/null +++ b/rocclr/runtime/platform/prof_protocol.h @@ -0,0 +1,78 @@ +/* +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 INC_EXT_PROF_PROTOCOL_H_ +#define INC_EXT_PROF_PROTOCOL_H_ + +// Traced API domains +typedef enum { + ACTIVITY_DOMAIN_HSA_API = 0, // HSA domain + ACTIVITY_DOMAIN_HSA_OPS = 1, // HSA async activity domain + ACTIVITY_DOMAIN_HCC_OPS = 2, // HCC async activity domain + ACTIVITY_DOMAIN_HIP_API = 3, // HIP domain + ACTIVITY_DOMAIN_HIP_VDI = 4, // VDI domain + ACTIVITY_DOMAIN_NUMBER = 5 +} activity_domain_t; + +// API calback type +typedef void (*activity_rtapi_callback_t)(uint32_t domain, uint32_t cid, const void* data, void* arg); +typedef uint32_t activity_kind_t; +typedef uint32_t activity_op_t; + +// API callback phase +typedef enum { + ACTIVITY_API_PHASE_ENTER = 0, + ACTIVITY_API_PHASE_EXIT = 1 +} activity_api_phase_t; + +// Trace record types +// Correlation id +typedef uint64_t activity_correlation_id_t; + +// Activity record type +struct activity_record_t { + uint32_t domain; // activity domain id + activity_kind_t kind; // activity kind + activity_op_t op; // activity op + activity_correlation_id_t correlation_id; // activity ID + uint64_t begin_ns; // host begin timestamp + uint64_t end_ns; // host end timestamp + union { + struct { + int device_id; // device id + uint64_t queue_id; // queue id + }; + struct { + uint32_t process_id; // device id + uint32_t thread_id; // thread id + }; + }; + size_t bytes; // data size bytes +}; + +// Activity sync calback type +typedef activity_record_t* (*activity_sync_callback_t)(uint32_t cid, activity_record_t* record, const void* data, void* arg); +// Activity async calback type +typedef void (*activity_id_callback_t)(activity_correlation_id_t id); +typedef void (*activity_async_callback_t)(uint32_t op, void* record, void* arg); + +#endif // INC_EXT_PROF_PROTOCOL_H_