diff --git a/projects/clr/rocclr/runtime/device/pal/palcounters.cpp b/projects/clr/rocclr/runtime/device/pal/palcounters.cpp index 4835f1a16e..10e142619f 100644 --- a/projects/clr/rocclr/runtime/device/pal/palcounters.cpp +++ b/projects/clr/rocclr/runtime/device/pal/palcounters.cpp @@ -2,18 +2,26 @@ // Copyright (c) 2015 Advanced Micro Devices, Inc. All rights reserved. // -#include "device/pal/paldefs.hpp" #include "device/pal/palcounters.hpp" #include "device/pal/palvirtual.hpp" namespace pal { PalCounterReference* -PalCounterReference::Create( - VirtualGPU& gpu, - const Pal::PerfExperimentCreateInfo& createInfo) +PalCounterReference::Create(VirtualGPU& gpu) { Pal::Result result; + + // Create performance experiment + Pal::PerfExperimentCreateInfo createInfo = {}; + + createInfo.optionFlags.sampleInternalOperations = 1; + createInfo.optionFlags.cacheFlushOnCounterCollection = 1; + createInfo.optionFlags.sqShaderMask = 1; + createInfo.optionValues.sampleInternalOperations = true; + createInfo.optionValues.cacheFlushOnCounterCollection = true; + createInfo.optionValues.sqShaderMask = Pal::PerfShaderMaskCs; + size_t palExperSize = gpu.dev().iDev()->GetPerfExperimentSize( createInfo, &result); if (result != Pal::Result::Success) { @@ -33,47 +41,110 @@ PalCounterReference::Create( return memRef; } -PalCounterReference::~PalCounterReference() { +PalCounterReference::~PalCounterReference() +{ // The counter object is always associated with a particular queue, // so we have to lock just this queue amd::ScopedLock lock(gpu_.execution()); + + if (layout_ != nullptr) { + delete layout_; + } + + if (memory_ != nullptr) { + delete memory_; + } + if (nullptr != iPerf()) { iPerf()->Destroy(); } } -bool -PalCounterReference::growResultArray(uint index) { - if (results_ != nullptr) { - delete [] results_; +uint64_t PalCounterReference::result(uint index) +{ + if (layout_ != nullptr) { + assert(index <= layout_->sampleCount && "index not in range"); + const Pal::GlobalSampleLayout& sample = layout_->samples[index]; + if (sample.dataType == Pal::PerfCounterDataType::Uint32) { + uint32_t beginVal = *reinterpret_cast(reinterpret_cast(cpuAddr_) + sample.beginValueOffset); + uint32_t endVal = *reinterpret_cast(reinterpret_cast(cpuAddr_) + sample.endValueOffset); + return (endVal - beginVal); + } + else if (sample.dataType == Pal::PerfCounterDataType::Uint64) { + uint64_t beginVal = *reinterpret_cast(reinterpret_cast(cpuAddr_) + sample.beginValueOffset); + uint64_t endVal = *reinterpret_cast(reinterpret_cast(cpuAddr_) + sample.endValueOffset); + return (endVal - beginVal); + } + else { + assert(0 && "dataType should be either Uint32 or Uint64"); + return 0; + } } - results_ = new uint64_t [index + 1]; - if (results_ == nullptr) { + + return 0; +} + +bool PalCounterReference::finalize() +{ + Pal::Result result; + + iPerf()->Finalize(); + + // Acquire GPU memory for the query from the pool and bind it. + Pal::GpuMemoryRequirements gpuMemReqs = {}; + iPerf()->GetGpuMemoryRequirements(&gpuMemReqs); + + memory_ = new Memory(gpu().dev(), amd::alignUp(gpuMemReqs.size, gpuMemReqs.alignment)); + + if (nullptr == memory_) { + return false; + } + + if (!memory_->create(Resource::Remote)) { + return false; + } + + cpuAddr_ = memory_->cpuMap(gpu_); + + if (nullptr == cpuAddr_) { + return false; + } + + gpu_.queue(gpu_.engineID_).addMemRef(memory_->iMem()); + + result = iPerf()->BindGpuMemory(memory_->iMem(), 0); + + if (result == Pal::Result::Success) { + Pal::GlobalCounterLayout layout = {}; + iPerf()->GetGlobalCounterLayout(&layout); + + size_t size = sizeof(Pal::GlobalCounterLayout) + (sizeof(Pal::GlobalSampleLayout) * (layout.sampleCount - 1)); + layout_ = reinterpret_cast(new char[size]); + if (layout_ != nullptr) { + layout_->sampleCount = layout.sampleCount; + iPerf()->GetGlobalCounterLayout(layout_); + } + return true; + } + else { return false; } - return true; } PerfCounter::~PerfCounter() { - if (calRef_ == nullptr) { + if (palRef_ == nullptr) { return; } // Release the counter reference object - calRef_->release(); + palRef_->release(); } bool -PerfCounter::create( - PalCounterReference* calRef) +PerfCounter::create() { - assert(&gpu() == &calRef->gpu()); - - calRef_ = calRef; - counter_ = calRef->iPerf(); - index_ = calRef->retain() - 2; - calRef->growResultArray(index_); + index_ = palRef_->retain() - 2; // Initialize the counter Pal::PerfCounterInfo counterInfo = {}; @@ -81,7 +152,7 @@ PerfCounter::create( counterInfo.block = static_cast(info_.blockIndex_); counterInfo.instance = info_.counterIndex_; counterInfo.eventId = info_.eventIndex_; - Pal::Result result = counter_->AddCounter(counterInfo); + Pal::Result result = iPerf()->AddCounter(counterInfo); if (result != Pal::Result::Success) { return false; } @@ -106,9 +177,7 @@ PerfCounter::getInfo(uint64_t infoType) const return info()->eventIndex_; } case CL_PERFCOUNTER_DATA: { - Unimplemented(); - //gslCounter()->GetResult(gpu().cs(), reinterpret_cast(calRef_->results())); - return calRef_->results()[index_]; + return palRef_->result(index_); } default: LogError("Wrong PerfCounter::getInfo parameter"); diff --git a/projects/clr/rocclr/runtime/device/pal/palcounters.hpp b/projects/clr/rocclr/runtime/device/pal/palcounters.hpp index 0d4216e7f8..14bae0a9a9 100644 --- a/projects/clr/rocclr/runtime/device/pal/palcounters.hpp +++ b/projects/clr/rocclr/runtime/device/pal/palcounters.hpp @@ -15,9 +15,7 @@ class VirtualGPU; class PalCounterReference : public amd::ReferenceCountedObject { public: - static PalCounterReference* Create( - VirtualGPU& gpu, - const Pal::PerfExperimentCreateInfo& createInfo); + static PalCounterReference* Create(VirtualGPU& gpu); //! Default constructor PalCounterReference( @@ -25,7 +23,9 @@ public: ) : perfExp_(nullptr) , gpu_(gpu) - , results_(nullptr) {} + , memory_(nullptr) + , cpuAddr_(nullptr) + , layout_(nullptr) {} //! Get PAL counter Pal::IPerfExperiment* iPerf() const { return perfExp_; } @@ -33,21 +33,11 @@ public: //! Returns the virtual GPU device const VirtualGPU& gpu() const { return gpu_; } - //! Increases the results array for this PAL counter(container) - bool growResultArray( - uint maxIndex //!< the maximum HW counter index in the PAL counter - ); - - void finalize() { - iPerf()->Finalize(); - Pal::GlobalCounterLayout layout = {}; - layout.sampleCount = referenceCount() - 1; - iPerf()->GetGlobalCounterLayout(&layout); } + //! Prepare for execution + bool finalize(); //! Returns the PAL counter results - uint64_t* results() const { return results_; } - - Pal::IPerfExperiment* perfExp_; //!< PAL performance experiment object + uint64_t result(uint index); protected: //! Default destructor @@ -60,8 +50,11 @@ private: //! Disable operator= PalCounterReference& operator=(const PalCounterReference&); - VirtualGPU& gpu_; //!< The virtual GPU device object - uint64_t* results_; //!< Counter results + VirtualGPU& gpu_; //!< The virtual GPU device object + Pal::IPerfExperiment* perfExp_; //!< PAL performance experiment object + Pal::GlobalCounterLayout* layout_; //!< Layout of the result + Memory* memory_; + void* cpuAddr_; //!< CPU address of memory_ }; //! Performance counter implementation on GPU @@ -76,26 +69,15 @@ public: uint eventIndex_; //!< Event you wish to count with the counter }; - //! The PerfCounter flags - enum Flags - { - BeginIssued = 0x00000001, - EndIssued = 0x00000002, - ResultReady = 0x00000004 - }; - //! Constructor for the GPU PerfCounter object PerfCounter( const Device& device, //!< A GPU device object - const VirtualGPU& gpu, //!< Virtual GPU device object + PalCounterReference* palRef, //!< Counter Reference cl_uint blockIndex, //!< HW block index cl_uint counterIndex, //!< Counter index within the block cl_uint eventIndex) //!< Event index for profiling : gpuDevice_(device) - , gpu_(gpu) - , calRef_(NULL) - , flags_(0) - , counter_(0) + , palRef_(palRef) , index_(0) { info_.blockIndex_ = blockIndex; @@ -107,9 +89,7 @@ public: virtual ~PerfCounter(); //! Creates the current object - bool create( - PalCounterReference* calRef //!< Reference counter - ); + bool create(); //! Returns the specific information about the counter uint64_t getInfo( @@ -120,13 +100,13 @@ public: const Device& dev() const { return gpuDevice_; } //! Returns the virtual GPU device - const VirtualGPU& gpu() const { return gpu_; } + const VirtualGPU& gpu() const { return palRef_->gpu(); } //! Returns the CAL performance counter descriptor const Info* info() const { return &info_; } //! Returns the Info structure for performance counter - Pal::IPerfExperiment* iPerf() const { return counter_; } + Pal::IPerfExperiment* iPerf() const { return palRef_->iPerf(); } private: //! Disable default copy constructor @@ -135,16 +115,10 @@ private: //! Disable default operator= PerfCounter& operator=(const PerfCounter&); - const Device& gpuDevice_; //!< The backend device - const VirtualGPU& gpu_; //!< The virtual GPU device object - - PalCounterReference* calRef_; //!< Reference counter - uint flags_; //!< The perfcounter object state - Info info_; //!< The info structure for perfcounter - Pal::IPerfExperiment* counter_; //!< GSL counter object - uint index_; //!< Counter index in the CAL container + const Device& gpuDevice_; //!< The backend device + PalCounterReference* palRef_; //!< Reference counter + Info info_; //!< The info structure for perfcounter + uint index_; //!< Counter index in the CAL container }; } // namespace pal - - diff --git a/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp b/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp index 417de5b431..88cd742daa 100644 --- a/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp +++ b/projects/clr/rocclr/runtime/device/pal/palvirtual.cpp @@ -2304,11 +2304,7 @@ VirtualGPU::submitPerfCounter(amd::PerfCounterCommand& vcmd) const amd::PerfCounterCommand::PerfCounterList counters = vcmd.getCounters(); - // Create performance experiment - Pal::PerfExperimentCreateInfo createInfo = {}; - createInfo.optionValues.sqShaderMask = Pal::PerfShaderMaskCs; - - PalCounterReference* palRef = PalCounterReference::Create(*this, createInfo); + PalCounterReference* palRef = PalCounterReference::Create(*this); if (palRef == nullptr) { LogError("We failed to allocate memory for the GPU perfcounter"); vcmd.setStatus(CL_INVALID_OPERATION); @@ -2328,7 +2324,7 @@ VirtualGPU::submitPerfCounter(amd::PerfCounterCommand& vcmd) amd::PerfCounter::Properties prop = amdCounter->properties(); PerfCounter* gpuCounter = new PerfCounter( gpuDevice_, - *this, + palRef, prop[CL_PERFCOUNTER_GPU_BLOCK_INDEX], prop[CL_PERFCOUNTER_GPU_COUNTER_INDEX], prop[CL_PERFCOUNTER_GPU_EVENT_INDEX]); @@ -2337,7 +2333,7 @@ VirtualGPU::submitPerfCounter(amd::PerfCounterCommand& vcmd) vcmd.setStatus(CL_INVALID_OPERATION); return; } - else if (gpuCounter->create(palRef)) { + else if (gpuCounter->create()) { amdCounter->setDeviceCounter(gpuCounter); newExperiment = true; } @@ -2351,7 +2347,6 @@ VirtualGPU::submitPerfCounter(amd::PerfCounterCommand& vcmd) vcmd.setStatus(CL_INVALID_OPERATION); return; } - counter = gpuCounter; } }