diff --git a/projects/clr/rocclr/runtime/platform/context.cpp b/projects/clr/rocclr/runtime/platform/context.cpp index b57f880c85..189b23603e 100644 --- a/projects/clr/rocclr/runtime/platform/context.cpp +++ b/projects/clr/rocclr/runtime/platform/context.cpp @@ -28,23 +28,24 @@ Context::Context( , properties_(NULL) , glenv_(NULL) , customHostAllocDevice_(NULL) - , customSvmAllocDevice_(NULL) { - for (std::vector::const_iterator it = devices_.begin(); - it != devices_.end(); it++) { - Device* device = *it; + for (const auto& device : devices) { device->retain(); if (device->customHostAllocator()) { assert(!customHostAllocDevice_ && "Only one custom host allocator " "is allowed per context"); customHostAllocDevice_ = device; } - if (device->customSvmAllocator() - && (customSvmAllocDevice_ == NULL)) - { - customSvmAllocDevice_ = device; + if (device->customSvmAllocator()) { + customSvmAllocDevice_.push_back(device); } } + //make sure the first device is GPU + if ((customSvmAllocDevice_.size() > 1) + && (customSvmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU)) { + std::swap(customSvmAllocDevice_.front(), customSvmAllocDevice_.back()); + } + } Context::~Context() @@ -292,20 +293,47 @@ Context::hostFree(void* ptr) const void* Context::svmAlloc(size_t size, size_t alignment, cl_svm_mem_flags flags) { - if (customSvmAllocDevice_ != NULL) { - return customSvmAllocDevice_->svmAlloc(*this, size, alignment, flags); + unsigned int numSVMDev = customSvmAllocDevice_.size(); + if (numSVMDev < 1) { + return NULL; + } + + if (customSvmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) { + return AlignedMemory::allocate(size, alignment); + } + else { + void* svmPtrAlloced = NULL; + void* tempPtr = NULL; + + for (const auto& dev : customSvmAllocDevice_) { + if (dev->type() == CL_DEVICE_TYPE_GPU) { + tempPtr = dev->svmAlloc(*this, size, alignment, flags); + if (dev == customSvmAllocDevice_.front()) { + svmPtrAlloced = tempPtr; + } + if ((svmPtrAlloced != tempPtr) || (NULL == tempPtr)) { + return NULL; + } + } + } + return svmPtrAlloced; } - return AlignedMemory::allocate(size, alignment); } void Context::svmFree(void* ptr) const { - if (customSvmAllocDevice_ != NULL) { - customSvmAllocDevice_->svmFree(ptr); + if (customSvmAllocDevice_.front()->type() == CL_DEVICE_TYPE_CPU) { + AlignedMemory::deallocate(ptr); return; } - AlignedMemory::deallocate(ptr); + + for (const auto& dev : customSvmAllocDevice_) { + if (dev->type() == CL_DEVICE_TYPE_GPU) { + dev->svmFree(ptr); + } + } + return; } bool diff --git a/projects/clr/rocclr/runtime/platform/context.hpp b/projects/clr/rocclr/runtime/platform/context.hpp index 4c90bce262..bfbc4bdf3f 100644 --- a/projects/clr/rocclr/runtime/platform/context.hpp +++ b/projects/clr/rocclr/runtime/platform/context.hpp @@ -142,6 +142,9 @@ public: //! Return the devices associated with this context. const std::vector& devices() const { return devices_; } + //! Return the SVM capable devices associated with this context. + const std::vector& svmDevices() const { return customSvmAllocDevice_; } + //! Returns true if the given device is associated with this context. bool containsDevice(const Device* device) const; @@ -184,7 +187,7 @@ private: cl_context_properties* properties_; //!< Original properties GLFunctions* glenv_; //!< OpenGL context Device* customHostAllocDevice_; //!< Device responsible for host allocations - Device* customSvmAllocDevice_; //!< Device responsible for SVM allocations + std::vector customSvmAllocDevice_; //!< Devices can support SVM allocations std::map deviceQueues_; //!< Device queues mapping Monitor ctxLock_; //!< Lock for the context access };