天天向上队——pipeline文件夹注释 #26

Open
WEI_4614 wants to merge 26 commits from WEI_4614/mindspore2022:comp into master
1 changed files with 111 additions and 1 deletions
Showing only changes of commit 18a2b69706 - Show all commits

View File

@ -30,6 +30,7 @@
namespace mindspore {
namespace abstract {
namespace {
// Record the run logs of the evaluator, including the evaluator name, scope name, and information about the abstract base pointer.
string EvalEntryLogging(const EvaluatorPtr &evaluator, const AbstractBasePtrList &arg_spec_list,
const AnfNodeConfigPtr &out_conf) {
MS_EXCEPTION_IF_NULL(evaluator);
@ -44,6 +45,9 @@ string EvalEntryLogging(const EvaluatorPtr &evaluator, const AbstractBasePtrList
return ss.str();
}
// Check whether the evaluator and output configuration are empty,
// get the node and determine the node type, and then output the appropriate error log based on the node type,
// including the evaluator name, node full name, or debugging information.
void EvalFailLogging(const EvaluatorPtr &evaluator, const AbstractBasePtrList &, const AnfNodeConfigPtr &out_conf) {
MS_EXCEPTION_IF_NULL(evaluator);
if (out_conf != nullptr) {
@ -59,6 +63,7 @@ void EvalFailLogging(const EvaluatorPtr &evaluator, const AbstractBasePtrList &,
}
} // namespace
// Check whether a given parameter is always evaluated, based on the results of previous analysis and the value of the current parameter.
bool CheckIfAlwaysEval(const AnfNodeConfigPtr &conf, const AbstractBasePtr &arg) {
auto new_sequence = dyn_cast<AbstractSequence>(arg);
if (new_sequence != nullptr && new_sequence->sequence_nodes() != nullptr && new_sequence->size() != 0) {
@ -78,6 +83,12 @@ bool CheckIfAlwaysEval(const AnfNodeConfigPtr &conf, const AbstractBasePtr &arg)
return false;
}
// Checks if the argument passed in is empty and throws an exception if it is.
// Enter the new func graph. Gets the current node and the current context, and creates the call configuration.
// Create a new evaluator and get a new context.
// Log new context and call configuration entry events.Increase and check function call depth and stack frame depth.
// If the depth of a function call exceeds the maximum depth limit, output an exception log with methods for adjusting the maximum depth of calls and suggestions on how to avoid stack overflows.
// Output a debug log, showing the evaluator type, name, and depth of incoming function calls and stack frame depth information.
void BaseFuncGraphEvaluator::EnterStackFrame(const AnalysisEnginePtr &engine, const StackFramePtr &current_stack_frame,
const StackFramePtr &new_stack_frame) {
MS_EXCEPTION_IF_NULL(current_stack_frame);
@ -111,6 +122,7 @@ void BaseFuncGraphEvaluator::EnterStackFrame(const AnalysisEnginePtr &engine, co
<< "), enter, function call depth: " << FunctionCallDepth() << " - " << StackFrameDepth();
}
// Leave the current function call stack frame and perform the associated operations and records.
void BaseFuncGraphEvaluator::LeaveStackFrame(const AnalysisEnginePtr &, const StackFramePtr &current_stack_frame) {
MS_EXCEPTION_IF_NULL(current_stack_frame);
// Leave current func graph.
@ -174,6 +186,7 @@ AbstractBasePtr BaseFuncGraphEvaluator::LaunchStackFrame(const AnalysisEnginePtr
return res_base;
}
// Recursively executes the function graph and returns the result
AbstractBasePtr BaseFuncGraphEvaluator::LaunchRecursiveEval(const AnalysisEnginePtr &engine, const FuncGraphPtr &fg,
const AnalysisContextPtr &context) {
MS_EXCEPTION_IF_NULL(fg);
@ -207,6 +220,12 @@ AbstractBasePtr BaseFuncGraphEvaluator::LaunchRecursiveEval(const AnalysisEngine
return res_base;
}
// Checks if the argument passed in is empty and throws an exception if it is.
// Enter the new func graph. Gets the current node and the current context, and creates the call configuration.
// Create a new evaluator and get a new context.
// Log new context and call configuration entry events.Increase and check function call depth and stack frame depth.
// If the depth of a function call exceeds the maximum depth limit, output an exception log with methods for adjusting the maximum depth of calls and suggestions on how to avoid stack overflows.
// Output a debug log, showing the evaluator type, name, and depth of incoming function calls and stack frame depth information.
EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const AbstractBasePtrList &args_abs_list,
const AnfNodeConfigPtr &out_conf) {
auto eval_result = evaluator_cache_mgr_->GetValue(args_abs_list);
@ -301,6 +320,7 @@ EvalResultPtr BaseFuncGraphEvaluator::Eval(AnalysisEnginePtr engine, const Abstr
return res;
}
// Each parameter in the input parameter list is extended and the extended parameter list is stored at the location pointed by broaded_args.
void BroadenArgs(const AbstractBasePtrList &args_spec_list, AbstractBasePtrList *broaded_args) {
MS_EXCEPTION_IF_NULL(broaded_args);
(void)std::transform(args_spec_list.begin(), args_spec_list.end(), std::back_inserter(*broaded_args),
@ -313,6 +333,7 @@ void BroadenArgs(const AbstractBasePtrList &args_spec_list, AbstractBasePtrList
});
}
// The input parameter list is extended or not extended depending on whether the function graph has a flag for ignoring values.
AbstractBasePtrList FuncGraphEvaluator::NormalizeArgs(const AbstractBasePtrList &args_spec_list) const {
MS_EXCEPTION_IF_NULL(func_graph_);
if (func_graph_->has_flag(FUNC_GRAPH_FLAG_IGNORE_VALUE)) {
@ -325,6 +346,11 @@ AbstractBasePtrList FuncGraphEvaluator::NormalizeArgs(const AbstractBasePtrList
return args_spec_list;
}
// Checks if the argument passed in is empty and throws an exception if it is.
// If the func graph has an ignore value flag, the parameter specification list (args_spec_list) is returned directly.
// If the function graph has an undetermined flag, set the ignore value flag to true, normalize the list of parameter specifications,
// and output a debug log. Finally, the normalized parameter specification list is returned.
// If the function graph has neither ignored value flags nor undefined flags, the list of parameter specifications is directly returned.
AbstractBasePtrList FuncGraphEvaluator::BroadenUndeterminedArgs(const AbstractBasePtrList &args_spec_list) {
MS_EXCEPTION_IF_NULL(func_graph_);
if (func_graph_->has_flag(FUNC_GRAPH_FLAG_IGNORE_VALUE)) {
@ -341,6 +367,8 @@ AbstractBasePtrList FuncGraphEvaluator::BroadenUndeterminedArgs(const AbstractBa
return args_spec_list;
}
// The corresponding function graph object is obtained from the input parameter list.
// If it does not exist in the cache, a new function graph object is generated and added to the cache.
FuncGraphPtr FuncGraphEvaluator::GetFuncGraph(AnalysisEnginePtr engine, const AbstractBasePtrList &args_spec_list) {
auto iter = func_graph_cache_.find(args_spec_list);
FuncGraphPtr res;
@ -369,6 +397,13 @@ FuncGraphPtr FuncGraphEvaluator::GetFuncGraph(AnalysisEnginePtr engine, const Ab
return res;
}
// First, check the cache (func_graph_cache_) to see if a function graph object corresponding to the parameter specification list already exists, and return it directly if it does.
// If no corresponding function graph object exists in the cache, a new function graph object is generated based on whether the bound_node() pointer of the current object is empty.
// If bound_node() is not empty, then meta_func_graph_ and bound_node()->debug_info() are used to generate a new function graph object;
// Otherwise, a new function graph object is also generated using meta_func_graph_ and bound_node()->debug_info().
// Create a new clone function graph object (cloned_func_graph) and add it to the cache (func_graph_cache_).
// Add the newly generated function graph object to the engine's function graph manager.
// Finally, the newly generated function graph object is returned.
FuncGraphPtr MetaFuncGraphEvaluator::GetFuncGraph(AnalysisEnginePtr engine, const AbstractBasePtrList &args_spec_list) {
auto iter = func_graph_cache_.find(args_spec_list);
if (iter != func_graph_cache_.end()) {
@ -396,6 +431,17 @@ FuncGraphPtr MetaFuncGraphEvaluator::GetFuncGraph(AnalysisEnginePtr engine, cons
return cloned_func_graph;
}
// The function takes three arguments:
// engine for the analysis engine object,
// args_conf_list for the function parameter configuration list to run,
// out_conf for the output node configuration object.
// converts each configuration object in args_conf_list into a corresponding evaluation result object
// and stores them in args_spec_list. It then normalizes args_spec_list and extends the undefined parameters.
// Next, the function attempts to retrieve the evaluation result object corresponding to args_spec_list from the cache.
// If it does not exist in the cache, the corresponding evaluation function is called to evaluate and the result is stored in the cache.
// If it exists in the cache, the evaluation result object in the cache is returned directly.
// The function also determines whether to update the information of the input sequence node based on the value of the environment variable MS_DEV_ENABLE_DDE before returning the result object.
// If this option is enabled, usage flags for the nodes of the old sequence and the new sequence are recursively synchronized.
EvalResultPtr Evaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &out_conf) {
AbstractBasePtrList args_spec_list;
@ -450,6 +496,10 @@ EvalResultPtr Evaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args
return eval_result;
}
// determine whether the current Evaluator is a Python Prim Evaluator based on the identifier passed in (identifier_), and if so set is_py_eval to true
// Convert the parameter configuration list (args_conf_list) into an abstract base pointer list (args_spec_list) and process each element in it.
// If the current Evaluator is a Python Prim Evaluator and the parameter configuration object is an AbstractRef type, convert it to an AbstractRefPtr type and extend its ref_key.
// Call EvalPrim function, pass the engine, abstract base pointer list (args_spec_list) and other parameters, and return the evaluation result (EvalResultPtr).
EvalResultPtr TrivialPrimEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &) {
AbstractBasePtrList args_spec_list;
@ -469,6 +519,9 @@ EvalResultPtr TrivialPrimEvaluator::Run(AnalysisEnginePtr engine, const ConfigPt
return EvalPrim(engine, args_spec_list);
}
// Checks if args_conf_list is empty, and throws an exception if it is empty and the identifiers are not "MakeTupleEvaluator", "MakeListEvaluator", or" RaiseEvaluator".
// Convert each configuration object in args_conf_list to the corresponding evaluation result object and store them in args_spec_list.
// The EvalPrim() function is called for in-place conversion evaluation and the result is stored in res. Finally, it returns res as the result. Note that because caching is not required, the cache manager is not used.
EvalResultPtr TransitionPrimEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &out_conf) {
if (args_conf_list.empty() && identifier_ != "MakeTupleEvaluator" && identifier_ != "MakeListEvaluator" &&
@ -486,6 +539,8 @@ EvalResultPtr TransitionPrimEvaluator::Run(AnalysisEnginePtr engine, const Confi
return res;
}
// Their main function is to run a Prim algorithm by configuring the list (args_conf_list) and identifier_ (identifier_) based on the parameters passed in,
// and return the evaluation result (EvalResultPtr).
EvalResultPtr SymbolicPrimEvaluator::Run(AnalysisEnginePtr, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &) {
return EvalPrim(args_conf_list);
@ -506,6 +561,12 @@ EvalResultPtr TrackedEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrLis
return res;
}
// engine represents the analysis engine object, args_conf_list represents the function parameter configuration list to run, and out_conf represents the output node configuration object
// Convert each configuration object in args_conf_list to the corresponding evaluation result object and store them in args_spec_list.
// Checks if the cache manager contains the evaluation result in evaluator_cache_mgr_ and returns it directly if it does.
// Otherwise, it merges some of the application arguments and the remaining arguments into a new parameter configuration list, partial_args_conf_list,
// and calls the evaluator evaluator_ to evaluate.
// The result of the evaluation is stored in the cache manager and the result is returned.
EvalResultPtr PartialAppEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &out_conf) {
AbstractBasePtrList args_spec_list;
@ -532,6 +593,7 @@ EvalResultPtr PartialAppEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtr
return res;
}
// Run a Prim algorithm and return an EvalResultPtr by configuring the args_conf_list and engine based on the parameters passed in.
EvalResultPtr JEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list, const AnfNodeConfigPtr &) {
AbstractBasePtrList args_spec_list;
(void)std::transform(args_conf_list.begin(), args_conf_list.end(), std::back_inserter(args_spec_list),
@ -577,6 +639,7 @@ EvalResultPtr JEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &arg
return res;
}
// Run the Taylor evaluator.
EvalResultPtr TaylorEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &) {
AbstractBasePtrList args_spec_list;
@ -598,6 +661,7 @@ EvalResultPtr TaylorEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList
return result;
}
// Configure a list (args_conf_list) and an engine based on the parameters passed in to run a Prim algorithm and return an EvalResultPtr. To be specific:
EvalResultPtr ShardEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &) {
AbstractBasePtrList args_spec_list;
@ -621,6 +685,12 @@ EvalResultPtr ShardEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList
}
namespace {
// Reduce the dimension of the tensor.
// axis represents the dimension index to be reduced, orig_abs represents the original tensor, and axis_size represents the size of each dimension.
// Checks if orig_abs is of type AbstractTensor, and throws an exception if it is not. It then takes the shape of the original tensor and calculates the length of the shape.
// Check that axis is in a valid range and throw an exception if it is not
// Check that axis is in a valid range and throw an exception if it is not
// Removes the dimensions specified in the original tensor and returns a new tensor object whose dimensions have been reduced by the specified dimensions.
AbstractBasePtr ReduceDim(int *axis, const AbstractBasePtr &orig_abs, int *axis_size) {
if (!orig_abs->isa<abstract::AbstractTensor>()) {
MS_LOG(EXCEPTION) << "ValueError: orig_abs should be AbstractTensor, but got a " << orig_abs->ToString() << ".";
@ -646,10 +716,13 @@ AbstractBasePtr ReduceDim(int *axis, const AbstractBasePtr &orig_abs, int *axis_
return abs_clone;
}
// Accept the physical view (physical_view_abs), the input axis (in_axes), and the axis size (axis_size) as parameters.
AbstractBasePtr GetLogicalViewAbs(const AbstractBasePtr &physical_view_abs, const ValuePtr &in_axes, int *axis_size) {
MS_EXCEPTION_IF_NULL(physical_view_abs);
MS_EXCEPTION_IF_NULL(in_axes);
auto physical_view_abs_sequence = dyn_cast<abstract::AbstractSequence>(physical_view_abs);
// Determines whether the physical view is of a sequence type, and if so,
// calls the GetLogicalViewAbs function recursively to combine the abstract base pointer list of the subviews into a new logical view abstract base pointer list.
if (physical_view_abs_sequence != nullptr) {
AbstractBasePtrList abs_list = physical_view_abs_sequence->elements();
AbstractBasePtrList logical_view_abs_list;
@ -670,7 +743,9 @@ AbstractBasePtr GetLogicalViewAbs(const AbstractBasePtr &physical_view_abs, cons
}
return std::make_shared<AbstractTuple>(logical_view_abs_list);
}
// If the physical view is not of a sequence type, it is processed according to the type of the input axis.
ValuePtr in_axis = in_axes;
// If the input axis is Int64Imm, the ReduceDim function is called to reduce the dimension of the physical view and the result is returned.
if (in_axis->isa<Int64Imm>()) {
int axis = dyn_cast<Int64Imm>(in_axis)->value();
auto logical_view_abs = ReduceDim(&axis, physical_view_abs, axis_size);
@ -684,6 +759,7 @@ AbstractBasePtr GetLogicalViewAbs(const AbstractBasePtr &physical_view_abs, cons
return physical_view_abs;
}
// Extend the dimensions of the tensor.
AbstractBasePtr ExtendDim(int *axis, const AbstractBasePtr &orig_abs, int axis_size) {
MS_EXCEPTION_IF_NULL(orig_abs);
AbstractBasePtr out_abs = nullptr;
@ -711,65 +787,91 @@ AbstractBasePtr ExtendDim(int *axis, const AbstractBasePtr &orig_abs, int axis_s
return out_abs;
}
// Process physical view
AbstractBasePtr GetPhysicalViewAbs(const AbstractBasePtr &logical_view_abs, const ValuePtr &out_axes, int axis_size) {
// Check whether the logical view abstraction is empty, if it is empty, raise the exception
MS_EXCEPTION_IF_NULL(logical_view_abs);
// Attempts to convert the abstraction of a logical view to an abstract sequence type
auto logical_view_abs_sequence = dyn_cast<abstract::AbstractSequence>(logical_view_abs);
// if the conversion is successful, the logical view is a sequence.
if (logical_view_abs_sequence != nullptr) {
// Gets the element list of a logical view sequence
AbstractBasePtrList logical_view_abs_list = logical_view_abs_sequence->elements();
AbstractBasePtrList physical_view_abs_list;
// Try to convert the value of the output axis to the value sequence type
auto out_axes_seq = dyn_cast<ValueSequeue>(out_axes);
// if the conversion is successful, the output axis is a sequence
if (out_axes_seq != nullptr) {
// Check whether the size of the output axis sequence is equal to the size of the logical view sequence. if not, throw an exception
if (logical_view_abs_list.size() != out_axes_seq->size()) {
MS_LOG(EXCEPTION) << "The size of vmap's 'out_axes' should be equal to the number of results of 'fn': "
<< logical_view_abs_list.size() << ", but got size: " << out_axes_seq->size() << ".";
}
}
// Defines an index variable that traverses the output axis sequence
int index = 0;
// For each element in the logical view sequence, convert according to the corresponding output axis value. And add the result to the physical view sequence
(void)std::transform(
logical_view_abs_list.begin(), logical_view_abs_list.end(), std::back_inserter(physical_view_abs_list),
[&axis_size, &index, &out_axes_seq, out_axes](const AbstractBasePtr &arg_spec) -> AbstractBasePtr {
// Defines a child output axis value that holds the output axis value corresponding to the current element
ValuePtr sub_out_axes = out_axes;
// if the output axis isa sequence, take the value corresponding to the current index from it and update the index
if (out_axes->isa<ValueSequeue>()) {
sub_out_axes = (*out_axes_seq)[index];
index++;
}
// If the current element is an abstract sequence type, this function is called recursively.
if (arg_spec->isa<AbstractSequence>()) {
return GetPhysicalViewAbs(arg_spec, sub_out_axes, axis_size);
}
// If the sub-output axis value is an integer type, then the ExtendDim function is called to extend the dimension of the current element based on the axis value and axis size.
if (sub_out_axes->isa<Int64Imm>()) {
int axis = dyn_cast<Int64Imm>(sub_out_axes)->value();
return ExtendDim(&axis, arg_spec, axis_size);
} else if (sub_out_axes->isa<None>()) {
// If the suboutput axis value is an empty type, return the current element without any conversion.
return arg_spec;
}
// If the suboutput axis value is neither an integer nor an empty type,
MS_LOG(EXCEPTION) << "The axis in vmap's 'out_axes' should be a None or a scalar of type Int64Imm, but got a "
<< sub_out_axes->ToString() << ".";
});
// If the logical view is an abstract list type, Returns an abstract list type
if (logical_view_abs->isa<AbstractList>()) {
// Otherwise an abstract tuple consisting of a sequence of physical views is returned.
return std::make_shared<AbstractList>(physical_view_abs_list);
}
return std::make_shared<AbstractTuple>(physical_view_abs_list);
}
// for the single output case, outputs: A, and out_axes: 1 or (1,).
// If the logical view is not a sequence but a single output, then the output axis should also be a single value
// Define a suboutput axis value to hold the value of the output axis
ValuePtr sub_out_axes = out_axes;
// Try to convert the value of the output axis to the value sequence type
ValueSequeuePtr out_axes_seq = dyn_cast<ValueSequeue>(out_axes);
// if the conversion is successful, the output axis is a sequence
if (out_axes_seq != nullptr) {
// Check whether the output axis sequence size is 1, if not, throw an exception
if (out_axes_seq->size() != 1) {
MS_LOG(EXCEPTION) << "The size of vmap's 'out_axes' should be equal to the result size: 1, but got size: "
<< out_axes_seq->size() << ".";
}
sub_out_axes = (*out_axes_seq)[0];
}
// Define an axis variable that holds the sub-output axis value
int axis = 0;
// Try to convert the sub-output axis value to an integer type
auto axis_int_ptr = dyn_cast<Int64Imm>(sub_out_axes);
// if the conversion succeeds, the integer value is assigned to the axis variable
if (axis_int_ptr != nullptr) {
axis = LongToInt(axis_int_ptr->value());
} else {
MS_LOG(EXCEPTION) << "The axis in vmap's 'out_axes' should be a None or a scalar of type Int64Imm, but got a "
<< sub_out_axes->ToString() << ".";
}
// Call ExtendDim function, extending the dimension of the logical view based on axis variable and axis size, and return the result
return ExtendDim(&axis, logical_view_abs, axis_size);
}
} // namespace
@ -829,15 +931,19 @@ EvalResultPtr VmapEvaluator::Run(AnalysisEnginePtr engine, const ConfigPtrList &
return res;
}
// VirtualEvaluator::Eval method to evaluate the output of VirtualEvaluator
EvalResultPtr VirtualEvaluator::Eval(AnalysisEnginePtr, const AbstractBasePtrList &args_spec_list,
const AnfNodeConfigPtr &out_conf) {
// Check whether the size of the parameter list is as expected, and throw an exception if it is not
if (args_spec_list.size() != args_spec_list_.size()) {
MS_LOG(EXCEPTION) << "Arguments mismatch, parameters no: " << args_spec_list_.size()
<< ", arguments no: " << args_spec_list.size();
}
// Gets the value of the environment variable MS_DEV_ENABLE_DDE. If it is not 0, the function to eliminate unused elements is enabled
static const auto enable_eliminate_unused_element = (common::GetEnv("MS_DEV_ENABLE_DDE") != "0");
// Check each parameter and argument match;
for (std::size_t i = 0; i < args_spec_list.size(); i++) {
// If the argument is null, an exception is thrown
MS_EXCEPTION_IF_NULL(args_spec_list[i]);
// For VirtualAbstractClosure, likely J's bprop, we just set its tuple arguments as used before really grad.
if (enable_eliminate_unused_element && args_spec_list[i]->isa<abstract::AbstractSequence>()) {
@ -845,14 +951,18 @@ EvalResultPtr VirtualEvaluator::Eval(AnalysisEnginePtr, const AbstractBasePtrLis
<< "]: " << args_spec_list[i]->ToString();
SetSequenceElementsUseFlagsRecursively(args_spec_list[i], true);
}
// Join the parameters with the expected ones, throwing an exception if they are incompatible
(void)args_spec_list[i]->Join(args_spec_list_[i]);
}
// Returns evaluation results, including output and attribute value mapping
return std::make_shared<EvalResult>(output_, std::make_shared<AttrValueMap>());
}
// Evaluator::SingleRun method for performing a single evaluation
EvalResultPtr Evaluator::SingleRun(AnalysisEnginePtr engine, const ConfigPtrList &args_conf_list,
const AnfNodeConfigPtr &out_conf) {
EvalResultPtr result;
try {
// Call the Run method, which implements different logic depending on the type of evaluator
result = this->Run(engine, args_conf_list, out_conf);
} catch (const std::exception &ex) {
MS_LOG(INFO) << "Eval " << ToString() << " throw exception.";