//===----------- MemoryManager.h - Target independent memory manager ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Declarations for target independent memory manager. // //===----------------------------------------------------------------------===// #ifndef LLVM_OPENMP_LIBOMPTARGET_SRC_MEMORYMANAGER_H #define LLVM_OPENMP_LIBOMPTARGET_SRC_MEMORYMANAGER_H #include #include #include #include #include #include #include // Forward declaration struct DeviceTy; class MemoryManagerTy { /// A structure stores the meta data of a target pointer struct NodeTy { /// Memory size const size_t Size; /// Target pointer void *Ptr; /// Constructor NodeTy(size_t Size, void *Ptr) : Size(Size), Ptr(Ptr) {} }; /// To make \p NodePtrTy ordered when they're put into \p std::multiset. struct NodeCmpTy { bool operator()(const NodeTy &LHS, const NodeTy &RHS) const { return LHS.Size < RHS.Size; } }; /// A \p FreeList is a set of Nodes. We're using \p std::multiset here to make /// the look up procedure more efficient. using FreeListTy = std::multiset, NodeCmpTy>; /// A list of \p FreeListTy entries, each of which is a \p std::multiset of /// Nodes whose size is less or equal to a specific bucket size. std::vector FreeLists; /// A list of mutex for each \p FreeListTy entry std::vector FreeListLocks; /// A table to map from a target pointer to its node std::unordered_map PtrToNodeTable; /// The mutex for the table \p PtrToNodeTable std::mutex MapTableLock; /// A reference to its corresponding \p DeviceTy object DeviceTy &Device; /// Request memory from target device void *allocateOnDevice(size_t Size, void *HstPtr) const; /// Deallocate data on device int deleteOnDevice(void *Ptr) const; /// This function is called when it tries to allocate memory on device but the /// device returns out of memory. It will first free all memory in the /// FreeList and try to allocate again. void *freeAndAllocate(size_t Size, void *HstPtr); /// The goal is to allocate memory on the device. It first tries to allocate /// directly on the device. If a \p nullptr is returned, it might be because /// the device is OOM. In that case, it will free all unused memory and then /// try again. void *allocateOrFreeAndAllocateOnDevice(size_t Size, void *HstPtr); public: /// Constructor. If \p Threshold is non-zero, then the default threshold will /// be overwritten by \p Threshold. MemoryManagerTy(DeviceTy &Dev, size_t Threshold = 0); /// Destructor ~MemoryManagerTy(); /// Allocate memory of size \p Size from target device. \p HstPtr is used to /// assist the allocation. void *allocate(size_t Size, void *HstPtr); /// Deallocate memory pointed by \p TgtPtr int free(void *TgtPtr); }; #endif // LLVM_OPENMP_LIBOMPTARGET_SRC_MEMORYMANAGER_H