diff --git a/mindspore-lite/src/common/common.h b/mindspore-lite/src/common/common.h index dc1c806741906328246e7f1e92b49009600f5d8b..244d340f8af7c775ebfe73593c2b57207b214125 100644 --- a/mindspore-lite/src/common/common.h +++ b/mindspore-lite/src/common/common.h @@ -186,6 +186,8 @@ static const char *const kInnerSharableHandle = "inner_sharable_handle"; // for lora static const char *const kBundleModel = "bundle_model"; +static constexpr size_t kMaxConfigLen = 1e6; + // for graph split static const char *const kSubgraphInferPath = "subgraph_infer_path"; static const char *const kSubgraphInputNames = "subgraph_input_names"; diff --git a/mindspore-lite/test/st/python/benchmark/mslite_model.py b/mindspore-lite/test/st/python/benchmark/mslite_model.py index 164b0e4d2c2af0a02612bd2a042bb2cca65e013c..7ea335328db6d5e563a7ba2b96c106f2ba35d409 100644 --- a/mindspore-lite/test/st/python/benchmark/mslite_model.py +++ b/mindspore-lite/test/st/python/benchmark/mslite_model.py @@ -103,11 +103,11 @@ class MSLiteModel(): self.mindir_path = os.path.join(save_models_path, self.model_name + "_graph.mindir") self.input_shape_str = "" if model_info.split(";")[3].split(" ")[0] == "static": - for i in range(len(self.input_names)): + for i,name in enumerate(self.input_names): input_shape_str = "" for shape in self.input_shapes[i]: input_shape_str += str(shape) + "," - self.input_shape_str += self.input_names[i] + ":" + input_shape_str[:-1] + ";" + self.input_shape_str += name + ":" + input_shape_str[:-1] + ";" self.input_shape_str = self.input_shape_str[:-1] self.predict_result = {} @@ -123,7 +123,7 @@ class MSLiteModel(): model_inputs = self.model.get_inputs() inputs = [] if len(self.in_data_file_list) == len(model_inputs): - for i in range(len(model_inputs)): + for i,_ in enumerate(model_inputs): if model_inputs[i].dtype == mslite.DataType.FLOAT32: data = np.fromfile(self.in_data_file_list[i], dtype=np.float32).reshape(self.input_shapes[i]) elif model_inputs[i].dtype == mslite.DataType.INT32: @@ -137,7 +137,7 @@ class MSLiteModel(): inputs.append(model_inputs[i]) else: - for i in range(len(model_inputs)): + for i,_ in enumerate(model_inputs): if model_inputs[i].dtype == mslite.DataType.FLOAT32: data = np.random.random(self.input_shapes[i]).astype(np.float32) elif model_inputs[i].dtype == mslite.DataType.INT32: @@ -155,7 +155,7 @@ class MSLiteModel(): """ all_benchmark_data = [] num_line = 0 - with open(benchmark_file, "r") as f: + with open(benchmark_file, "r", encoding='utf-8') as f: for line in f: num_line += 1 if line[-1] == "\n": @@ -172,12 +172,14 @@ class MSLiteModel(): if len(all_benchmark_data) != len(outputs_tensors): raise RuntimeError("benchmark data file is wrong.") all_err = 0 - for input_i in range(len(outputs_tensors)): + for input_i,output in enumerate(outputs_tensors): mean_err = 0 count = 0 - out_data = outputs_tensors[input_i].get_data_to_numpy().flatten() + out_data = output.get_data_to_numpy().flatten() benchmark_data = all_benchmark_data[input_i] - for i in range(len(benchmark_data)): + if len(benchmark_data) != out_data.size: + raise RuntimeError("benchmark data size not equal to model output data size.") + for i,_ in enumerate(benchmark_data): abs_err = np.abs(out_data[i] - benchmark_data[i]) tolerance = 1e-10 + 1e-7 * np.abs(benchmark_data[i]) if abs_err > tolerance: @@ -249,10 +251,10 @@ class MSLiteModel(): """ self.model.resize(self.model.get_inputs(), self.input_shapes) inputs = self.CreateInputTensors() - for i in range(WARM_UP): + for _ in range(WARM_UP): outputs = self.model.predict(inputs) time_predict_start = time.time() - for i in range(LOOP_COUNT): + for _ in range(LOOP_COUNT): outputs = self.model.predict(inputs) time_predict_end = time.time() time_predict = (time_predict_end - time_predict_start) * 1000 / LOOP_COUNT diff --git a/mindspore-lite/tools/converter/CMakeLists.txt b/mindspore-lite/tools/converter/CMakeLists.txt index 78242b3444b802c81468de38b174268949f04e08..226392c0a7d84b44bc49d4f7b1ac20391d794358 100644 --- a/mindspore-lite/tools/converter/CMakeLists.txt +++ b/mindspore-lite/tools/converter/CMakeLists.txt @@ -449,7 +449,6 @@ file(STRINGS "${TOP_DIR}/version.txt" VERSION) add_definitions(-DVERSION=\"${VERSION}\") set(CCSRC_SRC_NEW ${CCSRC_DIR}/backend/common/pass_manager/graph_optimizer.cc ${CCSRC_DIR}/backend/common/pass_manager/pattern_engine.cc - ${CCSRC_DIR}/utils/convert_utils.cc ${CCSRC_DIR}/utils/ir_dump/mindir_exporter.cc ${CCSRC_DIR}/backend/common/pass_manager/visitor.cc ${CCSRC_DIR}/utils/common.cc diff --git a/mindspore-lite/tools/converter/anf_transform.cc b/mindspore-lite/tools/converter/anf_transform.cc index 261d915e547b2473870fa1115413c658aab42a01..82042b5a6e8acd072a8c8c2011c85afb1c9cc765 100644 --- a/mindspore-lite/tools/converter/anf_transform.cc +++ b/mindspore-lite/tools/converter/anf_transform.cc @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include "nnacl_c/op_base.h" #include "src/common/log_adapter.h" @@ -210,6 +212,26 @@ std::map> TransStringToInputShapes(const std:: } return shapes; } + +std::set GetVariableNodeNames(const std::shared_ptr ¶m) { + std::string variable_weights_file = ""; + std::set variable_nodes; + std::vector node_name_list; + auto config_infos = param->config_infos; + if (config_infos.find(lite::kAscendContextSection) != config_infos.end()) { + auto ascend_context = config_infos.at(lite::kAscendContextSection); + if (ascend_context.find(lite::kVariableWeightsFile) != ascend_context.end()) { + variable_weights_file = ascend_context.at(lite::kVariableWeightsFile); + } + } + if (variable_weights_file != "" && + opt::ParseVariableNode(variable_weights_file, &variable_nodes, &node_name_list) != lite::RET_OK) { + MS_LOG(ERROR) << "Parse variable node name failed!"; + return {}; + } + return variable_nodes; +} + } // namespace AnfTransform::AnfTransform() = default; @@ -258,8 +280,10 @@ STATUS AnfTransform::MarkTrainWeightSharingOp(const FuncGraphPtr &func_graph, co return RET_OK; } -STATUS AnfTransform::MarkTrainOp(const FuncGraphPtr &func_graph) { +STATUS AnfTransform::MarkOperatorAsNonFusible(const FuncGraphPtr &func_graph, + const std::shared_ptr ¶m) { auto node_list = TopoSort(func_graph->get_return()); + auto variable_node_names = GetVariableNodeNames(param); for (auto &node : node_list) { if (!utils::isa(node)) { continue; @@ -284,6 +308,13 @@ STATUS AnfTransform::MarkTrainOp(const FuncGraphPtr &func_graph) { return RET_ERROR; } } + for (size_t i = 1; i < cnode->inputs().size(); i++) { + if (utils::isa(cnode->input(i)) && + variable_node_names.find(cnode->input(i)->fullname_with_scope()) != variable_node_names.end()) { + (void)prim->AddAttr("trainOp", MakeValue(true)); + break; + } + } } return RET_OK; } @@ -351,11 +382,6 @@ std::vector InitFusions(const std::shared_ptr ¶ } int AnfTransform::RunFusionPass(const FuncGraphPtr &old_graph, const std::shared_ptr ¶m) { - auto status = MarkTrainOp(old_graph); - if (status != RET_OK) { - MS_LOG(ERROR) << "MarkTrainOp failed."; - return RET_ERROR; - } auto optimizer = std::make_shared(); CHECK_NULL_RETURN(optimizer); auto fusion_pm = std::make_shared("anf fusion pass manager", false); @@ -677,7 +703,12 @@ STATUS AnfTransform::ProcOnlineTransform(const FuncGraphPtr &old_graph, const st } int AnfTransform::RunPass(const FuncGraphPtr &old_graph, const std::shared_ptr ¶m) { - auto status = RunConvertPass(old_graph, param); + auto status = MarkOperatorAsNonFusible(old_graph, param); + if (status != RET_OK) { + MS_LOG(ERROR) << "MarkOperatorAsNonFusible failed."; + return RET_ERROR; + } + status = RunConvertPass(old_graph, param); if (status != RET_OK) { MS_LOG(ERROR) << "Run convert pass failed."; return RET_ERROR; diff --git a/mindspore-lite/tools/converter/anf_transform.h b/mindspore-lite/tools/converter/anf_transform.h index 3c45851005e4dfbf9de184df8136e6d1b706535c..bf4c68511a8c3a08e3ff63f284ab6bc878d9073c 100644 --- a/mindspore-lite/tools/converter/anf_transform.h +++ b/mindspore-lite/tools/converter/anf_transform.h @@ -66,7 +66,7 @@ class AnfTransform { static STATUS MarkTrainWeightSharingOp(const FuncGraphPtr &func_graph, const CNodePtr &cnode); - static STATUS MarkTrainOp(const FuncGraphPtr &func_graph); + static STATUS MarkOperatorAsNonFusible(const FuncGraphPtr &func_graph, const std::shared_ptr ¶m); static bool CheckExternalExtension(const std::shared_ptr ¶m); diff --git a/mindspore-lite/tools/optimizer/common/gllo_utils.cc b/mindspore-lite/tools/optimizer/common/gllo_utils.cc index 83ddf44cb6f4be36421b91583d6883a7a39a24af..e9c9c4b9ef6a505688c31c490f985699a8533d09 100644 --- a/mindspore-lite/tools/optimizer/common/gllo_utils.cc +++ b/mindspore-lite/tools/optimizer/common/gllo_utils.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "mindspore/ops/op_def/structure_ops.h" #include "mindspore/ops/op_def/sequence_ops.h" #include "mindspore/ops/op_def/conv_pool_ops.h" @@ -61,6 +63,8 @@ #include "mindspore/core/include/ir/graph_utils.h" #include "mindspore/ops/infer/return.h" #include "mindspore/ops/infer/make_tuple.h" +#include "tools/common/parse_config_utils.h" +#include "common/common.h" namespace mindspore { namespace opt { @@ -283,6 +287,12 @@ int CopyTensorDataFromTensorInfo(const tensor::TensorPtr &tensor_info, } return RET_OK; } + +bool MatchPattern(const std::string &input) { + std::regex pattern(R"(^([\s\S]*?):(\d+(?:,\d+)*);([\s\S]*)$)"); + return std::regex_match(input, pattern); +} + } // namespace bool CheckInputs(const CNodePtr &cnode) { @@ -2113,5 +2123,45 @@ Status BuildReturnNode(const FuncGraphPtr &anf_graph, const std::vectorset_return(return_cnode); return kSuccess; } + +lite::STATUS ParseVariableNode(std::string file_path, std::set *variable_nodes, + std::vector *node_name_list) { + MS_CHECK_TRUE_RET(variable_nodes != nullptr, lite::RET_NULL_PTR); + MS_CHECK_TRUE_RET(node_name_list != nullptr, lite::RET_NULL_PTR); + std::ifstream file; + auto ret = lite::ReadFileToIfstream(file_path, &file); + if (ret != RET_OK) { + MS_LOG(ERROR) << "read file to ifstream failed!"; + return ret; + } + size_t config_len = 0; + std::string line; + while (std::getline(file, line)) { + if (!MatchPattern(line)) { + MS_LOG(ERROR) << "Format of config error, it should be 'weight_name:num1,num2,num3;node_name', input config:" + << line; + return RET_ERROR; + } + config_len++; + if (config_len >= lite::kMaxConfigLen) { + MS_LOG(ERROR) << "Support max config len is " << lite::kMaxConfigLen << ", current len:" << config_len << "!"; + return RET_ERROR; + } + std::reverse(line.begin(), line.end()); + auto pos_colon = line.find(':'); + if (pos_colon == std::string::npos) { + MS_LOG(ERROR) << "Parse variable weight file error!"; + file.close(); + return RET_ERROR; + } + auto variable_para_name = line.substr(pos_colon + 1, line.size() - pos_colon); + std::reverse(variable_para_name.begin(), variable_para_name.end()); + (*node_name_list).push_back(variable_para_name); + variable_nodes->insert(variable_para_name); + } + file.close(); + return RET_OK; +} + }; // namespace opt } // namespace mindspore diff --git a/mindspore-lite/tools/optimizer/common/gllo_utils.h b/mindspore-lite/tools/optimizer/common/gllo_utils.h index 2fe4035a4540e71ff734cdbc3758939399c7d78a..5c8d0e411423592fe76d8a13ff83479f3142a433 100644 --- a/mindspore-lite/tools/optimizer/common/gllo_utils.h +++ b/mindspore-lite/tools/optimizer/common/gllo_utils.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "ops/primitive_c.h" #include "mindspore/ops/op_def/framework_ops.h" #include "ir/anf.h" @@ -233,6 +234,8 @@ tensor::TensorPtr GetTensorFromParameterNode(const EquivPtr &equiv, const VarPtr const float GetFloatParameterValue(const EquivPtr &equiv, const VarPtr &input); const int GetIntParameterValue(const EquivPtr &equiv, const VarPtr &input); STATUS GetPrimFromCnode(const CNodePtr &cnode, PrimitivePtr *prim_ptr); +STATUS ParseVariableNode(std::string file_path, std::set *variable_nodes, + std::vector *node_name_list); } // namespace opt } // namespace mindspore #endif // MINDSPORE_LITE_TOOLS_OPTIMIZER_COMMON_GLLO_UTILS_H_ diff --git a/mindspore-lite/tools/optimizer/const_fold/fold_along_infershape.cc b/mindspore-lite/tools/optimizer/const_fold/fold_along_infershape.cc index 39cd9f708467a39a2a81478aa0c9d8163b67ef0a..1c271b3f31fdd2e1fcaa0d65b66448dc39b8e0ae 100644 --- a/mindspore-lite/tools/optimizer/const_fold/fold_along_infershape.cc +++ b/mindspore-lite/tools/optimizer/const_fold/fold_along_infershape.cc @@ -63,7 +63,7 @@ bool ConstFoldAlongInferShape::CheckCanFold(const FuncGraphPtr &func_graph, cons } auto is_inferred = prim->GetAttr(kInferDone) != nullptr && GetValue(prim->GetAttr(kInferDone)); if (!is_inferred) { - MS_LOG(DEBUG) << "is_inferred is flase."; + MS_LOG(DEBUG) << "is_inferred is false."; return false; } if (CheckPrimitiveType(cnode, prim::kPrimShape) && diff --git a/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.cc b/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.cc index e7ef9f0c9c99e8add4dc7cec0aa9a890224401fd..86b6947d19b0dfa3196795721555b3d0d46f6e6c 100644 --- a/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.cc +++ b/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.cc @@ -58,50 +58,8 @@ constexpr float kInitOne = 1.0; constexpr size_t kInitBatchSize = 1; constexpr size_t kMaxConfigLen = 1e6; constexpr uint16_t kFloatOne = 15360; - -bool MatchPattern(const std::string &input) { - std::regex pattern(R"(^([^:;]+):(\d+(?:,\d+)*);([^:;]+)$)"); - return std::regex_match(input, pattern); -} } // namespace -lite::STATUS InsertVariableNodePass::ParseInsertNode(std::string file_path, std::set *variable_nodes, - std::vector *node_name_list) { - MS_CHECK_TRUE_RET(variable_nodes != nullptr, lite::RET_NULL_PTR); - MS_CHECK_TRUE_RET(node_name_list != nullptr, lite::RET_NULL_PTR); - std::ifstream file; - auto ret = lite::ReadFileToIfstream(file_path, &file); - if (ret != RET_OK) { - MS_LOG(ERROR) << "read file to ifstream failed!"; - return ret; - } - size_t config_len = 0; - std::string line; - while (std::getline(file, line)) { - if (!MatchPattern(line)) { - MS_LOG(ERROR) << "Format of config error, it should be 'weight_name:num1,num2,num3;node_name', input config:" - << line; - return RET_ERROR; - } - config_len++; - if (config_len >= kMaxConfigLen) { - MS_LOG(ERROR) << "Support max config len is " << kMaxConfigLen << ", current len:" << config_len << "!"; - return RET_ERROR; - } - auto pos_colon = line.find(':'); - if (pos_colon == std::string::npos) { - MS_LOG(ERROR) << "Parse variable weight file error!"; - file.close(); - return RET_ERROR; - } - auto variable_para_name = line.substr(0, pos_colon); - (*node_name_list).push_back(variable_para_name); - variable_nodes->insert(variable_para_name); - } - file.close(); - return RET_OK; -} - void InsertVariableNodePass::InitWeightParam(std::string *variable_weights_file, int32_t *max_weight_batch) { if (param_->config_infos.find(lite::kAscendContextSection) != param_->config_infos.end()) { auto ascend_context = param_->config_infos.at(lite::kAscendContextSection); @@ -203,7 +161,7 @@ lite::STATUS InsertVariableNodePass::BuildVariableNode(FuncGraphPtr func_graph) std::unordered_map node_name_map; std::unordered_map node_abstract_map; std::vector node_name_list; - auto ret = ParseInsertNode(variable_weights_file, &variable_nodes, &node_name_list); + auto ret = ParseVariableNode(variable_weights_file, &variable_nodes, &node_name_list); MS_CHECK_TRUE_MSG(ret == RET_OK, ret, "ParseInsertNode failed!"); uint32_t matched_num = 0; auto node_list = TopoSort(func_graph->get_return()); diff --git a/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.h b/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.h index c2bbb52e01a8c9e79501e9b5acb4ea792afbbcee..30fd302539f3830618d8b9c5085211e738e7159b 100644 --- a/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.h +++ b/mindspore-lite/tools/optimizer/graph/add_variable_node_pass.h @@ -38,8 +38,6 @@ class InsertVariableNodePass : public Pass { private: lite::STATUS BuildVariableNode(FuncGraphPtr func_graph); - lite::STATUS ParseInsertNode(std::string file_path, std::set *variable_nodes, - std::vector *node_name_list); template ParameterPtr BuildZeroVecNDParameterNode(const FuncGraphPtr &anf_graph, ShapeVector weight_shape, const std::string &node_name, T value, TypeId dtype);