已合并
【PR】: elmwise 双输入时为 compact reduce 兜底检查插入 pad #1963
JacsonPile创建于 18 天前
【PR】: elmwise 双输入时为 compact reduce 兜底检查插入 pad #1963
已合并
共 3 个文件变更+236-8
| @@ -303,14 +303,102 @@ af::Status BaseAlignmentStrategy::AddRemovePadForOneNode(ascir::ImplGraph &impl_ | |||
| 303 | return af::SUCCESS; | 303 | return af::SUCCESS; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | +bool BaseAlignmentStrategy::FindCompactReduceInput(const af::AscNodePtr &node, af::InDataAnchorPtr &reduce_input, | ||
| 307 | + af::OutDataAnchorPtr &reduce_output) const { | ||
| 308 | + if (node->attr.api.compute_type != af::ComputeType::kComputeElewise) { | ||
| 309 | + return false; | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + bool has_aligned_broadcast = false; | ||
| 313 | + size_t linked_input_count = 0UL; | ||
| 314 | + for (const auto &in_anchor : node->GetAllInDataAnchorsPtr()) { | ||
| 315 | + const auto peer_out = in_anchor->GetPeerOutAnchor(); | ||
| 316 | + if (peer_out == nullptr) { | ||
| 317 | + continue; | ||
| 318 | + } | ||
| 319 | + ++linked_input_count; | ||
| 320 | + const auto producer = std::dynamic_pointer_cast<af::AscNode>(peer_out->GetOwnerNode()); | ||
| 321 | + if (producer == nullptr) { | ||
| 322 | + continue; | ||
| 323 | + } | ||
| 324 | + const auto state_iter = tensor_to_align_type_.find(&af::AscTensorAttr::GetTensorAttr(*peer_out)); | ||
| 325 | + if (state_iter == tensor_to_align_type_.end()) { | ||
| 326 | + continue; | ||
| 327 | + } | ||
| 328 | + if (af::ops::IsOps<af::ascir_op::Broadcast>(producer) && state_iter->second.align_type == AlignmentType::kAligned) { | ||
| 329 | + has_aligned_broadcast = true; | ||
| 330 | + } else if (af::ops::IsOps<af::ascir_op::Sum>(producer)) { | ||
| 331 | + const auto &reduce_attr = af::AscTensorAttr::GetTensorAttr(*peer_out); | ||
| 332 | + if (!reduce_attr.vectorized_axis.empty()) { | ||
| 333 | + const auto axis = reduce_attr.vectorized_axis.back(); | ||
| 334 | + const auto axis_iter = std::find(reduce_attr.axis.begin(), reduce_attr.axis.end(), axis); | ||
| 335 | + const auto axis_index = static_cast<size_t>(std::distance(reduce_attr.axis.begin(), axis_iter)); | ||
| 336 | + const bool compact_output = axis_iter != reduce_attr.axis.end() && axis_index < reduce_attr.strides.size() && | ||
| 337 | + af::SymbolicUtils::StaticCheckEq(reduce_attr.strides[axis_index], | ||
| 338 | + af::sym::kSymbolZero) == af::TriBool::kTrue; | ||
| 339 | + // Compact Reduce 的尾轴 stride 为零,即使反向传播已把状态改成 kAligned,物理布局仍是 not-aligned。 | ||
| 340 | + if (compact_output) { | ||
| 341 | + reduce_input = node->GetInDataAnchor(in_anchor->GetIdx()); | ||
| 342 | + reduce_output = peer_out; | ||
| 343 | + } | ||
| 344 | + } | ||
| 345 | + } | ||
| 346 | + } | ||
| 347 | + return linked_input_count == 2UL && has_aligned_broadcast && reduce_input != nullptr && reduce_output != nullptr; | ||
| 348 | +} | ||
| 349 | + | ||
| 350 | +af::Status BaseAlignmentStrategy::InsertPadForCompactReduce(ascir::ImplGraph &impl_graph, | ||
| 351 | + const af::InDataAnchorPtr &reduce_input, | ||
| 352 | + const af::OutDataAnchorPtr &reduce_output, bool &inserted) { | ||
| 353 | + const auto reduce_node = std::dynamic_pointer_cast<af::AscNode>(reduce_output->GetOwnerNode()); | ||
| 354 | + GE_ASSERT_NOTNULL(reduce_node); | ||
| 355 | + const auto output_index = reduce_output->GetIdx(); | ||
| 356 | + auto &reduce_attr = reduce_node->outputs[output_index].attr; | ||
| 357 | + bool is_no_need_pad = false; | ||
| 358 | + GE_ASSERT_SUCCESS(CheckIsNoNeedPad(reduce_node, reduce_attr, is_no_need_pad)); | ||
| 359 | + if (is_no_need_pad) { | ||
| 360 | + return af::SUCCESS; | ||
| 361 | + } | ||
| 362 | + std::vector<af::DataType> exp_dtypes{reduce_attr.dtype}; | ||
| 363 | + if (ScheduleUtils::CallAscirInferDataType<af::ascir_op::Pad>({reduce_attr.dtype}, exp_dtypes) != af::SUCCESS) { | ||
| 364 | + GELOGW("Pad is unsupported for compact Reduce output in graph [%s].", impl_graph.GetName().c_str()); | ||
| 365 | + return af::UNSUPPORTED; | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + const std::string node_name = reduce_node->GetName() + "_" + std::to_string(output_index) + "_pad"; | ||
| 369 | + af::ascir_op::Pad pad_op(node_name.c_str()); | ||
| 370 | + const auto pad_node = impl_graph.AddNode(pad_op); | ||
| 371 | + GE_ASSERT_NOTNULL(pad_node); | ||
| 372 | + pad_node->attr = reduce_node->attr; | ||
| 373 | + pad_node->outputs[0].attr = reduce_attr; | ||
| 374 | + pad_node->attr.api.compute_type = af::ComputeType::kComputeElewise; | ||
| 375 | + pad_node->attr.api.type = af::ApiType::kAPITypeCompute; | ||
| 376 | + pad_node->attr.api.unit = af::ComputeUnit::kUnitVector; | ||
| 377 | + tensor_to_align_type_[&pad_node->outputs[0].attr].align_type = AlignmentType::kAligned; | ||
| 378 | + GE_ASSERT_SUCCESS(af::AscGraphUtils::InsertNodeAfter(reduce_output, {reduce_input}, pad_node)); | ||
| 379 | + inserted = true; | ||
| 380 | + return af::SUCCESS; | ||
| 381 | +} | ||
| 382 | + | ||
| 383 | +af::Status BaseAlignmentStrategy::AddPadForCompactReduce(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, | ||
| 384 | + bool &inserted) { | ||
| 385 | + af::InDataAnchorPtr reduce_input; | ||
| 386 | + af::OutDataAnchorPtr reduce_output; | ||
| 387 | + if (!FindCompactReduceInput(node, reduce_input, reduce_output)) { | ||
| 388 | + return af::SUCCESS; | ||
| 389 | + } | ||
| 390 | + return InsertPadForCompactReduce(impl_graph, reduce_input, reduce_output, inserted); | ||
| 391 | +} | ||
| 392 | + | ||
| 306 | af::Status BaseAlignmentStrategy::CheckIsNoNeedPad(const af::AscNodePtr &node, af::AscTensorAttr &out_attr, | 393 | af::Status BaseAlignmentStrategy::CheckIsNoNeedPad(const af::AscNodePtr &node, af::AscTensorAttr &out_attr, |
| 307 | bool &is_no_need_pad) const { | 394 | bool &is_no_need_pad) const { |
| 308 | - size_t valid_axis_num = 0UL; | 395 | + bool has_valid_outer_axis = false; |
| 309 | bool tail_axis_aligned = false; | 396 | bool tail_axis_aligned = false; |
| 310 | for (auto axis_it = out_attr.vectorized_axis.rbegin(); axis_it != out_attr.vectorized_axis.rend(); ++axis_it) { | 397 | for (auto axis_it = out_attr.vectorized_axis.rbegin(); axis_it != out_attr.vectorized_axis.rend(); ++axis_it) { |
| 311 | auto it = std::find(out_attr.axis.begin(), out_attr.axis.end(), *axis_it); | 398 | auto it = std::find(out_attr.axis.begin(), out_attr.axis.end(), *axis_it); |
| 312 | GE_ASSERT_TRUE(it != out_attr.axis.end()); | 399 | GE_ASSERT_TRUE(it != out_attr.axis.end()); |
| 313 | const size_t distance = std::distance(out_attr.axis.begin(), it); | 400 | const size_t distance = std::distance(out_attr.axis.begin(), it); |
| 401 | + GE_ASSERT_TRUE(distance < out_attr.repeats.size() && distance < out_attr.strides.size()); | ||
| 314 | if (axis_it == out_attr.vectorized_axis.rbegin()) { | 402 | if (axis_it == out_attr.vectorized_axis.rbegin()) { |
| 315 | const auto dtype_size = af::GetSizeByDataType(out_attr.dtype); | 403 | const auto dtype_size = af::GetSizeByDataType(out_attr.dtype); |
| 316 | GE_ASSERT_TRUE(dtype_size > 0, "Node [%s]'s data type size:[%d] is invalid.", node->GetNamePtr(), dtype_size); | 404 | GE_ASSERT_TRUE(dtype_size > 0, "Node [%s]'s data type size:[%d] is invalid.", node->GetNamePtr(), dtype_size); |
| @@ -322,12 +410,17 @@ af::Status BaseAlignmentStrategy::CheckIsNoNeedPad(const af::AscNodePtr &node, a | |||
| 322 | af::SymbolicUtils::ToString(repeat).c_str(), node->GetNamePtr()); | 410 | af::SymbolicUtils::ToString(repeat).c_str(), node->GetNamePtr()); |
| 323 | break; | 411 | break; |
| 324 | } | 412 | } |
| 325 | - } else if (af::SymbolicUtils::StaticCheckNe(out_attr.strides[distance], af::sym::kSymbolZero) == | 413 | + continue; |
| 326 | - af::TriBool::kTrue) { | 414 | + } |
| 327 | - valid_axis_num++; | 415 | + const bool is_inactive_axis = |
| 416 | + af::SymbolicUtils::StaticCheckEq(out_attr.strides[distance], af::sym::kSymbolZero) == af::TriBool::kTrue || | ||
| 417 | + af::SymbolicUtils::StaticCheckEq(out_attr.repeats[distance], af::sym::kSymbolOne) == af::TriBool::kTrue; | ||
| 418 | + if (!is_inactive_axis) { | ||
| 419 | + has_valid_outer_axis = true; | ||
| 420 | + break; | ||
| 328 | } | 421 | } |
| 329 | } | 422 | } |
| 330 | - is_no_need_pad = tail_axis_aligned || valid_axis_num == 0UL; | 423 | + is_no_need_pad = tail_axis_aligned || !has_valid_outer_axis; |
| 331 | return af::SUCCESS; | 424 | return af::SUCCESS; |
| 332 | } | 425 | } |
| 333 | 426 | ||
| @@ -385,6 +478,9 @@ af::Status BaseAlignmentStrategy::AlignVectorizedStrides(ascir::ImplGraph &impl_ | |||
| 385 | } | 478 | } |
| 386 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::AddRemovePadForOneNode)); | 479 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::AddRemovePadForOneNode)); |
| 387 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::InferAlignmentForOneNode)); | 480 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::InferAlignmentForOneNode)); |
| 481 | + // Compact Reduce 依赖已推导的对齐状态,必须在对齐推导之后、通用冲突补 Pad 与向量化 stride 生成之前执行, | ||
| 482 | + // 确保只改写原始 Reduce 边一次,并让新插入的 Pad 参与最终 stride 生成。 | ||
| 483 | + GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::AddPadForCompactReduce)); | ||
| 388 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::AddPadForAlignmentConflictOneNode)); | 484 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::AddPadForAlignmentConflictOneNode)); |
| 389 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::SetVectorizedStridesForOneNode)); | 485 | GE_CHK_STATUS_RET_NOLOG(ForEachNode(impl_graph, &BaseAlignmentStrategy::SetVectorizedStridesForOneNode)); |
| 390 | return af::SUCCESS; | 486 | return af::SUCCESS; |
| @@ -428,9 +524,7 @@ void BaseAlignmentStrategy::SetAlignInfoForNodeInputs(AlignmentType aligned_type | |||
| 428 | continue; | 524 | continue; |
| 429 | } | 525 | } |
| 430 | 526 | ||
| 431 | - const bool is_compact_reduce = | 527 | + if (align_info.align_type == AlignmentType::kFixedNotAligned) { |
| 432 | - ScheduleUtils::IsReduce(asc_node) && align_info.align_type == AlignmentType::kNotAligned; | ||
| 433 | - if (align_info.align_type == AlignmentType::kFixedNotAligned || is_compact_reduce) { | ||
| 434 | align_info.conflict_with_output = true; | 528 | align_info.conflict_with_output = true; |
| 435 | GELOGD("SetAlignInfoForNodeInputs: input[%s] is FixedNotAligned, set conflict_with_output=true.", | 529 | GELOGD("SetAlignInfoForNodeInputs: input[%s] is FixedNotAligned, set conflict_with_output=true.", |
| 436 | asc_node->GetNamePtr()); | 530 | asc_node->GetNamePtr()); |
| @@ -88,6 +88,11 @@ class BaseAlignmentStrategy { | |||
| 88 | std::queue<af::Node *> &node_queue); | 88 | std::queue<af::Node *> &node_queue); |
| 89 | 89 | ||
| 90 | af::Status AddRemovePadForOneNode(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, bool &inserted); | 90 | af::Status AddRemovePadForOneNode(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, bool &inserted); |
| 91 | + af::Status AddPadForCompactReduce(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, bool &inserted); | ||
| 92 | + bool FindCompactReduceInput(const af::AscNodePtr &node, af::InDataAnchorPtr &reduce_input, | ||
| 93 | + af::OutDataAnchorPtr &reduce_output) const; | ||
| 94 | + af::Status InsertPadForCompactReduce(ascir::ImplGraph &impl_graph, const af::InDataAnchorPtr &reduce_input, | ||
| 95 | + const af::OutDataAnchorPtr &reduce_output, bool &inserted); | ||
| 91 | af::Status CheckIsNoNeedPad(const af::AscNodePtr &node, af::AscTensorAttr &out_attr, bool &is_no_need_pad) const; | 96 | af::Status CheckIsNoNeedPad(const af::AscNodePtr &node, af::AscTensorAttr &out_attr, bool &is_no_need_pad) const; |
| 92 | af::Status AddPadForAlignmentConflictOneNode(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, | 97 | af::Status AddPadForAlignmentConflictOneNode(ascir::ImplGraph &impl_graph, const af::AscNodePtr &node, |
| 93 | bool &inserted); | 98 | bool &inserted); |
| @@ -44,6 +44,28 @@ void SetTwoDimNodeAttr(Op &op, Dtype dtype, af::ComputeType compute_type, const | |||
| 44 | *op.y.vectorized_axis = axes; | 44 | *op.y.vectorized_axis = axes; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | +void BuildCompactReduceAddGraph(af::AscGraph &graph, const af::Expression &reduce_tail_stride) { | ||
| 48 | + auto rows = af::Symbol(8); | ||
| 49 | + auto cols = af::Symbol(11); | ||
| 50 | + auto row_axis = graph.CreateAxis("row", rows); | ||
| 51 | + auto col_axis = graph.CreateAxis("col", cols); | ||
| 52 | + std::vector<af::AxisId> axes = {row_axis.id, col_axis.id}; | ||
| 53 | + | ||
| 54 | + af::ascir_op::Data data("data", graph); | ||
| 55 | + data.y.dtype = ge::DT_FLOAT; | ||
| 56 | + data.attr.api.type = af::ApiType::kAPITypeBuffer; | ||
| 57 | + af::ascir_op::Sum sum("sum"); | ||
| 58 | + sum.x = data.y; | ||
| 59 | + SetTwoDimNodeAttr(sum, ge::DT_FLOAT, af::ComputeType::kComputeReduce, axes, {rows, One}, {One, reduce_tail_stride}); | ||
| 60 | + af::ascir_op::Broadcast broadcast("broadcast"); | ||
| 61 | + broadcast.x = data.y; | ||
| 62 | + SetTwoDimNodeAttr(broadcast, ge::DT_FLOAT, af::ComputeType::kComputeBroadcast, axes, {rows, cols}, {cols, One}); | ||
| 63 | + af::ascir_op::Add add("add"); | ||
| 64 | + add.x1 = sum.y; | ||
| 65 | + add.x2 = broadcast.y; | ||
| 66 | + SetTwoDimNodeAttr(add, ge::DT_FLOAT, af::ComputeType::kComputeElewise, axes, {rows, cols}, {cols, One}); | ||
| 67 | +} | ||
| 68 | + | ||
| 47 | void ExpectCompactReduceBranch(const af::AscGraph &graph, const char *aligned_input) { | 69 | void ExpectCompactReduceBranch(const af::AscGraph &graph, const char *aligned_input) { |
| 48 | std::vector<af::Expression> aligned_input_strides = {af::Symbol(24), One}; | 70 | std::vector<af::Expression> aligned_input_strides = {af::Symbol(24), One}; |
| 49 | std::vector<af::Expression> compact_output_strides = {One, Zero}; | 71 | std::vector<af::Expression> compact_output_strides = {One, Zero}; |
| @@ -77,6 +99,13 @@ class VectorizedAlignmentUT : public testing::Test { | |||
| 77 | af::Status AccessInferAlignment(ImplGraph &impl_graph) { | 99 | af::Status AccessInferAlignment(ImplGraph &impl_graph) { |
| 78 | return ForEachNode(impl_graph, &AlignmentStrategyShadow::InferAlignmentForOneNode); | 100 | return ForEachNode(impl_graph, &AlignmentStrategyShadow::InferAlignmentForOneNode); |
| 79 | } | 101 | } |
| 102 | + bool AccessFindCompactReduceInput(const af::AscNodePtr &node, af::InDataAnchorPtr &reduce_input, | ||
| 103 | + af::OutDataAnchorPtr &reduce_output) const { | ||
| 104 | + return FindCompactReduceInput(node, reduce_input, reduce_output); | ||
| 105 | + } | ||
| 106 | + void SetAlignmentType(const af::AscNodePtr &node, AlignmentType align_type) { | ||
| 107 | + tensor_to_align_type_[&node->outputs[0].attr].align_type = align_type; | ||
| 108 | + } | ||
| 80 | // 当前tensor的对齐行为只会出现在尾轴,如果没有新的对齐行为或者类型,该函数不应该修改 | 109 | // 当前tensor的对齐行为只会出现在尾轴,如果没有新的对齐行为或者类型,该函数不应该修改 |
| 81 | af::Status AccessSetVectorizedStrides(ImplGraph &impl_graph) { | 110 | af::Status AccessSetVectorizedStrides(ImplGraph &impl_graph) { |
| 82 | return ForEachNode(impl_graph, &AlignmentStrategyShadow::SetVectorizedStridesForOneNode); | 111 | return ForEachNode(impl_graph, &AlignmentStrategyShadow::SetVectorizedStridesForOneNode); |
| @@ -870,4 +899,104 @@ TEST_F(VectorizedAlignmentUT, sibling_reduce_keeps_compact_output_alignment) { | |||
| 870 | ExpectCompactReduceBranch(graph, "relu"); | 899 | ExpectCompactReduceBranch(graph, "relu"); |
| 871 | } | 900 | } |
| 872 | 901 | ||
| 902 | +TEST_F(VectorizedAlignmentUT, compact_reduce_pad_for_aligned_broadcast_add) { | ||
| 903 | + af::AscGraph graph("compact_reduce_pad_for_aligned_broadcast_add"); | ||
| 904 | + auto rows = af::Symbol(8); | ||
| 905 | + auto cols = af::Symbol(11); | ||
| 906 | + auto row_axis = graph.CreateAxis("row", rows); | ||
| 907 | + auto col_axis = graph.CreateAxis("col", cols); | ||
| 908 | + std::vector<af::AxisId> axes = {row_axis.id, col_axis.id}; | ||
| 909 | + | ||
| 910 | + af::ascir_op::Data data("data", graph); | ||
| 911 | + data.y.dtype = ge::DT_FLOAT; | ||
| 912 | + data.attr.api.type = af::ApiType::kAPITypeBuffer; | ||
| 913 | + af::ascir_op::Load reduce_load("reduce_load"); | ||
| 914 | + reduce_load.x = data.y; | ||
| 915 | + SetTwoDimNodeAttr(reduce_load, ge::DT_FLOAT, af::ComputeType::kComputeLoad, axes, {rows, cols}, {cols, One}); | ||
| 916 | + af::ascir_op::Sum reduce_sum("reduce_sum"); | ||
| 917 | + reduce_sum.x = reduce_load.y; | ||
| 918 | + SetTwoDimNodeAttr(reduce_sum, ge::DT_FLOAT, af::ComputeType::kComputeReduce, axes, {rows, One}, {One, Zero}); | ||
| 919 | + af::ascir_op::Load aligned_load("aligned_load"); | ||
| 920 | + aligned_load.x = data.y; | ||
| 921 | + SetTwoDimNodeAttr(aligned_load, ge::DT_FLOAT, af::ComputeType::kComputeLoad, axes, {rows, cols}, | ||
| 922 | + {cols * af::Symbol(2), One}); | ||
| 923 | + af::ascir_op::Broadcast broadcast("broadcast"); | ||
| 924 | + broadcast.x = aligned_load.y; | ||
| 925 | + SetTwoDimNodeAttr(broadcast, ge::DT_FLOAT, af::ComputeType::kComputeBroadcast, axes, {rows, cols}, | ||
| 926 | + {cols * af::Symbol(2), One}); | ||
| 927 | + af::ascir_op::Add add("add"); | ||
| 928 | + add.x1 = reduce_sum.y; | ||
| 929 | + add.x2 = broadcast.y; | ||
| 930 | + SetTwoDimNodeAttr(add, ge::DT_FLOAT, af::ComputeType::kComputeElewise, axes, {rows, cols}, {cols, One}); | ||
| 931 | + af::ascir_op::Store store("store"); | ||
| 932 | + store.x = add.y; | ||
| 933 | + SetTwoDimNodeAttr(store, ge::DT_FLOAT, af::ComputeType::kComputeStore, axes, {rows, cols}, {cols, One}); | ||
| 934 | + | ||
| 935 | + ASSERT_EQ(AlignmentHandler::AlignVectorizedStrides(graph), af::SUCCESS); | ||
| 936 | + auto pad_node = graph.FindNode("reduce_sum_0_pad"); | ||
| 937 | + ASSERT_NE(pad_node, nullptr); | ||
| 938 | + auto add_node = graph.FindNode("add"); | ||
| 939 | + ASSERT_NE(add_node, nullptr); | ||
| 940 | + EXPECT_EQ(add_node->inputs[0].anchor.GetOwnerNodeBarePtr(), pad_node.get()); | ||
| 941 | +} | ||
| 942 | + | ||
| 943 | +TEST_F(VectorizedAlignmentUT, scalar_reduce_skips_pad_for_aligned_broadcast_add) { | ||
| 944 | + af::AscGraph graph("scalar_reduce_skips_pad_for_aligned_broadcast_add"); | ||
| 945 | + auto rows = af::Symbol(8); | ||
| 946 | + auto cols = af::Symbol(11); | ||
| 947 | + auto row_axis = graph.CreateAxis("row", rows); | ||
| 948 | + auto col_axis = graph.CreateAxis("col", cols); | ||
| 949 | + std::vector<af::AxisId> axes = {row_axis.id, col_axis.id}; | ||
| 950 | + | ||
| 951 | + af::ascir_op::Data data("data", graph); | ||
| 952 | + data.y.dtype = ge::DT_FLOAT; | ||
| 953 | + data.attr.api.type = af::ApiType::kAPITypeBuffer; | ||
| 954 | + af::ascir_op::Load reduce_load("reduce_load"); | ||
| 955 | + reduce_load.x = data.y; | ||
| 956 | + SetTwoDimNodeAttr(reduce_load, ge::DT_FLOAT, af::ComputeType::kComputeLoad, axes, {rows, cols}, {cols, One}); | ||
| 957 | + af::ascir_op::Sum reduce_sum("reduce_sum"); | ||
| 958 | + reduce_sum.x = reduce_load.y; | ||
| 959 | + SetTwoDimNodeAttr(reduce_sum, ge::DT_FLOAT, af::ComputeType::kComputeReduce, axes, {One, One}, {One, Zero}); | ||
| 960 | + af::ascir_op::Load aligned_load("aligned_load"); | ||
| 961 | + aligned_load.x = data.y; | ||
| 962 | + SetTwoDimNodeAttr(aligned_load, ge::DT_FLOAT, af::ComputeType::kComputeLoad, axes, {rows, cols}, | ||
| 963 | + {cols * af::Symbol(2), One}); | ||
| 964 | + af::ascir_op::Broadcast broadcast("broadcast"); | ||
| 965 | + broadcast.x = aligned_load.y; | ||
| 966 | + SetTwoDimNodeAttr(broadcast, ge::DT_FLOAT, af::ComputeType::kComputeBroadcast, axes, {rows, cols}, | ||
| 967 | + {cols * af::Symbol(2), One}); | ||
| 968 | + af::ascir_op::Add add("add"); | ||
| 969 | + add.x1 = reduce_sum.y; | ||
| 970 | + add.x2 = broadcast.y; | ||
| 971 | + SetTwoDimNodeAttr(add, ge::DT_FLOAT, af::ComputeType::kComputeElewise, axes, {rows, cols}, {cols, One}); | ||
| 972 | + | ||
| 973 | + ASSERT_EQ(AlignmentHandler::AlignVectorizedStrides(graph), af::SUCCESS); | ||
| 974 | + EXPECT_EQ(graph.FindNode("reduce_sum_0_pad"), nullptr); | ||
| 975 | + auto add_node = graph.FindNode("add"); | ||
| 976 | + ASSERT_NE(add_node, nullptr); | ||
| 977 | + EXPECT_EQ(add_node->inputs[0].anchor.GetOwnerNodeBarePtr(), graph.FindNode("reduce_sum").get()); | ||
| 978 | +} | ||
| 979 | + | ||
| 980 | +TEST_F(VectorizedAlignmentUT, non_aligned_broadcast_skips_compact_reduce_pad) { | ||
| 981 | + af::AscGraph graph("non_aligned_broadcast_skips_compact_reduce_pad"); | ||
| 982 | + BuildCompactReduceAddGraph(graph, Zero); | ||
| 983 | + AlignmentStrategyShadow strategy; | ||
| 984 | + strategy.SetAlignmentType(graph.FindNode("sum"), AlignmentType::kNotAligned); | ||
| 985 | + strategy.SetAlignmentType(graph.FindNode("broadcast"), AlignmentType::kNotAligned); | ||
| 986 | + af::InDataAnchorPtr reduce_input; | ||
| 987 | + af::OutDataAnchorPtr reduce_output; | ||
| 988 | + EXPECT_FALSE(strategy.AccessFindCompactReduceInput(graph.FindNode("add"), reduce_input, reduce_output)); | ||
| 989 | +} | ||
| 990 | + | ||
| 991 | +TEST_F(VectorizedAlignmentUT, non_compact_sum_skips_compact_reduce_pad) { | ||
| 992 | + af::AscGraph graph("non_compact_sum_skips_compact_reduce_pad"); | ||
| 993 | + BuildCompactReduceAddGraph(graph, One); | ||
| 994 | + AlignmentStrategyShadow strategy; | ||
| 995 | + strategy.SetAlignmentType(graph.FindNode("sum"), AlignmentType::kNotAligned); | ||
| 996 | + strategy.SetAlignmentType(graph.FindNode("broadcast"), AlignmentType::kAligned); | ||
| 997 | + af::InDataAnchorPtr reduce_input; | ||
| 998 | + af::OutDataAnchorPtr reduce_output; | ||
| 999 | + EXPECT_FALSE(strategy.AccessFindCompactReduceInput(graph.FindNode("add"), reduce_input, reduce_output)); | ||
| 1000 | +} | ||
| 1001 | + | ||
| 873 | } // namespace optimize | 1002 | } // namespace optimize |