| 555 | } |
| 556 | |
| 557 | void InOutParallelDimReduce(const Shape& in_hierarchy, const Shape& out_hierarchy, |
| 558 | const NdSbp& in_nd_sbp, const NdSbp& out_nd_sbp, |
| 559 | Shape* reduced_in_hierarchy, Shape* reduced_out_hierarchy, |
| 560 | NdSbp* reduced_in_nd_sbp, NdSbp* reduced_out_nd_sbp, |
| 561 | const Shape& logical_shape) { |
| 562 | if (in_hierarchy == out_hierarchy) { |
| 563 | // [2, 4]: (S0, S0) -> [2, 4]: (S0, S1) |
| 564 | NdSbpsDimReduce(in_hierarchy, {&in_nd_sbp, &out_nd_sbp}, reduced_in_hierarchy, |
| 565 | {reduced_in_nd_sbp, reduced_out_nd_sbp}, logical_shape); |
| 566 | *reduced_out_hierarchy = *reduced_in_hierarchy; |
| 567 | } else { |
| 568 | // [2, 4]: (S0, S0) -> [4, 2]: (S0, S1) |
| 569 | // [2, 4]: (S0, S0) -> [3, 3]: (S0, S1) |
| 570 | NdSbpDimReduce(in_hierarchy, in_nd_sbp, reduced_in_hierarchy, reduced_in_nd_sbp, logical_shape); |
| 571 | NdSbpDimReduce(out_hierarchy, out_nd_sbp, reduced_out_hierarchy, reduced_out_nd_sbp, |
| 572 | logical_shape); |
| 573 | |
| 574 | // Sbp of 3d or higher dimension would use general basic communication |
| 575 | // Only looks at 1d to 2d or 2d to 1d |
| 576 | if (reduced_in_hierarchy->NumAxes() + reduced_out_hierarchy->NumAxes() == 3 |
| 577 | && reduced_in_hierarchy->elem_cnt() == reduced_out_hierarchy->elem_cnt()) { |
| 578 | if (reduced_in_hierarchy->NumAxes() == 1) { |
| 579 | // [8]: S0 -> [4, 2]: (S0, S1) |
| 580 | // [8]: B -> [2, 4]: (S0, S1) |
| 581 | const auto& in_sbp_parallel = reduced_in_nd_sbp->sbp_parallel(0); |
| 582 | if (!in_sbp_parallel.has_split_parallel() |
| 583 | || CanMergeSplit(logical_shape.At(in_sbp_parallel.split_parallel().axis()), |
| 584 | reduced_in_hierarchy->elem_cnt())) { |
| 585 | // Change [8]: S0 -> [4, 2]: (S0, S1) to [4, 2]: (S0, S0) -> [4, 2]: (S0, S1) |
| 586 | // Change [8]: B -> [2, 4]: (S0, S1) to [2, 4]: (B, B) -> [2, 4]: (S0, S1) |
| 587 | *reduced_in_nd_sbp->add_sbp_parallel() = in_sbp_parallel; |
| 588 | *reduced_in_hierarchy = *reduced_out_hierarchy; |
| 589 | } |
| 590 | } else { |
| 591 | // [2, 3]: (S0, P) -> [6]: S0 |
| 592 | // [3, 4]: (B, S1) -> [12]: B |
| 593 | const auto& out_sbp_parallel = reduced_out_nd_sbp->sbp_parallel(0); |
| 594 | if (!out_sbp_parallel.has_split_parallel() |
| 595 | || CanMergeSplit(logical_shape.At(out_sbp_parallel.split_parallel().axis()), |
| 596 | reduced_out_hierarchy->elem_cnt())) { |
| 597 | // Change [2, 3]: (S0, P) -> [6]: S0 to [2, 3]: (S0, P) -> [2, 3]: (S0, S0) |
| 598 | // Change [3, 4]: (B, S1) -> [12]: B to [3, 4]: (B, S1) -> [3, 4]: (B, B) |
| 599 | *reduced_out_nd_sbp->add_sbp_parallel() = out_sbp_parallel; |
| 600 | *reduced_out_hierarchy = *reduced_in_hierarchy; |
| 601 | } |
| 602 | } |
| 603 | } |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | void InOutParallelDimReduce(const ParallelDesc& in_parallel_desc, |
| 608 | const ParallelDesc& out_parallel_desc, const NdSbp& in_nd_sbp, |
no test coverage detected