fix cyclomatic complexity exceeds problem

This commit is contained in:
zhangzhaoju 2021-05-10 16:02:53 +08:00 committed by chujinjin
parent a7c4cb42fe
commit 5c8130821c
4 changed files with 67 additions and 48 deletions

View File

@ -855,7 +855,7 @@ FuncGraphPtr KPynativeCellImpl::BuildBPropCutFuncGraph(const PrimitivePtr &prim,
auto func_graph = std::make_shared<FuncGraph>();
std::vector<AnfNodePtr> outputs;
auto bprop_cut = std::make_shared<PrimitivePy>("bprop_cut", py::object());
auto bprop_cut = std::make_shared<PrimitivePy>("bprop_cut");
bprop_cut->CopyHookFunction(prim);
auto cell_id = GetValue<std::string>(prim->GetAttr("cell_id"));

View File

@ -89,46 +89,24 @@ class InlinerBase : public AnfVisitor {
: use_move_(use_move), criterions_(criterions) {}
~InlinerBase() override = default;
AnfNodePtr operator()(const OptimizerPtr &, const AnfNodePtr &node) override {
if (!node->isa<CNode>()) {
return nullptr;
}
auto &inputs = node->cast<CNodePtr>()->inputs();
if (inputs.size() < 1 || !IsValueNode<FuncGraph>(inputs[0])) {
auto cnode = dyn_cast<CNode>(node);
if (cnode == nullptr || cnode->size() < 1) {
return nullptr;
}
auto &inputs = cnode->inputs();
// G
auto fg = GetValueNode<FuncGraphPtr>(inputs[0]);
if (fg->has_flag(FUNC_GRAPH_FLAG_DEFER_INLINE) || fg->stage() != -1 || fg->stub()) {
if (!CheckFuncGraph(node, fg)) {
return nullptr;
}
// Do not inline GraphKernel to Cell.
if (fg->has_attr(FUNC_GRAPH_ATTR_GRAPH_KERNEL) && !node->func_graph()->has_attr(FUNC_GRAPH_ATTR_GRAPH_KERNEL)) {
// If the GraphKernel only contains a return node, we make it inlined.
if (fg->nodes().size() - fg->parameters().size() > 1) {
return nullptr;
}
}
Reset();
// 'criterions_': {criterion_group_1:{criterion1, criterion2, ...}, criterion_group_2:{...}, ...}
// All the criterions of 'criterion group' are true would set 'criterion group' as 'true'. As [AND].
// Anyone of 'criterion group' in 'criterions_' is 'true' would be matched. As [OR].
bool is_match = false;
for (auto &criterions : criterions_) { // Each 'criterion group' in criterions_.
is_match = true;
for (auto &criterion : criterions) { // Each criterion in 'criterion group'.
if (!criterion(this, fg, node)) {
is_match = false;
break;
}
}
if (is_match) {
break;
}
}
bool is_match = ApplyCriterions(node, fg);
if (!is_match) {
return nullptr;
}
@ -144,22 +122,9 @@ class InlinerBase : public AnfVisitor {
if (IsUniqueUse(nullptr, fg, nullptr)) {
// For the single used fg, including non-after and after not matched above,
// we move the whole fg nodes.
if (use_move_) {
auto mng = fg->manager();
MS_EXCEPTION_IF_NULL(mng);
ReplaceParams(mng, args, fg);
auto out_node = fg->output();
mng->MoveAllCNodeDropGraph(fg, node->func_graph(), inputs[0]->scope());
return out_node;
}
// The other branch calling the last after block.
if (fg->has_flag(FUNC_GRAPH_FLAG_AFTER_BLOCK)) {
// Check if parameters' changed.
auto param_simplified_caller = SimplifyAfterParameter(fg, node, args);
if (param_simplified_caller != nullptr) {
return param_simplified_caller;
}
auto ret_node = InlineForUniqueUse(node, fg, args, inputs);
if (ret_node != nullptr) {
return ret_node;
}
} else {
// We don't expand the middle multiple used after block, except the last one.
@ -178,6 +143,60 @@ class InlinerBase : public AnfVisitor {
return InlineClone(fg, node->func_graph(), args, inputs[0]->scope());
}
AnfNodePtr InlineForUniqueUse(const AnfNodePtr &node, const FuncGraphPtr &fg, const std::vector<AnfNodePtr> &args,
const std::vector<AnfNodePtr> &inputs) {
if (use_move_) {
auto mng = fg->manager();
MS_EXCEPTION_IF_NULL(mng);
ReplaceParams(mng, args, fg);
auto out_node = fg->output();
mng->MoveAllCNodeDropGraph(fg, node->func_graph(), inputs[0]->scope());
return out_node;
}
// The other branch calling the last after block.
if (fg->has_flag(FUNC_GRAPH_FLAG_AFTER_BLOCK)) {
// Check if parameters' changed.
auto param_simplified_caller = SimplifyAfterParameter(fg, node, args);
if (param_simplified_caller != nullptr) {
return param_simplified_caller;
}
}
return nullptr;
}
bool ApplyCriterions(const AnfNodePtr &node, const FuncGraphPtr &fg) {
bool is_match = false;
for (auto &criterions : criterions_) { // Each 'criterion group' in criterions_.
is_match = true;
for (auto &criterion : criterions) { // Each criterion in 'criterion group'.
if (!criterion(this, fg, node)) {
is_match = false;
break;
}
}
if (is_match) {
break;
}
}
return is_match;
}
bool CheckFuncGraph(const AnfNodePtr &node, const FuncGraphPtr &fg) const {
if (fg == nullptr || fg->has_flag(FUNC_GRAPH_FLAG_DEFER_INLINE) || fg->stage() != -1 || fg->stub()) {
return false;
}
// Do not inline GraphKernel to Cell.
if (fg->has_attr(FUNC_GRAPH_ATTR_GRAPH_KERNEL) && !node->func_graph()->has_attr(FUNC_GRAPH_ATTR_GRAPH_KERNEL)) {
// If the GraphKernel only contains a return node, we make it inlined.
if (fg->nodes().size() - fg->parameters().size() > 1) {
return false;
}
}
return true;
}
void ReplaceParams(const FuncGraphManagerPtr &mng, const std::vector<AnfNodePtr> &new_params,
const FuncGraphPtr &fg) {
auto params = fg->parameters();
@ -296,9 +315,9 @@ class InlinerBase : public AnfVisitor {
};
bool IsUniqueUse(InlinerBase *, const FuncGraphPtr &fg, const AnfNodePtr &) {
auto &cnodes = fg->func_graph_cnodes_index();
const auto &users = fg->func_graph_cnodes_index();
int64_t n_use = std::accumulate(
cnodes.begin(), cnodes.end(), 0,
users.begin(), users.end(), 0,
[](int64_t sum, const std::pair<const CNodeIndexPairPtr, int64_t> &item) { return sum + item.second; });
return n_use == 1;
}

View File

@ -189,7 +189,7 @@ FuncGraphPtr BpropGraphFinalOptPass(const ResourcePtr &res) {
opt::irpass::OptimizeIRPassLib irpass;
opt::OptPassConfig bg_final_opt_ = opt::OptPassConfig({
irpass.inline_,
irpass.item_tuple_or_list_eliminate_,
irpass.tuple_list_get_set_item_eliminator_,
irpass.depend_value_elim_,
irpass.reshape_eliminate_,
irpass.switch_simplify_,

View File

@ -2138,7 +2138,7 @@ void GradExecutor::DoGradForCustomBprop(const py::object &cell, const py::object
py::function bprop_func = py::getattr(cell, parse::CUSTOM_BPROP_NAME);
auto bprop_func_cellid = GetId(bprop_func);
bprop_cell_list_.emplace_back(bprop_func_cellid);
auto fake_prim = std::make_shared<PrimitivePy>(prim::kPrimHookBackward->name(), py::object());
auto fake_prim = std::make_shared<PrimitivePy>(prim::kPrimHookBackward->name());
fake_prim->set_hook(bprop_func);
const auto &cell_id = GetCellId(cell, args);
(void)fake_prim->AddAttr("cell_id", MakeValue(cell_id));