• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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