• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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