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_OPENCL_ALLOCATOR_H_ 18 #define MINDSPORE_LITE_SRC_RUNTIME_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/runtime/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 }; 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 } 86 87 private: 88 void Lock(); 89 void UnLock(); 90 void *MinimumFit(MemType mem_type, size_t size, const ImageSize &img_size); 91 void *_Malloc(MemType mem_type, void *data, size_t size = 0, const ImageSize &img_size = ImageSize()); 92 void *CreateBuffer(size_t size, void *data, size_t flags, cl::Buffer **buffer); 93 int CreateImage2D(size_t size, const ImageSize &img_size, void *data, size_t flags, bool is_map, cl::Buffer **buffer, 94 cl::Image2D **image, void **host_ptr); 95 int GetImgDtypeSize(const ImageSize &img_size); 96 template <typename T> 97 void ClearMemList(T *list); 98 99 private: 100 OpenCLRuntime *ocl_runtime_{nullptr}; 101 std::mutex lock; 102 struct MemBuf { 103 std::atomic_int ref_count_ = 0; 104 size_t size_{0}; 105 void *device_ptr_{nullptr}; 106 void *host_ptr_{nullptr}; 107 void *image_ptr_{nullptr}; 108 MemType mem_type_{MemType::BUF}; 109 ImageSize img_size_; 110 bool map_flags_{false}; 111 }; 112 113 // <membuf->buf, membuf> 114 std::unordered_map<void *, MemBuf *> allocated_list_; 115 std::multimap<size_t, MemBuf *> free_list_; 116 uint64_t total_size_{0}; 117 // 6 is empirical value 118 int shift_factor_ = 6; 119 bool lock_flag_ = true; 120 }; 121 } // namespace mindspore::lite::opencl 122 123 #endif // MINDSPORE_LITE_SRC_RUNTIME_OPENCL_ALLOCATOR_H_ 124