!40052 [MS][LITE]Add micro op

Merge pull request !40052 from gongdaguo1/m_add_micro_op
This commit is contained in:
i-robot 2022-08-16 07:14:09 +00:00 committed by Gitee
commit e016c16c0c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
17 changed files with 366 additions and 6 deletions

View File

@ -80,6 +80,8 @@ set(CODER_OPCODERS_SRC
${MICRO_DIR}/coder/opcoders/nnacl/fp32/batchnorm_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/biasadd_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/concat_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/shape_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/split_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/conv2d_delegate_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/convolution_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/convolution_winograd_fp32_coder.cc

View File

@ -7,6 +7,7 @@ set(WRAPPER_SRC
${WRAPPER_DIR}/base/optimize_handler_wrapper.c
${WRAPPER_DIR}/base/affine_wrapper.c
${WRAPPER_DIR}/fp32/matmul_fp32_wrapper.c
${WRAPPER_DIR}/fp32/concat_fp32_wrapper.c
${WRAPPER_DIR}/fp32/arithmetic_fp32_wrapper.c
${WRAPPER_DIR}/fp32/deconvolution_fp32_wrapper.c
${WRAPPER_DIR}/fp32/scale_fp32_wrapper.c
@ -15,6 +16,7 @@ set(WRAPPER_SRC
${WRAPPER_DIR}/fp32/conv_winograd_fp32_wrapper.c
${WRAPPER_DIR}/fp32/pooling_fp32_wrapper.c
${WRAPPER_DIR}/fp32/transpose_fp32_wrapper.c
${WRAPPER_DIR}/fp32/split_fp32_wrapper.c
${WRAPPER_DIR}/int8/matmul_int8_wrapper.c
${WRAPPER_DIR}/int8/add_int8_wrapper.c
${WRAPPER_DIR}/int8/concat_int8_wrapper.c

View File

@ -63,6 +63,9 @@ int ActivationFP32Coder::DoCode(CoderContext *const context) {
case schema::ActivationType_HSWISH:
code.CodeFunction("HSwish", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_SWISH:
code.CodeFunction("Swish", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_HSIGMOID:
code.CodeFunction("HSigmoid", input_tensor_, count, output_tensor_);
break;

View File

@ -18,6 +18,7 @@
#include <vector>
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "coder/opcoders/file_collector.h"
#include "coder/opcoders/parallel.h"
using mindspore::schema::PrimitiveType_Concat;
@ -71,14 +72,19 @@ int ConcatFP32Coder::DoCode(CoderContext *const context) {
code << "shape_" << i << ", ";
}
code << "};\n";
if (support_parallel_) {
thread_num_ = 1;
if (!support_parallel_) {
code.CodeFunction("Concat", "inputs_addr", input_num, axis_, "inputs_output_shape", output_tensor_->shape().size(),
output_tensor_, 0, 1, sizeof(float));
} else {
Collect(context, {"wrapper/fp32/concat_fp32_wrapper.h"}, {"concat_fp32_wrapper.c"});
code.CodeBaseStruct("ConcatFp32Args", kRunArgs, "inputs_addr", input_num, axis_, "inputs_output_shape",
output_tensor_->shape().size(), output_tensor_, gThreadNum, sizeof(float));
code.CodeFunction(kParallelLaunch, "DoConcatRun", kRunArgsAddr, gThreadNum);
}
code.CodeFunction("Concat", "inputs_addr", input_num, axis_, "inputs_output_shape", output_tensor_->shape().size(),
output_tensor_, 0, thread_num_, sizeof(float));
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Concat, CPUOpCoderCreator<ConcatFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Concat, CPUOpCoderCreator<ConcatFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

View File

@ -94,4 +94,5 @@ int GatherFP32Coder::DoCode(CoderContext *context) {
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Gather, CPUOpCoderCreator<GatherFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Gather, CPUOpCoderCreator<GatherFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

View File

@ -28,6 +28,9 @@ int PowerFP32Coder::DoCode(CoderContext *const context) {
scale_ = reinterpret_cast<PowerParameter *>(parameter_)->scale_;
shift_ = reinterpret_cast<PowerParameter *>(parameter_)->shift_;
int size = input_tensor_->ElementsNum();
if (support_parallel_) {
thread_num_ = 1;
}
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
int stride = UP_DIV(size, thread_num_);
int len = MSMIN(stride, size - stride * kDefaultTaskId);

View File

@ -0,0 +1,48 @@
/**
* Copyright 2022 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 "coder/opcoders/nnacl/fp32/shape_fp32_coder.h"
#include <string>
#include <vector>
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Shape;
namespace mindspore::lite::micro::nnacl {
int ShapeFP32Coder::DoCode(CoderContext *const context) {
std::string output_str = allocator_->GetRuntimeAddr(output_tensor_);
NNaclFp32Serializer code;
MS_LOG(WARNING)
<< "The shape op can be fused and optimized by configuring the 'inputShape' parameter of the converter tool.";
code << " {\n";
int index = 0;
for (auto &shape : input_tensors_.at(0)->shape()) {
code << " " << output_str << "[" << index++ << "] = " << shape << ";\n";
}
code << " }\n";
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeBool, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt8, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeUInt8, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt64, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat16, PrimitiveType_Shape, CPUOpCoderCreator<ShapeFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

View File

@ -0,0 +1,36 @@
/**
* Copyright 2022 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_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SHAPE_FP32_CODER_H_
#define MINDSPORE_LITE_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SHAPE_FP32_CODER_H_
#include <vector>
#include "coder/opcoders/op_coder.h"
namespace mindspore::lite::micro::nnacl {
class ShapeFP32Coder final : public OperatorCoder {
public:
ShapeFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const LiteGraph::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ShapeFP32Coder() override = default;
int Prepare(CoderContext *const context) override { return RET_OK; }
int DoCode(CoderContext *const context) override;
};
} // namespace mindspore::lite::micro::nnacl
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SHAPE_FP32_CODER_H_

View File

@ -0,0 +1,77 @@
/**
* Copyright 2022 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 "coder/opcoders/nnacl/fp32/split_fp32_coder.h"
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "coder/opcoders/file_collector.h"
#include "coder/opcoders/parallel.h"
#include "src/litert/kernel/cpu/base/split_base.h"
using mindspore::schema::PrimitiveType_Split;
namespace mindspore::lite::micro::nnacl {
int SplitFP32Coder::Prepare(CoderContext *const context) {
auto status = mindspore::kernel::SplitBaseCPUKernel::CheckAndInitSplitParam(
*input_tensor_, reinterpret_cast<SplitParameter *>(parameter_));
if (RET_OK != status) {
MS_LOG(ERROR) << "CheckAndInitSplitParam failed";
return status;
}
return RET_OK;
}
int SplitFP32Coder::DoCode(CoderContext *const context) {
Collect(context, {"nnacl/base/split_base.h"}, {"split_base.c"});
if (support_parallel_) {
Collect(context, {"wrapper/fp32/split_fp32_wrapper.h"}, {"split_fp32_wrapper.c"});
}
auto param = reinterpret_cast<SplitParameter *>(parameter_);
int num_unit = param->split_count_ * param->num_split_;
NNaclFp32Serializer code;
code << " void *output_ptrs[" << output_tensors_.size() << "] = {";
for (int i = 0; i < param->num_split_; i++) {
code << allocator_->GetRuntimeAddr(output_tensors_.at(i)) << ",";
}
code << "};\n";
code << " int input_dim[" << input_tensor_->shape().size() << "] = {";
for (auto &dim : input_tensor_->shape()) {
code << dim << ",";
}
code << "};\n";
code << " int split_sizes[" << param->num_split_ << "] = {";
for (int i = 0; i < param->num_split_; i++) {
code << param->split_sizes_[i] << ",";
}
code << "};\n";
code.CodeStruct("split_param", *param);
if (!support_parallel_) {
code.CodeFunction("DoSplit", input_tensor_, "(void *)output_ptrs", "input_dim", "0", num_unit, "&split_param",
lite::DataTypeSize(input_tensor_->data_type()));
} else {
code.CodeBaseStruct("SplitFp32Args", kRunArgs, input_tensor_, "(void *)output_ptrs", "input_dim", num_unit,
lite::DataTypeSize(input_tensor_->data_type()), "&split_param");
code.CodeFunction(kParallelLaunch, "DoSplitRun", kRunArgsAddr, "split_param.op_parameter_.thread_num_");
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Split, CPUOpCoderCreator<SplitFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Split, CPUOpCoderCreator<SplitFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat16, PrimitiveType_Split, CPUOpCoderCreator<SplitFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

View File

@ -0,0 +1,37 @@
/**
* Copyright 2022 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_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SPLIT_FP32_CODER_H_
#define MINDSPORE_LITE_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SPLIT_FP32_CODER_H_
#include <vector>
#include "coder/opcoders/op_coder.h"
#include "nnacl/split_parameter.h"
namespace mindspore::lite::micro::nnacl {
class SplitFP32Coder final : public OperatorCoder {
public:
SplitFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const LiteGraph::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~SplitFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
};
} // namespace mindspore::lite::micro::nnacl
#endif // MINDSPORE_LITE_TOOLS_CONVERTER_MICRO_CODER_OPCODERS_NNACL_FP32_SPLIT_FP32_CODER_H_

View File

@ -97,6 +97,12 @@ void NNaclFp32Serializer::CodeStruct(const std::string &name, const SliceParamet
"{0}", slice_parameter.param_length_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const SplitParameter &split_parameter) {
CodeBaseStruct("SplitParameter", name, split_parameter.op_parameter_, split_parameter.num_split_, "split_sizes",
split_parameter.split_dim_, ToString(split_parameter.strides_), "{0}", split_parameter.n_dims_,
split_parameter.split_count_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const TileParameter &tile_parameter) {
CodeBaseStruct("TileParameter", name, tile_parameter.op_parameter_, ToString(tile_parameter.multiples_),
ToString(tile_parameter.in_shape_), ToString(tile_parameter.out_shape_),

View File

@ -26,6 +26,7 @@
#include "nnacl/matmul_parameter.h"
#include "nnacl/scale.h"
#include "nnacl/slice_parameter.h"
#include "nnacl/split_parameter.h"
#include "nnacl/base/tile_base.h"
#include "nnacl/fp32/transpose_fp32.h"
#include "nnacl/pooling_parameter.h"
@ -68,6 +69,7 @@ class NNaclFp32Serializer : public Serializer {
void CodeStruct(const std::string &name, const GroupNormParameter &gn_param);
void CodeStruct(const std::string &name, const ActivationParameter &activation_parameter);
void CodeStruct(const std::string &name, const OpParameter &op_param);
void CodeStruct(const std::string &name, const SplitParameter &split_parameter);
void CodeArrayStruct(const std::string &name, TensorC *tensorC, std::vector<Tensor *> tensor);
private:

View File

@ -0,0 +1,26 @@
/**
* Copyright 2022 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 "wrapper/fp32/concat_fp32_wrapper.h"
#include "nnacl/errorcode.h"
#include "nnacl/base/concat_base.h"
int DoConcatRun(void *cdata, int task_id, float lhs_scale, float rhs_scale) {
ConcatFp32Args *args = (ConcatFp32Args *)cdata;
Concat(args->inputs_addr_, args->input_num_, args->axis_, args->inputs_output_shape_, args->shape_size_,
args->output_, task_id, args->thread_num_, args->data_size_);
return NNACL_OK;
}

View File

@ -0,0 +1,41 @@
/**
* Copyright 2022 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_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_CONCAT_FP32_WRAPPER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_CONCAT_FP32_WRAPPER_H_
#include <string.h>
typedef struct {
void **inputs_addr_;
int input_num_;
int axis_;
int **inputs_output_shape_;
int shape_size_;
void *output_;
int thread_num_;
int data_size_;
} ConcatFp32Args;
#ifdef __cplusplus
extern "C" {
#endif
int DoConcatRun(void *cdata, int task_id, float lhs_scale, float rhs_scale);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_LITE_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_CONCAT_FP32_WRAPPER_H_

View File

@ -20,6 +20,5 @@
int DoMaxPooling(void *cdata, int task_id, float lhs_scale, float rhs_scale) {
PoolingFp32Args *args = (PoolingFp32Args *)cdata;
MaxPooling(args->input_, args->output_, args->pooling_param_, task_id, args->min_, args->max_);
return NNACL_OK;
return MaxPooling(args->input_, args->output_, args->pooling_param_, task_id, args->min_, args->max_);
}

View File

@ -0,0 +1,31 @@
/**
* Copyright 2022 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 "wrapper/fp32/split_fp32_wrapper.h"
#include "nnacl/errorcode.h"
int DoSplitRun(void *cdata, int task_id, float lhs_scale, float rhs_scale) {
SplitFp32Args *args = (SplitFp32Args *)cdata;
int thread_n_stride = UP_DIV(args->num_unit_, args->param->op_parameter_.thread_num_);
int num_unit_thread = MSMIN(thread_n_stride, args->num_unit_ - task_id * thread_n_stride);
if (num_unit_thread <= 0) {
return NNACL_OK;
}
int thread_offset = task_id * thread_n_stride;
return DoSplit(args->input_ptr_, args->output_ptr_, args->in_tensor_shape, thread_offset, num_unit_thread,
args->param, args->data_type_size);
}

View File

@ -0,0 +1,40 @@
/**
* Copyright 2022 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_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_SPLIT_FP32_WRAPPER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_SPLIT_FP32_WRAPPER_H_
#include <string.h>
#include "nnacl/base/split_base.h"
typedef struct {
const void *input_ptr_;
void *output_ptr_;
int *in_tensor_shape;
int num_unit_;
int data_type_size;
const SplitParameter *param;
} SplitFp32Args;
#ifdef __cplusplus
extern "C" {
#endif
int DoSplitRun(void *cdata, int task_id, float lhs_scale, float rhs_scale);
#ifdef __cplusplus
}
#endif
#endif // MINDSPORE_LITE_MICRO_CODER_OPERATOR_LIBRARY_WRAPPER_FP32_SPLIT_FP32_WRAPPER_H_