1 /** 2 * Copyright 2020 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_GPU_OPENCL_OPENCL_ALLOCATOR_H_ 18 #define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_GPU_OPENCL_OPENCL_ALLOCATOR_H_ 19 20 #include <memory> 21 #include <string> 22 #include <vector> 23 #include <mutex> 24 #include <map> 25 #include <unordered_map> 26 #include <unordered_set> 27 #include "src/litert/inner_allocator.h" 28 #include "CL/cl2.hpp" 29 30 namespace mindspore::lite::opencl { 31 // OpenCL memory type, SHARED only valid on Mali devices. 32 enum class MemType : char { BUF, IMG, SHARED, GLTexture }; 33 #define UNLOCK_AND_RETURN_NULL(condition, ptr) \ 34 do { \ 35 if (condition) { \ 36 UnLock(); \ 37 return (ptr); \ 38 } \ 39 } while (0) 40 41 class OpenCLRuntime; 42 43 struct ImageSize { 44 size_t width = 0; 45 size_t height = 0; 46 size_t dtype = CL_FLOAT; 47 bool operator==(const struct ImageSize &other) const { 48 return width == other.width && height == other.height && dtype == other.dtype; 49 } 50 }; 51 52 class OpenCLAllocator : public mindspore::Allocator { 53 public: 54 explicit OpenCLAllocator(OpenCLRuntime *ocl_runtime); 55 ~OpenCLAllocator() override; 56 void SetContext(const AllocatorContext &ctx); Malloc(size_t size,MemType type)57 void *Malloc(size_t size, MemType type) { return _Malloc(type, nullptr, size); } 58 59 // malloc shared Malloc(size_t size)60 void *Malloc(size_t size) override { return _Malloc(MemType::SHARED, nullptr, size); } 61 void *Malloc(size_t weight, size_t height, DataType type) override; 62 // malloc buffer Malloc(size_t size,void * data)63 void *Malloc(size_t size, void *data) { return _Malloc(MemType::BUF, data, size); } 64 // malloc image 65 void *Malloc(const ImageSize &img_size, void *data = nullptr) { return _Malloc(MemType::IMG, data, 0, img_size); } 66 void Free(void *ptr) override; 67 int RefCount(void *ptr) override; 68 int SetRefCount(void *ptr, int ref_count) override; 69 int DecRefCount(void *ptr, int ref_count) override; 70 int IncRefCount(void *ptr, int ref_count) override; 71 size_t total_size(); 72 73 void Clear(); 74 cl::Image2D *GetImage(void *host_ptr); 75 void *GetOpenclMemPtr(void *buffer, MemType *type, bool force_buffer = false); 76 void *MapBuffer(void *host_ptr, int flags, void *command_queue = nullptr, bool sync = true); 77 int UnmapBuffer(void *host_ptr, void *command_queue = nullptr); 78 MemType GetMemType(void *host_ptr); 79 int GetImageSize(void *host_ptr, ImageSize *img_size); Prepare(void * ptr)80 void *Prepare(void *ptr) override { 81 if (ptr != nullptr) { 82 ptr = MapBuffer(ptr, CL_MAP_READ | CL_MAP_WRITE, nullptr, true); 83 } 84 return ptr; 85 } IsOverSize()86 bool IsOverSize() { return is_oversize_; } 87 88 private: 89 void Lock(); 90 void UnLock(); 91 void *MinimumFit(MemType mem_type, size_t size, const ImageSize &img_size); 92 void *_Malloc(MemType mem_type, void *data, size_t size = 0, const ImageSize &img_size = ImageSize()); 93 void *CreateBuffer(size_t size, void *data, size_t flags, cl::Buffer **buffer); 94 int CreateImage2D(size_t size, const ImageSize &img_size, void *data, size_t flags, bool is_map, cl::Buffer **buffer, 95 cl::Image2D **image, void **host_ptr); 96 int GetImgDtypeSize(const ImageSize &img_size); 97 template <typename T> 98 void ClearMemList(T *list); 99 100 private: 101 OpenCLRuntime *ocl_runtime_{nullptr}; 102 std::mutex lock; 103 struct MemBuf { 104 std::atomic_int ref_count_ = 0; 105 size_t size_{0}; 106 void *device_ptr_{nullptr}; 107 void *host_ptr_{nullptr}; 108 void *image_ptr_{nullptr}; 109 MemType mem_type_{MemType::BUF}; 110 ImageSize img_size_; 111 bool map_flags_{false}; 112 }; 113 114 // <membuf->buf, membuf> 115 std::unordered_map<void *, MemBuf *> allocated_list_; 116 std::multimap<size_t, MemBuf *> free_list_; 117 uint64_t total_size_{0}; 118 // 6 is empirical value 119 int shift_factor_ = 6; 120 bool lock_flag_ = true; 121 bool is_oversize_{false}; 122 }; 123 } // namespace mindspore::lite::opencl 124 125 #endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_GPU_OPENCL_OPENCL_ALLOCATOR_H_ 126