1 /**
2 * Copyright 2021-2023 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 #include "backend/common/optimizer/common_backend_optimization.h"
17 #include <memory>
18 #include <string>
19 #include "include/backend/optimizer/optimizer.h"
20 #include "backend/common/pass/convert_list_to_tuple.h"
21 #include "backend/common/pass/eliminate_func_data_type.h"
22 #include "backend/common/pass/convert_const_input_to_attr.h"
23 #include "backend/common/pass/add_input_structural_for_py_execute.h"
24 #include "backend/common/pass/custom_op_const_input_to_attr.h"
25 #include "backend/common/pass/custom_op_reg_info_to_attr.h"
26 #include "backend/common/pass/convert_tuple_output_to_maketuple.h"
27 #include "backend/common/pass/convert_const_input_to_tensor_input.h"
28 #include "backend/common/pass/convert_tuple_input_to_dynamic_input.h"
29 #include "backend/common/pass/convert_const_scalar_to_tensor.h"
30 #include "backend/common/pass/convert_attr_to_unify_mindir.h"
31 #include "backend/common/pass/optimize_updatestate.h"
32 #include "backend/common/pass/conv_transpose_to_conv_bp.h"
33 #include "backend/common/pass/add_dynamic_shape_attr.h"
34 #include "backend/common/pass/add_akg_kernel_attrs.h"
35 #include "backend/common/pass/inplace_assign_for_custom_op.h"
36 #include "backend/common/pass/flatten_concat_fission.h"
37 #include "backend/common/optimizer/dynamic_shape/convert_custom_op.h"
38 #include "backend/common/optimizer/dynamic_shape/link_custom_op.h"
39 #include "backend/common/pass/convert_unused_tuple_para_to_make_tuple.h"
40 #include "backend/common/pass/convert_dynamic_broadcast_to.h"
41 #include "backend/common/pass/broadcast_to_fusion.h"
42 #include "backend/common/pass/add_attr_to_node/add_attr_to_node.h"
43 #include "backend/common/pass/replace_addn_fusion.h"
44 #include "utils/ms_context.h"
45 #include "include/common/debug/anf_ir_dump.h"
46 #ifdef ENABLE_DUMP_IR
47 #include "include/backend/debug/data_dump/dump_json_parser.h"
48 #include "include/backend/debug/data_dump/dump_utils.h"
49 #include "include/backend/debug/debugger/proto_exporter.h"
50 #include "backend/common/session/session_basic.h"
51 #endif
52
53 namespace mindspore {
54 namespace opt {
GetBackendCommonOptimizationPassManagerPtr(const FuncGraphPtr & graph)55 PassManagerPtr GetBackendCommonOptimizationPassManagerPtr(const FuncGraphPtr &graph) {
56 auto common_pm = std::make_shared<PassManager>("common_pm");
57 common_pm->AddPass(std::make_shared<ConvertDynamicBroadcastTo>());
58 common_pm->AddPass(std::make_shared<ConvertConstInputToAttr>());
59 common_pm->AddPass(std::make_shared<CustomOpConstInputToAttr>());
60 // Disable const to tensor pass, ascend platform need to match the change in the future.
61 auto context = MsContext::GetInstance();
62 int execution_mode = context->get_param<int>(MS_CTX_EXECUTION_MODE);
63 if (execution_mode == kPynativeMode) {
64 common_pm->AddPass(std::make_shared<ConvertConstInputToTensorInput>());
65 }
66 common_pm->AddPass(std::make_shared<ConvertConstInputToTensorInputForPrint>());
67 common_pm->AddPass(std::make_shared<ConvertTupleOutputToMaketuple>());
68 common_pm->AddPass(std::make_shared<ConvertUnusedTupleParaToMakeTuple>());
69 common_pm->AddPass(std::make_shared<FlattenConcatFission>());
70 common_pm->AddPass(std::make_shared<AddInputStructuralForPyExecute>());
71 common_pm->AddPass(std::make_shared<BroadcastToFusion>());
72 common_pm->AddPass(std::make_shared<AddAttrToNode>());
73 common_pm->AddPass(std::make_shared<ReplaceAddNFusion>());
74 return common_pm;
75 }
76
BackendCommonOptimization(const std::shared_ptr<session::KernelGraph> & kernel_graph)77 void BackendCommonOptimization(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
78 PROF_START(backend_common_optimization);
79 MS_EXCEPTION_IF_NULL(kernel_graph);
80 MS_LOG(INFO) << "Status record: start common optimization. graph id: " << kernel_graph->graph_id();
81 #ifdef ENABLE_DUMP_IR
82 auto context_ptr = MsContext::GetInstance();
83 MS_EXCEPTION_IF_NULL(context_ptr);
84 if (context_ptr->CanDump(kIntroductory)) {
85 std::string file_name = "hwopt_common_before_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
86 DumpIR(file_name, kernel_graph);
87 }
88 #endif
89 auto optimizer = std::make_shared<GraphOptimizer>();
90 optimizer->AddPassManager(GetBackendCommonOptimizationPassManagerPtr(kernel_graph));
91 (void)optimizer->Optimize(kernel_graph);
92 kernel_graph->SetExecOrderByDefault();
93 PROF_END(backend_common_optimization);
94 #ifdef ENABLE_DUMP_IR
95 if (context_ptr->CanDump(kIntroductory)) {
96 std::string file_name = "hwopt_common_after_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
97 DumpIR(file_name, kernel_graph);
98 }
99 #endif
100 MS_LOG(INFO) << "Status record: end common optimization. graph id: " << kernel_graph->graph_id();
101 }
102
103 // Delete this optimizer when dynamic and static ReduceSum is unified.
OpBackendCommonOptimization(const std::shared_ptr<session::KernelGraph> & kernel_graph)104 void OpBackendCommonOptimization(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
105 MS_EXCEPTION_IF_NULL(kernel_graph);
106 MS_LOG(INFO) << "Status record: start op common optimization. graph id: " << kernel_graph->graph_id();
107 auto optimizer = std::make_shared<GraphOptimizer>();
108 auto common_pm = std::make_shared<PassManager>("op_common_pm");
109 common_pm->AddPass(std::make_shared<ConvertConstInputToTensorInputForPrint>());
110 common_pm->AddPass(std::make_shared<BroadcastToFusion>());
111 common_pm->AddPass(std::make_shared<AddAttrToNode>());
112 optimizer->AddPassManager(common_pm);
113 (void)optimizer->Optimize(kernel_graph);
114 kernel_graph->SetExecOrderByDefault();
115 MS_LOG(INFO) << "Status record: end op common optimization. graph id: " << kernel_graph->graph_id();
116 }
117
CommonFinalOptimization(const std::shared_ptr<session::KernelGraph> & kernel_graph)118 void CommonFinalOptimization(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
119 MS_EXCEPTION_IF_NULL(kernel_graph);
120 // Run optimizer passes.
121 auto optimizer = std::make_shared<GraphOptimizer>();
122 auto pm = std::make_shared<PassManager>("final_opt");
123 pm->AddPass(std::make_shared<OptimizeUpdateState>());
124 pm->AddPass(std::make_shared<AddAkgKernelAttrs>());
125 optimizer->AddPassManager(pm);
126 (void)optimizer->Optimize(kernel_graph);
127 kernel_graph->SetExecOrderByDefault();
128 #ifdef ENABLE_DUMP_IR
129 // Dump IR if save_graphs is set.
130 auto context = MsContext::GetInstance();
131 MS_EXCEPTION_IF_NULL(context);
132 if (context->CanDump(kIntroductory)) {
133 std::string filename = "hwopt_common_final_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
134 DumpIR(filename, kernel_graph);
135 }
136 #endif
137 }
138
GetCommonUnifyMindIRPassManager()139 PassManagerPtr GetCommonUnifyMindIRPassManager() {
140 auto pm = std::make_shared<PassManager>("common_unify_mindir_pm");
141 pm->AddPass(std::make_shared<ConvTransposeToConvBackpropInputPass>());
142 pm->AddPass(std::make_shared<CustomOpRegInfoToAttr>());
143 pm->AddPass(std::make_shared<InplaceAssignForCustomOp>());
144 pm->AddPass(std::make_shared<ConvertAttrToUnifyMindIR>());
145 return pm;
146 }
147
CommonUnifyMindIR(const std::shared_ptr<session::KernelGraph> & kernel_graph)148 void CommonUnifyMindIR(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
149 MS_EXCEPTION_IF_NULL(kernel_graph);
150 MS_LOG(INFO) << "start common unify mindir opt graph:" << kernel_graph->graph_id();
151 #ifdef ENABLE_DUMP_IR
152 auto context_ptr = MsContext::GetInstance();
153 MS_EXCEPTION_IF_NULL(context_ptr);
154 if (context_ptr->CanDump(kIntroductory)) {
155 std::string file_name =
156 "hwopt_common_unify_mindir_before_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
157 DumpIR(file_name, kernel_graph);
158 }
159 #endif
160 auto opt = std::make_shared<GraphOptimizer>();
161 opt->AddPassManager(GetCommonUnifyMindIRPassManager());
162 (void)opt->Optimize(kernel_graph);
163 kernel_graph->SetExecOrderByDefault();
164 #ifdef ENABLE_DUMP_IR
165 if (context_ptr->CanDump(kIntroductory)) {
166 std::string file_name = "hwopt_common_unify_mindir_after_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
167 DumpIR(file_name, kernel_graph);
168 }
169 #endif
170 }
171
AddDynamicShapeAttrPass(const std::shared_ptr<session::KernelGraph> & kernel_graph)172 void AddDynamicShapeAttrPass(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
173 auto opt = std::make_shared<GraphOptimizer>();
174 auto pm = std::make_shared<PassManager>("add_dynamic_shape_attr");
175 pm->AddPass(std::make_shared<AddDynamicShapeAttr>());
176 opt->AddPassManager(pm);
177 (void)opt->Optimize(kernel_graph);
178 }
179
GetEliminateIllegalDataTypePassManager()180 PassManagerPtr GetEliminateIllegalDataTypePassManager() {
181 auto pm = std::make_shared<PassManager>("common_eliminate_illegal_data_type_pm");
182 pm->AddPass(std::make_shared<ConvertListToTuple>("convert_list_to_tuple"));
183 pm->AddPass(std::make_shared<EliminateFuncDataType>());
184 return pm;
185 }
186
EliminateIllegalDataTypePass(const std::shared_ptr<session::KernelGraph> & kernel_graph)187 void EliminateIllegalDataTypePass(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
188 MS_EXCEPTION_IF_NULL(kernel_graph);
189 MS_LOG(INFO) << "Start eliminate illegal data type for kernel graph id:" << kernel_graph->graph_id();
190 #ifdef ENABLE_DUMP_IR
191 auto context_ptr = MsContext::GetInstance();
192 MS_EXCEPTION_IF_NULL(context_ptr);
193 if (context_ptr->CanDump(kIntroductory)) {
194 std::string file_name =
195 "hwopt_common_eliminate_illegal_data_type_before_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
196 DumpIR(file_name, kernel_graph);
197 }
198 #endif
199 auto opt = std::make_shared<GraphOptimizer>();
200 opt->AddPassManager(GetEliminateIllegalDataTypePassManager());
201 (void)opt->Optimize(kernel_graph);
202 kernel_graph->SetExecOrderByDefault();
203 #ifdef ENABLE_DUMP_IR
204 if (context_ptr->CanDump(kIntroductory)) {
205 std::string file_name =
206 "hwopt_common_eliminate_illegal_data_type_after_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
207 DumpIR(file_name, kernel_graph);
208 }
209 #endif
210 }
211
DynamicShapeConvertPass(const std::shared_ptr<session::KernelGraph> & kernel_graph)212 void DynamicShapeConvertPass(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
213 MS_EXCEPTION_IF_NULL(kernel_graph);
214 MS_LOG(INFO) << "Start dynamic shape convert for kernel graph id:" << kernel_graph->graph_id();
215 #ifdef ENABLE_DUMP_IR
216 auto context_ptr = MsContext::GetInstance();
217 MS_EXCEPTION_IF_NULL(context_ptr);
218 if (context_ptr->CanDump(kIntroductory)) {
219 std::string file_name =
220 "hwopt_d_before_dynamic_shape_convert_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
221 DumpIR(file_name, kernel_graph);
222 }
223 #endif
224 auto optimizer = std::make_shared<opt::GraphOptimizer>();
225 auto dynamic_shape_convert_pm = std::make_shared<opt::PassManager>("dynamic_shape_convert_pm");
226 dynamic_shape_convert_pm->AddPass(std::make_shared<opt::dynamic_shape::ConvertCustomOp>());
227 dynamic_shape_convert_pm->AddPass(std::make_shared<opt::dynamic_shape::LinkCustomOp>());
228 optimizer->AddPassManager(dynamic_shape_convert_pm);
229 (void)optimizer->Optimize(kernel_graph);
230 #ifdef ENABLE_DUMP_IR
231 if (context_ptr->CanDump(kIntroductory)) {
232 std::string file_name =
233 "hwopt_d_after_dynamic_shape_convert_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
234 DumpIR(file_name, kernel_graph);
235 }
236 #endif
237 }
238
OptimizationWithoutBackend(const std::shared_ptr<session::KernelGraph> & kernel_graph)239 void OptimizationWithoutBackend(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
240 MS_EXCEPTION_IF_NULL(kernel_graph);
241 MS_LOG(DEBUG) << "Start OptimizationWithoutBackend for kernel graph id:" << kernel_graph->graph_id();
242 #ifdef ENABLE_DUMP_IR
243 auto context_ptr = MsContext::GetInstance();
244 MS_EXCEPTION_IF_NULL(context_ptr);
245 if (context_ptr->CanDump(kIntroductory)) {
246 std::string file_name =
247 "hwopt_d_before_optimization_without_backend_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
248 DumpIR(file_name, kernel_graph);
249 }
250 #endif
251 EliminateIllegalDataTypePass(kernel_graph);
252 CommonUnifyMindIR(kernel_graph);
253 BackendCommonOptimization(kernel_graph);
254 MS_LOG(DEBUG) << "End OptimizationWithoutBackend for kernel graph id:" << kernel_graph->graph_id();
255 #ifdef ENABLE_DUMP_IR
256 if (context_ptr->CanDump(kIntroductory)) {
257 std::string file_name =
258 "hwopt_d_after_optimization_without_backend_graph_" + std::to_string(kernel_graph->graph_id()) + ".ir";
259 DumpIR(file_name, kernel_graph);
260 }
261 #endif
262 }
263
OptimizationForAnyTypeKernelGraph(const std::shared_ptr<session::KernelGraph> & kernel_graph)264 void OptimizationForAnyTypeKernelGraph(const std::shared_ptr<session::KernelGraph> &kernel_graph) {
265 MS_EXCEPTION_IF_NULL(kernel_graph);
266 auto common_pm = std::make_shared<opt::PassManager>("common_pm");
267 common_pm->AddPass(std::make_shared<ConvertListToTuple>("convert_list_to_tuple"));
268 common_pm->AddPass(std::make_shared<EliminateFuncDataType>());
269 common_pm->AddPass(std::make_shared<ConvertConstInputToAttr>());
270 common_pm->AddPass(std::make_shared<opt::ConvertConstInputToTensorInputForPrint>());
271 common_pm->AddPass(std::make_shared<opt::ConvertTupleOutputToMaketuple>());
272 auto optimizer = std::make_shared<opt::GraphOptimizer>();
273 optimizer->AddPassManager(common_pm);
274 optimizer->Optimize(kernel_graph);
275 }
276 } // namespace opt
277 } // namespace mindspore
278