2019-04-17 10:49:11 +08:00
|
|
|
//
|
|
|
|
// Backend.hpp
|
|
|
|
// MNN
|
|
|
|
//
|
|
|
|
// Created by MNN on 2018/07/06.
|
|
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef Backend_hpp
|
|
|
|
#define Backend_hpp
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
#include <MNN/MNNForwardType.h>
|
2019-04-17 10:49:11 +08:00
|
|
|
#include <stdio.h>
|
2020-11-05 16:41:56 +08:00
|
|
|
#include <MNN/ErrorCode.hpp>
|
|
|
|
#include <MNN/Tensor.hpp>
|
2019-04-17 10:49:11 +08:00
|
|
|
#include <map>
|
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
2020-11-05 16:41:56 +08:00
|
|
|
#include "Command.hpp"
|
2019-04-17 10:49:11 +08:00
|
|
|
#include "NonCopyable.hpp"
|
|
|
|
|
|
|
|
namespace MNN {
|
|
|
|
|
|
|
|
struct Op;
|
|
|
|
struct GpuLibrary;
|
|
|
|
class Execution;
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
class Runtime;
|
2019-04-17 10:49:11 +08:00
|
|
|
/** abstract backend */
|
|
|
|
class Backend : public NonCopyable {
|
|
|
|
public:
|
|
|
|
/** info used to create backend */
|
|
|
|
struct Info {
|
|
|
|
/** forward type. */
|
|
|
|
MNNForwardType type = MNN_FORWARD_CPU;
|
|
|
|
/** for CPU only. number of threads. */
|
|
|
|
int numThread = 4;
|
|
|
|
/** user data. */
|
|
|
|
BackendConfig* user = NULL;
|
- dynamic computation graph (beta)
- add supports (/express)
- add tests
- add benchmarks with it (/benchmark/exprModels)
- Python
- MNN engine and tools were submitted to pip
- available on Windows/macOS/Linux
- Engine/Converter
- add supports for each op benchmarking
- refactor optimizer by separating steps
- CPU
- add supports for Conv3D, Pool3D, ELU, ReverseSequence
- fix ArgMax, Permute, Scale, BinaryOp, Slice, SliceTf
- OpenCL
- add half transform in CPU
- add broadcast supports for binary
- optimize Conv2D, Reshape, Eltwise, Gemm, etc.
- OpenGL
- add sub, real div supports for binary
- add supports for unary
- optimize Conv2D, Reshape
- Vulkan
- add max supports for eltwise
- Metal
- fix metallib missing problem
- Train/Quantization
- use express to refactor training codes
2019-09-26 21:02:07 +08:00
|
|
|
enum Mode {
|
|
|
|
// The Op will be run in execution->onExecute
|
|
|
|
DIRECT = 0,
|
|
|
|
|
|
|
|
// The Op will be recorded. Run in onExecuteBegin and Wait in onExecuteEnd
|
|
|
|
INDIRECT = 1
|
|
|
|
};
|
|
|
|
Mode mode = DIRECT;
|
2019-04-17 10:49:11 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** backend buffer storage type */
|
|
|
|
enum StorageType {
|
|
|
|
/**
|
|
|
|
use NOT reusable memory.
|
|
|
|
- allocates memory when `onAcquireBuffer` is called.
|
|
|
|
- releases memory when `onReleaseBuffer` is called or when the backend is deleted.
|
|
|
|
- do NOTHING when `onClearBuffer` is called.
|
|
|
|
*/
|
|
|
|
STATIC,
|
|
|
|
/**
|
|
|
|
use reusable memory.
|
|
|
|
- allocates or reuses memory when `onAcquireBuffer` is called. prefers reusing.
|
|
|
|
- collects memory for reuse when `onReleaseBuffer` is called.
|
|
|
|
- releases memory when `onClearBuffer` is called or when the backend is deleted.
|
|
|
|
*/
|
|
|
|
DYNAMIC,
|
|
|
|
/**
|
|
|
|
use NOT reusable memory.
|
|
|
|
- allocates memory when `onAcquireBuffer` is called.
|
|
|
|
- do NOTHING when `onReleaseBuffer` is called.
|
|
|
|
- releases memory when `onClearBuffer` is called or when the backend is deleted.
|
|
|
|
*/
|
|
|
|
DYNAMIC_SEPERATE
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief initializer.
|
|
|
|
* @param type forward type.
|
|
|
|
*/
|
|
|
|
Backend(MNNForwardType type) : mType(type) {
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief deinitializer.
|
|
|
|
*/
|
|
|
|
virtual ~Backend() = default;
|
|
|
|
|
|
|
|
public:
|
- dynamic computation graph (beta)
- add supports (/express)
- add tests
- add benchmarks with it (/benchmark/exprModels)
- Python
- MNN engine and tools were submitted to pip
- available on Windows/macOS/Linux
- Engine/Converter
- add supports for each op benchmarking
- refactor optimizer by separating steps
- CPU
- add supports for Conv3D, Pool3D, ELU, ReverseSequence
- fix ArgMax, Permute, Scale, BinaryOp, Slice, SliceTf
- OpenCL
- add half transform in CPU
- add broadcast supports for binary
- optimize Conv2D, Reshape, Eltwise, Gemm, etc.
- OpenGL
- add sub, real div supports for binary
- add supports for unary
- optimize Conv2D, Reshape
- Vulkan
- add max supports for eltwise
- Metal
- fix metallib missing problem
- Train/Quantization
- use express to refactor training codes
2019-09-26 21:02:07 +08:00
|
|
|
/**
|
|
|
|
* @brief measure the cost for op with input and output tensors.
|
|
|
|
* @param inputs input tensors.
|
|
|
|
* @param outputs output tensors.
|
|
|
|
* @param op given op.
|
|
|
|
* @return std::make_pair(timeDelayInMs, support);
|
|
|
|
*/
|
|
|
|
virtual std::pair<float, bool> onMeasure(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs,
|
2020-11-05 16:41:56 +08:00
|
|
|
const MNN::Op* op) {
|
- dynamic computation graph (beta)
- add supports (/express)
- add tests
- add benchmarks with it (/benchmark/exprModels)
- Python
- MNN engine and tools were submitted to pip
- available on Windows/macOS/Linux
- Engine/Converter
- add supports for each op benchmarking
- refactor optimizer by separating steps
- CPU
- add supports for Conv3D, Pool3D, ELU, ReverseSequence
- fix ArgMax, Permute, Scale, BinaryOp, Slice, SliceTf
- OpenCL
- add half transform in CPU
- add broadcast supports for binary
- optimize Conv2D, Reshape, Eltwise, Gemm, etc.
- OpenGL
- add sub, real div supports for binary
- add supports for unary
- optimize Conv2D, Reshape
- Vulkan
- add max supports for eltwise
- Metal
- fix metallib missing problem
- Train/Quantization
- use express to refactor training codes
2019-09-26 21:02:07 +08:00
|
|
|
return std::make_pair(0.0f, false);
|
|
|
|
}
|
|
|
|
|
2019-04-17 10:49:11 +08:00
|
|
|
/**
|
|
|
|
* @brief create execution for op with input and output tensors.
|
|
|
|
* @param inputs input tensors.
|
|
|
|
* @param outputs output tensors.
|
|
|
|
* @param op given op.
|
|
|
|
* @return created execution if op is supported, nullptr otherwise.
|
|
|
|
*/
|
|
|
|
virtual Execution* onCreate(const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs,
|
|
|
|
const MNN::Op* op) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief callback before resize ops.
|
|
|
|
*/
|
|
|
|
virtual void onResizeBegin() {
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @brief callback after resize ops.
|
|
|
|
*/
|
|
|
|
virtual void onResizeEnd() {
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief callback before executing ops.
|
|
|
|
*/
|
|
|
|
virtual void onExecuteBegin() const = 0;
|
|
|
|
/**
|
|
|
|
* @brief callback after executing ops.
|
|
|
|
*/
|
|
|
|
virtual void onExecuteEnd() const = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief allocate buffer of tensor for given storage type.
|
|
|
|
* @param tensor buffer provider.
|
|
|
|
* @param storageType buffer storage type.
|
|
|
|
* @return success or not.
|
|
|
|
*/
|
|
|
|
virtual bool onAcquireBuffer(const Tensor* tensor, StorageType storageType) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief release buffer of tensor for given storage type.
|
|
|
|
* @param tensor buffer provider.
|
|
|
|
* @param storageType buffer storage type.
|
|
|
|
* @return success or not.
|
|
|
|
*/
|
|
|
|
virtual bool onReleaseBuffer(const Tensor* tensor, StorageType storageType) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief clear all dynamic buffers.
|
|
|
|
* @return success or not.
|
|
|
|
*/
|
|
|
|
virtual bool onClearBuffer() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief copy buffer from tensor to tensor.
|
|
|
|
* @param srcTensor source buffer provider.
|
|
|
|
* @param dstTensor dest buffer provider.
|
|
|
|
*/
|
|
|
|
virtual void onCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor) const = 0;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* @brief get forward type.
|
|
|
|
* @return forward type.
|
|
|
|
*/
|
|
|
|
inline MNNForwardType type() const {
|
|
|
|
return mType;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const MNNForwardType mType;
|
|
|
|
};
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
/** Each backend belong to a runtime*/
|
|
|
|
class Runtime : public NonCopyable {
|
2019-04-17 10:49:11 +08:00
|
|
|
public:
|
|
|
|
/**
|
2020-11-05 16:41:56 +08:00
|
|
|
Origin Op -> (Compiler) -> New Op -> Backend
|
|
|
|
Default use Compiler_Geometry, Origin Op -> Compiler_Geometry -> Little Op
|
|
|
|
For serveral Backend, we can't use Geometry to decompose origin op, then it set Compiler_Origin
|
2019-04-17 10:49:11 +08:00
|
|
|
*/
|
2020-11-05 16:41:56 +08:00
|
|
|
enum CompilerType {
|
|
|
|
Compiler_Geometry = 0,
|
|
|
|
Compiler_Origin = 1,
|
|
|
|
};
|
2019-04-17 10:49:11 +08:00
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
virtual CompilerType onGetCompilerType() const {
|
|
|
|
return Compiler_Geometry;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual ~Runtime() = default;
|
2019-04-17 10:49:11 +08:00
|
|
|
/**
|
2020-11-05 16:41:56 +08:00
|
|
|
@brief create backend
|
2019-04-17 10:49:11 +08:00
|
|
|
@return created backend
|
|
|
|
*/
|
2020-11-05 16:41:56 +08:00
|
|
|
virtual Backend* onCreate() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
@brief clear unuseful resource
|
|
|
|
@param level clear level: 0 - 100, bigger mean clear more, smaller mean cache more
|
|
|
|
*/
|
|
|
|
virtual void onGabageCollect(int level) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
@brief Measure the memory it used in MB
|
|
|
|
*/
|
|
|
|
virtual float onGetMemoryInMB() {
|
|
|
|
return 0.0f;
|
|
|
|
}
|
2019-04-17 10:49:11 +08:00
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
// If buffer is not nullptr, try copy cache, else delete cache
|
|
|
|
virtual bool onSetCache(const void* buffer, size_t size) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual std::pair<const void*, size_t> onGetCache() {
|
|
|
|
return std::make_pair(nullptr, 0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/** abstract Runtime register */
|
|
|
|
class RuntimeCreator {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
@brief initializer.
|
|
|
|
*/
|
|
|
|
virtual ~RuntimeCreator() = default;
|
- dynamic computation graph (beta)
- add supports (/express)
- add tests
- add benchmarks with it (/benchmark/exprModels)
- Python
- MNN engine and tools were submitted to pip
- available on Windows/macOS/Linux
- Engine/Converter
- add supports for each op benchmarking
- refactor optimizer by separating steps
- CPU
- add supports for Conv3D, Pool3D, ELU, ReverseSequence
- fix ArgMax, Permute, Scale, BinaryOp, Slice, SliceTf
- OpenCL
- add half transform in CPU
- add broadcast supports for binary
- optimize Conv2D, Reshape, Eltwise, Gemm, etc.
- OpenGL
- add sub, real div supports for binary
- add supports for unary
- optimize Conv2D, Reshape
- Vulkan
- add max supports for eltwise
- Metal
- fix metallib missing problem
- Train/Quantization
- use express to refactor training codes
2019-09-26 21:02:07 +08:00
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
virtual Runtime* onCreate(const Backend::Info& info) const = 0;
|
- dynamic computation graph (beta)
- add supports (/express)
- add tests
- add benchmarks with it (/benchmark/exprModels)
- Python
- MNN engine and tools were submitted to pip
- available on Windows/macOS/Linux
- Engine/Converter
- add supports for each op benchmarking
- refactor optimizer by separating steps
- CPU
- add supports for Conv3D, Pool3D, ELU, ReverseSequence
- fix ArgMax, Permute, Scale, BinaryOp, Slice, SliceTf
- OpenCL
- add half transform in CPU
- add broadcast supports for binary
- optimize Conv2D, Reshape, Eltwise, Gemm, etc.
- OpenGL
- add sub, real div supports for binary
- add supports for unary
- optimize Conv2D, Reshape
- Vulkan
- add max supports for eltwise
- Metal
- fix metallib missing problem
- Train/Quantization
- use express to refactor training codes
2019-09-26 21:02:07 +08:00
|
|
|
/**
|
|
|
|
@brief Turn info to supported.
|
|
|
|
@param info info to valid.
|
|
|
|
@return success or not
|
|
|
|
*/
|
|
|
|
virtual bool onValid(Backend::Info& info) const {
|
|
|
|
info.mode = Backend::Info::DIRECT;
|
|
|
|
return true;
|
|
|
|
}
|
2020-11-05 16:41:56 +08:00
|
|
|
|
2019-04-17 10:49:11 +08:00
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
@brief deinitializer.
|
|
|
|
*/
|
2020-11-05 16:41:56 +08:00
|
|
|
RuntimeCreator() = default;
|
2019-04-17 10:49:11 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief get registered backend creator for given forward type.
|
|
|
|
* @param type given forward type.
|
|
|
|
* @return backend creator pointer if registered, nullptr otherwise.
|
|
|
|
*/
|
2020-11-05 16:41:56 +08:00
|
|
|
MNN_PUBLIC const RuntimeCreator* MNNGetExtraRuntimeCreator(MNNForwardType type);
|
2019-04-17 10:49:11 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief register backend creator for given forward type.
|
|
|
|
* @param type given forward type.
|
|
|
|
* @param creator registering backend creator.
|
|
|
|
* @return true if backend creator for given forward type was not registered before, false otherwise.
|
|
|
|
*/
|
2020-11-05 16:41:56 +08:00
|
|
|
MNN_PUBLIC bool MNNInsertExtraRuntimeCreator(MNNForwardType type, const RuntimeCreator* creator,
|
2019-04-17 10:49:11 +08:00
|
|
|
bool needCheck = false);
|
|
|
|
|
2020-11-05 16:41:56 +08:00
|
|
|
MNN_PUBLIC bool MNNCPUCopyBuffer(const Tensor* srcTensor, const Tensor* dstTensor);
|
2019-04-17 10:49:11 +08:00
|
|
|
} // namespace MNN
|
|
|
|
|
|
|
|
#endif /* Backend_hpp */
|