!14366 support rpnt_pdr model

From: @zoloft
Reviewed-by: @wangchengyuan,@hangangqiang
Signed-off-by: @wangchengyuan
This commit is contained in:
mindspore-ci-bot 2021-03-30 20:38:09 +08:00 committed by Gitee
commit 7d70d5707a
14 changed files with 369 additions and 16 deletions

View File

@ -59,6 +59,7 @@ set(CODER_OPCODERS_SRC
${MICRO_DIR}/coder/opcoders/base/reshape_base_coder.cc
${MICRO_DIR}/coder/opcoders/base/softmax_base_coder.cc
${MICRO_DIR}/coder/opcoders/base/detection_post_process_base_coder.cc
${MICRO_DIR}/coder/opcoders/base/strided_slice_base_coder.cc
#### cmsis int8 coder
${MICRO_DIR}/coder/opcoders/cmsis-nn/int8/add_int8_coder.cc
${MICRO_DIR}/coder/opcoders/cmsis-nn/int8/conv2d_base_coder.cc
@ -96,6 +97,7 @@ set(CODER_OPCODERS_SRC
${MICRO_DIR}/coder/opcoders/nnacl/fp32/tile_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/transpose_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/splice_fp32_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/fp32/exp_fp32_coder.cc
#### nnacl int8 coder
${MICRO_DIR}/coder/opcoders/nnacl/int8/activation_int8_coder.cc
${MICRO_DIR}/coder/opcoders/nnacl/int8/add_int8_coder.cc
@ -138,6 +140,7 @@ set(LITE_SRC
${LITE_DIR}/src/common/utils.cc
### populate operator parameter
${LITE_DIR}/src/ops/ops_utils.cc
${LITE_DIR}/src/ops/populate/default_populate.cc
${LITE_DIR}/src/ops/populate/conv2d_populate.cc
${LITE_DIR}/src/ops/populate/arithmetic_populate.cc
${LITE_DIR}/src/ops/populate/add_populate.cc
@ -158,6 +161,15 @@ set(LITE_SRC
${LITE_DIR}/src/ops/populate/activation_populate.cc
${LITE_DIR}/src/ops/populate/softmax_populate.cc
${LITE_DIR}/src/ops/populate/splice_populate.cc
${LITE_DIR}/src/ops/populate/transpose_populate.cc
${LITE_DIR}/src/ops/populate/sub_populate.cc
${LITE_DIR}/src/ops/populate/power_populate.cc
${LITE_DIR}/src/ops/populate/mul_populate.cc
${LITE_DIR}/src/ops/populate/arithmetic_self_populate.cc
${LITE_DIR}/src/ops/populate/div_populate.cc
${LITE_DIR}/src/ops/populate/erf_populate.cc
${LITE_DIR}/src/ops/populate/exp_populate.cc
${LITE_DIR}/src/ops/populate/strided_slice_populate.cc
### tools
${LITE_DIR}/tools/common/flag_parser.cc
)

View File

@ -104,7 +104,8 @@ void MemoryAllocator::RecordOriginWeightsAddr(const std::vector<std::unique_ptr<
for (const auto &node : nodes) {
std::vector<Tensor *> inputs = node->input_tensors();
for (const auto &tensor : inputs) {
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
if (tensor->category() == Tensor::Category::CONST_TENSOR ||
tensor->category() == Tensor::Category::CONST_SCALAR) {
std::string runtime_addr = net_weight_addr_ + std::to_string(weight_index_);
origin_weights_addr_.insert(std::make_pair(tensor, runtime_addr));
weight_index_++;

View File

@ -60,24 +60,25 @@ int CoderGraph::ConvertTensors() {
// tensor dims
std::vector<int> shape;
if (origin_tensor->nodeType() == NodeType_ValueNode) {
MS_CHECK_PTR_WITH_EXE(origin_tensor->dims(), clear_tensors());
for (uint32_t j = 0; j < origin_tensor->dims()->size(); j++) {
MS_CHECK_PTR(origin_tensor->dims()->data());
int dim = static_cast<int>(origin_tensor->dims()->data()[j]);
MS_CHECK_RET_CODE_WITH_EXE(check_dim(dim), "parse shape failed!", clear_tensors());
shape.push_back(dim);
if (origin_tensor->dims() != nullptr) {
for (uint32_t j = 0; j < origin_tensor->dims()->size(); j++) {
MS_CHECK_PTR(origin_tensor->dims()->data());
int dim = static_cast<int>(origin_tensor->dims()->data()[j]);
MS_CHECK_RET_CODE_WITH_EXE(check_dim(dim), "parse shape failed!", clear_tensors());
shape.push_back(dim);
}
}
}
// tensor Datatype
if (shape.empty()) {
shape.push_back(1);
}
int origin_data_type = static_cast<int>(origin_tensor->dataType());
Tensor *dstTensor = new (std::nothrow)
lite::Tensor(TypeId(origin_data_type), shape, origin_tensor->format(), TensorCategory(origin_tensor));
MS_CHECK_PTR(dstTensor);
if (origin_tensor->nodeType() == NodeType_ValueNode && origin_tensor->data() != nullptr &&
origin_tensor->data()->size() > 0) {
if (shape.empty()) {
shape.push_back(1);
}
// copy data, this is weight && bias
MS_CHECK_TRUE_WITH_EXE(origin_tensor->data()->size() > 0, "invalid meta_tensor data size.", delete dstTensor);
auto data_size = static_cast<size_t>(origin_tensor->data()->size());
@ -120,10 +121,8 @@ int CoderGraph::InitGraphInOutTensors() {
std::vector<uint32_t> input_indices;
for (auto in_node_index : graph_input_node_indexes) {
in_node_index = static_cast<uint32_t>(in_node_index);
auto *in_node = model_->all_nodes_.at(in_node_index);
if (in_node == nullptr) {
return RET_ERROR;
}
auto in_node = model_->all_nodes_.at(in_node_index);
MS_CHECK_PTR(in_node);
for (uint32_t i = 0; i < in_node->input_indices_.size(); i++) {
auto in_tensor_index = size_t(in_node->input_indices_.at(i));
bool is_graph_input = false;

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 "coder/opcoders/base/strided_slice_base_coder.h"
#include <math.h>
#include <string>
#include "coder/opcoders/file_collector.h"
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
using mindspore::schema::PrimitiveType_StridedSlice;
namespace mindspore::lite::micro {
namespace {
size_t GetInnerSize(TypeId type_id, int inner_elements) {
switch (type_id) {
case kNumberTypeInt8:
return inner_elements * sizeof(int8_t);
case kNumberTypeFloat32:
return inner_elements * sizeof(float);
case kNumberTypeInt32:
return inner_elements * sizeof(int32_t);
default:
MS_LOG(ERROR) << "Not supported data type: " << type_id;
return 0;
}
}
} // namespace
bool StridedSliceBaseCoder::MatchFastPattern() {
std::vector<int> in_shape = input_tensor_->shape();
std::vector<int> out_shape = output_tensor_->shape();
if (in_shape.size() != out_shape.size()) {
return false;
}
std::vector<int> axis_list;
for (int i = 0; i < static_cast<int>(in_shape.size()); ++i) {
if (in_shape[i] != out_shape[i]) {
axis_list.emplace_back(i);
}
}
if (axis_list.size() == 1) {
split_axis_ = axis_list.front();
return true;
}
return false;
}
void StridedSliceBaseCoder::InitFastRunParam() {
std::vector<int> in_shape = input_tensor_->shape();
std::vector<int> out_shape = output_tensor_->shape();
// reset && cal inner, outer
for (int i = 0; i < split_axis_; ++i) {
outer_ *= in_shape[i];
}
for (size_t i = split_axis_ + 1; i < in_shape.size(); i++) {
inner_ *= in_shape[i];
}
int thread_num = strided_slice_parameter_->op_parameter_.thread_num_;
// decide multi-thread launch strategy
if (outer_ == 1) {
parallel_on_split_axis_ = true;
cal_num_per_thread_ = UP_DIV(out_shape[split_axis_], thread_num);
} else {
parallel_on_outer_ = true;
cal_num_per_thread_ = UP_DIV(outer_, thread_num);
}
}
int StridedSliceBaseCoder::ReSize() {
fast_run_ = MatchFastPattern();
if (fast_run_) {
InitFastRunParam();
}
return RET_OK;
}
int StridedSliceBaseCoder::Prepare(CoderContext *context) {
strided_slice_parameter_ = reinterpret_cast<StridedSliceParameter *>(parameter_);
return ReSize();
}
int StridedSliceBaseCoder::DoFastCode(CoderContext *ctx) {
std::vector<int> in_shape = input_tensor_->shape();
std::vector<int> out_shape = output_tensor_->shape();
int task_id = 0;
int begin_index = strided_slice_parameter_->begins_[split_axis_];
int caled_num = task_id * cal_num_per_thread_;
nnacl::NNaclFp32Serializer code;
std::string input_ptr_str = allocator_->GetRuntimeAddr(input_tensor_);
std::string output_ptr_str = allocator_->GetRuntimeAddr(output_tensor_);
if (parallel_on_outer_) {
int cur_outer = outer_ - caled_num;
if (cur_outer <= 0) {
return RET_OK;
}
if (cur_outer > cal_num_per_thread_) {
cur_outer = cal_num_per_thread_;
}
code << "uint8_t *cur_in_ptr = " << input_ptr_str << " + "
<< (caled_num * in_shape[split_axis_] + begin_index) * inner_size_ << ";\n";
code << " uint8_t *cur_out_ptr = " << output_ptr_str << " + " << caled_num * out_shape[split_axis_] * inner_size_
<< ";\n";
code.CodeFunction("FastStride", "cur_in_ptr", "cur_out_ptr", out_shape.at(split_axis_),
strided_slice_parameter_->strides_[split_axis_], cur_outer, inner_size_,
in_shape.at(split_axis_) * inner_size_);
} else {
int cal_axis_num = out_shape.at(split_axis_) - caled_num;
if (cal_axis_num <= 0) {
return RET_OK;
}
if (cal_axis_num > cal_num_per_thread_) {
cal_axis_num = cal_num_per_thread_;
}
code << "uint8_t *cur_in_ptr = " << input_ptr_str << " + "
<< (caled_num * strided_slice_parameter_->strides_[split_axis_] + begin_index) * inner_size_ << ";\n";
code << "uint8_t *cur_out_ptr = " << output_ptr_str << " + " << caled_num * inner_size_ << ";\n";
code.CodeFunction("FastStride", "cur_in_ptr", "cur_out_ptr", cal_axis_num,
strided_slice_parameter_->strides_[split_axis_], 1, inner_size_, 0);
}
ctx->AppendCode(code.str());
return RET_OK;
}
int StridedSliceBaseCoder::DoNormalCode(CoderContext *ctx) {
nnacl::NNaclFp32Serializer code;
code.CodeStruct("strided_slice_parameter", *strided_slice_parameter_);
code.CodeFunction("DoStridedSlice", input_tensor_, output_tensor_,
"(StridedSliceParameter *)&strided_slice_parameter");
ctx->AppendCode(code.str());
return RET_OK;
}
int StridedSliceBaseCoder::DoCode(CoderContext *ctx) {
inner_size_ = GetInnerSize(input_tensor_->data_type(), inner_);
Collect(ctx,
{
"nnacl/fp32/strided_slice_fp32.h",
},
{
"strided_slice_fp32.c",
});
if (fast_run_) {
return DoFastCode(ctx);
}
return DoNormalCode(ctx);
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_StridedSlice,
CPUOpCoderCreator<StridedSliceBaseCoder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt32, PrimitiveType_StridedSlice, CPUOpCoderCreator<StridedSliceBaseCoder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeInt8, PrimitiveType_StridedSlice, CPUOpCoderCreator<StridedSliceBaseCoder>)
} // 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 MINDSPORE_LITE_MICRO_CODER_OPCODERS_BASE_STRIDED_SLICE_BASE_CODER_H
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_BASE_STRIDED_SLICE_BASE_CODER_H
#include <vector>
#include "coder/opcoders/op_coder.h"
#include "nnacl/fp32/strided_slice_fp32.h"
namespace mindspore::lite::micro {
class StridedSliceBaseCoder final : public OperatorCoder {
public:
StridedSliceBaseCoder(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) {}
~StridedSliceBaseCoder() override = default;
int Prepare(CoderContext *context) override;
int DoCode(CoderContext *context) override;
private:
int ReSize();
void InitFastRunParam();
bool MatchFastPattern();
int DoNormalCode(CoderContext *ctx);
int DoFastCode(CoderContext *ctx);
private:
StridedSliceParameter *strided_slice_parameter_{nullptr};
int split_axis_{-1};
int inner_{1};
int outer_{1};
int cal_num_per_thread_{1};
size_t inner_size_{1};
bool fast_run_{false};
bool parallel_on_split_axis_{false};
bool parallel_on_outer_{false};
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_BASE_STRIDED_SLICE_BASE_CODER_H

View File

@ -48,6 +48,7 @@ int ArithmeticSelfFP32Coder::Prepare(CoderContext *const context) {
{PrimitiveType_Ceil, [this]() { arithmetic_self_run_ = "ElementCeil"; }},
{PrimitiveType_Round, [this]() { arithmetic_self_run_ = "ElementRound"; }},
{PrimitiveType_Neg, [this]() { arithmetic_self_run_ = "ElementNegative"; }},
{PrimitiveType_Erf, [this]() { arithmetic_self_run_ = "ElementErf"; }},
};
auto iter = type_setters.find(parameter_->type_);
if (iter != type_setters.end()) {
@ -108,4 +109,6 @@ REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Round, CPUOpCo
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Neg, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Erf, CPUOpCoderCreator<ArithmeticSelfFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

View File

@ -87,6 +87,8 @@ using mindspore::schema::PrimitiveType_Sin;
using mindspore::schema::PrimitiveType_Square;
using mindspore::schema::PrimitiveType_Erf;
class ArithmeticSelfFP32Coder final : public OperatorCoder {
public:
ArithmeticSelfFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,

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 "coder/opcoders/nnacl/fp32/exp_fp32_coder.h"
#include <math.h>
#include "coder/opcoders/file_collector.h"
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
using mindspore::schema::PrimitiveType_ExpFusion;
namespace mindspore::lite::micro::nnacl {
int ExpFP32Coder::Prepare(CoderContext *context) {
exp_parameter_ = reinterpret_cast<ExpParameter *>(parameter_);
exp_parameter_->thread_num_ = exp_parameter_->op_parameter_.thread_num_;
float log_ = (exp_parameter_->base_ == -1) ? 1 : logf(exp_parameter_->base_);
exp_parameter_->in_scale_ = exp_parameter_->scale_ * log_;
if (exp_parameter_->shift_ == 0) {
exp_parameter_->out_scale_ = 1;
} else {
if (log_ == 1) {
exp_parameter_->out_scale_ = expf(exp_parameter_->shift_);
} else {
exp_parameter_->out_scale_ = powf(exp_parameter_->base_, exp_parameter_->shift_);
}
}
exp_parameter_->element_num_ = input_tensor_->ElementsNum();
return RET_OK;
}
int ExpFP32Coder::DoCode(CoderContext *ctx) {
Collect(ctx,
{
"nnacl/fp32/exp_fp32.h",
},
{
"exp_fp32.c",
});
nnacl::NNaclFp32Serializer code;
int task_id = 0;
code.CodeStruct("exp_parameter", *exp_parameter_);
code.CodeFunction("Exp", input_tensor_, "(ExpParameter *)&exp_parameter", task_id);
ctx->AppendCode(code.str());
return RET_OK;
}
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_ExpFusion, CPUOpCoderCreator<ExpFP32Coder>)
} // namespace mindspore::lite::micro::nnacl

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 MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_EXP_FP32_CODER_H
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_EXP_FP32_CODER_H
#include <vector>
#include "coder/opcoders/op_coder.h"
#include "nnacl/fp32/exp_fp32.h"
namespace mindspore::lite::micro::nnacl {
class ExpFP32Coder final : public OperatorCoder {
public:
ExpFP32Coder(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) {}
~ExpFP32Coder() override = default;
int Prepare(CoderContext *context) override;
int DoCode(CoderContext *context) override;
private:
ExpParameter *exp_parameter_{nullptr};
};
} // namespace mindspore::lite::micro::nnacl
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_EXP_FP32_CODER_H

View File

@ -42,10 +42,10 @@ int TransposeFp32Coder::Resize() {
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));
in_shape_ = reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt32, in_shape_data_size, kOfflinePackWeight));
MS_CHECK_PTR(in_shape_);
out_shape_ =
reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt, out_shape.size() * sizeof(int), kOfflinePackWeight));
reinterpret_cast<int *>(allocator_->Malloc(kNumberTypeInt32, 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");

View File

@ -127,4 +127,20 @@ void NNaclFp32Serializer::CodeStruct(const std::string &name, const SpliceParame
splice_parameter.forward_indexes_dim_, splice_parameter.src_to_dst_row_offset_, "splice_context",
nullptr, splice_parameter.output_dim_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const ExpParameter &exp_parameter) {
CodeBaseStruct("ExpParameter", name, exp_parameter.op_parameter_, exp_parameter.base_, exp_parameter.scale_,
exp_parameter.shift_, exp_parameter.thread_num_, exp_parameter.in_scale_, exp_parameter.out_scale_,
exp_parameter.element_num_);
}
void NNaclFp32Serializer::CodeStruct(const std::string &name, const StridedSliceParameter &strided_slice_parameter) {
CodeBaseStruct("StridedSliceParameter", name, strided_slice_parameter.op_parameter_,
ToString(strided_slice_parameter.begins_), ToString(strided_slice_parameter.ends_),
ToString(strided_slice_parameter.strides_), strided_slice_parameter.isScale,
strided_slice_parameter.in_shape_length_, ToString(strided_slice_parameter.in_shape_),
strided_slice_parameter.num_axes_, strided_slice_parameter.data_type,
strided_slice_parameter.begins_mask_, strided_slice_parameter.ellipsisMask_,
strided_slice_parameter.newAxisMask_, strided_slice_parameter.shrinkAxisMask_);
}
} // namespace mindspore::lite::micro::nnacl

View File

@ -32,6 +32,8 @@
#include "nnacl/splice_parameter.h"
#include "nnacl/lstm_parameter.h"
#include "wrapper/fp32/dequant_int8_to_fp32_wrapper.h"
#include "nnacl/fp32/exp_fp32.h"
#include "nnacl/fp32/strided_slice_fp32.h"
namespace mindspore::lite::micro::nnacl {
class NNaclFp32Serializer : public Serializer {
@ -51,6 +53,8 @@ class NNaclFp32Serializer : public Serializer {
void CodeStruct(const std::string &name, const TransposeParameter &transpose_parameter);
void CodeStruct(const std::string &name, const DeQuantArg &de_quant_arg);
void CodeStruct(const std::string &name, const SpliceParameter &splice_parameter);
void CodeStruct(const std::string &name, const ExpParameter &exp_parameter);
void CodeStruct(const std::string &name, const StridedSliceParameter &strided_slice_parameter);
};
} // namespace mindspore::lite::micro::nnacl

View File

@ -18,6 +18,7 @@
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_SERIALIZERS_NNACL_STREAM_UTILS_H_
#include <sstream>
#include <string>
#include "nnacl/op_base.h"
#include "nnacl/pooling_parameter.h"
#include "nnacl/slice_parameter.h"
#include "nnacl/softmax_parameter.h"

View File

@ -236,6 +236,7 @@ class Serializer {
void GenCode(uint8_t t) { code << std::to_string(t); }
void GenCode(decltype(nullptr) t) { code << "NULL"; }
void GenCode(const char *t) { code << t; }
void GenCode(LiteDataType t) { code << "(LiteDataType)" << t; }
};
} // namespace mindspore::lite::micro
#endif // MINDSPORE_LITE_MICRO_CODER_SERIALIZERS_SERIALIZER_H_