diff --git a/projects/clr/rocclr/runtime/device/pal/paldefs.hpp b/projects/clr/rocclr/runtime/device/pal/paldefs.hpp index fbdec58fb3..6547886042 100644 --- a/projects/clr/rocclr/runtime/device/pal/paldefs.hpp +++ b/projects/clr/rocclr/runtime/device/pal/paldefs.hpp @@ -146,14 +146,26 @@ static const AMDDeviceInfo DeviceInfo[] = { }; static const AMDDeviceInfo GfxIpDeviceInfo[] = { -/* Unknown */ { "", "unknown", 4, 16, 1, 256, 64 * Ki, 32, 000 }, -/* GFX6_0_0 */ { "GFX6_0_0", "gfx6_0_0", 4, 16, 1, 256, 64 * Ki, 32, 600 }, -/* GFX7_0_0 */ { "GFX7_0_0", "gfx7_0_0", 4, 16, 1, 256, 64 * Ki, 32, 700 }, -/* GFX8_0_0 */ { "GFX8_0_0", "gfx8_0_0", 4, 16, 1, 256, 64 * Ki, 32, 800 }, -/* GFX8_0_1 */ { "GFX8_0_1", "gfx8_0_1", 4, 16, 1, 256, 64 * Ki, 32, 801 }, +/* Unknown */ { "", "unknown", 4, 16, 1, 256, 64 * Ki, 32, 000 }, +/* GFX6_0_0 */ { "", "gfx6_0_0", 4, 16, 1, 256, 64 * Ki, 32, 600 }, +/* GFX7_0_0 */ { "", "gfx7_0_0", 4, 16, 1, 256, 64 * Ki, 32, 700 }, +/* GFX8_0_0 */ { "", "gfx8_0_0", 4, 16, 1, 256, 64 * Ki, 32, 800 }, +/* GFX8_0_1 */ { "", "gfx8_0_1", 4, 16, 1, 256, 64 * Ki, 32, 801 }, /* GFX9_0_0 */ { "", "", 4, 16, 1, 256, 64 * Ki, 32, 900 }, }; +enum gfx_handle { + gfx700 = 700, + gfx701 = 701, + gfx702 = 702, + gfx800 = 800, + gfx801 = 801, + gfx804 = 804, + gfx810 = 810, + gfx900 = 900, + gfx901 = 901 +}; + static const char* Gfx700 = "AMD:AMDGPU:7:0:0"; static const char* Gfx701 = "AMD:AMDGPU:7:0:1"; static const char* Gfx800 = "AMD:AMDGPU:8:0:0"; diff --git a/projects/clr/rocclr/runtime/device/pal/paldevice.cpp b/projects/clr/rocclr/runtime/device/pal/paldevice.cpp index 9fe842fa0b..a62b001f1f 100644 --- a/projects/clr/rocclr/runtime/device/pal/paldevice.cpp +++ b/projects/clr/rocclr/runtime/device/pal/paldevice.cpp @@ -18,7 +18,7 @@ #include "palLib.h" #include "palPlatform.h" #include "palDevice.h" - +#include "cz_id.h" #include "acl.h" #include "amdocl/cl_common.hpp" @@ -77,13 +77,46 @@ NullDevice::init() devices = getDevices(CL_DEVICE_TYPE_GPU, false); + // Loop through all supported devices and create each of them + for (uint id = 0; id < sizeof(DeviceInfo) / sizeof(AMDDeviceInfo); ++id) { + bool foundActive = false; + Pal::AsicRevision revision = static_cast(id); + + if (pal::DeviceInfo[id].targetName_[0] == '\0') { + continue; + } + + // Loop through all active devices and see if we match one + for (uint i = 0; i < devices.size(); ++i) { + if (static_cast(devices[i])->asicRevision() == revision) { + foundActive = true; + break; + } + } + + // Don't report an offline device if it's active + if (foundActive) { + continue; + } + + NullDevice* dev = new NullDevice(); + if (nullptr != dev) { + if (!dev->create(revision, Pal::GfxIpLevel::_None)) { + delete dev; + } + else { + dev->registerDevice(); + } + } + } + // Loop through all supported devices and create each of them for (uint id = static_cast(Pal::GfxIpLevel::GfxIp7); id <= static_cast(Pal::GfxIpLevel::GfxIp9); ++id) { bool foundActive = false; Pal::GfxIpLevel ipLevel = static_cast(id); - if (pal::DeviceInfo[id].targetName_[0] == '\0') { + if (pal::GfxIpDeviceInfo[id].targetName_[0] == '\0') { continue; } @@ -102,7 +135,7 @@ NullDevice::init() NullDevice* dev = new NullDevice(); if (nullptr != dev) { - if (!dev->create(ipLevel)) { + if (!dev->create(Pal::AsicRevision::Unknown, ipLevel)) { delete dev; } else { @@ -115,15 +148,24 @@ NullDevice::init() } bool -NullDevice::create(Pal::GfxIpLevel ipLevel) +NullDevice::create(Pal::AsicRevision asicRevision, Pal::GfxIpLevel ipLevel) { online_ = false; Pal::DeviceProperties properties = {}; // Use fake GFX IP for the device init + asicRevision_ = asicRevision; ipLevel_ = ipLevel; + properties.revision = asicRevision; properties.gfxLevel = ipLevel; - hwInfo_ = &DeviceInfo[static_cast(ipLevel)]; + + // Update HW info for the device + if (ipLevel == Pal::GfxIpLevel::_None) { + hwInfo_ = &DeviceInfo[static_cast(asicRevision)]; + } + else { + hwInfo_ = &GfxIpDeviceInfo[static_cast(ipLevel)]; + } settings_ = new pal::Settings(); pal::Settings* palSettings = reinterpret_cast(settings_); @@ -329,7 +371,14 @@ void NullDevice::fillDeviceInfo( info_.platform_ = AMD_PLATFORM; - ::strcpy(info_.name_, hwInfo()->targetName_); + if (false && (asicRevision() == Pal::AsicRevision::Carrizo) /*&& + ASICREV_IS_CARRIZO_BRISTOL(palProp.revisionId)*/) { + const static char* bristol = "Bristol Ridge"; + ::strcpy(info_.name_, bristol); + } + else { + ::strcpy(info_.name_, hwInfo()->targetName_); + } ::strcpy(info_.vendor_, "Advanced Micro Devices, Inc."); ::snprintf(info_.driverVersion_, sizeof(info_.driverVersion_) - 1, AMD_BUILD_STRING "%s", " (VM)"); @@ -635,6 +684,7 @@ Device::create(Pal::IDevice* device) // Save the IP level for the offline detection ipLevel_ = properties().gfxLevel; + asicRevision_ = properties().revision; // Update HW info for the device if (properties().revision == Pal::AsicRevision::Unknown) { diff --git a/projects/clr/rocclr/runtime/device/pal/paldevice.hpp b/projects/clr/rocclr/runtime/device/pal/paldevice.hpp index 732ecfd9a4..29c5c7efed 100644 --- a/projects/clr/rocclr/runtime/device/pal/paldevice.hpp +++ b/projects/clr/rocclr/runtime/device/pal/paldevice.hpp @@ -44,7 +44,8 @@ public: //! Creates an offline device with the specified target bool create( - Pal::GfxIpLevel ipLevel //!< GPU ip level + Pal::AsicRevision asicRevision, //!< GPU ASIC revision + Pal::GfxIpLevel ipLevel //!< GPU ip level ); virtual cl_int createSubDevices( @@ -98,6 +99,7 @@ public: virtual void freeMapTarget(amd::Memory& mem, void* target) {} Pal::GfxIpLevel ipLevel() const { return ipLevel_; } + Pal::AsicRevision asicRevision() const { return asicRevision_; } const AMDDeviceInfo* hwInfo() const { return hwInfo_; } @@ -111,8 +113,9 @@ public: virtual void svmFree(void* ptr) const {return;} protected: - Pal::GfxIpLevel ipLevel_; //!< Device IP level - const AMDDeviceInfo* hwInfo_; //!< Device HW info structure + Pal::AsicRevision asicRevision_; //!< ASIC revision + Pal::GfxIpLevel ipLevel_; //!< Device IP level + const AMDDeviceInfo* hwInfo_; //!< Device HW info structure //! Fills OpenCL device info structure void fillDeviceInfo( diff --git a/projects/clr/rocclr/runtime/device/pal/palkernel.cpp b/projects/clr/rocclr/runtime/device/pal/palkernel.cpp index b29b46a879..f3490f52c9 100644 --- a/projects/clr/rocclr/runtime/device/pal/palkernel.cpp +++ b/projects/clr/rocclr/runtime/device/pal/palkernel.cpp @@ -680,7 +680,8 @@ HSAILKernel::init(amd::hsa::loader::Symbol *sym, bool finalize) } // Copy wavefront size - workGroupInfo_.wavefrontSize_ = dev().properties().gfxipProperties.shaderCore.wavefrontSize; + workGroupInfo_.wavefrontSize_ = prog().isNull() ? 64 : + dev().properties().gfxipProperties.shaderCore.wavefrontSize; // Find total workgroup size if (workGroupInfo_.compileSize_[0] != 0) { workGroupInfo_.size_ = diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp index c985ae4e94..ba094d83d9 100644 --- a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp +++ b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp @@ -502,7 +502,7 @@ HSAILProgram::linkImpl(amd::option::Options* options) // ACL_TYPE_CG stage is not performed for offline compilation hsa_agent_t agent; agent.handle = 1; - if (!isNull() && hsaLoad) { + if (hsaLoad) { executable_ = loader_->CreateExecutable(HSA_PROFILE_FULL, NULL); if (executable_ == nullptr) { buildLog_ += "Error: Executable for AMD HSA Code Object isn't created.\n"; @@ -527,7 +527,7 @@ HSAILProgram::linkImpl(amd::option::Options* options) buildLog_ += "Error: Querying of kernel names size from the binary failed.\n"; return false; } - if (!isNull() && kernelNamesSize > 0) { + if (kernelNamesSize > 0) { char* kernelNames = new char[kernelNamesSize]; errorCode = aclQueryInfo(dev().compiler(), binaryElf_, RT_KERNEL_NAMES, nullptr, kernelNames, &kernelNamesSize); if (errorCode != ACL_SUCCESS) { @@ -720,7 +720,7 @@ bool ORCAHSALoaderContext::IsaSupportedByAgent(hsa_agent_t agent, hsa_isa_t isa) // gfx701 only differs from gfx700 by faster fp operations and can be loaded on either device. return isa.handle == gfx700 || isa.handle == gfx701; case gfx800: - switch (program_->dev().properties().revision) { + switch (program_->dev().asicRevision()) { case Pal::AsicRevision::Iceland: case Pal::AsicRevision::Tonga: return isa.handle == gfx800; @@ -735,15 +735,15 @@ bool ORCAHSALoaderContext::IsaSupportedByAgent(hsa_agent_t agent, hsa_isa_t isa) case Pal::AsicRevision::Stoney: return isa.handle == gfx810; default: - assert(0); + assert(0 && "Unknown asic!"); return false; } case gfx900: - switch (program_->dev().properties().gfxLevel) { + switch (program_->dev().ipLevel()) { case Pal::GfxIpLevel::GfxIp9: return isa.handle == gfx900 || isa.handle == gfx901; default: - assert(0); + assert(0 && "Unknown asic!"); return false; } } @@ -798,8 +798,10 @@ void* ORCAHSALoaderContext::SegmentAddress(amdgpu_hsa_elf_segment_t segment, case AMDGPU_HSA_SEGMENT_GLOBAL_PROGRAM: case AMDGPU_HSA_SEGMENT_GLOBAL_AGENT: case AMDGPU_HSA_SEGMENT_READONLY_AGENT: { - pal::Memory *gpuMem = reinterpret_cast(seg); - return reinterpret_cast(gpuMem->vmAddress() + offset); + if (!program_->isNull()) { + pal::Memory *gpuMem = reinterpret_cast(seg); + return reinterpret_cast(gpuMem->vmAddress() + offset); + } } case AMDGPU_HSA_SEGMENT_CODE_AGENT: return (char*) seg + offset; default: @@ -874,6 +876,7 @@ void* ORCAHSALoaderContext::CpuMemAlloc(size_t size, size_t align, bool zero) { assert(size); assert(align); assert(sizeof(void*) == 8 || sizeof(void*) == 4); + void* ptr = amd::Os::alignedMalloc(size, align); if (zero) { memset(ptr, 0, size); @@ -896,6 +899,10 @@ void* ORCAHSALoaderContext::GpuMemAlloc(size_t size, size_t align, bool zero) { assert(size); assert(align); assert(sizeof(void*) == 8 || sizeof(void*) == 4); + if (program_->isNull()) { + return new char[size]; + } + pal::Memory* mem = new pal::Memory(program_->dev(), amd::alignUp(size, align)); if (!mem || !mem->create(pal::Resource::Local)) { delete mem; @@ -918,10 +925,24 @@ bool ORCAHSALoaderContext::GpuMemCopy(void *dst, size_t offset, const void *src, if (0 == size) { return true; } + if (program_->isNull()) { + memcpy(reinterpret_cast
(dst) + offset, src, size); + return true; + } assert(program_->dev().xferQueue()); pal::Memory* mem = reinterpret_cast(dst); return program_->dev().xferMgr().writeBuffer(src, *mem, amd::Coord3D(offset), amd::Coord3D(size), true); return true; } +void ORCAHSALoaderContext::GpuMemFree(void *ptr, size_t size) +{ + if (program_->isNull()) { + delete[] reinterpret_cast(ptr); + } + else { + delete reinterpret_cast(ptr); + } +} + } // namespace pal diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp index 09089723ab..fb0aade8cf 100644 --- a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp +++ b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp @@ -29,7 +29,6 @@ namespace pal { using namespace amd::hsa::loader; class HSAILProgram; -class ClBinaryHsa; class ORCAHSALoaderContext final: public Context { public: @@ -131,26 +130,12 @@ private: bool GpuMemCopy(void *dst, size_t offset, const void *src, size_t size); - void GpuMemFree(void *ptr, size_t size = 0) { - delete reinterpret_cast(ptr); - } + void GpuMemFree(void *ptr, size_t size = 0); ORCAHSALoaderContext(const ORCAHSALoaderContext &c); ORCAHSALoaderContext& operator=(const ORCAHSALoaderContext &c); - enum gfx_handle { - gfx700 = 700, - gfx701 = 701, - gfx702 = 702, - gfx800 = 800, - gfx801 = 801, - gfx804 = 804, - gfx810 = 810, - gfx900 = 900, - gfx901 = 901 - }; - pal::HSAILProgram* program_; };