forked from huawei/mindspore2022
refactor nnacl: move operator's packing and computing from lite framework to nnacl lib
This commit is contained in:
parent
8fef59d1df
commit
1ec81d783c
|
|
@ -33,6 +33,7 @@ file(GLOB KERNEL_SRC
|
|||
${NNACL_DIR}/infer/*.c
|
||||
${NNACL_DIR}/base/*.c
|
||||
${NNACL_DIR}/fp32_grad/*.c
|
||||
#${NNACL_DIR}/experiment/HPC-generator/*.c
|
||||
)
|
||||
|
||||
if((NOT DEFINED MSLITE_ENABLE_INT8) OR MSLITE_ENABLE_INT8)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
/**
|
||||
* Copyright 2021 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <mindspore/ccsrc/backend/kernel_compiler/cpu/nnacl/conv_parameter.h>
|
||||
#include "nnacl/tensor_c.h"
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/kernel.h"
|
||||
|
||||
typedef struct ConvStru {
|
||||
KernelStru base;
|
||||
int inIm2colW;
|
||||
int inIm2colH;
|
||||
} ConvStru;
|
||||
|
||||
int conv_init_fp32_nc4hw4_armv8(struct KernelStru *self, KernelContext *ctx) {
|
||||
ConvStru *conv = (ConvStru *)self;
|
||||
self->ctx = ctx;
|
||||
self->infershape(self->param, self->in, self->insize, self->out, self->outsize);
|
||||
|
||||
int outw = self->out[kOutputIndex]->shape_[kNCHW_W];
|
||||
int outh = self->in[kWeightIndex]->shape_[kNCHW_H];
|
||||
int inch = self->in[kInputIndex]->shape_[kNCHW_C];
|
||||
int kw = self->in[kWeightIndex]->shape_[kNCHW_W];
|
||||
int kh = self->in[kWeightIndex]->shape_[kNCHW_H];
|
||||
|
||||
// im2col buffer
|
||||
conv->inIm2colW = inch * kw * kh;
|
||||
conv->inIm2colH = outw * outh;
|
||||
self->buf[0] = ctx->alloc(conv->inIm2colW * conv->inIm2colH);
|
||||
self->buf[1] = ctx->alloc(conv->inIm2colW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conv_release_fp32_nc4hw4_armv8(KernelStru *self) {
|
||||
size_t sz = sizeof(self->buf) / sizeof(self->buf[0]);
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
free(self->buf[sz]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int conv_compute_fp32_nc4hw4_armv8(KernelStru *self) {
|
||||
int outw = self->out[kOutputIndex]->shape_[kNCHW_W];
|
||||
int outh = self->in[kWeightIndex]->shape_[kNCHW_H];
|
||||
int outch = self->out[kOutputIndex]->shape_[kNCHW_C];
|
||||
int inw = self->in[kInputIndex]->shape_[kNCHW_W];
|
||||
int inh = self->in[kInputIndex]->shape_[kNCHW_H];
|
||||
int inch = self->in[kInputIndex]->shape_[kNCHW_C];
|
||||
int kw = self->in[kWeightIndex]->shape_[kNCHW_W];
|
||||
int kh = self->in[kWeightIndex]->shape_[kNCHW_H];
|
||||
|
||||
int outPos = 0;
|
||||
float *outPtr = (float *)self->out[kOutputIndex]->data_;
|
||||
|
||||
ConvParameter *param = (ConvParameter *)self->param;
|
||||
for (size_t n = 0; n < self->out[kOutputIndex]->shape_[kNCHW_N]; n++) {
|
||||
// im2col input
|
||||
float *inIm2colBuf = (float *)self->buf[0];
|
||||
int index = 0;
|
||||
|
||||
// along the input height direction
|
||||
for (int y = 0; y < outh; y++) {
|
||||
// along the input width direction
|
||||
for (int x = 0; x < outw; x++) {
|
||||
// per input channel
|
||||
for (int ch = 0; ch < inch; ch++) {
|
||||
float *fp = (float *)(self->in[kInputIndex] + inch * inw * inh);
|
||||
|
||||
// per sliding window
|
||||
for (int rowStart = 0; rowStart < kh; rowStart++) {
|
||||
for (int colStart = 0; colStart < kw; colStart++) {
|
||||
int posx = x + colStart;
|
||||
int posy = y + rowStart;
|
||||
|
||||
// the padding area
|
||||
if (posx < inw || posx >= inw + param->pad_l_ || posy < inh || posy >= inh + param->pad_u_) {
|
||||
inIm2colBuf[index++] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
inIm2colBuf[index++] = *(fp + (posy - param->pad_u_) * inw + (posx - param->pad_l_));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t co = 0; co < outch; co++) { // along out channel direction
|
||||
index = 0;
|
||||
float *wtIm2colBuf = self->buf[1];
|
||||
float *fp = (float *)(self->in[kWeightIndex] + co * inch * kh * kw);
|
||||
|
||||
// im2col weight
|
||||
for (int ch = 0; ch < inch; ch++) {
|
||||
for (int y = 0; y < kh; y++) {
|
||||
for (int x = 0; x < kw; x++) {
|
||||
wtIm2colBuf[index++] = *(fp + ch * kh * kw + y * kh + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < outh * outw; y++) { // along output height*width direction
|
||||
float *rowBuf = inIm2colBuf + y * kw * kh;
|
||||
float *colBuf = wtIm2colBuf;
|
||||
float *outfp = outPtr + outPos;
|
||||
*outfp = 0;
|
||||
for (int l = 0; l < kh * kw; l++) {
|
||||
*outfp += rowBuf[l] * colBuf[l];
|
||||
}
|
||||
outPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KernelStru *CreateConv(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize) {
|
||||
ConvStru *conv = (ConvStru *)malloc(sizeof(ConvStru));
|
||||
conv->base.init = conv_init_fp32_nc4hw4_armv8;
|
||||
conv->base.release = conv_release_fp32_nc4hw4_armv8;
|
||||
conv->base.compute = conv_compute_fp32_nc4hw4_armv8;
|
||||
conv->base.param = param;
|
||||
conv->base.in = in;
|
||||
conv->base.insize = insize;
|
||||
conv->base.out = out;
|
||||
conv->base.outsize = outsize;
|
||||
return (KernelStru *)conv;
|
||||
}
|
||||
|
||||
REG_KERNEL_CREATOR(Conv2D, PrimType_Conv2DFusion, kDataTypeFloat, NC4HW4, CreateConv);
|
||||
|
|
@ -23,213 +23,6 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
enum PrimType {
|
||||
PrimType_NONE = 0,
|
||||
PrimType_Abs = 1,
|
||||
PrimType_Activation = 2,
|
||||
PrimType_ActivationGrad = 3,
|
||||
PrimType_Adam = 4,
|
||||
PrimType_AddFusion = 5,
|
||||
PrimType_AdderFusion = 6,
|
||||
PrimType_AddGrad = 7,
|
||||
PrimType_AddN = 8,
|
||||
PrimType_All = 9,
|
||||
PrimType_ApplyMomentum = 10,
|
||||
PrimType_ArgMaxFusion = 11,
|
||||
PrimType_ArgMinFusion = 12,
|
||||
PrimType_Assert = 13,
|
||||
PrimType_Assign = 14,
|
||||
PrimType_AssignAdd = 15,
|
||||
PrimType_AudioSpectrogram = 16,
|
||||
PrimType_AvgPoolFusion = 17,
|
||||
PrimType_AvgPoolGrad = 18,
|
||||
PrimType_BatchNorm = 19,
|
||||
PrimType_BatchNormGrad = 20,
|
||||
PrimType_BatchToSpace = 21,
|
||||
PrimType_BatchToSpaceND = 22,
|
||||
PrimType_BiasAdd = 23,
|
||||
PrimType_BinaryCrossEntropy = 24,
|
||||
PrimType_BinaryCrossEntropyGrad = 25,
|
||||
PrimType_BiasAddGrad = 26,
|
||||
PrimType_BroadcastTo = 27,
|
||||
PrimType_Cast = 28,
|
||||
PrimType_Ceil = 29,
|
||||
PrimType_Clip = 30,
|
||||
PrimType_Concat = 31,
|
||||
PrimType_Attention = 32,
|
||||
PrimType_Conv2DBackpropFilterFusion = 33,
|
||||
PrimType_Conv2DBackpropInputFusion = 34,
|
||||
PrimType_Conv2DFusion = 35,
|
||||
PrimType_Conv2dTransposeFusion = 36,
|
||||
PrimType_Cos = 37,
|
||||
PrimType_ConstantOfShape = 38,
|
||||
PrimType_Crop = 39,
|
||||
PrimType_CustomExtractFeatures = 40,
|
||||
PrimType_CustomNormalize = 41,
|
||||
PrimType_CustomPredict = 42,
|
||||
PrimType_DeConv2DGradFilter = 43,
|
||||
PrimType_Depend = 44,
|
||||
PrimType_DepthToSpace = 45,
|
||||
PrimType_DetectionPostProcess = 46,
|
||||
PrimType_DivFusion = 47,
|
||||
PrimType_DivGrad = 48,
|
||||
PrimType_Dropout = 49,
|
||||
PrimType_DropoutGrad = 50,
|
||||
PrimType_Elu = 51,
|
||||
PrimType_Eltwise = 52,
|
||||
PrimType_Equal = 53,
|
||||
PrimType_EmbeddingLookupFusion = 54,
|
||||
PrimType_ExpFusion = 55,
|
||||
PrimType_ExpandDims = 56,
|
||||
PrimType_FakeQuantWithMinMaxVars = 57,
|
||||
PrimType_FakeQuantWithMinMaxVarsPerChannel = 58,
|
||||
PrimType_FftReal = 59,
|
||||
PrimType_FftImag = 60,
|
||||
PrimType_Flatten = 61,
|
||||
PrimType_FlattenGrad = 62,
|
||||
PrimType_Floor = 63,
|
||||
PrimType_FloorDiv = 64,
|
||||
PrimType_FloorMod = 65,
|
||||
PrimType_Fill = 66,
|
||||
PrimType_FullConnection = 67,
|
||||
PrimType_FusedBatchNorm = 68,
|
||||
PrimType_Gather = 69,
|
||||
PrimType_GatherNd = 70,
|
||||
PrimType_Greater = 71,
|
||||
PrimType_GreaterEqual = 72,
|
||||
PrimType_HashtableLookup = 73,
|
||||
PrimType_InstanceNorm = 74,
|
||||
PrimType_LayerNormFusion = 75,
|
||||
PrimType_LeakyRelu = 76,
|
||||
PrimType_Less = 77,
|
||||
PrimType_LessEqual = 78,
|
||||
PrimType_Log = 79,
|
||||
PrimType_LogGrad = 80,
|
||||
PrimType_LogicalAnd = 81,
|
||||
PrimType_LogicalNot = 82,
|
||||
PrimType_LogicalOr = 83,
|
||||
PrimType_LpNormalization = 84,
|
||||
PrimType_LRN = 85,
|
||||
PrimType_LshProjection = 86,
|
||||
PrimType_LSTM = 87,
|
||||
PrimType_L2NormalizeFusion = 88,
|
||||
PrimType_MatMul = 89,
|
||||
PrimType_Maximum = 90,
|
||||
PrimType_MaximumGrad = 91,
|
||||
PrimType_MaxPoolFusion = 92,
|
||||
PrimType_MaxPoolGrad = 93,
|
||||
PrimType_Merge = 94,
|
||||
PrimType_Mfcc = 95,
|
||||
PrimType_Minimum = 96,
|
||||
PrimType_MinimumGrad = 97,
|
||||
PrimType_Mod = 98,
|
||||
PrimType_MulFusion = 99,
|
||||
PrimType_MulGrad = 100,
|
||||
PrimType_Neg = 101,
|
||||
PrimType_NegGrad = 102,
|
||||
PrimType_NotEqual = 103,
|
||||
PrimType_NonMaxSuppression = 104,
|
||||
PrimType_OneHot = 105,
|
||||
PrimType_OnesLike = 106,
|
||||
PrimType_PadFusion = 107,
|
||||
PrimType_PartialFusion = 108,
|
||||
PrimType_PowerGrad = 109,
|
||||
PrimType_PowFusion = 110,
|
||||
PrimType_PriorBox = 111,
|
||||
PrimType_PReLUFusion = 112,
|
||||
PrimType_QuantDTypeCast = 113,
|
||||
PrimType_Rank = 114,
|
||||
PrimType_Range = 115,
|
||||
PrimType_Reciprocal = 116,
|
||||
PrimType_RealDiv = 117,
|
||||
PrimType_ReduceFusion = 118,
|
||||
PrimType_Reshape = 119,
|
||||
PrimType_Resize = 120,
|
||||
PrimType_ReverseSequence = 121,
|
||||
PrimType_ReverseV2 = 122,
|
||||
PrimType_Rfft = 123,
|
||||
PrimType_ROIPooling = 124,
|
||||
PrimType_Round = 125,
|
||||
PrimType_Rsqrt = 126,
|
||||
PrimType_ScaleFusion = 127,
|
||||
PrimType_ScatterNd = 128,
|
||||
PrimType_SGD = 129,
|
||||
PrimType_Shape = 130,
|
||||
PrimType_SigmoidCrossEntropyWithLogits = 131,
|
||||
PrimType_SigmoidCrossEntropyWithLogitsGrad = 132,
|
||||
PrimType_Sin = 133,
|
||||
PrimType_SkipGram = 134,
|
||||
PrimType_SliceFusion = 135,
|
||||
PrimType_SmoothL1Loss = 136,
|
||||
PrimType_SmoothL1LossGrad = 137,
|
||||
PrimType_Softmax = 138,
|
||||
PrimType_SoftmaxCrossEntropyWithLogits = 139,
|
||||
PrimType_SpaceToBatch = 140,
|
||||
PrimType_SpaceToBatchND = 141,
|
||||
PrimType_SpaceToDepth = 142,
|
||||
PrimType_SparseSoftmaxCrossEntropyWithLogits = 143,
|
||||
PrimType_SparseToDense = 144,
|
||||
PrimType_Split = 145,
|
||||
PrimType_Sqrt = 146,
|
||||
PrimType_Squeeze = 147,
|
||||
PrimType_Square = 148,
|
||||
PrimType_SquaredDifference = 149,
|
||||
PrimType_Stack = 150,
|
||||
PrimType_StridedSlice = 151,
|
||||
PrimType_SubFusion = 152,
|
||||
PrimType_SubGrad = 153,
|
||||
PrimType_Switch = 154,
|
||||
PrimType_TensorListFromTensor = 155,
|
||||
PrimType_TensorListGetItem = 156,
|
||||
PrimType_TensorListReserve = 157,
|
||||
PrimType_TensorListSetItem = 158,
|
||||
PrimType_TensorListStack = 159,
|
||||
PrimType_TileFusion = 160,
|
||||
PrimType_TopKFusion = 161,
|
||||
PrimType_Transpose = 162,
|
||||
PrimType_Unique = 163,
|
||||
PrimType_UnsortedSegmentSum = 164,
|
||||
PrimType_Unsqueeze = 165,
|
||||
PrimType_Unstack = 166,
|
||||
PrimType_LSTMGrad = 167,
|
||||
PrimType_Where = 168,
|
||||
PrimType_ZerosLike = 169,
|
||||
PrimType_Select = 170,
|
||||
PrimType_ScatterNdUpdate = 171,
|
||||
PrimType_GRU = 172,
|
||||
PrimType_NonZero = 173,
|
||||
PrimType_InvertPermutation = 174,
|
||||
PrimType_Size = 175,
|
||||
PrimType_RandomStandardNormal = 176,
|
||||
PrimType_CropAndResize = 177,
|
||||
PrimType_Erf = 178,
|
||||
PrimType_StridedSliceGrad = 179,
|
||||
PrimType_IsFinite = 180,
|
||||
PrimType_LinSpace = 181,
|
||||
PrimType_UniformReal = 182,
|
||||
PrimType_AbsGrad = 183,
|
||||
PrimType_RsqrtGrad = 184,
|
||||
PrimType_SqrtGrad = 185,
|
||||
PrimType_LayerNormGrad = 186,
|
||||
PrimType_ResizeGrad = 187,
|
||||
PrimType_Splice = 188,
|
||||
PrimType_LogSoftmax = 189,
|
||||
PrimType_Call = 190,
|
||||
PrimType_Custom = 191,
|
||||
PrimType_CumSum = 192,
|
||||
PrimType_SplitWithOverlap = 193,
|
||||
PrimType_GenOP = 194,
|
||||
PrimType_RaggedRange = 195,
|
||||
PrimType_GLU = 196,
|
||||
PrimType_TensorArray = 197,
|
||||
PrimType_TensorArrayRead = 198,
|
||||
PrimType_TensorArrayWrite = 199,
|
||||
PrimType_Affine = 200,
|
||||
PrimType_AllGather = 201,
|
||||
PrimType_ReduceScatter = 202,
|
||||
PrimType_MIN = PrimType_NONE,
|
||||
PrimType_MAX = PrimType_ReduceScatter + 1
|
||||
};
|
||||
|
||||
void RegInfer(int prim_type, InferShape func);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "nnacl/kernel.h"
|
||||
#include "nnacl/tensor_c.h"
|
||||
#include "nnacl/op_base.h"
|
||||
static KernelCreator g_kernelCreatorRegistry[PrimType_MAX][kDataTypeMax][NUM_OF_FORMAT];
|
||||
|
||||
void RegKernelCreator(int opType, LiteDataType dataType, TensorCFormat format, KernelCreator creator) {
|
||||
g_kernelCreatorRegistry[opType][dataType][format] = creator;
|
||||
}
|
||||
|
||||
KernelStru *CreateKernel(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize) {
|
||||
int format = in[kInputIndex]->format_;
|
||||
int dtype = in[kInputIndex]->data_type_;
|
||||
return g_kernelCreatorRegistry[param->type_][format][dtype](param, in, insize, out, outsize);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef MINDSPORE_NNACL_KERNEL_H_
|
||||
#define MINDSPORE_NNACL_KERNEL_H_
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/tensor_c.h"
|
||||
|
||||
typedef struct KernelContext {
|
||||
void *(*alloc)(size_t sz);
|
||||
void (*free)(void *ptr);
|
||||
int threadNum;
|
||||
void (*parallelLaunch)(void *task, void *param, int taskNr);
|
||||
} KernelContext;
|
||||
|
||||
typedef struct KernelStru {
|
||||
int (*init)(struct KernelStru *self, KernelContext *ctx);
|
||||
int (*release)(struct KernelStru *self);
|
||||
int (*compute)(struct KernelStru *self);
|
||||
int (*infershape)(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize);
|
||||
OpParameter *param;
|
||||
TensorC **in; // in/out tensor's space should be managed by the invoker
|
||||
size_t insize;
|
||||
TensorC **out;
|
||||
size_t outsize;
|
||||
KernelContext *ctx;
|
||||
void *buf[4];
|
||||
} KernelStru;
|
||||
|
||||
KernelStru *CreateKernel(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize);
|
||||
typedef KernelStru *(*KernelCreator)(OpParameter *param, TensorC *in[], size_t insize, TensorC *out[], size_t outsize);
|
||||
void RegKernelCreator(int opType, LiteDataType dataType, TensorCFormat format, KernelCreator func);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define REG_KERNEL_CREATOR(op, op_type, data_type, format, func)
|
||||
#else
|
||||
#define REG_KERNEL_CREATOR(op, op_type, data_type, format, func) \
|
||||
__attribute__((constructor(102))) void Reg##op##Creator() { RegKernelCreator(op_type, data_type, format, func); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -257,13 +257,222 @@
|
|||
|
||||
#endif
|
||||
|
||||
enum PrimType {
|
||||
PrimType_NONE = 0,
|
||||
PrimType_Abs = 1,
|
||||
PrimType_Activation = 2,
|
||||
PrimType_ActivationGrad = 3,
|
||||
PrimType_Adam = 4,
|
||||
PrimType_AddFusion = 5,
|
||||
PrimType_AdderFusion = 6,
|
||||
PrimType_AddGrad = 7,
|
||||
PrimType_AddN = 8,
|
||||
PrimType_All = 9,
|
||||
PrimType_ApplyMomentum = 10,
|
||||
PrimType_ArgMaxFusion = 11,
|
||||
PrimType_ArgMinFusion = 12,
|
||||
PrimType_Assert = 13,
|
||||
PrimType_Assign = 14,
|
||||
PrimType_AssignAdd = 15,
|
||||
PrimType_AudioSpectrogram = 16,
|
||||
PrimType_AvgPoolFusion = 17,
|
||||
PrimType_AvgPoolGrad = 18,
|
||||
PrimType_BatchNorm = 19,
|
||||
PrimType_BatchNormGrad = 20,
|
||||
PrimType_BatchToSpace = 21,
|
||||
PrimType_BatchToSpaceND = 22,
|
||||
PrimType_BiasAdd = 23,
|
||||
PrimType_BinaryCrossEntropy = 24,
|
||||
PrimType_BinaryCrossEntropyGrad = 25,
|
||||
PrimType_BiasAddGrad = 26,
|
||||
PrimType_BroadcastTo = 27,
|
||||
PrimType_Cast = 28,
|
||||
PrimType_Ceil = 29,
|
||||
PrimType_Clip = 30,
|
||||
PrimType_Concat = 31,
|
||||
PrimType_Attention = 32,
|
||||
PrimType_Conv2DBackpropFilterFusion = 33,
|
||||
PrimType_Conv2DBackpropInputFusion = 34,
|
||||
PrimType_Conv2DFusion = 35,
|
||||
PrimType_Conv2dTransposeFusion = 36,
|
||||
PrimType_Cos = 37,
|
||||
PrimType_ConstantOfShape = 38,
|
||||
PrimType_Crop = 39,
|
||||
PrimType_CustomExtractFeatures = 40,
|
||||
PrimType_CustomNormalize = 41,
|
||||
PrimType_CustomPredict = 42,
|
||||
PrimType_DeConv2DGradFilter = 43,
|
||||
PrimType_Depend = 44,
|
||||
PrimType_DepthToSpace = 45,
|
||||
PrimType_DetectionPostProcess = 46,
|
||||
PrimType_DivFusion = 47,
|
||||
PrimType_DivGrad = 48,
|
||||
PrimType_Dropout = 49,
|
||||
PrimType_DropoutGrad = 50,
|
||||
PrimType_Elu = 51,
|
||||
PrimType_Eltwise = 52,
|
||||
PrimType_Equal = 53,
|
||||
PrimType_EmbeddingLookupFusion = 54,
|
||||
PrimType_ExpFusion = 55,
|
||||
PrimType_ExpandDims = 56,
|
||||
PrimType_FakeQuantWithMinMaxVars = 57,
|
||||
PrimType_FakeQuantWithMinMaxVarsPerChannel = 58,
|
||||
PrimType_FftReal = 59,
|
||||
PrimType_FftImag = 60,
|
||||
PrimType_Flatten = 61,
|
||||
PrimType_FlattenGrad = 62,
|
||||
PrimType_Floor = 63,
|
||||
PrimType_FloorDiv = 64,
|
||||
PrimType_FloorMod = 65,
|
||||
PrimType_Fill = 66,
|
||||
PrimType_FullConnection = 67,
|
||||
PrimType_FusedBatchNorm = 68,
|
||||
PrimType_Gather = 69,
|
||||
PrimType_GatherNd = 70,
|
||||
PrimType_Greater = 71,
|
||||
PrimType_GreaterEqual = 72,
|
||||
PrimType_HashtableLookup = 73,
|
||||
PrimType_InstanceNorm = 74,
|
||||
PrimType_LayerNormFusion = 75,
|
||||
PrimType_LeakyRelu = 76,
|
||||
PrimType_Less = 77,
|
||||
PrimType_LessEqual = 78,
|
||||
PrimType_Log = 79,
|
||||
PrimType_LogGrad = 80,
|
||||
PrimType_LogicalAnd = 81,
|
||||
PrimType_LogicalNot = 82,
|
||||
PrimType_LogicalOr = 83,
|
||||
PrimType_LpNormalization = 84,
|
||||
PrimType_LRN = 85,
|
||||
PrimType_LshProjection = 86,
|
||||
PrimType_LSTM = 87,
|
||||
PrimType_L2NormalizeFusion = 88,
|
||||
PrimType_MatMul = 89,
|
||||
PrimType_Maximum = 90,
|
||||
PrimType_MaximumGrad = 91,
|
||||
PrimType_MaxPoolFusion = 92,
|
||||
PrimType_MaxPoolGrad = 93,
|
||||
PrimType_Merge = 94,
|
||||
PrimType_Mfcc = 95,
|
||||
PrimType_Minimum = 96,
|
||||
PrimType_MinimumGrad = 97,
|
||||
PrimType_Mod = 98,
|
||||
PrimType_MulFusion = 99,
|
||||
PrimType_MulGrad = 100,
|
||||
PrimType_Neg = 101,
|
||||
PrimType_NegGrad = 102,
|
||||
PrimType_NotEqual = 103,
|
||||
PrimType_NonMaxSuppression = 104,
|
||||
PrimType_OneHot = 105,
|
||||
PrimType_OnesLike = 106,
|
||||
PrimType_PadFusion = 107,
|
||||
PrimType_PartialFusion = 108,
|
||||
PrimType_PowerGrad = 109,
|
||||
PrimType_PowFusion = 110,
|
||||
PrimType_PriorBox = 111,
|
||||
PrimType_PReLUFusion = 112,
|
||||
PrimType_QuantDTypeCast = 113,
|
||||
PrimType_Rank = 114,
|
||||
PrimType_Range = 115,
|
||||
PrimType_Reciprocal = 116,
|
||||
PrimType_RealDiv = 117,
|
||||
PrimType_ReduceFusion = 118,
|
||||
PrimType_Reshape = 119,
|
||||
PrimType_Resize = 120,
|
||||
PrimType_ReverseSequence = 121,
|
||||
PrimType_ReverseV2 = 122,
|
||||
PrimType_Rfft = 123,
|
||||
PrimType_ROIPooling = 124,
|
||||
PrimType_Round = 125,
|
||||
PrimType_Rsqrt = 126,
|
||||
PrimType_ScaleFusion = 127,
|
||||
PrimType_ScatterNd = 128,
|
||||
PrimType_SGD = 129,
|
||||
PrimType_Shape = 130,
|
||||
PrimType_SigmoidCrossEntropyWithLogits = 131,
|
||||
PrimType_SigmoidCrossEntropyWithLogitsGrad = 132,
|
||||
PrimType_Sin = 133,
|
||||
PrimType_SkipGram = 134,
|
||||
PrimType_SliceFusion = 135,
|
||||
PrimType_SmoothL1Loss = 136,
|
||||
PrimType_SmoothL1LossGrad = 137,
|
||||
PrimType_Softmax = 138,
|
||||
PrimType_SoftmaxCrossEntropyWithLogits = 139,
|
||||
PrimType_SpaceToBatch = 140,
|
||||
PrimType_SpaceToBatchND = 141,
|
||||
PrimType_SpaceToDepth = 142,
|
||||
PrimType_SparseSoftmaxCrossEntropyWithLogits = 143,
|
||||
PrimType_SparseToDense = 144,
|
||||
PrimType_Split = 145,
|
||||
PrimType_Sqrt = 146,
|
||||
PrimType_Squeeze = 147,
|
||||
PrimType_Square = 148,
|
||||
PrimType_SquaredDifference = 149,
|
||||
PrimType_Stack = 150,
|
||||
PrimType_StridedSlice = 151,
|
||||
PrimType_SubFusion = 152,
|
||||
PrimType_SubGrad = 153,
|
||||
PrimType_Switch = 154,
|
||||
PrimType_TensorListFromTensor = 155,
|
||||
PrimType_TensorListGetItem = 156,
|
||||
PrimType_TensorListReserve = 157,
|
||||
PrimType_TensorListSetItem = 158,
|
||||
PrimType_TensorListStack = 159,
|
||||
PrimType_TileFusion = 160,
|
||||
PrimType_TopKFusion = 161,
|
||||
PrimType_Transpose = 162,
|
||||
PrimType_Unique = 163,
|
||||
PrimType_UnsortedSegmentSum = 164,
|
||||
PrimType_Unsqueeze = 165,
|
||||
PrimType_Unstack = 166,
|
||||
PrimType_LSTMGrad = 167,
|
||||
PrimType_Where = 168,
|
||||
PrimType_ZerosLike = 169,
|
||||
PrimType_Select = 170,
|
||||
PrimType_ScatterNdUpdate = 171,
|
||||
PrimType_GRU = 172,
|
||||
PrimType_NonZero = 173,
|
||||
PrimType_InvertPermutation = 174,
|
||||
PrimType_Size = 175,
|
||||
PrimType_RandomStandardNormal = 176,
|
||||
PrimType_CropAndResize = 177,
|
||||
PrimType_Erf = 178,
|
||||
PrimType_StridedSliceGrad = 179,
|
||||
PrimType_IsFinite = 180,
|
||||
PrimType_LinSpace = 181,
|
||||
PrimType_UniformReal = 182,
|
||||
PrimType_AbsGrad = 183,
|
||||
PrimType_RsqrtGrad = 184,
|
||||
PrimType_SqrtGrad = 185,
|
||||
PrimType_LayerNormGrad = 186,
|
||||
PrimType_ResizeGrad = 187,
|
||||
PrimType_Splice = 188,
|
||||
PrimType_LogSoftmax = 189,
|
||||
PrimType_Call = 190,
|
||||
PrimType_Custom = 191,
|
||||
PrimType_CumSum = 192,
|
||||
PrimType_SplitWithOverlap = 193,
|
||||
PrimType_GenOP = 194,
|
||||
PrimType_RaggedRange = 195,
|
||||
PrimType_GLU = 196,
|
||||
PrimType_TensorArray = 197,
|
||||
PrimType_TensorArrayRead = 198,
|
||||
PrimType_TensorArrayWrite = 199,
|
||||
PrimType_Affine = 200,
|
||||
PrimType_AllGather = 201,
|
||||
PrimType_ReduceScatter = 202,
|
||||
PrimType_MIN = PrimType_NONE,
|
||||
PrimType_MAX = PrimType_ReduceScatter + 1
|
||||
};
|
||||
|
||||
typedef enum LiteDataType {
|
||||
kDataTypeFloat,
|
||||
kDataTypeFloat16,
|
||||
kDataTypeInt,
|
||||
kDataTypeInt8,
|
||||
kDataTypeBool,
|
||||
kDataTypeFloat64
|
||||
kDataTypeFloat64,
|
||||
kDataTypeMax
|
||||
} LiteDataType;
|
||||
|
||||
typedef enum DataOrder {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
#define MINDSPORE_NNACL_TENSOR_C_H_
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
typedef enum TensorCFormat { NCHW, NHWC, NC4HW4, NUM_OF_FORMAT } TensorCFormat;
|
||||
|
||||
typedef struct TensorC {
|
||||
bool is_ready_;
|
||||
int data_type_;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "experiment/kernel/convolution_fp32.h"
|
||||
|
||||
namespace mindspore::kernel {
|
||||
ConvolutionCPUFp32::ConvolutionCPUFp32(OpParameter *parameter, std::vector<lite::Tensor *> in_tensors,
|
||||
std::vector<lite::Tensor *> out_tensors, const lite::Context *ctx)
|
||||
: InnerKernel(parameter, in_tensors, out_tensors, ctx) {
|
||||
TensorC *in[4];
|
||||
size_t insize = 0;
|
||||
for (; insize < in_tensors.size() && insize < 4; insize++) {
|
||||
in[insize] = &in_tensors[insize]->TensorC();
|
||||
}
|
||||
|
||||
TensorC *out[1];
|
||||
size_t outsize = 0;
|
||||
for (; outsize < out_tensors.size() && outsize < 1; outsize++) {
|
||||
out[outsize] = &out_tensors[outsize]->TensorC();
|
||||
}
|
||||
kernel = CreateKernel(parameter, in, insize, out, outsize);
|
||||
}
|
||||
|
||||
ConvolutionCPUFp32::~ConvolutionCPUFp32() {
|
||||
kernel->release(kernel);
|
||||
free(kernel);
|
||||
}
|
||||
|
||||
int ConvolutionCPUFp32::Prepare() {
|
||||
if (kernel == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
kernel->init(kernel, &ctx_); // init kernel, pack weight
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConvolutionCPUFp32::PreProcess() {
|
||||
// allocate output tensor
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConvolutionCPUFp32::Run() { return kernel->compute(kernel); }
|
||||
|
||||
int ConvolutionCPUFp32::PostProcess() { return kernel->compute(kernel); }
|
||||
|
||||
} // namespace mindspore::kernel
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_CONVOLUTION_FP32_H_
|
||||
#define MINDSPORE_LITE_CONVOLUTION_FP32_H_
|
||||
|
||||
#include <vector>
|
||||
#include "src/inner_kernel.h"
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/kernel.h"
|
||||
|
||||
namespace mindspore::kernel {
|
||||
class ConvolutionCPUFp32 : public InnerKernel {
|
||||
public:
|
||||
ConvolutionCPUFp32(OpParameter *parameter, std::vector<lite::Tensor *> in_tensors,
|
||||
std::vector<lite::Tensor *> out_tensors, const lite::Context *ctx);
|
||||
virtual ~ConvolutionCPUFp32();
|
||||
int Prepare() override; // init, execute once
|
||||
|
||||
int Run() override;
|
||||
int ReSize() override;
|
||||
int PostProcess() override; // invoke after running, e.g., free input tensor
|
||||
int PreProcess() override; // invoke before running, e.g., allocate output tensor, pack input
|
||||
|
||||
private:
|
||||
KernelStru *kernel;
|
||||
KernelContext ctx_;
|
||||
};
|
||||
} // namespace mindspore::kernel
|
||||
|
||||
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_FP32_CONVOLUTION_FP32_H_
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "src/tensor.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include "securec/include/securec.h"
|
||||
#include "include/errorcode.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
#if ENABLE_HIGH_PERFORMANCE
|
||||
#define CHECK_INT64_MUL_OVERFLOW(x, y)
|
||||
#else
|
||||
#define CHECK_INT64_MUL_OVERFLOW(x, y) \
|
||||
do { \
|
||||
if (INT64_MUL_OVERFLOW(x, y)) { \
|
||||
MS_LOG(ERROR) << "INT64 MUL OVERFLOW"; \
|
||||
return INT64_MAX; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INT64_MUL_OVERFLOW(x, y) \
|
||||
(((x) == 0) ? false \
|
||||
: ((x) > 0 ? (((y) >= 0) ? (INT64_MAX / (x)) < (y) : (INT64_MAX / (x)) < (-1 * (y))) \
|
||||
: (((y) >= 0) ? (INT64_MAX / (x)) > (-1 * (y)) : (INT64_MAX / (x)) > (y))))
|
||||
#endif
|
||||
|
||||
Tensor::Tensor(const TypeId data_type, std::vector<int> shape, const mindspore::Format &format, Category category)
|
||||
: data_type_(data_type), shape_(std::move(shape)), format_(format), category_(category) {}
|
||||
|
||||
int Tensor::CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor) {
|
||||
if (dst_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "dst_tensor is nullptr";
|
||||
return RET_PARAM_INVALID;
|
||||
}
|
||||
if (src_tensor.data_ == nullptr) {
|
||||
MS_LOG(INFO) << "data of src tensor is nullptr";
|
||||
return RET_OK;
|
||||
}
|
||||
size_t data_size = dst_tensor->Size();
|
||||
if (data_size != src_tensor.Size()) {
|
||||
MS_LOG(ERROR) << "Size of dst tensor is not compatible with src tensor";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (dst_tensor->MallocData() != RET_OK) {
|
||||
MS_LOG(ERROR) << "Malloc memory failed";
|
||||
return RET_ERROR;
|
||||
}
|
||||
dst_tensor->ResetRefCount();
|
||||
memcpy(dst_tensor->data_, src_tensor.data_, data_size);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
Tensor *Tensor::CopyTensor(const Tensor &src_tensor, bool copy_data, AllocatorPtr allocator) {
|
||||
auto *result = new (std::nothrow) Tensor;
|
||||
if (result == nullptr) {
|
||||
MS_LOG(ERROR) << "New tensor failed";
|
||||
return nullptr;
|
||||
}
|
||||
result->data_type_ = src_tensor.data_type_;
|
||||
result->shape_ = src_tensor.shape_;
|
||||
result->category_ = src_tensor.category_;
|
||||
result->format_ = src_tensor.format_;
|
||||
result->set_allocator(allocator);
|
||||
if (copy_data) {
|
||||
auto ret = CopyTensorData(src_tensor, result);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "CopyTensorData error";
|
||||
delete result;
|
||||
return nullptr;
|
||||
}
|
||||
result->own_data_ = src_tensor.own_data_;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Tensor::~Tensor() {
|
||||
FreeData();
|
||||
this->data_ = nullptr;
|
||||
}
|
||||
|
||||
bool Tensor::operator==(const Tensor &tensor) {
|
||||
return data_ == tensor.data_ && shape_ == tensor.shape_ && data_type_ == tensor.data_type_;
|
||||
}
|
||||
|
||||
int32_t Tensor::Batch() const {
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::NCHW:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::KHWC:
|
||||
case mindspore::NC:
|
||||
case mindspore::NC4:
|
||||
return this->shape_[0];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[3];
|
||||
case mindspore::HWKC:
|
||||
return this->shape_[2];
|
||||
case mindspore::CKHW:
|
||||
return this->shape_[1];
|
||||
default:
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Tensor::Channel() const {
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::NC:
|
||||
case mindspore::NC4:
|
||||
return this->shape_[1];
|
||||
case mindspore::HWCK:
|
||||
return this->shape_[2];
|
||||
case mindspore::HWKC:
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::KHWC:
|
||||
return this->shape_[3];
|
||||
case mindspore::CKHW:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[0];
|
||||
default:
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Tensor::Height() const {
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::CKHW:
|
||||
return this->shape_[2];
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::KHWC:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[1];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::HWKC:
|
||||
case mindspore::HW:
|
||||
case mindspore::HW4:
|
||||
return this->shape_[0];
|
||||
default:
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Tensor::Width() const {
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::CKHW:
|
||||
return this->shape_[3];
|
||||
case mindspore::KHWC:
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[2];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::HWKC:
|
||||
case mindspore::HW:
|
||||
case mindspore::HW4:
|
||||
return this->shape_[1];
|
||||
default:
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
size_t Tensor::Size() const {
|
||||
size_t element_size = DataTypeSize(this->data_type_);
|
||||
auto element_num = (format_ == mindspore::NC4HW4 || format_ == mindspore::NHWC4) ? ElementsC4Num() : ElementsNum();
|
||||
if (element_num < 0) {
|
||||
MS_LOG(INFO) << "Element number of tensor should large than 0 : " << element_num;
|
||||
return 0;
|
||||
}
|
||||
return element_size * element_num;
|
||||
}
|
||||
|
||||
int64_t Tensor::ElementsNum() const {
|
||||
if (this->category_ == CONST_SCALAR) {
|
||||
return 1;
|
||||
}
|
||||
int64_t num = 1;
|
||||
for (size_t i = 0; i < shape_.size(); ++i) {
|
||||
CHECK_INT64_MUL_OVERFLOW(num, shape_[i]);
|
||||
num *= shape_[i];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
int64_t Tensor::ElementsC4Num() const {
|
||||
if (this->category_ == CONST_SCALAR) {
|
||||
return 1;
|
||||
}
|
||||
int64_t result = 1;
|
||||
constexpr int kC4Align = 4;
|
||||
if (this->shape_.size() == 4) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Batch());
|
||||
result *= Batch();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Height());
|
||||
result *= Height();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Width());
|
||||
result *= Width();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 3LL) / kC4Align * kC4Align);
|
||||
result *= (Channel() + 3LL) / kC4Align * kC4Align;
|
||||
} else if (this->shape_.size() == 2) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, this->shape_[0]);
|
||||
result *= this->shape_[0];
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (this->shape_[1] + 3LL) / kC4Align * kC4Align);
|
||||
result *= (this->shape_[1] + 3LL) / kC4Align * kC4Align;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int Tensor::DimensionSize(const size_t index) const {
|
||||
int dim_size = -1;
|
||||
if (index < shape_.size()) {
|
||||
dim_size = shape_[index];
|
||||
} else {
|
||||
MS_LOG(ERROR) << "Dimension index is wrong: " << index;
|
||||
}
|
||||
return dim_size;
|
||||
}
|
||||
|
||||
std::string Tensor::ToString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "schema::Format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
oss << " DataType: " << this->data_type_;
|
||||
oss << " Category: " << this->category_;
|
||||
oss << " Shape:";
|
||||
for (auto &dim : this->shape()) {
|
||||
oss << " " << dim;
|
||||
}
|
||||
oss << std::endl << "Data:";
|
||||
switch (this->data_type_) {
|
||||
case kNumberTypeFloat32: {
|
||||
oss << DataToString<float>(data_, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeFloat16: {
|
||||
oss << DataToString<int16_t>(data_, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt32: {
|
||||
oss << DataToString<int32_t>(data_, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt16: {
|
||||
oss << DataToString<int16_t>(data_, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt8: {
|
||||
oss << DataToString<int8_t>(data_, this->ElementsNum());
|
||||
} break;
|
||||
default:
|
||||
oss << "Unsupported data type to print";
|
||||
break;
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
int Tensor::MallocData(const AllocatorPtr allocator) {
|
||||
if (this->data_ != nullptr) {
|
||||
return RET_OK;
|
||||
}
|
||||
if (allocator != nullptr) {
|
||||
allocator_ = allocator;
|
||||
}
|
||||
auto data_size = this->Size();
|
||||
|
||||
if (data_size > GetMaxMallocSize()) {
|
||||
MS_LOG(ERROR) << "Malloc size is too big while coping data, " << data_size << " bytes";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (allocator_ == nullptr) {
|
||||
this->data_ = malloc(data_size);
|
||||
} else {
|
||||
this->data_ = allocator_->Malloc(data_size);
|
||||
}
|
||||
if (this->data_ == nullptr) {
|
||||
MS_LOG(ERROR) << "Malloc tensor data failed, size=" << data_size;
|
||||
return RET_ERROR;
|
||||
}
|
||||
this->own_data_ = true;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void Tensor::FreeData() {
|
||||
if (IS_RUNTIME_ALLOCATOR(allocator_)) {
|
||||
return;
|
||||
}
|
||||
if (this->data_ != nullptr && this->own_data_) {
|
||||
if (this->allocator_ != nullptr) {
|
||||
this->allocator_->Free(this->data_);
|
||||
if (!IS_STATIC_ALLOCATOR(allocator_) || (allocator_->RefCount(this->data_) != 0)) {
|
||||
this->data_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
free(this->data_);
|
||||
this->data_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *Tensor::ReallocData() {
|
||||
if (this->data_ != nullptr) {
|
||||
FreeData();
|
||||
}
|
||||
return this->MutableData();
|
||||
}
|
||||
|
||||
void *Tensor::MutableData() {
|
||||
if (this->data_ == nullptr) {
|
||||
auto ret = this->MallocData();
|
||||
if (ret != 0) {
|
||||
MS_LOG(WARNING) << "Malloc data failed";
|
||||
}
|
||||
}
|
||||
Prepare();
|
||||
return this->data_;
|
||||
}
|
||||
|
||||
void Tensor::IncRefCount() {
|
||||
ref_count_++;
|
||||
if (allocator_ != nullptr) {
|
||||
allocator_->IncRefCount(this->data_, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Tensor::DecRefCount() {
|
||||
if (this->IsConst() || this->IsGraphInput()) {
|
||||
return;
|
||||
}
|
||||
int tensor_ref_count = --ref_count_;
|
||||
int data_ref_count = tensor_ref_count;
|
||||
|
||||
if (allocator_ != nullptr) {
|
||||
data_ref_count = allocator_->DecRefCount(this->data_, 1);
|
||||
}
|
||||
if (tensor_ref_count <= 0) {
|
||||
if (data_ref_count <= 0) {
|
||||
FreeData();
|
||||
} else {
|
||||
data_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tensor::AddQuantParam(const LiteQuantParam &quant_param) { this->quant_params_.push_back(quant_param); }
|
||||
|
||||
std::vector<LiteQuantParam> Tensor::quant_params() const { return this->quant_params_; }
|
||||
|
||||
void Tensor::set_quant_params(const std::vector<LiteQuantParam> quant_params) { this->quant_params_ = quant_params; }
|
||||
|
||||
std::vector<float> Tensor::quant_clusters() const { return this->quant_clusters_; }
|
||||
|
||||
void Tensor::set_quant_clusters(const std::vector<float> &clusters) { this->quant_clusters_ = clusters; }
|
||||
|
||||
std::vector<tensor::MSTensor *> TensorVectorCast(const std::vector<Tensor *> &src) {
|
||||
std::vector<tensor::MSTensor *> target(src.size());
|
||||
std::transform(src.begin(), src.end(), target.begin(), [](Tensor *t) { return static_cast<tensor::MSTensor *>(t); });
|
||||
return target;
|
||||
}
|
||||
|
||||
} // namespace lite
|
||||
|
||||
} // namespace mindspore
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_SRC_TENSOR_H_
|
||||
#define MINDSPORE_LITE_SRC_TENSOR_H_
|
||||
|
||||
#include <math.h>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <numeric>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include "include/ms_tensor.h"
|
||||
#include "include/api/format.h"
|
||||
#include "src/runtime/inner_allocator.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "schema/model_generated.h"
|
||||
#include "src/common/utils.h"
|
||||
#include "src/tensor_category.h"
|
||||
#include "nnacl/tensor_c.h"
|
||||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
#define STATIC_ALLOCATION -271964
|
||||
#define RUNTIME_REFCOUNT 0x9999
|
||||
#define IS_STATIC_ALLOCATOR(allocator) ((allocator != nullptr) && (allocator->RefCount(nullptr) == STATIC_ALLOCATION))
|
||||
#define IS_RUNTIME_ALLOCATOR(allocator) ((allocator != nullptr) && (allocator->RefCount(nullptr) == RUNTIME_REFCOUNT))
|
||||
struct LiteQuantParam {
|
||||
double scale;
|
||||
int32_t zeroPoint;
|
||||
float var_corr{1};
|
||||
float mean_corr{0};
|
||||
bool inited{false};
|
||||
std::vector<float> clusters{};
|
||||
int bitNum{8};
|
||||
int roundType{1};
|
||||
int multiplier{1};
|
||||
int dstDtype{32};
|
||||
};
|
||||
|
||||
class Tensor : public mindspore::tensor::MSTensor {
|
||||
public:
|
||||
Tensor() = default;
|
||||
|
||||
Tensor(TypeId data_type, std::vector<int> shape, const mindspore::Format &format = mindspore::NHWC,
|
||||
Category category = VAR);
|
||||
|
||||
Tensor(const Tensor &tensor) = delete;
|
||||
|
||||
Tensor(Tensor &&other) = delete;
|
||||
|
||||
Tensor &operator=(const Tensor &tensor) = delete;
|
||||
|
||||
Tensor &operator=(Tensor &&src) = delete;
|
||||
|
||||
~Tensor() override;
|
||||
|
||||
static int CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor);
|
||||
|
||||
static Tensor *CopyTensor(const Tensor &src_tensor, bool copy_data = false, AllocatorPtr allocator = nullptr);
|
||||
|
||||
virtual bool operator==(const Tensor &tensor);
|
||||
|
||||
void set_tensor_name(const std::string &name) override { tensor_name_ = name; }
|
||||
|
||||
std::string tensor_name() const override { return tensor_name_; }
|
||||
|
||||
TypeId data_type() const override { return (TypeId)tensorc.data_type_; }
|
||||
|
||||
void set_data_type(TypeId data_type) override { tensorc.data_type_ = data_type; }
|
||||
|
||||
std::vector<int> shape() const override {
|
||||
std::vector<int> shape(tensorc.shape_size_);
|
||||
for (size_t s = 0; s < tensorc.shape_size_; s++) {
|
||||
shape[s] = tensorc.shape_[s];
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
void set_shape(const std::vector<int> &shape) override {
|
||||
tensorc.shape_size_ = shape.size();
|
||||
for (size_t s = 0; s < tensorc.shape_size_; s++) {
|
||||
tensorc.shape_[s] = shape[s];
|
||||
}
|
||||
}
|
||||
|
||||
int DimensionSize(size_t index) const;
|
||||
|
||||
int64_t ElementsNum() const override;
|
||||
|
||||
int32_t Batch() const;
|
||||
|
||||
int32_t Channel() const;
|
||||
|
||||
int32_t Height() const;
|
||||
|
||||
int32_t Width() const;
|
||||
|
||||
int64_t ElementsC4Num() const;
|
||||
|
||||
size_t Size() const override;
|
||||
|
||||
void set_allocator(AllocatorPtr allocator) override { allocator_ = allocator; }
|
||||
|
||||
AllocatorPtr allocator() const override { return allocator_; }
|
||||
|
||||
virtual int MallocData(const AllocatorPtr allocator = nullptr);
|
||||
|
||||
virtual void FreeData();
|
||||
|
||||
void *MutableData() override;
|
||||
|
||||
void *ReallocData();
|
||||
|
||||
void *data() override { return tensorc.data_; };
|
||||
|
||||
virtual void *data() const { return tensorc.data_; }
|
||||
|
||||
// tensor will hold this data, and free this data in destructor
|
||||
void set_data(void *data) override {
|
||||
this->tensorc.data_ = data;
|
||||
this->own_data_ = true;
|
||||
}
|
||||
|
||||
Category category() const { return this->category_; }
|
||||
|
||||
void set_category(Category category) { this->category_ = category; }
|
||||
|
||||
void set_format(mindspore::Format format) override { this->tensorc.format_ = format; }
|
||||
|
||||
mindspore::Format format() const override { return (mindspore::Format)this->tensorc.format_; }
|
||||
virtual int ref_count() const { return ref_count_; }
|
||||
|
||||
virtual int init_ref_count() const { return static_cast<int>(this->init_ref_count_); }
|
||||
|
||||
virtual void set_ref_count(int ref_count) {
|
||||
ref_count_ = ref_count;
|
||||
if (allocator_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
allocator_->SetRefCount(tensorc.data_, ref_count);
|
||||
return;
|
||||
}
|
||||
|
||||
void set_init_ref_count(int ref_count) { this->init_ref_count_ = ref_count; }
|
||||
|
||||
virtual void ResetRefCount() { set_ref_count(static_cast<int>(this->init_ref_count_)); }
|
||||
|
||||
virtual void IncRefCount();
|
||||
|
||||
virtual void DecRefCount();
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
void AddQuantParam(const LiteQuantParam &quant_param);
|
||||
|
||||
std::vector<LiteQuantParam> quant_params() const override;
|
||||
|
||||
void set_quant_params(std::vector<LiteQuantParam>) override;
|
||||
|
||||
std::vector<float> quant_clusters() const;
|
||||
|
||||
void set_quant_clusters(const std::vector<float> &clusters);
|
||||
|
||||
bool IsConst() const override {
|
||||
return (this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR) && this->tensorc.data_ != nullptr;
|
||||
}
|
||||
|
||||
bool IsScalar() const { return this->category_ == CONST_SCALAR && this->tensorc.data_ != nullptr; }
|
||||
|
||||
bool IsGraphInput() const { return this->category_ == GRAPH_INPUT; }
|
||||
|
||||
bool IsGraphOutput() const { return this->category_ == GRAPH_OUTPUT; }
|
||||
|
||||
void Prepare() {
|
||||
if (allocator_ != nullptr) {
|
||||
tensorc.data_ = allocator_->Prepare(tensorc.data_);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsReady() const {
|
||||
return this->IsConst() || (this->IsGraphInput() && this->tensorc.data_ != nullptr) || ref_count() >= 1;
|
||||
}
|
||||
|
||||
bool own_data() const { return this->own_data_; }
|
||||
|
||||
virtual void set_own_data(bool own_data) { this->own_data_ = own_data; }
|
||||
|
||||
template <typename T>
|
||||
int Scale(float scale) {
|
||||
T cast_scale = static_cast<T>(scale);
|
||||
auto data = reinterpret_cast<T *>(tensorc.data_);
|
||||
if (data == nullptr) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
int length = ElementsNum();
|
||||
for (int i = 0; i < length; i++) {
|
||||
data[i] *= cast_scale;
|
||||
}
|
||||
scale_ *= scale;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
float get_scale() const { return this->scale_; }
|
||||
|
||||
void set_scale(float scale) { this->scale_ = scale; }
|
||||
|
||||
bool IsScale() const { return (std::fabs(this->scale_ - 1.0f) > 1.0e-05); }
|
||||
|
||||
TensorC &TensorC() { return tensorc; }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
std::string DataToString(void *data, size_t data_number, size_t print_len = 40) const {
|
||||
if (data == nullptr) {
|
||||
return "Data of tensor is nullptr";
|
||||
}
|
||||
std::ostringstream oss;
|
||||
auto casted_data = static_cast<T *>(data);
|
||||
for (size_t i = 0; i < print_len && i < data_number; i++) {
|
||||
oss << " " << casted_data[i];
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string tensor_name_;
|
||||
// void *tensor.data_ = nullptr;
|
||||
// TypeId data_type_;
|
||||
// std::vector<int> shape_;
|
||||
// mindspore::Format tensor.format_;
|
||||
TensorC tensorc;
|
||||
Category category_;
|
||||
std::atomic_int ref_count_ = {0};
|
||||
size_t init_ref_count_ = 0;
|
||||
std::vector<LiteQuantParam> quant_params_;
|
||||
std::vector<float> quant_clusters_;
|
||||
AllocatorPtr allocator_ = nullptr;
|
||||
bool own_data_{false};
|
||||
float scale_ = 1.0f;
|
||||
};
|
||||
|
||||
std::vector<tensor::MSTensor *> TensorVectorCast(const std::vector<Tensor *> &src);
|
||||
} // namespace lite
|
||||
} // namespace mindspore
|
||||
|
||||
using TensorPtr = std::shared_ptr<mindspore::lite::Tensor>;
|
||||
#endif // MINDSPORE_LITE_SRC_TENSOR_H_
|
||||
|
|
@ -129,6 +129,13 @@ if(MSLITE_ENABLE_CONTROLFLOW)
|
|||
set(LITE_SRC ${LITE_SRC} ${CONTROL_FLOW_SRC})
|
||||
endif()
|
||||
|
||||
if(BUILD_EXPERIMENT)
|
||||
file(GLOB EXPERIMENT_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../experiment/kernel/*.cc
|
||||
)
|
||||
set(LITE_SRC ${LITE_SRC} ${EXPERIMENT_SRC})
|
||||
endif()
|
||||
|
||||
if(MSLITE_ENABLE_RUNTIME_GLOG)
|
||||
add_definitions(-DPRIMITIVE_WRITEABLE)
|
||||
add_definitions(-DUSE_GLOG)
|
||||
|
|
|
|||
Loading…
Reference in New Issue