diff --git a/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc b/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc index 01c08b3217..aaa526cf6e 100644 --- a/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc +++ b/mindspore/ccsrc/backend/optimizer/ascend/ascend_backend_optimization.cc @@ -65,7 +65,7 @@ #include "backend/optimizer/ascend/ir_fusion/confusion_mul_grad_fusion.h" #include "backend/optimizer/ascend/ir_fusion/softmax_grad_ext_fusion.h" #include "backend/optimizer/ascend/format_type/insert_trans_op.h" -#include "backend/optimizer/ascend/format_type/add_attr_for_3d_graph.h" +#include "backend/optimizer/ascend/format_type/add_reformat_op.h" #include "backend/optimizer/ascend/format_type/dynamic_rnn_grad_reformat.h" #include "backend/optimizer/ascend/format_type/insert_transpose_for_basiclstm_op.h" #include "backend/optimizer/ascend/format_type/insert_transpose_for_dyanmic_gru_v2.h" @@ -117,6 +117,7 @@ #include "backend/optimizer/ascend/enhancer/split_inputs_for_reduce_scatter.h" #include "backend/optimizer/ascend/enhancer/add_placeholder_for_dynamic_rnn.h" #include "backend/optimizer/ascend/enhancer/add_placeholder_for_dynamic_gru.h" +#include "backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.h" #include "utils/ms_context.h" #include "utils/config_manager.h" #include "debug/anf_ir_dump.h" @@ -210,7 +211,6 @@ void AscendDataLayout(const std::shared_ptr &kernel_graph) data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); - data_layout_pm->AddPass(std::make_shared()); auto ms_context = MsContext::GetInstance(); MS_EXCEPTION_IF_NULL(ms_context); if (ms_context->get_param(MS_CTX_EXECUTION_MODE) == kPynativeMode) { @@ -222,6 +222,8 @@ void AscendDataLayout(const std::shared_ptr &kernel_graph) data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); } + data_layout_pm->AddPass(std::make_shared()); + data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); data_layout_pm->AddPass(std::make_shared()); @@ -381,6 +383,7 @@ void AscendBackendOptimization(const std::shared_ptr &kern ConfigManager::GetInstance().iter_num() > 1) { other2_pm->AddPass(std::make_shared()); } + other2_pm->AddPass(std::make_shared()); other2_pm->AddPass(std::make_shared()); optimizer2->AddPassManager(other2_pm); (void)optimizer2->Optimize(kernel_graph); diff --git a/mindspore/ccsrc/backend/optimizer/ascend/ascend_helper.cc b/mindspore/ccsrc/backend/optimizer/ascend/ascend_helper.cc index dc90ea3f35..ab96c6af11 100644 --- a/mindspore/ccsrc/backend/optimizer/ascend/ascend_helper.cc +++ b/mindspore/ccsrc/backend/optimizer/ascend/ascend_helper.cc @@ -32,7 +32,6 @@ namespace mindspore { namespace opt { using KernelBuildInfoBuilder = kernel::KernelBuildInfo::KernelBuildInfoBuilder; namespace { -const std::set k3DFormatSet = {kOpFormat_NCDHW, kOpFormat_NDC1HWC0, kOpFormat_FRACTAL_Z_3D}; AnfNodePtr CreateReshapeNode(const FuncGraphPtr &func_graph, const AnfNodePtr &input_node, const KernelSelectPtr &kernel_select, const std::vector &dst_shape) { std::vector trans_inputs; @@ -66,19 +65,24 @@ void SetTransNodeAttr(const CNodePtr &trans_node) { std::string InitDefaultFormat(const AnfNodePtr &node) { MS_EXCEPTION_IF_NULL(node); - std::string default_format = kOpFormat_DEFAULT; if (node->isa() && AnfAlgo::HasNodeAttr("io_format", node->cast())) { auto attr = AnfAlgo::GetNodeAttr(node, "io_format"); if (attr == kOpFormat_NCDHW) { - default_format = kOpFormat_NCDHW; + return kOpFormat_NCDHW; } - } else if (node->isa() || node->isa()) { - auto out_format = AnfAlgo::GetOutputFormat(node, 0); - if (k3DFormatSet.find(out_format) != k3DFormatSet.end()) { - default_format = kOpFormat_NCDHW; + } else if (AnfAlgo::IsRealKernel(node)) { + auto formats = AnfAlgo::GetAllOutputFormats(node); + if (std::any_of(formats.begin(), formats.end(), + [](const std::string &format) { return k3DFormatSet.find(format) != k3DFormatSet.end(); })) { + return kOpFormat_NCDHW; + } + } else { + auto format = AnfAlgo::GetOutputFormat(node, 0); + if (k3DFormatSet.find(format) != k3DFormatSet.end()) { + return kOpFormat_NCDHW; } } - return default_format; + return kOpFormat_DEFAULT; } void ReFreshInferShape(const AnfNodePtr &trans_node, const AnfNodePtr &node) { diff --git a/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.cc b/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.cc new file mode 100644 index 0000000000..f07f1d314d --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.cc @@ -0,0 +1,49 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.h" +#include +#include "backend/session/anf_runtime_algorithm.h" +#include "utils/utils.h" +#include "base/core_ops.h" +#include "runtime/device/kernel_info.h" +#include "backend/optimizer/common/helper.h" + +namespace mindspore { +namespace opt { +const BaseRef AddIoFormatAttrFor3DGraph::DefinePattern() const { + std::shared_ptr V = std::make_shared(UnVisited); + std::shared_ptr Xs = std::make_shared(); + return VectorRef({V, Xs}); +} + +const AnfNodePtr AddIoFormatAttrFor3DGraph::Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, + const EquivPtr &) const { + MS_EXCEPTION_IF_NULL(node); + MS_EXCEPTION_IF_NULL(func_graph); + if (AnfAlgo::IsRealKernel(node)) { + AnfAlgo::SetNodeAttr(kAttrVisited, MakeValue(true), node); + auto formats = AnfAlgo::GetAllOutputFormats(node); + if (std::any_of(formats.begin(), formats.end(), + [](const std::string &format) { return k3DFormatSet.find(format) != k3DFormatSet.end(); })) { + AnfAlgo::SetNodeAttr("io_format", MakeValue(kOpFormat_NCDHW), node); + } + return node; + } + return nullptr; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.h b/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.h new file mode 100644 index 0000000000..2f847da7f3 --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/ascend/enhancer/add_attr_for_3d_graph.h @@ -0,0 +1,40 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_ADD_ATTR_FOR_3D_GRAPH_H +#define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_ADD_ATTR_FOR_3D_GRAPH_H +#include +#include +#include +#include +#include "ir/anf.h" +#include "backend/optimizer/common/optimizer.h" +#include "backend/optimizer/ascend/ascend_helper.h" + +namespace mindspore { +namespace opt { +class AddIoFormatAttrFor3DGraph : public PatternProcessPass { + public: + explicit AddIoFormatAttrFor3DGraph(bool multigraph = true) + : PatternProcessPass("add_attr_for_3d_graph", multigraph) {} + ~AddIoFormatAttrFor3DGraph() override = default; + const BaseRef DefinePattern() const override; + const AnfNodePtr Process(const FuncGraphPtr &, const AnfNodePtr &, const EquivPtr &) const override; +}; +} // namespace opt +} // namespace mindspore + +#endif // MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_ENHANCER_ADD_ATTR_FOR_3D_GRAPH_H diff --git a/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.cc b/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.cc deleted file mode 100644 index ec8366fe28..0000000000 --- a/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.cc +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2020 Huawei Technologies Co., Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "backend/optimizer/ascend/format_type/add_attr_for_3d_graph.h" -#include -#include "backend/session/anf_runtime_algorithm.h" -#include "utils/utils.h" -#include "base/core_ops.h" -#include "runtime/device/kernel_info.h" -#include "backend/optimizer/common/helper.h" - -namespace mindspore { -namespace opt { -namespace { -void AddAttrForAllCNode(const std::vector &node_list) { - for (auto node : node_list) { - if (node == nullptr || !node->isa() || !AnfAlgo::IsRealKernel(node)) { - continue; - } - AnfAlgo::SetNodeAttr("io_format", MakeValue(kOpFormat_NCDHW), node); - } -} - -bool NodeHasAttrIoFormat(const AnfNodePtr &node) { - MS_EXCEPTION_IF_NULL(node); - if (node->isa()) { - auto cnode = node->cast(); - MS_EXCEPTION_IF_NULL(cnode); - if (AnfAlgo::HasNodeAttr("io_format", cnode)) { - auto attr = AnfAlgo::GetNodeAttr(cnode, "io_format"); - return attr == kOpFormat_NCDHW; - } - } - return false; -} -} // namespace - -bool AddIoFormatAttrFor3DGraph::Run(const FuncGraphPtr &func_graph) { - MS_EXCEPTION_IF_NULL(func_graph); - std::vector node_list = TopoSort(func_graph->get_return()); - bool changed = false; - if (std::any_of(node_list.begin(), node_list.end(), - [](const AnfNodePtr &node) { return NodeHasAttrIoFormat(node); })) { - AddAttrForAllCNode(node_list); - changed = true; - } - return changed; -} -} // namespace opt -} // namespace mindspore diff --git a/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.cc b/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.cc new file mode 100644 index 0000000000..59c784f1c8 --- /dev/null +++ b/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.cc @@ -0,0 +1,136 @@ +/** + * Copyright 2020 Huawei Technologies Co., Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "backend/optimizer/ascend/format_type/add_reformat_op.h" +#include +#include "backend/session/anf_runtime_algorithm.h" +#include "utils/utils.h" +#include "base/core_ops.h" +#include "runtime/device/kernel_info.h" +#include "backend/optimizer/common/helper.h" + +namespace mindspore { +namespace opt { +using KernelWithIndex = std::pair; +namespace { +AnfNodePtr InsertReFormatOp(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const AnfNodePtr &in_node, + size_t idx) { + MS_EXCEPTION_IF_NULL(node); + MS_EXCEPTION_IF_NULL(in_node); + MS_EXCEPTION_IF_NULL(func_graph); + std::vector reformat_inputs; + auto node_kernel_build_info = AnfAlgo::GetSelectKernelBuildInfo(node); + MS_EXCEPTION_IF_NULL(node_kernel_build_info); + auto reformat_prim = std::make_shared(prim::kPrimReformat->name()); + reformat_inputs.push_back(NewValueNode(reformat_prim)); + reformat_inputs.push_back(in_node); + auto reformat = func_graph->NewCNode(reformat_inputs); + auto reformat_builder = std::make_shared(); + reformat_builder->SetInputsFormat({AnfAlgo::GetPrevNodeOutputFormat(node, idx)}); + reformat_builder->SetOutputsFormat({AnfAlgo::GetInputFormat(node, idx)}); + reformat_builder->SetInputsDeviceType({AnfAlgo::GetPrevNodeOutputDeviceDataType(node, idx)}); + reformat_builder->SetOutputsDeviceType({node_kernel_build_info->GetInputDeviceType(idx)}); + AnfAlgo::SetSelectKernelBuildInfo(reformat_builder->Build(), reformat.get()); + + reformat->set_abstract(in_node->abstract()); + AnfAlgo::SetNodeAttr("nop_op", MakeValue(true), reformat); + return reformat; +} + +bool NeedInsert(const CNodePtr &cnode, const size_t input_index) { + KernelWithIndex kernel_with_index = AnfAlgo::GetPrevNodeOutput(cnode, input_index); + auto real_input_node = kernel_with_index.first; + auto idx = kernel_with_index.second; + auto input_format = AnfAlgo::GetInputFormat(cnode, input_index); + auto prev_format = AnfAlgo::GetOutputFormat(real_input_node, idx); + bool flag_format = (input_format != prev_format); + if (!flag_format) { + return false; + } + + bool flag_shape = true; + auto input_origin_shape = AnfAlgo::GetOutputInferShape(real_input_node, idx); + if (prev_format == kOpFormat_DEFAULT || input_format == kOpFormat_DEFAULT) { + string checking_format = (prev_format == kOpFormat_DEFAULT) ? input_format : prev_format; + // when input shape size is 1D, default format and NC1HWC0 are compatible + if (input_origin_shape.size() == 1 && checking_format == kOpFormat_NC1HWC0) { + flag_shape = false; + } + if (kDefaultCompatibleFormat.find(checking_format) != kDefaultCompatibleFormat.end()) { + flag_shape = false; + } + } + if (input_origin_shape.size() == 0) { + flag_shape = false; + } + return flag_format && flag_shape; +} + +AnfNodePtr NeedInSertReformatOp(const FuncGraphPtr &func_graph, const AnfNodePtr &node) { + MS_EXCEPTION_IF_NULL(node); + MS_EXCEPTION_IF_NULL(func_graph); + if (!node->isa() || !AnfAlgo::IsRealKernel(node)) { + return nullptr; + } + auto cnode = node->cast(); + MS_EXCEPTION_IF_NULL(cnode); + auto in_nums = AnfAlgo::GetInputTensorNum(cnode); + bool need_insert = false; + std::vector new_inputs = {AnfAlgo::GetCNodePrimitiveNode(cnode)}; + for (size_t i = 0; i < in_nums; i++) { + auto input_node = AnfAlgo::GetInputNode(cnode, i); + if (NeedInsert(cnode, i)) { + need_insert = true; + auto re_format = InsertReFormatOp(func_graph, cnode, input_node, i); + new_inputs.push_back(re_format); + continue; + } + new_inputs.push_back(input_node); + } + if (need_insert) { + auto kernel_graph = func_graph->cast>(); + CNodePtr new_node = nullptr; + if (kernel_graph == nullptr) { + new_node = std::make_shared(*cnode); + } else { + new_node = kernel_graph->NewCNode(cnode); + } + MS_EXCEPTION_IF_NULL(new_node); + new_node->set_inputs(new_inputs); + AnfAlgo::CopyNodeAttrs(cnode, new_node); + return new_node; + } + return nullptr; +} +} // namespace + +bool AddReFormatOp::Run(const FuncGraphPtr &func_graph) { + MS_EXCEPTION_IF_NULL(func_graph); + std::vector node_list = TopoSort(func_graph->get_return()); + bool changed = false; + auto manager = func_graph->manager(); + MS_EXCEPTION_IF_NULL(manager); + for (auto &node : node_list) { + auto new_node = NeedInSertReformatOp(func_graph, node); + if (new_node != nullptr) { + manager->Replace(node, new_node); + changed = true; + } + } + return changed; +} +} // namespace opt +} // namespace mindspore diff --git a/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.h b/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.h similarity index 85% rename from mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.h rename to mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.h index 0f08b9fda7..38a474ce42 100644 --- a/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_attr_for_3d_graph.h +++ b/mindspore/ccsrc/backend/optimizer/ascend/format_type/add_reformat_op.h @@ -25,10 +25,10 @@ namespace mindspore { namespace opt { -class AddIoFormatAttrFor3DGraph : public Pass { +class AddReFormatOp : public Pass { public: - explicit AddIoFormatAttrFor3DGraph(size_t groups = 1) : Pass("add_attr_for_3d_graph"), groups_(groups) {} - ~AddIoFormatAttrFor3DGraph() override = default; + explicit AddReFormatOp(size_t groups = 1) : Pass("add_reformat_op"), groups_(groups) {} + ~AddReFormatOp() override = default; bool Run(const FuncGraphPtr &graph) override; private: diff --git a/mindspore/ccsrc/backend/optimizer/common/helper.cc b/mindspore/ccsrc/backend/optimizer/common/helper.cc index bd70bdde20..d5aa0e758a 100644 --- a/mindspore/ccsrc/backend/optimizer/common/helper.cc +++ b/mindspore/ccsrc/backend/optimizer/common/helper.cc @@ -281,7 +281,7 @@ bool IsNopNode(const AnfNodePtr &node) { static std::unordered_set nop_nodes = {prim::kPrimReshape->name(), kExpandDimsOpName, prim::kPrimSqueeze->name(), prim::kPrimFlatten->name(), - kFlattenGradOpName}; + kFlattenGradOpName, prim::kPrimReformat->name()}; if (node == nullptr || !node->isa()) { return false; } diff --git a/mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc b/mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc index b00a31528d..1639051cf1 100644 --- a/mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc +++ b/mindspore/ccsrc/runtime/device/ascend/ascend_device_address.cc @@ -93,9 +93,9 @@ namespace device { namespace ascend { const int FLOAT_LEN = sizeof(float); const int FLOAT16_LEN = 2; // sizeof(float16); -const std::set kOpNeedTransFormat = {kOpFormat_NHWC, kOpFormat_HWCN, kOpFormat_NC1HWC0, - kOpFormat_FRAC_Z, kOpFormat_C1HWNCoC0, kOpFormat_FRAC_NZ, - kOpFormat_NC1HWC0_C04, kOpFormat_FRACTAL_Z_C04}; +const std::set kOpNeedTransFormat = {kOpFormat_NHWC, kOpFormat_HWCN, kOpFormat_NC1HWC0, + kOpFormat_FRAC_Z, kOpFormat_C1HWNCoC0, kOpFormat_FRAC_NZ, + kOpFormat_NC1HWC0_C04, kOpFormat_FRACTAL_Z_C04, kOpFormat_NDC1HWC0}; void SyncMemory(void *dst, const void *src, uint64_t size, rtMemcpyKind_t kind) { auto ms_context = MsContext::GetInstance(); diff --git a/mindspore/ccsrc/utils/utils.h b/mindspore/ccsrc/utils/utils.h index 5dc1fb001b..5669722fc1 100644 --- a/mindspore/ccsrc/utils/utils.h +++ b/mindspore/ccsrc/utils/utils.h @@ -488,6 +488,8 @@ const std::set kFloatDataTypeSet = {kNumberTypeFloat16, kNumberTypeFloat const std::set kComputeDepend = {kUniqueOpName, kComputeAccidentalHitsOpName, kSubAndFilterOpName, kPadAndShiftOpName}; +const std::set k3DFormatSet = {kOpFormat_NCDHW, kOpFormat_NDC1HWC0, kOpFormat_FRACTAL_Z_3D}; + static inline void ChangeFileMode(const std::string &file_name, mode_t mode) { try { if (chmod(file_name.c_str(), mode) != 0) { diff --git a/mindspore/core/base/core_ops.h b/mindspore/core/base/core_ops.h index f8fa2106e0..8ab89abffc 100644 --- a/mindspore/core/base/core_ops.h +++ b/mindspore/core/base/core_ops.h @@ -308,6 +308,7 @@ inline const PrimitivePtr kPrimErrorOnDynamicShapeInput = std::make_shared("Depend"); +inline const PrimitivePtr kPrimReformat = std::make_shared("Reformat"); inline const PrimitivePtr kPrimPartial = std::make_shared("Partial"); inline const PrimitivePtr kPrimIdentity = std::make_shared("identity"); inline const PrimitivePtr kPrimHookBackward = std::make_shared("HookBackward");