You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cc 62 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
5 years ago
4 years ago
5 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <dirent.h>
  17. #include <dlfcn.h>
  18. #include <gflags/gflags.h>
  19. #include <sys/types.h>
  20. #include <unistd.h>
  21. #include <cctype>
  22. #include <climits>
  23. #include <cstdlib>
  24. #include <iostream>
  25. #include "common/gflags_util.h"
  26. #include "common/util.h"
  27. #include "common/util/error_manager/error_manager.h"
  28. #include "framework/common/debug/ge_log.h"
  29. #include "ge/ge_api.h"
  30. #include "generator/ge_generator.h"
  31. #include "graph/anchor.h"
  32. #include "graph/debug/ge_attr_define.h"
  33. #include "graph/graph.h"
  34. #include "graph/op_desc.h"
  35. #include "graph/utils/graph_utils.h"
  36. #include "graph/utils/type_utils.h"
  37. #include "init/gelib.h"
  38. #include "ir_build/atc_ir_common.h"
  39. #include "omg/omg.h"
  40. #include "omg/parser/parser_factory.h"
  41. #include "omg/parser/parser_inner_ctx.h"
  42. #include "parser/common/register_tbe.h"
  43. #include "register/op_registry.h"
  44. #include "single_op_parser.h"
  45. #include "external/ge/ge_ir_build.h"
  46. using domi::BuildMode;
  47. using domi::OpRegistrationData;
  48. using domi::OpRegistry;
  49. using domi::Status;
  50. using domi::SUCCESS;
  51. using ge::GEN_OM_MODEL;
  52. using ge::GflagsUtils;
  53. using ge::MODEL_TO_JSON;
  54. using ge::ONLY_PRE_CHECK;
  55. using ge::ParseInputShape;
  56. using ge::PBTXT_TO_JSON;
  57. using std::map;
  58. using std::pair;
  59. using std::shared_ptr;
  60. using std::string;
  61. using std::vector;
  62. namespace {
  63. static bool is_dynamic_input = false;
  64. const char *const kModeSupport = "only support 0(model to framework model), "
  65. "1(framework model to json), 3(only pre-check), "
  66. "5(pbtxt to json), 6(display model info)";
  67. const char *const kModelToJsonSupport = "only support 0(Caffe) 3(TensorFlow) 5(Onnx)";
  68. const char *const kCaffeFormatSupport = "only support NCHW, ND in Caffe model";
  69. const char *const kTFFormatSupport = "only support NCHW, NHWC, ND, NCDHW, NDHWC in TF model";
  70. const char *const kONNXFormatSupport = "only support NCHW, ND in ONNX model";
  71. // limit available mem size 2G
  72. const long kMinAvailableMem = 2097152; // 2 * 1024 * 1024
  73. } // namespace
  74. DEFINE_string(model, "", "The model file.");
  75. DEFINE_string(output, "", "The output file path&name.");
  76. DEFINE_int32(framework, -1, "Framework type(0:Caffe; 1:MindSpore; 3:Tensorflow; 5:Onnx).");
  77. DEFINE_string(weight, "", "Optional; weight file. Required when framework is Caffe.");
  78. DEFINE_string(input_shape, "",
  79. "Optional; shape of input data. Required when framework is caffe "
  80. "or TensorFLow or MindSpore or Onnx. "
  81. "Format: \"input_name1:n1,c1,h1,w1;input_name2:n2,c2,h2,w2\"");
  82. DEFINE_bool(h, false, "show this help message");
  83. DEFINE_string(cal_conf, "", "Optional; the calibration config file.");
  84. DEFINE_string(insert_op_conf, "", "Optional; the config file to insert new op, for example AIPP op.");
  85. DEFINE_string(op_name_map, "", "Optional; custom op name mapping file.");
  86. DEFINE_string(target, "", "Optional; mini.");
  87. DEFINE_string(om, "", "The model file to be converted to json.");
  88. DEFINE_string(json, "", "The output json file path&name which is converted from a model.");
  89. DEFINE_int32(mode, 0,
  90. "Optional; run mode, 0(default): model => framework model; 1: "
  91. "framework model => json; 3: only pre-check; 5: txt => json.");
  92. #if !defined(__ANDROID__) && !defined(ANDROID)
  93. DEFINE_int32(encrypt_mode, -1, "Optional; the encrypt flag. 0: encrypt; -1(default): not encrypt");
  94. DEFINE_string(encrypt_key, "", "Optional; the encrypt_key file.");
  95. DEFINE_string(certificate, "", "Optional; the certificate file.");
  96. DEFINE_string(hardware_key, "", "Optional; the ISV key file.");
  97. DEFINE_string(private_key, "", "Optional; the private key file.");
  98. #endif
  99. DEFINE_string(out_nodes, "",
  100. "Optional; output nodes designated by users."
  101. "Format: \"node_name1:0;node_name1:1;node_name2:0\"");
  102. DEFINE_string(precision_mode, "force_fp16",
  103. "Optional; precision mode."
  104. "Support force_fp16, allow_mix_precision, allow_fp32_to_fp16, must_keep_origin_dtype.");
  105. DEFINE_string(keep_dtype, "",
  106. "Optional; config file to specify the precision used by the operator during compilation.");
  107. DEFINE_string(input_format, "",
  108. "Optional; input_format, format of input data, NCHW;NHWC."
  109. "Format:\"NHWC\"");
  110. DEFINE_string(check_report, "check_result.json", "Optional; the pre-checking report file.");
  111. DEFINE_string(input_fp16_nodes, "",
  112. "Optional; input node datatype is fp16 and format is NC1HWC0."
  113. "Format:\"node_name1;node_name2\"");
  114. DEFINE_string(is_output_adjust_hw_layout, "",
  115. "Optional; Net output node's datatype is fp16 and format is "
  116. "NC1HWC0, or not."
  117. "Format:\"false,true,false,true\"");
  118. DEFINE_string(is_input_adjust_hw_layout, "",
  119. "Optional; Intput node's datatype is fp16 and format is "
  120. "NC1HWC0, or not."
  121. "Format:\"false,true,false,true\"");
  122. DEFINE_string(output_type, "",
  123. "Optional; output type! "
  124. "Support FP32,FP16,INT8,INT16,UINT16,UINT8,INT32,INT64,UINT32,UINT64,DOUBLE.");
  125. DEFINE_string(op_select_implmode, "",
  126. "Optional; op select implmode! "
  127. "Support high_precision, high_performance.");
  128. DEFINE_string(optypelist_for_implmode, "",
  129. "Optional; Nodes need use implmode selected in op_select_implmode "
  130. "Format:\"node_name1,node_name2\"");
  131. DEFINE_string(singleop, "", "Optional; If set, generate single op model with the given json file.");
  132. DEFINE_int32(disable_reuse_memory, 0, "Optional; If set to 1, disable reuse memory when generating if.");
  133. DEFINE_string(auto_tune_mode, "", "Optional; Set tune mode.");
  134. DEFINE_string(soc_version, "", "The soc version.");
  135. DEFINE_string(core_type, "AiCore", "Optional; If set to VectorCore, only use vector core.");
  136. DEFINE_string(aicore_num, "", "Optional; Set aicore num");
  137. DEFINE_string(buffer_optimize, "l2_optimize", "Optional; buffer optimize");
  138. DEFINE_string(fusion_switch_file, "", "Optional; Set fusion switch file path");
  139. DEFINE_string(save_original_model, "", "Optional; enable output original offline model. false(default)");
  140. DEFINE_string(dynamic_batch_size, "",
  141. "Optional; If set, generate dynamic multi batch model. "
  142. "Different batch sizes are split by ','."
  143. "dynamic_batch_size, dynamic_image_size and dynamic_dims can only be set one.");
  144. DEFINE_string(dynamic_image_size, "",
  145. "Optional; If set, generate dynamic multi image size model."
  146. "Different groups of image size are split by ';',"
  147. "while different dimensions of each group are split by ','."
  148. "dynamic_batch_size, dynamic_image_size and dynamic_dims can only be set one.");
  149. DEFINE_string(dynamic_dims, "",
  150. "Optional; If set, generate dynamic input size model. "
  151. "Different groups of size are split by ';', while different dimensions of each group are split by ','."
  152. "dynamic_batch_size, dynamic_image_size and dynamic_dims can only be set one.");
  153. DEFINE_string(enable_small_channel, "0", "Optional; If set to 1, small channel is enabled.");
  154. DEFINE_string(enable_compress_weight, "false",
  155. "Optional; enable compress weight. true: enable; false(default): disable");
  156. DEFINE_string(compress_weight_conf, "", "Optional; the config file to compress weight");
  157. DEFINE_string(enable_single_stream, "", "Optional; enable single stream. true: enable; false(default): disable");
  158. DEFINE_string(log, "null", "Optional; generate atc log. Support debug, info, warning, error, null");
  159. DEFINE_string(dump_mode, "0", "Optional; generate infershape json,only support 1 , 0.");
  160. DEFINE_int32(op_debug_level, 0, "Optional; configure debug level of compiler. 0(default): close debug;"
  161. "1: open TBE compiler, export ccec file and TBE instruction mapping file; 2: open ccec compiler");
  162. DEFINE_string(enable_scope_fusion_passes, "", "Optional; validate the non-general scope fusion pass,"
  163. "multiple names can be set and separated by ','.");
  164. DEFINE_string(debug_dir, "", "Optional; the path to save the intermediate files of operator compilation");
  165. DEFINE_string(op_compiler_cache_dir, "", "Optional; the path to cache operator compilation files");
  166. DEFINE_string(op_compiler_cache_mode, "", "Optional; choose the operator compiler cache mode");
  167. DEFINE_string(mdl_bank_path, "", "Optional; model bank path");
  168. DEFINE_string(op_bank_path, "", "Optional; op bank path");
  169. DEFINE_string(display_model_info, "0", "Optional; display model info");
  170. class GFlagUtils {
  171. public:
  172. /**
  173. * @name InitGFlag
  174. * @brief initialize gflag
  175. * @return void
  176. */
  177. static void InitGFlag(int argc, char *argv[]) {
  178. // -help
  179. gflags::SetUsageMessage(
  180. "usage: ./atc <args>\n"
  181. "generate offline model example:\n"
  182. "./atc --model=./alexnet.prototxt --weight=./alexnet.caffemodel \n"
  183. "--framework=0 --output=./domi \n"
  184. "generate offline model for single op example:\n"
  185. "./atc --singleop=./op_list.json --output=./op_model \n"
  186. "===== Basic Functionality =====\n"
  187. "[General]\n"
  188. " --h/help Show this help message\n"
  189. " --mode Run mode. 0(default): generate offline model; 1: convert model to JSON format; "
  190. "3: only pre-check; 5: convert ge dump txt file to JSON format; 6: display model info\n"
  191. "\n[Input]\n"
  192. " --model Model file\n"
  193. " --weight Weight file. Required when framework is Caffe\n"
  194. " --om The model file to be converted to json\n"
  195. " --framework Framework type. 0:Caffe; 1:MindSpore; 3:Tensorflow; 5:Onnx\n"
  196. " --input_format Format of input data. E.g.: \"NCHW\"\n"
  197. " --input_shape Shape of input data. Separate multiple nodes with semicolons (;). "
  198. "Use double quotation marks (\") to enclose each argument.\n"
  199. " E.g.: \"input_name1:n1,c1,h1,w1;input_name2:n2,c2,h2,w2\"\n"
  200. " --dynamic_batch_size Set dynamic batch size. E.g.: \"batchsize1,batchsize2,batchsize3\"\n"
  201. " --dynamic_image_size Set dynamic image size. Separate multiple nodes with semicolons (;). "
  202. "Use double quotation marks (\") to enclose each argument.\n"
  203. " E.g.: \"imagesize1_height,imagesize1_width;imagesize2_height,imagesize2_width\"\n"
  204. " --dynamic_dims Set dynamic dims. Separate multiple nodes with semicolons (;). "
  205. "Use double quotation marks (\") to enclose each argument.\n"
  206. " E.g.: \"dims1_n1,dims1_n2;dims2_n1,dims2_n2\"\n"
  207. " --singleop Single op definition file. atc will generate offline "
  208. "model(s) for single op if --singleop is set.\n"
  209. "\n[Output]\n"
  210. " --output Output file path&name(needn't suffix, will add .om automatically). \n"
  211. " If --singleop is set, this arg specifies the directory to "
  212. "which the single op offline model will be generated\n"
  213. " --output_type Set net output type. Support FP32, FP16, UINT8. "
  214. "E.g.: FP16, indicates that all out nodes are set to FP16.\n"
  215. " \"node1:0:FP16;node2:1:FP32\", indicates setting the datatype of multiple out nodes.\n"
  216. " --check_report The pre-checking report file. Default value is: \"check_result.json\"\n"
  217. " --json The output json file path&name which is converted from a model\n"
  218. "\n[Target]\n"
  219. " --soc_version The soc version.\n"
  220. " --core_type Set core type AiCore or VectorCore. VectorCore: use vector core. "
  221. "Default value is: AiCore\n"
  222. " --aicore_num Set aicore num\n"
  223. "===== Advanced Functionality =====\n"
  224. "[Feature]\n"
  225. " --out_nodes Output nodes designated by users. Separate multiple nodes with semicolons (;)."
  226. "Use double quotation marks (\") to enclose each argument.\n"
  227. " E.g.: \"node_name1:0;node_name1:1;node_name2:0\"\n"
  228. " --input_fp16_nodes Input node datatype is fp16. Separate multiple nodes with semicolons (;). "
  229. "Use double quotation marks (\") to enclose each argument. "
  230. "E.g.: \"node_name1;node_name2\"\n"
  231. " --insert_op_conf Config file to insert new op\n"
  232. " --op_name_map Custom op name mapping file\n"
  233. " Note: A semicolon(;) cannot be included in each "
  234. "path, otherwise the resolved path will not match the expected one.\n"
  235. " --is_input_adjust_hw_layout Intput node datatype is fp16 and format is "
  236. "NC1HWC0, used with input_fp16_nodes. E.g.: \"true,true,false,true\"\n"
  237. " --is_output_adjust_hw_layout Net output node datatype is fp16 and format is "
  238. "NC1HWC0, used with out_nodes. E.g.: \"true,true,false,true\"\n"
  239. "\n[Model Tuning]\n"
  240. " --disable_reuse_memory The switch of reuse memory. Default value is : 0. "
  241. "0 means reuse memory, 1 means do not reuse memory.\n"
  242. " --fusion_switch_file Set fusion switch file path\n"
  243. " --enable_scope_fusion_passes validate the non-general scope fusion passes, "
  244. "multiple names can be set and separated by ','. E.g.: ScopePass1,ScopePass2,...\n"
  245. " --enable_single_stream Enable single stream. true: enable; false(default): disable\n"
  246. " --enable_small_channel Set enable small channel. 0(default): disable; 1: enable\n"
  247. " --enable_compress_weight Enable compress weight. true: enable; false(default): disable\n"
  248. " --compress_weight_conf Config file to compress weight\n"
  249. " --buffer_optimize Set buffer optimize. Support \"l2_optimize\" (default), "
  250. "\"l1_optimize\", \"off_optimize\"\n"
  251. " --mdl_bank_path Set the path of the custom repository generated after model tuning.\n"
  252. "\n[Operator Tuning]\n"
  253. " --precision_mode precision mode, support force_fp16(default), allow_mix_precision, "
  254. "allow_fp32_to_fp16, must_keep_origin_dtype.\n"
  255. " --keep_dtype Retains the precision of certain operators in inference "
  256. "scenarios by using a configuration file.\n"
  257. " --auto_tune_mode Set tune mode. E.g.: \"GA,RL\", support configure multiple, spit by ,\n"
  258. " --op_bank_path Set the path of the custom repository generated after operator tuning with Auto Tune.\n"
  259. " --op_select_implmode Set op select implmode. Support high_precision, high_performance. "
  260. "default: high_performance\n"
  261. " --optypelist_for_implmode Appoint which op to select implmode, cooperated with op_select_implmode.\n"
  262. " Separate multiple nodes with commas (,). Use double quotation marks (\") "
  263. "to enclose each argument. E.g.: \"node_name1,node_name2\"\n"
  264. " --op_debug_level Debug enable for TBE operator building.\n"
  265. " 0 (default): Disable debug; 1: Enable TBE pipe_all, "
  266. "and generate the operator CCE file and Python-CCE mapping file (.json);\n"
  267. " 2: Enable TBE pipe_all, generate the operator CCE file and Python-CCE mapping file "
  268. "(.json), and enable the CCE compiler -O0-g.\n"
  269. " 3: Disable debug, and keep generating kernel file (.o and .json)\n"
  270. "\n[Debug]\n"
  271. " --save_original_model Control whether to output original model. E.g.: true: output original model\n"
  272. " --log Generate log with level. Support debug, info, warning, error, null\n"
  273. " --dump_mode The switch of dump json with shape, to be used with mode 1. "
  274. "0(default): disable; 1: enable.\n"
  275. " --debug_dir Set the save path of operator compilation intermediate files.\n"
  276. "Default value: ./kernel_meta\n"
  277. " --op_compiler_cache_dir Set the save path of operator compilation cache files.\n"
  278. "Default value: $HOME/atc_data\n"
  279. " --op_compiler_cache_mode Set the operator compilation cache mode."
  280. "Options are disable(default), enable and force(force to refresh the cache)\n"
  281. " --display_model_info enable for display model info; 0(default): close display, 1: open display");
  282. gflags::ParseCommandLineNonHelpFlags(&argc, &argv, true);
  283. // Using gflags to analyze input parameters
  284. GflagsUtils::ChangeHelpFlags(FLAGS_h);
  285. gflags::HandleCommandLineHelpFlags();
  286. }
  287. static Status CheckDumpInfershapeJsonFlags() {
  288. Status ret = CheckFrameWorkValid(FLAGS_framework, FLAGS_weight);
  289. GE_CHK_BOOL_EXEC(ret == domi::SUCCESS, return domi::FAILED,
  290. "check custom aicpu run so failed!");
  291. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  292. FLAGS_weight != "" && !ge::CheckInputPathValid(FLAGS_weight, "--weight"),
  293. return domi::FAILED, "Input parameter[--weight]'s value[%s] is invalid!",
  294. FLAGS_weight.c_str());
  295. return domi::SUCCESS;
  296. }
  297. static Status CheckFlags() {
  298. Status ret = ge::SUCCESS;
  299. // No model file information passed in
  300. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  301. FLAGS_model == "",
  302. ErrorManager::GetInstance().ATCReportErrMessage("E10004", {"parameter"}, {"model"});
  303. ret = ge::FAILED, "Input parameter[--model]'s value is empty!");
  304. // check param disable_reuse_memory
  305. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  306. ge::CheckDisableReuseMemoryParamValid(to_string(FLAGS_disable_reuse_memory)) != ge::SUCCESS,
  307. ret = ge::FAILED, "check disable_reuse_memory failed!");
  308. // check optypelist_for_implmode and op_select_implmode
  309. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  310. ge::CheckImplmodeParamValid(FLAGS_optypelist_for_implmode,
  311. FLAGS_op_select_implmode) != ge::SUCCESS,
  312. ret = ge::FAILED, "check optypelist_for_implmode and op_select_implmode failed!");
  313. // No output file information passed in
  314. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  315. FLAGS_mode == GEN_OM_MODEL && FLAGS_output == "",
  316. ErrorManager::GetInstance().ATCReportErrMessage("E10004", {"parameter"}, {"output"});
  317. ret = ge::FAILED, "Input parameter[--output]'s value is empty!");
  318. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  319. CheckFrameWorkValid(FLAGS_framework, FLAGS_weight) != ge::SUCCESS,
  320. ret = ge::FAILED,
  321. "CheckFrameWorkValid failed");
  322. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  323. ge::CheckDynamicInputParamValid(FLAGS_dynamic_batch_size, FLAGS_dynamic_image_size,
  324. FLAGS_dynamic_dims, FLAGS_input_shape,
  325. FLAGS_input_format, is_dynamic_input) != ge::SUCCESS,
  326. ret = ge::FAILED, "check dynamic size(batch size, image size or dims) failed!");
  327. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  328. !FLAGS_insert_op_conf.empty() && !FLAGS_dynamic_dims.empty(),
  329. ErrorManager::GetInstance().ATCReportErrMessage("E10001",
  330. {"parameter", "value", "reason"},
  331. {"--insert_op_conf", FLAGS_insert_op_conf,
  332. "dynamic dims function does not support aipp"});
  333. ret = ge::FAILED, "dynamic dims function does not support aipp");
  334. #if !defined(__ANDROID__) && !defined(ANDROID)
  335. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(!CheckEncryptModeValid(FLAGS_encrypt_mode), ret = ge::FAILED,
  336. "encrypt_mode %d not valid!!", FLAGS_encrypt_mode);
  337. if (FLAGS_encrypt_mode == 0) { // Encryption mode
  338. GELOGI("ge will run with encrypt!");
  339. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(!ge::CheckInputPathValid(FLAGS_encrypt_key), ret = ge::FAILED,
  340. "encrypt_key file not found!!");
  341. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(!ge::CheckInputPathValid(FLAGS_certificate), ret = ge::FAILED,
  342. "certificate file not found!!");
  343. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(!ge::CheckInputPathValid(FLAGS_hardware_key), ret = ge::FAILED,
  344. "hardware_key file not found!!");
  345. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(!ge::CheckInputPathValid(FLAGS_private_key), ret = ge::FAILED,
  346. "private_key file not found!!");
  347. } else { // No encryption
  348. GELOGI("ge will run without encrypt!");
  349. }
  350. #endif
  351. /**
  352. * Check the validity of the I / O file path
  353. */
  354. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  355. FLAGS_model != "" && !ge::CheckInputPathValid(FLAGS_model, "--model"), ret = ge::FAILED,
  356. "model file %s not found!!", FLAGS_model.c_str());
  357. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  358. FLAGS_weight != "" && !ge::CheckInputPathValid(FLAGS_weight, "--weight"),
  359. ret = ge::FAILED, "weight file %s not found!!",
  360. FLAGS_weight.c_str());
  361. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  362. FLAGS_cal_conf != "" && !ge::CheckInputPathValid(FLAGS_cal_conf, "--cal_conf"),
  363. ret = ge::FAILED, "calibration config file %s not found!!",
  364. FLAGS_cal_conf.c_str());
  365. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  366. FLAGS_op_name_map != "" && !ge::CheckInputPathValid(FLAGS_op_name_map, "--op_name_map"),
  367. ret = ge::FAILED, "op config file %s not found!!",
  368. FLAGS_op_name_map.c_str());
  369. GE_CHK_BOOL_EXEC(ge::CheckInsertOpConfParamValid(std::string(FLAGS_insert_op_conf)) == ge::SUCCESS,
  370. ret = ge::FAILED, "check insert op conf failed!");
  371. GE_CHK_BOOL_EXEC(ge::CheckCompressWeightParamValid(
  372. FLAGS_enable_compress_weight, FLAGS_compress_weight_conf) == ge::SUCCESS,
  373. ret = ge::FAILED, "check compress weight failed!");
  374. GE_CHK_BOOL_EXEC(ge::CheckKeepTypeParamValid(FLAGS_keep_dtype) == ge::SUCCESS,
  375. ret = ge::FAILED, "check keep dtype failed!");
  376. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  377. !ge::CheckOutputPathValid(FLAGS_check_report, "--check_report"), ret = ge::FAILED,
  378. "check_report file %s not found!!", FLAGS_check_report.c_str());
  379. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  380. FLAGS_mode == GEN_OM_MODEL && FLAGS_output != "" &&
  381. (!ge::CheckOutputPathValid(FLAGS_output, "--output") || !CheckPathWithName(FLAGS_output)),
  382. ret = ge::FAILED, "output path %s is not valid!!", FLAGS_output.c_str());
  383. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  384. FLAGS_save_original_model != "" &&
  385. FLAGS_save_original_model != "true" &&
  386. FLAGS_save_original_model != "false",
  387. ErrorManager::GetInstance().ATCReportErrMessage(
  388. "E10005", {"parameter", "value"}, {"save_original_model", FLAGS_save_original_model});
  389. ret = ge::FAILED,
  390. "Input parameter[--save_original_model]'s value[%s] must be true or false.",
  391. FLAGS_save_original_model.c_str());
  392. GE_CHK_BOOL_EXEC(ge::CheckBufferOptimizeParamValid(FLAGS_buffer_optimize) == ge::SUCCESS,
  393. ret = ge::FAILED, "check output type failed!");
  394. GE_CHK_BOOL_EXEC(
  395. ge::CheckEnableSingleStreamParamValid(std::string(FLAGS_enable_single_stream)) == ge::SUCCESS,
  396. ret = ge::FAILED, "check enable single stream failed!");
  397. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG((FLAGS_display_model_info != "0") && (FLAGS_display_model_info != "1"),
  398. ErrorManager::GetInstance().ATCReportErrMessage("E10006", {"parameter"}, {"display_model_info"});
  399. ret = ge::FAILED, "Input parameter[--display_model_info]'s value must be 1 or 0.");
  400. return ret;
  401. }
  402. /**
  403. * Verifying the parameters of converting model to JSON
  404. * 1. Fmk_model
  405. * 2. out_json
  406. **/
  407. static Status CheckConverJsonParamFlags() {
  408. Status ret = ge::SUCCESS;
  409. // No model path passed in
  410. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(FLAGS_om == "",
  411. ErrorManager::GetInstance().ATCReportErrMessage("E10004", {"parameter"}, {"om"});
  412. ret = ge::FAILED,
  413. "Input parameter[--om]'s value is empty!!");
  414. // JSON path not passed in
  415. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(FLAGS_json == "",
  416. ErrorManager::GetInstance().ATCReportErrMessage("E10004", {"parameter"}, {"json"});
  417. ret = ge::FAILED,
  418. "Input parameter[--json]'s value is empty!!");
  419. // Check if the model path is valid
  420. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  421. FLAGS_om != "" && !ge::CheckInputPathValid(FLAGS_om, "--om"),
  422. ret = ge::FAILED,
  423. "model file path is invalid: %s.", FLAGS_om.c_str());
  424. // Check whether the JSON path is valid
  425. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  426. FLAGS_json != "" && !ge::CheckOutputPathValid(FLAGS_json, "--json"),
  427. ret = ge::FAILED,
  428. "json file path is invalid: %s.", FLAGS_json.c_str());
  429. return ret;
  430. }
  431. /**
  432. * Check command line parameters for explicit settings
  433. * true: Explicit setup
  434. * false: Not set up
  435. * */
  436. static bool CheckFlagSet(string flag) {
  437. gflags::CommandLineFlagInfo info;
  438. return !(gflags::GetCommandLineFlagInfo(flag.c_str(), &info) && info.is_default);
  439. }
  440. private:
  441. static bool CheckEncryptModeValid(const int encrypt_mode) {
  442. #if !defined(__ANDROID__) && !defined(ANDROID)
  443. if (encrypt_mode != 0 && encrypt_mode != -1) {
  444. DOMI_LOGE("encrypt mode must be 0 or -1");
  445. return false;
  446. }
  447. #else
  448. if (encrypt_mode != -1) {
  449. DOMI_LOGE("encrypt mode must be -1");
  450. return false;
  451. }
  452. #endif
  453. return true;
  454. }
  455. static Status CheckFrameWorkValid(int framework, const std::string weight_file) {
  456. if (framework != (int32_t)domi::CAFFE && framework != (int32_t)domi::TENSORFLOW &&
  457. framework != (int32_t)domi::MINDSPORE && framework != (int32_t)domi::ONNX) {
  458. // No framework information was passed in or the entered framework is illegal
  459. ErrorManager::GetInstance().ATCReportErrMessage(
  460. "E10007", {"parameter", "support"},
  461. {"framework", "0(Caffe) or 1(MindSpore) or 3(TensorFlow) or 5(Onnx)"});
  462. DOMI_LOGE("Input parameter[--framework] is mandatory and it's value must be: "
  463. "0(Caffe) or 1(MindSpore) or 3(TensorFlow) or 5(Onnx).");
  464. return domi::PARAM_INVALID;
  465. }
  466. if ((framework == (int32_t)domi::CAFFE) && (weight_file == "")) {
  467. ErrorManager::GetInstance().ATCReportErrMessage("E10008", {"parameter"}, {"weight"});
  468. DOMI_LOGE("Input parameter[--weight]'s value is empty when framework is 0(CAFFE)!");
  469. return domi::PARAM_INVALID;
  470. }
  471. if ((framework == (int32_t)domi::TENSORFLOW) && (weight_file != "")) {
  472. GELOGW("Parameter weight is ignored for TensorFlow.");
  473. }
  474. if ((framework == (int32_t)domi::ONNX) && (weight_file != "")) {
  475. GELOGW("Parameter weight is ignored for Onnx.");
  476. }
  477. return domi::SUCCESS;
  478. }
  479. static bool CheckPathWithName(const std::string &fileName) {
  480. // Determine file path length
  481. if (fileName.size() > static_cast<int>(PATH_MAX)) {
  482. ErrorManager::GetInstance().ATCReportErrMessage(
  483. "E10021", {"parameter", "size"}, {"output", std::to_string(PATH_MAX)});
  484. GELOGE(ge::FAILED, "Input parameter[--output]'s path is too long, it must be less than %d", PATH_MAX);
  485. return false;
  486. }
  487. // Find the last separator
  488. int slashPosition = fileName.size() - 1;
  489. for (; slashPosition >= 0; slashPosition--) {
  490. if (fileName[slashPosition] == '\\' || fileName[slashPosition] == '/') {
  491. break;
  492. }
  493. }
  494. // Failure if no filename follows the path
  495. if (slashPosition == static_cast<int>(fileName.size() - 1)) {
  496. ErrorManager::GetInstance().ATCReportErrMessage("E10022", {"parameter", "filename"}, {"output", fileName});
  497. DOMI_LOGE("Input parameter[--output]'s path[%s] not include file name", fileName.c_str());
  498. return false;
  499. }
  500. return true;
  501. }
  502. };
  503. void SetDynamicInputSizeOptions() {
  504. if (!FLAGS_dynamic_batch_size.empty()) {
  505. domi::GetContext().dynamic_batch_size = FLAGS_dynamic_batch_size;
  506. }
  507. if (!FLAGS_dynamic_image_size.empty()) {
  508. domi::GetContext().dynamic_image_size = FLAGS_dynamic_image_size;
  509. }
  510. if (!FLAGS_dynamic_dims.empty()) {
  511. domi::GetContext().dynamic_dims = FLAGS_dynamic_dims;
  512. }
  513. }
  514. /// Validate the non-general scope fusion pass.
  515. /// The parameter is set to the name of the fusion rule.
  516. /// Multiple names can be set and separated by ",".
  517. void SetEnableScopeFusionPasses(const std::string pass_names) {
  518. ge::GetParserContext().enable_scope_fusion_passes = pass_names;
  519. }
  520. static bool CheckInputFormat() {
  521. if (FLAGS_input_format.empty()) {
  522. // Set default format
  523. if (FLAGS_framework == static_cast<int32_t>(domi::TENSORFLOW)) {
  524. FLAGS_input_format = "NHWC";
  525. } else {
  526. FLAGS_input_format = "NCHW";
  527. }
  528. return true;
  529. } else if ((FLAGS_framework == static_cast<int32_t>(domi::CAFFE))) { // caffe
  530. if (ge::caffe_support_input_format.find(FLAGS_input_format) != ge::caffe_support_input_format.end()) {
  531. return true;
  532. }
  533. // only support NCHW ND
  534. ErrorManager::GetInstance().ATCReportErrMessage(
  535. "E10001", {"parameter", "value", "reason"}, {"--input_format", FLAGS_input_format, kCaffeFormatSupport});
  536. GELOGE(ge::FAILED,
  537. "Invalid value for --input_format[%s], %s.", FLAGS_input_format.c_str(), kCaffeFormatSupport);
  538. return false;
  539. } else if ((FLAGS_framework == static_cast<int32_t>(domi::TENSORFLOW))) { // tf
  540. if (ge::tf_support_input_format.find(FLAGS_input_format) != ge::tf_support_input_format.end()) {
  541. return true;
  542. }
  543. // only support NCHW NHWC ND NCDHW NDHWC
  544. ErrorManager::GetInstance().ATCReportErrMessage(
  545. "E10001", {"parameter", "value", "reason"}, {"--input_format", FLAGS_input_format, kTFFormatSupport});
  546. GELOGE(ge::FAILED,
  547. "Invalid value for --input_format[%s], %s.", FLAGS_input_format.c_str(), kTFFormatSupport);
  548. return false;
  549. } else if (FLAGS_framework == static_cast<int32_t>(domi::ONNX)) {
  550. if (ge::onnx_support_input_format.find(FLAGS_input_format) != ge::onnx_support_input_format.end()) {
  551. return true;
  552. }
  553. // only support NCHW ND
  554. ErrorManager::GetInstance().ATCReportErrMessage(
  555. "E10001", {"parameter", "value", "reason"}, {"--input_format", FLAGS_input_format, kONNXFormatSupport});
  556. GELOGE(ge::FAILED,
  557. "Invalid value for --input_format[%s], %s.", FLAGS_input_format.c_str(), kONNXFormatSupport);
  558. return false;
  559. }
  560. return true;
  561. }
  562. #if !defined(__ANDROID__) && !defined(ANDROID)
  563. static void GetCustomOpPath(std::string &customop_path) {
  564. GELOGI("Enter get custom op path schedule");
  565. std::string fmk_type = ge::TypeUtils::FmkTypeToSerialString(static_cast<domi::FrameworkType>(FLAGS_framework));
  566. GELOGI("Framework type is %s.", fmk_type.c_str());
  567. const char *path_env = std::getenv("ASCEND_OPP_PATH");
  568. if (path_env != nullptr) {
  569. std::string path = path_env;
  570. customop_path = (path + "/framework/custom" + "/:") + (path + "/framework/built-in/" + fmk_type);
  571. GELOGI("Get custom so path from env : %s", path_env);
  572. return;
  573. }
  574. std::string path_base = ge::GELib::GetPath();
  575. GELOGI("path_base is %s", path_base.c_str());
  576. path_base = path_base.substr(0, path_base.rfind('/'));
  577. path_base = path_base.substr(0, path_base.rfind('/') + 1);
  578. customop_path = (path_base + "ops/framework/custom" + "/:") + (path_base + "ops/framework/built-in/" + fmk_type);
  579. return;
  580. }
  581. void GetPluginSoFileList(const string &path, vector<string> &fileList, string &caffe_parser_path) {
  582. // Support to split multiple so directories by ":"
  583. GELOGI("path is %s", path.c_str());
  584. vector<string> v_path = ge::StringUtils::Split(path, ':');
  585. for (size_t i = 0; i < v_path.size(); ++i) {
  586. ge::FindParserSo(v_path[i], fileList, caffe_parser_path);
  587. GELOGI("CustomOpLib full name = %s", v_path[i].c_str());
  588. }
  589. }
  590. void LoadModelParserLib(std::string caffe_parser_path) {
  591. if (FLAGS_framework == static_cast<int32_t>(domi::TENSORFLOW)) {
  592. void *tf_handle = dlopen("libfmk_parser.so", RTLD_NOW | RTLD_GLOBAL);
  593. if (tf_handle == nullptr) {
  594. GELOGW("dlopen fmk library [libfmk_parser.so] failed.");
  595. return;
  596. }
  597. GELOGI("plugin load libfmk_parser.so success.");
  598. } else if (FLAGS_framework == static_cast<int32_t>(domi::CAFFE)) {
  599. // What we are dealing with here is that the user modifies the caffe.proto scenario.
  600. // If no lib_Caffe_Parser.so is found under the plugin path, use the default lib_Caffe_Parser.so path.
  601. caffe_parser_path = caffe_parser_path.empty() ? "lib_caffe_parser.so" : caffe_parser_path;
  602. void *handle = dlopen(caffe_parser_path.c_str(), RTLD_NOW | RTLD_GLOBAL);
  603. if (handle == nullptr) {
  604. GELOGW("dlopen failed, plugin name:%s. Message(%s).", caffe_parser_path.c_str(), dlerror());
  605. return;
  606. }
  607. GELOGI("plugin load %s success.", caffe_parser_path.c_str());
  608. // According to the dependency, the Caffe parsing module of the framework is loaded here( libfmk_parser.so).
  609. // (depend on the lib_caffe_parser.so)
  610. void *fmk_handle = dlopen("libfmk_parser.so", RTLD_NOW | RTLD_GLOBAL);
  611. if (fmk_handle == nullptr) {
  612. GELOGW("dlopen fmk library [libfmk_parser.so] failed.");
  613. if (dlclose(handle) != 0) {
  614. GELOGW("dlclose lib_caffe_parser.so failed.");
  615. }
  616. return;
  617. }
  618. GELOGI("plugin load libfmk_parser.so success.");
  619. } else if (FLAGS_framework == static_cast<int32_t>(domi::ONNX)) {
  620. void *handle = dlopen("libfmk_onnx_parser.so", RTLD_NOW | RTLD_GLOBAL);
  621. if (handle == nullptr) {
  622. GELOGW("dlopen fmk library [libfmk_onnx_parser.so] failed.");
  623. return;
  624. }
  625. GELOGI("plugin load libfmk_onnx_parser.so success.");
  626. } else {
  627. GELOGW("Framework:%s is not support.",
  628. ge::TypeUtils::FmkTypeToSerialString(static_cast<domi::FrameworkType>(FLAGS_framework)).c_str());
  629. return;
  630. }
  631. return;
  632. }
  633. void LoadCustomOpLib(bool need_load_ops_plugin) {
  634. std::string plugin_path;
  635. GetCustomOpPath(plugin_path);
  636. vector<string> fileList;
  637. string caffe_parser_path = "";
  638. // whether there are files in the plugin so path
  639. GetPluginSoFileList(plugin_path, fileList, caffe_parser_path);
  640. // no file
  641. if (fileList.empty() && caffe_parser_path.empty()) {
  642. GELOGW("can not find any plugin file in plugin_path: %s", plugin_path.c_str());
  643. }
  644. LoadModelParserLib(caffe_parser_path);
  645. if (!need_load_ops_plugin) {
  646. GELOGI("No need to load ops plugin so.");
  647. return;
  648. }
  649. OpRegistry::Instance()->registrationDatas.clear();
  650. // load other so files except lib_caffe_parser.so in the plugin so path
  651. for (auto elem : fileList) {
  652. ge::StringUtils::Trim(elem);
  653. void *handle = dlopen(elem.c_str(), RTLD_NOW | RTLD_GLOBAL);
  654. if (handle == nullptr) {
  655. GELOGW("dlopen failed, plugin name:%s. Message(%s).", elem.c_str(), dlerror());
  656. } else {
  657. GELOGI("plugin load %s success.", elem.c_str());
  658. }
  659. }
  660. std::vector<OpRegistrationData> registrationDatas = OpRegistry::Instance()->registrationDatas;
  661. for (OpRegistrationData reg_data : registrationDatas) {
  662. if (reg_data.GetFrameworkType() == static_cast<domi::FrameworkType>(FLAGS_framework)) {
  663. (void)ge::OpRegistrationTbe::Instance()->Finalize(reg_data);
  664. (void)OpRegistry::Instance()->Register(reg_data);
  665. }
  666. }
  667. }
  668. void SaveCustomCaffeProtoPath() {
  669. GELOGI("Enter save custom caffe proto path.");
  670. std::string path_base = ge::GELib::GetPath();
  671. GELOGI("path_base is %s", path_base.c_str());
  672. path_base = path_base.substr(0, path_base.rfind('/'));
  673. path_base = path_base.substr(0, path_base.rfind('/') + 1);
  674. ge::GetParserContext().caffe_proto_path = path_base + "include/proto/";
  675. string customop_path;
  676. const char *path_env = std::getenv("ASCEND_OPP_PATH");
  677. if (path_env != nullptr) {
  678. std::string path = path_env;
  679. customop_path = path + "/framework/custom/caffe/";
  680. GELOGI("Get custom proto path from env : %s", path_env);
  681. ge::GetParserContext().custom_proto_path = customop_path;
  682. return;
  683. }
  684. customop_path = path_base + "ops/framework/custom/caffe/";
  685. ge::GetParserContext().custom_proto_path = customop_path;
  686. return;
  687. }
  688. #endif
  689. Status CreateInputsForInference(const ge::Graph &graph, vector<ge::GeTensor> &inputs) {
  690. auto compute_graph = ge::GraphUtils::GetComputeGraph(graph);
  691. GE_CHECK_NOTNULL(compute_graph);
  692. for (ge::NodePtr &input_node : compute_graph->GetAllNodes()) {
  693. GE_CHECK_NOTNULL(input_node);
  694. ge::OpDescPtr op = input_node->GetOpDesc();
  695. GE_CHECK_NOTNULL(op);
  696. if (op->GetType() == ge::DATA) {
  697. GELOGI("Data op inputDesc size is: %zu", op->GetAllInputsDesc().size());
  698. ge::GeTensorDesc tensor = op->GetInputDesc(0);
  699. string data_op_name = op->GetName();
  700. GELOGI("Data op name is: %s", data_op_name.c_str());
  701. ge::GeShape data_shape;
  702. auto iter = domi::GetContext().input_dims.find(data_op_name);
  703. if (iter != domi::GetContext().input_dims.end()) {
  704. data_shape = ge::GeShape(iter->second);
  705. GELOGI("Data op get shape from Context.");
  706. } else {
  707. data_shape = tensor.GetShape();
  708. GELOGI("Data op get shape from InputDesc in geir graph.");
  709. }
  710. ge::DataType data_type = tensor.GetDataType();
  711. string data_type_str = ge::TypeUtils::DataTypeToSerialString(data_type);
  712. GELOGI("Data op get data type:%s from InputDesc in geir graph.", data_type_str.c_str());
  713. ge::GeTensor input_tensor;
  714. ge::GeTensorDesc desc(data_shape, ge::Format(domi::GetContext().format), data_type);
  715. input_tensor.SetTensorDesc(desc);
  716. inputs.push_back(input_tensor);
  717. }
  718. }
  719. GELOGI("Build ME model, inputs size is: %zu", inputs.size());
  720. return ge::SUCCESS;
  721. }
  722. domi::Status GenerateInfershapeJson() {
  723. if (!CheckInputFormat()) {
  724. GELOGE(ge::FAILED, "Check input_format failed");
  725. return domi::FAILED;
  726. }
  727. Status ret = GFlagUtils::CheckDumpInfershapeJsonFlags();
  728. GE_CHK_BOOL_EXEC(ret == domi::SUCCESS, return domi::FAILED, "Check flags failed!");
  729. ge::GeGenerator ge_generator;
  730. std::map<string, string> options;
  731. ge::Status geRet = ge_generator.Initialize(options, domi::GetContext());
  732. if (geRet != ge::SUCCESS) {
  733. DOMI_LOGE("GeGenerator initialize failed!");
  734. return domi::FAILED;
  735. }
  736. ge::Graph graph;
  737. std::map<string, string> atc_params;
  738. atc_params.insert(std::pair<string, string>("input_format", FLAGS_input_format));
  739. ret = ParseGraph(graph, atc_params, FLAGS_om.c_str(), FLAGS_weight.c_str(), (domi::FrameworkType) FLAGS_framework,
  740. "", FLAGS_target.c_str(), (ge::RunMode) FLAGS_mode, false);
  741. if (ret != ge::SUCCESS) {
  742. DOMI_LOGE("ATC Parse graph domi::FAILED");
  743. (void)ge_generator.Finalize();
  744. return domi::FAILED;
  745. }
  746. geRet = ge_generator.GenerateInfershapeGraph(graph);
  747. if (geRet != ge::SUCCESS) {
  748. DOMI_LOGE("ATC GenerateInfershapeJson failed");
  749. (void)ge_generator.Finalize();
  750. return domi::FAILED;
  751. }
  752. if (DumpInfershapeJson(graph, FLAGS_json.c_str()) != SUCCESS) {
  753. DOMI_LOGE("ATC DumpInfershapeJson failed");
  754. (void)ge_generator.Finalize();
  755. return domi::FAILED;
  756. }
  757. (void)ge_generator.Finalize();
  758. return ge::SUCCESS;
  759. }
  760. static Status ConvertModelToJson(int fwk_type, const string &model_file, const string &json_file) {
  761. Status ret = ge::SUCCESS;
  762. if (fwk_type == -1) {
  763. ret = ge::ConvertOm(model_file.c_str(), json_file.c_str(), true);
  764. return ret;
  765. }
  766. if ((fwk_type != domi::TENSORFLOW) && (fwk_type != domi::CAFFE) && (fwk_type != domi::ONNX)) {
  767. ErrorManager::GetInstance().ATCReportErrMessage(
  768. "E10001", {"parameter", "value", "reason"},
  769. {"--framework", std::to_string(fwk_type), kModelToJsonSupport});
  770. GELOGE(ge::FAILED, "Invalid value for --framework[%d], %s.", fwk_type, kModelToJsonSupport);
  771. ret = ge::FAILED;
  772. }
  773. if (FLAGS_dump_mode != "0" && FLAGS_dump_mode != "1") {
  774. ErrorManager::GetInstance().ATCReportErrMessage("E10006", {"parameter"}, {"dump_mode"});
  775. GELOGE(ge::FAILED, "Input parameter[--dump_mode]'s value must be 1 or 0.");
  776. ret = ge::FAILED;
  777. }
  778. if (ret != ge::SUCCESS) return ret;
  779. // Need to save caffe.proto path
  780. SaveCustomCaffeProtoPath();
  781. if (FLAGS_dump_mode == "0") {
  782. // Caffe or tf model to json depend on lib_caffe_parser.so or libfmk_parser.so.
  783. LoadCustomOpLib(false);
  784. ret = ge::ConvertFwkModelToJson((domi::FrameworkType)fwk_type, model_file.c_str(), json_file.c_str());
  785. } else if (FLAGS_dump_mode == "1") {
  786. // Caffe or tf model to json depend on lib_caffe_parser.so or libfmk_parser.so and ops plugin so.
  787. LoadCustomOpLib(true);
  788. ret = GenerateInfershapeJson();
  789. }
  790. return ret;
  791. }
  792. static Status SetAttrOptions(ge::Graph &graph) {
  793. if (!FLAGS_keep_dtype.empty()) {
  794. if (ge::aclgrphSetOpAttr(graph, ge::ATTR_TYPE_KEEP_DTYPE, FLAGS_keep_dtype.c_str()) != ge::GRAPH_SUCCESS) {
  795. return ge::FAILED;
  796. }
  797. }
  798. if (!FLAGS_compress_weight_conf.empty()) {
  799. if (ge::aclgrphSetOpAttr(graph, ge::ATTR_TYPE_WEIGHT_COMPRESS, FLAGS_compress_weight_conf.c_str())
  800. != ge::GRAPH_SUCCESS) {
  801. return ge::FAILED;
  802. }
  803. }
  804. return ge::SUCCESS;
  805. }
  806. domi::Status GenerateModel(std::map<string, string> &options, std::string output) {
  807. ge::GeGenerator ge_generator;
  808. ge::Status geRet = ge::SUCCESS;
  809. std::shared_ptr<ge::GELib> instance_ptr = ge::GELib::GetInstance();
  810. if (instance_ptr == nullptr || !instance_ptr->InitFlag()) {
  811. geRet = ge::GELib::Initialize(options);
  812. if (geRet != ge::SUCCESS) {
  813. DOMI_LOGE("GE initialize failed!");
  814. return domi::FAILED;
  815. }
  816. }
  817. geRet = ge_generator.Initialize(options, domi::GetContext());
  818. if (geRet != ge::SUCCESS) {
  819. DOMI_LOGE("GeGenerator initialize failed!");
  820. (void)ge::GELib::GetInstance()->Finalize();
  821. return domi::FAILED;
  822. }
  823. ge::Graph graph;
  824. std::vector<ge::GeTensor> inputs;
  825. if (FLAGS_framework == domi::MINDSPORE) {
  826. // load model from file
  827. ge::Model load_model = ge::Model("loadmodel", "version2");
  828. auto ret1 = load_model.LoadFromFile(FLAGS_model);
  829. if (ret1 != ge::GRAPH_SUCCESS) {
  830. ErrorManager::GetInstance().ATCReportErrMessage("E10041", {"parameter"}, {FLAGS_model});
  831. DOMI_LOGE("Load model from %s failed, please check model file or "
  832. "input parameter[--framework] is correct", FLAGS_model.c_str());
  833. (void)ge_generator.Finalize();
  834. (void)ge::GELib::GetInstance()->Finalize();
  835. return domi::FAILED;
  836. }
  837. graph = load_model.GetGraph();
  838. GE_CHK_STATUS_EXEC(ge::InitDomiOmgContext(FLAGS_input_shape, FLAGS_input_format, "", is_dynamic_input),
  839. GELOGE(ge::FAILED, "ATC Generate call InitDomiOmgContext ret fail");
  840. (void)ge_generator.Finalize(); (void)ge::GELib::GetInstance()->Finalize(); return domi::FAILED);
  841. Status ret = CreateInputsForInference(graph, inputs);
  842. if (ret != ge::SUCCESS) {
  843. GELOGE(ge::FAILED, "create inputs for inference failed.");
  844. (void)ge_generator.Finalize();
  845. (void)ge::GELib::GetInstance()->Finalize();
  846. return domi::FAILED;
  847. }
  848. } else {
  849. std::map<string, string> atc_params;
  850. atc_params.insert(std::pair<string, string>("input_shape", FLAGS_input_shape));
  851. atc_params.insert(std::pair<string, string>("out_nodes", FLAGS_out_nodes));
  852. atc_params.insert(std::pair<string, string>("input_format", FLAGS_input_format));
  853. atc_params.insert(std::pair<string, string>("check_report", FLAGS_check_report));
  854. atc_params.insert(std::pair<string, string>("input_fp16_nodes", FLAGS_input_fp16_nodes));
  855. atc_params.insert(std::pair<string, string>("is_input_adjust_hw_layout", FLAGS_is_input_adjust_hw_layout));
  856. atc_params.insert(std::pair<string, string>("is_output_adjust_hw_layout", FLAGS_is_output_adjust_hw_layout));
  857. atc_params.insert(std::pair<string, string>(string(ge::OUTPUT_DATATYPE), FLAGS_output_type));
  858. atc_params.insert(std::pair<string, string>("output", output));
  859. Status ret =
  860. ParseGraph(graph, atc_params, FLAGS_model.c_str(), FLAGS_weight.c_str(), (domi::FrameworkType)FLAGS_framework,
  861. FLAGS_op_name_map.c_str(), FLAGS_target.c_str(), (ge::RunMode)FLAGS_mode, is_dynamic_input);
  862. // in ONLY_PRE_CHECK mode, pre-checking report has already saved in ParseGraph
  863. if (FLAGS_mode == ge::ONLY_PRE_CHECK) {
  864. (void)ge_generator.Finalize();
  865. (void)ge::GELib::GetInstance()->Finalize();
  866. if (ret != ge::SUCCESS) {
  867. DOMI_LOGE("ATC precheck fail.");
  868. return domi::FAILED;
  869. }
  870. return domi::SUCCESS;
  871. }
  872. if (ret != ge::SUCCESS) {
  873. DOMI_LOGE("ATC Parse graph domi::FAILED");
  874. DOMI_LOGE("ATC Generate execute failed"); // Duplicate log. (for test case
  875. (void)ge_generator.Finalize();
  876. (void)ge::GELib::GetInstance()->Finalize();
  877. return domi::FAILED;
  878. }
  879. if (ge::SetOutputNodeInfo(graph, FLAGS_output_type, "") != domi::SUCCESS) {
  880. DOMI_LOGE("Set output node info fail.");
  881. (void)ge_generator.Finalize();
  882. (void)ge::GELib::GetInstance()->Finalize();
  883. return domi::FAILED;
  884. }
  885. }
  886. if (SetAttrOptions(graph) != ge::SUCCESS) {
  887. (void)ge_generator.Finalize();
  888. (void)ge::GELib::GetInstance()->Finalize();
  889. return domi::FAILED;
  890. }
  891. geRet = ge_generator.GenerateOfflineModel(graph, output, inputs);
  892. if (geRet != ge::SUCCESS) {
  893. DOMI_LOGE("GE GenerateOfflineModel execute failed");
  894. DOMI_LOGE("ATC Generate execute failed"); // Duplicate log. (for test case
  895. // checking error log)
  896. (void)ge_generator.Finalize();
  897. (void)ge::GELib::GetInstance()->Finalize();
  898. return domi::FAILED;
  899. }
  900. (void)ge_generator.Finalize();
  901. (void)ge::GELib::GetInstance()->Finalize();
  902. return ge::SUCCESS;
  903. }
  904. static void SetEnvForSingleOp(std::map<string, string> &options) {
  905. string flag_on = "1";
  906. string flag_off = "0";
  907. options.emplace(ge::GE_FE_FLAG, flag_on);
  908. options.emplace(ge::STREAM_NUM, "1"); // single op only use one stream
  909. options.emplace(ge::RUN_FLAG, flag_off);
  910. options.emplace(ge::OPTION_GRAPH_RUN_MODE, flag_off);
  911. options.emplace(ge::SINGLE_OP_FLAG, flag_on);
  912. options.emplace(ge::PRECISION_MODE, FLAGS_precision_mode);
  913. options.emplace(ge::SOC_VERSION, FLAGS_soc_version);
  914. options.emplace(ge::CORE_TYPE, FLAGS_core_type);
  915. options.emplace(ge::AICORE_NUM, FLAGS_aicore_num);
  916. options.emplace(ge::OP_SELECT_IMPL_MODE, FLAGS_op_select_implmode);
  917. options.emplace(ge::OPTYPELIST_FOR_IMPLMODE, FLAGS_optypelist_for_implmode);
  918. options.emplace(ge::AUTO_TUNE_MODE, FLAGS_auto_tune_mode);
  919. options.emplace(ge::OP_DEBUG_LEVEL, to_string(FLAGS_op_debug_level));
  920. options.emplace(ge::DEBUG_DIR, FLAGS_debug_dir);
  921. options.emplace(ge::OP_COMPILER_CACHE_DIR, FLAGS_op_compiler_cache_dir);
  922. options.emplace(ge::OP_COMPILER_CACHE_MODE, FLAGS_op_compiler_cache_mode);
  923. options.emplace(ge::MDL_BANK_PATH_FLAG, FLAGS_mdl_bank_path);
  924. options.emplace(ge::OP_BANK_PATH_FLAG, FLAGS_op_bank_path);
  925. }
  926. domi::Status GenerateSingleOp(const std::string& json_file_path) {
  927. if (!FLAGS_output.empty() && !ge::CheckOutputPathValid(FLAGS_output, "--output")) {
  928. DOMI_LOGE("output path %s is not valid!", FLAGS_output.c_str());
  929. return domi::FAILED;
  930. }
  931. // check optypelist_for_implmode and op_select_implmode
  932. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  933. ge::CheckImplmodeParamValid(FLAGS_optypelist_for_implmode, FLAGS_op_select_implmode) != ge::SUCCESS,
  934. return ge::FAILED, "check optypelist_for_implmode and op_select_implmode failed!");
  935. std::map<string, string> options;
  936. // need to be changed when ge.ini plan is done
  937. SetEnvForSingleOp(options);
  938. auto ret = ge::GELib::Initialize(options);
  939. if (ret != ge::SUCCESS) {
  940. DOMI_LOGE("GE initialize failed!");
  941. return domi::FAILED;
  942. }
  943. ge::GeGenerator generator;
  944. ret = generator.Initialize(options, domi::GetContext());
  945. if (ret != SUCCESS) {
  946. DOMI_LOGE("GeGenerator initialize failed!");
  947. (void)ge::GELib::GetInstance()->Finalize();
  948. return domi::FAILED;
  949. }
  950. vector<ge::SingleOpBuildParam> build_params;
  951. if (ge::SingleOpParser::ParseSingleOpList(json_file_path, build_params) != ge::SUCCESS) {
  952. DOMI_LOGE("parse single op json file failed");
  953. (void)generator.Finalize();
  954. (void)ge::GELib::GetInstance()->Finalize();
  955. return domi::FAILED;
  956. }
  957. int index = 0;
  958. for (auto &param : build_params) {
  959. string output_path;
  960. if (!FLAGS_output.empty()) {
  961. output_path = FLAGS_output + "/";
  962. }
  963. output_path += param.file_name;
  964. ret = generator.BuildSingleOpModel(param.op_desc, param.inputs, param.outputs, output_path);
  965. if (ret != SUCCESS) {
  966. DOMI_LOGE("Compile op failed. ge ret = %u, op index = %d", ret, index);
  967. ret = domi::FAILED;
  968. break;
  969. }
  970. GELOGI("Compile op success. op index = %d, output = %s", index, output_path.c_str());
  971. index += 1;
  972. }
  973. (void)generator.Finalize();
  974. (void)ge::GELib::GetInstance()->Finalize();
  975. return ret;
  976. }
  977. domi::Status GenerateOmModel() {
  978. if (!CheckInputFormat()) {
  979. GELOGE(ge::FAILED, "Check input_format failed");
  980. return domi::FAILED;
  981. }
  982. Status ret = GFlagUtils::CheckFlags();
  983. GE_CHK_BOOL_EXEC(ret == domi::SUCCESS, return domi::FAILED,
  984. "Check flags failed! Please check whether some atc params that include semicolons[;] use double "
  985. "quotation marks (\") to enclose each argument such as out_nodes, input_shape, dynamic_image_size");
  986. #if !defined(__ANDROID__) && !defined(ANDROID)
  987. // Load custom operator Library
  988. LoadCustomOpLib(true);
  989. SaveCustomCaffeProtoPath();
  990. GE_CHK_BOOL_EXEC(ret == domi::SUCCESS, return domi::FAILED, "check custom aicpu run so failed!");
  991. #endif
  992. const int f_stream_num = 1;
  993. std::map<string, string> options;
  994. options.insert(std::pair<string, string>(string(ge::FRAMEWORK_TYPE), to_string(FLAGS_framework)));
  995. options.insert(std::pair<string, string>(string(ge::STREAM_NUM), to_string(f_stream_num)));
  996. options.insert(std::pair<string, string>(string(ge::CALIBRATION_CONF_FILE), FLAGS_cal_conf));
  997. options.insert(std::pair<string, string>(string(ge::ENCRYPT_MODE), to_string(FLAGS_encrypt_mode)));
  998. options.insert(std::pair<string, string>(string(ge::EK_FILE), FLAGS_encrypt_key));
  999. options.insert(std::pair<string, string>(string(ge::CERT_FILE), FLAGS_certificate));
  1000. options.insert(std::pair<string, string>(string(ge::HW_KEY_FILE), FLAGS_hardware_key));
  1001. options.insert(std::pair<string, string>(string(ge::PRIVATE_KEY_FILE), FLAGS_private_key));
  1002. options.insert(std::pair<string, string>(string(ge::OUTPUT_NODE_NAME), FLAGS_out_nodes));
  1003. options.insert(std::pair<string, string>(string(ge::INSERT_OP_FILE), FLAGS_insert_op_conf));
  1004. options.insert(std::pair<string, string>(string(ge::PRECISION_MODE), FLAGS_precision_mode));
  1005. options.insert(std::pair<string, string>(string(ge::RUN_FLAG), to_string(0)));
  1006. options.insert(std::pair<string, string>(string(ge::TRAIN_FLAG), to_string(0)));
  1007. if (!FLAGS_output_type.empty()) {
  1008. options.insert(std::pair<string, string>(string(ge::OUTPUT_DATATYPE), FLAGS_output_type));
  1009. }
  1010. options.insert(std::pair<string, string>(string(ge::OP_SELECT_IMPL_MODE), FLAGS_op_select_implmode));
  1011. options.insert(std::pair<string, string>(string(ge::OPTYPELIST_FOR_IMPLMODE), FLAGS_optypelist_for_implmode));
  1012. if (!FLAGS_input_fp16_nodes.empty()) {
  1013. GELOGI("FLAGS_input_fp16_nodes : %s .", FLAGS_input_fp16_nodes.c_str());
  1014. options.insert(std::pair<string, string>(ge::INPUT_FP16_NODES, FLAGS_input_fp16_nodes));
  1015. }
  1016. options.insert(std::pair<string, string>(string(ge::AUTO_TUNE_MODE), FLAGS_auto_tune_mode));
  1017. options.insert(
  1018. std::pair<string, string>(string(ge::OPTION_EXEC_DISABLE_REUSED_MEMORY), to_string(FLAGS_disable_reuse_memory)));
  1019. options.insert(std::pair<string, string>(string(ge::SOC_VERSION), FLAGS_soc_version));
  1020. options.insert(std::pair<string, string>(string(ge::CORE_TYPE), FLAGS_core_type));
  1021. options.insert(std::pair<string, string>(string(ge::AICORE_NUM), FLAGS_aicore_num));
  1022. options.insert(std::pair<string, string>(string(ge::BUFFER_OPTIMIZE), FLAGS_buffer_optimize));
  1023. options.insert(std::pair<string, string>(string(ge::ENABLE_SMALL_CHANNEL), FLAGS_enable_small_channel));
  1024. options.insert(std::pair<string, string>(string(ge::FUSION_SWITCH_FILE), FLAGS_fusion_switch_file));
  1025. options.insert(std::pair<string, string>(string(ge::ENABLE_COMPRESS_WEIGHT),
  1026. (FLAGS_enable_compress_weight == "true") ?
  1027. ge::kEnableCompressWeightTrue : ge::kEnableCompressWeightFalse));
  1028. options.insert(std::pair<string, string>(string(ge::ENABLE_SINGLE_STREAM), FLAGS_enable_single_stream));
  1029. options.insert(std::pair<string, string>(string(ge::DEBUG_DIR), FLAGS_debug_dir));
  1030. options.insert(std::pair<string, string>(string(ge::OP_COMPILER_CACHE_DIR), FLAGS_op_compiler_cache_dir));
  1031. options.insert(std::pair<string, string>(string(ge::OP_COMPILER_CACHE_MODE), FLAGS_op_compiler_cache_mode));
  1032. SetDynamicInputSizeOptions();
  1033. if (!FLAGS_save_original_model.empty()) {
  1034. options.insert(std::pair<string, string>(string(ge::SAVE_ORIGINAL_MODEL), FLAGS_save_original_model));
  1035. options.insert(std::pair<string, string>(string(ge::ORIGINAL_MODEL_FILE), FLAGS_output + "_original.om"));
  1036. }
  1037. options.insert(std::pair<string, string>(string(ge::OP_DEBUG_LEVEL), to_string(FLAGS_op_debug_level)));
  1038. options.insert(std::pair<string, string>(string(ge::MDL_BANK_PATH_FLAG), FLAGS_mdl_bank_path));
  1039. options.insert(std::pair<string, string>(string(ge::OP_BANK_PATH_FLAG), FLAGS_op_bank_path));
  1040. options.insert(std::pair<string, string>(string(ge::DISPLAY_MODEL_INFO), FLAGS_display_model_info));
  1041. // set enable scope fusion passes
  1042. SetEnableScopeFusionPasses(FLAGS_enable_scope_fusion_passes);
  1043. // print atc option map
  1044. ge::PrintOptionMap(options, "atc option");
  1045. // When the ATC module is transferred to a model, the suffix ".om" is automatically added to the model name
  1046. FLAGS_output = FLAGS_output + ".om";
  1047. ret = GenerateModel(options, FLAGS_output);
  1048. if (ret != domi::SUCCESS) {
  1049. return domi::FAILED;
  1050. }
  1051. if (FLAGS_display_model_info == "1") {
  1052. GELOGI("need to display model info.");
  1053. return ge::ConvertOm(FLAGS_output.c_str(), "", false);
  1054. }
  1055. return domi::SUCCESS;
  1056. }
  1057. domi::Status ConvertModelToJson() {
  1058. Status ret = GFlagUtils::CheckConverJsonParamFlags();
  1059. GE_CHK_BOOL_EXEC(ret == domi::SUCCESS, return domi::FAILED, "Check convert json params flags failed!");
  1060. ret = ConvertModelToJson(FLAGS_framework, FLAGS_om, FLAGS_json);
  1061. GE_IF_BOOL_EXEC(ret != domi::SUCCESS, return domi::FAILED);
  1062. return domi::SUCCESS;
  1063. }
  1064. domi::Status DisplayModelInfo() {
  1065. // No model path passed in
  1066. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(FLAGS_om == "",
  1067. ErrorManager::GetInstance().ATCReportErrMessage("E10004", {"parameter"}, {"om"});
  1068. return ge::FAILED,
  1069. "Input parameter[--om]'s value is empty!!");
  1070. // Check if the model path is valid
  1071. GE_CHK_BOOL_TRUE_EXEC_WITH_LOG(
  1072. FLAGS_om != "" && !ge::CheckInputPathValid(FLAGS_om, "--om"),
  1073. return ge::FAILED,
  1074. "model file path is invalid: %s.", FLAGS_om.c_str());
  1075. if (FLAGS_framework == -1) {
  1076. return ge::ConvertOm(FLAGS_om.c_str(), "", false);
  1077. }
  1078. return ge::FAILED;
  1079. }
  1080. bool CheckRet(domi::Status ret) {
  1081. if (ret != domi::SUCCESS) {
  1082. if (FLAGS_mode == ONLY_PRE_CHECK) {
  1083. GELOGW("ATC precheck failed.");
  1084. } else if (FLAGS_mode == GEN_OM_MODEL) {
  1085. GELOGW("ATC generate offline model failed.");
  1086. } else if (FLAGS_mode == MODEL_TO_JSON) {
  1087. GELOGW("ATC convert model to json file failed.");
  1088. } else if (FLAGS_mode == PBTXT_TO_JSON) {
  1089. GELOGW("ATC convert pbtxt to json file failed.");
  1090. } else {
  1091. return false;
  1092. }
  1093. return false;
  1094. }
  1095. if (FLAGS_mode == ONLY_PRE_CHECK) {
  1096. GELOGI("ATC precheck success.");
  1097. } else if (FLAGS_mode == GEN_OM_MODEL) {
  1098. GELOGI("ATC generate offline model success.");
  1099. } else if (FLAGS_mode == MODEL_TO_JSON) {
  1100. GELOGI("ATC convert model to json file success.");
  1101. } else if (FLAGS_mode == PBTXT_TO_JSON) {
  1102. GELOGI("ATC convert pbtxt to json file success.");
  1103. }
  1104. return true;
  1105. }
  1106. domi::Status ConvertPbtxtToJson() {
  1107. Status ret = GFlagUtils::CheckConverJsonParamFlags();
  1108. if (ret != domi::SUCCESS) {
  1109. GELOGE(ge::FAILED, "Check convert json params flags failed!");
  1110. return domi::FAILED;
  1111. }
  1112. ret = ge::ConvertPbtxtToJson(FLAGS_om.c_str(), FLAGS_json.c_str());
  1113. if (ret != domi::SUCCESS) {
  1114. GELOGE(ge::FAILED, "ConvertPbtxtToJson fail.");
  1115. return domi::FAILED;
  1116. }
  1117. return domi::SUCCESS;
  1118. }
  1119. int init(int argc, char* argv[]) {
  1120. GFlagUtils::InitGFlag(argc, argv);
  1121. // set log level
  1122. int ret = -1;
  1123. const std::set<string> log_level = {"null", "debug", "info", "warning", "error"};
  1124. if (log_level.count(FLAGS_log) == 0) {
  1125. std::cout << "E10010: invalid value for --log:" << FLAGS_log
  1126. <<", only support debug, info, warning, error, null"<< std::endl;
  1127. return ret;
  1128. }
  1129. ret = ge::CheckLogParamValidAndSetLogLevel(FLAGS_log);
  1130. if (ret != 0) {
  1131. return ret;
  1132. }
  1133. std::string path_base = ge::GELib::GetPath();
  1134. ret = ErrorManager::GetInstance().Init(path_base);
  1135. if (ret != 0) {
  1136. DOMI_LOGE("ErrorManager init fail !");
  1137. return ret;
  1138. }
  1139. ErrorManager::GetInstance().GenWorkStreamIdDefault();
  1140. return 0;
  1141. }
  1142. long GetMemInfo(const std::string &key) {
  1143. std::string file_path = "/proc/meminfo";
  1144. std::ifstream fs(file_path, std::ifstream::in);
  1145. if (!fs.is_open()) {
  1146. GELOGW("Can not open %s .", file_path.c_str());
  1147. return 0;
  1148. }
  1149. std::string line;
  1150. while (getline(fs, line)) { // line not with \n
  1151. if (line.find(key) != std::string::npos) {
  1152. GELOGI("Find mem [%s] info line [%s]", key.c_str(), line.c_str());
  1153. fs.close();
  1154. size_t pos = line.find(":");
  1155. if (pos == std::string::npos) {
  1156. return 0;
  1157. }
  1158. std::string current_mem_info_str = line.substr(pos + 1);
  1159. ge::StringUtils::Trim(current_mem_info_str);
  1160. GELOGI("Find mem [%s] info [%s].", key.c_str(), current_mem_info_str.c_str());
  1161. return stol(current_mem_info_str);
  1162. }
  1163. }
  1164. fs.close(); // close the file
  1165. return 0;
  1166. }
  1167. bool CheckMemInfo() {
  1168. if (FLAGS_auto_tune_mode.empty()) {
  1169. return true;
  1170. }
  1171. // only check current available mem when auto_tune_mode is set.
  1172. long current_mem_available = GetMemInfo("MemAvailable");
  1173. GELOGI("Get mem available [%lu kB].", current_mem_available);
  1174. std::cout << "Current available mem is " << current_mem_available << "kB." << std::endl;
  1175. if ((current_mem_available > 0) && (current_mem_available < kMinAvailableMem)) {
  1176. GELOGE(ge::PARAM_INVALID, "Current available mem [%lu kB] can not be smaller than [%lu kB] .",
  1177. current_mem_available, kMinAvailableMem);
  1178. ErrorManager::GetInstance().ATCReportErrMessage("E10044", {"value", "min_value"},
  1179. {to_string(current_mem_available), to_string(kMinAvailableMem)});
  1180. return false;
  1181. }
  1182. return true;
  1183. }
  1184. int main(int argc, char* argv[]) {
  1185. Status ret = domi::SUCCESS;
  1186. std::cout << "ATC start working now, please wait for a moment." << std::endl;
  1187. // Initialize
  1188. if (init(argc, argv) != 0) {
  1189. std::cout << "ATC run failed, Please check the detail log, Try \'atc --help\' for more information" << std::endl;
  1190. return -1;
  1191. }
  1192. do {
  1193. if (!CheckMemInfo()) {
  1194. GELOGE(ge::PARAM_INVALID, "Current available mem is too small");
  1195. ret = domi::FAILED;
  1196. break;
  1197. }
  1198. if (!FLAGS_singleop.empty()) {
  1199. ret = GenerateSingleOp(FLAGS_singleop);
  1200. break;
  1201. }
  1202. // default mode(mode:0), Open source model to model
  1203. if (GEN_OM_MODEL == FLAGS_mode || ONLY_PRE_CHECK == FLAGS_mode) {
  1204. GE_IF_BOOL_EXEC(GenerateOmModel() != domi::SUCCESS, ret = domi::FAILED; break);
  1205. } else if (MODEL_TO_JSON == FLAGS_mode) { // Mode 1, transfer model to JSON
  1206. GE_CHK_BOOL_EXEC(ConvertModelToJson() == domi::SUCCESS, ret = domi::FAILED;
  1207. break, "ATC ConvertJson execute failed!!");
  1208. } else if (FLAGS_mode == ge::RunMode::PBTXT_TO_JSON) {
  1209. GE_CHK_BOOL_EXEC(ConvertPbtxtToJson() == domi::SUCCESS, ret = domi::FAILED;
  1210. break, "ATC convert pbtxt to json execute failed!!");
  1211. } else if (FLAGS_mode == ge::RunMode::DISPLAY_OM_INFO) {
  1212. GE_CHK_BOOL_EXEC(DisplayModelInfo() == domi::SUCCESS, ret = domi::FAILED;
  1213. break, "ATC DisplayModelInfo failed!!");
  1214. } else {
  1215. ErrorManager::GetInstance().ATCReportErrMessage(
  1216. "E10001", {"parameter", "value", "reason"}, {"--mode", std::to_string(FLAGS_mode), kModeSupport});
  1217. GELOGE(ge::PARAM_INVALID, "Invalid value for --mode[%d], %s.", FLAGS_mode, kModeSupport);
  1218. ret = domi::FAILED;
  1219. break;
  1220. }
  1221. } while (0);
  1222. if (!CheckRet(ret)) {
  1223. std::cout << "ATC run failed, Please check the detail log, Try \'atc --help\' for more information" << std::endl;
  1224. int result = ErrorManager::GetInstance().OutputErrMessage(STDOUT_FILENO);
  1225. if (result != 0) {
  1226. DOMI_LOGE("ErrorManager outputErrMessage fail !");
  1227. }
  1228. GELOGI("Current mem available mem is [%lu kB]", GetMemInfo("MemAvailable"));
  1229. return ret;
  1230. } else {
  1231. std::cout << "ATC run success, welcome to the next use." << std::endl;
  1232. (void)ErrorManager::GetInstance().OutputMessage(STDOUT_FILENO);
  1233. return 0;
  1234. }
  1235. } /*lint +e530*/

图引擎模块(GE)是MindSpore的一个子模块,其代码由C++实现,位于前端模块ME和底层硬件之间,起到承接作用。图引擎模块以ME下发的图作为输入,然后进行一系列的深度图优化操作,最后输出一张可以在底层硬件上高效运行的图。GE针对昇腾AI处理器的硬件结构特点,做了特定的优化工作,以此来充分发挥出昇腾AI处理器的强大算力。在进行模型训练/推理时,GE会被自动调用而用户并不感知。GE主要由GE API和GE Core两部分组成,详细的架构图如下所示