diff --git a/ge/ir_build/ge_ir_build.cc b/ge/ir_build/ge_ir_build.cc index ea521f5b..052af2f6 100644 --- a/ge/ir_build/ge_ir_build.cc +++ b/ge/ir_build/ge_ir_build.cc @@ -263,6 +263,7 @@ class Impl { omg_context_.user_attr_index_valid = false; }; ~Impl() { (void)generator_.Finalize(); }; + graphStatus CheckBuildModeAndBuildStep(); graphStatus GetSupportedOptions(const std::map &in, std::map &out); graphStatus CheckOptions(const std::map &options); @@ -451,6 +452,37 @@ graphStatus Impl::UpdateDataOpAttr(const Graph &graph) { return GRAPH_SUCCESS; } +graphStatus Impl::CheckBuildModeAndBuildStep() { + std::string build_mode; + auto it = options_.find(BUILD_MODE); + if (it != options_.end() && !(it->second.empty())) { + if (build_mode_options.find(it->second) == build_mode_options.end()) { + REPORT_INPUT_ERROR("E10001", std::vector({"parameter", "value", "reason"}), + std::vector({BUILD_MODE, it->second, "value is unsupported. Please check!"})); + GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildMode]:%s is unsupported. Please check!", it->second.c_str()); + return GRAPH_PARAM_INVALID; + } + build_mode = it->second; + } + it = options_.find(BUILD_STEP); + if (it != options_.end() && !(it->second.empty())) { + if (build_step_options.find(it->second) == build_step_options.end()) { + REPORT_INPUT_ERROR("E10001", std::vector({"parameter", "value", "reason"}), + std::vector({BUILD_STEP, it->second, "value is unsupported. Please check!"})); + GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildStep]:%s is unsupported. Please check!", it->second.c_str()); + return GRAPH_PARAM_INVALID; + } + } else { + if (build_mode == BUILD_MODE_TUNING) { + REPORT_INPUT_ERROR("E10001", std::vector({"parameter", "value", "reason"}), + std::vector({BUILD_MODE, it->second, "tuning must specify build step. Please check!"})); + GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildMode] tuning must specify build step. Please check!"); + return GRAPH_PARAM_INVALID; + } + } + return GRAPH_SUCCESS; +} + graphStatus Impl::GetSupportedOptions(const std::map &in, std::map &out) { for (auto &ele : in) { @@ -475,29 +507,12 @@ graphStatus Impl::CheckOptions(const std::map &options } // Check options build_mode and build_step. - std::string build_mode; - auto it = options_.find(BUILD_MODE); - if (it != options_.end() && !(it->second.empty())) { - if (build_mode_options.find(it->second) == build_mode_options.end()) { - GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildMode]:%s is unsupported. Please check!", it->second.c_str()); - return GRAPH_PARAM_INVALID; - } - build_mode = it->second; - } - it = options_.find(BUILD_STEP); - if (it != options_.end() && !(it->second.empty())) { - if (build_step_options.find(it->second) == build_step_options.end()) { - GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildStep]:%s is unsupported. Please check!", it->second.c_str()); - return GRAPH_PARAM_INVALID; - } - } else { - if (build_mode == BUILD_MODE_TUNING) { - GELOGE(GRAPH_PARAM_INVALID, "[Check][BuildMode] tuning must specify build step. Please check!"); - return GRAPH_PARAM_INVALID; - } + ret = CheckBuildModeAndBuildStep(); + if (ret != GRAPH_SUCCESS) { + return ret; } // Check option EXEC_DISABLE_REUSED_MEMORY - it = options_.find(ge::ir_option::EXEC_DISABLE_REUSED_MEMORY); + auto it = options_.find(ge::ir_option::EXEC_DISABLE_REUSED_MEMORY); if (it != options_.end() && (CheckDisableReuseMemoryParamValid(it->second) != GRAPH_SUCCESS)) { return GRAPH_PARAM_INVALID; } @@ -505,6 +520,18 @@ graphStatus Impl::CheckOptions(const std::map &options if (ge::CheckModifyMixlistParamValid(options_) != GRAPH_SUCCESS) { return GRAPH_PARAM_INVALID; } + // Check option OP_PRECISION_MODE + it = options_.find(ge::ir_option::OP_PRECISION_MODE); + if (it != options_.end() && !it->second.empty() && !ge::CheckInputPathValid(it->second)) { + REPORT_INPUT_ERROR("E10001", std::vector({"parameter", "value", "reason"}), + std::vector({ge::ir_option::OP_PRECISION_MODE, it->second, "path is not found"})); + GELOGE(GRAPH_PARAM_INVALID, "[Check][OP_PRECISION_MODE] %s not found", it->second.c_str()); + return GRAPH_PARAM_INVALID; + } + if (it != options_.end()) { + GELOGI("Option set successfully, option_key=%s, option_value=%s", + ge::ir_option::OP_PRECISION_MODE, it->second.c_str()); + } // Check Input Format if (options_.find(kInputFormat) != options_.end()) { return CheckInputFormat(options_[kInputFormat]); diff --git a/ge/offline/main.cc b/ge/offline/main.cc index a78ff392..54bded4b 100755 --- a/ge/offline/main.cc +++ b/ge/offline/main.cc @@ -106,10 +106,14 @@ DEFINE_string(out_nodes, "", "Optional; output nodes designated by users." "Format: \"node_name1:0;node_name1:1;node_name2:0\""); +DEFINE_string(op_precision_mode, "", "Optional; operator precision mode configuration file path"); + DEFINE_string(precision_mode, "force_fp16", "Optional; precision mode." "Support force_fp16, force_fp32, allow_mix_precision, allow_fp32_to_fp16, must_keep_origin_dtype."); +DEFINE_string(modify_mixlist, "", "Optional; operator mixed precision configuration file path"); + DEFINE_string(keep_dtype, "", "Optional; config file to specify the precision used by the operator during compilation."); @@ -192,8 +196,11 @@ DEFINE_string(log, "null", "Optional; generate atc log. Support debug, info, war DEFINE_string(dump_mode, "0", "Optional; generate infershape json,only support 1 , 0."); -DEFINE_int32(op_debug_level, 0, "Optional; configure debug level of compiler. 0(default): close debug;" - "1: open TBE compiler, export ccec file and TBE instruction mapping file; 2: open ccec compiler"); +DEFINE_int32(op_debug_level, 0, "Optional; configure debug level of compiler. 0(default): close debug; " + "1: open TBE compiler, export ccec file and TBE instruction mapping file; 2: open ccec compiler; " + "3: disable debug, and keep generating kernel file (.o and .json); 4: disable debug, " + "keep generation kernel file (.o and .json) and generate the operator CCE file (.cce) " + "and the UB fusion computing description file (.json)"); DEFINE_string(enable_scope_fusion_passes, "", "Optional; validate the non-general scope fusion pass," "multiple names can be set and separated by ','."); DEFINE_string(debug_dir, "", "Optional; the path to save the intermediate files of operator compilation"); @@ -210,8 +217,6 @@ DEFINE_string(display_model_info, "0", "Optional; display model info"); DEFINE_string(device_id, "0", "Optional; user device id"); -DEFINE_string(modify_mixlist, "", "Optional; operator mixed precision configuration file path"); - class GFlagUtils { public: /** @@ -298,8 +303,10 @@ class GFlagUtils { "\"l1_optimize\", \"off_optimize\"\n" " --mdl_bank_path Set the path of the custom repository generated after model tuning.\n" "\n[Operator Tuning]\n" + " --op_precision_mode Set the path of operator precision mode configuration file (.ini)\n" " --precision_mode precision mode, support force_fp16(default), force_fp32, allow_mix_precision, " "allow_fp32_to_fp16, must_keep_origin_dtype.\n" + " --modify_mixlist Set the path of operator mixed precision configuration file.\n" " --keep_dtype Retains the precision of certain operators in inference " "scenarios by using a configuration file.\n" " --auto_tune_mode Set tune mode. E.g.: \"GA,RL\", support configure multiple, spit by ,\n" @@ -315,7 +322,8 @@ class GFlagUtils { " 2: Enable TBE pipe_all, generate the operator CCE file and Python-CCE mapping file " "(.json), and enable the CCE compiler -O0-g.\n" " 3: Disable debug, and keep generating kernel file (.o and .json)\n" - " --modify_mixlist Set the path of operator mixed precision configuration file.\n" + " 4: Disable debug, keep generation kernel file (.o and .json) and generate the " + "operator CCE file (.cce) and the UB fusion computing description file (.json)" "\n[Debug]\n" " --save_original_model Control whether to output original model. E.g.: true: output original model\n" " --log Generate log with level. Support debug, info, warning, error, null\n" @@ -365,6 +373,14 @@ class GFlagUtils { FLAGS_op_select_implmode) != ge::SUCCESS, ret = ge::FAILED, "[Check][ImplMode]check optypelist_for_implmode and op_select_implmode failed!"); + if (!FLAGS_op_precision_mode.empty() && !ge::CheckInputPathValid(FLAGS_op_precision_mode, "--op_precision_mode")) { + ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"}, + {"op_precision_mode", FLAGS_op_precision_mode.c_str(), + "path is not found"}); + GELOGE(ge::FAILED, "[Check][op_precision_mode] %s not found", FLAGS_op_precision_mode.c_str()); + ret = ge::FAILED; + } + if (ge::CheckModifyMixlistParamValid(FLAGS_precision_mode, FLAGS_modify_mixlist) != ge::SUCCESS) { ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"}, {"modify_mixlist", FLAGS_modify_mixlist.c_str(), @@ -1049,6 +1065,7 @@ static void SetEnvForSingleOp(std::map &options) { options.emplace(ge::RUN_FLAG, flag_off); options.emplace(ge::OPTION_GRAPH_RUN_MODE, flag_off); options.emplace(ge::SINGLE_OP_FLAG, flag_on); + options.emplace(ge::OP_PRECISION_MODE, FLAGS_op_precision_mode); options.emplace(ge::PRECISION_MODE, FLAGS_precision_mode); options.emplace(ge::SOC_VERSION, FLAGS_soc_version); options.emplace(ge::CORE_TYPE, FLAGS_core_type); @@ -1076,6 +1093,14 @@ domi::Status GenerateSingleOp(const std::string& json_file_path) { ge::CheckImplmodeParamValid(FLAGS_optypelist_for_implmode, FLAGS_op_select_implmode) != ge::SUCCESS, return ge::FAILED, "[Check][ImplmodeParam] fail for input optypelist_for_implmode and op_select_implmode."); + if (!FLAGS_op_precision_mode.empty() && !ge::CheckInputPathValid(FLAGS_op_precision_mode, "--op_precision_mode")) { + ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"}, + {"op_precision_mode", FLAGS_op_precision_mode.c_str(), + "path is not found"}); + GELOGE(ge::FAILED, "[Check][op_precision_mode] %s not found", FLAGS_op_precision_mode.c_str()); + return ge::FAILED; + } + if (ge::CheckModifyMixlistParamValid(FLAGS_precision_mode, FLAGS_modify_mixlist) != ge::SUCCESS) { ErrorManager::GetInstance().ATCReportErrMessage("E10001", {"parameter", "value", "reason"}, {"modify_mixlist", FLAGS_modify_mixlist.c_str(), @@ -1159,6 +1184,7 @@ domi::Status GenerateOmModel() { options.insert(std::pair(string(ge::CALIBRATION_CONF_FILE), FLAGS_cal_conf)); options.insert(std::pair(string(ge::OUTPUT_NODE_NAME), FLAGS_out_nodes)); options.insert(std::pair(string(ge::INSERT_OP_FILE), FLAGS_insert_op_conf)); + options.insert(std::pair(string(ge::OP_PRECISION_MODE), FLAGS_op_precision_mode)); options.insert(std::pair(string(ge::PRECISION_MODE), FLAGS_precision_mode)); options.insert(std::pair(string(ge::TUNE_DEVICE_IDS), FLAGS_device_id)); diff --git a/ge/session/inner_session.cc b/ge/session/inner_session.cc index aabbe19c..54e62d32 100755 --- a/ge/session/inner_session.cc +++ b/ge/session/inner_session.cc @@ -82,6 +82,18 @@ Status InnerSession::Initialize() { return ret; } + //Check option OP_PRECISION_MODE + auto iter = all_options.find(ge::OP_PRECISION_MODE); + if (iter != all_options.end() && !iter->second.empty() && !ge::CheckInputPathValid(iter->second)) { + REPORT_INPUT_ERROR("E10001", std::vector({"parameter", "value", "reason"}), + std::vector({ge::OP_PRECISION_MODE, iter->second, "path is not found"})); + GELOGE(PARAM_INVALID, "[Check][OP_PRECISION_MODE] %s not found", iter->second.c_str()); + return FAILED; + } + if (iter != all_options.end()) { + GELOGI("Option set successfully, option_key=%s, option_value=%s", + ge::OP_PRECISION_MODE.c_str(), iter->second.c_str()); + } // Check option modify_mixlist if (ge::CheckModifyMixlistParamValid(all_options) != ge::SUCCESS) { return FAILED; diff --git a/inc/external/ge/ge_api_types.h b/inc/external/ge/ge_api_types.h index fbd6c020..6f5bbfbf 100644 --- a/inc/external/ge/ge_api_types.h +++ b/inc/external/ge/ge_api_types.h @@ -113,6 +113,7 @@ const char *const INPUT_FP16_NODES = "ge.INPUT_NODES_SET_FP16"; const char *const OP_DEBUG_LEVEL = "ge.opDebugLevel"; const char *const PERFORMANCE_MODE = "ge.performance_mode"; const char *const MODIFY_MIXLIST = "ge.exec.modify_mixlist"; +const char *const OP_PRECISION_MODE = "ge.exec.op_precision_mode"; } // namespace configure_option // Configure stream num by Session constructor options param, // its value should be int32_t type, default value is "1" @@ -326,6 +327,8 @@ const std::string PERFORMANCE_MODE = "ge.performance_mode"; const std::string MODIFY_MIXLIST = "ge.exec.modify_mixlist"; +const std::string OP_PRECISION_MODE = "ge.exec.op_precision_mode"; + // Graph run mode enum GraphRunMode { PREDICTION = 0, TRAIN }; @@ -405,6 +408,7 @@ static const char *const OP_BANK_UPDATE = ge::OP_BANK_UPDATE_FLAG.c_str(); static const char *const OP_DEBUG_LEVEL = ge::OP_DEBUG_LEVEL.c_str(); static const char *const PERFORMANCE_MODE = ge::PERFORMANCE_MODE.c_str(); static const char *const MODIFY_MIXLIST = ge::MODIFY_MIXLIST.c_str(); +static const char *const OP_PRECISION_MODE = ge::OP_PRECISION_MODE.c_str(); // for interface: aclgrphBuildModel #ifdef __GNUC__ @@ -416,6 +420,7 @@ const std::set ir_builder_suppported_options = {INPUT_FORMAT, DYNAMIC_IMAGE_SIZE, DYNAMIC_DIMS, INSERT_OP_FILE, + OP_PRECISION_MODE, PRECISION_MODE, TUNE_DEVICE_IDS, EXEC_DISABLE_REUSED_MEMORY, diff --git a/tests/ut/ge/graph_ir/ge_ir_build_unittest.cc b/tests/ut/ge/graph_ir/ge_ir_build_unittest.cc index 197c9300..60f33ed3 100644 --- a/tests/ut/ge/graph_ir/ge_ir_build_unittest.cc +++ b/tests/ut/ge/graph_ir/ge_ir_build_unittest.cc @@ -391,6 +391,43 @@ TEST(UtestIrBuild, check_modify_mixlist_param) { EXPECT_EQ(ret, GRAPH_PARAM_INVALID); } +TEST(UtestIrBuild, check_op_precision_mode_param) { + Graph graph = BuildIrGraph1(); + const std::map build_options = { + {"ge.exec.op_precision_mode", "./op_precision_mode.ini"} + }; + ModelBufferData model; + + auto ret = aclgrphBuildModel(graph, build_options, model); + EXPECT_EQ(ret, GRAPH_PARAM_INVALID); +} + +TEST(UtestIrBuild, check_build_model_and_build_step) { + Graph graph_1 = BuildIrGraph1(); + const std::map build_options_1 = { + {"ge.buildMode", "xxx"} + }; + ModelBufferData model_1; + auto ret_1 = aclgrphBuildModel(graph_1, build_options_1, model_1); + EXPECT_NE(ret_1, GRAPH_SUCCESS); + + Graph graph_2 = BuildIrGraph1(); + const std::map build_options_2 = { + {"ge.buildStep", "xxx"} + }; + ModelBufferData model_2; + auto ret_2 = aclgrphBuildModel(graph_2, build_options_2, model_2); + EXPECT_NE(ret_2, GRAPH_SUCCESS); + + Graph graph_3 = BuildIrGraph1(); + const std::map build_options_3 = { + {"ge.buildMode", "tuning"} + }; + ModelBufferData model_3; + auto ret_3 = aclgrphBuildModel(graph_3, build_options_3, model_3); + EXPECT_NE(ret_3, GRAPH_SUCCESS); +} + TEST(UtestIrBuild, atc_cfg_optype_param) { ComputeGraphPtr graph = BuildComputeGraph1(); FILE *fp = fopen("./keep.txt", "w+"); diff --git a/tests/ut/ge/session/ge_api_unittest.cc b/tests/ut/ge/session/ge_api_unittest.cc index 2cabc4a3..9a7058f3 100644 --- a/tests/ut/ge/session/ge_api_unittest.cc +++ b/tests/ut/ge/session/ge_api_unittest.cc @@ -64,7 +64,7 @@ TEST_F(UtestGeApi, build_graph_success) { ASSERT_NE(ret, SUCCESS); } -TEST_F(UtestGeApi, ge_initialize) { +TEST_F(UtestGeApi, ge_initialize_modify_mixlist) { std::map options = { {ge::MODIFY_MIXLIST, "/mixlist.json"} }; diff --git a/tests/ut/ge/session/inner_session_unittest.cc b/tests/ut/ge/session/inner_session_unittest.cc index ecad56d6..0d20f06a 100644 --- a/tests/ut/ge/session/inner_session_unittest.cc +++ b/tests/ut/ge/session/inner_session_unittest.cc @@ -53,4 +53,14 @@ TEST_F(Utest_Inner_session, initialize) { auto ret = inner_session.Initialize(); EXPECT_NE(ret, ge::SUCCESS); } + +TEST_F(Utest_Inner_session, check_op_precision_mode) { + std::map options = { + {ge::OP_PRECISION_MODE, "./op_precision_mode.ini"} + }; + uint64_t session_id = 1; + InnerSession inner_session(session_id, options); + auto ret = inner_session.Initialize(); + EXPECT_NE(ret, ge::SUCCESS); +} } // namespace ge