From 2de960a6373790a6ba1d20b7a1cf293822d4cbb5 Mon Sep 17 00:00:00 2001 From: hanhuifeng2020 Date: Mon, 7 Mar 2022 15:16:19 +0800 Subject: [PATCH] [DynamicShape]fix some problems of InferShapeForNopNode --- .../ccsrc/backend/common/optimizer/helper.cc | 2 ++ .../ccsrc/include/common/utils/anfalgo.h | 1 + mindspore/ccsrc/include/common/utils/utils.h | 1 + mindspore/ccsrc/kernel/kernel.cc | 20 +++++++----- mindspore/ccsrc/kernel/kernel.h | 2 +- mindspore/ccsrc/utils/anfalgo.cc | 19 +++++++++++ tests/st/ops/gpu/test_dynamic_ops.py | 32 +++++++++++++++++++ 7 files changed, 68 insertions(+), 9 deletions(-) diff --git a/mindspore/ccsrc/backend/common/optimizer/helper.cc b/mindspore/ccsrc/backend/common/optimizer/helper.cc index ace67246370..3aebfa478a5 100644 --- a/mindspore/ccsrc/backend/common/optimizer/helper.cc +++ b/mindspore/ccsrc/backend/common/optimizer/helper.cc @@ -337,6 +337,7 @@ void HideNopNode(session::KernelGraph *const graph) { MS_EXCEPTION_IF_NULL(cnode); if (NeedHideNode(outputs, cnode, is_dynamic_graph)) { common::AnfAlgo::SetNodeAttr(kAttrSkipNopOpAddr, MakeValue(true), cnode); + common::AnfAlgo::SetNodeAttr(kAttrSkipNopOpExecution, MakeValue(true), cnode); } else { new_nodes.push_back(cnode); } @@ -361,6 +362,7 @@ void RemoveNopNode(session::KernelGraph *const graph) { // ignore nop node itself if (NeedHideNode(outputs, cnode, is_dynamic_graph)) { common::AnfAlgo::SetNodeAttr(kAttrSkipNopOpAddr, MakeValue(true), cnode); + common::AnfAlgo::SetNodeAttr(kAttrSkipNopOpExecution, MakeValue(true), cnode); continue; } // Replace the input which is nop node diff --git a/mindspore/ccsrc/include/common/utils/anfalgo.h b/mindspore/ccsrc/include/common/utils/anfalgo.h index c1a73a7c3ba..49c52a2850c 100644 --- a/mindspore/ccsrc/include/common/utils/anfalgo.h +++ b/mindspore/ccsrc/include/common/utils/anfalgo.h @@ -145,6 +145,7 @@ class COMMON_EXPORT AnfAlgo { static bool IsInplaceNode(const AnfNodePtr &node, const string &type); static bool IsGetNext(const NotNull &node); static bool IsNeedSkipNopOpAddr(const AnfNodePtr &node); + static bool IsNeedSkipNopOpExecution(const AnfNodePtr &node); static FuncGraphPtr GetValueNodeFuncGraph(const AnfNodePtr &node); static bool IsSwitchCall(const CNodePtr &call_node); static bool IsScalarInput(const CNodePtr &cnode, size_t index); diff --git a/mindspore/ccsrc/include/common/utils/utils.h b/mindspore/ccsrc/include/common/utils/utils.h index b79cf80c5c5..9180332083d 100644 --- a/mindspore/ccsrc/include/common/utils/utils.h +++ b/mindspore/ccsrc/include/common/utils/utils.h @@ -520,6 +520,7 @@ constexpr auto kAttrInputSize = "input_size"; constexpr auto kAttrDstType = "dst_type"; constexpr auto kAttrDump = "dump"; constexpr auto kAttrSkipNopOpAddr = "skip_nop_op_addr"; +constexpr auto kAttrSkipNopOpExecution = "skip_nop_op_execution"; constexpr auto kAttrFixedInputFormat = "fixed_input_format"; constexpr auto kAttrFixedOutputFormat = "fixed_output_format"; constexpr auto kAttrFixedInputDeviceShape = "fixed_input_device_shape"; diff --git a/mindspore/ccsrc/kernel/kernel.cc b/mindspore/ccsrc/kernel/kernel.cc index 7e893f07859..012409f9801 100644 --- a/mindspore/ccsrc/kernel/kernel.cc +++ b/mindspore/ccsrc/kernel/kernel.cc @@ -63,7 +63,7 @@ void KernelMod::InferShape() { MS_EXCEPTION_IF_NULL(real_input); auto cnode_input = cnode->input(i + 1); MS_EXCEPTION_IF_NULL(cnode_input); - InferShapeForNopNode(&real_input); + InferShapeForNopNode(real_input); if (depend_list_.find(i) != depend_list_.end()) { auto pre_node_with_index = common::AnfAlgo::GetPrevNodeOutput(cnode, i); bool skip_nop_node = !context->get_param(MS_CTX_ENABLE_MINDRT); @@ -125,24 +125,28 @@ bool KernelMod::InferShapeForDefiniteOutputNode(const CNodePtr &cnode) { return true; } -void KernelMod::InferShapeForNopNode(AnfNodePtr *input_node) { - MS_EXCEPTION_IF_NULL(*input_node); - if (!common::AnfAlgo::IsNopNode(*input_node) || !common::AnfAlgo::IsDynamicShape(*input_node)) { +void KernelMod::InferShapeForNopNode(const AnfNodePtr &input_node) { + MS_EXCEPTION_IF_NULL(input_node); + if (!common::AnfAlgo::IsNopNode(input_node) || !common::AnfAlgo::IsDynamicShape(input_node)) { MS_LOG(INFO) << "Input node is not a nop node, no need infer."; return; } + if (!common::AnfAlgo::IsNeedSkipNopOpExecution(input_node)) { + MS_LOG(INFO) << "The Nop node need execution, no need the InferShapeForNopNode."; + return; + } MS_LOG(INFO) << "Infer shape for nop node."; std::stack nop_road; - nop_road.push(*input_node); + nop_road.push(input_node); + auto in_node = input_node; /*lint -e716*/ while (true) { - auto input_node_with_idx = common::AnfAlgo::GetPrevNodeOutput(*input_node, 0); - auto in_node = input_node_with_idx.first; + auto input_node_with_idx = common::AnfAlgo::GetPrevNodeOutput(in_node, 0); + in_node = input_node_with_idx.first; MS_EXCEPTION_IF_NULL(in_node); if (common::AnfAlgo::IsNopNode(in_node)) { nop_road.push(in_node); - *input_node = in_node; } else { break; } diff --git a/mindspore/ccsrc/kernel/kernel.h b/mindspore/ccsrc/kernel/kernel.h index f48af0bb6ba..db7573777f6 100644 --- a/mindspore/ccsrc/kernel/kernel.h +++ b/mindspore/ccsrc/kernel/kernel.h @@ -238,7 +238,7 @@ class KernelMod { std::set depend_list_; private: - void InferShapeForNopNode(AnfNodePtr *input_node); + void InferShapeForNopNode(const AnfNodePtr &input_node); bool InferShapeForDefiniteOutputNode(const CNodePtr &cnode); std::vector inputs_addr_; diff --git a/mindspore/ccsrc/utils/anfalgo.cc b/mindspore/ccsrc/utils/anfalgo.cc index 17434436c2e..c3d9dc34605 100644 --- a/mindspore/ccsrc/utils/anfalgo.cc +++ b/mindspore/ccsrc/utils/anfalgo.cc @@ -961,6 +961,25 @@ bool AnfAlgo::IsNeedSkipNopOpAddr(const AnfNodePtr &node) { return GetValue(skip_nop_op_addr_attr); } +bool AnfAlgo::IsNeedSkipNopOpExecution(const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + if (!node->isa()) { + return false; + } + + auto primitive = AnfAlgo::GetCNodePrimitive(node); + if (primitive == nullptr) { + return false; + } + + auto skip_nop_execution_attr = primitive->GetAttr(kAttrSkipNopOpExecution); + if (skip_nop_execution_attr == nullptr) { + return false; + } + + return GetValue(skip_nop_execution_attr); +} + FuncGraphPtr AnfAlgo::GetValueNodeFuncGraph(const AnfNodePtr &node) { MS_EXCEPTION_IF_NULL(node); auto value_node = node->cast(); diff --git a/tests/st/ops/gpu/test_dynamic_ops.py b/tests/st/ops/gpu/test_dynamic_ops.py index 116f858cd58..f3daa6f34e3 100644 --- a/tests/st/ops/gpu/test_dynamic_ops.py +++ b/tests/st/ops/gpu/test_dynamic_ops.py @@ -258,3 +258,35 @@ def test_dynamic_reduce_sum(): inputs = data_list[0] output_cmp = np.sum(inputs[0], inputs[1][0]) assert np.allclose(output.asnumpy(), output_cmp, rtol=1.0e-4, atol=1.0e-4) + + +class NopNet(nn.Cell): + def construct(self, x): + x1 = ops.squeeze(x) + y1 = ops.expand_dims(x1, 1) + return ops.sub(y1, x1) + + +@pytest.mark.level0 +@pytest.mark.platform_x86_gpu_training +@pytest.mark.env_onecard +def test_dynamic_nop(): + """ + Feature: Test Nop. + Description: The shape of inputs is dynamic. + Expectation: Assert that results are consistent with fixed shape. + """ + dtype = np.float32 + data_list = [] + for i in [2, 64]: + data = [] + data.append(np.random.rand(i, 1).astype(dtype)) + data_list.append(tuple(data)) + column_names = get_columns(len(data_list[0])) + dataset = ds.GeneratorDataset(data_list, column_names, shuffle=False) + dynamic_columns = {column_names[0]: [None, 1]} + dataset.set_dynamic_columns(columns=dynamic_columns) + net = NopNet() + output = dynamic_shape_sink_process(net, dataset) + output_cmp = fixed_shape_process(net, dataset) + assert compare(output, output_cmp)