1 /**
2 * Copyright 2020-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_GRAPH_KERNEL_HELPER_H_
17 #define MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_GRAPH_KERNEL_HELPER_H_
18
19 #include <map>
20 #include <memory>
21 #include <set>
22 #include <string>
23 #include <tuple>
24 #include <unordered_set>
25 #include <utility>
26 #include <vector>
27 #include "ir/anf.h"
28 #include "ir/func_graph.h"
29 #include "ir/primitive.h"
30 #include "backend/session/anf_runtime_algorithm.h"
31 #include "backend/session/kernel_graph.h"
32 #include "backend/kernel_compiler/akg/akg_kernel_json_generator.h"
33 #include <nlohmann/json.hpp>
34 #include "backend/optimizer/graph_kernel/model/lite_graph.h"
35
36 namespace mindspore {
37 namespace opt {
38 using kernel::DumpOption;
39
40 constexpr auto kIsFeatureMapOutput = "IsFeatureMapOutput";
41 constexpr auto kIsFeatureMapInputList = "IsFeatureMapInputList";
42 constexpr auto kGraphKernelModule = "mindspore._extends.graph_kernel";
43 constexpr auto kGraphKernelEstimateOps = "estimate_ops";
44 constexpr auto kGraphKernelGetNodeCalAmount = "estimate_calulation_amount";
45 constexpr auto kGraphKernelSplitFunc = "split_with_json";
46 constexpr auto kGetGraphKernelOpExpander = "get_op_expander";
47 constexpr auto kJsonKeyMultiGraph = "multi_graph";
48 constexpr auto kJsonKeyGraphDesc = "graph_desc";
49 constexpr auto kJsonKeyGraphMode = "graph_mode";
50 constexpr auto kAllTarget = "ALL";
51
52 constexpr auto kGraphKernelDumpPath = "graph_kernel_dump";
53 inline const PrimitivePtr kPrimUnPadAkg = std::make_shared<Primitive>("UnPadAkg");
54 inline const PrimitivePtr kPrimPadAkg = std::make_shared<Primitive>("PadAkg");
55 struct DataInfo {
56 std::string format{kOpFormat_DEFAULT};
57 ShapeVector shape{1};
58 TypePtr type{nullptr};
59 };
60
61 bool ConvertNonscalarTensorToParameter(const FuncGraphPtr &fg, AnfNodePtrList *inputs_ptr);
62 std::tuple<FuncGraphPtr, AnfNodePtrList, AnfNodePtrList> MixedNodesTransToGraph(const AnfNodePtrList &fuse_nodes,
63 AnfNodePtrList *src_outputs = nullptr);
64 void SetNewKernelInfo(const AnfNodePtr &new_node, const FuncGraphPtr &fg, const AnfNodePtrList &inputs,
65 const AnfNodePtrList &outputs);
66 kernel::KernelBuildInfoPtr BuildSelectKernelBuildInfo(const std::vector<std::string> &inputs_format,
67 const std::vector<TypeId> &inputs_type,
68 const std::vector<std::string> &output_formats,
69 const std::vector<TypeId> &output_types, const AnfNodePtr &node);
70 kernel::KernelBuildInfoPtr BuildSelectKernelBuildInfo(const std::vector<std::string> &inputs_format,
71 const std::vector<TypeId> &inputs_type,
72 const std::vector<std::string> &output_formats,
73 const std::vector<TypeId> &output_types);
74 AnfNodePtr CreateNewFuseCNode(const FuncGraphPtr &kernel_graph, const FuncGraphPtr &fg, const AnfNodePtrList &inputs,
75 const AnfNodePtrList &outputs);
76 void ReplaceNewFuseCNode(const FuncGraphPtr &kernel_graph, const AnfNodePtr &new_fuse_cnode,
77 const AnfNodePtrList &outputs);
78 std::tuple<AnfNodePtr, AnfNodePtrList> FuseNodesToSubGraph(const std::vector<AnfNodePtr> &fuse_nodes,
79 const FuncGraphPtr &kernel_graph,
80 const std::string &postfix = "");
81 bool AnfToJsonDesc(const AnfNodePtrList &nodes, const DumpOption &dump_option, nlohmann::json *op_desc);
82 bool AnfToJsonDesc(const AnfNodePtrList &nodes, const DumpOption &dump_option, nlohmann::json *op_desc,
83 std::map<std::string, AnfNodePtr> *address_node_map);
84 bool AnfToJsonDesc(const std::vector<AnfNodePtrList> &graphs, const DumpOption &dump_option, nlohmann::json *op_desc);
85 FuncGraphPtr JsonDescToAnf(const std::string &json_desc);
86 std::string ExtractGraphKernelName(const AnfNodePtrList &cnodes, const string &prefix = "", const string &postfix = "");
87 void ResetKernelInfo(const AnfNodePtr &node, KernelType kernel_type = KernelType::UNKNOWN_KERNEL_TYPE);
88
89 std::string GetFormat(const AnfNodePtr &node);
90 TypePtr GetType(const AnfNodePtr &node);
91 ShapeVector GetShape(const AnfNodePtr &node);
92 ShapeVector GetDeviceShape(const AnfNodePtr &node);
93 std::vector<int64_t> GetReduceAxis(const AnfNodePtr &node);
94
95 CNodePtr CreateCNode(const std::vector<AnfNodePtr> &inputs, const FuncGraphPtr &func_graph, const DataInfo &out_info,
96 bool use_fake_abstract = false);
97 void SetNodeAttrSafely(const std::string &key, const ValuePtr &value, const AnfNodePtr &node);
98 bool IsKeepBasicNode(const AnfNodePtr &node);
99 void OpListFilter(std::vector<PrimitivePtr> *ops, const std::vector<std::string> &enable_ops_only,
100 const std::vector<std::string> &enable_ops, const std::vector<std::string> &disable_ops);
101 template <typename T>
CreateScalarTensorValueNode(const DataInfo & info,T value,size_t data_length)102 ValueNodePtr CreateScalarTensorValueNode(const DataInfo &info, T value, size_t data_length) {
103 // Create tensor value.
104 if (info.shape.size() != 1 && info.shape[0] != 1) {
105 MS_LOG(EXCEPTION) << "Only support create scalar tensor value node!!!";
106 }
107
108 if (info.type == nullptr) {
109 MS_LOG(EXCEPTION) << "Data type is needed!!!";
110 }
111
112 tensor::TensorPtr tensor = std::make_shared<tensor::Tensor>(info.type->type_id(), info.shape);
113 MS_EXCEPTION_IF_NULL(tensor);
114 tensor::DeviceInfo device_info{info.format, info.type};
115 tensor->set_device_info(device_info);
116 auto data_ptr = tensor->data_c();
117 MS_EXCEPTION_IF_NULL(data_ptr);
118 auto ret_code = memcpy_s(data_ptr, static_cast<size_t>(tensor->data().nbytes()), &value, data_length);
119 if (ret_code != 0) {
120 MS_LOG(EXCEPTION) << "Failed to copy data into scalar tensor.";
121 }
122
123 // Create value node.
124 ValueNodePtr new_value_node = std::make_shared<ValueNode>(tensor);
125 new_value_node->set_abstract(tensor->ToAbstract());
126 auto kernel_info = std::make_shared<device::KernelInfo>();
127 new_value_node->set_kernel_info(kernel_info);
128 auto kernel_build_info_builder = std::make_shared<kernel::KernelBuildInfo::KernelBuildInfoBuilder>();
129 kernel_build_info_builder->SetOutputsFormat(std::vector<std::string>{info.format});
130 std::vector<TypeId> types = {info.type->type_id()};
131 kernel_build_info_builder->SetOutputsDeviceType(types);
132 AnfAlgo::SetSelectKernelBuildInfo(kernel_build_info_builder->Build(), new_value_node.get());
133
134 return new_value_node;
135 }
136
137 AbstractBasePtr GetOutputAbstract(const AnfNodePtr &node, size_t output_idx);
138
139 // functions to graphkernel model
140 graphkernel::LiteGraphPtr AnfGraph2LiteGraph(const FuncGraphPtr &func_graph);
141 FuncGraphPtr LiteGraph2AnfGraph(const graphkernel::LiteGraphPtr &lite_graph, AnfNodePtrList *outputs = nullptr);
142
143 // remove parameter which is not used
144 void EliminateRedundantParameters(const FuncGraphPtr &func_graph, AnfNodePtrList *inputs);
145
146 std::vector<PrimitivePtr> GetValidOps(
147 const std::vector<std::tuple<std::string, unsigned int, PrimitivePtr>> &ops_with_level, unsigned int level);
148
149 // return a func_graph's manager
150 FuncGraphManagerPtr GetFuncGraphManager(const FuncGraphPtr &func_graph);
151
152 void UpdateMng(const FuncGraphManagerPtr &mng, const FuncGraphPtr &func_graph);
153 } // namespace opt
154 } // namespace mindspore
155
156 #endif // MINDSPORE_CCSRC_BACKEND_OPTIMIZER_GRAPH_KERNEL_GRAPH_KERNEL_HELPER_H_
157