1 /** 2 * Copyright 2019-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 #ifndef MINDSPORE_CCSRC_BACKEND_OPTIMIZER_COMMON_HELPER_H_ 17 #define MINDSPORE_CCSRC_BACKEND_OPTIMIZER_COMMON_HELPER_H_ 18 19 #include <vector> 20 #include <memory> 21 #include <utility> 22 #include <string> 23 #include <set> 24 #include "base/base.h" 25 #include "utils/hash_set.h" 26 #include "ir/func_graph.h" 27 #include "include/backend/kernel_graph.h" 28 #include "utils/ms_utils.h" 29 #include "include/backend/optimizer/pattern_engine.h" 30 #include "kernel/kernel_build_info.h" 31 #include "include/backend/visible.h" 32 33 namespace mindspore { 34 namespace opt { 35 constexpr size_t kTransOpInputTensorNum = 1; 36 constexpr size_t kCastInputTensorNum = 1; 37 constexpr size_t kDependInputTensorNum = 2; 38 constexpr size_t kReluInputTensorNum = 1; 39 constexpr size_t kReluGradInputTensorNum = 2; 40 constexpr size_t kAddInputTensorNum = 2; 41 constexpr size_t kTupleGetItemInputTensorNum = 2; 42 constexpr size_t kConvInputTensorNum = 2; 43 constexpr size_t kRealDivInputTensorNum = 2; 44 constexpr size_t kSqrtInputTensorNum = 1; 45 constexpr size_t kMatMulInputTensorNum = 2; 46 constexpr size_t kMulInputTensorNum = 2; 47 constexpr size_t kSubInputTensorNum = 2; 48 constexpr size_t kAssignSubInputTensorNum = 2; 49 constexpr size_t kDropoutInputTensorNum = 4; 50 constexpr size_t kAssignInputTensorNum = 2; 51 52 constexpr size_t kGradIndex = 3; 53 constexpr size_t kAddNInputNum = 2; 54 55 constexpr size_t kConvBn1OutputNum = 3; 56 constexpr size_t kBn2ReluOutputNum = 4; 57 58 constexpr size_t kBnInputTensorNum = 9; 59 constexpr size_t kSyncBnInputTensorNum = 5; 60 constexpr size_t kBnOutputNum = 5; 61 62 constexpr size_t kBN1OutputNum = 2; 63 constexpr size_t kBN2OutputNum = 3; 64 constexpr size_t kBN3OutputNum = 1; 65 66 constexpr size_t kBNGradInputTensorNum = 9; 67 constexpr size_t kSyncBNGradInputTensorNum = 5; 68 constexpr size_t kBNGradOutputNum = 3; 69 70 constexpr size_t kBNGrad1OutputNum = 3; 71 constexpr size_t kBNGrad2OutputNum = 5; 72 constexpr size_t kBNGrad3OutputNum = 1; 73 74 constexpr size_t kBNTrainingReduceOutputNum = 2; 75 constexpr size_t kBNTrainingUpdateOutputNum = 5; 76 constexpr size_t kBNTrainingUpdateV2OutputNum = 3; 77 constexpr size_t kBNTrainingUpdateV3OutputNum = 5; 78 constexpr size_t kBNTrainingUpdateGradOutputNum = 2; 79 80 constexpr size_t kSingleOutputNum = 1; 81 constexpr size_t kSumNodeInputTensorNum = 1; 82 constexpr size_t kSquareNodeInputTensorNum = 1; 83 constexpr size_t kSquareSumv2OutputNum = 2; 84 constexpr size_t kMinimumInputTensorNum = 2; 85 86 constexpr size_t kLambNextMVWithDecayInputNum = 7; 87 constexpr size_t kLambNextMVWithDecayConstantMulInputNum = 5; 88 constexpr size_t kLambNextMVWithDecayOutputNum = 4; 89 constexpr size_t kLambNextMVWithDecayV1OutputNum = 4; 90 constexpr size_t kLambNextRightOutputNum = 2; 91 constexpr size_t kLambUpdateWithLrV2InputNum = 8; 92 constexpr size_t kLambNextMVRuleInputNum = 14; 93 constexpr size_t kLambNextMVRuleOutputNum = 4; 94 constexpr size_t kBackendReshapeInputTensorNum = 1; 95 constexpr size_t kBackendTransposeInputTensorNum = 1; 96 constexpr size_t kAdamApplyOneWithDecayOutputNum = 3; 97 constexpr size_t kLayerNormBetaGammaBackpropInputTensorNum = 4; 98 constexpr size_t kLayerNormBetaGammaBackpropOutputNum = 2; 99 constexpr size_t kLayerNormBetaGammaBackpropV2InputTensorNum = 2; 100 constexpr size_t kLayerNormXBackpropOutputNum = 4; 101 constexpr size_t kLayerNormXBackpropV2OutputNum = 2; 102 constexpr size_t kLayerNormGradInputTensorNum = 5; 103 constexpr size_t kAdamApplyOneOutputNum = 3; 104 constexpr size_t kApplyMomentumInputTensorNum = 5; 105 constexpr size_t kBiasAddInputTensorNum = 2; 106 constexpr size_t kTopkInputTensorNum = 2; 107 constexpr size_t kLarsV2InputTensorNum = 4; 108 constexpr size_t kFusedMulApplyMomentumOutputNum = 2; 109 constexpr size_t kSplitInputTensorNum = 1; 110 constexpr size_t kGatherV2DynInputTensorNum = 3; 111 constexpr size_t kUnsortedSegmentSumDInputTensorNum = 2; 112 constexpr size_t kSoftmaxCrossEntropyWithLogitsOutputNum = 2; 113 constexpr size_t kSparseSoftmaxCrossEntropyWithLogitsInputTensorNum = 2; 114 constexpr size_t kOneHotOutputNum = 1; 115 constexpr size_t kOneHotInputTensorNum = 4; 116 117 enum FusedBatchNormInput { 118 kX = 1, 119 kVariance = 5, 120 }; 121 enum FusedBatchNormOutput { 122 kY = 0, 123 kRunningMean, 124 kRunningVariance, 125 kSaveMean, 126 kSaveInvVariance, 127 }; 128 enum ConvBn1Output { 129 kData = 0, 130 kVarPart, 131 kMean, 132 }; 133 134 // check whether node depends on either of nodes or not 135 BACKEND_EXPORT bool IsDepend(const FuncGraph &graph, const AnfNodePtr &node, const std::vector<AnfNodePtr> &nodes); 136 BACKEND_EXPORT bool IsDepend(const FuncGraph &graph, const AnfNodePtr &node, const std::vector<AnfNodePtr> &nodes, 137 mindspore::HashSet<AnfNodePtr> *visited_nodes); 138 139 BACKEND_EXPORT bool UnVisited(const BaseRef &n); 140 141 BACKEND_EXPORT bool Visited(const BaseRef &n); 142 143 // Create new cnode with dump flag and trace info maintained 144 BACKEND_EXPORT CNodePtr NewCNode(const std::vector<AnfNodePtr> &inputs, const FuncGraphPtr &fg, 145 const std::vector<AnfNodePtr> &orig_nodes); 146 147 BACKEND_EXPORT CNodePtr NewCNode(const CNodePtr &cnode, const KernelGraphPtr &fg, 148 const std::vector<AnfNodePtr> &orig_nodes); 149 150 // check if the input node is CNode, then check it's input_size, return CNodePtr if check success. 151 BACKEND_EXPORT CNodePtr CheckAnfNodeIfCNodeAndInputSize(const AnfNodePtr &node, size_t input_size); 152 153 BACKEND_EXPORT void CheckCNodeInputSize(const CNodePtr &cnode, size_t input_tensor_size); 154 155 bool HasSymmetricalKernelInfo(const AnfNodePtr &node_x, const AnfNodePtr &node_y); 156 157 const AnfNodePtr EliminateDependTransop(const FuncGraphPtr &func_graph, const AnfNodePtr &node); 158 159 void CreateOutputsOfConvBn1(const FuncGraphPtr &func_graph, const CNodePtr &conv_cnode, const CNodePtr &bn_cnode, 160 std::vector<AnfNodePtr> *conv_bn1_outputs); 161 162 void CreateOutputsOfFusedBn2(const FuncGraphPtr &graph, const std::vector<AnfNodePtr> &fused_bn1_outputs, 163 const CNodePtr &bn_node, std::vector<AnfNodePtr> *fused_bn2_outputs); 164 void CreateOutputsOfFusedBn3(const FuncGraphPtr &graph, const AnfNodePtr &data_input, 165 const std::vector<AnfNodePtr> &fused_bn1_outputs, 166 const std::vector<AnfNodePtr> &fused_bn2_outputs, const CNodePtr &bn_node, 167 std::vector<AnfNodePtr> *fused_bn3_outputs); 168 169 BACKEND_EXPORT void CreateMultipleOutputsOfAnfNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, 170 size_t output_num, std::vector<AnfNodePtr> *outputs); 171 172 tensor::TensorPtr CreateTensorWithValueTuple(const ValueTuplePtr &value_tuple_ptr, const TypePtr &type_ptr, 173 size_t data_length); 174 175 BACKEND_EXPORT tensor::TensorPtr CreateTupleTensor(const ValueTuplePtr &value_tuple); 176 177 BACKEND_EXPORT AnfNodePtr CreateTensorInput(const KernelGraphPtr &kernel_graph, const AnfNodePtr &input_node); 178 179 BACKEND_EXPORT AnfNodePtr CreateTensorMoveOp(const FuncGraphPtr &graph, const AnfNodePtr &node); 180 181 BACKEND_EXPORT std::vector<AnfNodePtr> InsertTensorMoveForGraphOutput(const FuncGraphPtr &graph, 182 const AnfNodePtr &node); 183 184 bool IsAllNopNode(const session::KernelGraph *const graph); 185 186 BACKEND_EXPORT void HideNopNode(session::KernelGraph *const graph); 187 188 BACKEND_EXPORT void RemoveNopNode(session::KernelGraph *const graph); 189 190 BACKEND_EXPORT CNodePtr CreatTupleGetItemNode(const FuncGraphPtr &func_graph, const AnfNodePtr &node, 191 size_t output_idx); 192 193 BACKEND_EXPORT CNodePtr CreateMakeTupleNode(const FuncGraphPtr &func_graph, 194 const std::vector<AnfNodePtr> &tuple_inputs); 195 196 BACKEND_EXPORT ValueNodePtr CreateShapeValueNode(const FuncGraphPtr &func_graph, const std::vector<int64_t> &shape, 197 bool to_tensor = false); 198 199 BACKEND_EXPORT CNodePtr AddCastNode(const FuncGraphPtr &func_graph, const TypeId dst_type, const CNodePtr &node, 200 const bool is_input, const size_t input_index = 0); 201 202 BACKEND_EXPORT AnfNodePtr CreateNodeBase(const FuncGraphPtr &graph, const std::vector<AnfNodePtr> &new_node_inputs, 203 const AnfNodePtr &node); 204 205 BACKEND_EXPORT bool IsUsedByOthers(const FuncGraphPtr &graph, const AnfNodePtr &node); 206 207 BACKEND_EXPORT std::shared_ptr<std::vector<std::pair<AnfNodePtr, int>>> GetRealNodeUsedList(const FuncGraphPtr &graph, 208 const AnfNodePtr &node); 209 210 size_t GetRealNodeNum(const FuncGraphPtr &graph, const AnfNodePtr &node); 211 212 BACKEND_EXPORT std::shared_ptr<std::vector<std::pair<AnfNodePtr, int>>> GetRealNodeUsedListByOutputIdx( 213 const FuncGraphPtr &graph, const AnfNodePtr &node, size_t output_index); 214 bool IsNotRealUsedByOthers(const FuncGraphPtr &graph, const AnfNodePtr &node); 215 216 bool AnfEqual(const BaseRef &a, const BaseRef &b); 217 218 bool CNodeTypeEqual(const BaseRef &a, const BaseRef &b); 219 220 AnfNodePtr SexpToNode(const BaseRef &sexp, const BaseRef &graph, PrimitiveVarMap *primitive_vars, 221 bool multigraph = false); 222 223 // Check var_node in two equivs is the same node 224 BACKEND_EXPORT bool IsSameNode(const EquivPtr &equiv1, const EquivPtr &equiv2, const VarPtr &var_node); 225 226 // Get anf_node from equiv by var_node 227 BACKEND_EXPORT AnfNodePtr GetAnfNodeByVar(const EquivPtr &equiv, const VarPtr &var_node); 228 229 // Get tuple getitem's index 230 BACKEND_EXPORT int64_t GetGetitemIndex(const AnfNodePtr &getitem); 231 232 // Compare tuple getitem's index, return bool[n1's index < n2's index] 233 BACKEND_EXPORT bool CompareTupleGetitem(const AnfNodePtr &n1, const AnfNodePtr &n2); 234 235 // Get attr which is bool from cnode 236 BACKEND_EXPORT bool GetBoolAttr(const AnfNodePtr &node, const std::string &attr_name); 237 238 // Check node's data type is in supported data type set 239 BACKEND_EXPORT bool CheckSupportDataType(const AnfNodePtr &node, const std::set<TypeId> &supported_data_type_set); 240 241 // Create a new value node of func graph, not kernel graph 242 ValueNodePtr MakeValueNode(const ValueNodePtr &value_node); 243 244 // Transfer depend or updatestate to the new node 245 BACKEND_EXPORT void TransferDependOrUpdateState(const CNodePtr &old_node, const FuncGraphPtr &graph, 246 const CNodePtr &new_node); 247 248 // Infer the shape and write to out abstract. 249 void CppInferShape(const PrimitivePtr &prim, const AbstractBasePtrList &args_spec_list, const CNodePtr &cnode); 250 251 // Infer the shape and type. 252 BACKEND_EXPORT AbstractBasePtr CppInferShapeAndType(const PrimitivePtr &prim, 253 const AbstractBasePtrList &args_spec_list); 254 255 // Generate kernel build info for created kernel 256 BACKEND_EXPORT kernel::KernelBuildInfoPtr GenerateKernelBuildInfo(const std::vector<AnfNodePtr> &node_list); 257 258 // Get used number of node's each output 259 BACKEND_EXPORT std::vector<int64_t> GetNodeOutputUsedNum(const session::KernelGraph &kernel_graph, 260 const AnfNodePtr &node); 261 262 // Get total used number of node's output 263 BACKEND_EXPORT int64_t GetNodeOutputTotalUsedNum(const session::KernelGraph &kernel_graph, const AnfNodePtr &node); 264 265 // Get custom operator attr input indexes 266 BACKEND_EXPORT void GetCustomOpAttrIndex(const PrimitivePtr &primitive, mindspore::HashSet<size_t> *indexes); 267 268 BACKEND_EXPORT size_t GetInputNodeIndex(const AnfNodePtr &input, const CNodePtr &user_node); 269 270 BACKEND_EXPORT int64_t SplitTupleInputs(const FuncGraphPtr &graph, const AnfNodePtr &tuple_input, 271 std::vector<AnfNodePtr> *plant_inputs); 272 273 BACKEND_EXPORT AnfNodePtr ConvertMakeTupleInputToPlantInputs(const FuncGraphPtr &graph, const CNodePtr &cnode_ptr); 274 275 BACKEND_EXPORT void InferOp(const CNodePtr &node, void *args = nullptr); 276 277 using LaunchHandler = abstract::AbstractBasePtr (*)(const PrimitivePtr &, 278 const std::vector<abstract::AbstractBase *> &); 279 BACKEND_EXPORT void set_launch_handler(const LaunchHandler &handler); 280 281 BACKEND_EXPORT abstract::AbstractBasePtr LaunchPy(const PrimitivePtr &primitive, 282 const std::vector<abstract::AbstractBase *> &args_abs_list); 283 BACKEND_EXPORT AbstractBasePtr InferAbstract(const PrimitivePtr &primitive, const std::vector<AnfNodePtr> &input_list); 284 285 BACKEND_EXPORT AnfNodePtr CreateValueNodeWithKernelInfo(const FuncGraphPtr &graph, const ValuePtr &value); 286 } // namespace opt 287 } // namespace mindspore 288 #endif // MINDSPORE_CCSRC_BACKEND_OPTIMIZER_COMMON_HELPER_H_ 289