From ee6905dc37e055ee8dbc010f10250875bc582a8a Mon Sep 17 00:00:00 2001 From: gxl1 Date: Thu, 5 Oct 2023 14:15:45 +0800 Subject: [PATCH] Update pipeline_ge.cc --- mindspore/ccsrc/pipeline/jit/pipeline_ge.cc | 51 +++++++++++++++------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/mindspore/ccsrc/pipeline/jit/pipeline_ge.cc b/mindspore/ccsrc/pipeline/jit/pipeline_ge.cc index 0c9dad73aa7..4c3f16161f2 100644 --- a/mindspore/ccsrc/pipeline/jit/pipeline_ge.cc +++ b/mindspore/ccsrc/pipeline/jit/pipeline_ge.cc @@ -58,9 +58,11 @@ void DoExecNonInputGraph(const std::string &phase) { MS_LOG(ERROR) << "Can not found GraphRunner"; return; } + //It provides a basic framework for performing non-input graph calculations, + //and the specific calculation logic is implemented in subsequent code { - // Release GIL before calling into (potentially long-running) C++ code + // Release GIL before calling into (potentially long-running) C++ code py::gil_scoped_release release; Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); if (ret != Status::SUCCESS) { @@ -73,6 +75,7 @@ void DoExecNonInputGraph(const std::string &phase) { void SetGeOption(const std::map &options) { ConfigManager::GetInstance().set_ge_initialize_options(options); } + //We can flexibly set GE's initialization parameters to meet different needs Status CreateSessionAndGraphRunner(bool is_training = true) { std::shared_ptr sess = DfGraphManager::GetInstance().GetGeSession(); @@ -98,6 +101,9 @@ Status CreateSessionAndGraphRunner(bool is_training = true) { DfGraphManager::GetInstance().SetGraphRunner(graph_runner); return Status::SUCCESS; } + //The role of this code is to create session and graph runner objects, + //and configure the corresponding options, + //which provides the infrastructure for the calculation process of the model bool InitExecDatasetGe(const std::string &queue_name, int64_t size, int64_t batch_size, const std::vector &types, const std::vector> &shapes, @@ -108,11 +114,15 @@ bool InitExecDatasetGe(const std::string &queue_name, int64_t size, int64_t batc }); ConfigManager::GetInstance().set_dataset_mode(DatasetMode::DS_SINK_MODE); + //Set the dataset mode to Data Drop Mode ConfigManager::GetInstance().set_iter_num(queue_name, size); + //Set the number of iterations ConfigManager::GetInstance().set_dataset_phase(phase); + //Set up the dataset stage DatasetGraphParam param(queue_name, size, batch_size, ge_types, shapes, input_indexes); ConfigManager::GetInstance().set_dataset_param(param); + //Set some specific configurations for the dataset if (transform::BuildDatasetGraph(param, phase) != transform::SUCCESS) { MS_LOG(ERROR) << "Build dateset graph failed."; @@ -169,6 +179,8 @@ void ConvertObjectToTensors(const py::dict &dict, TensorOrderMap *const tensors) (void)tensors->emplace(name, tensor); } } +//By processing key-value pairs in the Python dictionary one by one, +//they are converted into tensors and stored in TensorOrderMap for later use bool AddDFGraph(const std::map &info, const py::dict &init_params, const std::string &phase, const py::object &broadcast_params) { @@ -211,15 +223,15 @@ bool AddDFGraph(const std::map &info, const py::di } #ifdef ENABLE_DUMP_IR if (MsContext::GetInstance()->get_param(MS_CTX_SAVE_GRAPHS_FLAG)) { - converter.DrawComputeGraph(GetSaveGraphsPathName("ge_graph.dot")); // for debug - converter.DrawInitGraph(GetSaveGraphsPathName("init_graph.dot")); // for debug - converter.DrawSaveCheckpointGraph(GetSaveGraphsPathName("save_checkpoint_graph.dot")); // for debug + converter.DrawComputeGraph(GetSaveGraphsPathName("ge_graph.dot")); // for debug + converter.DrawInitGraph(GetSaveGraphsPathName("init_graph.dot")); // for debug + converter.DrawSaveCheckpointGraph(GetSaveGraphsPathName("save_checkpoint_graph.dot")); // for debug } #endif std::string init_graph = "init_subgraph." + net_id; std::string checkpoint_name = "save." + net_id; if (phase.find("train") != std::string::npos) { - (void)DfGraphManager::GetInstance().AddGraph(phase, converter.GetComputeGraph(), {{"ge.exec.variable_acc", "1"}}); + (void)DfGraphManager::GetInstance().AddGraph(phase, converter.GetComputeGraph(), {{"ge.exec.variable_acc", "1"}});//Add additional properties to the graph } else { (void)DfGraphManager::GetInstance().AddGraph(phase, converter.GetComputeGraph()); } @@ -246,6 +258,8 @@ FuncGraphPtr BuildDFGraph(const std::map &info, co DumpIR("anf_graph.ir", anf_graph, true); } #endif +//Computational graphs can be saved in the form of images +//and texts for subsequent visualization, analysis, and debugging if (!AddDFGraph(info, init_params, phase, broadcast_params)) { MS_LOG(ERROR) << "GenConvertor failed"; @@ -300,7 +314,7 @@ void RunGEInitGraph(const py::dict &init_params, const std::string &phase) { MS_LOG(EXCEPTION) << "Can not found GraphRunner."; } { - // Release GIL before calling into (potentially long-running) C++ code + // Release GIL before calling into (potentially long-running) C++ code py::gil_scoped_release release; Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); if (ret != Status::SUCCESS) { @@ -329,6 +343,9 @@ py::object ExtractGeneralCnodeRet(const AbstractBasePtr &cnode_data, const py::t MS_LOG(EXCEPTION) << "The number of elements in the outputs : " << data.size() << " less than the number of elements required. "; } + //This code is used to check whether the abstract tensor data output + //by the compute node is available and determine + //whether the amount of output data is consistent with the required quantity. BaseShapePtr shape = cnode_data->BuildShape(); if (!shape->isa()) { @@ -337,7 +354,7 @@ py::object ExtractGeneralCnodeRet(const AbstractBasePtr &cnode_data, const py::t auto shape_me = shape->cast()->shape(); auto shape_ge = py::cast(data[*count]).shape(); - if (shape_ge != shape_me) { // dynamic shape + if (shape_ge != shape_me) { // dynamic shape MS_LOG(WARNING) << "The shape of the " << *count << "th tensor returned: " << shape_ge << " is not the same as the shape of the tensor derived: " << shape_me; } @@ -350,6 +367,7 @@ py::object ExtractGeneralCnodeRet(const AbstractBasePtr &cnode_data, const py::t << "only be a tensor or a tuple of tensor, but got " << cnode_data->BuildValue()->ToString() << "."; } + //Used to check whether the data type of the compute node output is an abstract tuple auto data_tp = cnode_data->cast(); auto elements = data_tp->elements(); size_t size = data_tp->size(); @@ -380,6 +398,7 @@ py::object StructureOutput(const AnfNodePtr &output_node, const py::tuple &data, MS_LOG(EXCEPTION) << "The final anf graph could only have constant, parameter, and operator, but got " << output_node->ToString(); } + //Used to check whether the final output of the graph is constant, parameter, or operator if (output_c->IsApply(prim::kPrimMakeTuple)) { auto input_list = output_c->inputs(); @@ -413,7 +432,7 @@ std::shared_ptr DoExecGraph(const FuncGraphPtr &graph, const std::ve } { - // Release GIL before calling into (potentially long-running) C++ code + // Release GIL before calling into (potentially long-running) C++ code py::gil_scoped_release release; MS_LOG(DEBUG) << "Run graph begin, inputs size is: " << inputs.size(); Status ret = graph_runner->RunGraph(run_options, ge_tensors, &ge_outputs); @@ -447,7 +466,7 @@ std::shared_ptr DoExecGraph(const FuncGraphPtr &graph, const std::ve void ProcessGeArg(const std::map &info, const py::tuple &args, const std::string &phase, std::vector *inputs) { - // check the arg and use the GraphExecutorPy args + // check the arg and use the GraphExecutorPy args std::size_t size = args.size(); if (info.count(phase) == 0) { @@ -459,8 +478,8 @@ void ProcessGeArg(const std::map &info, const py:: MS_LOG(EXCEPTION) << "The real arg num : size = " << size << ". graph_arg_size = " << arg_size; } - // process the first args of tensor - // only in dataset normal(non-sink) mode, fp_bp graph need input tensors + // process the first args of tensor + // only in dataset normal(non-sink) mode, fp_bp graph need input tensors if (ConfigManager::GetInstance().dataset_mode() == DS_NORMAL_MODE) { for (std::size_t i = 0; i < size; i++) { ValuePtr converted = nullptr; @@ -492,7 +511,7 @@ py::object ExecDFGraph(const std::map &info, const FuncGraphPtr anf_graph = info.at(phase)->func_graph; std::shared_ptr ret_val = std::make_shared(); - // We will not execute graph when output is constant or just input itself. + // We will not execute graph when output is constant or just input itself. if (IsGraphOutputValueNodeOrParameter(info.at(phase)->func_graph->output(), args, ret_val)) { ConfigManager::GetInstance().ResetConfig(); return *ret_val; @@ -517,6 +536,10 @@ void ExportDFGraph(const std::string &file_name, const std::string &phase) { MS_LOG(ERROR) << "Get graph form DfGraphManager failed!"; return; } + //It is mainly used to export deep learning framework diagrams to disk files + //for use by other modules or tools. + //You need to obtain the corresponding DfGraphWrapperPtr object + //through DfGraphManager and then export it through this object transform::DfGraphPtr ge_graph = wrap_ptr->graph_ptr_; if (ge_graph == nullptr) { @@ -529,5 +552,5 @@ void ExportDFGraph(const std::string &file_name, const std::string &phase) { } MS_LOG(INFO) << "Export air model finish."; } -} // namespace pipeline -} // namespace mindspore +} // namespace pipeline +} // namespace mindspore