!12112 add mciro opcoders

From: @zoloft
Reviewed-by: 
Signed-off-by:
This commit is contained in:
mindspore-ci-bot 2021-02-07 09:44:58 +08:00 committed by Gitee
commit 11b2d4c8aa
53 changed files with 3514 additions and 0 deletions

View File

@ -71,11 +71,28 @@ set(MICRO_CODER_SRC
${CMAKE_CURRENT_SOURCE_DIR}/opcoders/file_collector.cc
)
file(GLOB OPCODER_SRC_SERIALIZER ${CMAKE_CURRENT_SOURCE_DIR}
opcoders/serializers/nnacl_serializer/*.cc
)
file(GLOB_RECURSE OPCODER_SRC_FP32 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
opcoders/nnacl/fp32/*.cc
)
file(GLOB_RECURSE OPCODER_SRC_INT8 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
opcoders/nnacl/int8/*.cc
)
list(APPEND MICRO_CODER_SRC
${MICRO_ALLOCATOR}
${MICRO_GENERATOR}
${MICRO_OPCODERS_BASE}
${MICRO_OPCODERS_CMSIS_NN}
${OPCODER_SRC_SERIALIZER}
${OPCODER_SRC_FP32}
${OPCODER_SRC_INT8}
)
add_executable(codegen main.cc

View File

@ -0,0 +1,71 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/activation_fp32_coder.h"
#include <string>
#include "nnacl/fp32/activation_fp32.h"
#include "nnacl/op_base.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Activation;
namespace mindspore::lite::micro {
int ActivationFP32Coder::DoCode(CoderContext *const context) {
// attribute
auto *activation_parameter = reinterpret_cast<ActivationParameter *>(parameter_);
int task_id = 0;
int length = input_tensor_->ElementsNum();
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
int stride = UP_DIV(length, thread_num_);
int count = MSMIN(stride, length - stride * task_id);
if (activation_parameter->type_ == schema::ActivationType_SIGMOID) {
Collect(context, {"runtime/kernel/fp32/sigmoid.h"}, {"sigmoid.c"});
} else {
Collect(context, {"nnacl/fp32/activation.h"}, {"activation.c"});
}
nnacl::NNaclFp32Serializer code;
switch (activation_parameter->type_) {
case schema::ActivationType_RELU:
code.CodeFunction("Fp32Relu", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_RELU6:
code.CodeFunction("Fp32Relu6", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_LEAKY_RELU:
code.CodeFunction("LRelu", input_tensor_, count, output_tensor_, activation_parameter->alpha_);
break;
case schema::ActivationType_SIGMOID:
code.CodeFunction("Sigmoid", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_TANH:
code.CodeFunction("Tanh", input_tensor_, count, output_tensor_);
break;
case schema::ActivationType_HSWISH:
code.CodeFunction("HSwish", input_tensor_, count, output_tensor_);
break;
default:
MS_LOG(ERROR) << "Activation type error";
return RET_ERROR;
}
MS_LOG(DEBUG) << "ActivationFP32Code has been called";
context->AppendCode(code.str());
return lite::RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Activation, CPUOpCoderCreator<ActivationFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,48 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/addn_fp32_coder.h"
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_AddN;
namespace mindspore::lite::micro {
int AddNFP32Coder::DoCode(CoderContext *const context) {
Tensor *input0 = input_tensors_.at(kInputIndex);
Tensor *input1 = input_tensors_.at(1);
int elements_num = input0->ElementsNum();
// Get Tensor Pointer
std::string input0_str = allocator_->GetRuntimeAddr(input0);
std::string input1_str = allocator_->GetRuntimeAddr(input1);
Collect(context, {"nnacl/kernel/fp32/add_fp32_slim.h"}, {"add_fp32_slim.c"});
nnacl::NNaclFp32Serializer code;
code.CodeFunction("ElementAdd", input0_str, input1_str, output_tensor_, elements_num);
if (input_tensors_.size() > 2) {
for (size_t i = 2; i < input_tensors_.size(); ++i) {
std::string input_str = allocator_->GetRuntimeAddr(input_tensors_.at(i));
code.CodeFunction("ElementAdd", input_str, output_tensor_, elements_num);
}
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_AddN, CPUOpCoderCreator<AddNFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,373 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/arithmetic_fp32_coder.h"
#include <string>
#include <map>
#include <type_traits>
#include "micro/coder/opcoders/file_collector.h"
#include "nnacl/fp32/arithmetic_fp32.h"
#include "micro/coder/log.h"
namespace mindspore::lite::micro {
int ArithmeticFP32Coder::Init(CoderContext *const context) {
filter_tensor_ = input_tensors_.at(kWeightIndex);
MS_CHECK_PTR(filter_tensor_);
if (input_tensor_->data_type() == kNumberTypeFloat32 || input_tensor_->data_type() == kNumberTypeFloat16) {
data_type_ = kDataTypeFloat;
} else {
data_type_ = kDataTypeInt;
}
arithmetic_parameter_->in_elements_num0_ = input_tensor_->ElementsNum();
arithmetic_parameter_->in_elements_num1_ = filter_tensor_->ElementsNum();
arithmetic_parameter_->out_elements_num_ = output_tensor_->ElementsNum();
for (size_t i = 0; i < input_tensor_->shape().size(); i++) {
if (arithmetic_parameter_->in_shape0_[i] == -1) {
MS_CHECK_RET_CODE(
memcpy_s(arithmetic_parameter_->in_shape0_, DEFAULT_ARITHMETIC_NDIMS * sizeof(int),
static_cast<void *>(input_tensor_->shape().data()), input_tensor_->shape().size() * sizeof(int)),
"memcpy_s in shape0 failed!");
}
}
for (size_t i = 0; i < filter_tensor_->shape().size(); i++) {
if (arithmetic_parameter_->in_shape1_[i] == -1) {
MS_CHECK_RET_CODE(
memcpy_s(arithmetic_parameter_->in_shape1_, DEFAULT_ARITHMETIC_NDIMS * sizeof(int),
static_cast<void *>(filter_tensor_->shape().data()), filter_tensor_->shape().size() * sizeof(int)),
"memcpy_s in shape1 failed!");
}
}
for (size_t i = 0; i < output_tensor_->shape().size(); i++) {
if (arithmetic_parameter_->out_shape_[i] == -1) {
MS_CHECK_RET_CODE(
memcpy_s(arithmetic_parameter_->out_shape_, DEFAULT_ARITHMETIC_NDIMS * sizeof(int),
static_cast<void *>(output_tensor_->shape().data()), output_tensor_->shape().size() * sizeof(int)),
"memcpy_s in out shape failed!");
}
}
if (arithmetic_parameter_->in_elements_num0_ == 1 || arithmetic_parameter_->in_elements_num1_ == 1) {
switch (arithmetic_parameter_->op_parameter_.type_) {
case PrimitiveType_Mul:
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptMulRelu";
arithmetic_opt_run_int_ = "ElementOptMulReluInt";
break;
case schema::ActivationType_RELU6:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptMulRelu6";
arithmetic_opt_run_int_ = "ElementOptMulRelu6Int";
break;
default:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptMul";
arithmetic_opt_run_int_ = "ElementOptMulInt";
break;
}
break;
case PrimitiveType_Add:
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptAddRelu";
arithmetic_opt_run_int_ = "ElementOptAddReluInt";
break;
case schema::ActivationType_RELU6:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptAddRelu6";
arithmetic_opt_run_int_ = "ElementOptAddRelu6Int";
break;
default:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptAdd";
arithmetic_opt_run_int_ = "ElementOptAddInt";
break;
}
break;
case PrimitiveType_Sub:
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptSubRelu";
break;
case schema::ActivationType_RELU6:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptSubRelu6";
break;
default:
arithmetic_parameter_->broadcasting_ = false;
arithmetic_opt_run_ = "ElementOptSub";
break;
}
break;
default:
break;
}
}
return RET_OK;
}
int ArithmeticFP32Coder::BroadcastRun(const std::string &input0, const std::string &input1, const std::string &output,
int dim, int out_count, int out_thread_stride,
nnacl::NNaclFp32Serializer *const code) {
if (dim > break_pos_) {
if (data_type_ == kDataTypeInt) {
*code << "\t\t" << arithmetic_run_int_ << "(((" << input0 << ") + " << out_thread_stride << "), ((" << input1
<< ") + " << out_thread_stride << "), ((" << output << ") + " << out_thread_stride << "), " << out_count
<< ");\n";
} else {
*code << "\t\t" << arithmetic_run_ << "(((" << input0 << ") + " << out_thread_stride << "), ((" << input1
<< ") + " << out_thread_stride << "), ((" << output << ") + " << out_thread_stride << "), " << out_count
<< ");\n";
}
return RET_OK;
}
for (int i = 0; i < arithmetic_parameter_->out_shape_[dim]; ++i) {
int pos0_ = arithmetic_parameter_->in_shape0_[dim] == 1 ? 0 : i;
int pos1_ = arithmetic_parameter_->in_shape1_[dim] == 1 ? 0 : i;
int error_code = BroadcastRun(input0 + "+" + std::to_string(pos0_ * arithmetic_parameter_->in_strides0_[dim]),
input1 + "+" + std::to_string(pos1_ * arithmetic_parameter_->in_strides1_[dim]),
output + "+" + std::to_string(i * arithmetic_parameter_->out_strides_[dim]), dim + 1,
out_count, out_thread_stride, code);
if (error_code != RET_OK) {
return error_code;
}
}
return RET_OK;
}
int ArithmeticFP32Coder::Prepare(CoderContext *const context) {
if (parameter_ == nullptr) {
return RET_ERROR;
}
arithmetic_parameter_ = reinterpret_cast<ArithmeticParameter *>(parameter_);
std::map<int, std::function<void()>> type_setters = {
{PrimitiveType_Mul,
[this]() {
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_run_ = "ElementMulRelu";
arithmetic_run_int_ = "ElementMulReluInt";
break;
case schema::ActivationType_RELU6:
arithmetic_run_ = "ElementMulRelu6";
arithmetic_run_int_ = "ElementMulRelu6Int";
break;
default:
arithmetic_run_ = "ElementMul";
arithmetic_run_int_ = "ElementMulInt";
break;
}
}},
{PrimitiveType_Add,
[this]() {
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_run_ = "ElementAddRelu";
arithmetic_run_int_ = "ElementAddReluInt";
break;
case schema::ActivationType_RELU6:
arithmetic_run_ = "ElementAddRelu6";
arithmetic_run_int_ = "ElementAddRelu6Int";
break;
default:
arithmetic_run_ = "ElementAdd";
arithmetic_run_int_ = "ElementAddInt";
break;
}
}},
{PrimitiveType_Sub,
[this]() {
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_run_ = "ElementSubRelu";
break;
case schema::ActivationType_RELU6:
arithmetic_run_ = "ElementSubRelu6";
break;
default:
arithmetic_run_ = "ElementSub";
break;
}
}},
{PrimitiveType_Div,
[this]() {
switch (arithmetic_parameter_->activation_type_) {
case schema::ActivationType_RELU:
arithmetic_run_ = "ElementDivRelu";
break;
case schema::ActivationType_RELU6:
arithmetic_run_ = "ElementDivRelu6";
break;
default:
arithmetic_run_ = "ElementDiv";
break;
}
}},
{PrimitiveType_LogicalAnd, [this]() { arithmetic_run_ = "ElementLogicalAnd"; }},
{PrimitiveType_LogicalOr, [this]() { arithmetic_run_ = "ElementLogicalOr"; }},
{PrimitiveType_Maximum, [this]() { arithmetic_run_ = "ElementMaximum"; }},
{PrimitiveType_Minimum, [this]() { arithmetic_run_ = "ElementMinimum"; }},
{PrimitiveType_FloorDiv, [this]() { arithmetic_run_ = "ElementFloorDiv"; }},
{PrimitiveType_FloorMod, [this]() { arithmetic_run_ = "ElementFloorMod"; }},
{PrimitiveType_Equal, [this]() { arithmetic_run_ = "ElementEqual"; }},
{PrimitiveType_NotEqual, [this]() { arithmetic_run_ = "ElementNotEqual"; }},
{PrimitiveType_Less, [this]() { arithmetic_run_ = "ElementLess"; }},
{PrimitiveType_LessEqual, [this]() { arithmetic_run_ = "ElementLessEqual"; }},
{PrimitiveType_Greater, [this]() { arithmetic_run_ = "ElementGreater"; }},
{PrimitiveType_GreaterEqual, [this]() { arithmetic_run_ = "ElementGreaterEqual"; }},
{PrimitiveType_SquaredDifference, [this]() { arithmetic_run_ = "ElementSquaredDifference"; }},
};
auto iter = type_setters.find(parameter_->type_);
if (iter != type_setters.end()) {
iter->second();
} else {
MS_LOG(ERROR) << "Error Operator type " << parameter_;
arithmetic_run_ = "NULL";
return RET_ERROR;
}
MS_CHECK_RET_CODE(Init(context), "do arothmetic code failed!");
return RET_OK;
}
int ArithmeticFP32Coder::DoCode(CoderContext *const context) {
int task_id = 0;
if (arithmetic_parameter_->broadcasting_) {
outside_ = 1;
for (auto i = arithmetic_parameter_->ndim_ - 1; i >= 0; --i) {
if (arithmetic_parameter_->in_shape0_[i] != arithmetic_parameter_->in_shape1_[i]) {
break_pos_ = i;
break;
}
outside_ *= arithmetic_parameter_->out_shape_[i];
}
ComputeStrides(arithmetic_parameter_->in_shape0_, arithmetic_parameter_->in_strides0_,
arithmetic_parameter_->ndim_);
ComputeStrides(arithmetic_parameter_->in_shape1_, arithmetic_parameter_->in_strides1_,
arithmetic_parameter_->ndim_);
ComputeStrides(arithmetic_parameter_->out_shape_, arithmetic_parameter_->out_strides_,
arithmetic_parameter_->ndim_);
}
int element_num = output_tensor_->ElementsNum();
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
int stride = UP_DIV(element_num, thread_num_);
int count = MSMIN(stride, element_num - stride * task_id);
MS_CHECK_TRUE(!arithmetic_run_.empty(), "arithmetic_run function is nullptr!");
nnacl::NNaclFp32Serializer code;
/**
* for nnacl's operator combine all arithmetic to nnalc/arithmetic.c
* this solution is not suitable for micro, for the size of package.
* */
if (arithmetic_opt_run_ == "ElementOptSub" || arithmetic_run_ == "ElementSub") {
Collect(context, {"nnacl/kernel/fp32/sub.h"}, {"sub.c"});
} else if (arithmetic_opt_run_ == "ElementOptAdd" || arithmetic_run_ == "ElementAdd") {
Collect(context, {"nnacl/kernel/fp32/add_fp32_slim.h"}, {"add_fp32_slim.c"});
} else if (arithmetic_opt_run_ == "ElementOptMul" || arithmetic_run_ == "ElementMul") {
Collect(context, {"nnacl/kernel/fp32/mul.h"}, {"mul.c"});
} else if (arithmetic_run_ == "ElementAddRelu") {
Collect(context, {"nnacl/kernel/fp32/add_relu.h"}, {"add_relu.c"});
} else {
Collect(context, {"nnacl/arithmetic_common.h", "nnacl/fp32/arithmetic.h"}, {"arithmetic_common.c", "arithmetic.c"});
}
if (arithmetic_parameter_->broadcasting_) {
stride = UP_DIV(outside_, thread_num_);
out_count_ = MSMIN(stride, outside_ - stride * task_id);
out_thread_stride_ = stride * task_id;
std::string input0_str = allocator_->GetRuntimeAddr(input_tensor_);
std::string input1_str = allocator_->GetRuntimeAddr(filter_tensor_);
std::string output_str = allocator_->GetRuntimeAddr(output_tensor_);
MS_CHECK_RET_CODE(BroadcastRun(input0_str, input1_str, output_str, 0, out_count_, out_thread_stride_, &code),
"do broad cast code failed!");
} else if (!arithmetic_opt_run_.empty()) {
code.CodeStruct("arithmetic_parameter", *arithmetic_parameter_);
if (arithmetic_parameter_->in_elements_num0_ == 1) {
if (data_type_ == kDataTypeFloat) {
code.CodeFunction(arithmetic_opt_run_, input_tensor_, filter_tensor_, output_tensor_, count,
"&arithmetic_parameter");
} else {
code.CodeFunction(arithmetic_opt_run_int_, input_tensor_, filter_tensor_, output_tensor_, count,
"&arithmetic_parameter");
}
} else if (arithmetic_parameter_->in_elements_num1_ == 1) {
if (data_type_ == kDataTypeFloat) {
code.CodeFunction(arithmetic_opt_run_, input_tensor_, filter_tensor_, output_tensor_, count,
"&arithmetic_parameter");
} else {
code.CodeFunction(arithmetic_opt_run_int_, input_tensor_, filter_tensor_, output_tensor_, count,
"&arithmetic_parameter");
}
} else {
MS_LOG(ERROR) << "arithmetic opt code run: at least one of inputs is scalar";
return RET_ERROR;
}
} else {
if (data_type_ == kDataTypeFloat) {
code.CodeFunction(arithmetic_run_, input_tensor_, filter_tensor_, output_tensor_, count);
} else {
code.CodeFunction(arithmetic_run_int_, input_tensor_, filter_tensor_, output_tensor_, count);
}
}
MS_LOG(DEBUG) << "ArithmeticFP32Code has been called";
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Add, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Mul, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Add, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Sub, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Div, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_LogicalAnd, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_LogicalOr, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Maximum, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Minimum, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_FloorDiv, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_FloorMod, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_SquaredDifference,
CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Equal, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_NotEqual, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Less, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_LessEqual, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Greater, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_GreaterEqual, CPUOpCoderCreator<ArithmeticFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Eltwise, CPUOpCoderCreator<ArithmeticFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,109 @@
/**
* 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.
*/
#ifndef MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
#define MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
#include <vector>
#include <string>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/fp32/arithmetic_fp32.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#define DEFAULT_ARITHMETIC_NDIMS 10
namespace mindspore::lite::micro {
using mindspore::schema::PrimitiveType_Add;
using mindspore::schema::PrimitiveType_Div;
using mindspore::schema::PrimitiveType_Equal;
using mindspore::schema::PrimitiveType_FloorDiv;
using mindspore::schema::PrimitiveType_FloorMod;
using mindspore::schema::PrimitiveType_Greater;
using mindspore::schema::PrimitiveType_GreaterEqual;
using mindspore::schema::PrimitiveType_Less;
using mindspore::schema::PrimitiveType_LessEqual;
using mindspore::schema::PrimitiveType_LogicalAnd;
using mindspore::schema::PrimitiveType_LogicalOr;
using mindspore::schema::PrimitiveType_Maximum;
using mindspore::schema::PrimitiveType_Minimum;
using mindspore::schema::PrimitiveType_Mul;
using mindspore::schema::PrimitiveType_NotEqual;
using mindspore::schema::PrimitiveType_RealDiv;
using mindspore::schema::PrimitiveType_SquaredDifference;
using mindspore::schema::PrimitiveType_Sub;
using mindspore::schema::PrimitiveType_Eltwise;
using mindspore::schema::PrimitiveType_Minimum;
class ArithmeticFP32Coder final : public OperatorCoder {
public:
ArithmeticFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ArithmeticFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
int Init(CoderContext *const context);
int BroadcastRun(const std::string &input0, const std::string &input1, const std::string &output, int dim,
int out_count, int out_thread_stride, nnacl::NNaclFp32Serializer *const code);
int break_pos_{0};
int outside_{0};
int out_thread_stride_{0};
int out_count_{0};
ArithmeticParameter *arithmetic_parameter_{nullptr};
Tensor *filter_tensor_{nullptr};
std::string arithmetic_run_;
std::string arithmetic_run_int_;
std::string arithmetic_opt_run_;
std::string arithmetic_opt_run_int_;
LiteDataType data_type_{kDataTypeFloat};
};
} // namespace mindspore::lite::micro
#endif // MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_

View File

@ -0,0 +1,104 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/arithmetic_self_fp32_coder.h"
#include <string>
#include <map>
#include "nnacl/fp32/arithmetic_fp32.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
namespace mindspore::lite::micro {
int ArithmeticSelfFP32Coder::ReSize() {
data_size_ = input_tensor_->ElementsNum();
thread_sz_count_ = MSMIN(thread_num_, static_cast<int>(data_size_));
MS_CHECK_TRUE(thread_sz_count_ > 0, "thread_sz_count_ <= 0");
thread_sz_stride_ = UP_DIV(data_size_, thread_sz_count_);
return RET_OK;
}
int ArithmeticSelfFP32Coder::Prepare(CoderContext *const context) {
if (parameter_ == nullptr) {
return RET_ERROR;
}
std::map<int, std::function<void()>> type_setters = {
{PrimitiveType_Abs, [this]() { arithmetic_self_run_ = "ElementAbs"; }},
{PrimitiveType_Cos, [this]() { arithmetic_self_run_ = "ElementCos"; }},
{PrimitiveType_Log, [this]() { arithmetic_self_run_ = "ElementLog"; }},
{PrimitiveType_Square, [this]() { arithmetic_self_run_ = "ElementSquare"; }},
{PrimitiveType_Sqrt, [this]() { arithmetic_self_run_ = "ElementSqrt"; }},
{PrimitiveType_Rsqrt, [this]() { arithmetic_self_run_ = "ElementRsqrt"; }},
{PrimitiveType_Sin, [this]() { arithmetic_self_run_ = "ElementSin"; }},
{PrimitiveType_LogicalNot, [this]() { arithmetic_self_run_ = "ElementLogicalNot"; }},
{PrimitiveType_Floor, [this]() { arithmetic_self_run_ = "ElementFloor"; }},
{PrimitiveType_Ceil, [this]() { arithmetic_self_run_ = "ElementCeil"; }},
{PrimitiveType_Round, [this]() { arithmetic_self_run_ = "ElementRound"; }},
{PrimitiveType_Neg, [this]() { arithmetic_self_run_ = "ElementNegative"; }},
};
auto iter = type_setters.find(parameter_->type_);
if (iter != type_setters.end()) {
iter->second();
} else {
MS_LOG(ERROR) << "Error Operator type " << parameter_;
return RET_ERROR;
}
MS_CHECK_RET_CODE(ReSize(), "ReSize failed");
return RET_OK;
}
int ArithmeticSelfFP32Coder::DoCode(CoderContext *const context) {
int task_id = 0;
int size = MSMIN(thread_sz_stride_, static_cast<int>(data_size_ - task_id * thread_sz_stride_));
MS_CHECK_TRUE(!arithmetic_self_run_.empty(), "arithmetic_run function is nullptr!");
Collect(context, {"nnacl/arithmetic_common.h", "nnacl/fp32/arithmetic_self.h"}, {"nnacl/fp32/arithmetic_self.c"});
nnacl::NNaclFp32Serializer code;
code.CodeFunction(arithmetic_self_run_, input_tensor_, output_tensor_, size);
MS_LOG(DEBUG) << "ArithmeticSelfFP32Coder has been called";
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Abs, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Cos, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Log, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Square, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Sqrt, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Rsqrt, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Sin, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_LogicalNot,
CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Floor, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Ceil, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Round, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Neg, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,109 @@
/**
* 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.
*/
#ifndef MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
#define MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
#include <string>
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/fp32/arithmetic_self_fp32.h"
#include "nnacl/arithmetic_self_parameter.h"
namespace mindspore::lite::micro {
using mindspore::schema::PrimitiveType_Abs;
using mindspore::schema::PrimitiveType_Add;
using mindspore::schema::PrimitiveType_AddN;
using mindspore::schema::PrimitiveType_Neg;
using mindspore::schema::PrimitiveType_Ceil;
using mindspore::schema::PrimitiveType_Cos;
using mindspore::schema::PrimitiveType_Div;
using mindspore::schema::PrimitiveType_Equal;
using mindspore::schema::PrimitiveType_Floor;
using mindspore::schema::PrimitiveType_FloorDiv;
using mindspore::schema::PrimitiveType_FloorMod;
using mindspore::schema::PrimitiveType_Greater;
using mindspore::schema::PrimitiveType_GreaterEqual;
using mindspore::schema::PrimitiveType_Less;
using mindspore::schema::PrimitiveType_LessEqual;
using mindspore::schema::PrimitiveType_Log;
using mindspore::schema::PrimitiveType_LogicalAnd;
using mindspore::schema::PrimitiveType_LogicalOr;
using mindspore::schema::PrimitiveType_LogicalNot;
using mindspore::schema::PrimitiveType_Maximum;
using mindspore::schema::PrimitiveType_Minimum;
using mindspore::schema::PrimitiveType_Mul;
using mindspore::schema::PrimitiveType_NotEqual;
using mindspore::schema::PrimitiveType_RealDiv;
using mindspore::schema::PrimitiveType_Round;
using mindspore::schema::PrimitiveType_Rsqrt;
using mindspore::schema::PrimitiveType_Sqrt;
using mindspore::schema::PrimitiveType_SquaredDifference;
using mindspore::schema::PrimitiveType_Sub;
using mindspore::schema::PrimitiveType_Sin;
using mindspore::schema::PrimitiveType_Square;
class ArithmeticSelfFP32Coder final : public OperatorCoder {
public:
ArithmeticSelfFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
~ArithmeticSelfFP32Coder() override = default;
private:
int ReSize();
private:
int thread_sz_count_{0};
int thread_sz_stride_{0};
size_t data_size_{0};
std::string arithmetic_self_run_;
};
} // namespace mindspore::lite::micro
#endif // MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_

View File

@ -0,0 +1,55 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/assign_add_fp32_coder.h"
#include <string>
#include "schema/inner/ops_generated.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
namespace mindspore::lite::micro {
using mindspore::schema::PrimitiveType_AssignAdd;
int AssignAddFP32Coder::Prepare(CoderContext *const context) { return RET_OK; }
int AssignAddFP32Coder::DoCode(CoderContext *const context) {
MS_CHECK_TRUE(input_tensors_.size() == 2, "inputs size is not equal to two");
Tensor *input0 = input_tensors_.at(0);
Tensor *input1 = input_tensors_.at(1);
if (input0->Size() != input1->Size()) {
MS_LOG(ERROR) << "input0 size: " << input0->Size() << ", input1 size: " << input1->Size();
return RET_ERROR;
}
nnacl::NNaclFp32Serializer code;
// Get Tensor Pointer
std::string input0_str = allocator_->GetRuntimeAddr(input0);
std::string input1_str = allocator_->GetRuntimeAddr(input1);
size_t data_size = input0->Size();
// assign add, just add input1'data to input0
code << "\t\tfor (int i = 0; i < " << data_size << "; ++i) {\n";
code << "\t\t\t(" << input0_str << ")[i] += (" << input1_str << ")[i];\n";
code << "\t\t}\n";
code.CodeFunction("memcpy", output_tensor_, input0_str, data_size);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_AssignAdd, CPUOpCoderCreator<AssignAddFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_AssignAdd, CPUOpCoderCreator<AssignAddFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,69 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/batchnorm_fp32_coder.h"
#include <string>
#include <vector>
#include "nnacl/fp32/batchnorm_fp32.h"
#include "src/ops/batch_norm.h"
#include "nnacl/op_base.h"
#include "micro/coder/opcoders/file_collector.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
using mindspore::schema::PrimitiveType_BatchNorm;
namespace mindspore::lite::micro {
int BatchnormFP32Coder::Init() {
auto bn_parameter = reinterpret_cast<BatchNormParameter *>(parameter_);
auto bn_prim = reinterpret_cast<const mindspore::lite::BatchNorm *>(OperatorCoder::primitive());
bn_parameter->epsilon_ = bn_prim->GetEpsilon();
std::vector<int> input_shapes = input_tensor_->shape();
if (input_shapes.empty()) {
return RET_ERROR;
}
int n_dim = static_cast<int>(input_shapes.size());
bn_parameter->channel_ = input_shapes.at(n_dim - 1);
bn_parameter->unit_ = 1;
for (int i = 0; i < n_dim - 1; i++) {
bn_parameter->unit_ *= input_shapes.at(i);
}
bn_parameter->op_parameter_.thread_num_ = MSMIN(bn_parameter->op_parameter_.thread_num_, bn_parameter->unit_);
return RET_OK;
}
int BatchnormFP32Coder::DoCode(CoderContext *const context) {
// attribute
int task_id = 0;
auto bn_parameter = reinterpret_cast<BatchNormParameter *>(parameter_);
if (Init() != RET_OK) {
MS_LOG(ERROR) << "BatchnormFP32Coder Init error";
return RET_ERROR;
}
MS_CHECK_TRUE(input_tensors_.size() == 3, "inputs size is not equal to three");
Tensor *mean_tensor = input_tensors_.at(1);
Tensor *var_tensor = input_tensors_.at(2);
Collect(context, {"nnacl/fp32/batchnorm.h"}, {"nnacl/fp32/batchnorm.c"});
nnacl::NNaclFp32Serializer code;
code.CodeStruct("bn_parameter", *bn_parameter);
code.CodeFunction("BatchNorm", output_tensor_, input_tensor_, mean_tensor, var_tensor, task_id, "&bn_parameter");
MS_LOG(INFO) << "BatchnormFP32Code has been called";
context->AppendCode(code.str());
return lite::RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_BatchNorm, CPUOpCoderCreator<BatchnormFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,43 @@
/**
* 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.
*/
#ifndef MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
#define MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
namespace mindspore::lite::micro {
class BatchnormFP32Coder final : public OperatorCoder {
public:
BatchnormFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~BatchnormFP32Coder() override = default;
int Prepare(CoderContext *const context) override { return RET_OK; }
int DoCode(CoderContext *const context) override;
private:
int Init();
};
} // namespace mindspore::lite::micro
#endif // MICRO_CODER_OPCODERS_FP32_CODER_H_

View File

@ -0,0 +1,77 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/concat_fp32_coder.h"
#include <string>
#include <vector>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Concat;
namespace mindspore::lite::micro {
int ConcatFP32Coder::Prepare(CoderContext *const context) {
concat_param_ = reinterpret_cast<ConcatParameter *>(parameter_);
return ReSize();
}
int ConcatFP32Coder::ReSize() {
axis_ = concat_param_->axis_ >= 0 ? concat_param_->axis_
: static_cast<int>(input_tensor_->shape().size()) + concat_param_->axis_;
return RET_OK;
}
int ConcatFP32Coder::DoCode(CoderContext *const context) {
Collect(context, {"nnacl/fp32/concat.h"}, {"nnacl/fp32/concat.c"});
size_t input_num = input_tensors_.size();
nnacl::NNaclFp32Serializer code;
code << "\t\tvoid *inputs_addr[] = {";
for (size_t i = 0; i < input_num; ++i) {
code << allocator_->GetRuntimeAddr(input_tensors_.at(i)) << ", ";
}
code << "};\n";
size_t i;
for (i = 0; i < input_num; ++i) {
code << "\t\tint shape_" << i << "[] = {";
for (auto &shape : input_tensors_.at(i)->shape()) {
code << shape << ", ";
}
code << "};\n";
}
code << "\t\tint shape_" << i << "[] = {";
for (auto &shape : output_tensor_->shape()) {
code << shape << ", ";
}
code << "};\n";
code << "\t\tint *inputs_output_shape[] = {";
for (i = 0; i <= input_num; ++i) {
code << "shape_" << i << ", ";
}
code << "};\n";
code.CodeFunction("Concat", "inputs_addr", input_num, axis_, "inputs_output_shape", output_tensor_->shape().size(),
output_tensor_, 0, thread_num_);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Concat, CPUOpCoderCreator<ConcatFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,42 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/concat_parameter.h"
namespace mindspore::lite::micro {
class ConcatFP32Coder : public OperatorCoder {
public:
ConcatFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ConcatFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
int ReSize();
int axis_{0};
ConcatParameter *concat_param_{nullptr};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_FP32_CODER_H_

View File

@ -0,0 +1,52 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/expand_dims_fp32_coder.h"
#include <string>
#include "micro/coder/opcoders/file_collector.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
using mindspore::schema::PrimitiveType_ExpandDims;
namespace mindspore::lite::micro {
int ExpandDimsFP32Coder::Prepare(CoderContext *const context) { return ReSize(); }
int ExpandDimsFP32Coder::ReSize() {
data_size_ = input_tensor_->ElementsNum();
thread_sz_count_ = MSMIN(thread_num_, static_cast<int>(data_size_));
MS_CHECK_TRUE(thread_sz_count_ > 0, "thread_sz_count_ is less or equal to 0");
thread_sz_stride_ = UP_DIV(data_size_, thread_sz_count_);
return RET_OK;
}
int ExpandDimsFP32Coder::DoCode(CoderContext *const context) {
// generate code .h .c
Collect(context, {"nnacl/fp32/expandDims.h"}, {"nnacl/fp32/expandDims.c"});
nnacl::NNaclFp32Serializer code;
int task_id = 0;
size_t size = MSMIN(thread_sz_stride_, static_cast<int>(data_size_ - task_id * thread_sz_stride_));
if (!size) {
return RET_OK;
}
code.CodeFunction("ExpandDims", input_tensor_, output_tensor_, size * sizeof(float));
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_ExpandDims, CPUOpCoderCreator<ExpandDimsFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_ExpandDims, CPUOpCoderCreator<ExpandDimsFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,42 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_EXPANDDIMS_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_EXPANDDIMS_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
namespace mindspore::lite::micro {
class ExpandDimsFP32Coder : public OperatorCoder {
public:
ExpandDimsFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ExpandDimsFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
int ReSize();
int thread_sz_count_{0};
int thread_sz_stride_{0};
size_t data_size_{0};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_EXPANDDIMS_FP32_CODER_H_

View File

@ -0,0 +1,69 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/gather_fp32_coder.h"
#include <string>
#include "nnacl/gather_parameter.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/log.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Gather;
namespace mindspore::lite::micro {
int GatherFP32Coder::Prepare(CoderContext *const context) { return RET_OK; }
int GatherFP32Coder::DoCode(CoderContext *context) {
Tensor *input0 = input_tensors_.at(0);
Tensor *input1 = input_tensors_.at(1);
// generate code .h .c
Collect(context, {"nnacl/fp32/gather.h"}, {"nnacl/fp32/gather.c"});
nnacl::NNaclFp32Serializer code;
std::vector<int> in_shape = input0->shape();
int in_rank = in_shape.size();
int indices_element_size = input1->ElementsNum();
int axis = (reinterpret_cast<GatherParameter *>(parameter_))->axis_;
MS_CHECK_TRUE(static_cast<int>(in_shape.size()) >= axis, "invalid axis in gather parameter");
const int limit = in_shape.at(axis);
int outer_size = 1, inner_size = 1;
for (int i = 0; i < axis; ++i) {
outer_size *= in_shape.at(i);
}
for (int i = axis + 1; i < in_rank; ++i) {
inner_size *= in_shape.at(i);
}
int task_id = 0;
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
int stride = UP_DIV(outer_size, thread_num_);
int count = MSMIN(stride, outer_size - stride * task_id);
// call the op function
if (input0->data_type() == kNumberTypeInt32) {
code.CodeFunction("GatherInt32", input0, count, inner_size, limit, input1, indices_element_size, output_tensor_);
} else {
code.CodeFunction("Gather", input0, count, inner_size, limit, input1, indices_element_size, output_tensor_);
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Gather, CPUOpCoderCreator<GatherFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,41 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_GATHER_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_GATHER_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/base/tile_base.h"
namespace mindspore::lite::micro {
class GatherFP32Coder : public OperatorCoder {
public:
GatherFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~GatherFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
int32_t *indices_{nullptr};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_GATHER_FP32_CODER_H_

View File

@ -0,0 +1,51 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/nchw2nhwc_fp32_coder.h"
#include <vector>
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Nchw2Nhwc;
namespace mindspore::lite::micro {
int Nchw2NhwcFP32Coder::Prepare(CoderContext *const context) { return RET_OK; }
int Nchw2NhwcFP32Coder::DoCode(CoderContext *context) {
// generate code .h .c
Collect(context, {"nnacl/pack.h"}, {"nnacl/pack.c"});
nnacl::NNaclFp32Serializer code;
if (input_tensor_->shape().size() == 4) {
if (input_tensor_->data_type() == kNumberTypeFloat32) {
code.CodeFunction("PackNCHWToNHWCFp32", input_tensor_, output_tensor_, output_tensor_->Batch(),
output_tensor_->Height() * output_tensor_->Width(), output_tensor_->Channel());
} else if (input_tensor_->data_type() == kNumberTypeInt8) {
code.CodeFunction("PackNCHWToNHWCInt8", input_tensor_, output_tensor_, output_tensor_->Batch(),
output_tensor_->Height() * output_tensor_->Width(), output_tensor_->Channel());
} else {
MS_LOG(ERROR) << "unsupported format transform";
}
} else {
code.CodeFunction("memcpy", output_tensor_, input_tensor_, input_tensor_->ElementsNum() * sizeof(float));
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Nchw2Nhwc, CPUOpCoderCreator<Nchw2NhwcFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,38 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_NCHW2FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NCHW2FP32_CODER_H_
#include <string>
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/base/tile_base.h"
namespace mindspore::lite::micro {
class Nchw2NhwcFP32Coder : public OperatorCoder {
public:
Nchw2NhwcFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~Nchw2NhwcFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_NCHW2FP32_CODER_H_

View File

@ -0,0 +1,50 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/nhwc2nchw_fp32_coder.h"
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Nhwc2Nchw;
namespace mindspore::lite::micro {
int Nhwc2NchwFP32Coder::Prepare(CoderContext *const context) { return RET_OK; }
int Nhwc2NchwFP32Coder::DoCode(CoderContext *const context) {
// generate code .h .c
Collect(context, {"nnacl/pack.h"}, {"pack.c"});
nnacl::NNaclFp32Serializer code;
if (input_tensor_->shape().size() == 4) {
if (input_tensor_->data_type() == kNumberTypeFloat32) {
code.CodeFunction("PackNHWCToNCHWFp32", input_tensor_, output_tensor_, output_tensor_->Batch(),
output_tensor_->Height() * output_tensor_->Width(), output_tensor_->Channel());
} else if (input_tensor_->data_type() == kNumberTypeInt8) {
code.CodeFunction("PackNHWCToNCHWInt8", input_tensor_, output_tensor_, output_tensor_->Batch(),
output_tensor_->Height() * output_tensor_->Width(), output_tensor_->Channel());
} else {
MS_LOG(ERROR) << "unsupported format transform";
}
} else {
code.CodeFunction("memcpy", output_tensor_, input_tensor_, input_tensor_->ElementsNum() * sizeof(float));
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Nhwc2Nchw, CPUOpCoderCreator<Nhwc2NchwFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,103 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/pad_fp32_coder.h"
#include <string>
#include <vector>
#include "micro/coder/log.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Pad;
namespace mindspore::lite::micro {
int PadFP32Coder::Prepare(CoderContext *const context) {
pad_param_ = reinterpret_cast<PadParameter *>(parameter_);
return ReSize();
}
int PadFP32Coder::ReSize() {
size_t rank = input_tensor_->shape().size();
if (rank > DEFAULT_PAD_NDIMS) {
MS_LOG(ERROR) << "Pad input rank should <= " << DEFAULT_PAD_NDIMS << ", got " << rank;
return RET_ERROR;
}
if (pad_param_->pad_mode_ == static_cast<int>(schema::PaddingMode_CONSTANT)) {
MS_CHECK_RET_CODE(ExtendShape(in_, DEFAULT_PAD_NDIMS, input_tensor_->shape().data(), rank),
"ExtendShape input error");
MS_CHECK_RET_CODE(ExtendShape(out_, DEFAULT_PAD_NDIMS, output_tensor_->shape().data(), rank),
"ExtendShape output error");
if (pad_param_->padding_length < MAX_PAD_SIZE) {
int ori_paddings[MAX_PAD_SIZE];
for (int i = 0; i < pad_param_->padding_length; ++i) {
ori_paddings[i] = pad_param_->paddings_[i];
}
MS_CHECK_RET_CODE(ExtendPaddings(pad_param_->paddings_, MAX_PAD_SIZE, ori_paddings, pad_param_->padding_length),
"Extendpadding error");
pad_param_->padding_length = MAX_PAD_SIZE;
}
}
return RET_OK;
}
int PadFP32Coder::ExtendShape(int *shape, int length, const int *ori_shape, int rank) {
MS_CHECK_PTR(shape);
MS_CHECK_PTR(ori_shape);
for (int i = 0; i < length - rank; ++i) {
shape[i] = 1;
}
for (int i = length - rank; i < length; ++i) {
shape[i] = ori_shape[i - (length - rank)];
}
return RET_OK;
}
int PadFP32Coder::ExtendPaddings(int *paddings, int length, const int *ori_paddings, int ori_length) {
MS_CHECK_PTR(paddings);
MS_CHECK_PTR(ori_paddings);
for (int i = 0; i < length - ori_length; ++i) {
paddings[i] = 0;
}
for (int i = length - ori_length; i < length; ++i) {
paddings[i] = ori_paddings[i - (length - ori_length)];
}
return RET_OK;
}
int PadFP32Coder::DoCode(CoderContext *const context) {
int task_id = thread_num_ - 1;
Collect(context, {"nnacl/fp32/pad.h", "nnacl/pad_parameter.h"}, {"nnacl/fp32/pad.c"});
nnacl::NNaclFp32Serializer code;
code.CodeArray("in_", in_, DEFAULT_PAD_NDIMS);
code.CodeArray("out_", out_, DEFAULT_PAD_NDIMS);
code.CodeArray("padding_", pad_param_->paddings_, MAX_PAD_SIZE);
int output_size = output_tensor_->ElementsNum();
if (pad_param_->constant_value_ - 0.0f < 1e-5) {
code.CodeFunction("memset", output_tensor_, "0", output_size * sizeof(float));
} else {
std::vector<float> constant_values(output_size, pad_param_->constant_value_);
code.CodeArray("output_tensor_", constant_values.data(), output_size);
}
code.CodeFunction("Pad", input_tensor_, output_tensor_, "in_", "out_", "padding_", task_id, thread_num_);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Pad, CPUOpCoderCreator<PadFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,49 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_PAD_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_PAD_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/fp32/pad_fp32.h"
namespace mindspore::lite::micro {
class PadFP32Coder : public OperatorCoder {
public:
PadFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~PadFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
int ReSize();
private:
int ExtendShape(int *shape, int length, const int *ori_shape, int rank);
int ExtendPaddings(int *paddings, int length, const int *ori_paddings, int ori_length);
protected:
PadParameter *pad_param_{nullptr};
int in_[DEFAULT_PAD_NDIMS]{0};
int out_[DEFAULT_PAD_NDIMS]{0};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_PAD_FP32_CODER_H_

View File

@ -0,0 +1,103 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/pooling_fp32_coder.h"
#include <cfloat>
#include <string>
#include "nnacl/fp32/pooling_fp32.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/log.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Pooling;
namespace mindspore::lite::micro {
int PoolingFP32Coder::DoCode(CoderContext *const context) {
// attribute
auto pooling_parameter = reinterpret_cast<PoolingParameter *>(parameter_);
int task_id = 0;
// init struct PoolingParameters
pooling_parameter->input_batch_ = input_tensor_->Batch();
pooling_parameter->input_channel_ = input_tensor_->Channel();
pooling_parameter->input_h_ = input_tensor_->Height();
pooling_parameter->input_w_ = input_tensor_->Width();
pooling_parameter->output_batch_ = output_tensor_->Batch();
pooling_parameter->output_channel_ = output_tensor_->Channel();
pooling_parameter->output_h_ = output_tensor_->Height();
pooling_parameter->output_w_ = output_tensor_->Width();
pooling_parameter->thread_num_ = pooling_parameter->op_parameter_.thread_num_;
nnacl::NNaclFp32Serializer code;
code.CodeStruct("pooling_parameter", *pooling_parameter);
float minf = -FLT_MAX;
float maxf = FLT_MAX;
if (pooling_parameter->pool_mode_ == PoolMode_MaxPool) {
Collect(context, {"nnacl/kernel/fp32/max_pooling_fp32_slim.h"}, {"max_pooling_fp32_slim.c"});
switch (pooling_parameter->act_type_) {
case ActType_Relu: {
minf = 0.f;
break;
}
case ActType_Relu6: {
minf = 0.f;
maxf = 6.f;
break;
}
default: {
MS_LOG(INFO) << "no actype";
break;
}
}
if (thread_num_ > 1) {
code.CodeBaseStruct("PoolingFp32Args", "args", input_tensor_, output_tensor_, "&pooling_parameter", minf, maxf);
CODE_PARALLEL_FUNC("MaxPoolingFp32Run");
} else {
code.CodeFunction("MaxPooling", input_tensor_, output_tensor_, "&pooling_parameter", task_id, minf, maxf);
}
} else {
Collect(context, {"nnacl/fp32/pooling.h"}, {"pooling.c"});
switch (pooling_parameter->act_type_) {
case ActType_Relu: {
minf = 0.f;
break;
}
case ActType_Relu6: {
minf = 0.f;
maxf = 6.f;
break;
}
default: {
MS_LOG(INFO) << "no actype";
break;
}
}
if (thread_num_ > 1) {
code.CodeBaseStruct("PoolingFp32Args", "args", input_tensor_, output_tensor_, "&pooling_parameter", minf, maxf);
CODE_PARALLEL_FUNC("AvgPoolingFp32Run");
} else {
code.CodeFunction("AvgPooling", input_tensor_, output_tensor_, "&pooling_parameter", task_id, minf, maxf);
}
}
MS_LOG(INFO) << "PoolingFp32Code has been called";
context->AppendCode(code.str());
return lite::RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Pooling, CPUOpCoderCreator<PoolingFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,60 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/power_fp32_coder.h"
#include <string>
#include <vector>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Power;
namespace mindspore::lite::micro {
int PowerFP32Coder::DoCode(CoderContext *const context) {
scale_ = reinterpret_cast<PowerParameter *>(parameter_)->scale_;
shift_ = reinterpret_cast<PowerParameter *>(parameter_)->shift_;
Tensor *filter_tensor = input_tensors_.at(kWeightIndex);
MS_CHECK_PTR(filter_tensor);
int size = input_tensor_->ElementsNum();
int task_id = 0;
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
int stride = UP_DIV(size, thread_num_);
int len = MSMIN(stride, size - stride * task_id);
std::string exp_addr;
bool broadcast = true;
if (input_tensors_.size() == 2) {
exp_addr = allocator_->GetRuntimeAddr(filter_tensor);
broadcast = !(input_tensor_->shape() == filter_tensor->shape());
}
std::string cur_exp_str;
if (broadcast) {
cur_exp_str = input_tensors_.size() == 2 ? exp_addr : "&power";
} else {
cur_exp_str = exp_addr;
}
// generate code .h .c
Collect(context, {"nnacl/power.h"}, {"power.c"});
nnacl::NNaclFp32Serializer code;
code.CodeFunction("Power", input_tensor_, cur_exp_str, output_tensor_, len, scale_, shift_, broadcast);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Power, CPUOpCoderCreator<PowerFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,42 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_POWER_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_POWER_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/power_parameter.h"
namespace mindspore::lite::micro {
class PowerFP32Coder : public OperatorCoder {
public:
PowerFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~PowerFP32Coder() override = default;
int Prepare(CoderContext *const context) override { return RET_OK; }
int DoCode(CoderContext *const context) override;
private:
float scale_{0.0f};
float shift_{0.0f};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_POWER_FP32_CODER_H_

View File

@ -0,0 +1,39 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/reshape_fp32_coder.h"
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Reshape;
namespace mindspore::lite::micro {
int ReshapeFP32Coder::DoCode(CoderContext *const context) {
size_t data_size = input_tensor_->Size();
Collect(context, {"nnacl/reshape.h"}, {"reshape.c"});
nnacl::NNaclFp32Serializer code;
code.CodeFunction("Reshape", input_tensor_, output_tensor_, data_size);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Reshape, CPUOpCoderCreator<ReshapeFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_Reshape, CPUOpCoderCreator<ReshapeFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,164 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/scale_fp32_coder.h"
#include <string>
#include "micro/coder/log.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Scale;
namespace mindspore::lite::micro {
ScaleFP32Coder::~ScaleFP32Coder() {
if (scale_param_->const_scale_) {
if (scale_) {
free(scale_);
scale_ = nullptr;
}
}
if (scale_param_->const_offset_) {
if (offset_) {
free(offset_);
offset_ = nullptr;
}
}
}
int ScaleFP32Coder::InitScaleOffset() {
Tensor *scale_tensor = input_tensors_.at(kWeightIndex);
MS_CHECK_PTR(scale_tensor);
if (reinterpret_cast<float *>(scale_tensor->data_c())) {
scale_param_->const_scale_ = true;
scale_ = reinterpret_cast<float *>(malloc(scale_tensor->ElementsNum() * sizeof(float)));
MS_CHECK_PTR(scale_);
MS_CHECK_TRUE(scale_tensor->Size() > 0, "invalid scale tensor size");
MS_CHECK_RET_CODE(memcpy_s(scale_, scale_tensor->Size(), scale_tensor->data_c(), scale_tensor->Size()),
"memcpy scale failed");
} else {
scale_param_->const_scale_ = false;
scale_ = nullptr;
}
if (input_tensors_.size() == 2) {
scale_param_->const_offset_ = true;
offset_ = reinterpret_cast<float *>(malloc(scale_tensor->ElementsNum() * sizeof(float)));
MS_CHECK_PTR(offset_);
MS_CHECK_RET_CODE(memset_s(offset_, scale_tensor->Size(), 0, scale_tensor->Size()), "memset_s failed!");
} else if (input_tensors_.size() == 3 && reinterpret_cast<float *>(input_tensors_.at(2)->data_c())) {
scale_param_->const_offset_ = true;
Tensor *offset_tensor = input_tensors_.at(2);
offset_ = reinterpret_cast<float *>(malloc(offset_tensor->ElementsNum() * sizeof(float)));
MS_CHECK_PTR(offset_);
MS_CHECK_TRUE(offset_tensor->Size() > 0, "invalid offset tensor size");
MS_CHECK_RET_CODE(memcpy_s(offset_, offset_tensor->Size(), offset_tensor->data_c(), offset_tensor->Size()),
"memcpy_s failed!");
} else {
scale_param_->const_offset_ = false;
offset_ = nullptr;
}
return RET_OK;
}
int ScaleFP32Coder::CalculateParameter() {
std::vector<int> in_shape = input_tensor_->shape();
Tensor *scale_tensor = input_tensors_.at(kWeightIndex);
MS_CHECK_PTR(scale_tensor);
std::vector<int> scale_shape = scale_tensor->shape();
if (scale_param_->axis_ < 0) {
scale_param_->axis_ = scale_param_->axis_ + in_shape.size();
}
if (scale_shape.size() + scale_param_->axis_ > in_shape.size()) {
MS_LOG(ERROR) << "Scale tensor shape is incorrect.";
return RET_ERROR;
}
scale_param_->outer_size_ = 1;
scale_param_->axis_size_ = 1;
scale_param_->inner_size_ = 1;
for (int i = 0; i < scale_param_->axis_; i++) {
scale_param_->outer_size_ *= in_shape.at(i);
}
for (size_t i = 0; i < scale_shape.size(); i++) {
if (in_shape.at(i + scale_param_->axis_) != scale_shape.at(i)) {
MS_LOG(ERROR) << "Scale tensor shape is incorrect.";
return RET_ERROR;
}
scale_param_->axis_size_ *= in_shape.at(i + scale_param_->axis_);
}
for (size_t i = scale_param_->axis_ + scale_shape.size(); i < in_shape.size(); i++) {
scale_param_->inner_size_ *= in_shape.at(i);
}
scale_param_->op_parameter_.thread_num_ = MSMIN(scale_param_->op_parameter_.thread_num_, scale_param_->outer_size_);
return RET_OK;
}
int ScaleFP32Coder::Prepare(CoderContext *const context) {
this->scale_param_ = reinterpret_cast<ScaleParameter *>(parameter_);
if (input_tensors_.size() < 2 || input_tensors_.size() > 3) {
MS_LOG(ERROR) << "inputs to Scale operator should be 2 or 3, but " << input_tensors_.size() << " is given.";
return RET_ERROR;
}
MS_CHECK_RET_CODE(InitScaleOffset(), "Scale fp32 InitScaleOffset failed.");
return ReSize();
}
int ScaleFP32Coder::ReSize() {
MS_CHECK_RET_CODE(CalculateParameter(), "Scale fp32 CalculateParameter failed.");
return RET_OK;
}
int ScaleFP32Coder::DoCode(CoderContext *const context) {
// init struct ScaleParameters
Tensor *scale_tensor = input_tensors_.at(kWeightIndex);
Tensor *offset_tensor = input_tensors_.at(kBiasIndex);
MS_CHECK_PTR(scale_tensor);
MS_CHECK_PTR(offset_tensor);
Collect(context, {"nnacl/scale.h", "nnacl/fp32/scale.h", "nnacl/quantization/quantize.h"}, {"scale.c"});
nnacl::NNaclFp32Serializer code;
code.CodeStruct("scale_parameter", *scale_param_);
if (thread_num_ > 1) {
code.CodeBaseStruct("ScaleFp32Args", "args", input_tensor_, output_tensor_, scale_tensor, offset_tensor,
"&scale_parameter");
CODE_PARALLEL_FUNC("ScaleFp32Run");
} else {
int task_id = 0;
switch (scale_param_->activation_type_) {
case schema::ActivationType_RELU6:
code.CodeFunction("DoScaleRelu6", input_tensor_, output_tensor_, scale_tensor, offset_tensor, task_id,
"&scale_parameter");
break;
case schema::ActivationType_RELU:
code.CodeFunction("DoScaleRelu", input_tensor_, output_tensor_, scale_tensor, offset_tensor, task_id,
"&scale_parameter");
break;
case schema::ActivationType_NO_ACTIVATION:
code.CodeFunction("DoScale", input_tensor_, output_tensor_, scale_tensor, offset_tensor, task_id,
"&scale_parameter");
break;
default:
MS_LOG(ERROR) << "Scale does not support activation type " << scale_param_->activation_type_;
return RET_ERROR;
}
}
MS_LOG(INFO) << "ScaleFP32Code has been called";
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Scale, CPUOpCoderCreator<ScaleFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,49 @@
/**
* 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.
*/
#ifndef MICRO_CODER_OPCODERS_FP32_SCALEFP32_CODER_H_
#define MICRO_CODER_OPCODERS_FP32_SCALEFP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/scale.h"
namespace mindspore::lite::micro {
class ScaleFP32Coder final : public OperatorCoder {
public:
ScaleFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ScaleFP32Coder() override;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
int ReSize();
int CalculateParameter();
int InitScaleOffset();
private:
ScaleParameter *scale_param_{nullptr};
float *scale_{nullptr};
float *offset_{nullptr};
};
} // namespace mindspore::lite::micro
#endif // MICRO_CODER_OPCODERS_FP32__CODER_H_

View File

@ -0,0 +1,74 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/slice_fp32_coder.h"
#include <string>
#include "nnacl/slice_parameter.h"
#include "src/ops/slice.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Slice;
namespace mindspore::lite::micro {
int SliceFP32Coder::Prepare(CoderContext *const context) { return RET_OK; }
int SliceFP32Coder::DoCode(CoderContext *const context) {
// generate code .h .c
Collect(context, {"nnacl/slice_parameter.h", "nnacl/fp32/slice.h"}, {"slice.c"});
auto param = reinterpret_cast<SliceParameter *>(parameter_);
auto primitive_slice = reinterpret_cast<const mindspore::lite::Slice *>(OperatorCoder::primitive());
std::vector<int> begin = primitive_slice->GetPostProcessBegin();
std::vector<int> size = primitive_slice->GetPostProcessSize();
std::vector<int> input_shape = input_tensor_->shape();
nnacl::NNaclFp32Serializer code;
for (int i = 0; i < param->param_length_; i++) {
param->shape_[i] = input_shape.at(i);
}
for (int i = 0; i < param->param_length_; i++) {
param->begin_[i] = begin.at(i);
}
for (int i = 0; i < param->param_length_; i++) {
int tmp_size = size.at(i);
if (size.at(i) < 0) {
tmp_size = input_shape.at(i) - begin.at(i);
}
param->end_[i] = (begin.at(i) + tmp_size);
}
for (int i = 0; i < param->param_length_; i++) {
if (size.at(i) < 0) {
param->size_[i] = (input_shape.at(i) - begin.at(i));
continue;
}
param->size_[i] = size.at(i);
}
code.CodeStruct("slice_parameter", *param);
// call the op function
if (param->param_length_ < DIMENSION_4D) {
code.CodeFunction("PadSliceParameterTo4D", "&slice_parameter");
}
code.CodeFunction("DoSliceNoParallel", input_tensor_, output_tensor_, "&slice_parameter");
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Slice, CPUOpCoderCreator<SliceFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,45 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/squeeze_dims_fp32_coder.h"
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Squeeze;
namespace mindspore::lite::micro {
int SqueezeFP32Coder::DoCode(CoderContext *const context) {
size_t data_size = input_tensor_->Size();
// generate code .h .c
Collect(context, {"nnacl/squeeze.h"}, {"nnacl/squeeze.c"});
nnacl::NNaclFp32Serializer code;
// call the op function
if (input_tensor_->data_type() == kNumberTypeInt32) {
code.CodeFunction("DoSqueezeInt32", input_tensor_, output_tensor_, data_size);
} else {
code.CodeFunction("DoSqueeze", input_tensor_, output_tensor_, data_size);
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Squeeze, CPUOpCoderCreator<SqueezeFP32Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,68 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/tile_fp32_coder.h"
#include <string>
#include <type_traits>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Tile;
namespace mindspore::lite::micro {
void TileFP32Coder::ComputeStrides(const int *shape, int *strides, int ndim) const {
int stride = 1;
for (int i = ndim - 1; i >= 0; i--) {
strides[i] = stride;
stride *= shape[i];
}
}
int TileFP32Coder::Resize() {
tile_param_ = reinterpret_cast<TileParameter *>(parameter_);
MS_CHECK_TRUE(tile_param_->in_dim_ < static_cast<int>(std::extent<decltype(tile_param_->in_dim_)>::value),
"invalid dims count");
MS_CHECK_TRUE(static_cast<int>(input_tensor_->shape().size()) < tile_param_->in_dim_, "invalid input shape number.");
MS_CHECK_TRUE(static_cast<int>(output_tensor_->shape().size()) < tile_param_->in_dim_,
"invalid output shape number.");
for (int i = 0; i < tile_param_->in_dim_; ++i) {
tile_param_->in_shape_[i] = input_tensor_->shape().at(i);
tile_param_->out_shape_[i] = output_tensor_->shape().at(i);
}
ComputeStrides(tile_param_->in_shape_, tile_param_->in_strides_, tile_param_->in_dim_);
ComputeStrides(tile_param_->out_shape_, tile_param_->out_strides_, tile_param_->in_dim_);
return RET_OK;
}
int TileFP32Coder::Prepare(CoderContext *const context) { return Resize(); }
int TileFP32Coder::DoCode(CoderContext *const context) {
// generate code .h .c
Collect(context, {"nnacl/fp32/tile.h"}, {"nnacl/fp32/tile.c"});
nnacl::NNaclFp32Serializer code;
code.CodeStruct("tile_parameter", *tile_param_);
// call the op function
code.CodeFunction("Tile", input_tensor_, output_tensor_, "&tile_parameter");
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Tile, CPUOpCoderCreator<TileFP32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,43 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_TILE_FP32_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_TILE_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/base/tile_base.h"
namespace mindspore::lite::micro {
class TileFP32Coder : public OperatorCoder {
public:
TileFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~TileFP32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
void ComputeStrides(const int *shape, int *strides, int ndim) const;
int Resize();
TileParameter *tile_param_{nullptr};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_TILE_FP32_CODER_H_

View File

@ -0,0 +1,94 @@
/**
* 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 "micro/coder/opcoders/nnacl/fp32/transpose_fp32_coder.h"
#include <vector>
#include <string>
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using mindspore::schema::PrimitiveType_Transpose;
namespace mindspore::lite::micro {
int TransposeFp32Coder::Resize() {
num_unit_ = static_cast<int>(input_tensor_->shape().at(transpose_parameter_->perm_[kNHWC_H]));
thread_h_num_ = MSMIN(thread_num_, num_unit_);
MS_CHECK_TRUE(thread_h_num_ > 0, "thread_h_num_ <= 0");
thread_h_stride_ = UP_DIV(num_unit_, thread_h_num_);
std::vector<int> in_shape = input_tensor_->shape();
std::vector<int> out_shape = output_tensor_->shape();
transpose_parameter_->strides_[transpose_parameter_->num_axes_ - 1] = 1;
transpose_parameter_->out_strides_[transpose_parameter_->num_axes_ - 1] = 1;
transpose_parameter_->data_size_ = static_cast<int>(input_tensor_->Size());
for (int i = transpose_parameter_->num_axes_ - 2; i >= 0; i--) {
transpose_parameter_->strides_[i] = in_shape.at(i + 1) * transpose_parameter_->strides_[i + 1];
transpose_parameter_->out_strides_[i] = out_shape.at(i + 1) * transpose_parameter_->out_strides_[i + 1];
}
MS_CHECK_TRUE(in_shape.size() > 0, "invalid shape size");
MS_CHECK_TRUE(out_shape.size() > 0, "invalid shape size");
auto in_shape_data_size = static_cast<size_t>(in_shape.size() * sizeof(int));
auto out_shape_data_size = static_cast<size_t>(out_shape.size() * sizeof(int));
in_shape_ = reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt, in_shape_data_size, kOfflinePackWeight));
MS_CHECK_PTR(in_shape_);
out_shape_ =
reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt, out_shape.size() * sizeof(int), kOfflinePackWeight));
MS_CHECK_PTR(out_shape_);
MS_CHECK_RET_CODE(memcpy_s(in_shape_, in_shape_data_size, in_shape.data(), in_shape_data_size), "memcpy failed");
MS_CHECK_RET_CODE(memcpy_s(out_shape_, out_shape_data_size, out_shape.data(), out_shape_data_size), "memcpy failed");
return RET_OK;
}
int TransposeFp32Coder::Init() {
transpose_parameter_ = reinterpret_cast<TransposeParameter *>(parameter_);
MS_CHECK_PTR(transpose_parameter_);
return Resize();
}
int TransposeFp32Coder::Prepare(CoderContext *const context) {
MS_CHECK_RET_CODE(Init(), "init failed");
int out_dims = static_cast<int>(output_tensor_->shape().size());
auto out_data_dims_size = static_cast<size_t>(out_dims * thread_h_num_ * sizeof(int));
if (out_dims > MAX_TRANSPOSE_DIM_SIZE) {
dim_size_ = reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt, out_data_dims_size, kWorkspace));
MS_CHECK_PTR(dim_size_);
position_ = reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt, out_data_dims_size, kWorkspace));
MS_CHECK_PTR(position_);
}
return RET_OK;
}
int TransposeFp32Coder::DoCode(CoderContext *const context) {
int task_id = 0;
int num_unit_thread = MSMIN(thread_h_stride_, num_unit_ - task_id * thread_h_stride_);
if (num_unit_thread <= 0) {
return RET_OK;
}
Collect(context, {"nnacl/transpose.h", "nnacl/fp32/transpose.h", "nnacl/errorcode.h"}, {"transpose.c"});
nnacl::NNaclFp32Serializer code;
code.CodeStruct("transpose_parameter", *transpose_parameter_);
code.CodeFunction("DoTransposeFp32", input_tensor_, output_tensor_, in_shape_, out_shape_, "&transpose_parameter",
task_id, num_unit_thread, dim_size_, position_);
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Transpose, CPUOpCoderCreator<TransposeFp32Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,53 @@
/**
* 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.
*/
#ifndef MICRO_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
#define MICRO_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/transpose.h"
namespace mindspore::lite::micro {
class TransposeFp32Coder final : public OperatorCoder {
public:
TransposeFp32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~TransposeFp32Coder() override = default;
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
int Resize();
int Init();
private:
TransposeParameter *transpose_parameter_ = nullptr;
int thread_num_ = 1;
int thread_h_stride_ = 0;
int thread_h_num_ = 0;
int num_unit_ = 0;
int *in_shape_ = nullptr;
int *out_shape_ = nullptr;
int *dim_size_ = nullptr;
int *position_ = nullptr;
};
} // namespace mindspore::lite::micro
#endif // MICRO_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_

View File

@ -0,0 +1,114 @@
/**
* 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 "micro/coder/opcoders/nnacl/int8/concat_int8_coder.h"
#include <limits>
#include "nnacl/int8/concat_int8.h"
#include "nnacl/int8/arithmetic_int8.h"
#include "nnacl/int8/quantize.h"
#include "micro/coder/opcoders/file_collector.h"
#include "micro/coder/log.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
int MallocQuantArgForConcat(ConcatQuantArg *quant_arg, size_t input_num) {
quant_arg->in_args_ = static_cast<QuantArg *>(malloc(sizeof(QuantArg) * input_num));
MS_CHECK_PTR(quant_arg->in_args_);
return mindspore::lite::RET_OK;
}
using mindspore::schema::PrimitiveType_Concat;
namespace mindspore::lite::micro {
int ConcatInt8Coder::Prepare(CoderContext *const context) {
this->concat_param_ = reinterpret_cast<ConcatParameter *>(parameter_);
concat_param_->input_shapes_ = nullptr;
size_t input_num = input_tensors().size();
MS_CHECK_PTR(input_data_);
MS_CHECK_RET_CODE(MallocQuantArgForConcat(&concat_param_->quant_arg_, input_num),
"Null pointer reference: quant_concat_parm_->in_quant_args_.");
for (int i = 0; i < static_cast<int>(input_num); i++) {
auto *input_tensor = input_tensors().at(i);
auto quant_args = input_tensor->quant_params();
concat_param_->quant_arg_.in_args_[i].scale_ = quant_args.at(0).scale;
concat_param_->quant_arg_.in_args_[i].zp_ = quant_args.at(0).zeroPoint;
}
auto quant_args = output_tensor_->quant_params();
concat_param_->quant_arg_.out_args_.scale_ = quant_args.at(0).scale;
concat_param_->quant_arg_.out_args_.zp_ = quant_args.at(0).zeroPoint;
concat_param_->quant_arg_.output_activation_min_ = std::numeric_limits<int8_t>::min();
concat_param_->quant_arg_.output_activation_max_ = std::numeric_limits<int8_t>::max();
// concat base resize
axis_ = concat_param_->axis_ >= 0 ? concat_param_->axis_ : input_tensor_->shape().size() + concat_param_->axis_;
// concat int8 resize
concat_param_->input_num_ = input_num;
concat_param_->input_shapes_ = reinterpret_cast<int **>(malloc(sizeof(int *) * input_num));
MS_CHECK_PTR(concat_param_->input_shapes_);
for (int i = 0; i < static_cast<int>(input_num); i++) {
concat_param_->input_shapes_[i] = reinterpret_cast<int *>(input_tensors().at(i)->shape().data());
}
before_axis_size = 1;
for (int i = 0; i < axis_ && i < static_cast<int>(output_tensor_->shape().size()); i++) {
before_axis_size *= output_tensor_->DimensionSize(i);
}
int64_t after_axis_size = 1;
int output_dim = static_cast<int>(output_tensor_->shape().size());
concat_param_->output_shapes_ = output_tensor_->shape().data();
for (int i = axis_ + 1; i < output_dim; i++) {
after_axis_size *= concat_param_->output_shapes_[i];
}
concat_param_->after_axis_size = after_axis_size;
return RET_OK;
}
int ConcatInt8Coder::DoCode(CoderContext *const context) {
concat_param_->thread_count_ = thread_num_;
MS_CHECK_TRUE(thread_num_ > 0, "thread_num_ <= 0");
count_unit_ = thread_num_ > 1 ? UP_DIV(before_axis_size, thread_num_) : before_axis_size;
concat_param_->count_unit_ = count_unit_;
Collect(context, {"nnacl/int8/concat_int8.h"}, {"concat_int8.c"});
nnacl::NNaclInt8Serializer code;
int in_tensor_count = input_tensors().size();
code << "int8_t *input_data[" << in_tensor_count << "];\n";
// input data
for (int i = 0; i < static_cast<int>(input_tensors().size()); ++i) {
MS_CHECK_PTR(input_tensors().at(i));
code << "input_data[" << i << "] = " << allocator_->GetRuntimeAddr(input_tensors().at(i)) << ";\n";
}
code.CodeStruct("concat_param", *concat_param_, in_tensor_count, input_tensor_->shape().size(),
output_tensor_->shape().size());
if (thread_num_ > 1) {
code.CodeBaseStruct("ConcatInt8Args", "args", "input_data", output_tensor_, "&concat_param", axis_,
before_axis_size, count_unit_);
code.CodeFunction("ParallelLaunch", "THREAD_POOL_DEFAULT", "ConcatInt8Run", "&args", "thread_num");
} else {
int task_id = 0;
int64_t real_dst_count = MSMIN(before_axis_size - task_id * count_unit_, count_unit_);
code.CodeFunction("Int8Concat", "input_data", output_tensor_, "&concat_param", axis_, real_dst_count, task_id);
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt8, PrimitiveType_Concat, CPUOpCoderCreator<ConcatInt8Coder>)
} // namespace mindspore::lite::micro

View File

@ -0,0 +1,56 @@
/**
* 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.
*/
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_INT8_CODER_H_
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_INT8_CODER_H_
#include <cstring>
#include <vector>
#include "micro/coder/opcoders/op_coder.h"
#include "nnacl/int8/concat_int8.h"
namespace mindspore::lite::micro {
class ConcatInt8Coder : public OperatorCoder {
public:
ConcatInt8Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
const Model::Node *node, size_t node_index, Target target)
: OperatorCoder(in_tensors, out_tensors, node, node_index, target) {}
~ConcatInt8Coder() {
if (concat_param_ == nullptr) {
return;
}
if (concat_param_->quant_arg_.in_args_ != nullptr) {
free(concat_param_->quant_arg_.in_args_);
}
if (concat_param_->input_shapes_ != nullptr) {
free(concat_param_->input_shapes_);
}
}
int Prepare(CoderContext *const context) override;
int DoCode(CoderContext *const context) override;
private:
ConcatParameter *concat_param_{nullptr};
int64_t before_axis_size{0};
int64_t count_unit_{0};
int8_t *input_data_{nullptr};
int axis_ = 0;
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_CONCAT_INT8_CODER_H_

View File

@ -0,0 +1,82 @@
/**
* 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 "micro/coder/opcoders/nnacl/int8/pooling_int8_coder.h"
#include <memory>
#include <string>
#include <vector>
#include "nnacl/int8/pooling_int8.h"
#include "micro/coder/log.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
#include "micro/coder/opcoders/file_collector.h"
using std::string;
using mindspore::schema::PrimitiveType_Pooling;
namespace mindspore::lite::micro {
int PoolingInt8Coder::DoCode(CoderContext *const context) {
// attribute
auto *pooling_parameter = reinterpret_cast<PoolingParameter *>(parameter_);
MS_CHECK_PTR(pooling_parameter);
// init struct PoolingParameters
Tensor *in_tensor = input_tensors_.at(kInputIndex);
Tensor *out_tensor = output_tensors_.at(kOutputIndex);
MS_CHECK_PTR(in_tensor);
MS_CHECK_PTR(out_tensor);
pooling_parameter->input_batch_ = in_tensor->Batch();
pooling_parameter->input_channel_ = in_tensor->Channel();
pooling_parameter->input_h_ = in_tensor->Height();
pooling_parameter->input_w_ = in_tensor->Width();
pooling_parameter->output_batch_ = out_tensor->Batch();
pooling_parameter->output_channel_ = out_tensor->Channel();
pooling_parameter->output_h_ = out_tensor->Height();
pooling_parameter->output_w_ = out_tensor->Width();
// get quant params
std::vector<QuantArg> in_quant_args = in_tensor->quant_params();
std::vector<QuantArg> out_quant_args = out_tensor->quant_params();
Collect(context, {"nnacl/int8/pooling_int8.h", "nnacl/errorcode.h"}, {"pooling_int8.c"});
nnacl::NNaclInt8Serializer code;
code.precision(kPrecision);
// code op parameter
::QuantArg quant_arg_in = {static_cast<float>(in_quant_args.at(0).scale), in_quant_args.at(0).zeroPoint};
::QuantArg quant_arg_out = {static_cast<float>(out_quant_args.at(0).scale), out_quant_args.at(0).zeroPoint};
::QuantArg *quant_args[2] = {&quant_arg_in, &quant_arg_out};
pooling_parameter->quant_args_ = quant_args;
code.CodeStruct("pooling_parameter", *pooling_parameter);
if (thread_num_ > 1) {
code.CodeBaseStruct("PoolingInt8Args", "args", in_tensor, out_tensor, "(PoolingParameter *)&pooling_parameter");
if (pooling_parameter->pool_mode_ == PoolMode_MaxPool) {
code.CodeFunction("ParallelLaunch", "THREAD_POOL_DEFAULT", "MaxPoolingInt8Run", "&args", "thread_num");
} else {
code.CodeFunction("ParallelLaunch", "THREAD_POOL_DEFAULT", "AvgPoolingInt8Run", "&args", "thread_num");
}
} else {
int task_id = 0;
if (pooling_parameter->pool_mode_ == PoolMode_MaxPool) {
code.CodeFunction("MaxPoolingInt8", in_tensor, out_tensor, "(PoolingParameter *)&pooling_parameter", task_id);
} else {
code.CodeFunction("AvgPoolingInt8", in_tensor, out_tensor, "(PoolingParameter *)&pooling_parameter", task_id);
}
}
MS_LOG(INFO) << "PoolingInt8Code has been called";
context->AppendCode(code.str());
return lite::RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt8, PrimitiveType_Pooling, CPUOpCoderCreator<PoolingInt8Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,58 @@
/**
* 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 "micro/coder/opcoders/nnacl/int8/reshape_int8_coder.h"
#include <vector>
#include <string>
#include "micro/coder/opcoders/file_collector.h"
#include "micro/coder/log.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
using mindspore::schema::PrimitiveType_Reshape;
namespace mindspore::lite::micro {
int ReshapeInt8Coder::DoCode(CoderContext *const context) {
Tensor *input = OperatorCoder::input_tensors().at(kInputIndex);
Tensor *output = OperatorCoder::output_tensors().at(kOutputIndex);
MS_CHECK_PTR(input);
MS_CHECK_PTR(output);
int elements_num = input->ElementsNum();
std::vector<QuantArg> input_quant_args = input->quant_params();
std::vector<QuantArg> output_quant_args = output->quant_params();
Collect(context, {"nnacl/int8/reshape_int8.h"}, {"reshape_int8.c"});
nnacl::NNaclInt8Serializer code;
code.precision(kPrecision);
ReshapeQuantArg reshape_quant_arg = {
{static_cast<float>(input_quant_args.at(0).scale), input_quant_args.at(0).zeroPoint},
{static_cast<float>(output_quant_args.at(0).scale), output_quant_args.at(0).zeroPoint},
INT8_MIN,
INT8_MAX};
code.CodeStruct("reshape_quant_arg", reshape_quant_arg);
if (thread_num_ > 1) {
code.CodeBaseStruct("ReshapeInt8Args", "args", input, output, elements_num, thread_num_s_, "reshape_quant_arg");
CODE_PARALLEL_FUNC("ReshapeInt8Run");
} else {
code.CodeFunction("Int8Reshape", input, output, elements_num, "reshape_quant_arg");
}
context->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt8, PrimitiveType_Reshape, CPUOpCoderCreator<ReshapeInt8Coder>)
} // namespace mindspore::lite::micro

View File

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

View File

@ -0,0 +1,94 @@
/**
* 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 "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
#include "src/common/log_adapter.h"
#include "micro/coder/log.h"
#include "nnacl/pooling_parameter.h"
namespace mindspore::lite::micro::nnacl {
void NNaclFp32Serializer::CodeStruct(const std::string &name, const PoolingParameter &pooling_parameter) {
CodeBaseStruct("PoolingParameter", name, pooling_parameter.op_parameter_, pooling_parameter.pool_mode_,
pooling_parameter.round_mode_, pooling_parameter.act_type_, pooling_parameter.avg_mode_,
pooling_parameter.global_, pooling_parameter.window_w_, pooling_parameter.window_h_,
pooling_parameter.stride_w_, pooling_parameter.stride_h_, pooling_parameter.input_w_,
pooling_parameter.input_w_, pooling_parameter.input_batch_, pooling_parameter.input_channel_,
pooling_parameter.output_w_, pooling_parameter.output_h_, pooling_parameter.output_batch_,
pooling_parameter.output_channel_, pooling_parameter.pad_u_, pooling_parameter.pad_d_,
pooling_parameter.pad_l_, pooling_parameter.pad_r_, pooling_parameter.thread_num_, "NULL",
pooling_parameter.quantize_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const BatchNormParameter &batch_norm_parameter) {
CodeBaseStruct("BatchNormParameter", name, batch_norm_parameter.op_parameter_, batch_norm_parameter.epsilon_,
batch_norm_parameter.momentum_, batch_norm_parameter.unit_, batch_norm_parameter.units_,
batch_norm_parameter.channel_, batch_norm_parameter.fused_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const ArithmeticParameter &arithmetic_parameter) {
CodeBaseStruct("ArithmeticParameter", name, arithmetic_parameter.op_parameter_, arithmetic_parameter.broadcasting_,
arithmetic_parameter.ndim_, arithmetic_parameter.activation_type_,
ToString(arithmetic_parameter.in_shape0_), arithmetic_parameter.in_elements_num0_,
ToString(arithmetic_parameter.in_shape1_), arithmetic_parameter.in_elements_num1_,
ToString(arithmetic_parameter.out_shape_), arithmetic_parameter.out_elements_num_,
ToString(arithmetic_parameter.in_strides0_), ToString(arithmetic_parameter.in_strides1_),
ToString(arithmetic_parameter.out_strides_), ToString(arithmetic_parameter.multiples0_),
ToString(arithmetic_parameter.multiples1_));
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const SoftmaxParameter &softmax_parameter) {
CodeBaseStruct("SoftmaxParameter", name, softmax_parameter.op_parameter_, softmax_parameter.axis_,
ToString(softmax_parameter.input_shape_), softmax_parameter.element_size_, softmax_parameter.n_dim_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const ConvParameter &conv_parameter) {
CodeBaseStruct("ConvParameter", name, conv_parameter.op_parameter_, "{NULL}", conv_parameter.kernel_h_,
conv_parameter.kernel_w_, conv_parameter.stride_h_, conv_parameter.stride_w_,
conv_parameter.dilation_h_, conv_parameter.dilation_w_, conv_parameter.pad_u_, conv_parameter.pad_d_,
conv_parameter.pad_l_, conv_parameter.pad_r_, conv_parameter.group_, conv_parameter.tile_num_,
conv_parameter.input_batch_, conv_parameter.input_h_, conv_parameter.input_w_,
conv_parameter.input_channel_, conv_parameter.output_batch_, conv_parameter.output_h_,
conv_parameter.output_w_, conv_parameter.output_channel_, conv_parameter.op_parameter_.thread_num_,
conv_parameter.input_unit_, conv_parameter.output_unit_, conv_parameter.act_type_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const ScaleParameter &scale_parameter) {
CodeBaseStruct("ScaleParameter", name, scale_parameter.op_parameter_, scale_parameter.outer_size_,
scale_parameter.axis_size_, scale_parameter.inner_size_, scale_parameter.axis_,
scale_parameter.const_scale_, scale_parameter.const_offset_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const SliceParameter &slice_parameter) {
CodeBaseStruct("SliceParameter", name, slice_parameter.op_parameter_, ToString(slice_parameter.shape_),
ToString(slice_parameter.begin_), ToString(slice_parameter.end_), ToString(slice_parameter.size_),
"{0}", slice_parameter.param_length_);
}
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_),
ToString(tile_parameter.in_strides_), ToString(tile_parameter.out_strides_), tile_parameter.in_dim_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const TransposeParameter &transpose_parameter) {
CodeBaseStruct("TransposeParameter", name, transpose_parameter.op_parameter_, ToString(transpose_parameter.perm_),
transpose_parameter.conjugate_, ToString(transpose_parameter.strides_),
ToString(transpose_parameter.out_strides_), transpose_parameter.num_axes_,
transpose_parameter.data_size_);
}
} // namespace mindspore::lite::micro::nnacl

View File

@ -0,0 +1,51 @@
/**
* 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.
*/
#ifndef MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_FP32_SERIALIZER_H_
#define MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_FP32_SERIALIZER_H_
#include <string>
#include <sstream>
#include "micro/coder/opcoders/serializers/serializer.h"
#include "nnacl/batchnorm_parameter.h"
#include "nnacl/fp32/arithmetic_fp32.h"
#include "nnacl/conv_parameter.h"
#include "nnacl/matmul_parameter.h"
#include "nnacl/scale.h"
#include "nnacl/slice_parameter.h"
#include "nnacl/base/tile_base.h"
#include "nnacl/fp32/transpose_fp32.h"
#include "nnacl/pooling_parameter.h"
#include "nnacl/softmax_parameter.h"
namespace mindspore::lite::micro::nnacl {
class NNaclFp32Serializer : public Serializer {
public:
NNaclFp32Serializer() = default;
~NNaclFp32Serializer() = default;
void CodeStruct(const std::string &name, const PoolingParameter &pooling_parameter);
void CodeStruct(const std::string &name, const SoftmaxParameter &softmax_parameter);
void CodeStruct(const std::string &name, const BatchNormParameter &batch_norm_parameter);
void CodeStruct(const std::string &name, const ArithmeticParameter &arithmetic_parameter);
void CodeStruct(const std::string &name, const ConvParameter &conv_parameter);
void CodeStruct(const std::string &name, const MatMulParameter &mat_mul_parameter);
void CodeStruct(const std::string &name, const ScaleParameter &scale_parameter);
void CodeStruct(const std::string &name, const SliceParameter &slice_parameter);
void CodeStruct(const std::string &name, const TileParameter &tile_parameter);
void CodeStruct(const std::string &name, const TransposeParameter &transpose_parameter);
};
} // namespace mindspore::lite::micro::nnacl
#endif // MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_FP32_ERIALIZER_H_

View File

@ -0,0 +1,119 @@
/**
* 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 "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
#include <string>
#include "src/common/log_adapter.h"
#include "micro/coder/log.h"
namespace mindspore::lite::micro::nnacl {
void NNaclInt8Serializer::CodeStruct(const std::string &name, const ArithmeticParameter &arithmetic_parameter) {
CodeBaseStruct("ArithmeticParameter", name, arithmetic_parameter.op_parameter_, arithmetic_parameter.broadcasting_,
arithmetic_parameter.ndim_, arithmetic_parameter.activation_type_,
ToString(arithmetic_parameter.in_shape0_), arithmetic_parameter.in_elements_num0_,
ToString(arithmetic_parameter.in_shape1_), arithmetic_parameter.in_elements_num1_,
ToString(arithmetic_parameter.out_shape_), arithmetic_parameter.out_elements_num_,
ToString(arithmetic_parameter.in_strides0_), ToString(arithmetic_parameter.in_strides1_),
ToString(arithmetic_parameter.out_strides_), ToString(arithmetic_parameter.multiples0_),
ToString(arithmetic_parameter.multiples1_));
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const PoolingParameter &pooling_parameter) {
std::string quant_name = name + "_quant";
std::string in_quant_name = quant_name + "_in";
std::string out_quant_name = quant_name + "_out";
MS_CHECK_PTR_IF_NULL(pooling_parameter.quant_args_);
::QuantArg *in_quant_args = pooling_parameter.quant_args_[0];
::QuantArg *out_quant_args = pooling_parameter.quant_args_[1];
MS_CHECK_PTR_IF_NULL(in_quant_args);
MS_CHECK_PTR_IF_NULL(out_quant_args);
code << "static QuantArg " << in_quant_name << " = " << *out_quant_args << ";\n";
code << "static QuantArg " << out_quant_name << " = " << *out_quant_args << ";\n";
code << "static QuantArg *" << quant_name << "[2] = {"
<< " &" << in_quant_name << ", "
<< " &" << out_quant_name << "};\n";
CodeBaseStruct("PoolingParameter", name, pooling_parameter.op_parameter_, pooling_parameter.pool_mode_,
pooling_parameter.round_mode_, pooling_parameter.act_type_, pooling_parameter.avg_mode_,
pooling_parameter.global_, pooling_parameter.window_w_, pooling_parameter.window_h_,
pooling_parameter.stride_w_, pooling_parameter.stride_h_, pooling_parameter.input_w_,
pooling_parameter.input_h_, pooling_parameter.input_batch_, pooling_parameter.input_channel_,
pooling_parameter.output_w_, pooling_parameter.output_h_, pooling_parameter.output_batch_,
pooling_parameter.output_channel_, pooling_parameter.pad_u_, pooling_parameter.pad_d_,
pooling_parameter.pad_l_, pooling_parameter.pad_r_, pooling_parameter.op_parameter_.thread_num_,
quant_name, pooling_parameter.quantize_);
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const SoftmaxParameter &softmax_parameter) {
CodeBaseStruct("SoftmaxParameter", name, softmax_parameter.op_parameter_, softmax_parameter.axis_,
ToString(softmax_parameter.input_shape_), softmax_parameter.element_size_, softmax_parameter.n_dim_);
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const SoftmaxQuantArg &softmax_quant_parameter) {
CodeBaseStruct("SoftmaxQuantArg", name, softmax_quant_parameter.in_quant_args_,
softmax_quant_parameter.out_quant_arg_, softmax_quant_parameter.output_activation_min_,
softmax_quant_parameter.output_activation_max_, softmax_quant_parameter.output_multiplier_,
softmax_quant_parameter.shift_left_, softmax_quant_parameter.shift_right_);
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const ConcatParameter &concat_parameter,
int in_tensor_count, int in_shape, int out_shape) {
std::string quant_arg_name = name + "_quant_arg";
std::string in_args_name = quant_arg_name + "_in_args";
std::string input_shapes_name = name + "_input_shapes";
std::string output_shapes_name = name + "_output_shapes";
CodeArray(in_args_name, concat_parameter.quant_arg_.in_args_, in_tensor_count, false);
CodeBaseStruct("ConcatQuantArg", quant_arg_name, in_args_name, concat_parameter.quant_arg_.out_args_,
concat_parameter.quant_arg_.output_activation_min_,
concat_parameter.quant_arg_.output_activation_max_);
auto get_shape_name = [&input_shapes_name](int i) { return input_shapes_name + "_" + std::to_string(i); };
// input_shape
for (int i = 0; i < in_tensor_count; ++i) {
CodeArray(get_shape_name(i), concat_parameter.input_shapes_[i], in_shape);
}
code << "const int *" << input_shapes_name << "[] = {";
for (int i = 0; i < in_tensor_count; ++i) {
code << get_shape_name(i) << " ,";
}
code << "};\n";
// output_shape
CodeArray(output_shapes_name, concat_parameter.output_shapes_, out_shape, false);
CodeBaseStruct("ConcatParameter", name, concat_parameter.op_parameter_, quant_arg_name, concat_parameter.axis_,
concat_parameter.thread_count_, concat_parameter.input_num_, input_shapes_name, output_shapes_name,
concat_parameter.after_axis_size, concat_parameter.count_unit_);
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const ReduceQuantArg &reduce_quant_arg) {
CodeBaseStruct(
"ReduceQuantArg", name, reduce_quant_arg.in_scale_, reduce_quant_arg.in_zp_, reduce_quant_arg.out_scale_,
reduce_quant_arg.out_zp_, reduce_quant_arg.in_out_multiplier_, reduce_quant_arg.in_out_left_shift_,
reduce_quant_arg.in_out_right_shift_, reduce_quant_arg.mean_multiplier_, reduce_quant_arg.mean_left_shift_,
reduce_quant_arg.mean_right_shift_, reduce_quant_arg.prod_multiplier_, reduce_quant_arg.prod_left_shift_,
reduce_quant_arg.prod_right_shift_, reduce_quant_arg.sum_square_multiplier_,
reduce_quant_arg.sum_square_left_shift_, reduce_quant_arg.sum_square_right_shift_);
}
void NNaclInt8Serializer::CodeStruct(const std::string &name, const ReshapeQuantArg &reshape_quant_arg) {
CodeBaseStruct("ReshapeQuantArg", name, reshape_quant_arg.in_args_, reshape_quant_arg.out_args_,
reshape_quant_arg.output_activation_min_, reshape_quant_arg.output_activation_max_);
}
} // namespace mindspore::lite::micro::nnacl

View File

@ -0,0 +1,51 @@
/**
* 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.
*/
#ifndef MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_INT8_SERIALIZER_H_
#define MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_INT8_SERIALIZER_H_
#include <ostream>
#include <string>
#include "nnacl/pooling_parameter.h"
#include "nnacl/softmax_parameter.h"
#include "micro/coder/opcoders/serializers/serializer.h"
#include "nnacl/int8/add_int8.h"
#include "nnacl/int8/arithmetic_int8.h"
#include "nnacl/conv_parameter.h"
#include "nnacl/matmul_parameter.h"
#include "nnacl/int8/concat_int8.h"
#include "nnacl/int8/quantize.h"
#include "nnacl/reshape_parameter.h"
namespace mindspore::lite::micro::nnacl {
class NNaclInt8Serializer : public Serializer {
public:
NNaclInt8Serializer() = default;
~NNaclInt8Serializer() = default;
void CodeStruct(const std::string &name, const ConvParameter &conv_parameter);
void CodeStruct(const std::string &name, const MatMulParameter &matmul_parameter);
void CodeStruct(const std::string &name, const AddQuantParameter &add_quant_parameter);
void CodeStruct(const std::string &name, const ArithmeticParameter &arithmetic_parameter);
void CodeStruct(const std::string &name, const PoolingParameter &pooling_parameter);
void CodeStruct(const std::string &name, const SoftmaxParameter &softmax_parameter);
void CodeStruct(const std::string &name, const SoftmaxQuantArg &softmax_quant_parameter);
void CodeStruct(const std::string &name, const ConcatParameter &concat_parameter, int input_tensors, int in_shape,
int out_shape);
void CodeStruct(const std::string &name, const ReduceQuantArg &reduce_quant_arg);
void CodeStruct(const std::string &name, const ReshapeQuantArg &reshape_quant_arg);
};
} // namespace mindspore::lite::micro::nnacl
#endif // MICRO_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_INT8_SERIALIZER_H_

View File

@ -0,0 +1,65 @@
/**
* 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.
*/
#ifndef LITE_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_STREAM_UTILS_H_
#define LITE_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_STREAM_UTILS_H_
#include <sstream>
#include <string>
#include "nnacl/pooling_parameter.h"
#include "nnacl/softmax_parameter.h"
#include "nnacl/int8/quantize.h"
namespace mindspore::lite::micro {
inline std::ostream &operator<<(std::ostream &code, const ::QuantArg &quant_arg) {
code << "{" << static_cast<float>(quant_arg.scale_) << ", " << quant_arg.zp_ << "}";
return code;
}
inline std::ostream &operator<<(std::ostream &code, const OpParameter &tile) {
code << "{ \"\""
<< ", " << tile.type_ << ", " << tile.thread_num_ << "}";
return code;
}
inline std::ostream &operator<<(std::ostream &code, PoolMode pool_mode) {
code << "(PoolMode)"
<< "(" << static_cast<int>(pool_mode) << ")";
return code;
}
inline std::ostream &operator<<(std::ostream &code, RoundMode round_mode) {
code << "(RoundMode)"
<< "(" << static_cast<int>(round_mode) << ")";
return code;
}
inline std::ostream &operator<<(std::ostream &code, ActType act_type) {
code << "(ActType)"
<< "(" << static_cast<int>(act_type) << ")";
return code;
}
inline std::ostream &operator<<(std::ostream &code, DataOrder data_order) {
if (data_order == RowMajor) {
code << "RowMajor";
} else {
code << "ColMajor";
}
return code;
}
} // namespace mindspore::lite::micro
#endif // LITE_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_STREAM_UTILS_H_

View File

@ -22,6 +22,7 @@
#include <sstream>
#include "micro/coder/utils/print_utils.h"
#include "micro/coder/allocator/allocator.h"
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_stream_utils.h"
namespace mindspore::lite::micro {