forked from mindspore-Ecosystem/mindspore
!12323 [MSLITE]unified the macro defined in header files && feature, push micro generator
From: @wangchengyuan Reviewed-by: @zhanghaibo5,@kisnwang Signed-off-by: @zhanghaibo5
This commit is contained in:
commit
196554bcff
|
@ -203,9 +203,7 @@ if(ENABLE_CONVERTER)
|
|||
include(${TOP_DIR}/cmake/external_libs/eigen.cmake)
|
||||
include(${TOP_DIR}/cmake/external_libs/protobuf.cmake)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tools/converter)
|
||||
if(NOT WIN32)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/micro/coder)
|
||||
endif()
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/micro/coder)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_ARM32 OR PLATFORM_ARM64)
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
#### classify all .h .c .cc files to FILE_SET
|
||||
set(CODER_SRC
|
||||
${MICRO_DIR}/coder/coder.cc
|
||||
${MICRO_DIR}/coder/coder_context.cc
|
||||
${MICRO_DIR}/coder/coder_graph.cc
|
||||
${MICRO_DIR}/coder/debug.cc
|
||||
${MICRO_DIR}/coder/session_coder.cc
|
||||
${MICRO_DIR}/coder/context.cc
|
||||
${MICRO_DIR}/coder/graph.cc
|
||||
${MICRO_DIR}/coder/session.cc
|
||||
)
|
||||
|
||||
set(CODER_ALLOC_SRC
|
||||
set(CODER_ALLOCATOR_SRC
|
||||
${MICRO_DIR}/coder/allocator/allocator.cc
|
||||
${MICRO_DIR}/coder/allocator/memory_manager.cc
|
||||
)
|
||||
|
@ -15,7 +14,10 @@ set(CODER_ALLOC_SRC
|
|||
set(CODER_GENERATOR_SRC
|
||||
${MICRO_DIR}/coder/generator/generator.cc
|
||||
${MICRO_DIR}/coder/generator/inference/inference_generator.cc
|
||||
${MICRO_DIR}/coder/generator/utils/generator_utils.cc
|
||||
${MICRO_DIR}/coder/generator/component/benchmark_component.cc
|
||||
${MICRO_DIR}/coder/generator/component/common_component.cc
|
||||
${MICRO_DIR}/coder/generator/component/weight_component.cc
|
||||
${MICRO_DIR}/coder/generator/component/cmake_component.cc
|
||||
)
|
||||
|
||||
set(CODER_OPCODERS_SRC
|
||||
|
@ -51,6 +53,9 @@ set(CODER_OPCODERS_SRC
|
|||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/assign_add_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/batchnorm_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/concat_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/convolution_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/convolution_winograd_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/convolution_depthwise_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/expand_dims_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/gather_fp32_coder.cc
|
||||
${MICRO_DIR}/coder/opcoders/nnacl/fp32/nchw2nhwc_fp32_coder.cc
|
||||
|
@ -77,19 +82,10 @@ set(CODER_OPCODERS_SRC
|
|||
set(CODER_UTILS_SRC
|
||||
${MICRO_DIR}/coder/utils/coder_utils.cc
|
||||
${MICRO_DIR}/coder/utils/dir_utils.cc
|
||||
${MICRO_DIR}/coder/utils/print_utils.cc
|
||||
)
|
||||
|
||||
set(PRIMITIVE_OP_SRC
|
||||
${LITE_DIR}/src/ops/batch_norm.cc
|
||||
${LITE_DIR}/src/ops/primitive_c.cc
|
||||
${LITE_DIR}/src/ops/slice.cc
|
||||
${LITE_DIR}/src/ops/while.cc
|
||||
${MICRO_DIR}/coder/utils/type_cast.cc
|
||||
)
|
||||
|
||||
set(LITE_SRC
|
||||
${PRIMITIVE_OP_SRC}
|
||||
${LITE_DIR}/tools/common/flag_parser.cc
|
||||
${LITE_DIR}/src/common/file_utils.cc
|
||||
${LITE_DIR}/src/common/graph_util.cc
|
||||
${LITE_DIR}/src/common/string_util.cc
|
||||
|
@ -98,11 +94,25 @@ set(LITE_SRC
|
|||
${LITE_DIR}/src/tensorlist.cc
|
||||
${LITE_DIR}/src/tensor.cc
|
||||
${LITE_DIR}/src/common/log_adapter.cc
|
||||
### src/ops for parameter and infer shape
|
||||
${LITE_DIR}/src/ops/batch_norm.cc
|
||||
${LITE_DIR}/src/ops/conv2d.cc
|
||||
${LITE_DIR}/src/ops/primitive_c.cc
|
||||
${LITE_DIR}/src/ops/slice.cc
|
||||
${LITE_DIR}/src/ops/while.cc
|
||||
### populate operator parameter
|
||||
${LITE_DIR}/src/ops/populate/conv2d_populate.cc
|
||||
### nnacl
|
||||
${LITE_DIR}/nnacl/base/minimal_filtering_generator.c
|
||||
${LITE_DIR}/nnacl/fp32/winograd_utils.c
|
||||
${LITE_DIR}/nnacl/fp32/pack_fp32.c
|
||||
${LITE_DIR}/nnacl/int8/quantize.c
|
||||
${LITE_DIR}/nnacl/int8/pack_int8.c
|
||||
${LITE_DIR}/nnacl/int8/matmul_int8.c
|
||||
${LITE_DIR}/nnacl/int8/fixed_point.c
|
||||
### tools
|
||||
${LITE_DIR}/tools/common/flag_parser.cc
|
||||
)
|
||||
|
||||
list(APPEND FILE_SET ${CODER_SRC} ${CODER_UTILS_SRC} ${CODER_OPCODERS_SRC} ${CODER_GENERATOR_SRC}
|
||||
${CODER_ALLOC_SRC} ${LITE_SRC})
|
||||
${CODER_ALLOCATOR_SRC} ${LITE_SRC})
|
||||
|
|
|
@ -13,9 +13,7 @@ include_directories(${LITE_DIR})
|
|||
include_directories(${TOP_DIR}/mindspore/core/)
|
||||
|
||||
#include coder
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/utils)
|
||||
include(${MICRO_DIR}/cmake/file_list.cmake)
|
||||
add_executable(codegen main.cc ${FILE_SET})
|
||||
add_dependencies(codegen fbs_src)
|
||||
|
|
|
@ -19,25 +19,20 @@
|
|||
#include <map>
|
||||
#include "coder/allocator/memory_manager.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "coder/coder_config.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
const std::map<std::type_index, std::pair<TypeId, size_t>> types_map = {
|
||||
{std::type_index(typeid(float *)), {kNumberTypeFloat32, sizeof(float)}},
|
||||
{std::type_index(typeid(int *)), {kNumberTypeInt32, sizeof(int)}},
|
||||
{std::type_index(typeid(int32_t *)), {kNumberTypeInt32, sizeof(int32_t)}},
|
||||
{std::type_index(typeid(int16_t *)), {kNumberTypeInt16, sizeof(int16_t)}},
|
||||
{std::type_index(typeid(int8_t *)), {kNumberTypeInt8, sizeof(int8_t)}},
|
||||
};
|
||||
|
||||
void *MemoryAllocator::MallocWeightTensor(TypeId type_id, size_t size, MallocType type) {
|
||||
auto item = types_map.find(std::type_index(typeid(type_id)));
|
||||
MS_CHECK_TRUE_RET_NULL(item != types_map.end(), "unsupported type idnex");
|
||||
TypeId typei = item->second.first;
|
||||
size_t type_size = item->second.second;
|
||||
static const std::map<TypeId, size_t> size_map = {{kNumberTypeFloat32, sizeof(float)},
|
||||
{kNumberTypeInt32, sizeof(int)},
|
||||
{kNumberTypeInt32, sizeof(int32_t)},
|
||||
{kNumberTypeInt16, sizeof(int16_t)},
|
||||
{kNumberTypeInt8, sizeof(int8_t)}};
|
||||
auto item = size_map.find(type_id);
|
||||
MS_CHECK_TRUE_RET_NULL(item != size_map.end(), "unsupported type idnex");
|
||||
size_t type_size = item->second;
|
||||
std::vector<int> shape = {1, static_cast<int>(size / type_size)};
|
||||
auto cate = type == kOfflinePackWeight ? Tensor::Category::CONST_TENSOR : Tensor::Category::VAR;
|
||||
Tensor *weight = new (std::nothrow) lite::Tensor(typei, shape, schema::Format_NHWC, cate);
|
||||
Tensor *weight = new (std::nothrow) lite::Tensor(type_id, shape, schema::Format_NHWC, cate);
|
||||
MS_CHECK_PTR_RET_NULL(weight);
|
||||
std::string runtime_addr = net_weight_addr_ + std::to_string(weight_index_++);
|
||||
malloc_weights_addr_.insert(std::make_pair(weight, runtime_addr));
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <string>
|
||||
#include "coder/allocator/memory_manager.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/utils/print_utils.h"
|
||||
#include "coder/utils/type_cast.h"
|
||||
#include "src/tensor.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include <map>
|
||||
#include "schema/inner/model_generated.h"
|
||||
#include "tools/common/flag_parser.h"
|
||||
#include "coder/session_coder.h"
|
||||
#include "coder/coder_context.h"
|
||||
#include "coder/session.h"
|
||||
#include "coder/context.h"
|
||||
#include "utils/dir_utils.h"
|
||||
#include "securec/include/securec.h"
|
||||
#include "src/common/file_utils.h"
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_CODER_H_
|
||||
#define MICRO_CODER_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_CODER_H_
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "coder/session_coder.h"
|
||||
#include "coder/session.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
|
@ -41,4 +41,4 @@ class Coder final {
|
|||
int RunCoder(int argc, const char **argv);
|
||||
|
||||
} // namespace mindspore::lite::micro
|
||||
#endif // MICRO_CODER_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_CODER_H_
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_CONFIG_H
|
||||
#define MICRO_CODER_CONFIG_H
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_CONFIG_H
|
||||
#define MINDSPORE_LITE_MICRO_CODER_CONFIG_H
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -36,11 +36,13 @@ class Configurator {
|
|||
void set_code_path(const std::string &code_path) { code_path_ = code_path; }
|
||||
std::string code_path() const { return code_path_; }
|
||||
|
||||
void set_subgraph_(const std::string &subgraph) { sub_graph_ = subgraph; }
|
||||
std::string sub_graph() { return sub_graph_; }
|
||||
|
||||
void set_target(Target target) { target_ = target; }
|
||||
Target target() const { return target_; }
|
||||
|
||||
void set_code_mode(CodeMode code_mode) { code_mode_ = code_mode; }
|
||||
|
||||
CodeMode code_mode() const { return code_mode_; }
|
||||
|
||||
void set_debug_mode(bool debug) { debug_mode_ = debug; }
|
||||
|
@ -56,6 +58,7 @@ class Configurator {
|
|||
bool is_weight_file_{false};
|
||||
std::string module_name_;
|
||||
std::string code_path_;
|
||||
std::string sub_graph_;
|
||||
Target target_{kTargetUnknown};
|
||||
CodeMode code_mode_{Code_Unknown};
|
||||
bool debug_mode_{false};
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/coder_context.h"
|
||||
#include "micro/coder/context.h"
|
||||
#include "micro/coder/coder_config.h"
|
||||
#include "micro/coder/allocator/allocator.h"
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_CODER_CONTEXT_H_
|
||||
#define MICRO_CODER_CODER_CONTEXT_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_CODER_CONTEXT_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_CODER_CONTEXT_H_
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
@ -24,8 +24,6 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
#include "src/tensor.h"
|
||||
#include "coder/utils/coder_utils.h"
|
||||
#include "coder/utils/print_utils.h"
|
||||
namespace mindspore::lite::micro {
|
||||
class CoderContext {
|
||||
public:
|
||||
|
@ -36,7 +34,13 @@ class CoderContext {
|
|||
std::vector<std::string> init_contents() const { return initialContent_; }
|
||||
|
||||
void set_code_blocks(const std::vector<std::string> &code_block) { code_blocks_ = code_block; }
|
||||
std::vector<std::string> code_blocks() { return code_blocks_; }
|
||||
std::vector<std::string> code_blocks() const { return code_blocks_; }
|
||||
|
||||
void set_inference_blocks(const std::vector<std::string> &inference_blocks) { inference_blocks_ = inference_blocks; }
|
||||
std::vector<std::string> inference_blocks() const { return inference_blocks_; }
|
||||
|
||||
void set_train_blocks(const std::vector<std::string> &train_blocks) { train_blocks_ = train_blocks; }
|
||||
std::vector<std::string> train_blocks() const { return train_blocks_; }
|
||||
|
||||
void set_tensor_map(const std::map<Tensor *, std::string> &tensor_map) {
|
||||
tensors_map_.insert(tensor_map.begin(), tensor_map.end());
|
||||
|
@ -64,16 +68,13 @@ class CoderContext {
|
|||
void AppendInitCode(const std::string &codeBlock);
|
||||
|
||||
std::set<std::string> c_files() const { return c_files_; }
|
||||
|
||||
void set_c_files(const std::set<std::string> files) { c_files_.insert(files.begin(), files.end()); }
|
||||
void set_c_files(const std::set<std::string> &files) { c_files_.insert(files.begin(), files.end()); }
|
||||
|
||||
std::set<std::string> h_files() const { return h_files_; }
|
||||
|
||||
void set_h_files(const std::set<std::string> files) { h_files_.insert(files.begin(), files.end()); }
|
||||
void set_h_files(const std::set<std::string> &files) { h_files_.insert(files.begin(), files.end()); }
|
||||
|
||||
std::set<std::string> asm_files() const { return asm_files_; }
|
||||
|
||||
void set_asm_files(const std::set<std::string> files) { asm_files_.insert(files.begin(), files.end()); }
|
||||
void set_asm_files(const std::set<std::string> &files) { asm_files_.insert(files.begin(), files.end()); }
|
||||
|
||||
private:
|
||||
std::vector<Tensor *> graph_inputs_;
|
||||
|
@ -101,9 +102,11 @@ class CoderContext {
|
|||
std::set<std::string> asm_files_;
|
||||
// operator header files
|
||||
std::set<std::string> h_files_;
|
||||
// net.c's content, include the inference and prediction implementation
|
||||
// net.c's content, include the Inference and Training implementation
|
||||
std::vector<std::string> code_blocks_;
|
||||
std::vector<std::string> train_blocks_;
|
||||
std::vector<std::string> inference_blocks_;
|
||||
};
|
||||
|
||||
} // namespace mindspore::lite::micro
|
||||
#endif // MICRO_CODER_CODER_CONTEXT_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_CONTEXT_H_
|
|
@ -1,95 +0,0 @@
|
|||
/**
|
||||
* 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/debug.h"
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "include/errorcode.h"
|
||||
#include "micro/coder/utils/print_utils.h"
|
||||
#include "micro/coder/coder_context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void MicroDebug::DumpTensorData(Tensor *tensor, const std::string &tensor_addr, std::string *code_block_str,
|
||||
bool is_input) {
|
||||
*code_block_str += "\t\t\t{\n\t\t\t\tMicroTensor tensor;\n";
|
||||
|
||||
std::string format_str = "\t\t\t\ttensor.format = " + std::to_string(tensor->format()) + ";\n";
|
||||
std::string type_str = "\t\t\t\ttensor.type = " + GetMicroTensorDataType(tensor->data_type()) + ";\n";
|
||||
std::string ndim_str = "\t\t\t\ttensor.ndim = " + std::to_string(static_cast<int>(tensor->shape().size())) + ";\n";
|
||||
|
||||
*code_block_str += "\t\t\t\tint dim[] = {";
|
||||
for (size_t i = 0; i < tensor->shape().size(); ++i) {
|
||||
*code_block_str += std::to_string(tensor->shape().at(i)) + ", ";
|
||||
}
|
||||
*code_block_str += "};\n";
|
||||
*code_block_str += "\t\t\t\ttensor.dim = dim;\n";
|
||||
std::string data_str = "\t\t\t\ttensor.data = (void *)(" + tensor_addr + ");\n";
|
||||
std::string in_or_out = (is_input == 1 ? "input" : "output");
|
||||
std::string fprint_str = "\t\t\t\tfprintf(output_file, \"" + in_or_out + " Tensor:" + tensor_addr + "\\n\");\n";
|
||||
std::string print_str = "\t\t\t\tPrintTensor(&tensor,output_file," + std::to_string(is_input) + ");\n\t\t\t}\n";
|
||||
|
||||
*code_block_str += ndim_str;
|
||||
*code_block_str += type_str;
|
||||
*code_block_str += format_str;
|
||||
*code_block_str += data_str;
|
||||
*code_block_str += fprint_str;
|
||||
*code_block_str += print_str;
|
||||
}
|
||||
|
||||
int MicroDebug::DumpNodeData(const std::unique_ptr<OperatorCoder> &op_coder,
|
||||
const std::map<Tensor *, std::string> &tensor_addrs, std::string *code_block_str) {
|
||||
auto config = Configurator::GetInstance();
|
||||
if (!config->debug_mode()) {
|
||||
return RET_OK;
|
||||
}
|
||||
std::string node_name = op_coder->ID();
|
||||
std::string file_str = "\n\t\t{\n\t\t\tFILE *output_file = fopen( \"./" + node_name +
|
||||
".ir\", \"w\");\n\t\t\tfprintf(output_file, \"Node:" + op_coder->ID() + "\\n\");\n";
|
||||
|
||||
*code_block_str += file_str;
|
||||
auto runtime_tensor_iterator = [&op_coder, tensor_addrs, &code_block_str](const std::vector<Tensor *> &tensors,
|
||||
bool dump_data) {
|
||||
for (const auto &tensor : tensors) {
|
||||
if (tensor->data_c() != nullptr) {
|
||||
continue;
|
||||
}
|
||||
auto find_item =
|
||||
std::find_if(tensor_addrs.begin(), tensor_addrs.end(),
|
||||
[tensor](const std::pair<Tensor *, std::string> &item) { return item.first == tensor; });
|
||||
if (find_item != tensor_addrs.end()) {
|
||||
DumpTensorData(tensor, find_item->second, code_block_str, dump_data);
|
||||
}
|
||||
}
|
||||
return RET_OK;
|
||||
};
|
||||
int status = runtime_tensor_iterator(op_coder->input_tensors(), true);
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "dump runtime input tensor failed!";
|
||||
return status;
|
||||
}
|
||||
status = runtime_tensor_iterator(op_coder->output_tensors(), false);
|
||||
if (status != RET_OK) {
|
||||
MS_LOG(ERROR) << "dump runtime input tensor failed!";
|
||||
return status;
|
||||
}
|
||||
std::string end_file_str = "\t\t\tfclose(output_file);\n\t\t}\n";
|
||||
*code_block_str += end_file_str;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* 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/generator/component/benchmark_component.h"
|
||||
#include <memory>
|
||||
#include "coder/generator/component/const_blocks/license.h"
|
||||
#include "coder/log.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
constexpr int kWarmUp = 3;
|
||||
void CodeBenchmarkHeader(std::ofstream &ofs, const std::string &header) {
|
||||
ofs << g_hwLicense;
|
||||
ofs << "#include <stdio.h>\n"
|
||||
"#include <string.h>\n"
|
||||
"#include <stdlib.h>\n"
|
||||
"#include <stdint.h>\n"
|
||||
"#include \"microtensor.h\"\n"
|
||||
"#include \"load_input.h\"\n"
|
||||
"#include \"debug_utils.h\"\n";
|
||||
ofs << "#include \"" << header << "\"\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkUsage(std::ofstream &ofs) {
|
||||
ofs << "void usage() {\n"
|
||||
" printf(\n"
|
||||
" \"-- mindspore micro params usage:\\n\"\n"
|
||||
" \"args[0]: executable file\\n\"\n"
|
||||
" \"args[1]: inputs binary file\\n\"\n"
|
||||
" \"args[2]: model weight binary file\\n\"\n"
|
||||
" \"args[3]: loop count for performance test\\n\"\n"
|
||||
" \"args[4]: runtime thread num\\n\"\n"
|
||||
" \"args[5]: runtime thread bind mode\\n\\n\");\n"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkWarmup(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "// the default number of warm-ups is 3\n"
|
||||
<< "void " << module_name << "_WarmUp() {\n"
|
||||
<< " for (int i = 0; i < " << kWarmUp << "; ++i) {\n"
|
||||
<< " " << module_name << "_Inference();\n"
|
||||
<< " }\n"
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkSetInputs(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx) {
|
||||
ofs << "int main(int argc, char **argv) {\n"
|
||||
" if (argc < 2) {\n"
|
||||
" MICRO_ERROR(\"input command is invalid\\n\");\n"
|
||||
" usage();\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
std::vector<Tensor *> inputs = ctx->graph_inputs();
|
||||
size_t inputs_num = inputs.size();
|
||||
ofs << " // input shape: ";
|
||||
std::for_each(inputs.begin(), inputs.end(), [&](Tensor *t) {
|
||||
ofs << "[ ";
|
||||
for (int i : t->shape()) {
|
||||
ofs << i << ", ";
|
||||
}
|
||||
ofs << "], ";
|
||||
});
|
||||
ofs << "\n";
|
||||
ofs << " void *inputs_binbuf[" << inputs_num << "];\n";
|
||||
ofs << " int inputs_size[" << inputs_num << "] = {";
|
||||
for (size_t i = 0; i < inputs_num; ++i) {
|
||||
Tensor *input = inputs[i];
|
||||
ofs << input->Size() << ", ";
|
||||
}
|
||||
ofs << "};\n";
|
||||
ofs << " int ret = ReadInputsFile(argv[1], inputs_binbuf, inputs_size, " << inputs_num
|
||||
<< ");\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"read inputs file failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
ofs << " ret = " << module_name << "_SetInputs((const void **)inputs_binbuf, " << inputs_num
|
||||
<< ");\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"set inputs failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkSetBuffer(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << " int total_buffer_size = " << module_name << "_GetBufferSize();\n";
|
||||
ofs << " void *buffer = malloc(total_buffer_size);\n";
|
||||
ofs << " if (buffer == NULL ){\n"
|
||||
" MICRO_ERROR(\"malloc memory buffer failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
ofs << " ret = " << module_name
|
||||
<< "_SetBuffer(buffer);\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"set inputs failed\");\n"
|
||||
" return RET_ERROR;"
|
||||
" }\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkInitWeight(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << " int weight_size = 0;\n"
|
||||
" void *weight_buffer = ReadInputData(argv[2], &weight_size); \n"
|
||||
" if("
|
||||
<< module_name
|
||||
<< "_Init(weight_buffer, weight_size) != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"model init failed\");\n"
|
||||
" "
|
||||
<< module_name
|
||||
<< "_FreeResource();\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n"
|
||||
" free(weight_buffer);\n"
|
||||
" weight_buffer = NULL;\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkConfigThread(std::ofstream &ofs) {
|
||||
ofs << " int thread_num = 4;\n"
|
||||
" BindMode bind_mode = NO_BIND_MODE;\n"
|
||||
" if (argc >= 6) {\n"
|
||||
" thread_num = atoi(argv[4]);\n"
|
||||
" bind_mode = atoi(argv[5]);\n"
|
||||
" }\n"
|
||||
" ret = ConfigThreadPool(THREAD_POOL_DEFAULT, thread_num, bind_mode);\n"
|
||||
" if (ret != 0) {\n"
|
||||
" MICRO_ERROR(\"create thread pool failed\");\n"
|
||||
" }\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkInference(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << " if (argc >= 4) {\n"
|
||||
<< " " << module_name << "_WarmUp();\n"
|
||||
<< " uint64_t timeAvg = 0;\n"
|
||||
<< " int loop_count = atoi(argv[3]);\n"
|
||||
<< " printf(\"======Inference Start======\\n\");\n"
|
||||
<< " printf(\"cycles: %d\", loop_count);\n"
|
||||
<< " for (int i = 0; i < loop_count; i++) {\n"
|
||||
<< " uint64_t runBegin = GetTimeUs();\n"
|
||||
<< " " << module_name << "_Inference();\n"
|
||||
<< " uint64_t runEnd = GetTimeUs();\n"
|
||||
<< " uint64_t time = runEnd - runBegin;\n"
|
||||
<< " timeAvg += time;\n"
|
||||
<< " }\n"
|
||||
<< " float cunCost = (float)timeAvg / 1000.0f;\n"
|
||||
<< " printf(\"=======Inference End=======\\n\");\n"
|
||||
" printf(\"total time:\\t %.5fms, per time: \\t %.5fms\\n\", cunCost, cunCost/loop_count);\n"
|
||||
<< " }\n";
|
||||
ofs << " " << module_name << "_Inference();\n";
|
||||
}
|
||||
|
||||
void CodeBenchmarkPrintOutputs(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << " // print model outputs \n";
|
||||
ofs << " const MicroTensorList *outs = " << module_name << "_GetOutputs();\n";
|
||||
ofs << " for (int i = 0; i < outs->num; ++i) {\n"
|
||||
" MicroTensor *tensor = outs->tensor + i;\n"
|
||||
" PrintTensorData(tensor);\n"
|
||||
" }\n";
|
||||
ofs << " printf(\"" << module_name << " inference success.\\n\");\n";
|
||||
ofs << " free(buffer);\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. free malloc memory buffer
|
||||
* 2. set input and buffer to NULL, and free packed weight memory
|
||||
* 3. free input binary memory
|
||||
*/
|
||||
void CodeBenchmarkFreeResourse(std::ofstream &ofs, const std::string &module_name, size_t inputs_num) {
|
||||
ofs << " free(buffer);\n";
|
||||
ofs << " " << module_name << "_FreeResource();\n";
|
||||
ofs << " for (int i = 0; i < " << inputs_num << "; ++i) {\n";
|
||||
ofs << " free(inputs_binbuf[i]);\n"
|
||||
" }\n"
|
||||
" return RET_OK;"
|
||||
"}\n\n";
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_GENERATOR_BENCHMARK_COMPONENT_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_BENCHMARK_COMPONENT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include "src/tensor.h"
|
||||
#include "coder/context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void CodeBenchmarkHeader(std::ofstream &ofs, const std::string &header);
|
||||
|
||||
void CodeBenchmarkUsage(std::ofstream &ofs);
|
||||
|
||||
void CodeBenchmarkWarmup(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeBenchmarkSetInputs(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
void CodeBenchmarkSetBuffer(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeBenchmarkInitWeight(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeBenchmarkConfigThread(std::ofstream &ofs);
|
||||
|
||||
void CodeBenchmarkInference(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeBenchmarkPrintOutputs(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeBenchmarkFreeResourse(std::ofstream &ofs, const std::string &module_name, size_t inputs_num);
|
||||
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_BENCHMARK_COMPONENT_H_
|
|
@ -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 "coder/generator/component/cmake_component.h"
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
void CodeCMakeNetLibrary(std::ofstream &ofs, const std::string &module_name, const std::unique_ptr<CoderContext> &ctx,
|
||||
Target target) {
|
||||
ofs << "include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/)\n";
|
||||
if (target == kARM32M) {
|
||||
ofs << "include_directories(${OP_HEADER_PATH}/cmsis)\n"
|
||||
<< "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/NN/Include)\n"
|
||||
<< "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/DSP/Include)\n"
|
||||
<< "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/Core/Include)\n";
|
||||
}
|
||||
ofs << "set(OP_SRC\n";
|
||||
for (const std::string &c_file : ctx->c_files()) {
|
||||
ofs << " " << c_file << ".o\n";
|
||||
}
|
||||
ofs << " " << module_name << "_weight.c.o\n"
|
||||
<< " " << module_name << ".c.o\n"
|
||||
<< ")\n";
|
||||
|
||||
std::set<std::string> kernel_cmake_asm_set_files = ctx->asm_files();
|
||||
if (!kernel_cmake_asm_set_files.empty()) {
|
||||
ofs << "set(ASSEMBLY_SRC\n";
|
||||
for (const std::string &asm_file : kernel_cmake_asm_set_files) {
|
||||
ofs << " " << asm_file << ".o\n";
|
||||
}
|
||||
ofs << ")\n"
|
||||
<< "set_property(SOURCE ${ASSEMBLY_SRC} PROPERTY LANGUAGE C)\n"
|
||||
<< "list(APPEND OP_SRC ${ASSEMBLY_SRC})\n";
|
||||
}
|
||||
|
||||
ofs << "file(GLOB NET_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.c)\n"
|
||||
<< "add_library(${PROJ_NAME} STATIC ${NET_SRC})\n";
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -14,30 +14,22 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_MICRO_LITE_CODER_DEBUG_H_
|
||||
#define MINDSPORE_MICRO_LITE_CODER_DEBUG_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_GENERATOR_CMAKE_COMPONENT_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_CMAKE_COMPONENT_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include "src/tensor.h"
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/coder_config.h"
|
||||
#include "coder/context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void CodeCMakeNetLibrary(std::ofstream &ofs, const std::string &module_name, const std::unique_ptr<CoderContext> &ctx,
|
||||
Target target);
|
||||
|
||||
class MicroDebug {
|
||||
public:
|
||||
MicroDebug() = default;
|
||||
~MicroDebug() = default;
|
||||
|
||||
static void DumpTensorData(Tensor *tensor, const std::string &tensor_addr, std::string *code_block_str,
|
||||
bool is_input);
|
||||
|
||||
static int DumpNodeData(const std::unique_ptr<OperatorCoder> &op_coder,
|
||||
const std::map<Tensor *, std::string> &tensor_addrs, std::string *code_block_str);
|
||||
};
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_DEBUG_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_CMAKE_COMPONENT_H_
|
|
@ -0,0 +1,209 @@
|
|||
/**
|
||||
* 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/generator/component/common_component.h"
|
||||
#include <memory>
|
||||
#include "coder/generator/component/const_blocks/license.h"
|
||||
#include "coder/utils/type_cast.h"
|
||||
#include "coder/log.h"
|
||||
#include "include/errorcode.h"
|
||||
#include "nnacl/op_base.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void CodeSourceFileInclude(std::ofstream &ofs, const std::string &weight_file, const std::string &header) {
|
||||
ofs << g_hwLicense << "#include \"microtensor.h\"\n"
|
||||
<< "#include \"" << weight_file << "\"\n"
|
||||
<< "#include \"" << header << "\"\n";
|
||||
}
|
||||
|
||||
void CodeInputAndOutputState(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "/**\n"
|
||||
<< " * set input tensors\n"
|
||||
<< " * @param inputs, the input data ptr's array of the model, the tensors' count of input may be greater than "
|
||||
"one.\n"
|
||||
<< " * @param num, the input data's number of the model.\n"
|
||||
<< " **/\n"
|
||||
<< "int " << module_name << "_SetInputs(const void **inputs, int num);\n\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * get output tensor of the model \n"
|
||||
<< " **/\n"
|
||||
<< "const MicroTensorList *" << module_name << "_GetOutputs();\n\n";
|
||||
}
|
||||
|
||||
void PrintMicroTensors(std::ofstream &ofs, std::vector<Tensor *> tensors, const std::string &name,
|
||||
const std::map<Tensor *, std::string> &tensors_map) {
|
||||
for (size_t i = 0; i < tensors.size(); ++i) {
|
||||
Tensor *tensor = tensors[i];
|
||||
auto item = tensors_map.find(tensor);
|
||||
if (item == tensors_map.end()) {
|
||||
MS_LOG(ERROR) << "nonexistent tensor";
|
||||
break;
|
||||
}
|
||||
ofs << " static int dim[] = {";
|
||||
for (size_t j = 0; j < tensor->shape().size(); ++j) {
|
||||
ofs << tensor->shape()[j] << ", ";
|
||||
}
|
||||
ofs << "};\n"
|
||||
<< " " << name << "[" << i << "].ndim = " << tensor->shape().size() << ";\n"
|
||||
<< " " << name << "[" << i << "].dim = dim;\n"
|
||||
<< " " << name << "[" << i << "].type = " << EnumMicroTensorDataType(tensor->data_type()) << ";\n"
|
||||
<< " " << name << "[" << i << "].format = " << std::to_string(tensor->format()) << ";\n"
|
||||
<< " " << name << "[" << i << "].data =" << item->second << ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
void CodeInputAndOutputImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx) {
|
||||
// input tensors
|
||||
ofs << "\n// input tensors\n";
|
||||
std::vector<Tensor *> inputs = ctx->graph_inputs();
|
||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||
ofs << "static const unsigned char *" << ctx->input_name() + std::to_string(i) << " = 0;\n";
|
||||
}
|
||||
size_t size = inputs.size();
|
||||
ofs << "int " << module_name << "_SetInputs(const void **inputs, int num) {\n"
|
||||
<< " if (inputs == NULL) {\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n"
|
||||
<< " if (num !=" << size << ") {\n"
|
||||
<< " return RET_ERROR;\n"
|
||||
" }\n";
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
ofs << "\t" << ctx->input_name() + std::to_string(i) << " = inputs[" << i << "];\n";
|
||||
}
|
||||
ofs << " return RET_OK;\n}\n";
|
||||
|
||||
// output tensors
|
||||
ofs << "\n// output tensors\n";
|
||||
std::vector<Tensor *> outputs = ctx->graph_outputs();
|
||||
size_t output_num = outputs.size();
|
||||
std::string output_name = ctx->output_name();
|
||||
|
||||
ofs << "const MicroTensorList* " << module_name << "_GetOutputs() {\n"
|
||||
<< " static MicroTensor " << output_name << "[" << output_num << "] ;\n";
|
||||
|
||||
PrintMicroTensors(ofs, outputs, output_name, ctx->tensors_map());
|
||||
ofs << " static MicroTensorList " << module_name << "_TensorArray;\n"
|
||||
<< " " << module_name << "_TensorArray.num = " << output_num << ";\n"
|
||||
<< " " << module_name << "_TensorArray.tensor = &" << output_name << "[0];\n"
|
||||
<< " return &" << module_name << "_TensorArray; \n}\n";
|
||||
}
|
||||
|
||||
void CodeGraphQuantArgsState(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "/**\n"
|
||||
<< " * get input and output QuantArgs of the model \n"
|
||||
<< " **/\n"
|
||||
<< "GraphQuantArgs " << module_name << "_GetInOutQuantArgs();\n\n";
|
||||
}
|
||||
|
||||
void CodeGraphQuantArgsImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx) {
|
||||
std::vector<Tensor *> graph_inputs = ctx->graph_inputs();
|
||||
Tensor *in_tensor = graph_inputs.at(kInputIndex);
|
||||
MS_CHECK_PTR_IF_NULL(in_tensor);
|
||||
std::vector<Tensor *> graph_outputs = ctx->graph_outputs();
|
||||
Tensor *out_tensor = graph_outputs.at(kOutputIndex);
|
||||
MS_CHECK_PTR_IF_NULL(out_tensor);
|
||||
std::vector<QuantArg> in_quant_args = in_tensor->quant_params();
|
||||
std::vector<QuantArg> out_quant_args = out_tensor->quant_params();
|
||||
if (graph_inputs.empty() || graph_outputs.empty() || in_quant_args.empty() || out_quant_args.empty()) {
|
||||
MS_LOG(ERROR) << "code model quant args failed";
|
||||
return;
|
||||
}
|
||||
ofs << "GraphQuantArgs " << module_name << "_GetInOutQuantArgs() {\n"
|
||||
<< "\t\tGraphQuantArgs quan_args = { " << in_quant_args.at(0).scale << ", " << out_quant_args.at(0).scale << ", "
|
||||
<< in_quant_args.at(0).zeroPoint << ", " << out_quant_args.at(0).zeroPoint << "};\n"
|
||||
<< "\t\treturn quan_args;\n"
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
void CodeInitWeightState(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "/**\n"
|
||||
<< " * @param weight_buffer, the address of the weight binary file\n"
|
||||
<< " * @param weight_size, the size of the model file in bytes\n"
|
||||
<< " **/\n"
|
||||
<< "int " << module_name << "_Init(void *weight_buffer, int weight_size);\n\n";
|
||||
}
|
||||
|
||||
void CodeManageResourceState(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "/**\n"
|
||||
<< " * get the memory space size of the inference.\n"
|
||||
<< " **/\n"
|
||||
<< "int " << module_name << "_GetBufferSize();\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * set the memory space for the inference\n"
|
||||
<< " **/\n"
|
||||
<< "int " << module_name << "_SetBuffer(void *buffer);\n\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * free the memory of packed weights, and set the membuf buffer and input address to NULL\n"
|
||||
<< " **/\n"
|
||||
<< "void " << module_name << "_FreeResource();\n";
|
||||
}
|
||||
|
||||
void CodeInitResourceImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx) {
|
||||
ofs << "int " << module_name << "deconv_GetBufferSize() {\n"
|
||||
<< " return " << ctx->total_buffer_size() << ";\n"
|
||||
<< "}\n";
|
||||
ofs << "int " << module_name << "_SetBuffer( void *buffer) {\n";
|
||||
ofs << " if (buffer == NULL) {\n"
|
||||
" MICRO_ERROR(\"memory buffer is NULL\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
ofs << " " << ctx->buffer_name()
|
||||
<< " = buffer;\n"
|
||||
" return RET_OK;\n"
|
||||
"}\n";
|
||||
}
|
||||
|
||||
void CodeFreeResourceImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx) {
|
||||
ofs << "void " << module_name << "_FreeResource() {\n";
|
||||
ofs << " " << ctx->buffer_name() << "= NULL;\n";
|
||||
std::vector<Tensor *> inputs = ctx->graph_inputs();
|
||||
size_t size = inputs.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
ofs << " " << ctx->input_name() + std::to_string(i) << " = NULL;\n";
|
||||
}
|
||||
ofs << " void *allocated[] = {";
|
||||
size_t num = 0;
|
||||
for (const auto &item : ctx->tensors_map()) {
|
||||
Tensor *tensor = item.first;
|
||||
std::string name = item.second;
|
||||
if (tensor->data_c() != nullptr && tensor->category() != Tensor::Category::CONST_TENSOR) {
|
||||
ofs << name << ", ";
|
||||
num++;
|
||||
}
|
||||
}
|
||||
ofs << " };\n";
|
||||
ofs << " for (int i = 0; i < " << num << "; ++i) {\n"
|
||||
<< " free(allocated[i]);\n"
|
||||
<< " allocated[i] = NULL;\n"
|
||||
<< " }\n";
|
||||
ofs << "}\n";
|
||||
}
|
||||
|
||||
void CodeInferenceState(std::ofstream &ofs, const std::string &module_name) {
|
||||
ofs << "/**\n"
|
||||
<< " * net inference function\n"
|
||||
<< " **/\n"
|
||||
<< "void " << module_name << "_Inference();\n\n";
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -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 MINDSPORE_LITE_MICRO_CODER_GENERATOR_COMMON_COMPONENT_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_COMMON_COMPONENT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include "src/tensor.h"
|
||||
#include "coder/context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void CodeSourceFileInclude(std::ofstream &ofs, const std::string &weight_file, const std::string &header);
|
||||
|
||||
void CodeInputAndOutputState(std::ofstream &ofs, const std::string &module_name);
|
||||
void CodeInputAndOutputImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
void CodeGraphQuantArgsState(std::ofstream &ofs, const std::string &module_name);
|
||||
void CodeGraphQuantArgsImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
void CodeInitWeightState(std::ofstream &ofs, const std::string &module_name);
|
||||
|
||||
void CodeManageResourceState(std::ofstream &ofs, const std::string &module_name);
|
||||
void CodeInitResourceImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
void CodeFreeResourceImplement(std::ofstream &ofs, const std::string &module_name,
|
||||
const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
void CodeInferenceState(std::ofstream &ofs, const std::string &module_name);
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_COMMON_COMPONENT_H_
|
|
@ -42,11 +42,11 @@ static const char debug_utils_h[] =
|
|||
"#include <stdint.h>\n"
|
||||
"#include \"microtensor.h\"\n"
|
||||
"\n"
|
||||
"void PrintTensor(MicroTensor *tensor, FILE *output_file, int isInput);\n"
|
||||
"void PrintTensor(MicroTensor *tensor, FILE *output_file, const char *is_input);\n"
|
||||
"\n"
|
||||
"void PrintTensorData(MicroTensor *tensor);\n"
|
||||
"\n"
|
||||
"uint64_t GetTimeUs(void);\n"
|
||||
"uint64_t GetTimeUs();\n"
|
||||
"\n"
|
||||
"#endif // MINDSPORE_LITE_MICRO_MICRODEBUGUTIL_H_\n";
|
||||
|
||||
|
@ -238,31 +238,27 @@ static const char debug_utils_c[] =
|
|||
" fprintf(file, \"\\n\");\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void PrintTensor(MicroTensor *tensor, FILE *output_file, int isInput) {\n"
|
||||
"void PrintTensor(MicroTensor *tensor, FILE *output_file, const char *is_input) {\n"
|
||||
" if (output_file != NULL) {\n"
|
||||
" const char *tips = NULL;\n"
|
||||
" if (isInput) {\n"
|
||||
" tips = \"input\";\n"
|
||||
" } else {\n"
|
||||
" tips = \"output\";\n"
|
||||
" }\n"
|
||||
" fprintf(output_file, \"%s \", tips);\n"
|
||||
" for (int i = 0; i < tensor->ndim; ++i) {\n"
|
||||
" fprintf(output_file, \"%u, \", tensor->dim[i]);\n"
|
||||
" }\n"
|
||||
" fprintf(output_file, \"\\n\");\n"
|
||||
"\n"
|
||||
" const char *type = TypeNames[tensor->type];\n"
|
||||
" const char *format = EnumNameFormat(tensor->format);\n"
|
||||
" unsigned int tensorSize = GetTensorElementSize(tensor);\n"
|
||||
" fprintf(output_file, \"%s type:%s, format:%s, elementSize: %u\\n\", tips, type, format, tensorSize);\n"
|
||||
" fprintf(output_file, \"%s Data:\\n\", tips);\n"
|
||||
" PrintDataToFile(tensor->data, tensorSize, tensor->type, output_file);\n"
|
||||
" (void)fflush(output_file);\n"
|
||||
" MICRO_ERROR(\"output file is NULL\");\n"
|
||||
" return;\n"
|
||||
" }\n"
|
||||
" fprintf(output_file, \"%s \", is_input);\n"
|
||||
" for (int i = 0; i < tensor->ndim; ++i) {\n"
|
||||
" fprintf(output_file, \"%u, \", tensor->dim[i]);\n"
|
||||
" }\n"
|
||||
" fprintf(output_file, \"\\n\");\n"
|
||||
"\n"
|
||||
" const char *type = TypeNames[tensor->type];\n"
|
||||
" const char *format = EnumNameFormat(tensor->format);\n"
|
||||
" unsigned int tensorSize = GetTensorElementSize(tensor);\n"
|
||||
" fprintf(output_file, \"%s type:%s, format:%s, elementSize: %u\\n\", is_input, type, format, tensorSize);\n"
|
||||
" fprintf(output_file, \"%s Data:\\n\", is_input);\n"
|
||||
" PrintDataToFile(tensor->data, tensorSize, tensor->type, output_file);\n"
|
||||
" (void)fflush(output_file);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"uint64_t GetTimeUs(void) {\n"
|
||||
"uint64_t GetTimeUs() {\n"
|
||||
" const int USEC = 1000000;\n"
|
||||
" const int MSEC = 1000;\n"
|
||||
" struct timespec ts = {0, 0};\n"
|
|
@ -0,0 +1,150 @@
|
|||
/**
|
||||
* 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/generator/component/weight_component.h"
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include "coder/generator/component/const_blocks/license.h"
|
||||
#include "coder/utils/coder_utils.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void CodeWeightFileHeader(std::ofstream &ofs, const std::unique_ptr<CoderContext> &ctx) {
|
||||
ofs << g_hwLicense;
|
||||
// include all operator header
|
||||
for (const auto &h_file : ctx->h_files()) {
|
||||
ofs << "#include \"" << h_file << "\"\n";
|
||||
}
|
||||
ofs << "#include <stdlib.h>\n"
|
||||
<< "#include <string.h>\n"
|
||||
<< "#include \"microtensor.h\"\n\n"
|
||||
<< "extern unsigned char *" << ctx->buffer_name() << ";\n";
|
||||
}
|
||||
|
||||
void CodeModelParamsState(std::ofstream &ofs, const std::map<std::string, Tensor *> &weights) {
|
||||
for (auto &item : weights) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
ofs << "extern const " << GetTensorDataType(tensor->data_type()) << name << "[];\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeModelParamsData(std::ofstream &ofs, const std::map<std::string, Tensor *> &weights) {
|
||||
for (auto &item : weights) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
ofs << "const " << GetTensorDataType(tensor->data_type()) << name << "[] = ";
|
||||
PrintTensorData(tensor, ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CodeModelParamsForNet(std::ofstream &hofs, std::ofstream &cofs, const std::unique_ptr<CoderContext> &ctx) {
|
||||
// reverse key and value of tensors_map
|
||||
std::map<std::string, Tensor *> address_map;
|
||||
for (const auto &item : ctx->tensors_map()) {
|
||||
address_map.insert(std::make_pair(item.second, item.first));
|
||||
}
|
||||
for (auto &item : address_map) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
hofs << "extern " << GetTensorDataType(tensor->data_type()) << name << " = [];\n";
|
||||
cofs << GetTensorDataType(tensor->data_type()) << name << " = [" << tensor->ElementsNum() << "];\n";
|
||||
} else if (tensor->category() == Tensor::Category::VAR) {
|
||||
hofs << "extern " << GetTensorDataType(tensor->data_type()) << " *" << name << ";\n";
|
||||
cofs << GetTensorDataType(tensor->data_type()) << "*" << name << " = NULL;\n";
|
||||
}
|
||||
}
|
||||
cofs << "\n";
|
||||
}
|
||||
|
||||
void CodeWeightInitFunc(std::ofstream &ofs, const std::string &module_name, const std::unique_ptr<CoderContext> &ctx) {
|
||||
ofs << "int " << module_name << "_Init(void *weight_buffer, int weight_size) {\n"
|
||||
<< " if (weight_buffer == NULL) {\n"
|
||||
" MICRO_ERROR(\"weight buffer is NULL\");\n"
|
||||
<< " return RET_ERROR;\n"
|
||||
<< " }\n";
|
||||
|
||||
ofs << " struct ModelParameter {\n"
|
||||
<< " void *addr;\n"
|
||||
<< " size_t size;\n"
|
||||
<< " size_t offset;\n"
|
||||
<< " };\n";
|
||||
size_t params_num = 0;
|
||||
size_t offset = 0;
|
||||
std::string params;
|
||||
std::string origins;
|
||||
for (const auto &item : ctx->saved_weights()) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() != Tensor::Category::CONST_TENSOR) {
|
||||
continue;
|
||||
}
|
||||
auto iter = ctx->tensors_map().find(tensor);
|
||||
if (iter != ctx->tensors_map().end()) {
|
||||
origins += " {" + name + ", " + std::to_string(tensor->Size()) + ", " + std::to_string(offset) + "},\n";
|
||||
params_num++;
|
||||
} else {
|
||||
TypeId data_type = tensor->data_type();
|
||||
params +=
|
||||
" " + GetTensorDataType(data_type) + "*" + name + " = (weight_buffer + " + std::to_string(offset) + ");\n";
|
||||
}
|
||||
}
|
||||
ofs << " struct ModelParameter model_params[] = {\n" << origins << " };\n";
|
||||
ofs << params << "\n";
|
||||
|
||||
ofs << "\n";
|
||||
ofs << " for(int i = 0; i < " << params_num << "; ++i) {\n"
|
||||
<< " if (model_params[i].offset + model_params[i].size > weight_size) {\n"
|
||||
" MICRO_ERROR(\"buffer is invalid, size: %d, offset: %lu\", weight_size, model_params[i].offset);\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n"
|
||||
<< " memcpy(model_params[i].addr, (weight_buffer + model_params[i].offset), model_params[i].size);\n"
|
||||
<< " }\n";
|
||||
for (const auto &block : ctx->init_contents()) {
|
||||
ofs << "{\n" << block << "}\n";
|
||||
}
|
||||
ofs << " return RET_OK;\n";
|
||||
ofs << "}\n\n";
|
||||
}
|
||||
|
||||
void SaveDataToNet(const std::map<std::string, Tensor *> &saved_weights, const std::string &net_file) {
|
||||
std::ofstream net(net_file, std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
MS_CHECK_TRUE_WITHOUT_RET(net.is_open(), "net file open failed!");
|
||||
for (auto &item : saved_weights) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR && tensor->data_c() != nullptr) {
|
||||
net.write(reinterpret_cast<const char *>(tensor->data_c()), tensor->Size());
|
||||
}
|
||||
}
|
||||
net.close();
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -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_GENERATOR_WEIGHT_COMPONENT_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_WEIGHT_COMPONENT_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
#include "src/tensor.h"
|
||||
#include "coder/coder_config.h"
|
||||
#include "coder/context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
void CodeWeightFileHeader(std::ofstream &ofs, const std::unique_ptr<CoderContext> &ctx);
|
||||
void CodeModelParamsState(std::ofstream &ofs, const std::map<std::string, Tensor *> &weights);
|
||||
void CodeModelParamsData(std::ofstream &ofs, const std::map<std::string, Tensor *> &weights);
|
||||
|
||||
void SaveDataToNet(const std::map<std::string, Tensor *> &saved_weights, const std::string &net_file);
|
||||
void CodeModelParamsForNet(std::ofstream &hofs, std::ofstream &cofs, const std::unique_ptr<CoderContext> &ctx);
|
||||
void CodeWeightInitFunc(std::ofstream &ofs, const std::string &module_name, const std::unique_ptr<CoderContext> &ctx);
|
||||
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_WEIGHT_COMPONENT_H_
|
|
@ -18,15 +18,27 @@
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
#include "coder/generator/utils/generator_utils.h"
|
||||
#include "coder/generator/const_blocks/cmake_lists_code.h"
|
||||
#include "coder/generator/const_blocks/bench_debug_utils.h"
|
||||
#include "coder/generator/const_blocks/bench_load_input.h"
|
||||
#include "coder/generator/const_blocks/micro_tensor.h"
|
||||
#include "coder/generator/const_blocks/license.h"
|
||||
#include "coder/generator/component/cmake_component.h"
|
||||
#include "coder/generator/component/weight_component.h"
|
||||
#include "coder/generator/component/const_blocks/micro_tensor.h"
|
||||
#include "coder/generator/component/const_blocks/cmake_lists.h"
|
||||
#include "coder/generator/component/const_blocks/debug_utils.h"
|
||||
#include "coder/generator/component/const_blocks/load_input.h"
|
||||
#include "coder/generator/component/const_blocks/license.h"
|
||||
#include "micro/coder/log.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
int WriteContentToFile(const std::string &file, const std::string &content) {
|
||||
std::ofstream of(file);
|
||||
if (of.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << file;
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_LOG(INFO) << "write " << file;
|
||||
of << content;
|
||||
of.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
Generator::Generator(std::unique_ptr<CoderContext> ctx) {
|
||||
ctx_ = std::move(ctx);
|
||||
|
@ -46,104 +58,6 @@ Generator::Generator(std::unique_ptr<CoderContext> ctx) {
|
|||
|
||||
Generator::~Generator() { (void)umask(origin_umask_); }
|
||||
|
||||
int Generator::CodeGraphInOutQuanArgs(std::ofstream &ofs) {
|
||||
std::vector<Tensor *> graph_inputs = ctx_->graph_inputs();
|
||||
if (graph_inputs.empty()) {
|
||||
MS_LOG(ERROR) << "this graph has no input tensor";
|
||||
return RET_ERROR;
|
||||
}
|
||||
Tensor *in_tensor = graph_inputs.at(kInputIndex);
|
||||
MS_CHECK_PTR(in_tensor);
|
||||
std::vector<Tensor *> graph_outputs = ctx_->graph_outputs();
|
||||
if (graph_outputs.empty()) {
|
||||
MS_LOG(ERROR) << "this graph has no output tensor";
|
||||
return RET_ERROR;
|
||||
}
|
||||
Tensor *out_tensor = graph_outputs.at(kOutputIndex);
|
||||
MS_CHECK_PTR(out_tensor);
|
||||
std::vector<QuantArg> in_quant_args = in_tensor->quant_params();
|
||||
std::vector<QuantArg> out_quant_args = out_tensor->quant_params();
|
||||
if (in_quant_args.empty() || out_quant_args.empty()) {
|
||||
MS_LOG(WARNING) << "in_quant_args or out_quant_args is empty";
|
||||
return RET_OK;
|
||||
}
|
||||
ofs << "GraphQuantArgs " << config_->module_name() << "_GetInOutQuantArgs() {\n"
|
||||
<< "\t\t"
|
||||
<< "GraphQuantArgs quan_args = { " << in_quant_args.at(0).scale << ", " << out_quant_args.at(0).scale << ", "
|
||||
<< in_quant_args.at(0).zeroPoint << ", " << out_quant_args.at(0).zeroPoint << "};\n"
|
||||
<< "\t\t"
|
||||
<< "return quan_args;\n"
|
||||
<< "}\n";
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int Generator::CodeNetFileInputOutput(std::ofstream &ofs) {
|
||||
// input tensors
|
||||
ofs << "\n// set input tensors\n";
|
||||
std::vector<Tensor *> inputs = ctx_->graph_inputs();
|
||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||
ofs << "\nstatic const unsigned char *" << ctx_->input_name() + std::to_string(i) << " = 0;\n";
|
||||
}
|
||||
size_t size = inputs.size();
|
||||
ofs << "int " << config_->module_name() << "_SetInputs(const void **inputs, int num) {\n"
|
||||
<< "if (inputs == NULL) {\n"
|
||||
"\treturn RET_ERROR;\n"
|
||||
"\t}\n"
|
||||
<< "\tif (num !=" << size << ") { return RET_ERROR;}\n";
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
ofs << "\t" << ctx_->input_name() + std::to_string(i) << " = inputs[" << i << "];\n";
|
||||
}
|
||||
ofs << "\treturn RET_OK;\n}\n";
|
||||
|
||||
// output tensors
|
||||
ofs << "\n// output tensors\n";
|
||||
std::vector<Tensor *> outputs = ctx_->graph_outputs();
|
||||
size_t output_num = outputs.size();
|
||||
std::string output_name = ctx_->output_name();
|
||||
|
||||
ofs << "const MicroTensorList* " << config_->module_name() << "_GetOutputs() {\n"
|
||||
<< " static MicroTensor " << output_name << "[" << output_num << "] ;\n";
|
||||
|
||||
if (PrintMicroTensors(ofs, outputs, output_name, ctx_->tensors_map()) != RET_OK) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
ofs << " static MicroTensorList " << config_->module_name() << "_TensorArray;\n"
|
||||
<< " " << config_->module_name() << "_TensorArray.num = " << output_num << ";\n"
|
||||
<< " " << config_->module_name() << "_TensorArray.tensor = &" << output_name << "[0];\n"
|
||||
<< " return &" << config_->module_name() << "_TensorArray; \n}\n";
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void Generator::CodeNetFileMembuffer(std::ofstream &ofs) {
|
||||
// memory buffer
|
||||
ofs << "\n// Get MemBuffer Size\n"
|
||||
<< "unsigned int " << config_->module_name() << "_GetBufferSize() {\n"
|
||||
<< "\t return " << ctx_->total_buffer_size() << "; \n}\n";
|
||||
|
||||
ofs << "\n// set Membuffer address\n";
|
||||
ofs << "int " << config_->module_name() << "_SetBuffer( void *buffer) { \n";
|
||||
ofs << "\tif (buffer == NULL) {\n"
|
||||
"\t\tMICRO_ERROR(\"memory buffer is NULL\");\n"
|
||||
"\t\treturn RET_ERROR;\n"
|
||||
"\t}\n";
|
||||
ofs << "\t" << ctx_->buffer_name()
|
||||
<< "= buffer; \n"
|
||||
"\treturn RET_OK;";
|
||||
ofs << "}\n";
|
||||
}
|
||||
|
||||
void Generator::CodeNetFileInclude(std::ofstream &ofs) {
|
||||
ofs << g_hwLicense;
|
||||
// need copy head file of microtensor ro dst'dirs
|
||||
ofs << "#include \"microtensor.h\"\n";
|
||||
// copy debug head files to cmake include files
|
||||
ofs << "#include \"" << net_weight_hfile_ << "\"\n"
|
||||
<< "#include \"" << net_inc_hfile_ << "\"\n";
|
||||
if (config_->debug_mode()) {
|
||||
ofs << "#include \"../benchmark/debug_utils.h\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
void Generator::CodeNetRunFunc(std::ofstream &ofs) {
|
||||
// generate net predict code
|
||||
ofs << "void " << config_->module_name() << "_Inference() {\n";
|
||||
|
@ -158,69 +72,30 @@ void Generator::CodeNetRunFunc(std::ofstream &ofs) {
|
|||
ofs << "}\n";
|
||||
}
|
||||
|
||||
int Generator::CodeTestCMakeFile() {
|
||||
int Generator::CodeBenchmarkCMakeFile() {
|
||||
std::string net_main_cmake_file_path = net_main_file_path_;
|
||||
std::string test_cmake_file = net_main_cmake_file_path + "benchmark.cmake";
|
||||
std::ofstream of(test_cmake_file);
|
||||
if (of.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << test_cmake_file;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
std::ofstream ofs(test_cmake_file);
|
||||
MS_CHECK_TRUE(!ofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << test_cmake_file;
|
||||
of << "include_directories(${CMAKE_CURRENT_SOURCE_DIR})\n";
|
||||
of << "include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/)\n";
|
||||
of << "set(SRC_FILES\n";
|
||||
of << "\t\t" << config_->module_name() + "_benchmark.c\n";
|
||||
of << "\t\tload_input.c\n";
|
||||
of << "\t\tdebug_utils.c\n";
|
||||
of << ")\n";
|
||||
of.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int Generator::CodeCMakeExecutableFile(std::ofstream &ofs) const {
|
||||
ofs << "include_directories(${CMAKE_CURRENT_SOURCE_DIR})\n";
|
||||
ofs << "include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/)\n";
|
||||
if (config_->target() == kARM32M) {
|
||||
IncludeCmsisDirectories(ofs);
|
||||
}
|
||||
ofs << "set(OP_SRC\n";
|
||||
for (const std::string &c_file : ctx_->c_files()) {
|
||||
ofs << " " << c_file << ".o\n";
|
||||
}
|
||||
ofs << " " << config_->module_name() << "_weight.c.o\n";
|
||||
ofs << " " << config_->module_name() << ".c.o\n";
|
||||
ofs << "set(SRC_FILES\n";
|
||||
ofs << "\t\t" << config_->module_name() + "_benchmark.c\n";
|
||||
ofs << "\t\tload_input.c\n";
|
||||
ofs << "\t\tdebug_utils.c\n";
|
||||
ofs << ")\n";
|
||||
|
||||
std::set<std::string> kernel_cmake_asm_set_files = ctx_->asm_files();
|
||||
if (!kernel_cmake_asm_set_files.empty()) {
|
||||
ofs << "set(ASSEMBLY_SRC\n";
|
||||
for (const std::string &asm_file : kernel_cmake_asm_set_files) {
|
||||
ofs << " " << asm_file << ".o\n";
|
||||
}
|
||||
ofs << ")\n";
|
||||
ofs << "set_property(SOURCE ${ASSEMBLY_SRC} PROPERTY LANGUAGE C)\n";
|
||||
ofs << "list(APPEND OP_SRC ${ASSEMBLY_SRC})\n";
|
||||
}
|
||||
|
||||
ofs << "file(GLOB NET_SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.c)\n";
|
||||
ofs << "add_library(${PROJ_NAME} STATIC ${NET_SRC})\n";
|
||||
ofs.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int Generator::CodeCMakeFile() {
|
||||
int Generator::CodeSourceCMakeFile() {
|
||||
std::string src_cmake_file = net_src_file_path_ + cmake_file_name_;
|
||||
std::ofstream of(src_cmake_file);
|
||||
if (of.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << src_cmake_file;
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_LOG(INFO) << "write " << src_cmake_file.c_str();
|
||||
if (CodeCMakeExecutableFile(of) != RET_OK) {
|
||||
of.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
of.close();
|
||||
std::ofstream ofs(src_cmake_file);
|
||||
MS_CHECK_TRUE(!ofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << src_cmake_file;
|
||||
CodeCMakeNetLibrary(ofs, config_->module_name(), ctx_, config_->target());
|
||||
ofs.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -243,86 +118,32 @@ int Generator::CodeStaticContent() {
|
|||
return RET_OK;
|
||||
}
|
||||
|
||||
void Generator::CodeWeightInitFunc(const std::map<std::string, Tensor *> &address_map, std::ofstream &ofs) {
|
||||
ofs << "int " << config_->module_name() << "_Init(void *weight_buffer, int weight_size) {\n"
|
||||
<< "\tif (weight_buffer == NULL) {\n"
|
||||
"\t\tMICRO_ERROR(\"weight buffer is NULL\");\n"
|
||||
<< "\t\treturn RET_ERROR;\n"
|
||||
<< "\t}\n";
|
||||
CodeReadModelParams(ctx_->saved_weights(), ctx_->tensors_map(), ofs);
|
||||
for (const auto &block : ctx_->init_contents()) {
|
||||
ofs << "{\n" << block << "\n}\n";
|
||||
}
|
||||
ofs << "return RET_OK;";
|
||||
ofs << "}\n\n";
|
||||
}
|
||||
|
||||
void Generator::CodeFreeResource(const std::map<std::string, Tensor *> &address_map, std::ofstream &ofs) const {
|
||||
ofs << "\tvoid *allocated[] = {";
|
||||
size_t num = 0;
|
||||
for (const auto &item : address_map) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->data_c() != nullptr && tensor->category() != Tensor::Category::CONST_TENSOR) {
|
||||
ofs << name << ", ";
|
||||
num++;
|
||||
}
|
||||
}
|
||||
ofs << "\t};\n";
|
||||
|
||||
ofs << "\tfor (int i = 0; i < " << num << "; ++i) {\n";
|
||||
ofs << "\t\tfree(allocated[i]);\n";
|
||||
ofs << "\t\tallocated[i] = NULL;\n";
|
||||
ofs << "\t}\n";
|
||||
}
|
||||
|
||||
int Generator::CodeWeightFile() {
|
||||
// weight header file
|
||||
std::string hfile = net_src_file_path_ + net_weight_hfile_;
|
||||
std::ofstream hofs(hfile);
|
||||
if (hofs.bad()) {
|
||||
MS_LOG(ERROR) << "open file error" << hfile;
|
||||
return RET_ERROR;
|
||||
}
|
||||
hofs << g_hwLicense;
|
||||
for (const auto &h_file : ctx_->h_files()) {
|
||||
hofs << "#include \"" << h_file << "\"\n";
|
||||
}
|
||||
hofs << "#include <stdlib.h>\n";
|
||||
hofs << "#include <string.h>\n";
|
||||
hofs << "#include \"microtensor.h\"\n\n";
|
||||
hofs << "extern unsigned char *" << ctx_->buffer_name() << ";\n";
|
||||
MS_CHECK_TRUE(!hofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << hfile;
|
||||
CodeWeightFileHeader(hofs, ctx_);
|
||||
|
||||
// weight source file
|
||||
std::string cfile = net_src_file_path_ + config_->module_name() + "_weight.c";
|
||||
std::ofstream cofs(cfile);
|
||||
if (cofs.bad()) {
|
||||
MS_LOG(ERROR) << "open file error" << cfile;
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_CHECK_TRUE(!cofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << cfile;
|
||||
cofs << g_hwLicense;
|
||||
cofs << "#include \"" << net_weight_hfile_ << "\"\n\n";
|
||||
cofs << "unsigned char * " << ctx_->buffer_name() << " = 0 ; \n";
|
||||
|
||||
// reverse key and value of tensors_map
|
||||
std::map<std::string, Tensor *> address_map;
|
||||
for (const auto &item : ctx_->tensors_map()) {
|
||||
address_map.insert(std::make_pair(item.second, item.first));
|
||||
}
|
||||
|
||||
if (config_->is_weight_file()) {
|
||||
std::string net_file = net_src_file_path_ + config_->module_name() + ".net";
|
||||
if (SaveDataToNet(ctx_->saved_weights(), net_file) != RET_OK) {
|
||||
hofs.close();
|
||||
cofs.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
CodeModelParamsDefine(address_map, hofs, cofs);
|
||||
CodeWeightInitFunc(address_map, cofs);
|
||||
SaveDataToNet(ctx_->saved_weights(), net_file);
|
||||
CodeModelParamsForNet(hofs, cofs, ctx_);
|
||||
CodeWeightInitFunc(cofs, config_->module_name(), ctx_);
|
||||
} else {
|
||||
CodeModelParamsDefineAndData(ctx_->saved_weights(), hofs, cofs);
|
||||
CodeModelParamsState(hofs, ctx_->saved_weights());
|
||||
CodeModelParamsData(cofs, ctx_->saved_weights());
|
||||
}
|
||||
|
||||
hofs.close();
|
||||
cofs.close();
|
||||
return RET_OK;
|
||||
|
@ -332,9 +153,9 @@ int Generator::GenerateCode() {
|
|||
MS_CHECK_RET_CODE(CodeNetHFile(), "code net h file failed.");
|
||||
MS_CHECK_RET_CODE(CodeNetCFile(), "code net c file failed.");
|
||||
MS_CHECK_RET_CODE(CodeWeightFile(), "code weight file failed.");
|
||||
MS_CHECK_RET_CODE(CodeCMakeFile(), "code net cmake file failed.");
|
||||
MS_CHECK_RET_CODE(CodeTestFile(), "code test file failed.");
|
||||
MS_CHECK_RET_CODE(CodeTestCMakeFile(), "code test cmake file failed.");
|
||||
MS_CHECK_RET_CODE(CodeSourceCMakeFile(), "code net cmake file failed.");
|
||||
MS_CHECK_RET_CODE(CodeBenchmarkFile(), "code benchmark file failed.");
|
||||
MS_CHECK_RET_CODE(CodeBenchmarkCMakeFile(), "code benchmark cmake file failed.");
|
||||
MS_CHECK_RET_CODE(CodeStaticContent(), "code static content failed.");
|
||||
return RET_OK;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_MICRO_CODER_GENERATOR_H_
|
||||
#define MINDSPORE_MICRO_CODER_GENERATOR_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_GENERATOR_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_H_
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fstream>
|
||||
|
@ -28,13 +28,12 @@
|
|||
#include <vector>
|
||||
#include "include/errorcode.h"
|
||||
#include "src/tensor.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/coder_config.h"
|
||||
#include "coder/coder_context.h"
|
||||
#include "coder/utils/print_utils.h"
|
||||
#include "coder/context.h"
|
||||
#include "coder/utils/type_cast.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
constexpr int kWarmUp = 3;
|
||||
|
||||
class Generator {
|
||||
public:
|
||||
explicit Generator(std::unique_ptr<CoderContext> ctx);
|
||||
|
@ -43,18 +42,12 @@ class Generator {
|
|||
int GenerateCode();
|
||||
|
||||
protected:
|
||||
virtual int CodeTestFile() = 0;
|
||||
virtual int CodeBenchmarkFile() = 0;
|
||||
virtual int CodeNetHFile() = 0;
|
||||
virtual int CodeNetCFile() = 0;
|
||||
virtual int CodeCMakeFile();
|
||||
virtual int CodeWeightFile();
|
||||
|
||||
void CodeNetFileInclude(std::ofstream &ofs);
|
||||
int CodeNetFileInputOutput(std::ofstream &ofs);
|
||||
void CodeNetFileMembuffer(std::ofstream &ofs);
|
||||
void CodeNetRunFunc(std::ofstream &ofs);
|
||||
int CodeGraphInOutQuanArgs(std::ofstream &ofs);
|
||||
void CodeFreeResource(const std::map<std::string, Tensor *> &address_map, std::ofstream &ofs) const;
|
||||
|
||||
Configurator *config_{nullptr};
|
||||
std::unique_ptr<CoderContext> ctx_{nullptr};
|
||||
|
@ -70,10 +63,9 @@ class Generator {
|
|||
std::string net_main_file_path_;
|
||||
|
||||
private:
|
||||
int CodeTestCMakeFile();
|
||||
int CodeBenchmarkCMakeFile();
|
||||
int CodeSourceCMakeFile();
|
||||
int CodeStaticContent();
|
||||
int CodeCMakeExecutableFile(std::ofstream &ofs) const;
|
||||
void CodeWeightInitFunc(const std::map<std::string, Tensor *> &address_map, std::ofstream &ofs);
|
||||
|
||||
std::string cmake_file_name_{"net.cmake"};
|
||||
// the user's generated file's permission
|
||||
|
@ -84,4 +76,4 @@ class Generator {
|
|||
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_MICRO_CODER_GENERATOR_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_H_
|
||||
|
|
|
@ -16,284 +16,75 @@
|
|||
|
||||
#include "coder/generator/inference/inference_generator.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "coder/generator/const_blocks/license.h"
|
||||
#include "coder/generator/component/common_component.h"
|
||||
#include "coder/generator/component/benchmark_component.h"
|
||||
#include "coder/generator/component/const_blocks/license.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
int InferenceGenerator::CodeNetHFile() {
|
||||
std::string net_include_file = net_inc_file_path_ + net_inc_hfile_;
|
||||
std::ofstream ofs(net_include_file);
|
||||
if (ofs.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << net_include_file.c_str();
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_CHECK_TRUE(!ofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << net_include_file;
|
||||
ofs << g_hwLicense;
|
||||
if (config_->code_mode() == CodeMode::Code_Android) {
|
||||
ofs << "#include \"src/runtime/thread_pool.h\"\n";
|
||||
}
|
||||
ofs << "#include \"microtensor.h\"\n\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * set input tensors\n"
|
||||
<< " * @param inputs, the input data ptr's array of the model, the tensors' count of input may be greater than "
|
||||
"one.\n"
|
||||
<< " * @param num, the input data's number of the model.\n"
|
||||
<< " **/\n"
|
||||
<< "int " << config_->module_name() << "_SetInputs(const void **inputs, int num);\n\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * get output tensor of the model \n"
|
||||
<< " **/\n"
|
||||
<< "const MicroTensorList *" << config_->module_name() << "_GetOutputs();\n\n";
|
||||
|
||||
CodeInputAndOutputState(ofs, config_->module_name());
|
||||
if (is_get_quant_args_) {
|
||||
std::vector<Tensor *> graph_inputs = ctx_->graph_inputs();
|
||||
if (graph_inputs.empty()) {
|
||||
MS_LOG(ERROR) << "this graph has no input tensor";
|
||||
ofs.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
size_t total_input_size = std::accumulate(
|
||||
graph_inputs.begin(), graph_inputs.end(), 0UL,
|
||||
[](size_t total_input_size, const Tensor *const tensor) { return total_input_size += tensor->Size(); });
|
||||
ofs << "/**\n";
|
||||
ofs << " * get input sizes of the model \n";
|
||||
ofs << " **/\n";
|
||||
ofs << "inline int " << config_->module_name() << "_GetInputSizes() {\n"
|
||||
<< "\t\t"
|
||||
<< "return " << total_input_size << ";\n"
|
||||
<< "}\n\n";
|
||||
|
||||
ofs << "/**\n";
|
||||
ofs << " * get input and output QuantArgs of the model \n";
|
||||
ofs << " **/\n";
|
||||
ofs << "GraphQuantArgs " << config_->module_name() << "_GetInOutQuantArgs();\n\n";
|
||||
CodeGraphQuantArgsState(ofs, config_->module_name());
|
||||
}
|
||||
|
||||
if (config_->is_weight_file()) {
|
||||
ofs << "/**\n"
|
||||
<< " * @param weightBuffer, the ptr of the model's parameters\n"
|
||||
<< " * @param weightSize, the size of the model's parameters\n"
|
||||
<< " **/\n"
|
||||
<< "int " << config_->module_name() << "_Init(void *weightBuffer, int weightSize);\n\n";
|
||||
CodeInitWeightState(ofs, config_->module_name());
|
||||
}
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * free the memory of packed weights and model's workspace buffer, input address\n"
|
||||
<< " **/\n"
|
||||
<< "void " << config_->module_name() << "_FreeResource();\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * get the memory space size of the inference.\n"
|
||||
<< " **/\n"
|
||||
<< "unsigned int " << config_->module_name() << "_GetBufferSize();\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * set the memory space for the inference\n"
|
||||
<< " **/\n"
|
||||
<< "int " << config_->module_name() << "_SetBuffer(void *buffer);\n\n";
|
||||
|
||||
ofs << "/**\n"
|
||||
<< " * net inference function\n"
|
||||
<< " **/\n"
|
||||
<< "void " << config_->module_name() << "_Inference();\n\n";
|
||||
CodeManageResourceState(ofs, config_->module_name());
|
||||
CodeInferenceState(ofs, config_->module_name());
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int InferenceGenerator::CodeNetCFile() {
|
||||
std::string net_impl_file = net_src_file_path_ + net_src_cfile_;
|
||||
std::ofstream ofs(net_impl_file);
|
||||
if (ofs.bad()) {
|
||||
MS_LOG(ERROR) << "open file error" << net_impl_file.c_str();
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_LOG(DEBUG) << "write " << net_impl_file.c_str();
|
||||
CodeNetFileInclude(ofs);
|
||||
CodeNetFileMembuffer(ofs);
|
||||
MS_CHECK_TRUE(!ofs.bad(), "filed to open file");
|
||||
MS_LOG(INFO) << "write " << net_impl_file;
|
||||
CodeSourceFileInclude(ofs, net_weight_hfile_, net_inc_hfile_);
|
||||
CodeInputAndOutputImplement(ofs, config_->module_name(), ctx_);
|
||||
CodeInitResourceImplement(ofs, config_->module_name(), ctx_);
|
||||
CodeFreeResourceImplement(ofs, config_->module_name(), ctx_);
|
||||
if (is_get_quant_args_) {
|
||||
if (CodeGraphInOutQuanArgs(ofs) != RET_OK) {
|
||||
MS_LOG(ERROR) << "CodeGraphInOutQuanArgs failed";
|
||||
ofs.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
CodeGraphQuantArgsImplement(ofs, config_->module_name(), ctx_);
|
||||
}
|
||||
if (CodeNetFileInputOutput(ofs) != RET_OK) {
|
||||
ofs.close();
|
||||
return RET_ERROR;
|
||||
}
|
||||
ofs << "void " << config_->module_name() << "_FreeResource() {\n";
|
||||
ofs << "\t" << ctx_->buffer_name() << "= NULL;\n";
|
||||
std::vector<Tensor *> inputs = ctx_->graph_inputs();
|
||||
size_t size = inputs.size();
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
ofs << "\t" << ctx_->input_name() + std::to_string(i) << " = NULL;\n";
|
||||
}
|
||||
std::map<std::string, Tensor *> address_map;
|
||||
for (const auto &item : ctx_->tensors_map()) {
|
||||
address_map.insert(std::make_pair(item.second, item.first));
|
||||
}
|
||||
if (config_->is_weight_file()) {
|
||||
CodeFreeResource(address_map, ofs);
|
||||
}
|
||||
ofs << "}\n";
|
||||
CodeNetRunFunc(ofs);
|
||||
ofs.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void InferenceGenerator::CodeTestRelevantHeader(std::ofstream &code_test_ofs) {
|
||||
code_test_ofs << g_hwLicense;
|
||||
code_test_ofs << "#include <stdio.h>\n"
|
||||
"#include <string.h>\n"
|
||||
"#include <stdlib.h>\n"
|
||||
"#include <stdint.h>\n"
|
||||
"#include \"microtensor.h\"\n"
|
||||
"#include \"load_input.h\"\n"
|
||||
"#include \"debug_utils.h\"\n";
|
||||
code_test_ofs << "#include \"" << net_inc_hfile_ << "\"\n";
|
||||
|
||||
code_test_ofs << "/**\n"
|
||||
" * mindspore micro params usage:\n"
|
||||
" * args[0]: executable file\n"
|
||||
" * args[1]: inputs .bin file\n"
|
||||
" * args[2]: model weight .net file\n"
|
||||
" * args[3]: loop count for performance testing\n"
|
||||
" * args[4]: runtime thread num\n"
|
||||
" * args[5]: runtime thread bind mode\n"
|
||||
" */\n";
|
||||
|
||||
code_test_ofs << "\n// Warm up. \n"
|
||||
<< "void " << config_->module_name() << "_WarmUp() {\n"
|
||||
<< "\tfor (int i = 0; i < " << kWarmUp << "; ++i) {\n"
|
||||
<< "\t\t" << config_->module_name() << "_Inference();\n"
|
||||
<< "\t}\n"
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
void InferenceGenerator::CodeTestRelevantTile(std::ofstream &code_test_ofs) {
|
||||
if (config_->code_mode() == Code_Android) {
|
||||
code_test_ofs << " DestroyThreadPool(THREAD_POOL_DEFAULT);\n";
|
||||
}
|
||||
code_test_ofs << " // print model outputs \n";
|
||||
code_test_ofs << " const MicroTensorList *outs = " << config_->module_name() << "_GetOutputs();\n";
|
||||
code_test_ofs << " for (int i = 0; i < outs->num; ++i) {\n"
|
||||
" MicroTensor *tensor = outs->tensor + i;\n"
|
||||
" PrintTensorData(tensor);\n"
|
||||
" }\n";
|
||||
code_test_ofs << " printf(\"" << config_->module_name() << " inference End.\\n\");\n";
|
||||
code_test_ofs << " free(buffer);\n";
|
||||
code_test_ofs << " " << config_->module_name() << "_FreeResource();\n";
|
||||
std::vector<Tensor *> inputs = ctx_->graph_inputs();
|
||||
size_t inputs_num = inputs.size();
|
||||
code_test_ofs << " // this code_block can be ignore \n";
|
||||
code_test_ofs << " for (int i = 0; i < " << inputs_num
|
||||
<< "; ++i) {\n"
|
||||
" free(inputs_binbuf[i]);\n"
|
||||
" }\n";
|
||||
code_test_ofs << " return 0;\n";
|
||||
code_test_ofs << "}\n";
|
||||
}
|
||||
|
||||
int InferenceGenerator::CodeTestFile() {
|
||||
int InferenceGenerator::CodeBenchmarkFile() {
|
||||
std::string net_main_impl_file = net_main_file_path_ + net_main_cfile_;
|
||||
std::ofstream ofs(net_main_impl_file);
|
||||
if (ofs.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << net_main_impl_file.c_str();
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_LOG(INFO) << "write " << net_main_impl_file.c_str();
|
||||
CodeTestRelevantHeader(ofs);
|
||||
ofs << "int main(int argc, char **argv) {\n"
|
||||
" if (argc < 2) { printf(\"There is not input and out file.\\n\"); }\n";
|
||||
ofs << " printf(\"" << config_->module_name() << " inference Start.\\n\");\n";
|
||||
MS_LOG(INFO) << "write " << net_main_impl_file;
|
||||
MS_CHECK_TRUE(!ofs.bad(), "filed to open file");
|
||||
std::vector<Tensor *> inputs = ctx_->graph_inputs();
|
||||
size_t inputs_num = inputs.size();
|
||||
for (size_t i = 0; i < inputs_num; ++i) {
|
||||
Tensor *input = inputs[i];
|
||||
std::vector<int> shape = input->shape();
|
||||
ofs << " // model's input_shape is [ ";
|
||||
for (int sh : shape) {
|
||||
ofs << sh << ", ";
|
||||
}
|
||||
ofs << "];\n";
|
||||
}
|
||||
ofs << " void *inputs_binbuf[" << inputs_num << "];\n";
|
||||
ofs << " int inputs_size[" << inputs_num << "] = {";
|
||||
for (size_t i = 0; i < inputs_num; ++i) {
|
||||
Tensor *input = inputs[i];
|
||||
ofs << input->Size() << ", ";
|
||||
}
|
||||
ofs << "};\n";
|
||||
ofs << " int ret = ReadInputsFile(argv[1], inputs_binbuf, inputs_size, " << inputs_num
|
||||
<< ");\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"read inputs file failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
ofs << " ret = " << config_->module_name() << "_SetInputs((const void **)inputs_binbuf, " << inputs_num
|
||||
<< ");\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"set inputs failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
|
||||
ofs << " unsigned int total_buffer_size = " << config_->module_name() << "_GetBufferSize();\n";
|
||||
ofs << " void *buffer = malloc(total_buffer_size);\n";
|
||||
ofs << " if (buffer == NULL ){\n"
|
||||
" MICRO_ERROR(\"malloc memory buffer failed\");\n"
|
||||
" return RET_ERROR;\n"
|
||||
" }\n";
|
||||
ofs << " ret = " << config_->module_name()
|
||||
<< "_SetBuffer(buffer);\n"
|
||||
" if (ret != RET_OK) {\n"
|
||||
" MICRO_ERROR(\"set inputs failed\");\n"
|
||||
" return RET_ERROR;"
|
||||
" }\n";
|
||||
CodeBenchmarkHeader(ofs, net_inc_hfile_);
|
||||
CodeBenchmarkUsage(ofs);
|
||||
CodeBenchmarkWarmup(ofs, config_->module_name());
|
||||
|
||||
CodeBenchmarkSetInputs(ofs, config_->module_name(), ctx_);
|
||||
CodeBenchmarkSetBuffer(ofs, config_->module_name());
|
||||
if (config_->is_weight_file()) {
|
||||
ofs << " int weightSize = 0;\n";
|
||||
ofs << " void *weightBuffer = ReadInputData(argv[2], &weightSize); \n";
|
||||
ofs << " if(" << config_->module_name() << "_Init(weightBuffer, weightSize) != RET_OK) {\n";
|
||||
ofs << " printf(\"model init failed\");\n";
|
||||
ofs << " " << config_->module_name() << "_FreeResource();\n";
|
||||
ofs << " return RET_ERROR;\n";
|
||||
ofs << " }\n";
|
||||
ofs << " free(weightBuffer);\n";
|
||||
ofs << " weightBuffer = NULL;\n";
|
||||
CodeBenchmarkInitWeight(ofs, config_->module_name());
|
||||
}
|
||||
|
||||
if (config_->code_mode() == CodeMode::Code_Android) {
|
||||
ofs << " int thread_num = 4;\n"
|
||||
" BindMode bind_mode = NO_BIND_MODE;\n"
|
||||
" if (argc >= 6) {\n"
|
||||
" thread_num = atoi(argv[4]);\n"
|
||||
" bind_mode = atoi(argv[5]);\n"
|
||||
" }\n"
|
||||
" ret = ConfigThreadPool(THREAD_POOL_DEFAULT, thread_num, bind_mode);\n"
|
||||
" if (ret != 0) {\n"
|
||||
" printf(\"create thread pool failed\");\n"
|
||||
" }\n";
|
||||
CodeBenchmarkConfigThread(ofs);
|
||||
}
|
||||
ofs << " if (argc >= 4) {\n"
|
||||
<< " " << config_->module_name() << "_WarmUp();\n"
|
||||
<< " uint64_t timeAvg = 0;\n"
|
||||
<< " int loop_count = atoi(argv[3]);\n"
|
||||
<< " printf(\"\\n### begin to run %d\", loop_count);\n"
|
||||
<< " for (int i = 0; i < loop_count; i++) {\n"
|
||||
<< " uint64_t runBegin = GetTimeUs();\n"
|
||||
<< " " << config_->module_name() << "_Inference();\n"
|
||||
<< " uint64_t runEnd = GetTimeUs();\n"
|
||||
<< " uint64_t time = runEnd - runBegin;\n"
|
||||
<< " timeAvg += time;\n"
|
||||
<< " }\n"
|
||||
<< " float cunCost = (float)timeAvg / 1000.0f;\n"
|
||||
<< " printf(\"\\n###Run over, total time:\\t %5.5f ms.\\n\", cunCost);\n"
|
||||
<< " printf(\"\\n###Run over, predict per time:\\t %5.5f ms.\\n\", cunCost / loop_count);\n"
|
||||
<< " }\n";
|
||||
ofs << " " << config_->module_name() << "_Inference();\n";
|
||||
CodeTestRelevantTile(ofs);
|
||||
CodeBenchmarkInference(ofs, config_->module_name());
|
||||
CodeBenchmarkPrintOutputs(ofs, config_->module_name());
|
||||
|
||||
CodeBenchmarkFreeResourse(ofs, config_->module_name(), inputs_num);
|
||||
ofs.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_MICRO_CODER_ANDROID_GENERATOR_H_
|
||||
#define MINDSPORE_MICRO_CODER_ANDROID_GENERATOR_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_GENERATOR_INFERENCE_GENERATOR_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GENERATOR_INFERENCE_GENERATOR_H_
|
||||
|
||||
#include <utility>
|
||||
#include <memory>
|
||||
|
@ -27,15 +27,11 @@ class InferenceGenerator : public Generator {
|
|||
explicit InferenceGenerator(std::unique_ptr<CoderContext> ctx) : Generator(std::move(ctx)) {}
|
||||
~InferenceGenerator() override = default;
|
||||
|
||||
protected:
|
||||
private:
|
||||
int CodeNetHFile() override;
|
||||
int CodeNetCFile() override;
|
||||
|
||||
int CodeTestFile() override;
|
||||
|
||||
private:
|
||||
void CodeTestRelevantHeader(std::ofstream &code_test_ofs);
|
||||
void CodeTestRelevantTile(std::ofstream &code_test_ofs);
|
||||
int CodeBenchmarkFile() override;
|
||||
};
|
||||
} // namespace mindspore::lite::micro
|
||||
#endif // MINDSPORE_MICRO_CODER_ANDROID_GENERATOR_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GENERATOR_INFERENCE_GENERATOR_H_
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
/**
|
||||
* 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/generator/utils/generator_utils.h"
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <string>
|
||||
#include "include/errorcode.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/utils/print_utils.h"
|
||||
#include "src/common/file_utils.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
int WriteContentToFile(const std::string &file, const std::string &content) {
|
||||
std::ofstream of(file);
|
||||
if (of.bad()) {
|
||||
MS_LOG(ERROR) << "open file error " << file.c_str();
|
||||
return RET_ERROR;
|
||||
}
|
||||
MS_LOG(INFO) << "write " << file.c_str();
|
||||
of << content;
|
||||
of.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CodeReadModelParams(const std::map<std::string, Tensor *> &saved_weights,
|
||||
const std::map<Tensor *, std::string> &tensors_map, std::ofstream &ofs) {
|
||||
ofs << "\n\tstruct ModelParameter {\n"
|
||||
<< "\t\tvoid *addr;\n"
|
||||
<< "\t\tsize_t size;\n"
|
||||
<< "\t\tsize_t offset;\n"
|
||||
<< "\t};\n";
|
||||
|
||||
size_t params_num = 0;
|
||||
size_t offset = 0;
|
||||
ofs << "\n\tstruct ModelParameter model_params[] = {\n";
|
||||
for (const auto &item : saved_weights) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
auto iter = std::find_if(tensors_map.begin(), tensors_map.end(),
|
||||
[&tensor](const std::pair<Tensor *, std::string> &t) { return t.first == tensor; });
|
||||
if (iter != tensors_map.end()) {
|
||||
ofs << "\t\t{" << name << ", " << tensor->Size() << ", " << offset << "},\n";
|
||||
params_num++;
|
||||
}
|
||||
offset += tensor->Size();
|
||||
}
|
||||
}
|
||||
ofs << "\t};\n";
|
||||
|
||||
offset = 0;
|
||||
for (const auto &item : saved_weights) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
auto iter = std::find_if(tensors_map.begin(), tensors_map.end(),
|
||||
[&tensor](const std::pair<Tensor *, std::string> &t) { return t.first == tensor; });
|
||||
if (iter == tensors_map.end()) {
|
||||
TypeId data_type = tensor->data_type();
|
||||
ofs << "\t" << GetTensorDataType(data_type) << "*" << name << " = (weight_buffer + " << offset << ");\n";
|
||||
}
|
||||
offset += tensor->Size();
|
||||
}
|
||||
}
|
||||
ofs << "\n";
|
||||
|
||||
ofs << "\tfor(int i = 0; i < " << params_num << "; ++i) {\n"
|
||||
<< "\t\tif (model_params[i].offset + model_params[i].size > weight_size) {\n"
|
||||
"\t\t\tMICRO_ERROR(\"buffer is invalid, size: %d, offset: %lu\", weight_size, model_params[i].offset);\n"
|
||||
"\t\t\treturn RET_ERROR;\n"
|
||||
"\t\t}\n"
|
||||
<< "\t\tmemcpy(model_params[i].addr, (weight_buffer + model_params[i].offset), model_params[i].size);\n"
|
||||
<< "\t}\n";
|
||||
}
|
||||
|
||||
int SaveDataToNet(const std::map<std::string, Tensor *> &tensors_map, const std::string &net_file) {
|
||||
std::ofstream out(net_file, std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
MS_CHECK_TRUE(out.is_open(), "net file open failed!");
|
||||
for (auto &item : tensors_map) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
out.write(reinterpret_cast<const char *>(tensor->data_c()), tensor->Size());
|
||||
}
|
||||
}
|
||||
out.close();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CodeModelParamsDefine(const std::map<std::string, Tensor *> &address_map, std::ofstream &hfile,
|
||||
std::ofstream &cfile) {
|
||||
for (auto &item : address_map) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
PrintTensorForNet(tensor, cfile, hfile, name);
|
||||
} else if (tensor->category() == Tensor::Category::VAR) {
|
||||
hfile << "extern " << GetTensorDataType(tensor->data_type()) << " *" << name << ";\n";
|
||||
cfile << GetTensorDataType(tensor->data_type()) << "*" << name << " = NULL;\n";
|
||||
}
|
||||
}
|
||||
cfile << "\n";
|
||||
}
|
||||
|
||||
void CodeModelParamsDefineAndData(const std::map<std::string, Tensor *> &address_map, std::ofstream &hfile,
|
||||
std::ofstream &cfile) {
|
||||
for (auto &item : address_map) {
|
||||
std::string name = item.first;
|
||||
Tensor *tensor = item.second;
|
||||
if (tensor->category() == Tensor::Category::CONST_TENSOR) {
|
||||
if (tensor->data_c() == nullptr) {
|
||||
continue;
|
||||
}
|
||||
PrintTensor(tensor, cfile, hfile, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PrintMicroTensors(std::ofstream &ofs, std::vector<Tensor *> tensors, const std::string &name,
|
||||
const std::map<Tensor *, std::string> &tensors_map) {
|
||||
for (size_t index = 0; index < tensors.size(); ++index) {
|
||||
Tensor *tensor = tensors[index];
|
||||
auto item = tensors_map.find(tensor);
|
||||
if (item == tensors_map.end()) {
|
||||
MS_LOG(ERROR) << "nonexistent tensor";
|
||||
return RET_ERROR;
|
||||
}
|
||||
ofs << " static int dim[] = {";
|
||||
for (size_t i = 0; i < tensor->shape().size(); ++i) {
|
||||
ofs << tensor->shape()[i] << ", ";
|
||||
}
|
||||
ofs << "};\n";
|
||||
ofs << " " << name << "[" << index << "].ndim = " << tensor->shape().size() << ";\n";
|
||||
ofs << " " << name << "[" << index << "].dim = dim;\n";
|
||||
ofs << " " << name << "[" << index << "].type = " << GetMicroTensorDataType(tensor->data_type()) << ";\n";
|
||||
ofs << " " << name << "[" << index << "].format = " << std::to_string(tensor->format()) << ";\n";
|
||||
ofs << " " << name << "[" << index << "].data =" << item->second << ";\n";
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void IncludeCmsisDirectories(std::ofstream &ofs) {
|
||||
ofs << "include_directories(${OP_HEADER_PATH}/cmsis)\n";
|
||||
ofs << "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/NN/Include)\n";
|
||||
ofs << "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/DSP/Include)\n";
|
||||
ofs << "include_directories(${OP_HEADER_PATH}/cmsis/CMSIS/Core/Include)\n";
|
||||
}
|
||||
|
||||
} // namespace mindspore::lite::micro
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* 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_MICRO_CODER_GENERATOR_GENERATOR_UTILS_H_
|
||||
#define MINDSPORE_MICRO_CODER_GENERATOR_GENERATOR_UTILS_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "src/tensor.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
|
||||
int WriteContentToFile(const std::string &file, const std::string &content);
|
||||
|
||||
void CodeReadModelParams(const std::map<std::string, Tensor *> &saved_weights,
|
||||
const std::map<Tensor *, std::string> &tensors_map, std::ofstream &ofs);
|
||||
|
||||
int SaveDataToNet(const std::map<std::string, Tensor *> &tensors_map, const std::string &net_file);
|
||||
|
||||
void CodeModelParamsDefine(const std::map<std::string, Tensor *> &address_map, std::ofstream &hfile,
|
||||
std::ofstream &cfile);
|
||||
|
||||
void CodeModelParamsDefineAndData(const std::map<std::string, Tensor *> &address_map, std::ofstream &hfile,
|
||||
std::ofstream &cfile);
|
||||
|
||||
int PrintMicroTensors(std::ofstream &ofs, std::vector<Tensor *> tensors, const std::string &name,
|
||||
const std::map<Tensor *, std::string> &tensors_map);
|
||||
|
||||
void IncludeCmsisDirectories(std::ofstream &ofs);
|
||||
|
||||
} // namespace mindspore::lite::micro
|
||||
|
||||
#endif // MINDSPORE_MICRO_CODER_GENERATOR_GENERATOR_UTILS_H_
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/coder_graph.h"
|
||||
#include "micro/coder/graph.h"
|
||||
#include <queue>
|
||||
#include <deque>
|
||||
#include <string>
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_GRAPH_NODE_H_
|
||||
#define MICRO_CODER_GRAPH_NODE_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_GRAPH_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_GRAPH_H_
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include "schema/inner/model_generated.h"
|
||||
#include "src/common/graph_util.h"
|
||||
#include "src/tensor.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
class CoderGraph {
|
||||
public:
|
||||
|
@ -80,4 +81,4 @@ class CoderGraph {
|
|||
Model *model_{nullptr};
|
||||
};
|
||||
} // namespace mindspore::lite::micro
|
||||
#endif // MICRO_CODER_GRAPH_NODE_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_GRAPH_H_
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_LOG_H_
|
||||
#define MICRO_LOG_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_LOG_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_LOG_H_
|
||||
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "include/errorcode.h"
|
||||
|
@ -86,6 +86,23 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define MS_CHECK_TRUE_WITH_EXE(code, msg, FUNC) \
|
||||
do { \
|
||||
if (!(code)) { \
|
||||
MS_LOG(ERROR) << msg; \
|
||||
FUNC; \
|
||||
return mindspore::lite::RET_ERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MS_CHECK_TRUE_WITHOUT_RET(code, msg) \
|
||||
do { \
|
||||
if (!(code)) { \
|
||||
MS_LOG(ERROR) << msg; \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MS_CHECK_TRUE_RET_NULL(code, msg) \
|
||||
do { \
|
||||
if (!(code)) { \
|
||||
|
@ -102,4 +119,4 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // MICRO_LOG_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_LOG_H_
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/add_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/add_int8_coder.h"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "nnacl/arithmetic.h"
|
||||
#include "nnacl/int8/quantize.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "micro/coder/log.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/log.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Add;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_CMSIS_NN_ADD_INT8_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "nnacl/int8/quantize.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/base/conv2d_base_coder.h"
|
||||
#include "coder/opcoders/base/conv2d_base_coder.h"
|
||||
#include "nnacl/conv_parameter.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/conv2d_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/conv2d_int8_coder.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/dwconv_int8_coder.h"
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/dwconv_int8_coder.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Conv2D;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "nnacl/conv_parameter.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/dwconv_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/dwconv_int8_coder.h"
|
||||
#include <string>
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "micro/coder/log.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/log.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_DepthwiseConv2D;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_CMSIS_NN_DWCONV_INT8_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/conv2d_base_coder.h"
|
||||
#include "src/runtime/kernel/arm/int8/convolution_depthwise_int8.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/fullconnection_int8_coder.h"
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/fullconnection_int8_coder.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_FullConnection;
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/mul_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/mul_int8_coder.h"
|
||||
#include <string>
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "nnacl/int8/quantize.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Mul;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_CMSIS_NN_MUL_INT8_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
class MulInt8Coder final : public OperatorCoder {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/pooling_int8_coder.h"
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/pooling_int8_coder.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Pooling;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/int8/pooling_int8.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/reshape_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/reshape_int8_coder.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Reshape;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_CMSIS_NN_RESHAPE_INT8_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
class ReshapeInt8Coder final : public OperatorCoder {
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/cmsis-nn/int8/softmax_int8_coder.h"
|
||||
#include "coder/opcoders/cmsis-nn/int8/softmax_int8_coder.h"
|
||||
#include <limits>
|
||||
#include "micro/coder/opcoders/serializers/serializer.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/serializers/serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_SoftMax;
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/base/softmax_base_coder.h"
|
||||
#include "coder/opcoders/base/softmax_base_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::cmsis {
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/coder_context.h"
|
||||
#include "coder/context.h"
|
||||
|
||||
namespace mindspore::lite::micro {
|
||||
void Collect(CoderContext *const ctx, const std::vector<std::string> &headers,
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_OPCODERS_FP32_ACTIVATIONFP32_CODER_H_
|
||||
#define MICRO_CODER_OPCODERS_FP32_ACTIVATIONFP32_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ACTIVATIONFP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ACTIVATIONFP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_ADDN_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_ADDN_FP32_CODER_H_
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class AddNFP32Coder final : public OperatorCoder {
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
* 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 "coder/opcoders/nnacl/fp32/arithmetic_fp32_coder.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "nnacl/fp32/arithmetic_fp32.h"
|
||||
#include "micro/coder/log.h"
|
||||
#include "coder/log.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
#define MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/fp32/arithmetic_fp32.h"
|
||||
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#define DEFAULT_ARITHMETIC_NDIMS 10
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
@ -106,4 +106,4 @@ class ArithmeticFP32Coder final : public OperatorCoder {
|
|||
LiteDataType data_type_{kDataTypeFloat};
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_FP32_CODER_H_
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/arithmetic_self_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
#define MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/fp32/arithmetic_self_fp32.h"
|
||||
#include "nnacl/arithmetic_self_parameter.h"
|
||||
|
||||
|
@ -106,4 +106,4 @@ class ArithmeticSelfFP32Coder final : public OperatorCoder {
|
|||
std::string arithmetic_self_run_;
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_ARITHMETIC_SELF_FP32_CODER_H_
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_ASSIGN_ADD_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/base/tile_base.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
* 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 "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"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_BatchNorm;
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
|
||||
#define MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_BATCHNORM_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
@ -40,4 +40,4 @@ class BatchnormFP32Coder final : public OperatorCoder {
|
|||
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
|
||||
#endif // MICRO_CODER_OPCODERS_FP32_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CODER_H_
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* 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 "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Concat;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_CONCAT_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/concat_parameter.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/convolution_depthwise_fp32_coder.h"
|
||||
#include <string>
|
||||
#include "micro/coder/log.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_DepthwiseConv2D;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
int ConvolutionDepthwiseFP32Coder::Prepare(CoderContext *const context) {
|
||||
Conv2DBaseCoder::Init();
|
||||
MS_CHECK_RET_CODE(InitWeightBias(), "dwconvolution do init weightbais failed");
|
||||
conv_param_->thread_num_ = MSMIN(thread_num_, conv_param_->output_h_);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionDepthwiseFP32Coder::InitWeightBias() {
|
||||
// init weight: o, h, w, i; o == group, i == 1
|
||||
auto *origin_weight = reinterpret_cast<float *>(filter_tensor_->data_c());
|
||||
int channel = filter_tensor_->Batch();
|
||||
size_t pack_weight_size = filter_tensor_->Batch() * filter_tensor_->Height() * filter_tensor_->Width();
|
||||
size_t packed_weight_data_size = pack_weight_size * sizeof(float);
|
||||
packed_weight_ =
|
||||
reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, packed_weight_data_size, kOfflinePackWeight));
|
||||
MS_CHECK_PTR(packed_weight_);
|
||||
MS_CHECK_RET_CODE(memset_s(packed_weight_, packed_weight_data_size, 0, packed_weight_data_size),
|
||||
"memset packed weight failed!");
|
||||
PackNCHWToNHWCFp32(origin_weight, packed_weight_, 1, filter_tensor_->Height() * filter_tensor_->Width(), channel);
|
||||
|
||||
auto channel_size = static_cast<size_t>(channel);
|
||||
auto bias_size = static_cast<size_t>(channel_size * sizeof(float));
|
||||
bias_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, bias_size, kOfflinePackWeight));
|
||||
MS_CHECK_PTR(bias_);
|
||||
MS_CHECK_RET_CODE(memset_s(bias_, bias_size, 0, bias_size), "memset bias failed!");
|
||||
// init bias
|
||||
if (input_tensors_.size() == kInputSize2) {
|
||||
auto *ori_bias = reinterpret_cast<float *>(bias_tensor_->data_c());
|
||||
MS_CHECK_TRUE(bias_tensor_->ElementsNum() > 0, "invalid bias length");
|
||||
MS_CHECK_RET_CODE(memcpy_s(bias_, static_cast<size_t>(bias_tensor_->ElementsNum() * sizeof(float)), ori_bias,
|
||||
static_cast<size_t>(bias_tensor_->ElementsNum() * sizeof(float))),
|
||||
"memcpy_s bias failed!");
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionDepthwiseFP32Coder::DoCode(CoderContext *const context) {
|
||||
MS_CHECK_TRUE(conv_param_->input_channel_ == conv_param_->output_channel_,
|
||||
"Only support input channel equals output channel.");
|
||||
// generate code .h .c
|
||||
Collect(context, {"nnacl/fp32/conv_depthwise.h"}, {"conv_depthwise.c"});
|
||||
|
||||
nnacl::NNaclFp32Serializer code;
|
||||
// call the op function
|
||||
code.CodeStruct("conv_parameter", *conv_param_);
|
||||
int task_id = 0;
|
||||
code.CodeFunction("ConvDw", output_tensor_, input_tensor_, packed_weight_, bias_, "&conv_parameter", task_id);
|
||||
context->AppendCode(code.str());
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_DepthwiseConv2D,
|
||||
CPUOpCoderCreator<ConvolutionDepthwiseFP32Coder>)
|
||||
} // namespace mindspore::lite::micro::nnacl
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_DEPTHWISE_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_DEPTHWISE_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/base/conv2d_base_coder.h"
|
||||
#include "src/runtime/kernel/arm/fp32/convolution_depthwise_fp32.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ConvolutionDepthwiseFP32Coder final : public Conv2DBaseCoder {
|
||||
public:
|
||||
ConvolutionDepthwiseFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
|
||||
const Model::Node *node, size_t node_index, Target target)
|
||||
: Conv2DBaseCoder(in_tensors, out_tensors, node, node_index, target) {}
|
||||
|
||||
~ConvolutionDepthwiseFP32Coder() override = default;
|
||||
int Prepare(CoderContext *const context) override;
|
||||
|
||||
int DoCode(CoderContext *const context) override;
|
||||
|
||||
private:
|
||||
int InitWeightBias();
|
||||
float *packed_weight_{nullptr};
|
||||
float *bias_{nullptr};
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_DEPTHWISE_FP32_CODER_H_
|
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* 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/convolution_fp32_coder.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/nnacl/fp32/convolution_winograd_fp32_coder.h"
|
||||
#include "nnacl/fp32/winograd_utils.h"
|
||||
#include "src/ops/populate/populate_register.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "micro/coder/log.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Conv2D;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
int ConvolutionFP32Coder::InitTmpBuffer() {
|
||||
int in_channel = conv_param_->input_channel_;
|
||||
int uint_size;
|
||||
if (target_ == kARM32A) {
|
||||
uint_size = conv_param_->kernel_h_ * conv_param_->kernel_w_ * in_channel * C4NUM * thread_num_;
|
||||
} else {
|
||||
uint_size = conv_param_->kernel_h_ * conv_param_->kernel_w_ * in_channel * C12NUM * thread_num_;
|
||||
}
|
||||
packed_input_size_ = uint_size * sizeof(float);
|
||||
packed_input_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, packed_input_size_, kWorkspace));
|
||||
col_major_input_size_ = uint_size * sizeof(float);
|
||||
col_major_input_ =
|
||||
reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, col_major_input_size_, kWorkspace));
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionFP32Coder::Prepare(CoderContext *const context) {
|
||||
int ret = Conv2DBaseCoder::Init();
|
||||
MS_CHECK_RET_CODE(ret, "Conv2DBaseCoder::Init() failed.");
|
||||
ret = InitWeightBias(context);
|
||||
MS_CHECK_RET_CODE(ret, "Init weight bias failed.");
|
||||
return Resize();
|
||||
}
|
||||
|
||||
int ConvolutionFP32Coder::Resize() {
|
||||
int ret = Conv2DBaseCoder::CheckResizeValid();
|
||||
MS_CHECK_RET_CODE(ret, "Resize is invalid.");
|
||||
ret = Conv2DBaseCoder::Init();
|
||||
MS_CHECK_RET_CODE(ret, "init failed.");
|
||||
ret = InitTmpBuffer();
|
||||
MS_CHECK_RET_CODE(ret, "init tmp buffer failed.");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionFP32Coder::InitWeightBias(CoderContext *const context) {
|
||||
int kernel_h = filter_tensor_->Height();
|
||||
int kernel_w = filter_tensor_->Width();
|
||||
int in_channel = filter_tensor_->Channel();
|
||||
int out_channel = filter_tensor_->Batch();
|
||||
conv_param_->input_channel_ = in_channel;
|
||||
conv_param_->output_channel_ = out_channel;
|
||||
int kernel_plane = kernel_h * kernel_w;
|
||||
const int oc_block = C8NUM;
|
||||
int oc_block_num = UP_DIV(out_channel, C8NUM);
|
||||
int pack_weight_size = oc_block_num * oc_block * in_channel * kernel_plane;
|
||||
|
||||
auto origin_weight = reinterpret_cast<float *>(filter_tensor_->MutableData());
|
||||
MS_CHECK_PTR(origin_weight);
|
||||
packed_weight_ = reinterpret_cast<float *>(
|
||||
allocator_->Malloc(kNumberTypeFloat32, pack_weight_size * sizeof(float), kOnlinePackWeight));
|
||||
MS_CHECK_PTR(packed_weight_);
|
||||
auto out_channel_size = static_cast<size_t>(out_channel);
|
||||
|
||||
NNaclFp32Serializer code;
|
||||
code.CodeMallocExpression(packed_weight_, pack_weight_size * sizeof(float));
|
||||
code.CodeFunction("memset", packed_weight_, 0, pack_weight_size * sizeof(float));
|
||||
code.CodeFunction("RowMajor2Col8Major", filter_tensor_, packed_weight_, out_channel_size, in_channel * kernel_plane);
|
||||
|
||||
auto bias_data_size = static_cast<size_t>(oc_block_num * oc_block * sizeof(float));
|
||||
bias_data_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, bias_data_size, kOnlinePackWeight));
|
||||
MS_CHECK_PTR(bias_data_);
|
||||
if (input_tensors_.size() == kInputSize2) {
|
||||
code.CodeMallocExpression(bias_data_, bias_data_size);
|
||||
code.CodeFunction("memset", bias_data_, 0, bias_data_size);
|
||||
code.CodeFunction("memcpy", bias_data_, bias_tensor_, out_channel_size * sizeof(float));
|
||||
} else {
|
||||
return RET_ERROR;
|
||||
}
|
||||
context->AppendInitCode(code.str());
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionFP32Coder::DoCode(CoderContext *const context) {
|
||||
{
|
||||
std::vector<string> asmFiles;
|
||||
if (target_ == kARM32A) {
|
||||
asmFiles = {"MatmulFp32.S",
|
||||
"MatmulFp32Opt.S",
|
||||
"PreSum4x16Int8Peroc.S",
|
||||
"PreSum4x16Int8Pert.S",
|
||||
"IndirectGemmInt16to32_8x4.S",
|
||||
"MatmulInt8.S"};
|
||||
} else if (target_ == kARM64) {
|
||||
asmFiles = {"MatmulFp32.S", "MatmulFp32Opt.S", "PreSum4x16Int8Peroc.S", "MatVecMulFp32.S",
|
||||
"PreSum4x16Int8Peroc.S", "PreSum4x16Int8Pert.S", "IndirectGemmInt16to32_8x4.S", "MatmulInt8.S"};
|
||||
}
|
||||
Collect(context,
|
||||
{"nnacl/kernel/fp32/conv_fp32_slim.h", "nnacl/fp32/matmul.h", "nnacl/conv_parameter.h", "nnacl/op_base.h"},
|
||||
{"common_func.c", "conv_fp32_slim.c", "matmul.c"}, asmFiles);
|
||||
}
|
||||
NNaclFp32Serializer code;
|
||||
// call the op function
|
||||
code.CodeFunction("memset", packed_input_, "0", packed_input_size_);
|
||||
code.CodeFunction("memset", col_major_input_, "0", col_major_input_size_);
|
||||
code.CodeStruct("conv_parameter", *conv_param_);
|
||||
int task_id = 0;
|
||||
code.CodeFunction("ConvFp32Slim", input_tensor_, packed_input_, packed_weight_, bias_data_, col_major_input_,
|
||||
output_tensor_, task_id, "(ConvParameter *)&conv_parameter");
|
||||
|
||||
context->AppendCode(code.str());
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
std::unique_ptr<OperatorCoder> CPUConvolutionFP32CoderCreator(const std::vector<Tensor *> &in_tensors,
|
||||
const std::vector<Tensor *> &out_tensors,
|
||||
const Model::Node *node, size_t node_index,
|
||||
Target target) {
|
||||
std::vector<Tensor *> inputs = in_tensors;
|
||||
std::vector<Tensor *> outputs = out_tensors;
|
||||
auto primitive = node->primitive_;
|
||||
if (!primitive) {
|
||||
return nullptr;
|
||||
}
|
||||
OpParameter *parameter =
|
||||
PopulateRegistry::GetInstance()->GetParameterCreator((schema::PrimitiveType(primitive->Type())))(primitive);
|
||||
if (parameter == nullptr) {
|
||||
MS_LOG(ERROR) << "PopulateParameter return nullptr, type: "
|
||||
<< schema::EnumNamePrimitiveType((schema::PrimitiveType)(primitive->Type()));
|
||||
return nullptr;
|
||||
}
|
||||
auto conv_param = reinterpret_cast<ConvParameter *>(parameter);
|
||||
bool use_winograd = false;
|
||||
int out_unit = 0;
|
||||
int kernel_h = conv_param->kernel_h_;
|
||||
int kernel_w = conv_param->kernel_w_;
|
||||
conv_param->input_h_ = inputs.at(kInputIndex)->Height();
|
||||
conv_param->input_w_ = inputs.at(kInputIndex)->Width();
|
||||
conv_param->input_channel_ = inputs.at(kInputIndex)->Channel();
|
||||
conv_param->output_h_ = outputs.at(kOutputIndex)->Height();
|
||||
conv_param->output_w_ = outputs.at(kOutputIndex)->Width();
|
||||
conv_param->output_channel_ = outputs.at(kOutputIndex)->Channel();
|
||||
conv_param->op_parameter_.thread_num_ = 1;
|
||||
CheckIfUseWinograd(&use_winograd, &out_unit, conv_param);
|
||||
free(parameter);
|
||||
// weight de quant
|
||||
std::unique_ptr<OperatorCoder> coder;
|
||||
if (kernel_h == 1 && kernel_w == 1) {
|
||||
MS_LOG(DEBUG) << "create ConvolutionFP32Coder";
|
||||
coder = CPUOpCoderCreator<ConvolutionFP32Coder>(in_tensors, out_tensors, node, node_index, target);
|
||||
} else if (use_winograd) {
|
||||
MS_LOG(DEBUG) << "create Conv2DWinogradFP32Coder";
|
||||
coder = std::make_unique<ConvolutionWinogradFP32Coder>(in_tensors, out_tensors, node, node_index, target, out_unit);
|
||||
} else {
|
||||
MS_LOG(DEBUG) << "create ConvolutionFP32Coder";
|
||||
coder = CPUOpCoderCreator<ConvolutionFP32Coder>(in_tensors, out_tensors, node, node_index, target);
|
||||
}
|
||||
return coder;
|
||||
}
|
||||
|
||||
REG_OPERATOR_CODER(kAllTargets, kNumberTypeFloat32, PrimitiveType_Conv2D, CPUConvolutionFP32CoderCreator)
|
||||
} // namespace mindspore::lite::micro::nnacl
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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_FP32_CONVOLUTION_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "nnacl/conv_parameter.h"
|
||||
#include "micro/coder/opcoders/base/conv2d_base_coder.h"
|
||||
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ConvolutionFP32Coder final : public Conv2DBaseCoder {
|
||||
public:
|
||||
ConvolutionFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
|
||||
const Model::Node *node, size_t node_index, Target target)
|
||||
: Conv2DBaseCoder(in_tensors, out_tensors, node, node_index, target) {}
|
||||
|
||||
int Prepare(CoderContext *const context) override;
|
||||
|
||||
int DoCode(CoderContext *const context) override;
|
||||
|
||||
~ConvolutionFP32Coder() override = default;
|
||||
|
||||
private:
|
||||
int InitWeightBias(CoderContext *const context);
|
||||
|
||||
int InitTmpBuffer();
|
||||
|
||||
int Resize();
|
||||
|
||||
float *packed_weight_{nullptr};
|
||||
|
||||
float *bias_data_{nullptr};
|
||||
|
||||
float *packed_input_{nullptr};
|
||||
|
||||
size_t packed_input_size_{0};
|
||||
|
||||
int thread_stride_{0};
|
||||
|
||||
int thread_count_{0};
|
||||
|
||||
float *col_major_input_{nullptr};
|
||||
size_t col_major_input_size_{0};
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_FP32_CODER_H_
|
|
@ -0,0 +1,247 @@
|
|||
/**
|
||||
* 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/convolution_winograd_fp32_coder.h"
|
||||
#include <array>
|
||||
#include "nnacl/base/minimal_filtering_generator.h"
|
||||
#include "micro/coder/log.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
const std::array<std::string, 9> InputTransFuncList = {
|
||||
"", "", "", "", "InputTransform4x4Unit", "", "InputTransform6x6Unit", "", "InputTransform8x8Unit"};
|
||||
|
||||
const std::array<std::string, 4> OutputTransFuncList4 = {"", "", "OutputTransform4x2Unit", "OutputTransform4x3Unit"};
|
||||
|
||||
const std::array<std::string, 4> OutputTransFuncReluList4 = {"", "", "OutputTransform4x2ReluUnit",
|
||||
"OutputTransform4x3ReluUnit"};
|
||||
|
||||
const std::array<std::string, 4> OutputTransFuncRelu6List4 = {"", "", "OutputTransform4x2Relu6Unit",
|
||||
"OutputTransform4x3Relu6Unit"};
|
||||
const std::array<std::string, 6> OutputTransFuncList6 = {
|
||||
"", "", "OutputTransform6x2Unit", "OutputTransform6x3Unit", "OutputTransform6x4Unit", "OutputTransform6x5Unit"};
|
||||
|
||||
const std::array<std::string, 8> OutputTransFuncReluList6 = {"",
|
||||
"",
|
||||
"OutputTransform6x2ReluUnit",
|
||||
"OutputTransform6x3ReluUnit",
|
||||
"OutputTransform6x4ReluUnit",
|
||||
"OutputTransform6x5ReluUnit"};
|
||||
|
||||
const std::array<std::string, 8> OutputTransFuncRelu6List6 = {"",
|
||||
"",
|
||||
"OutputTransform6x2Relu6Unit",
|
||||
"OutputTransform6x3Relu6Unit",
|
||||
"OutputTransform6x4Relu6Unit",
|
||||
"OutputTransform6x5Relu6Unit"};
|
||||
|
||||
const std::array<std::string, 8> OutputTransFuncList8 = {"",
|
||||
"",
|
||||
"OutputTransform8x2Unit",
|
||||
"OutputTransform8x3Unit",
|
||||
"OutputTransform8x4Unit",
|
||||
"OutputTransform8x5Unit",
|
||||
"OutputTransform8x6Unit",
|
||||
"OutputTransform8x7Unit"};
|
||||
|
||||
const std::array<std::string, 8> OutputTransFuncReluList8 = {"",
|
||||
"",
|
||||
"OutputTransform8x2ReluUnit",
|
||||
"OutputTransform8x3ReluUnit",
|
||||
"OutputTransform8x4ReluUnit",
|
||||
"OutputTransform8x5ReluUnit",
|
||||
"OutputTransform8x6ReluUnit",
|
||||
"OutputTransform8x7ReluUnit"};
|
||||
const std::array<std::string, 8> OutputTransFuncRelu6List8 = {"",
|
||||
"",
|
||||
"OutputTransform8x2Relu6Unit",
|
||||
"OutputTransform8x3Relu6Unit",
|
||||
"OutputTransform8x4Relu6Unit",
|
||||
"OutputTransform8x5Relu6Unit",
|
||||
"OutputTransform8x6Relu6Unit",
|
||||
"OutputTransform8x7Relu6Unit"};
|
||||
|
||||
int ConvolutionWinogradFP32Coder::WinogradFilterTransform(const float *weight_data, float *matrix_g,
|
||||
const float *matrix_gt, int oc_block) {
|
||||
MS_CHECK_TRUE(oc_block, "Divide by zero!");
|
||||
return WinogradWeightTransform(weight_data, trans_weight_, matrix_g, matrix_gt, oc_block, input_unit_, kernel_unit_,
|
||||
conv_param_->input_channel_, conv_param_->output_channel_, true);
|
||||
}
|
||||
|
||||
int ConvolutionWinogradFP32Coder::InitTmpBuffer() {
|
||||
int channel_out = conv_param_->output_channel_;
|
||||
int oc8 = UP_DIV(channel_out, C8NUM);
|
||||
int tile_num = C12NUM;
|
||||
tile_buffer_size_ = thread_num_ * tile_num * input_unit_ * input_unit_ * conv_param_->input_channel_ * sizeof(float);
|
||||
trans_input_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, tile_buffer_size_, kWorkspace));
|
||||
gemm_out_size_ = thread_num_ * tile_num * input_unit_ * input_unit_ * oc8 * C8NUM * sizeof(float);
|
||||
gemm_out_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, gemm_out_size_, kWorkspace));
|
||||
tmp_data_size_ = thread_num_ * C4NUM * input_unit_ * input_unit_ * sizeof(float);
|
||||
tmp_data_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, tmp_data_size_, kWorkspace));
|
||||
col_buffer_size_ = thread_num_ * tile_num * conv_param_->input_channel_ * sizeof(float);
|
||||
col_buffer_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, col_buffer_size_, kWorkspace));
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionWinogradFP32Coder::ReSize() {
|
||||
// malloc tmp buffer
|
||||
int ret = ConfigInputOutput();
|
||||
MS_CHECK_RET_CODE(ret, "ConfigInputOutput failed.");
|
||||
ret = InitTmpBuffer();
|
||||
MS_CHECK_RET_CODE(ret, "Init tmp buffer failed.");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionWinogradFP32Coder::Prepare(CoderContext *const context) {
|
||||
int ret = Conv2DBaseCoder::Init();
|
||||
MS_CHECK_RET_CODE(ret, "convolution base coder init failed.");
|
||||
kernel_unit_ = conv_param_->kernel_h_;
|
||||
input_unit_ = output_unit_ + kernel_unit_ - 1;
|
||||
conv_param_->input_unit_ = input_unit_;
|
||||
conv_param_->output_unit_ = output_unit_;
|
||||
ret = InitWeightBias();
|
||||
MS_CHECK_RET_CODE(ret, "Init weight bias failed.");
|
||||
return ReSize();
|
||||
} // namespace micro
|
||||
|
||||
int ConvolutionWinogradFP32Coder::InitWeightBias() {
|
||||
int in_channel = filter_tensor_->Channel();
|
||||
int out_channel = filter_tensor_->Batch();
|
||||
MS_CHECK_TRUE(in_channel > 0, "invalid in channel size");
|
||||
MS_CHECK_TRUE(out_channel > 0, "invalid out channel size");
|
||||
conv_param_->input_channel_ = in_channel;
|
||||
conv_param_->output_channel_ = out_channel;
|
||||
|
||||
int oc4 = UP_DIV(out_channel, C4NUM);
|
||||
const int oc_block = C8NUM;
|
||||
int oc_block_num = UP_DIV(out_channel, C8NUM);
|
||||
// init weight
|
||||
int trans_matrix_data_size = input_unit_ * input_unit_ * in_channel * oc_block_num * oc_block;
|
||||
trans_weight_ = reinterpret_cast<float *>(
|
||||
allocator_->Malloc(kNumberTypeFloat32, trans_matrix_data_size * sizeof(float), kOfflinePackWeight));
|
||||
MS_CHECK_PTR(trans_weight_);
|
||||
int ret = memset_s(trans_weight_, trans_matrix_data_size * sizeof(float), 0, trans_matrix_data_size * sizeof(float));
|
||||
MS_CHECK_RET_CODE(ret, "memset_s failed!");
|
||||
float matrix_g[64];
|
||||
float matrix_gt[64];
|
||||
float matrix_a[64];
|
||||
float matrix_at[64];
|
||||
float matrix_b[64];
|
||||
float matrix_bt[64];
|
||||
float coef = 1.0f;
|
||||
if (input_unit_ == 8) {
|
||||
coef = 0.5f;
|
||||
}
|
||||
CookToomFilter(matrix_a, matrix_at, matrix_b, matrix_bt, matrix_g, matrix_gt, coef, output_unit_, kernel_unit_);
|
||||
|
||||
auto out_channel_size = static_cast<size_t>(out_channel);
|
||||
auto weight_data = reinterpret_cast<float *>(filter_tensor_->MutableData());
|
||||
ret = WinogradFilterTransform(weight_data, matrix_g, matrix_gt, oc_block);
|
||||
MS_CHECK_RET_CODE(ret, "winograd filter transform failed!");
|
||||
// init bias
|
||||
int new_bias_ele_num = oc4 * C4NUM;
|
||||
auto new_bias_ele_size = static_cast<size_t>(new_bias_ele_num * sizeof(float));
|
||||
new_bias_ = reinterpret_cast<float *>(allocator_->Malloc(kNumberTypeFloat32, new_bias_ele_size, kOfflinePackWeight));
|
||||
MS_CHECK_PTR(new_bias_);
|
||||
ret = memset_s(new_bias_, new_bias_ele_size, 0, new_bias_ele_size);
|
||||
MS_CHECK_RET_CODE(ret, "memset_s failed!");
|
||||
if (input_tensors_.size() == kInputSize2) {
|
||||
auto ori_bias_addr = reinterpret_cast<float *>(bias_tensor_->data_c());
|
||||
MS_CHECK_RET_CODE(memcpy_s(new_bias_, static_cast<size_t>(out_channel_size * sizeof(float)), ori_bias_addr,
|
||||
static_cast<size_t>(out_channel_size * sizeof(float))),
|
||||
"memset_s failed!");
|
||||
} else {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int ConvolutionWinogradFP32Coder::ConfigInputOutput() {
|
||||
in_func_ = GetInputTransFunc(input_unit_);
|
||||
MS_CHECK_TRUE(!in_func_.empty(), "Get input_trans_func failed.");
|
||||
out_func_ = GetOutputTransFunc(input_unit_, output_unit_, conv_param_->act_type_);
|
||||
MS_CHECK_TRUE(!out_func_.empty(), "Get output_trans_func_ failed.");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
std::string ConvolutionWinogradFP32Coder::GetInputTransFunc(int input_unit) {
|
||||
return InputTransFuncList.at(input_unit);
|
||||
}
|
||||
|
||||
std::string ConvolutionWinogradFP32Coder::GetOutputTransFunc(int input_unit, int output_unit, ActType act_type) {
|
||||
std::string res;
|
||||
if (input_unit == 4 && output_unit < 4) {
|
||||
if (act_type == ActType_Relu) {
|
||||
return OutputTransFuncReluList4.at(output_unit);
|
||||
} else if (act_type == ActType_Relu6) {
|
||||
return OutputTransFuncRelu6List4.at(output_unit);
|
||||
} else {
|
||||
return OutputTransFuncList4.at(output_unit);
|
||||
}
|
||||
} else if (input_unit == 6 && output_unit < 6) {
|
||||
if (act_type == ActType_Relu) {
|
||||
return OutputTransFuncReluList6.at(output_unit);
|
||||
} else if (act_type == ActType_Relu6) {
|
||||
return OutputTransFuncRelu6List6.at(output_unit);
|
||||
} else {
|
||||
return OutputTransFuncList6.at(output_unit);
|
||||
}
|
||||
} else if (input_unit == 8 && output_unit < 8) {
|
||||
if (act_type == ActType_Relu) {
|
||||
return OutputTransFuncReluList8.at(output_unit);
|
||||
} else if (act_type == ActType_Relu6) {
|
||||
return OutputTransFuncRelu6List8.at(output_unit);
|
||||
} else {
|
||||
return OutputTransFuncList8.at(output_unit);
|
||||
}
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
int ConvolutionWinogradFP32Coder::DoCode(CoderContext *const context) {
|
||||
std::vector<std::string> asmFiles;
|
||||
if (target_ == kARM32A) {
|
||||
asmFiles = {
|
||||
"MatmulFp32.S", "MatmulFp32Opt.S", "PreSum4x16Int8Peroc.S", "PreSum4x16Int8Pert.S", "IndirectGemmInt16to32_8x4.S",
|
||||
"MatmulInt8.S"};
|
||||
} else if (target_ == kARM64) {
|
||||
asmFiles = {"MatmulFp32.S", "MatmulFp32Opt.S", "PreSum4x16Int8Peroc.S", "MatVecMulFp32.S",
|
||||
"PreSum4x16Int8Peroc.S", "PreSum4x16Int8Pert.S", "IndirectGemmInt16to32_8x4.S", "MatmulInt8.S"};
|
||||
}
|
||||
Collect(context, {"nnacl/fp32/conv.h", "nnacl/common_func.h"},
|
||||
{"common_func.c", "conv_int8.c", "matmul_int8.c", "pack.c", "conv.c", "winograd_transform.c",
|
||||
"common_func_fp32.c", "fixed_point.c", "winograd_utils.c", "minimal_filtering_generator.c"},
|
||||
asmFiles);
|
||||
|
||||
NNaclFp32Serializer code;
|
||||
// call the op function
|
||||
code.CodeFunction("memset", trans_input_, "0", tile_buffer_size_);
|
||||
code.CodeFunction("memset", gemm_out_, "0", gemm_out_size_);
|
||||
code.CodeFunction("memset", tmp_data_, "0", tmp_data_size_);
|
||||
code.CodeFunction("memset", col_buffer_, "0", col_buffer_size_);
|
||||
code << "\t\tfloat *tmp_buffer_address_list[4] = {" << allocator_->GetRuntimeAddr(trans_input_) << ", "
|
||||
<< allocator_->GetRuntimeAddr(gemm_out_) << ", " << allocator_->GetRuntimeAddr(tmp_data_) << ", "
|
||||
<< allocator_->GetRuntimeAddr(col_buffer_) << "};\n";
|
||||
code.CodeStruct("conv_parameter", *conv_param_);
|
||||
// code operator func
|
||||
int task_id = 0;
|
||||
code.CodeFunction("ConvWinogardFp32", input_tensor_, trans_weight_, new_bias_, output_tensor_,
|
||||
"tmp_buffer_address_list", task_id, "&conv_parameter", in_func_, out_func_);
|
||||
context->AppendCode(code.str());
|
||||
return RET_OK;
|
||||
}
|
||||
} // namespace mindspore::lite::micro::nnacl
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 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_FP32_CONVOLUTION_WINOGRAD_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_WINOGRAD_FP32_CODER_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/base/conv2d_base_coder.h"
|
||||
#include "nnacl/conv_parameter.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ConvolutionWinogradFP32Coder : public Conv2DBaseCoder {
|
||||
public:
|
||||
ConvolutionWinogradFP32Coder(const std::vector<Tensor *> &in_tensors, const std::vector<Tensor *> &out_tensors,
|
||||
const Model::Node *node, size_t node_index, Target target, int output_unit)
|
||||
: Conv2DBaseCoder(in_tensors, out_tensors, node, node_index, target), output_unit_(output_unit) {}
|
||||
|
||||
int Prepare(CoderContext *const context) override;
|
||||
|
||||
int DoCode(CoderContext *const context) override;
|
||||
|
||||
~ConvolutionWinogradFP32Coder() override = default;
|
||||
|
||||
private:
|
||||
int InitWeightBias();
|
||||
|
||||
int ConfigInputOutput();
|
||||
|
||||
int InitTmpBuffer();
|
||||
|
||||
int ReSize();
|
||||
|
||||
int WinogradFilterTransform(const float *weight_data, float *matrix_g, const float *matrix_gt, int oc_block);
|
||||
|
||||
std::string GetInputTransFunc(int input_unit);
|
||||
|
||||
std::string GetOutputTransFunc(int input_unit, int output_unit, ActType act_type);
|
||||
|
||||
float *trans_weight_{nullptr};
|
||||
float *new_bias_{nullptr};
|
||||
|
||||
int kernel_unit_{0};
|
||||
int input_unit_{0};
|
||||
int output_unit_{0};
|
||||
|
||||
size_t tmp_data_size_{0};
|
||||
size_t tile_buffer_size_{0};
|
||||
size_t gemm_out_size_{0};
|
||||
size_t col_buffer_size_{0};
|
||||
|
||||
float *tmp_data_{nullptr};
|
||||
float *trans_input_{nullptr};
|
||||
float *gemm_out_{nullptr};
|
||||
float *col_buffer_{nullptr};
|
||||
|
||||
std::string in_func_;
|
||||
std::string out_func_;
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CONVOLUTION_WINOGRAD_FP32_CODER_H_
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/expand_dims_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_ExpandDims;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_EXPANDDIMS_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ExpandDimsFP32Coder final : public OperatorCoder {
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/gather_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Gather;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_GATHER_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/base/tile_base.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/nchw2nhwc_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Nchw2Nhwc;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/base/tile_base.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/nhwc2nchw_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Nhwc2Nchw;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_NHWC2NCHW_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/base/tile_base.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_PAD_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/fp32/pad_fp32.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
* 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 "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Pooling;
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_CODER_OPCODERS_FP32_POOLFP32_CODER_H_
|
||||
#define MICRO_CODER_OPCODERS_FP32_POOLFP32_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_POOLFP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_POOLFP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
|
@ -36,4 +36,4 @@ class PoolingFP32Coder final : public OperatorCoder {
|
|||
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
|
||||
#endif // MICRO_CODER_OPCODERS_FP32__CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_FP32_CODER_H_
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/power_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Power;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_POWER_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/power_parameter.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/reduce_fp32_coder.h"
|
||||
#include "coder/opcoders/nnacl/fp32/reduce_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"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Reduce;
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/base/reduce_base_coder.h"
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/base/reduce_base_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ReduceFP32Coder final : public ReduceBaseCoder {
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/reshape_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Reshape;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_RESHAPE_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ReshapeFP32Coder final : public OperatorCoder {
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* 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 "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"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Scale;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MICRO_CODER_OPCODERS_FP32_SCALEFP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/scale.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/slice_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Slice;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_SLICE_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class SliceFP32Coder final : public OperatorCoder {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/softmax_fp32_coder.h"
|
||||
#include "coder/opcoders/nnacl/fp32/softmax_fp32_coder.h"
|
||||
#include <string>
|
||||
#include "micro/coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "schema/inner/ops_generated.h"
|
||||
#include "micro/coder/opcoders/file_collector.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_SoftMax;
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/squeeze_dims_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Squeeze;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_SQUEEZE_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class SqueezeFP32Coder final : public OperatorCoder {
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/fp32/tile_fp32_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_fp32_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Tile;
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_TILE_FP32_CODER_H_
|
||||
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/base/tile_base.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
* 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_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/transpose.h"
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
@ -50,4 +50,4 @@ class TransposeFp32Coder final : public OperatorCoder {
|
|||
};
|
||||
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MICRO_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_NNACL_FP32_TRANSPOSE_FP32_CODER_H_
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "micro/coder/opcoders/nnacl/int8/concat_int8_coder.h"
|
||||
#include "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"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/log.h"
|
||||
#include "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));
|
||||
|
|
|
@ -13,14 +13,14 @@
|
|||
* 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 "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"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "micro/coder/opcoders/op_coder.h"
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "micro/coder/opcoders/nnacl/int8/reduce_int8_coder.h"
|
||||
#include "coder/opcoders/nnacl/int8/reduce_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"
|
||||
#include "coder/opcoders/file_collector.h"
|
||||
#include "coder/log.h"
|
||||
#include "coder/opcoders/serializers/nnacl_serializer/nnacl_int8_serializer.h"
|
||||
|
||||
using mindspore::schema::PrimitiveType_Reduce;
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MICRO_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
#define MICRO_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
#ifndef MINDSPORE_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
#define MINDSPORE_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "coder/opcoders/op_coder.h"
|
||||
#include "nnacl/int8/quantize.h"
|
||||
#include "nnacl/int8/reduce_int8.h"
|
||||
#include "micro/coder/opcoders/base/reduce_base_coder.h"
|
||||
#include "coder/opcoders/base/reduce_base_coder.h"
|
||||
namespace mindspore::lite::micro::nnacl {
|
||||
class ReduceInt8Coder final : public ReduceBaseCoder {
|
||||
public:
|
||||
|
@ -52,4 +52,4 @@ class ReduceInt8Coder final : public ReduceBaseCoder {
|
|||
std::vector<QuantMulArg *> sum_square_multipliers_;
|
||||
};
|
||||
} // namespace mindspore::lite::micro::nnacl
|
||||
#endif // MICRO_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
#endif // MINDSPORE_LITE_MICRO_CODER_OPCODERS_INT8_REDUCE_INT8_CODER_H_
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue