MNN/source/core/TensorUtils.hpp

221 lines
7.2 KiB
C++
Raw Normal View History

2019-04-17 10:49:11 +08:00
//
// TensorUtils.hpp
// MNN
//
// Created by MNN on 2019/01/23.
// Copyright © 2018, Alibaba Group Holding Limited
//
#ifndef TensorUtils_hpp
#define TensorUtils_hpp
2019-12-27 22:16:57 +08:00
#include <MNN/Tensor.hpp>
#include "Backend.hpp"
#include "AutoStorage.h"
#include "Tensor_generated.h"
2022-06-10 10:39:50 +08:00
#define MNN_MAX_TENSOR_DIM 8
2019-04-17 10:49:11 +08:00
2020-11-05 16:41:56 +08:00
#ifdef CONSTANT
#undef CONSTANT
#endif // CONSTANT
2019-04-17 10:49:11 +08:00
namespace MNN {
2021-01-06 16:29:37 +08:00
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;
};
2021-04-08 15:34:23 +08:00
struct QuantAttr {
float scale;
float zero = 0.0f;
float min = -127.0f;
2021-04-08 15:34:23 +08:00
float max = 127.0f;
};
2019-04-17 10:49:11 +08:00
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;
};
2023-07-31 14:24:48 +08:00
struct pad {
int32_t left = 0;
int32_t right = 0;
int32_t bottom = 0;
int32_t top = 0;
};
2020-11-05 16:41:56 +08:00
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,
2020-11-05 16:41:56 +08:00
CONSTANT,
/** Whether the tensor is a trainable parameter. Trainable parameter should be stored in a different area. */
TRAINABLE,
};
2023-06-16 09:42:45 +08:00
// For Mask
enum StageInfo {
GEOMETRY_STAGE = 1,
2024-04-19 11:58:21 +08:00
CONVERTED_STAGE = 1 << 1,
COMPUTE_SHAPE_STAGE = 1 << 2,
CONTENT_NOT_CHANGE = 1 << 3,
2023-06-16 09:42:45 +08:00
};
/** 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;
2024-04-19 11:58:21 +08:00
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;
2023-09-04 10:42:11 +08:00
int index = -1;
2024-04-19 11:58:21 +08:00
int group = 0;
2023-07-31 14:24:48 +08:00
int channel_pack_num = 4;
bool support_pack16 = true;
pad mPads;
2023-06-16 09:42:45 +08:00
// For isMutable = false Tensor , determine whether the content can be convert to main backend
uint32_t stageMask = 0;
2020-11-05 16:41:56 +08:00
};
std::shared_ptr<NativeInsideDescribe> mContent;
2024-04-19 11:58:21 +08:00
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;
2019-04-17 10:49:11 +08:00
};
typedef Tensor::InsideDescribe::Usage TensorUsage;
2019-04-17 10:49:11 +08:00
/** 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);
2019-04-17 10:49:11 +08:00
/**
* @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.
*/
2022-12-30 15:18:58 +08:00
static void copyShape(const Tensor* source, Tensor* dest, bool copyFormat = false, bool copyRef = false);
2019-04-17 10:49:11 +08:00
2021-04-16 14:50:43 +08:00
/**
* @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);
2019-04-17 10:49:11 +08:00
/**
* 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);
2020-11-05 16:41:56 +08:00
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);
2022-10-30 08:44:24 +08:00
static bool isTransposeRegion(const Tensor::InsideDescribe::Region& region);
static bool isTileRegion(const Tensor::InsideDescribe::Region& region);
static bool isDepthToSpaceRegions(const Tensor* output);
2020-11-05 16:41:56 +08:00
static bool reshapeSlice(Tensor::InsideDescribe::Region& slice, int outside, int inside, int axis);
class FuseRegionStatus;
class 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);
2022-12-30 15:18:58 +08:00
static void setRasterInputs(Command* cmd);
static bool refTensorContent(Tensor* dst, const Tensor* src);
2023-07-31 14:24:48 +08:00
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);
2019-04-17 10:49:11 +08:00
};
} // namespace MNN
#endif /* TensorDescribe_hpp */