diff --git a/rocclr/runtime/device/gpu/gpusettings.cpp b/rocclr/runtime/device/gpu/gpusettings.cpp index 4084e2df9f..2e38003502 100644 --- a/rocclr/runtime/device/gpu/gpusettings.cpp +++ b/rocclr/runtime/device/gpu/gpusettings.cpp @@ -36,7 +36,6 @@ Settings::Settings() // Initialize the GPU device default settings oclVersion_ = OpenCL12; debugFlags_ = 0; - singleHeap_ = false; syncObject_ = GPU_USE_SYNC_OBJECTS; remoteAlloc_ = REMOTE_ALLOC; @@ -344,7 +343,6 @@ Settings::create( hwLDSSize_ = 32 * Ki; imageSupport_ = true; - singleHeap_ = true; // Use kernels for blit if appropriate blitEngine_ = BlitEngineKernel; diff --git a/rocclr/runtime/device/gpu/gpusettings.hpp b/rocclr/runtime/device/gpu/gpusettings.hpp index e3777dc904..632c121ff6 100644 --- a/rocclr/runtime/device/gpu/gpusettings.hpp +++ b/rocclr/runtime/device/gpu/gpusettings.hpp @@ -43,7 +43,6 @@ public: union { struct { - uint singleHeap_: 1; //!< Device will use a preallocated heap uint remoteAlloc_: 1; //!< Allocate remote memory for the heap uint stagedXferRead_: 1; //!< Uses a staged buffer read uint stagedXferWrite_: 1; //!< Uses a staged buffer write @@ -71,7 +70,7 @@ public: uint asyncMemCopy_: 1; //!< Use async memory transfers uint useDeviceQueue_: 1; //!< Submit to separate device queue uint singleFpDenorm_: 1; //!< Support Single FP Denorm - uint reserved_: 4; + uint reserved_: 5; }; uint value_; }; diff --git a/rocclr/runtime/device/pal/palblit.cpp b/rocclr/runtime/device/pal/palblit.cpp index c9c1ac53d2..5d5ef73471 100644 --- a/rocclr/runtime/device/pal/palblit.cpp +++ b/rocclr/runtime/device/pal/palblit.cpp @@ -600,9 +600,10 @@ DmaBlitManager::copyBufferRect( bytesPerElement = bytesPerElement >> 1; } - // 19 bit limit in HW in SI and 16 bit limit in CI+(we adjust the ElementSize to 4bytes but the packet still has 14bits) - size_t pitchLimit = dev().settings().ciPlus_ ? (0x3FFF * bytesPerElement) | 0xF : 0x7FFFF; - size_t sizeLimit = dev().settings().ciPlus_ ? (0x3FFF * bytesPerElement) | 0xF : 0x3FFF; + // 19 bit limit in HW in SI and 16 bit limit in CI+ + // (we adjust the ElementSize to 4bytes but the packet still has 14bits) + size_t pitchLimit = (0x3FFF * bytesPerElement) | 0xF; + size_t sizeLimit = (0x3FFF * bytesPerElement) | 0xF; if (!optimalElementSize || (srcRect.rowPitch_ > pitchLimit) || @@ -2419,24 +2420,9 @@ KernelBlitManager::copyBuffer( size.c[0] /= CopyBuffAlignment[i]; } else { - if (dev().settings().ciPlus_) { - remain = size[0] % 4; - size.c[0] /= 4; - size.c[0] += 1; - } - else { - // Check if offsets are aligned - aligned = ((srcOrigin[0] % sizeof(uint32_t)) == 0); - aligned &= ((dstOrigin[0] % sizeof(uint32_t)) == 0); - if (aligned) { - remain = size[0] % 4; - size.c[0] /= 4; - size.c[0] += 1; - } - else { - remain = 8; - } - } + remain = size[0] % 4; + size.c[0] /= 4; + size.c[0] += 1; } // Program the dispatch dimensions diff --git a/rocclr/runtime/device/pal/palkernel.cpp b/rocclr/runtime/device/pal/palkernel.cpp index 5334e28931..b29b46a879 100644 --- a/rocclr/runtime/device/pal/palkernel.cpp +++ b/rocclr/runtime/device/pal/palkernel.cpp @@ -594,6 +594,8 @@ HSAILKernel::HSAILKernel(std::string name, , codeSize_(0) , hwMetaData_(nullptr) , extraArgumentsNum_(extraArgsNum) + , waveLimiter_(this, (prog->isNull() ? 1 : + dev().properties().gfxipProperties.shaderCore.numCusPerShaderArray) * dev().hwInfo()->simdPerCU_) { hsa_ = true; } @@ -737,6 +739,49 @@ HSAILKernel::init(amd::hsa::loader::Symbol *sym, bool finalize) } index_ = md.kernel_index; + size_t sizeOfWavesPerSimdHint = sizeof(workGroupInfo_.wavesPerSimdHint_); + error = aclQueryInfo(dev().compiler(), prog().binaryElf(), + RT_WAVES_PER_SIMD_HINT, openClKernelName.c_str(), + &workGroupInfo_.wavesPerSimdHint_, &sizeOfWavesPerSimdHint); + if (error != ACL_SUCCESS) { + return false; + } + + waveLimiter_.enable(); + + size_t sizeOfWorkGroupSizeHint = sizeof(workGroupInfo_.compileSizeHint_); + error = aclQueryInfo(dev().compiler(), prog().binaryElf(), + RT_WORK_GROUP_SIZE_HINT, openClKernelName.c_str(), + workGroupInfo_.compileSizeHint_, &sizeOfWorkGroupSizeHint); + if (error != ACL_SUCCESS) { + return false; + } + + size_t sizeOfVecTypeHint; + error = aclQueryInfo(dev().compiler(), prog().binaryElf(), + RT_VEC_TYPE_HINT, openClKernelName.c_str(), + NULL, &sizeOfVecTypeHint); + if (error != ACL_SUCCESS) { + return false; + } + + if (0 != sizeOfVecTypeHint) { + char* VecTypeHint = new char[sizeOfVecTypeHint + 1]; + if (NULL == VecTypeHint) { + return false; + } + error = aclQueryInfo(dev().compiler(), prog().binaryElf(), + RT_VEC_TYPE_HINT, openClKernelName.c_str(), + VecTypeHint, &sizeOfVecTypeHint); + if (error != ACL_SUCCESS) { + return false; + } + VecTypeHint[sizeOfVecTypeHint] = '\0'; + workGroupInfo_.compileVecTypeHint_ = std::string(VecTypeHint); + delete[] VecTypeHint; + } + + return true; } diff --git a/rocclr/runtime/device/pal/palkernel.hpp b/rocclr/runtime/device/pal/palkernel.hpp index 93a4609b77..c56b34ea48 100644 --- a/rocclr/runtime/device/pal/palkernel.hpp +++ b/rocclr/runtime/device/pal/palkernel.hpp @@ -187,6 +187,17 @@ public: //! Returns kernel's extra argument count uint extraArgumentsNum() const { return extraArgumentsNum_; } + //! Get profiling callback object + virtual amd::ProfilingCallback* getProfilingCallback( + const device::VirtualDevice *vdev) { + return waveLimiter_.getProfilingCallback(vdev); + } + + //! Get waves per shader array to be used for kernel execution. + uint getWavesPerSH(const device::VirtualDevice *vdev) const { + return waveLimiter_.getWavesPerSH(vdev); + } + private: //! Disable copy constructor HSAILKernel(const HSAILKernel&); @@ -237,6 +248,8 @@ private: uint value_; Flags(): value_(0) {} } flags_; + + WaveLimiterManager waveLimiter_; //!< adaptively control number of waves }; /*@}*/} // namespace pal diff --git a/rocclr/runtime/device/pal/palsettings.cpp b/rocclr/runtime/device/pal/palsettings.cpp index eb4e4dc907..3cd9d64f00 100644 --- a/rocclr/runtime/device/pal/palsettings.cpp +++ b/rocclr/runtime/device/pal/palsettings.cpp @@ -28,7 +28,6 @@ Settings::Settings() // Initialize the GPU device default settings oclVersion_ = OpenCL12; debugFlags_ = 0; - singleHeap_ = false; syncObject_ = GPU_USE_SYNC_OBJECTS; remoteAlloc_ = REMOTE_ALLOC; @@ -95,7 +94,6 @@ Settings::Settings() imageDMA_ = GPU_IMAGE_DMA; // Disable ASIC specific features by default - ciPlus_ = false; viPlus_ = false; aiPlus_ = false; @@ -197,7 +195,6 @@ Settings::create( // Fall through ... case Pal::AsicRevision::Bonaire: case Pal::AsicRevision::Hawaii: - ciPlus_ = true; threadTraceEnable_ = AMD_THREAD_TRACE_ENABLE; reportFMAF_ = false; if (palProp.revision == Pal::AsicRevision::Hawaii) { @@ -208,26 +205,20 @@ Settings::create( // L1 cache size is 16KB cacheSize_ = 16 * Ki; - if (ciPlus_) { - libSelector_ = amd::GPU_Library_CI; - if (LP64_SWITCH(WINDOWS_SWITCH(viPlus_, false), true)) { - oclVersion_ = !reportAsOCL12Device /*&& calAttr.isOpenCL200Device*/ ? - XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; - } - if (GPU_FORCE_OCL20_32BIT) { - force32BitOcl20_ = true; - oclVersion_ = !reportAsOCL12Device /*&& calAttr.isOpenCL200Device*/ ? - XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; - } - if (OPENCL_VERSION < 200) { - oclVersion_ = OpenCL12; - } - numComputeRings_ = 8; + libSelector_ = amd::GPU_Library_CI; + if (LP64_SWITCH(WINDOWS_SWITCH(viPlus_, false), true)) { + oclVersion_ = !reportAsOCL12Device /*&& calAttr.isOpenCL200Device*/ ? + XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; } - else { - numComputeRings_ = 2; - libSelector_ = amd::GPU_Library_SI; + if (GPU_FORCE_OCL20_32BIT) { + force32BitOcl20_ = true; + oclVersion_ = !reportAsOCL12Device /*&& calAttr.isOpenCL200Device*/ ? + XCONCAT(OpenCL, XCONCAT(OPENCL_MAJOR, OPENCL_MINOR)) : OpenCL12; } + if (OPENCL_VERSION < 200) { + oclVersion_ = OpenCL12; + } + numComputeRings_ = 8; // This needs to be cleaned once 64bit addressing is stable if (oclVersion_ < OpenCL20) { @@ -289,7 +280,6 @@ Settings::create( hwLDSSize_ = 32 * Ki; imageSupport_ = true; - singleHeap_ = true; // Use kernels for blit if appropriate blitEngine_ = BlitEngineKernel; diff --git a/rocclr/runtime/device/pal/palsettings.hpp b/rocclr/runtime/device/pal/palsettings.hpp index 50a27a9a43..d974129f5a 100644 --- a/rocclr/runtime/device/pal/palsettings.hpp +++ b/rocclr/runtime/device/pal/palsettings.hpp @@ -43,7 +43,6 @@ public: union { struct { - uint singleHeap_: 1; //!< Device will use a preallocated heap uint remoteAlloc_: 1; //!< Allocate remote memory for the heap uint stagedXferRead_: 1; //!< Uses a staged buffer read uint stagedXferWrite_: 1; //!< Uses a staged buffer write @@ -56,7 +55,6 @@ public: uint force32BitOcl20_: 1; //!< Force 32bit apps to take CLANG/HSAIL path on GPU uint imageDMA_: 1; //!< Enable direct image DMA transfers uint syncObject_: 1; //!< Enable syncobject - uint ciPlus_: 1; //!< CI and post CI features uint viPlus_: 1; //!< VI and post VI features uint aiPlus_: 1; //!< AI and post AI features uint threadTraceEnable_: 1; //!< Thread trace enable @@ -69,7 +67,7 @@ public: uint useDeviceQueue_: 1; //!< Submit to separate device queue uint singleFpDenorm_: 1; //!< Support Single FP Denorm uint sdamPageFaultWar_: 1; //!< SDAM page fault workaround - uint reserved_: 7; + uint reserved_: 9; }; uint value_; }; diff --git a/rocclr/runtime/device/pal/palvirtual.cpp b/rocclr/runtime/device/pal/palvirtual.cpp index a0972dcd0c..ecd259e777 100644 --- a/rocclr/runtime/device/pal/palvirtual.cpp +++ b/rocclr/runtime/device/pal/palvirtual.cpp @@ -1994,12 +1994,12 @@ VirtualGPU::submitKernelInternal( eventBegin(MainEngine); if (nullptr == scratch) { iCmd()->CmdDispatchAql(aqlPkt, 0, 0, 0, - hsaKernel.cpuAqlCode(), hsaQueueMem_->vmAddress(), 0x3ff); + hsaKernel.cpuAqlCode(), hsaQueueMem_->vmAddress(), hsaKernel.getWavesPerSH(this)); } else { iCmd()->CmdDispatchAql(aqlPkt, scratch->memObj_->vmAddress(), scratch->size_, scratch->offset_, - hsaKernel.cpuAqlCode(), hsaQueueMem_->vmAddress(), 0x3ff); + hsaKernel.cpuAqlCode(), hsaQueueMem_->vmAddress(), hsaKernel.getWavesPerSH(this)); } eventEnd(MainEngine, gpuEvent); diff --git a/rocclr/runtime/device/pal/palwavelimiter.cpp b/rocclr/runtime/device/pal/palwavelimiter.cpp index fec26ba8a7..300e7b0541 100644 --- a/rocclr/runtime/device/pal/palwavelimiter.cpp +++ b/rocclr/runtime/device/pal/palwavelimiter.cpp @@ -19,25 +19,22 @@ uint WLAlgorithmSmooth::AbandonThresh; uint WLAlgorithmSmooth::DscThresh; WaveLimiter::WaveLimiter( - HSAILKernel* owner, + WaveLimiterManager* manager, uint seqNum, bool enable, - bool enableDump): - owner_(owner), - dumper_(owner_->name() + "_" + std::to_string(seqNum), enableDump) { - auto gpuDev = static_cast(&owner_->dev()); -Unimplemented(); - //auto attrib = gpuDev->getAttribs(); - auto hwInfo = gpuDev->hwInfo(); - setIfNotDefault(SIMDPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, - /*attrib.numberOfCUsperShaderArray*/ 8 * hwInfo->simdPerCU_); + bool enableDump) + : manager_(manager) + , dumper_(manager_->name() + "_" + std::to_string(seqNum), enableDump) +{ + + setIfNotDefault(SIMDPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, manager->getSimdPerSH()); MaxWave = GPU_WAVE_LIMIT_MAX_WAVE; WarmUpCount = GPU_WAVE_LIMIT_WARMUP; RunCount = GPU_WAVE_LIMIT_RUN * MaxWave; state_ = WARMUP; if (!flagIsDefault(GPU_WAVE_LIMIT_TRACE)) { - traceStream_.open(std::string(GPU_WAVE_LIMIT_TRACE) + owner_->name() + + traceStream_.open(std::string(GPU_WAVE_LIMIT_TRACE) + manager_->name() + ".txt"); } @@ -47,19 +44,22 @@ Unimplemented(); enable_ = enable; } -WaveLimiter::~WaveLimiter() { +WaveLimiter::~WaveLimiter() +{ if (traceStream_.is_open()) { traceStream_.close(); } } -uint WaveLimiter::getWavesPerSH(){ +uint WaveLimiter::getWavesPerSH() +{ currWaves_ = waves_; return waves_ * SIMDPerSH_; } -WLAlgorithmSmooth::WLAlgorithmSmooth(HSAILKernel* owner, uint seqNum, bool enable, bool enableDump): - WaveLimiter(owner, seqNum, enable, enableDump) { +WLAlgorithmSmooth::WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump) + : WaveLimiter(manager, seqNum, enable, enableDump) +{ AdaptCount = 2 * MaxWave + 1; AbandonThresh = GPU_WAVE_LIMIT_ABANDON; DscThresh = GPU_WAVE_LIMIT_DSC_THRESH; @@ -73,11 +73,13 @@ WLAlgorithmSmooth::WLAlgorithmSmooth(HSAILKernel* owner, uint seqNum, bool enabl clearData(); } -WLAlgorithmSmooth::~WLAlgorithmSmooth() { +WLAlgorithmSmooth::~WLAlgorithmSmooth() +{ } -void WLAlgorithmSmooth::clearData() { +void WLAlgorithmSmooth::clearData() +{ waves_ = MaxWave; countAll_ = 0; clear(measure_); @@ -88,7 +90,8 @@ void WLAlgorithmSmooth::clearData() { dataCount_ = 0; } -void WLAlgorithmSmooth::updateData(ulong time) { +void WLAlgorithmSmooth::updateData(ulong time) +{ auto count = dataCount_ - 1; assert(count < 2 * MaxWave + 1); assert(time > 0); @@ -117,12 +120,13 @@ void WLAlgorithmSmooth::updateData(ulong time) { outputTrace(); } -void WLAlgorithmSmooth::outputTrace() { +void WLAlgorithmSmooth::outputTrace() +{ if (!traceStream_.is_open()) { return; } - traceStream_ << "[WaveLimiter] " << owner_->name() << " state=" << state_ + traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_ << " currWaves=" << currWaves_ << " waves=" << waves_ << " bestWave=" << bestWave_ << '\n'; output(traceStream_, "\n measure = ", measure_); @@ -132,10 +136,11 @@ void WLAlgorithmSmooth::outputTrace() { } -void WLAlgorithmSmooth::callback(ulong duration) { +void WLAlgorithmSmooth::callback(ulong duration) +{ dumper_.addData(duration, currWaves_, static_cast(state_)); - if (!enable_) { + if (!enable_ || (duration == 0)) { return; } @@ -187,14 +192,16 @@ void WLAlgorithmSmooth::callback(ulong duration) { } } -WaveLimiter::DataDumper::DataDumper(const std::string &kernelName, bool enable) { +WaveLimiter::DataDumper::DataDumper(const std::string &kernelName, bool enable) +{ enable_ = enable; if (enable_) { fileName_ = std::string(GPU_WAVE_LIMIT_DUMP) + kernelName + ".csv"; } } -WaveLimiter::DataDumper::~DataDumper() { +WaveLimiter::DataDumper::~DataDumper() +{ if (!enable_) { return; } @@ -207,7 +214,8 @@ WaveLimiter::DataDumper::~DataDumper() { OFS.close(); } -void WaveLimiter::DataDumper::addData(ulong time, uint wave, char state) { +void WaveLimiter::DataDumper::addData(ulong time, uint wave, char state) +{ if (!enable_) { return; } @@ -217,32 +225,34 @@ void WaveLimiter::DataDumper::addData(ulong time, uint wave, char state) { state_.push_back(state); } -WLAlgorithmAvrg::WLAlgorithmAvrg(HSAILKernel* owner, uint seqNum, bool enable, bool enableDump): - WaveLimiter(owner, seqNum, enable, enableDump) { - +WLAlgorithmAvrg::WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump) + : WaveLimiter(manager, seqNum, enable, enableDump) +{ measure_.resize(MaxWave + 1); clear(measure_); countAll_ = 0; } -WLAlgorithmAvrg::~WLAlgorithmAvrg() { +WLAlgorithmAvrg::~WLAlgorithmAvrg() +{ } -void WLAlgorithmAvrg::outputTrace() { +void WLAlgorithmAvrg::outputTrace() +{ if (!traceStream_.is_open()) { return; } - traceStream_ << "[WaveLimiter] " << owner_->name() << " state=" << state_ + traceStream_ << "[WaveLimiter] " << manager_->name() << " state=" << state_ << " currWaves=" << currWaves_ << " waves=" << waves_ << " bestWave=" << bestWave_ << '\n'; output(traceStream_, "\n measure = ", measure_); traceStream_ << "\n\n"; } - -void WLAlgorithmAvrg::callback(ulong duration) { +void WLAlgorithmAvrg::callback(ulong duration) +{ dumper_.addData(duration, currWaves_, static_cast(state_)); if (!enable_) { @@ -279,27 +289,24 @@ void WLAlgorithmAvrg::callback(ulong duration) { } } -WaveLimiterManager::WaveLimiterManager(HSAILKernel* kernel): - owner_(kernel), - enable_(false), - enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)) { - auto gpuDev = static_cast(&owner_->dev()); - Unimplemented(); - //auto attrib = gpuDev->getAttribs(); - auto hwInfo = gpuDev->hwInfo(); - unsigned simdPerSH = 0; - setIfNotDefault(simdPerSH, GPU_WAVE_LIMIT_CU_PER_SH, - /*attrib.numberOfCUsperShaderArray*/ 8 * hwInfo->simdPerCU_); - fixed_ = GPU_WAVES_PER_SIMD * simdPerSH; +WaveLimiterManager::WaveLimiterManager(device::Kernel* kernel, const uint simdPerSH) + : owner_(kernel) + , enable_(false) + , enableDump_(!flagIsDefault(GPU_WAVE_LIMIT_DUMP)) +{ + setIfNotDefault(simdPerSH_, GPU_WAVE_LIMIT_CU_PER_SH, simdPerSH); + fixed_ = GPU_WAVES_PER_SIMD * simdPerSH_; } -WaveLimiterManager::~WaveLimiterManager() { +WaveLimiterManager::~WaveLimiterManager() +{ for (auto &I: limiters_) { delete I.second; } } -uint WaveLimiterManager::getWavesPerSH(const device::VirtualDevice *vdev) const { +uint WaveLimiterManager::getWavesPerSH(const device::VirtualDevice *vdev) const +{ if (fixed_ > 0) { return fixed_; } @@ -315,7 +322,8 @@ uint WaveLimiterManager::getWavesPerSH(const device::VirtualDevice *vdev) const } amd::ProfilingCallback* WaveLimiterManager::getProfilingCallback( - const device::VirtualDevice *vdev) { + const device::VirtualDevice *vdev) +{ assert(vdev != nullptr); if (!enable_ && !enableDump_) { return nullptr; @@ -327,8 +335,7 @@ amd::ProfilingCallback* WaveLimiterManager::getProfilingCallback( return loc->second; } - auto limiter = new WLAlgorithmSmooth(owner_, limiters_.size(), enable_, - enableDump_); + auto limiter = new WLAlgorithmSmooth(this, limiters_.size(), enable_, enableDump_); if (limiter == nullptr) { enable_ = false; return nullptr; @@ -337,18 +344,25 @@ amd::ProfilingCallback* WaveLimiterManager::getProfilingCallback( return limiter; } -void WaveLimiterManager::enable() { +void WaveLimiterManager::enable() + { if (fixed_ > 0) { return; } - auto gpuDev = static_cast(&owner_->dev()); - auto hwInfo = gpuDev->hwInfo(); - Unimplemented(); + // Enable it only for CI+, unless GPU_WAVE_LIMIT_ENABLE is set to 1 // Disabled for SI due to bug #10817 - setIfNotDefault(enable_, GPU_WAVE_LIMIT_ENABLE, - /*owner_->workGroupInfo()->limitWave_*/ false && gpuDev->settings().ciPlus_); + if (!flagIsDefault(GPU_WAVE_LIMIT_ENABLE)) { + enable_ = GPU_WAVE_LIMIT_ENABLE; + } + else { + if (owner_->workGroupInfo()->wavesPerSimdHint_ == 0) { + enable_ = true; + } + else if (owner_->workGroupInfo()->wavesPerSimdHint_ <= GPU_WAVE_LIMIT_MAX_WAVE) { + fixed_ = owner_->workGroupInfo()->wavesPerSimdHint_ * getSimdPerSH(); + } + } } } // namespace pal - diff --git a/rocclr/runtime/device/pal/palwavelimiter.hpp b/rocclr/runtime/device/pal/palwavelimiter.hpp index 09f0cfb0b1..cd2639a73f 100644 --- a/rocclr/runtime/device/pal/palwavelimiter.hpp +++ b/rocclr/runtime/device/pal/palwavelimiter.hpp @@ -14,12 +14,13 @@ //! \namespace pal PAL Device Implementation namespace pal { +class WaveLimiterManager; class HSAILKernel; // Adaptively limit the number of waves per SIMD based on kernel execution time class WaveLimiter: public amd::ProfilingCallback { public: - explicit WaveLimiter(HSAILKernel*, uint seqNum, bool enable, bool enableDump); + explicit WaveLimiter(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump); virtual ~WaveLimiter(); //! Get waves per shader array to be used for kernel execution. @@ -48,14 +49,14 @@ protected: std::vector state_; }; - std::vector measure_; + std::vector measure_; bool enable_; uint SIMDPerSH_; // Number of SIMDs per SH uint waves_; // Waves per SIMD to be set uint bestWave_; // Optimal waves per SIMD uint countAll_; // Number of kernel executions StateKind state_; - HSAILKernel *owner_; + WaveLimiterManager* manager_; DataDumper dumper_; std::ofstream traceStream_; uint currWaves_; // Current waves per SIMD @@ -86,12 +87,12 @@ protected: class WLAlgorithmSmooth: public WaveLimiter { public: - explicit WLAlgorithmSmooth(HSAILKernel* owner, uint seqNum, bool enable, bool enableDump); + explicit WLAlgorithmSmooth(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump); virtual ~WLAlgorithmSmooth(); private: - std::vector reference_; - std::vector trial_; - std::vector ratio_; + std::vector reference_; + std::vector trial_; + std::vector ratio_; bool discontinuous_; // Measured data is discontinuous uint dynRunCount_; uint dataCount_; @@ -115,7 +116,7 @@ private: class WLAlgorithmAvrg: public WaveLimiter { public: - explicit WLAlgorithmAvrg(HSAILKernel* owner, uint seqNum, bool enable, bool enableDump); + explicit WLAlgorithmAvrg(WaveLimiterManager* manager, uint seqNum, bool enable, bool enableDump); virtual ~WLAlgorithmAvrg(); private: //! Call back from Event::recordProfilingInfo to get execution time. @@ -128,7 +129,7 @@ private: // Create wave limiter for each virtual device for a kernel and manages the wave limiters. class WaveLimiterManager { public: - explicit WaveLimiterManager(HSAILKernel* owner); + explicit WaveLimiterManager(device::Kernel* owner, const uint simdPerSH); virtual ~WaveLimiterManager(); //! Get waves per shader array for a specific virtual device. @@ -139,13 +140,21 @@ public: //! Enable wave limiter manager by kernel metadata and flags. void enable(); + + //! Returns the kernel name + const std::string& name() const { return owner_->name(); } + + //! Get SimdPerSH. + uint getSimdPerSH() const {return simdPerSH_;} + private: - HSAILKernel* owner_; //!< The kernel which owns this object + device::Kernel *owner_; // The kernel which owns this object + uint simdPerSH_; // Simd Per SH std::unordered_map limiters_; //!< Maps virtual device to wave limiter - bool enable_; //!< Whether the adaptation is enabled - bool enableDump_; //!< Whether the data dumper is enabled - uint fixed_; //!< The fixed waves/simd value if not zero - amd::Monitor monitor_; //!< The mutex for updating the wave limiter map + WaveLimiter*> limiters_; // Maps virtual device to wave limiter + bool enable_; // Whether the adaptation is enabled + bool enableDump_; // Whether the data dumper is enabled + uint fixed_; // The fixed waves/simd value if not zero + amd::Monitor monitor_; // The mutex for updating the wave limiter map }; }