1
1
# 自定义后端
2
- Backend是MNN对计算设备的抽象。MNN当前已经支持CPU、Vulkan、OpenCL、Metal等Backend,** 只在计算设备暂未支持时新增Backend** ,新增Op,请参阅[ 新增Op文档] ( customize_op ) 。
2
+ Runtime-Backend是MNN对计算设备的抽象。MNN当前已经支持CPU、Vulkan、OpenCL、Metal、CUDA等Backend,** 只在计算设备暂未支持时新增Backend** ,新增Op,请参阅[ 新增Op文档] ( op ) 。
3
+
4
+
3
5
4
6
## 声明
5
7
所有新增Backend都需继承` Backend ` 类,并实现所有纯虚函数。
@@ -10,8 +12,10 @@ class XPUBackend final : public Backend {
10
12
virtual Execution* onCreate(const std::vector<Tensor* >& inputs, const std::vector<Tensor* >& outputs, const MNN::Op* op) override;
11
13
virtual void onExecuteBegin() const override;
12
14
virtual void onExecuteEnd() const override;
13
- virtual bool onAcquireBuffer(const Tensor* tensor, StorageType storageType) override;
14
- virtual bool onReleaseBuffer(const Tensor* tensor, StorageType storageType) override;
15
+ virtual void onResizeBegin() override;
16
+ virtual ErrorCode onResizeEnd() override;
17
+
18
+ virtual MemObj* onAcquire(const Tensor* tensor, StorageType storageType) override;
15
19
virtual bool onClearBuffer() override;
16
20
virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const override;
17
21
}
@@ -91,7 +95,7 @@ static XPUCreatorRegister<XPUPoolingCreator> __reg(OpType_Pooling);
91
95
```
92
96
93
97
## 内存管理
94
- Backend通过`onAcquireBuffer`为tensor分配内存,通过`onReleaseBuffer`为tensor释放内存 。内存有三种存储模式:`STATIC`内存不复用,一般用于op常量存储;`DYNAMIC`内存可复用,一般用于变量存储;`DYNAMIC_SEPERATE`内存在pipeline间可复用,一般用于pipeline常量存储。`_onAcquireBuffer_`_和_`_onReleaseBuffer_`_中可以不实际分配/释放内存,只记录内存用量变更,在_`_onAllocateBuffer_`_调用时,再根据用量计算出优化方案,一次性完成分配/释放。_
98
+ Backend通过`onAcquire`创建`MemObj`内存对象,定义其析构函数以便为tensor释放内存 。内存有三种存储模式:`STATIC`内存不复用,一般用于op常量存储;`DYNAMIC`内存可复用,一般用于变量存储;`DYNAMIC_SEPERATE`内存在pipeline间可复用,一般用于pipeline常量存储。
95
99
96
100
```cpp
97
101
/** backend buffer storage type */
@@ -118,31 +122,13 @@ enum StorageType {
118
122
*/
119
123
DYNAMIC_SEPERATE
120
124
};
121
- /**
122
- * @brief allocate buffer of tensor for given storage type.
123
- * @param tensor buffer provider.
124
- * @param storageType buffer storage type.
125
- * @return success or not.
126
- */
127
- virtual bool onAcquireBuffer(const Tensor* tensor, StorageType storageType) = 0;
128
- /**
129
- * @brief release buffer of tensor for given storage type.
130
- * @param tensor buffer provider.
131
- * @param storageType buffer storage type.
132
- * @return success or not.
133
- */
134
- virtual bool onReleaseBuffer(const Tensor* tensor, StorageType storageType) = 0;
135
- ```
136
-
137
- 在所有内存都分配完成后,backend会收到` onAllocateBuffer ` 回调:
138
- ``` cpp
139
- /* *
140
- * @brief callback after all buffers needed by backend ops were allocated.
141
- * @return success or not. (result not used currently)
142
- */
143
- virtual bool onAllocateBuffer () {
144
- return true;
145
- }
125
+ /**
126
+ * @brief allocate buffer of tensor for given storage type.
127
+ * @param tensor buffer provider.
128
+ * @param storageType buffer storage type.
129
+ * @return MemObj for release, if failed, return nullptr.
130
+ */
131
+ virtual MemObj* onAcquire(const Tensor* tensor, StorageType storageType) = 0;
146
132
```
147
133
148
134
Backend在调用` onClearBuffer ` 时,需要释放所有` DYNAMIC ` 和` DYNAMIC_SEPERATE ` 存储模式的内存:
@@ -189,17 +175,47 @@ virtual void onExecuteEnd() const = 0;
189
175
190
176
```
191
177
192
- ## 注册Backend
193
- 最后,定义Backend Creator,注册方法中调用` MNNInsertExtraBackendCreator ` 就可以完成Backend的注册,这里的注册方法需要在BackendRegister.cpp中声明并调用:
178
+ ## Runtime(运行时)
179
+ 对于使用同一种后端,且存在先后顺序,不会同时运行的模型,MNN提供机制使其共享部分计算资源,比如线程池,内存池等等。
180
+ 这部分计算资源使用Runtime存储。而Backend则由Runtime创建
181
+
182
+ ### 实现Runtime
183
+ Runtime主要实现如下接口:
184
+
185
+ ```
186
+ virtual Backend* onCreate(const BackendConfig* config = nullptr, Backend* origin = nullptr) const = 0;
187
+
188
+ /**
189
+ @brief reset runtime
190
+ */
191
+ virtual void onReset(int numberThread, const BackendConfig* config, bool full) {
192
+ // Do nothing
193
+ }
194
+
195
+ /**
196
+ @brief clear unuseful resource
197
+ @param level clear level: 0 - 100, bigger mean clear more, smaller mean cache more
198
+ */
199
+ virtual void onGabageCollect(int level) = 0;
200
+
201
+ ```
202
+
203
+ - onCreate :创建 Backend
204
+ - onReset :重设默认配置
205
+ - onGabageCollect :清理资源以节省内存
206
+
207
+
208
+ ### 注册Runtime
209
+ 注册方法中调用` MNNInsertExtraRuntimeCreator ` 就可以完成Runtime的注册,这里的注册方法需要在Backend.cpp中声明并调用:
194
210
``` cpp
195
- class XPUBackendCreator : public BackendCreator {
196
- virtual Backend * onCreate(const Backend::Info &info) const {
197
- return new MetalBackend ;
211
+ class XPURuntimeCreator : public RuntimeCreator {
212
+ virtual Runtime * onCreate(const Backend::Info &info) const {
213
+ return new XPURuntime ;
198
214
}
199
215
};
200
- void registerCPUBackendCreator () {
201
- MNNInsertExtraBackendCreator(MNN_FORWARD_CPU , new CPUBackendCreator );
216
+ void registerXPURuntimeCreator () {
217
+ MNNInsertExtraBackendCreator(MNN_FORWARD_XPU , new XPURuntimeCreator );
202
218
};
203
219
```
204
220
205
- 使用cmake编译时,完成代码修改后,也需要相应修改CMakeLists.txt。
221
+ 使用cmake编译时,完成代码修改后,也需要相应修改CMakeLists.txt。
0 commit comments