diff --git a/projects/clr/rocclr/runtime/device/devprogram.hpp b/projects/clr/rocclr/runtime/device/devprogram.hpp index 02f950c7a1..8de0653a64 100644 --- a/projects/clr/rocclr/runtime/device/devprogram.hpp +++ b/projects/clr/rocclr/runtime/device/devprogram.hpp @@ -224,7 +224,8 @@ class Program : public amd::HeapObject { //! Check if SRAM ECC is enable const bool sramEccEnable() const { return (sramEccEnabled_ == 1); } - virtual bool findGlobalSymbols(void** dptr, size_t* bytes, const char* globalName) const { + virtual bool createGlobalVarObj(amd::Memory** amd_mem_obj, void** dptr, + size_t* bytes, const char* globalName) const { ShouldNotReachHere(); return false; } diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp index a3429697ea..1098f8864d 100644 --- a/projects/clr/rocclr/runtime/device/pal/palprogram.cpp +++ b/projects/clr/rocclr/runtime/device/pal/palprogram.cpp @@ -49,15 +49,36 @@ void Segment::DestroyCpuAccess() { } } +bool Segment::gpuAddressOffset(uint64_t offAddr, size_t* offset) { + uint64_t baseAddr = gpuAccess_->vmAddress(); + if (baseAddr > offAddr) { + return false; + } + *offset = (offAddr - baseAddr); + return true; +} + bool Segment::alloc(HSAILProgram& prog, amdgpu_hsa_elf_segment_t segment, size_t size, size_t align, bool zero) { align = amd::alignUp(align, sizeof(uint32_t)); - gpuAccess_ = new pal::Memory(prog.dev(), amd::alignUp(size, align)); - if ((gpuAccess_ == nullptr) || !gpuAccess_->create(pal::Resource::Shader)) { - delete gpuAccess_; - gpuAccess_ = nullptr; + + amd::Memory *amd_mem_obj = new (prog.dev().context()) + amd::Buffer(prog.dev().context(), 0, amd::alignUp(size, align), + reinterpret_cast(1)); + + if (amd_mem_obj == nullptr) { + LogError("[OCL] failed to create a mem object!"); return false; } + + if (!amd_mem_obj->create(nullptr)) { + LogError("[OCL] failed to create a svm hidden buffer!"); + amd_mem_obj->release(); + return false; + } + + gpuAccess_ = static_cast(amd_mem_obj->getDeviceMemory(prog.dev(), false)); + if (segment == AMDGPU_HSA_SEGMENT_CODE_AGENT) { void* ptr = nullptr; cpuAccess_ = new pal::Memory(prog.dev(), amd::alignUp(size, align)); @@ -353,6 +374,110 @@ bool HSAILProgram::saveBinaryAndSetType(type_t type) { return true; } +bool HSAILProgram::createGlobalVarObj(amd::Memory** amd_mem_obj, void** device_pptr, + size_t* bytes, const char* global_name) const { + uint32_t length = 0; + size_t offset = 0; + uint32_t flags = 0; + amd::Memory* parent = nullptr; + hsa_agent_t agent; + hsa_symbol_kind_t type; + hsa_status_t status = HSA_STATUS_SUCCESS; + amd::hsa::loader::Symbol* symbol = nullptr; + + if (amd_mem_obj == nullptr) { + buildLog_ += "amd_mem_obj is null"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the Symbol obj from global name*/ + agent.handle = 1; + symbol = executable_->GetSymbol(global_name, &agent); + if (!symbol) { + buildLog_ += "Error: Getting Global Var Symbol"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the symbol type */ + if (!symbol->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_TYPE, &type)) { + buildLog_ += "Error: Getting Global Var Symbol Type"; + buildLog_ += "\n"; + return false; + } + + /* Make sure the symbol is of type VARIABLE */ + if (type != HSA_SYMBOL_KIND_VARIABLE) { + buildLog_ += "Error: Retrieve Symbol type is not Variable "; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the symbol Name Length */ + if (!symbol->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_NAME_LENGTH, &length)) { + buildLog_ += "Error: Getting Global Var Symbol length"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the symbol name */ + char* name = reinterpret_cast(alloca(length + 1)); + if (!symbol->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_NAME, name)) { + buildLog_ += "Error: Getting Global Var Symbol name"; + buildLog_ += "\n"; + return false; + } + name[length] = '\0'; + + /* Make sure the name matches with the global name */ + if (std::string(name) != std::string(global_name)) { + buildLog_ += "Error: Global Var Name mismatch"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the Symbol address */ + if (!symbol->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_ADDRESS, device_pptr)) { + buildLog_ += "Error: Getting Global Var Symbol Address"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the Symbol size */ + if (!symbol->GetInfo(HSA_EXECUTABLE_SYMBOL_INFO_VARIABLE_SIZE, bytes)) { + buildLog_ += "Error: Getting Global Var Symbol size"; + buildLog_ += "\n"; + return false; + } + + /* Retrieve the Offset from global pal::Memory created @ segment::alloc */ + if(!codeSegment_->gpuAddressOffset(reinterpret_cast(*device_pptr), &offset)) { + buildLog_ += "Error: Cannot Retrieve the Address Offset"; + buildLog_ += "\n"; + return false; + } + + /* Create a View from the global pal::Memory */ + parent = codeSegGpu_->owner(); + *amd_mem_obj = new (parent->getContext()) amd::Buffer(*parent, flags, offset, *bytes); + + if (*amd_mem_obj == nullptr) { + buildLog_ += "[OCL] Failed to create a mem object!"; + buildLog_ += "\n"; + return false; + } + + if (!((*amd_mem_obj)->create(nullptr))) { + buildLog_ += "[OCL] failed to create a svm hidden buffer!"; + buildLog_ += "\n"; + (*amd_mem_obj)->release(); + return false; + } + + return true; +} + hsa_isa_t PALHSALoaderContext::IsaFromName(const char* name) { hsa_isa_t isa = {0}; uint32_t gfxip = 0; diff --git a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp index d463a09615..32e98aab6f 100644 --- a/projects/clr/rocclr/runtime/device/pal/palprogram.hpp +++ b/projects/clr/rocclr/runtime/device/pal/palprogram.hpp @@ -47,6 +47,8 @@ class Segment : public amd::HeapObject { //! Returns address for GPU access in the segment uint64_t gpuAddress(size_t offset) const { return gpuAccess_->vmAddress() + offset; } + bool gpuAddressOffset(uint64_t offAddr, size_t* offset); + //! Returns address for CPU access in the segment void* cpuAddress(size_t offset) const { return ((cpuAccess_ != nullptr) ? cpuAccess_->data() : cpuMem_) + offset; } @@ -177,10 +179,13 @@ class HSAILProgram : public device::Program { virtual bool setKernels(amd::option::Options* options, void* binary, size_t binSize) override; - //! Destroys CPU allocations in the code segment + //! Destroys CPU allocations in the code segment void DestroySegmentCpuAccess() const { if (codeSegment_ != nullptr) { codeSegment_->DestroyCpuAccess(); } } + virtual bool createGlobalVarObj(amd::Memory** amd_mem_obj, void** dptr, + size_t* bytes, const char* globalName) const; + private: //! Disable default copy constructor HSAILProgram(const HSAILProgram&); diff --git a/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp b/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp index 350182c056..444377aeb2 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocprogram.cpp @@ -113,12 +113,20 @@ bool Program::initClBinary(char* binaryIn, size_t size) { return clBinary()->setBinary(bin, sz, (decryptedBin != nullptr)); } -bool Program::findGlobalSymbols(void** device_pptr, size_t* bytes, const char* global_name) const { +bool Program::createGlobalVarObj(amd::Memory** amd_mem_obj, void** device_pptr, + size_t* bytes, const char* global_name) const { hsa_status_t status = HSA_STATUS_SUCCESS; + const roc::Device* roc_device = nullptr; hsa_agent_t hsa_device; hsa_symbol_kind_t sym_type; hsa_executable_symbol_t global_symbol; + if (amd_mem_obj == nullptr) { + buildLog_ += "amd_mem_obj is null"; + buildLog_ += "\n"; + return false; + } + hsa_device= dev().getBackendDevice(); /* Find HSA Symbol by name */ @@ -170,6 +178,22 @@ bool Program::findGlobalSymbols(void** device_pptr, size_t* bytes, const char* g return false; } + roc_device = static_cast(&dev()); + *amd_mem_obj = new(roc_device->context()) amd::Buffer(roc_device->context(), 0, *bytes, *device_pptr); + + if (*amd_mem_obj == nullptr) { + buildLog_ += "[OCL] Failed to create a mem object!"; + buildLog_ += "\n"; + return false; + } + + if (!((*amd_mem_obj)->create(nullptr))) { + buildLog_ += "[OCL] failed to create a svm hidden buffer!"; + buildLog_ += "\n"; + (*amd_mem_obj)->release(); + return false; + } + return true; } diff --git a/projects/clr/rocclr/runtime/device/rocm/rocprogram.hpp b/projects/clr/rocclr/runtime/device/rocm/rocprogram.hpp index 60ba2a7f38..2831460472 100644 --- a/projects/clr/rocclr/runtime/device/rocm/rocprogram.hpp +++ b/projects/clr/rocclr/runtime/device/rocm/rocprogram.hpp @@ -39,7 +39,8 @@ class Program : public device::Program { hsa_executable_t hsaExecutable() const { return hsaExecutable_; } - virtual bool findGlobalSymbols(void** dptr, size_t* bytes, const char* globalName) const; + virtual bool createGlobalVarObj(amd::Memory** amd_mem_obj, void** dptr, + size_t* bytes, const char* globalName) const; protected: /*! \brief Compiles LLVM binary to HSAIL code (compiler backend: link+opt+codegen) diff --git a/projects/clr/rocclr/runtime/platform/memory.cpp b/projects/clr/rocclr/runtime/platform/memory.cpp index 26cbbfd5b9..b1efa4bbba 100644 --- a/projects/clr/rocclr/runtime/platform/memory.cpp +++ b/projects/clr/rocclr/runtime/platform/memory.cpp @@ -107,6 +107,11 @@ Memory::Memory(Memory& parent, Flags flags, size_t origin, size_t size, Type typ if (parent.getHostMem() != nullptr) { setHostMem(reinterpret_cast
(parent.getHostMem()) + origin); } + + if (parent.getSvmPtr() != nullptr) { + setSvmPtr(reinterpret_cast
(parent.getSvmPtr()) + origin); + } + // Inherit memory flags from the parent if ((flags_ & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY)) == 0) { flags_ |= parent_->getMemFlags() & (CL_MEM_READ_WRITE | CL_MEM_READ_ONLY | CL_MEM_WRITE_ONLY);