diff --git a/rocclr/cmake/ROCclrPAL.cmake b/rocclr/cmake/ROCclrPAL.cmake index 5ca218c398..4d128ee3b8 100644 --- a/rocclr/cmake/ROCclrPAL.cmake +++ b/rocclr/cmake/ROCclrPAL.cmake @@ -76,6 +76,7 @@ target_sources(rocclr PRIVATE ${ROCCLR_SRC_DIR}/device/pal/palsignal.cpp ${ROCCLR_SRC_DIR}/device/pal/palthreadtrace.cpp ${ROCCLR_SRC_DIR}/device/pal/paltimestamp.cpp + ${ROCCLR_SRC_DIR}/device/pal/palubercapturemgr.cpp ${ROCCLR_SRC_DIR}/device/pal/palvirtual.cpp) target_compile_definitions(rocclr PUBLIC WITH_PAL_DEVICE PAL_GPUOPEN_OCL) diff --git a/rocclr/device/pal/palcapturemgr.hpp b/rocclr/device/pal/palcapturemgr.hpp new file mode 100644 index 0000000000..20307df8b9 --- /dev/null +++ b/rocclr/device/pal/palcapturemgr.hpp @@ -0,0 +1,60 @@ +/* Copyright (c) 2024 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. */ + +#pragma once + +#include "device/pal/paldefs.hpp" +#include "palDeveloperHooks.h" + +namespace amd::pal { + +class Device; +class VirtualGPU; +class HSAILKernel; + +// ================================================================================================ +class ICaptureMgr { + public: + virtual bool Update(Pal::IPlatform* platform) = 0; + + virtual void PreDispatch(VirtualGPU* gpu, + const HSAILKernel& kernel, + size_t x, size_t y, size_t z) = 0; + virtual void PostDispatch(VirtualGPU* gpu) = 0; + + virtual void FinishRGPTrace(VirtualGPU* gpu, bool aborted) = 0; + + virtual void WriteBarrierStartMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const = 0; + virtual void WriteBarrierEndMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const = 0; + + virtual bool RegisterTimedQueue(uint32_t queue_id, + Pal::IQueue* iQueue, bool* debug_vmid) const = 0; + + virtual Pal::Result TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, + const Pal::SubmitInfo& submitInfo) const = 0; + + virtual uint64_t AddElfBinary(const void* exe_binary, size_t exe_binary_size, + const void* elf_binary, size_t elf_binary_size, + Pal::IGpuMemory* pGpuMemory, size_t offset) = 0; +}; + +} // namespace amd::pal diff --git a/rocclr/device/pal/paldevice.cpp b/rocclr/device/pal/paldevice.cpp index a0de81959a..e0929d6fb1 100644 --- a/rocclr/device/pal/paldevice.cpp +++ b/rocclr/device/pal/paldevice.cpp @@ -25,6 +25,8 @@ #include "device/pal/paldefs.hpp" #include "device/pal/palmemory.hpp" #include "device/pal/paldevice.hpp" +#include "device/pal/palgpuopen.hpp" +#include "device/pal/palubercapturemgr.hpp" #include "utils/flags.hpp" #include "utils/versions.hpp" #include "thread/monitor.hpp" @@ -59,6 +61,7 @@ #ifdef PAL_GPUOPEN_OCL // gpuutil headers #include "gpuUtil/palGpaSession.h" +#include "palTraceSession.h" #include "devDriverServer.h" #include "protocols/rgpServer.h" #include "protocols/driverControlServer.h" @@ -816,7 +819,7 @@ Device::Device() globalScratchBuf_(nullptr), srdManager_(nullptr), resourceList_(nullptr), - rgpCaptureMgr_(nullptr) {} + captureMgr_(nullptr) {} Device::~Device() { if (p2p_stage_ != nullptr) { @@ -877,7 +880,7 @@ Device::~Device() { device_ = nullptr; // Delete developer driver manager - delete rgpCaptureMgr_; + delete captureMgr_; } extern const char* SchedulerSourceCode; @@ -969,10 +972,21 @@ bool Device::create(Pal::IDevice* device) { // Make sure CP DMA can be used for all possible transfers palSettings->cpDmaCmdCopyMemoryMaxBytes = 0xFFFFFFFF; - // Create RGP capture manager + // Create RGP / UberTrace capture manager // Note: RGP initialization in PAL must be performed before CommitSettingsAndInit() - rgpCaptureMgr_ = RgpCaptureMgr::Create(platform_, *this); - if (nullptr != rgpCaptureMgr_) { +#if PAL_BUILD_RDF + if ((platform_->GetTraceSession() != nullptr) && + (platform_->GetTraceSession()->IsTracingEnabled())) + { + captureMgr_ = UberTraceCaptureMgr::Create(platform_, *this); + } + else +#endif + { + captureMgr_ = RgpCaptureMgr::Create(platform_, *this); + } + + if (nullptr != captureMgr_) { // KMD forced DWORD alignment for debug VMID, request it back to Unaligned palSettings->hardwareBufferAlignmentMode = Pal::BufferAlignmentMode::Unaligned; Pal::IPlatform::InstallDeveloperCb(iPlat(), &Device::PalDeveloperCallback, this); @@ -1113,10 +1127,10 @@ void PAL_STDCALL Device::PalDeveloperCallback(void* pPrivateData, const Pal::uin switch (type) { case Pal::Developer::CallbackType::BarrierBegin: - device->rgpCaptureMgr()->WriteBarrierStartMarker(gpu, barrier); + device->captureMgr()->WriteBarrierStartMarker(gpu, barrier); break; case Pal::Developer::CallbackType::BarrierEnd: - device->rgpCaptureMgr()->WriteBarrierEndMarker(gpu, barrier); + device->captureMgr()->WriteBarrierEndMarker(gpu, barrier); break; case Pal::Developer::CallbackType::ImageBarrier: assert(false); @@ -1186,10 +1200,10 @@ bool Device::initializeHeapResources() { } // Update RGP capture manager - if (rgpCaptureMgr_ != nullptr) { - if (!rgpCaptureMgr_->Update(platform_)) { - delete rgpCaptureMgr_; - rgpCaptureMgr_ = nullptr; + if (captureMgr_ != nullptr) { + if (!captureMgr_->Update(platform_)) { + delete captureMgr_; + captureMgr_ = nullptr; } } diff --git a/rocclr/device/pal/paldevice.hpp b/rocclr/device/pal/paldevice.hpp index 28a45d61c8..20ee48e7ab 100644 --- a/rocclr/device/pal/paldevice.hpp +++ b/rocclr/device/pal/paldevice.hpp @@ -36,7 +36,7 @@ #include "device/pal/paldefs.hpp" #include "device/pal/palsettings.hpp" #include "device/pal/palappprofile.hpp" -#include "device/pal/palgpuopen.hpp" +#include "device/pal/palcapturemgr.hpp" #include "device/pal/palsignal.hpp" #include "acl.h" #include "memory" @@ -587,7 +587,8 @@ class Device : public NullDevice { //! Allow access for peer device bool deviceAllowAccess(void* dst) const; - RgpCaptureMgr* rgpCaptureMgr() const { return rgpCaptureMgr_; } + //! Returns a handle to the capture manager (RGP or UberTrace) + ICaptureMgr* captureMgr() const { return captureMgr_; } //! Update free memory for OCL extension void updateAllocedMemory(Pal::GpuHeap heap, //!< PAL GPU heap for update @@ -750,7 +751,7 @@ class Device : public NullDevice { mutable std::atomic allocedMem[Pal::GpuHeap::GpuHeapCount]; //!< Free memory counter std::unordered_set* resourceList_; //!< Active resource list - RgpCaptureMgr* rgpCaptureMgr_; //!< RGP capture manager + ICaptureMgr* captureMgr_; //!< RGP/UberTrace capture manager Pal::GpuMemoryHeapProperties heaps_[Pal::GpuHeapCount]; //!< Information about heaps, returned from PAL std::map queue_pool_; //!< Pool of PAL queues for recycling diff --git a/rocclr/device/pal/palgpuopen.hpp b/rocclr/device/pal/palgpuopen.hpp index 9b2899a430..1bb1985732 100644 --- a/rocclr/device/pal/palgpuopen.hpp +++ b/rocclr/device/pal/palgpuopen.hpp @@ -21,7 +21,7 @@ #pragma once #include -#include "device/pal/paldefs.hpp" +#include "device/pal/palcapturemgr.hpp" #include "platform/commandqueue.hpp" #include "device/blit.hpp" @@ -314,34 +314,36 @@ struct RgpSqttMarkerUserEventWithString { // ================================================================================================ // This class provides functionality to interact with the GPU Open Developer Mode message passing // service and the rest of the driver. -class RgpCaptureMgr { +class RgpCaptureMgr final : public ICaptureMgr { public: ~RgpCaptureMgr(); static RgpCaptureMgr* Create(Pal::IPlatform* platform, const Device& device); - void Finalize(); + void PreDispatch(VirtualGPU* gpu, const HSAILKernel& kernel, + size_t x, size_t y, size_t z) override; - void PreDispatch(VirtualGPU* gpu, const HSAILKernel& kernel, size_t x, size_t y, size_t z); - void PostDispatch(VirtualGPU* gpu); + void PostDispatch(VirtualGPU* gpu) override; - void WaitForDriverResume(); - - void PostDeviceCreate(); - void PreDeviceDestroy(); - void FinishRGPTrace(VirtualGPU* gpu, bool aborted); - - bool IsQueueTimingActive() const; + void FinishRGPTrace(VirtualGPU* gpu, bool aborted) override; void WriteBarrierStartMarker(const VirtualGPU* gpu, - const Pal::Developer::BarrierData& data) const; - void WriteBarrierEndMarker(const VirtualGPU* gpu, const Pal::Developer::BarrierData& data) const; - bool RegisterTimedQueue(uint32_t queue_id, Pal::IQueue* iQueue, bool* debug_vmid) const; + const Pal::Developer::BarrierData& data) const override; + + void WriteBarrierEndMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const override; + + bool RegisterTimedQueue(uint32_t queue_id, + Pal::IQueue* iQueue, bool* debug_vmid) const override; + Pal::Result TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, - const Pal::SubmitInfo& submitInfo) const; - bool Update(Pal::IPlatform* platform); - uint64_t AddElfBinary(const void* exe_binary, size_t exe_binary_size, const void* elf_binary, - size_t elf_binary_size, Pal::IGpuMemory* pGpuMemory, size_t offset); + const Pal::SubmitInfo& submitInfo) const override; + + bool Update(Pal::IPlatform* platform) override; + + uint64_t AddElfBinary(const void* exe_binary, size_t exe_binary_size, + const void* elf_binary, size_t elf_binary_size, + Pal::IGpuMemory* pGpuMemory, size_t offset) override; private: // Steps that an RGP trace goes through enum class TraceStatus { @@ -375,6 +377,8 @@ class RgpCaptureMgr { RgpCaptureMgr(Pal::IPlatform* platform, const Device& device); bool Init(Pal::IPlatform* platform); + void Finalize(); + Pal::Result PrepareRGPTrace(VirtualGPU* pQueue); Pal::Result BeginRGPTrace(VirtualGPU* pQueue); Pal::Result EndRGPHardwareTrace(VirtualGPU* pQueue); @@ -382,6 +386,7 @@ class RgpCaptureMgr { void DestroyRGPTracing(); Pal::Result CheckForTraceResults(); static bool GpuSupportsTracing(const Pal::DeviceProperties& props, const Settings& settings); + RgpSqttMarkerEvent BuildEventMarker(const VirtualGPU* gpu, RgpSqttMarkerEventType api_type) const; void WriteMarker(const VirtualGPU* gpu, const void* data, size_t data_size) const; void WriteEventWithDimsMarker(const VirtualGPU* gpu, RgpSqttMarkerEventType apiType, uint32_t x, @@ -390,6 +395,13 @@ class RgpCaptureMgr { const std::string& name) const; void WriteComputeBindMarker(const VirtualGPU* gpu, uint64_t api_hash) const; + void WaitForDriverResume(); + + void PostDeviceCreate(); + void PreDeviceDestroy(); + + bool IsQueueTimingActive() const; + const Device& device_; DevDriver::DevDriverServer* dev_driver_server_; DevDriver::RGPProtocol::RGPServer* rgp_server_; diff --git a/rocclr/device/pal/palprogram.cpp b/rocclr/device/pal/palprogram.cpp index 8c2fd590dd..c6d6c1a2ad 100644 --- a/rocclr/device/pal/palprogram.cpp +++ b/rocclr/device/pal/palprogram.cpp @@ -804,8 +804,8 @@ bool LightningProgram::setKernels(void* binary, size_t binSize, amd::Os::FileDes size_t foffset, std::string uri) { #if defined(USE_COMGR_LIBRARY) // Collect the information about compiled binary, except the trap handler - if (!isNull() && (palDevice().rgpCaptureMgr() != nullptr) && !isTrapHandler()) { - apiHash_ = palDevice().rgpCaptureMgr()->AddElfBinary( + if (!isNull() && (palDevice().captureMgr() != nullptr) && !isTrapHandler()) { + apiHash_ = palDevice().captureMgr()->AddElfBinary( binary, binSize, binary, binSize, codeSegGpu_->iMem(), codeSegGpu_->offset()); } diff --git a/rocclr/device/pal/palubercapturemgr.cpp b/rocclr/device/pal/palubercapturemgr.cpp new file mode 100644 index 0000000000..b037d1b43c --- /dev/null +++ b/rocclr/device/pal/palubercapturemgr.cpp @@ -0,0 +1,292 @@ +/* Copyright (c) 2024 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 "device/pal/palubercapturemgr.hpp" +#include "device/pal/paldevice.hpp" + +#include "palPlatform.h" +#include "palTraceSession.h" +#include "palRenderOpTraceController.h" +#include "palCodeObjectTraceSource.h" +#include "palQueueTimingsTraceSource.h" + +#include "devDriverServer.h" +#include "protocols/driverControlServer.h" +#include "util/ddStructuredReader.h" + +namespace amd::pal { + +// ================================================================================================ +// Returns true if the given device properties/settings support tracing. +static inline bool GpuSupportsTracing(const Pal::DeviceProperties& props, + const Settings& settings) { + return props.gfxipProperties.flags.supportRgpTraces && !settings.rgpSqttForceDisable_; +} + +// ================================================================================================ +// Creates the GPU Open Developer Mode manager class. +UberTraceCaptureMgr* UberTraceCaptureMgr::Create(Pal::IPlatform* platform, const Device& device) { + UberTraceCaptureMgr* mgr = new UberTraceCaptureMgr(platform, device); + + if (mgr != nullptr && !mgr->Init(platform)) { + delete mgr; + mgr = nullptr; + } + + return mgr; +} + +// ================================================================================================ +UberTraceCaptureMgr::UberTraceCaptureMgr(Pal::IPlatform* platform, const Device& device) + : device_(device), + dev_driver_server_(platform->GetDevDriverServer()), + global_disp_count_(1), // Must start from 1 according to RGP spec + trace_session_(platform->GetTraceSession()), + trace_controller_(nullptr), + code_object_trace_source_(nullptr), + queue_timings_trace_source_(nullptr) { +} + +// ================================================================================================ +UberTraceCaptureMgr::~UberTraceCaptureMgr() { + DestroyUberTraceResources(); +} + +// ================================================================================================ +bool UberTraceCaptureMgr::CreateUberTraceResources(Pal::IPlatform* platform) { + bool success = false; + + do { + // Initialize the renderop trace controller + trace_controller_ = new GpuUtil::RenderOpTraceController(platform, device_.iDev()); + if (trace_controller_ == nullptr) { + break; + } + + Pal::Result result = trace_session_->RegisterController(trace_controller_); + if (result != Pal::Result::Success) { + break; + } + + // Initialize the code object trace source + code_object_trace_source_ = new GpuUtil::CodeObjectTraceSource(platform); + if (code_object_trace_source_ == nullptr) { + break; + } + + result = trace_session_->RegisterSource(code_object_trace_source_); + if (result != Pal::Result::Success) { + break; + } + + // Initialize the queue timings trace source + queue_timings_trace_source_ = new GpuUtil::QueueTimingsTraceSource(platform); + if (queue_timings_trace_source_ == nullptr) { + break; + } + + result = trace_session_->RegisterSource(queue_timings_trace_source_); + if (result != Pal::Result::Success) { + break; + } + + success = true; + } while (false); + + return success; +} + +// ================================================================================================ +void UberTraceCaptureMgr::DestroyUberTraceResources() { + // Deallocate and unregister all created trace controllers & trace sources + + // RenderOp TraceController + if (trace_controller_ != nullptr) { + trace_session_->UnregisterController(trace_controller_); + delete trace_controller_; + trace_controller_ = nullptr; + } + + // CodeObjects TraceSource + if (code_object_trace_source_ != nullptr) { + trace_session_->UnregisterSource(code_object_trace_source_); + delete code_object_trace_source_; + code_object_trace_source_ = nullptr; + } + + // QueueTimings TraceSource + if (queue_timings_trace_source_ != nullptr) { + trace_session_->UnregisterSource(queue_timings_trace_source_); + delete queue_timings_trace_source_; + queue_timings_trace_source_ = nullptr; + } +} + +// ================================================================================================ +bool UberTraceCaptureMgr::Init(Pal::IPlatform* platform) { + // Finalize the devmode manager + if (dev_driver_server_ == nullptr) { + return false; + } + dev_driver_server_->Finalize(); + + // Initialize the trace sources & controllers owned by the compute driver + const bool success = CreateUberTraceResources(platform); + + if (!success) { + DestroyUberTraceResources(); + return false; + } + + return true; +} + +// ================================================================================================ +void UberTraceCaptureMgr::PreDispatch(VirtualGPU* gpu, const HSAILKernel& kernel, + size_t x, size_t y, size_t z) { + // Wait for the driver to be resumed in case it's been paused. + WaitForDriverResume(); + + // Increment dispatch count in RenderOp trace controller + Pal::IQueue* pQueue = gpu->queue(MainEngine).iQueue_; + trace_controller_->RecordRenderOp(pQueue, GpuUtil::RenderOpTraceController::RenderOpDispatch); + + // Increment the global dispatch counter + global_disp_count_++; +} + +// ================================================================================================ +void UberTraceCaptureMgr::PostDispatch(VirtualGPU* gpu) { +} + +// ================================================================================================ +// Waits for the driver to be resumed if it's currently paused. +void UberTraceCaptureMgr::WaitForDriverResume() { + auto* pDriverControlServer = dev_driver_server_->GetDriverControlServer(); + + assert(pDriverControlServer != nullptr); + pDriverControlServer->DriverTick(); +} + +// ================================================================================================ +void UberTraceCaptureMgr::PreDeviceDestroy() { + if (trace_session_->GetTraceSessionState() == GpuUtil::TraceSessionState::Ready) { + DestroyUberTraceResources(); + } +} + +// ================================================================================================ +void UberTraceCaptureMgr::FinishRGPTrace(VirtualGPU* gpu, bool aborted) { + // Nothing to be done +} + +// ================================================================================================ +bool UberTraceCaptureMgr::IsQueueTimingActive() const { + return ((queue_timings_trace_source_ != nullptr) && + (queue_timings_trace_source_->IsTimingInProgress())); +} + +// ================================================================================================ +void UberTraceCaptureMgr::WriteBarrierStartMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const { +} + +// ================================================================================================ +void UberTraceCaptureMgr::WriteBarrierEndMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const { +} + +// ================================================================================================ +bool UberTraceCaptureMgr::RegisterTimedQueue(uint32_t queue_id, + Pal::IQueue* iQueue, + bool* debug_vmid) const { + // Get the OS context handle for this queue (this is a thing that RGP needs on DX clients; + // it may be optional for Vulkan, but we provide it anyway if available). + Pal::KernelContextInfo kernelContextInfo = {}; + Pal::Result result = iQueue->QueryKernelContextInfo(&kernelContextInfo); + + // QueryKernelContextInfo may fail. + // If so, just use a context identifier of 0. + uint64_t queueContext = (result == Pal::Result::Success) + ? kernelContextInfo.contextIdentifier + : 0; + + // Register the queue with the GPA session class for timed queue operation support. + result = queue_timings_trace_source_->RegisterTimedQueue(iQueue, queue_id, queueContext); + + return (result == Pal::Result::Success); +} + +// ================================================================================================ +Pal::Result UberTraceCaptureMgr::TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, + const Pal::SubmitInfo& submitInfo) const { + // Fill in extra meta-data information to associate the API command buffer data with + // the generated timing information. + GpuUtil::TimedSubmitInfo timedSubmitInfo = {}; + Pal::uint64 apiCmdBufIds = cmdId; + Pal::uint32 sqttCmdBufIds = 0; + + timedSubmitInfo.pApiCmdBufIds = &apiCmdBufIds; + timedSubmitInfo.pSqttCmdBufIds = &sqttCmdBufIds; + timedSubmitInfo.frameIndex = 0; + + // Do a timed submit of all the command buffers + Pal::Result result = queue_timings_trace_source_->TimedSubmit(queue, + submitInfo, + timedSubmitInfo); + + // Punt to non-timed submit if a timed submit fails (or is not supported) + if (result != Pal::Result::Success) { + result = queue->Submit(submitInfo); + } + + return result; +} + +// ================================================================================================ +bool UberTraceCaptureMgr::Update(Pal::IPlatform* platform) { + Pal::Result result = queue_timings_trace_source_->Init(device_.iDev()); + return (result == Pal::Result::Success); +} + +// ================================================================================================ +uint64_t UberTraceCaptureMgr::AddElfBinary(const void* exe_binary, size_t exe_binary_size, + const void* elf_binary, size_t elf_binary_size, + Pal::IGpuMemory* pGpuMemory, size_t offset) { + GpuUtil::ElfBinaryInfo elfBinaryInfo = {}; + elfBinaryInfo.pBinary = exe_binary; + elfBinaryInfo.binarySize = exe_binary_size; ///< FAT Elf binary size. + elfBinaryInfo.pGpuMemory = pGpuMemory; ///< GPU Memory where the compiled ISA resides. + elfBinaryInfo.offset = static_cast(offset); + + elfBinaryInfo.originalHash = DevDriver::MetroHash::MetroHash64( + reinterpret_cast(elf_binary), elf_binary_size); + + elfBinaryInfo.compiledHash = DevDriver::MetroHash::MetroHash64( + reinterpret_cast(exe_binary), exe_binary_size); + + assert(code_object_trace_source_ != nullptr); + + code_object_trace_source_->RegisterElfBinary(elfBinaryInfo); + + return elfBinaryInfo.originalHash; +} + +} // namespace amd::pal diff --git a/rocclr/device/pal/palubercapturemgr.hpp b/rocclr/device/pal/palubercapturemgr.hpp new file mode 100644 index 0000000000..35950ce8f0 --- /dev/null +++ b/rocclr/device/pal/palubercapturemgr.hpp @@ -0,0 +1,96 @@ +/* Copyright (c) 2024 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. */ + +#pragma once + +#include "device/pal/palcapturemgr.hpp" + +namespace DevDriver +{ +class DevDriverServer; +} + +namespace GpuUtil +{ +class TraceSession; +class RenderOpTraceController; +class CodeObjectTraceSource; +class QueueTimingsTraceSource; +} + +namespace amd::pal { + +// ================================================================================================ +class UberTraceCaptureMgr final : public ICaptureMgr { + public: + static UberTraceCaptureMgr* Create(Pal::IPlatform* platform, const Device& device); + + ~UberTraceCaptureMgr(); + + bool Update(Pal::IPlatform* platform) override; + + void PreDispatch(VirtualGPU* gpu, const HSAILKernel& kernel, + size_t x, size_t y, size_t z) override; + + void PostDispatch(VirtualGPU* gpu) override; + + void FinishRGPTrace(VirtualGPU* gpu, bool aborted) override; + + void WriteBarrierStartMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const override; + + void WriteBarrierEndMarker(const VirtualGPU* gpu, + const Pal::Developer::BarrierData& data) const override; + + bool RegisterTimedQueue(uint32_t queue_id, + Pal::IQueue* iQueue, bool* debug_vmid) const override; + + Pal::Result TimedQueueSubmit(Pal::IQueue* queue, uint64_t cmdId, + const Pal::SubmitInfo& submitInfo) const override; + + uint64_t AddElfBinary(const void* exe_binary, size_t exe_binary_size, + const void* elf_binary, size_t elf_binary_size, + Pal::IGpuMemory* pGpuMemory, size_t offset) override; + private: + UberTraceCaptureMgr(Pal::IPlatform* platform, const Device& device); + bool Init(Pal::IPlatform* platform); + void WaitForDriverResume(); + + void PreDeviceDestroy(); + + bool IsQueueTimingActive() const; + + bool CreateUberTraceResources(Pal::IPlatform* platform); + void DestroyUberTraceResources(); + + const Device& device_; + DevDriver::DevDriverServer* dev_driver_server_; + uint64_t global_disp_count_; + + GpuUtil::TraceSession* trace_session_; + GpuUtil::RenderOpTraceController* trace_controller_; + GpuUtil::CodeObjectTraceSource* code_object_trace_source_; + GpuUtil::QueueTimingsTraceSource* queue_timings_trace_source_; + + PAL_DISALLOW_DEFAULT_CTOR(UberTraceCaptureMgr); + PAL_DISALLOW_COPY_AND_ASSIGN(UberTraceCaptureMgr); +}; + +} // namespace amd::pal diff --git a/rocclr/device/pal/palvirtual.cpp b/rocclr/device/pal/palvirtual.cpp index 5511e42122..0cb4e32f1a 100644 --- a/rocclr/device/pal/palvirtual.cpp +++ b/rocclr/device/pal/palvirtual.cpp @@ -422,7 +422,7 @@ bool VirtualGPU::Queue::flush() { // Submit command buffer to OS Pal::Result result; if (gpu_.rgpCaptureEna()) { - result = gpu_.dev().rgpCaptureMgr()->TimedQueueSubmit(iQueue_, cmdBufIdCurrent_, submitInfo); + result = gpu_.dev().captureMgr()->TimedQueueSubmit(iQueue_, cmdBufIdCurrent_, submitInfo); } else { result = iQueue_->Submit(submitInfo); } @@ -1025,12 +1025,11 @@ bool VirtualGPU::create(bool profiling, uint deviceQueueSize, uint rtCUs, // If the developer mode manager is available and it's not a device queue, // then enable RGP capturing - if ((index() != 0) && dev().rgpCaptureMgr() != nullptr) { + if ((index() != 0) && dev().captureMgr() != nullptr) { bool dbg_vmid = false; state_.rgpCaptureEnabled_ = true; - dev().rgpCaptureMgr()->RegisterTimedQueue(2 * index(), queue(MainEngine).iQueue_, &dbg_vmid); - dev().rgpCaptureMgr()->RegisterTimedQueue(2 * index() + 1, queue(SdmaEngine).iQueue_, - &dbg_vmid); + dev().captureMgr()->RegisterTimedQueue(2 * index(), queue(MainEngine).iQueue_, &dbg_vmid); + dev().captureMgr()->RegisterTimedQueue(2 * index() + 1, queue(SdmaEngine).iQueue_, &dbg_vmid); } return true; @@ -1076,7 +1075,7 @@ VirtualGPU::~VirtualGPU() { // Destroy RGP trace if (rgpCaptureEna()) { - dev().rgpCaptureMgr()->FinishRGPTrace(this, true); + dev().captureMgr()->FinishRGPTrace(this, true); } while (!freeCbQueue_.empty()) { @@ -2575,7 +2574,7 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, newLocalSize[i] = sizes.local()[i]; } } - dev().rgpCaptureMgr()->PreDispatch( + dev().captureMgr()->PreDispatch( this, hsaKernel, // Report global size in workgroups, since that's the RGP trace semantics newGlobalSize[0] / newLocalSize[0], newGlobalSize[1] / newLocalSize[1], @@ -2758,7 +2757,7 @@ bool VirtualGPU::submitKernelInternal(const amd::NDRangeContainer& sizes, // Perform post dispatch logic for RGP traces if (rgpCaptureEna()) { - dev().rgpCaptureMgr()->PostDispatch(this); + dev().captureMgr()->PostDispatch(this); } return true;