| 
									
										
										
										
											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>
 | 
					
						
							| 
									
										
										
										
											2019-08-22 20:13:46 +08:00
										 |  |  | #include "Tensor_generated.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  | #ifdef CONSTANT
 | 
					
						
							|  |  |  | #undef CONSTANT
 | 
					
						
							|  |  |  | #endif // CONSTANT
 | 
					
						
							| 
									
										
										
										
											2020-03-25 20:41:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | namespace MNN { | 
					
						
							|  |  |  | class Backend; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2021-06-11 17:17:13 +08:00
										 |  |  |     float min  = -127.0f; | 
					
						
							| 
									
										
										
										
											2021-04-08 15:34:23 +08:00
										 |  |  |     float max  = 127.0f; | 
					
						
							|  |  |  |     DataType type = DataType_DT_INT8; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | /** extra tensor info container */ | 
					
						
							|  |  |  | struct Tensor::InsideDescribe { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |     /** dimension format */ | 
					
						
							|  |  |  |     MNN_DATA_FORMAT dimensionFormat = MNN_DATA_FORMAT_NC4HW4; | 
					
						
							| 
									
										
										
										
											2020-12-15 14:12:35 +08:00
										 |  |  |     union { | 
					
						
							|  |  |  |         /** Serperate memory offset*/ | 
					
						
							|  |  |  |         int offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /** function used to free handle */ | 
					
						
							|  |  |  |         void (*handleFreeFunction)(void*); | 
					
						
							|  |  |  |     } extra; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     MemoryType memoryType = MEMORY_BACKEND; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  |     /** for DEVICE tensor only. backend used to manage tensor's device memory. */ | 
					
						
							|  |  |  |     Backend* backend = nullptr; | 
					
						
							|  |  |  |     /** for DEVICE tensor only. */ | 
					
						
							|  |  |  |     int useCount = 0; | 
					
						
							| 
									
										
										
										
											2020-01-15 13:33:47 +08:00
										 |  |  |     enum Usage { | 
					
						
							|  |  |  |         NORMAL, | 
					
						
							|  |  |  |         INPUT, | 
					
						
							|  |  |  |         OUTPUT, | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  |         CONSTANT, | 
					
						
							| 
									
										
										
										
											2020-01-15 13:33:47 +08:00
										 |  |  |         /** Whether the tensor is a trainable parameter. Trainable parameter should be stored in a different area. */ | 
					
						
							|  |  |  |         TRAINABLE, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     Usage usage = NORMAL; | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  |     struct View { | 
					
						
							| 
									
										
										
										
											2021-02-07 10:45:07 +08:00
										 |  |  |         int32_t offset = 0; | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  |         int32_t stride[3] = {1, 1, 1}; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     struct Region { | 
					
						
							|  |  |  |         View src; | 
					
						
							|  |  |  |         View dst; | 
					
						
							|  |  |  |         int32_t size[3] = {1, 1, 1}; | 
					
						
							|  |  |  |         Tensor* origin; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     std::vector<Region> regions; | 
					
						
							|  |  |  |     halide_dimension_t dims[MNN_MAX_TENSOR_DIM]; | 
					
						
							| 
									
										
										
										
											2021-01-06 16:29:37 +08:00
										 |  |  |     // TensorArray Attribute
 | 
					
						
							|  |  |  |     std::shared_ptr<TensorArrayAttr> tensorArrayAttr; | 
					
						
							| 
									
										
										
										
											2021-04-08 15:34:23 +08:00
										 |  |  |     // Tensor Quant Attribute
 | 
					
						
							|  |  |  |     std::shared_ptr<QuantAttr> quantAttr; | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2020-01-15 13:33:47 +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* getDescribe(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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 call handle free function to clear handle of tensor. | 
					
						
							|  |  |  |      * @param tensor    given tensor. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     static void clearHandleData(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); | 
					
						
							| 
									
										
										
										
											2021-06-11 17:17:13 +08:00
										 |  |  |     static bool isCopyRegion(const Tensor::InsideDescribe::Region& region); | 
					
						
							| 
									
										
										
										
											2020-11-05 16:41:56 +08:00
										 |  |  |     static bool reshapeSlice(Tensor::InsideDescribe::Region& slice, int outside, int inside, int axis); | 
					
						
							|  |  |  |     static bool fuseRegion(Tensor::InsideDescribe::Region& srcReg, Tensor::InsideDescribe::Region& dstReg); | 
					
						
							| 
									
										
										
										
											2020-12-17 14:17:48 +08:00
										 |  |  |     static void adjustTensorForCompability(Tensor* t); | 
					
						
							| 
									
										
										
										
											2021-01-07 13:47:43 +08:00
										 |  |  |     static Tensor::DimensionType getDimType(const Tensor* t); | 
					
						
							| 
									
										
										
										
											2021-04-08 15:34:23 +08:00
										 |  |  |     static halide_type_t DataTypeToHalideType(DataType t); | 
					
						
							|  |  |  |     static DataType HaildeTypeToDataType(halide_type_t t); | 
					
						
							| 
									
										
										
										
											2021-06-11 17:17:13 +08:00
										 |  |  |     static std::vector<float> getQuantInfo(const Tensor* t); | 
					
						
							| 
									
										
										
										
											2019-04-17 10:49:11 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | } // namespace MNN
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* TensorDescribe_hpp */
 |