1 /** 2 * Copyright 2021 Huawei Technologies Co., Ltd 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_DEPEND_ELIMINATION_H_ 17 #define MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_DEPEND_ELIMINATION_H_ 18 19 #include <memory> 20 21 #include "include/backend/optimizer/pass.h" 22 #include "include/backend/optimizer/optimizer.h" 23 24 namespace mindspore::graphkernel { 25 /** 26 * @brief this pass optimizes two cases of unnecessary Depend in the graph 27 * Case 1: %1 = Depend(%0, %0), This depend statement is necessary in frontend, but not here. 28 * Case 2: %2 = Depend(%0, %1). Here %1 is a node with memory side-effect. However, the inputs of node %0 do not 29 * use any nodes that may be changed by %1. 30 */ 31 class DependElimination : public opt::Pass { 32 public: DependElimination()33 DependElimination() : Pass("depend_elimination") {} 34 ~DependElimination() override = default; 35 bool Run(const FuncGraphPtr &func_graph) override; 36 }; 37 38 /** 39 * @brief the atomic add kernel compilation on Ascend or by AKG_V2 is failed, this kernel will be inlined to main graph. 40 * Then there will be unnecessary nodes in the main graph. This pass is used to eliminate these unnecessary nodes. 41 * @example 42 * Before atomic clean pass, the graph is: 43 * main(p0) { 44 * %1 = ReduceSum(p0) 45 * } 46 * After atomic clean pass, the graph should look like this: 47 * main(p0) { 48 * %0 = call fg0() 49 * %1 = call fg1(%0, p0) 50 * %2 = Depend(%0, %1) 51 * %3 = op(%2) 52 * } 53 * fg0() { 54 * %0 = BroadcastTo(0) 55 * return %0 56 * } 57 * fg1(p0, p1) { 58 * %0 = ReduceSum(p1) 59 * %1 = Assign(p0, p1) 60 * return %0 61 * } 62 * If the compilation of graph kernel fg1 is failed, it will be inlined. Then there will be redundant nodes fg0, 63 * Assign and Depend in this graph. For performance, we need to eliminate this generated Depend node, (fg0 and Assign 64 * will have no users and be deleted), then the graph will be the same as the graph before atomic clean pass. 65 */ 66 class GeneratedDependElimination : public opt::PatternProcessPass { 67 public: 68 explicit GeneratedDependElimination(bool multigraph = true) 69 : PatternProcessPass("generated_depend_elimination", multigraph), 70 input1_{std::make_shared<Var>()}, 71 input2_{std::make_shared<Var>()}, 72 input3_{std::make_shared<Var>()} {}; 73 ~GeneratedDependElimination() override = default; 74 75 const BaseRef DefinePattern() const override; 76 const AnfNodePtr Process(const FuncGraphPtr &func_graph, const AnfNodePtr &node, const EquivPtr &) const override; 77 78 private: 79 VarPtr input1_; 80 VarPtr input2_; 81 VarPtr input3_; 82 }; 83 } // namespace mindspore::graphkernel 84 #endif // MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_DEPEND_ELIMINATION_H_ 85