mirror of https://github.com/alibaba/MNN.git
231 lines
7.5 KiB
C++
231 lines
7.5 KiB
C++
//
|
|
// TensorUtils.hpp
|
|
// MNN
|
|
//
|
|
// Created by MNN on 2019/01/23.
|
|
// Copyright © 2018, Alibaba Group Holding Limited
|
|
//
|
|
|
|
#ifndef TensorUtils_hpp
|
|
#define TensorUtils_hpp
|
|
|
|
#include <MNN/Tensor.hpp>
|
|
#include "Backend.hpp"
|
|
#include "AutoStorage.h"
|
|
#include "Tensor_generated.h"
|
|
#define MNN_MAX_TENSOR_DIM 9
|
|
|
|
#ifdef CONSTANT
|
|
#undef CONSTANT
|
|
#endif // CONSTANT
|
|
|
|
#ifdef MNN_KLEIDIAI_ENABLED
|
|
#include "../backend/cpu/arm/mnn_kleidiai.h"
|
|
#endif
|
|
|
|
namespace MNN {
|
|
struct TensorArrayAttr {
|
|
// array size is dynamic or not
|
|
bool isDynamicSize = false;
|
|
// elemShape is identical or not
|
|
bool isIdenticalShape = false;
|
|
// the number of element
|
|
uint32_t arraySize = 0;
|
|
// the shape of element
|
|
std::vector<std::vector<int>> elemShape;
|
|
};
|
|
struct QuantAttr {
|
|
float scale;
|
|
float zero = 0.0f;
|
|
float min = -127.0f;
|
|
float max = 127.0f;
|
|
};
|
|
struct Tensor::InsideDescribe {
|
|
struct View {
|
|
int32_t offset = 0;
|
|
int32_t stride[3] = {1, 1, 1};
|
|
};
|
|
struct Region {
|
|
View src;
|
|
View dst;
|
|
int32_t size[3] = {1, 1, 1};
|
|
Tensor* origin;
|
|
};
|
|
struct pad {
|
|
int32_t left = 0;
|
|
int32_t right = 0;
|
|
int32_t bottom = 0;
|
|
int32_t top = 0;
|
|
};
|
|
enum MemoryType {
|
|
/** The tensor's memory come from Backend */
|
|
MEMORY_BACKEND = 0,
|
|
|
|
/** host memory is owned by tensor or not */
|
|
MEMORY_HOST,
|
|
|
|
/** The tensor don't has memory */
|
|
MEMORY_VIRTUAL,
|
|
|
|
/** host memory is owned by tensor or not */
|
|
MEMORY_OUTSIDE,
|
|
};
|
|
enum Usage {
|
|
NORMAL,
|
|
INPUT,
|
|
OUTPUT,
|
|
CONSTANT,
|
|
/** Whether the tensor is a trainable parameter. Trainable parameter should be stored in a different area. */
|
|
TRAINABLE,
|
|
};
|
|
// For Mask
|
|
enum StageInfo {
|
|
GEOMETRY_STAGE = 1,
|
|
CONVERTED_STAGE = 1 << 1,
|
|
COMPUTE_SHAPE_STAGE = 1 << 2,
|
|
CONTENT_NOT_CHANGE = 1 << 3,
|
|
};
|
|
/** extra tensor info container */
|
|
struct NativeInsideDescribe {
|
|
public:
|
|
/** dimension format */
|
|
MNN_DATA_FORMAT dimensionFormat = MNN_DATA_FORMAT_NC4HW4;
|
|
union {
|
|
/** Serperate memory offset*/
|
|
int offset;
|
|
|
|
/** function used to free handle */
|
|
void (*handleFreeFunction)(void*);
|
|
} extra;
|
|
MemoryType memoryType = MEMORY_BACKEND;
|
|
std::weak_ptr<Command> rasterCommand;
|
|
/** for DEVICE tensor only. */
|
|
int useCount = 0;
|
|
Usage usage = NORMAL;
|
|
std::vector<Region> regions;
|
|
halide_dimension_t dims[MNN_MAX_TENSOR_DIM];
|
|
// TensorArray Attribute
|
|
std::shared_ptr<TensorArrayAttr> tensorArrayAttr;
|
|
// Tensor Quant Attribute
|
|
std::shared_ptr<QuantAttr> quantAttr;
|
|
// Only valid when quantAttr is not nullptr
|
|
DataType type = DataType_DT_FLOAT;
|
|
bool isMutable = true;
|
|
int index = -1;
|
|
int group = 0;
|
|
int channel_pack_num = 4;
|
|
bool support_pack16 = true;
|
|
pad mPads;
|
|
// For isMutable = false Tensor , determine whether the content can be convert to main backend
|
|
uint32_t stageMask = 0;
|
|
// Use for shared memory
|
|
SharedPtr<Backend::MemObj> mSharedMem;
|
|
};
|
|
std::shared_ptr<NativeInsideDescribe> mContent;
|
|
SharedPtr<Backend::MemObj> mem;
|
|
inline Backend* getBackend() const {
|
|
return backend;
|
|
}
|
|
inline void setBackend(Backend* bn) {
|
|
backend = bn;
|
|
}
|
|
private:
|
|
/** for DEVICE tensor only. backend used to manage tensor's device memory. */
|
|
Backend* backend = nullptr;
|
|
};
|
|
|
|
typedef Tensor::InsideDescribe::Usage TensorUsage;
|
|
|
|
/** tensor utils */
|
|
class MNN_PUBLIC TensorUtils {
|
|
public:
|
|
/**
|
|
* @brief get extra tensor info.
|
|
* @param tensor given tensor.
|
|
* @return extra tensor info.
|
|
*/
|
|
static Tensor::InsideDescribe::NativeInsideDescribe* getDescribe(const Tensor* tensor);
|
|
|
|
static Tensor::InsideDescribe* getDescribeOrigin(const Tensor* tensor);
|
|
|
|
/**
|
|
* @brief copy shape from source tensor to dest tensor.
|
|
* @param source shape prodiver tensor.
|
|
* @param dest shape consumer tensor.
|
|
* @param copyFormat copy data format or not.
|
|
*/
|
|
static void copyShape(const Tensor* source, Tensor* dest, bool copyFormat = false, bool copyRef = false);
|
|
|
|
/**
|
|
* @brief set shape for dest tensor from a common int vector.
|
|
* @param dest shape consumer tensor.
|
|
* @param alldims dims info.
|
|
*/
|
|
static void setShape(Tensor* dest, const std::vector<int>& alldims);
|
|
|
|
/**
|
|
* auto update tensor's strides according to extents and reorder flags.
|
|
* @param tensor given tensor.
|
|
*/
|
|
static void setLinearLayout(Tensor* tensor);
|
|
|
|
/**
|
|
* @brief compare tensor to expected with tolerance.
|
|
* @param compareTensor comparing tensor.
|
|
* @param toTensor expected tensor.
|
|
* @param tolerance tolerable error, any error less than this value will be ignored.
|
|
* for integer types, compare with `abs(v1 - v2) > tolerance`;
|
|
* for float types, see `overallTolerance`.
|
|
* @param overall for float types only. compare with `abs(v1 - v2) / max(abs(allExpectValues))` if true,
|
|
* `abs(v1 - v2) / abs(v2)` otherwise.
|
|
* @param printsError print error data or not.
|
|
* @param printsTensors print tensor data or not when meets error.
|
|
* @return equals within tolerance or not.
|
|
*/
|
|
static bool compareTensors(const Tensor* compareTensor, const Tensor* toTensor, float tolerance = 0,
|
|
bool overall = false, bool printsError = true, bool printsTensors = false);
|
|
|
|
static void setupTensorInfo(const Tensor* tensor, Tensor* wrapTensor, MNN_DATA_FORMAT mMidFormat);
|
|
static Tensor::InsideDescribe::Region makeFullSlice(Tensor* input);
|
|
static bool regionIsFull(Tensor* input);
|
|
static bool isCopyRegion(const Tensor::InsideDescribe::Region& region);
|
|
static bool isTransposeRegion(const Tensor::InsideDescribe::Region& region);
|
|
static bool isTileRegion(const Tensor::InsideDescribe::Region& region);
|
|
static bool isDepthToSpaceRegions(const Tensor* output);
|
|
static bool reshapeSlice(Tensor::InsideDescribe::Region& slice, int outside, int inside, int axis);
|
|
|
|
class FuseRegionStatus;
|
|
class MNN_PUBLIC FuseWrap {
|
|
public:
|
|
FuseWrap();
|
|
~ FuseWrap();
|
|
bool match(const Tensor::InsideDescribe::Region& srcReg, const Tensor::InsideDescribe::Region& dstReg);
|
|
void apply(const Tensor::InsideDescribe::Region& srcReg, Tensor::InsideDescribe::Region& dstReg);
|
|
private:
|
|
FuseRegionStatus* mStatus;
|
|
};
|
|
static void adjustTensorForCompability(Tensor* t);
|
|
static Tensor::DimensionType getDimType(const Tensor* t);
|
|
static std::vector<float> getQuantInfo(const Tensor* t);
|
|
|
|
static size_t getRawSize(const Tensor* t);
|
|
static void setRasterInputs(Command* cmd);
|
|
|
|
static bool refTensorContent(Tensor* dst, const Tensor* src);
|
|
|
|
static int getTensorChannelPack(const Tensor* tensor);
|
|
|
|
static void setTensorChannelPack(const Tensor* tensor, int pack);
|
|
|
|
static void setTensorSupportPack(const Tensor* tensor, bool flag);
|
|
|
|
static void setTensorPad(const Tensor* tensor, int left, int right, int bottom, int top);
|
|
|
|
static void setSharedMem(const Tensor* tensor, Backend::MemObj *mem);
|
|
|
|
static Backend::MemObj* getSharedMem(const Tensor* tensor);
|
|
};
|
|
} // namespace MNN
|
|
|
|
#endif /* TensorDescribe_hpp */
|