Merged
【feat】: no tiling sink IFA can not be sk fusion #3407
tang-haojieAdd on Jun 6
【feat】: no tiling sink IFA can not be sk fusion #3407
Merged
Merged fromtang-haojie/getiling_sk_verifyintocann/gedevelop
Total: 3 files changed+120-12
| @@ -412,7 +412,7 @@ bool DynamicShapePartitioner::IsNeedMarkDynamicTilingDepend(const NodePtr &node) | |||
| 412 | if (ge::OpDescUtils::GetInputConstData(op, static_cast<uint32_t>(i)) != nullptr) { | 412 | if (ge::OpDescUtils::GetInputConstData(op, static_cast<uint32_t>(i)) != nullptr) { |
| 413 | continue; | 413 | continue; |
| 414 | } | 414 | } |
| 415 | - GELOGD("Input[%zu] of node: %s is dyanmic tilingDependent, index: %zu", | 415 | + GELOGI("Input[%zu] of node: %s is dyanmic tilingDependent, index: %zu", |
| 416 | i, node->GetName().c_str(), index); | 416 | i, node->GetName().c_str(), index); |
| 417 | return true; | 417 | return true; |
| 418 | } | 418 | } |
| @@ -60,6 +60,21 @@ namespace { | |||
| 60 | (node->GetType() == ge::CONSTANTOP) || | 60 | (node->GetType() == ge::CONSTANTOP) || |
| 61 | (node->GetType() == ge::CONSTPLACEHOLDER)); | 61 | (node->GetType() == ge::CONSTPLACEHOLDER)); |
| 62 | } | 62 | } |
| 63 | + | ||
| 64 | + Status IsSupportTilingOnAicpu(const NodePtr &node, bool &is_support) { | ||
| 65 | + GE_ASSERT_NOTNULL(node); | ||
| 66 | + auto op_desc = node->GetOpDesc(); | ||
| 67 | + GE_ASSERT_NOTNULL(op_desc); | ||
| 68 | + gert::OpImplSpaceRegistryV2Array space_registry_array; | ||
| 69 | + GE_ASSERT_TRUE(static_cast<size_t>(op_desc->GetOppImplVersion()) < space_registry_array.size()); | ||
| 70 | + space_registry_array.at(static_cast<size_t>(op_desc->GetOppImplVersion())) = | ||
| 71 | + gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry(); | ||
| 72 | + gert::DataDependentInterpreter ddi(op_desc, space_registry_array); | ||
| 73 | + is_support = false; | ||
| 74 | + GE_ASSERT_SUCCESS(ddi.IsSupportTilingDependPlacement(static_cast<uint32_t>(gert::TilingPlacement::TILING_ON_AICPU), | ||
| 75 | + is_support)); | ||
| 76 | + return SUCCESS; | ||
| 77 | + } | ||
| 63 | } | 78 | } |
| 64 | 79 | ||
| 65 | Status SuperKernelPass::Run(ge::ComputeGraphPtr graph) { | 80 | Status SuperKernelPass::Run(ge::ComputeGraphPtr graph) { |
| @@ -105,11 +120,16 @@ Status SuperKernelPass::Run(ge::ComputeGraphPtr graph) { | |||
| 105 | int64_t local_memory_size = 0; | 120 | int64_t local_memory_size = 0; |
| 106 | (void)AttrUtils::GetInt(op_desc, "local_memory_size", local_memory_size); | 121 | (void)AttrUtils::GetInt(op_desc, "local_memory_size", local_memory_size); |
| 107 | const bool is_simt_op = local_memory_size > 0; | 122 | const bool is_simt_op = local_memory_size > 0; |
| 123 | + bool is_ir_support_tiling_on_aicpu = false; | ||
| 124 | + GE_ASSERT_SUCCESS(IsSupportTilingOnAicpu(node, is_ir_support_tiling_on_aicpu)); | ||
| 125 | + bool is_tiling_sink_op = false; | ||
| 126 | + (void)ge::AttrUtils::GetBool(op_desc,"_tiling_sink_op", is_tiling_sink_op); | ||
| 127 | + bool is_tiling_op_no_sink = is_ir_support_tiling_on_aicpu && !is_tiling_sink_op; | ||
| 108 | std::string super_kernel_options; | 128 | std::string super_kernel_options; |
| 109 | (void)AttrUtils::GetStr(op_desc, ATTR_NAME_SUPER_KERNEL_OPTIONS, super_kernel_options); | 129 | (void)AttrUtils::GetStr(op_desc, ATTR_NAME_SUPER_KERNEL_OPTIONS, super_kernel_options); |
| 110 | std::string check_val; | 130 | std::string check_val; |
| 111 | GE_ASSERT_SUCCESS(ParseSuperKernelOptions(super_scope_name, super_kernel_options, check_val)); | 131 | GE_ASSERT_SUCCESS(ParseSuperKernelOptions(super_scope_name, super_kernel_options, check_val)); |
| 112 | - const bool no_support_sk_fusion = ((support != 1) || (is_simt_op)) && !IsHcomOpSupportSk(op_desc); | 132 | + const bool no_support_sk_fusion = (is_tiling_op_no_sink || (support != 1) || (is_simt_op)) && !IsHcomOpSupportSk(op_desc); |
| 113 | // cannot delete _super_kernel_scope attr when strict-scope-check is not empty, | 133 | // cannot delete _super_kernel_scope attr when strict-scope-check is not empty, |
| 114 | // because strict-scope-check logic need this attr to verify | 134 | // because strict-scope-check logic need this attr to verify |
| 115 | const bool need_del_attr = no_support_sk_fusion && check_val.empty(); | 135 | const bool need_del_attr = no_support_sk_fusion && check_val.empty(); |
| @@ -996,16 +1016,7 @@ Status SuperKernelScope::LinkEventNode() { | |||
| 996 | NodePtr real_dst_node = rcv_event_info.dst_node; | 1016 | NodePtr real_dst_node = rcv_event_info.dst_node; |
| 997 | // special process | 1017 | // special process |
| 998 | bool is_support = false; | 1018 | bool is_support = false; |
| 999 | - GE_ASSERT_NOTNULL(real_dst_node); | 1019 | + GE_ASSERT_SUCCESS(IsSupportTilingOnAicpu(real_dst_node, is_support)); |
| 1000 | - auto op_desc = real_dst_node->GetOpDesc(); | ||
| 1001 | - GE_ASSERT_NOTNULL(op_desc); | ||
| 1002 | - gert::OpImplSpaceRegistryV2Array space_registry_array; | ||
| 1003 | - GE_ASSERT_TRUE(static_cast<size_t>(op_desc->GetOppImplVersion()) < space_registry_array.size()); | ||
| 1004 | - space_registry_array.at(static_cast<size_t>(op_desc->GetOppImplVersion())) = | ||
| 1005 | - gert::DefaultOpImplSpaceRegistryV2::GetInstance().GetSpaceRegistry(); | ||
| 1006 | - gert::DataDependentInterpreter ddi(op_desc, space_registry_array); | ||
| 1007 | - (void)ddi.IsSupportTilingDependPlacement(static_cast<uint32_t>(gert::TilingPlacement::TILING_ON_AICPU), | ||
| 1008 | - is_support); | ||
| 1009 | const bool is_tiling_stream = (rcv_event_info.rcv_stream_id != real_dst_node->GetOpDesc()->GetStreamId()) && is_support; | 1020 | const bool is_tiling_stream = (rcv_event_info.rcv_stream_id != real_dst_node->GetOpDesc()->GetStreamId()) && is_support; |
| 1010 | bool is_first_rcv_node = rcv_event_info.dst_node->GetName() == super_nodes_[0]->GetName(); | 1021 | bool is_first_rcv_node = rcv_event_info.dst_node->GetName() == super_nodes_[0]->GetName(); |
| 1011 | auto it = first_other_stm_sub_nodes_.find(rcv_event_info.dst_node->GetName()); | 1022 | auto it = first_other_stm_sub_nodes_.find(rcv_event_info.dst_node->GetName()); |
| @@ -1126,4 +1126,101 @@ TEST_F(SuperKernelPassTest, super_kernel_pass_simt) { | |||
| 1126 | sub_graph = sk_node->GetOpDesc()->TryGetExtAttr("_sk_sub_graph", sub_graph); | 1126 | sub_graph = sk_node->GetOpDesc()->TryGetExtAttr("_sk_sub_graph", sub_graph); |
| 1127 | EXPECT_NE(sub_graph, nullptr); | 1127 | EXPECT_NE(sub_graph, nullptr); |
| 1128 | } | 1128 | } |
| 1129 | + | ||
| 1130 | +TEST_F(SuperKernelPassTest, tiling_sink_op_allows_fusion) { | ||
| 1131 | + auto builder = ut::GraphBuilder("test_tiling_sink"); | ||
| 1132 | + auto data = builder.AddNode("data1", DATA, 0, 1); | ||
| 1133 | + auto op1 = builder.AddNode("op1", TRANSDATA, 1, 1); | ||
| 1134 | + auto op2 = builder.AddNode("op2", TRANSDATA, 1, 1); | ||
| 1135 | + auto netoutput = builder.AddNode("net_output", NETOUTPUT, 1, 0); | ||
| 1136 | + builder.AddDataEdge(data, 0, op1, 0); | ||
| 1137 | + builder.AddDataEdge(op1, 0, op2, 0); | ||
| 1138 | + builder.AddDataEdge(op2, 0, netoutput, 0); | ||
| 1139 | + | ||
| 1140 | + AttrUtils::SetStr(op1->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1141 | + AttrUtils::SetInt(op1->GetOpDesc(), "supportSuperKernel", 1); | ||
| 1142 | + AttrUtils::SetBool(op1->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1143 | + AttrUtils::SetStr(op2->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1144 | + AttrUtils::SetInt(op2->GetOpDesc(), "supportSuperKernel", 1); | ||
| 1145 | + AttrUtils::SetBool(op2->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1146 | + op1->GetOpDesc()->SetStreamId(1); | ||
| 1147 | + op2->GetOpDesc()->SetStreamId(1); | ||
| 1148 | + | ||
| 1149 | + auto compute_graph = builder.GetGraph(); | ||
| 1150 | + ASSERT_EQ(compute_graph->TopologicalSorting(), GRAPH_SUCCESS); | ||
| 1151 | + | ||
| 1152 | + SuperKernelPass super_kernel_pass; | ||
| 1153 | + auto ret = super_kernel_pass.Run(compute_graph); | ||
| 1154 | + EXPECT_EQ(ret, SUCCESS); | ||
| 1155 | + | ||
| 1156 | + NodePtr sk_node; | ||
| 1157 | + for (auto &node : compute_graph->GetDirectNode()) { | ||
| 1158 | + if (node->GetType() == "SuperKernel") { | ||
| 1159 | + sk_node = node; | ||
| 1160 | + } | ||
| 1161 | + } | ||
| 1162 | + EXPECT_NE(sk_node, nullptr); | ||
| 1163 | +} | ||
| 1164 | + | ||
| 1165 | +TEST_F(SuperKernelPassTest, tiling_sink_op_with_unsupported_op_excluded_from_fusion) { | ||
| 1166 | + auto builder = ut::GraphBuilder("test_tiling_sink_unsupported"); | ||
| 1167 | + auto data = builder.AddNode("data1", DATA, 0, 1); | ||
| 1168 | + auto op1 = builder.AddNode("op1", TRANSDATA, 1, 1); | ||
| 1169 | + auto op2 = builder.AddNode("op2", TRANSDATA, 1, 1); | ||
| 1170 | + auto netoutput = builder.AddNode("net_output", NETOUTPUT, 1, 0); | ||
| 1171 | + builder.AddDataEdge(data, 0, op1, 0); | ||
| 1172 | + builder.AddDataEdge(op1, 0, op2, 0); | ||
| 1173 | + builder.AddDataEdge(op2, 0, netoutput, 0); | ||
| 1174 | + | ||
| 1175 | + AttrUtils::SetStr(op1->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1176 | + AttrUtils::SetInt(op1->GetOpDesc(), "supportSuperKernel", 1); | ||
| 1177 | + AttrUtils::SetBool(op1->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1178 | + AttrUtils::SetStr(op2->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1179 | + AttrUtils::SetInt(op2->GetOpDesc(), "supportSuperKernel", 0); | ||
| 1180 | + AttrUtils::SetBool(op2->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1181 | + op1->GetOpDesc()->SetStreamId(1); | ||
| 1182 | + op2->GetOpDesc()->SetStreamId(1); | ||
| 1183 | + | ||
| 1184 | + auto compute_graph = builder.GetGraph(); | ||
| 1185 | + ASSERT_EQ(compute_graph->TopologicalSorting(), GRAPH_SUCCESS); | ||
| 1186 | + | ||
| 1187 | + SuperKernelPass super_kernel_pass; | ||
| 1188 | + auto ret = super_kernel_pass.Run(compute_graph); | ||
| 1189 | + EXPECT_EQ(ret, SUCCESS); | ||
| 1190 | + | ||
| 1191 | + std::string scope_attr; | ||
| 1192 | + EXPECT_FALSE(AttrUtils::GetStr(op2->GetOpDesc(), "_super_kernel_scope", scope_attr)); | ||
| 1193 | +} | ||
| 1194 | + | ||
| 1195 | +TEST_F(SuperKernelPassTest, simt_op_with_tiling_sink_excluded_from_fusion) { | ||
| 1196 | + auto builder = ut::GraphBuilder("test_simt_tiling_sink"); | ||
| 1197 | + auto data = builder.AddNode("data1", DATA, 0, 1); | ||
| 1198 | + auto op1 = builder.AddNode("op1", TRANSDATA, 1, 1); | ||
| 1199 | + auto op2 = builder.AddNode("op2", TRANSDATA, 1, 1); | ||
| 1200 | + auto netoutput = builder.AddNode("net_output", NETOUTPUT, 1, 0); | ||
| 1201 | + builder.AddDataEdge(data, 0, op1, 0); | ||
| 1202 | + builder.AddDataEdge(op1, 0, op2, 0); | ||
| 1203 | + builder.AddDataEdge(op2, 0, netoutput, 0); | ||
| 1204 | + | ||
| 1205 | + AttrUtils::SetStr(op1->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1206 | + AttrUtils::SetInt(op1->GetOpDesc(), "supportSuperKernel", 1); | ||
| 1207 | + AttrUtils::SetBool(op1->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1208 | + AttrUtils::SetInt(op1->GetOpDesc(), "local_memory_size", 1024); | ||
| 1209 | + AttrUtils::SetStr(op2->GetOpDesc(), "_super_kernel_scope", "scope1"); | ||
| 1210 | + AttrUtils::SetInt(op2->GetOpDesc(), "supportSuperKernel", 1); | ||
| 1211 | + AttrUtils::SetBool(op2->GetOpDesc(), "_tiling_sink_op", true); | ||
| 1212 | + op1->GetOpDesc()->SetStreamId(1); | ||
| 1213 | + op2->GetOpDesc()->SetStreamId(1); | ||
| 1214 | + | ||
| 1215 | + auto compute_graph = builder.GetGraph(); | ||
| 1216 | + ASSERT_EQ(compute_graph->TopologicalSorting(), GRAPH_SUCCESS); | ||
| 1217 | + | ||
| 1218 | + SuperKernelPass super_kernel_pass; | ||
| 1219 | + auto ret = super_kernel_pass.Run(compute_graph); | ||
| 1220 | + EXPECT_EQ(ret, SUCCESS); | ||
| 1221 | + | ||
| 1222 | + std::string scope_attr; | ||
| 1223 | + EXPECT_FALSE(AttrUtils::GetStr(op1->GetOpDesc(), "_super_kernel_scope", scope_attr)); | ||
| 1224 | +} | ||
| 1225 | + | ||
| 1129 | } // namespace ge | 1226 | } // namespace ge |