diff --git a/rocclr/runtime/device/pal/paldevice.cpp b/rocclr/runtime/device/pal/paldevice.cpp index 27ad374028..91c138996f 100644 --- a/rocclr/runtime/device/pal/paldevice.cpp +++ b/rocclr/runtime/device/pal/paldevice.cpp @@ -621,6 +621,13 @@ void NullDevice::fillDeviceInfo(const Pal::DeviceProperties& palProp, if (settings().svmFineGrainSystem_) { info_.svmCapabilities_ |= CL_DEVICE_SVM_FINE_GRAIN_SYSTEM; } + if (IS_LINUX) { + // Report atomics capability based on GFX IP + // The atomic test failed in Windows OS. + if (amd::IS_HIP && ipLevel_ >= Pal::GfxIpLevel::GfxIp9) { + info_.svmCapabilities_ |= CL_DEVICE_SVM_ATOMICS; + } + } // OpenCL2.0 device info fields info_.maxWriteImageArgs_ = MaxReadWriteImage; //!< For compatibility info_.maxReadWriteImageArgs_ = MaxReadWriteImage; diff --git a/rocclr/runtime/device/pal/palresource.cpp b/rocclr/runtime/device/pal/palresource.cpp index f7e42f5590..79166b9cb5 100644 --- a/rocclr/runtime/device/pal/palresource.cpp +++ b/rocclr/runtime/device/pal/palresource.cpp @@ -275,6 +275,7 @@ Resource::Resource(const Device& gpuDev, size_t size) desc_.scratch_ = false; desc_.isAllocExecute_ = false; desc_.baseLevel_ = 0; + desc_.gl2CacheDisabled_ = false; gpuDev.addResource(this); } @@ -311,7 +312,7 @@ Resource::Resource(const Device& gpuDev, size_t width, size_t height, size_t dep desc_.scratch_ = false; desc_.isAllocExecute_ = false; desc_.baseLevel_ = 0; - + desc_.gl2CacheDisabled_ = false; switch (imageType) { case CL_MEM_OBJECT_IMAGE2D: desc_.dimSize_ = 2; @@ -1194,6 +1195,9 @@ bool Resource::create(MemoryType memType, CreateParams* params, bool forceLinear svmPtr = reinterpret_cast(params->owner_->getSvmPtr()); desc_.SVMRes_ = true; svmPtr = (svmPtr == 1) ? 0 : svmPtr; + if (params->owner_->getMemFlags() & CL_MEM_SVM_ATOMICS) { + desc_.gl2CacheDisabled_ = true; + } } if (desc_.SVMRes_) { return CreateSvm(params, svmPtr); @@ -1958,6 +1962,23 @@ bool FineMemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { return false; } +// ================================================================================================ +bool FineUncachedMemorySubAllocator::CreateChunk(const Pal::IGpuMemory* reserved_va) { + Pal::SvmGpuMemoryCreateInfo createInfo = {}; + createInfo.isUsedForKernel = false; + createInfo.size = device_->settings().subAllocationChunkSize_; + createInfo.alignment = MaxGpuAlignment; + createInfo.flags.useReservedGpuVa = (reserved_va != nullptr); + createInfo.pReservedGpuVaOwner = reserved_va; + createInfo.flags.gl2Uncached = true; + GpuMemoryReference* mem_ref = GpuMemoryReference::Create(*device_, createInfo); + if ((mem_ref != nullptr) && InitAllocator(mem_ref)) { + mem_ref->iMem()->Map(&mem_ref->cpuAddress_); + return mem_ref->cpuAddress_ != nullptr; + } + return false; +} + // ================================================================================================ MemorySubAllocator::~MemorySubAllocator() { // Release memory heap for suballocations @@ -2044,7 +2065,11 @@ bool ResourceCache::addGpuMemory(Resource::Descriptor* desc, GpuMemoryReference* } else if ((desc->type_ == Resource::Local) && desc->SVMRes_) { result = mem_sub_alloc_coarse_.Free(&lockCacheOps_, ref, offset); } else if (desc->SVMRes_) { - result = mem_sub_alloc_fine_.Free(&lockCacheOps_, ref, offset); + if (desc->gl2CacheDisabled_) { + result = mem_sub_alloc_fine_uncached_.Free(&lockCacheOps_, ref, offset); + } else { + result = mem_sub_alloc_fine_.Free(&lockCacheOps_, ref, offset); + } } // If a resource was a suballocation, don't try to cache it @@ -2095,7 +2120,11 @@ GpuMemoryReference* ResourceCache::findGpuMemory(Resource::Descriptor* desc, Pal } else if ((desc->type_ == Resource::Local) && desc->SVMRes_) { ref = mem_sub_alloc_coarse_.Allocate(size, alignment, reserved_va, offset); } else if (desc->SVMRes_) { - ref = mem_sub_alloc_fine_.Allocate(size, alignment, reserved_va, offset); + if (desc->gl2CacheDisabled_) { + ref = mem_sub_alloc_fine_uncached_.Allocate(size, alignment, reserved_va, offset); + } else { + ref = mem_sub_alloc_fine_.Allocate(size, alignment, reserved_va, offset); + } } if (ref != nullptr) { diff --git a/rocclr/runtime/device/pal/palresource.hpp b/rocclr/runtime/device/pal/palresource.hpp index 603fa9a34c..f2165a93c6 100644 --- a/rocclr/runtime/device/pal/palresource.hpp +++ b/rocclr/runtime/device/pal/palresource.hpp @@ -183,6 +183,7 @@ class Resource : public amd::HeapObject { uint scratch_ : 1; //!< Scratch buffer uint isAllocExecute_ : 1; //!< SVM resource allocation attribute for shader\cmdbuf uint isDoppTexture_ : 1; //!< PAL resource is for a DOPP desktop texture + uint gl2CacheDisabled_ : 1;//!< PAL resource is allocated with GPU L2 cache disabled. }; uint state_; }; @@ -534,6 +535,12 @@ class FineMemorySubAllocator : public MemorySubAllocator { bool CreateChunk(const Pal::IGpuMemory* reserved_va) override; }; +class FineUncachedMemorySubAllocator : public MemorySubAllocator { + public: + FineUncachedMemorySubAllocator(Device* device) : MemorySubAllocator(device) {} + bool CreateChunk(const Pal::IGpuMemory* reserved_va) override; +}; + class ResourceCache : public amd::HeapObject { public: //! Default constructor @@ -544,7 +551,8 @@ class ResourceCache : public amd::HeapObject { cacheSizeLimit_(cacheSizeLimit), mem_sub_alloc_local_(device), mem_sub_alloc_coarse_(device), - mem_sub_alloc_fine_(device) {} + mem_sub_alloc_fine_(device), + mem_sub_alloc_fine_uncached_(device){} //! Default destructor ~ResourceCache(); @@ -591,9 +599,10 @@ class ResourceCache : public amd::HeapObject { //! PAL resource cache std::list > resCache_; - MemorySubAllocator mem_sub_alloc_local_; //!< Allocator for suballocations in Local - CoarseMemorySubAllocator mem_sub_alloc_coarse_; //!< Allocator for suballocations in Coarse SVM - FineMemorySubAllocator mem_sub_alloc_fine_; //!< Allocator for suballocations in Fine SVM + MemorySubAllocator mem_sub_alloc_local_; //!< Allocator for suballocations in Local + CoarseMemorySubAllocator mem_sub_alloc_coarse_; //!< Allocator for suballocations in Coarse SVM + FineMemorySubAllocator mem_sub_alloc_fine_; //!< Allocator for suballocations in Fine SVM + FineUncachedMemorySubAllocator mem_sub_alloc_fine_uncached_; //!< Allocator for suballocations in Fine uncached SVM }; /*@}*/ // namespace pal diff --git a/rocclr/runtime/device/rocm/rocdevice.cpp b/rocclr/runtime/device/rocm/rocdevice.cpp index 8e6d2be1c1..91a5eeced2 100644 --- a/rocclr/runtime/device/rocm/rocdevice.cpp +++ b/rocclr/runtime/device/rocm/rocdevice.cpp @@ -1325,7 +1325,13 @@ bool Device::populateOCLDeviceConstants() { if (agent_profile_ == HSA_PROFILE_FULL) { info_.svmCapabilities_ |= CL_DEVICE_SVM_FINE_GRAIN_SYSTEM; } - if (!settings().useLightning_) { + if (amd::IS_HIP) { + // Report atomics capability based on GFX IP, control on Hawaii + if (info_.hostUnifiedMemory_ || deviceInfo_.gfxipVersion_ >= 800) { + info_.svmCapabilities_ |= CL_DEVICE_SVM_ATOMICS; + } + } + else if (!settings().useLightning_) { // Report atomics capability based on GFX IP, control on Hawaii // and Vega10. if (info_.hostUnifiedMemory_ || diff --git a/rocclr/runtime/device/rocm/rocmemory.cpp b/rocclr/runtime/device/rocm/rocmemory.cpp index 7779079c45..020ec81e77 100644 --- a/rocclr/runtime/device/rocm/rocmemory.cpp +++ b/rocclr/runtime/device/rocm/rocmemory.cpp @@ -697,7 +697,12 @@ bool Buffer::create() { if (owner()->getSvmPtr() == reinterpret_cast(1)) { if (isFineGrain) { - deviceMemory_ = dev().hostAlloc(size(), 1, false); + if (memFlags & CL_MEM_SVM_ATOMICS) { + deviceMemory_ = dev().hostAlloc(size(), 1, true); + } + else { + deviceMemory_ = dev().hostAlloc(size(), 1, false); + } flags_ |= HostMemoryDirectAccess; } else { deviceMemory_ = dev().deviceLocalAlloc(size()); diff --git a/rocclr/runtime/utils/flags.hpp b/rocclr/runtime/utils/flags.hpp index 552438efee..fbcedd9a97 100644 --- a/rocclr/runtime/utils/flags.hpp +++ b/rocclr/runtime/utils/flags.hpp @@ -204,7 +204,10 @@ release(uint, AMD_SERIALIZE_COPY, 0, \ "Serialize copies, 0x1 = Wait for completion before enqueue" \ "0x2 = Wait for completion after enqueue 0x3 = both") \ release(bool, PAL_ALWAYS_RESIDENT, false, \ - "Force memory resources to become resident at allocation time") + "Force memory resources to become resident at allocation time") \ +release(uint, HIP_HOST_COHERENT, 0, \ + "Coherent memory in hipHostMalloc, 0x1 = memory is coherent with host"\ + "0x0 = memory is not coherent between host and GPU") namespace amd {