| @@ -32,6 +32,8 @@ | |||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace kernel { | namespace kernel { | ||||
| constexpr char kAxis[] = "axis"; | |||||
| constexpr char kTypeInt32[] = "Int32"; | |||||
| const std::unordered_map<std::string, TypeId> type_id_maps = { | const std::unordered_map<std::string, TypeId> type_id_maps = { | ||||
| {"float", TypeId::kNumberTypeFloat32}, {"float16", TypeId::kNumberTypeFloat16}, | {"float", TypeId::kNumberTypeFloat32}, {"float16", TypeId::kNumberTypeFloat16}, | ||||
| {"float32", TypeId::kNumberTypeFloat32}, {"float64", TypeId::kNumberTypeFloat64}, | {"float32", TypeId::kNumberTypeFloat32}, {"float64", TypeId::kNumberTypeFloat64}, | ||||
| @@ -989,5 +991,39 @@ void MultiThreadCompute(const MultiThreadComputeFunc &func, MultiThreadComputePa | |||||
| threads[i].join(); | threads[i].join(); | ||||
| } | } | ||||
| } | } | ||||
| std::vector<int> GetReduceAttrAxis(const CNodePtr &cnode) { | |||||
| if (AnfAlgo::GetInputTensorNum(cnode) != AnfAlgo::GetOutputTensorNum(cnode) && | |||||
| AnfAlgo::GetInputTensorNum(cnode) != 1) { | |||||
| MS_LOG(EXCEPTION) << "the kind of reduce node [" << cnode->DebugString() | |||||
| << "] is not single input or single output "; | |||||
| } | |||||
| std::vector<int> axis; | |||||
| auto input_shape = AnfAlgo::GetPrevNodeOutputInferShape(cnode, 0); | |||||
| auto primitive = AnfAlgo::GetCNodePrimitive(cnode); | |||||
| MS_EXCEPTION_IF_NULL(primitive); | |||||
| auto axis_attr = primitive->GetAttr(kAxis); | |||||
| if (axis_attr == nullptr) { | |||||
| MS_LOG(ERROR) << "This node does't have axie attr."; | |||||
| return std::vector<int>(); | |||||
| } | |||||
| auto type = axis_attr->type(); | |||||
| MS_EXCEPTION_IF_NULL(type); | |||||
| std::vector<int> axis_list; | |||||
| if (type->ToString() == kTypeInt32) { | |||||
| axis_list.emplace_back(GetValue<int>(axis_attr)); | |||||
| } else { | |||||
| axis_list = GetValue<std::vector<int>>(axis_attr); | |||||
| } | |||||
| for (const auto &elem : axis_list) { | |||||
| if (elem < 0) { | |||||
| axis.emplace_back(input_shape.size() + elem); | |||||
| } else { | |||||
| axis.emplace_back(elem); | |||||
| } | |||||
| } | |||||
| AnfAlgo::SetNodeAttr(kAttrAxis, MakeValue(axis), cnode); | |||||
| return axis; | |||||
| } | |||||
| } // namespace kernel | } // namespace kernel | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -138,6 +138,7 @@ void ReduceMultiSparseGradient(const std::vector<std::shared_ptr<SparseGradient> | |||||
| size_t outer_dim); | size_t outer_dim); | ||||
| void TwoLevelReduceSparseGradient(const SparseGradient &origin_sparse_grad, SparseGradient *tmp_grad, | void TwoLevelReduceSparseGradient(const SparseGradient &origin_sparse_grad, SparseGradient *tmp_grad, | ||||
| SparseGradient *unique_grad, size_t first_dim, size_t outer_dim); | SparseGradient *unique_grad, size_t first_dim, size_t outer_dim); | ||||
| std::vector<int> GetReduceAttrAxis(const CNodePtr &cnode); | |||||
| } // namespace kernel | } // namespace kernel | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -20,11 +20,10 @@ | |||||
| #include "utils/utils.h" | #include "utils/utils.h" | ||||
| #include "session/anf_runtime_algorithm.h" | #include "session/anf_runtime_algorithm.h" | ||||
| #include "kernel/tbe/tbe_kernel_select/common_utils.h" | #include "kernel/tbe/tbe_kernel_select/common_utils.h" | ||||
| #include "kernel/common_utils.h" | |||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace kernel { | namespace kernel { | ||||
| constexpr char kAxis[] = "axis"; | |||||
| constexpr char kTypeInt32[] = "Int32"; | |||||
| constexpr size_t kInputIndex_0 = 0; | constexpr size_t kInputIndex_0 = 0; | ||||
| constexpr size_t kOutputIndex_0 = 0; | constexpr size_t kOutputIndex_0 = 0; | ||||
| constexpr size_t kChannelN = 0; | constexpr size_t kChannelN = 0; | ||||
| @@ -50,7 +49,7 @@ bool TbeKernelReduceSelecter::GetShapeInfo(SupportFormat *support_format) { | |||||
| // get keep dim attr | // get keep dim attr | ||||
| GetReduceAttrKeepDim(); | GetReduceAttrKeepDim(); | ||||
| // get axis attr | // get axis attr | ||||
| GetReduceAttrAxis(); | |||||
| axis_ = GetReduceAttrAxis(cnode_ptr_); | |||||
| AssignSupportFormat(kOpFormat_DEFAULT, support_format); | AssignSupportFormat(kOpFormat_DEFAULT, support_format); | ||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -121,31 +120,6 @@ bool TbeKernelReduceSelecter::IsFracZAndC1HWNCoC0Common(const std::string &forma | |||||
| return true; | return true; | ||||
| } | } | ||||
| void TbeKernelReduceSelecter::GetReduceAttrAxis() { | |||||
| auto primitive = AnfAlgo::GetCNodePrimitive(cnode_ptr_); | |||||
| MS_EXCEPTION_IF_NULL(primitive); | |||||
| auto axis = primitive->GetAttr(kAxis); | |||||
| if (axis == nullptr) { | |||||
| MS_LOG(INFO) << "This node does't have axie attr."; | |||||
| return; | |||||
| } | |||||
| auto type = axis->type(); | |||||
| MS_EXCEPTION_IF_NULL(type); | |||||
| std::vector<int> axis_list; | |||||
| if (type->ToString() == kTypeInt32) { | |||||
| axis_list.emplace_back(GetValue<int>(axis)); | |||||
| } else { | |||||
| axis_list = GetValue<std::vector<int>>(axis); | |||||
| } | |||||
| for (const auto &elem : axis_list) { | |||||
| if (elem < 0) { | |||||
| axis_.emplace_back(input_shape_.size() + elem); | |||||
| } else { | |||||
| axis_.emplace_back(IntToSize(elem)); | |||||
| } | |||||
| } | |||||
| } | |||||
| void TbeKernelReduceSelecter::GetReduceAttrKeepDim() { | void TbeKernelReduceSelecter::GetReduceAttrKeepDim() { | ||||
| if (!AnfAlgo::HasNodeAttr(kAttrKeepDims, cnode_ptr_)) { | if (!AnfAlgo::HasNodeAttr(kAttrKeepDims, cnode_ptr_)) { | ||||
| MS_LOG(INFO) << "This node does't have keep_attr."; | MS_LOG(INFO) << "This node does't have keep_attr."; | ||||
| @@ -36,7 +36,6 @@ class TbeKernelReduceSelecter { | |||||
| private: | private: | ||||
| bool IsFracZAndC1HWNCoC0Common(const std::string &format, SupportFormat *support_format) const; | bool IsFracZAndC1HWNCoC0Common(const std::string &format, SupportFormat *support_format) const; | ||||
| void GetReduceAttrAxis(); | |||||
| void GetReduceAttrKeepDim(); | void GetReduceAttrKeepDim(); | ||||
| void AssignSupportFormat(const std::string &support_format_str, SupportFormat *support_format) const; | void AssignSupportFormat(const std::string &support_format_str, SupportFormat *support_format) const; | ||||
| bool Is4DShape(const std::vector<size_t> &shape) const; | bool Is4DShape(const std::vector<size_t> &shape) const; | ||||
| @@ -44,7 +43,7 @@ class TbeKernelReduceSelecter { | |||||
| CNodePtr cnode_ptr_; | CNodePtr cnode_ptr_; | ||||
| std::vector<size_t> input_shape_{}; | std::vector<size_t> input_shape_{}; | ||||
| std::vector<size_t> output_shape_{}; | std::vector<size_t> output_shape_{}; | ||||
| std::vector<size_t> axis_{}; | |||||
| std::vector<int> axis_{}; | |||||
| bool keep_dims_ = false; | bool keep_dims_ = false; | ||||
| }; | }; | ||||
| } // namespace kernel | } // namespace kernel | ||||
| @@ -57,6 +57,7 @@ | |||||
| #include "pre_activate/ascend/ir_fusion/softmax_grad_ext_fusion.h" | #include "pre_activate/ascend/ir_fusion/softmax_grad_ext_fusion.h" | ||||
| #include "pre_activate/ascend/format_type/insert_trans_op.h" | #include "pre_activate/ascend/format_type/insert_trans_op.h" | ||||
| #include "pre_activate/ascend/format_type/rectify_do_mask_kernel_info.h" | #include "pre_activate/ascend/format_type/rectify_do_mask_kernel_info.h" | ||||
| #include "pre_activate/ascend/format_type/chang_axis_of_reduce_kernel.h" | |||||
| #include "pre_activate/pass/getitem_tuple.h" | #include "pre_activate/pass/getitem_tuple.h" | ||||
| #include "pre_activate/pass/optimize_dependence.h" | #include "pre_activate/pass/optimize_dependence.h" | ||||
| #include "pre_activate/pass/erase_visit_attr.h" | #include "pre_activate/pass/erase_visit_attr.h" | ||||
| @@ -157,6 +158,7 @@ void RunOpAscendDataLayout(const std::shared_ptr<session::KernelGraph> &kernel_g | |||||
| MS_EXCEPTION_IF_NULL(kernel_graph); | MS_EXCEPTION_IF_NULL(kernel_graph); | ||||
| auto optimizer = std::make_shared<GraphOptimizer>(); | auto optimizer = std::make_shared<GraphOptimizer>(); | ||||
| auto data_layout_pm = std::make_shared<PassManager>("pynative_transop_pm"); | auto data_layout_pm = std::make_shared<PassManager>("pynative_transop_pm"); | ||||
| data_layout_pm->AddPass(std::make_shared<ChangeAxisOfReduceKernel>()); | |||||
| data_layout_pm->AddPass(std::make_shared<RectifyDoMaskKernelInfo>()); | data_layout_pm->AddPass(std::make_shared<RectifyDoMaskKernelInfo>()); | ||||
| data_layout_pm->AddPass(std::make_shared<RunOpInsertTransData>()); | data_layout_pm->AddPass(std::make_shared<RunOpInsertTransData>()); | ||||
| data_layout_pm->AddPass(std::make_shared<GetitemTuple>()); | data_layout_pm->AddPass(std::make_shared<GetitemTuple>()); | ||||
| @@ -0,0 +1,103 @@ | |||||
| /** | |||||
| * Copyright 2019 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 "pre_activate/ascend/format_type/chang_axis_of_reduce_kernel.h" | |||||
| #include <string> | |||||
| #include <memory> | |||||
| #include <vector> | |||||
| #include <map> | |||||
| #include "utils/utils.h" | |||||
| #include "session/anf_runtime_algorithm.h" | |||||
| #include "common/utils.h" | |||||
| #include "kernel/common_utils.h" | |||||
| namespace mindspore { | |||||
| namespace opt { | |||||
| namespace { | |||||
| using ConvertFunction = std::function<void(const CNodePtr &)>; | |||||
| void ConvertReduceAttrFraczAnd6HD(const CNodePtr &cnode); | |||||
| const size_t kAxis_H = 2; | |||||
| const size_t kAxis_W = 3; | |||||
| const size_t kAxis_6HD_H = 1; | |||||
| const size_t kAxis_6HD_W = 2; | |||||
| const std::map<std::string, ConvertFunction> kReduceConvertMap = {{kOpFormat_FRAC_Z, ConvertReduceAttrFraczAnd6HD}, | |||||
| {kOpFormat_C1HWNCoC0, ConvertReduceAttrFraczAnd6HD}}; | |||||
| void SafeCheckFunction(const CNodePtr &cnode, const std::vector<int> &reduce_axis) { | |||||
| if (reduce_axis.empty()) { | |||||
| MS_LOG(EXCEPTION) << "The node " << cnode->DebugString() << "'s reduce axis got a empty vector"; | |||||
| } | |||||
| if (AnfAlgo::GetInputTensorNum(cnode) != AnfAlgo::GetOutputTensorNum(cnode) && | |||||
| AnfAlgo::GetInputTensorNum(cnode) != 1) { | |||||
| MS_LOG(EXCEPTION) << "the kind of reduce node [" << cnode->DebugString() | |||||
| << "] is not single input or single output "; | |||||
| } | |||||
| for (auto elem : reduce_axis) { | |||||
| if (elem > 4) { | |||||
| MS_LOG(INFO) << "reduce axis is larger than 4 dims reduce axis : [" << elem << "]"; | |||||
| } | |||||
| } | |||||
| } | |||||
| void ConvertReduceAttrFraczAnd6HD(const CNodePtr &cnode) { | |||||
| auto axis = kernel::GetReduceAttrAxis(cnode); | |||||
| std::vector<int> convert_axis; | |||||
| SafeCheckFunction(cnode, axis); | |||||
| auto format = AnfAlgo::GetInputFormat(cnode, 0); | |||||
| if (format != kOpFormat_FRAC_Z || format != kOpFormat_C1HWNCoC0) { | |||||
| MS_LOG(EXCEPTION) << "The node [" << cnode->DebugString() << "] format " << format << " is not 5hd"; | |||||
| } | |||||
| for (auto elem : axis) { | |||||
| switch (elem) { | |||||
| case kAxis_H: | |||||
| convert_axis.emplace_back(kAxis_6HD_H); | |||||
| break; | |||||
| case kAxis_W: | |||||
| convert_axis.emplace_back(kAxis_6HD_W); | |||||
| break; | |||||
| default: | |||||
| MS_LOG(INFO) << "reduce axis is axis : [" << elem << "]" | |||||
| << " but the format is not supported this reduce axis"; | |||||
| } | |||||
| } | |||||
| AnfAlgo::SetNodeAttr(kAttrAxis, MakeValue(convert_axis), cnode); | |||||
| } | |||||
| } // namespace | |||||
| const BaseRef ChangeAxisOfReduceKernel::DefinePattern() const { | |||||
| VarPtr X = std::make_shared<Var>(); | |||||
| VarPtr Xs = std::make_shared<SeqVar>(); | |||||
| return VectorRef({X, Xs}); | |||||
| } | |||||
| const AnfNodePtr ChangeAxisOfReduceKernel::Process(const FuncGraphPtr &, const AnfNodePtr &node, | |||||
| const EquivPtr &) const { | |||||
| if (node == nullptr || !node->isa<CNode>() || !AnfAlgo::IsRealKernel(node)) { | |||||
| return nullptr; | |||||
| } | |||||
| if (AnfAlgo::GetOpPattern(node) != kernel::kReducePattern) { | |||||
| return nullptr; | |||||
| } | |||||
| auto convert_map = kReduceConvertMap.find(AnfAlgo::GetInputFormat(node, 0)); | |||||
| if (convert_map == kReduceConvertMap.end()) { | |||||
| return nullptr; | |||||
| } | |||||
| convert_map->second(node->cast<CNodePtr>()); | |||||
| return nullptr; | |||||
| } | |||||
| } // namespace opt | |||||
| } // namespace mindspore | |||||
| @@ -0,0 +1,33 @@ | |||||
| /** | |||||
| * Copyright 2019 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_FORMAT_TYPE_CHANGE_AXIS_OF_REDUCE_KENRNEL_H_ | |||||
| #define MINDSPORE_CCSRC_PRE_ACTIVATE_ASCEND_FORMAT_TYPE_CHANGE_AXIS_OF_REDUCE_KENRNEL_H_ | |||||
| #include "pre_activate/common/optimizer.h" | |||||
| namespace mindspore { | |||||
| namespace opt { | |||||
| class ChangeAxisOfReduceKernel : public PatternProcessPass { | |||||
| public: | |||||
| explicit ChangeAxisOfReduceKernel(bool multigraph = true) | |||||
| : PatternProcessPass("change_axis_of_reduce_kernel", multigraph) {} | |||||
| ~ChangeAxisOfReduceKernel() 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_FORMAT_TYPE_CHANGE_AXIS_OF_REDUCE_KENRNEL_H_ | |||||