LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_template/ins_alg_template - ins_temp_reduce_mesh_2D.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 235 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 17 0

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "alg_data_trans_wrapper.h"
      12              : #include "ins_temp_reduce_mesh_2D.h"
      13              : 
      14              : namespace Hccl {
      15              : 
      16            0 : InsTempReduceMesh2D::InsTempReduceMesh2D(
      17              :     const RankId virtualRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
      18            0 :     const std::map<RankId, u32>& tempVirtRankMap)
      19            0 :     : InsAlgTemplateBase(virtualRank, tempRankSize, tempVTopo, tempVirtRankMap)
      20            0 : {}
      21              : 
      22            0 : InsTempReduceMesh2D::~InsTempReduceMesh2D() {}
      23              : 
      24            0 : HcclResult InsTempReduceMesh2D::CalcRes(AlgTempResReq& tempResReq)
      25              : {
      26            0 :     HCCL_INFO("[InsTempReduceMesh2D] Calculate communication resources start");
      27              : 
      28            0 :     CHK_PRT_RET(
      29              :         tempVTopo_.size() != AXIS_NUM,
      30              :         HCCL_ERROR(
      31              :             "[InsTempReduceMesh2D] The dimension of topo is invalid, expect [%u], now is [%u]", AXIS_NUM,
      32              :             tempVTopo_.size()),
      33              :         HcclResult::HCCL_E_INTERNAL);
      34              : 
      35            0 :     axisRankSize_[AXIS_X] = tempVTopo_.at(AXIS_X).size();
      36            0 :     axisRankSize_[AXIS_Y] = tempVTopo_.at(AXIS_Y).size();
      37              : 
      38            0 :     CHK_PRT_RET(
      39              :         axisRankSize_[AXIS_X] == 0 || axisRankSize_[AXIS_Y] == 0,
      40              :         HCCL_ERROR(
      41              :             "[InsTempReduceMesh2D] The rankSize of dimension is invalid, xRankSize is [%u], yRankSize is [%u]",
      42              :             axisRankSize_[AXIS_X], axisRankSize_[AXIS_Y]),
      43              :         HcclResult::HCCL_E_INTERNAL);
      44              : 
      45            0 :     tempResReq.queNum = axisRankSize_[AXIS_X] + axisRankSize_[AXIS_Y];
      46            0 :     tempResReq.streamNum = tempResReq.queNum;
      47              : 
      48            0 :     tempResReq.queNotifys = CreateNotifiesRequest(axisRankSize_[AXIS_X], axisRankSize_[AXIS_Y]);
      49              : 
      50            0 :     CHK_RET(CalcResLinksConcurrMesh(myRank_, tempRankSize_, tempVTopo_, linkNumBtwPeers_, tempResReq));
      51              : 
      52            0 :     HCCL_INFO(
      53              :         "[InsTempReduceMesh2D] Calculate communication resources finished, queNum[%u], streamNum[%u], "
      54              :         "queNotifyNum[%zu] linkNum[%zu]",
      55              :         tempResReq.queNum, tempResReq.streamNum, tempResReq.queNotifys.size(), tempResReq.links.size());
      56              : 
      57            0 :     return HcclResult::HCCL_SUCCESS;
      58              : }
      59              : 
      60            0 : std::vector<std::tuple<QId, QId, u32>> InsTempReduceMesh2D::CreateNotifiesRequest(u32 xQueueNum, u32 yQueueNum) const
      61              : {
      62            0 :     std::vector<std::tuple<QId, QId, u32>> notifyRequests;
      63            0 :     if (xQueueNum == 0) {
      64            0 :         HCCL_INFO("[InsTempReduceMesh2D] xQueueNum is zero, return empty notifyRequests");
      65            0 :         return notifyRequests;
      66              :     }
      67            0 :     if (yQueueNum == 0) {
      68            0 :         HCCL_INFO("[InsTempReduceMesh2D] yQueueNum is zero, return empty notifyRequests");
      69            0 :         return notifyRequests;
      70              :     };
      71            0 :     u32 queueNum = xQueueNum + yQueueNum;
      72              : 
      73            0 :     u32 slaveNum = queueNum - 1;
      74            0 :     if (slaveNum < 1) {
      75            0 :         HCCL_INFO("[InsTempReduceMesh2D] slaveNum is zero, return empty notifyRequests");
      76            0 :         return notifyRequests;
      77              :     }
      78              : 
      79            0 :     u32 ctrlNotfiyReqNum = 2;                // X轴向的控制流(主流)和Y轴向的控制流之间的Notify
      80            0 :     u32 xNotifyReqNum = (xQueueNum - 1) * 2; // X轴向的控制流和业务流之间的Notify
      81            0 :     u32 yNotifyReqNum = (yQueueNum - 1) * 2; // Y轴向的控制流和业务流之间的Notify
      82            0 :     u32 totalNotifyReqNum = ctrlNotfiyReqNum + xNotifyReqNum + yNotifyReqNum;
      83            0 :     notifyRequests.reserve(totalNotifyReqNum);
      84              : 
      85            0 :     QId xCtrlId = 0;
      86            0 :     QId yCtrlId = xCtrlId + xNotifyReqNum;
      87              : 
      88            0 :     notifyRequests.emplace_back(std::make_tuple(xCtrlId, yCtrlId, 0));
      89            0 :     notifyRequests.emplace_back(std::make_tuple(yCtrlId, xCtrlId, 0));
      90              : 
      91            0 :     for (QId xId = xCtrlId + 1; xId < xNotifyReqNum; ++xId) {
      92            0 :         notifyRequests.emplace_back(std::make_tuple(xCtrlId, xId, 0));
      93            0 :         notifyRequests.emplace_back(std::make_tuple(xId, xCtrlId, 0));
      94              :     }
      95              : 
      96            0 :     for (QId yId = yCtrlId + 1; yId < xNotifyReqNum + yNotifyReqNum; ++yId) {
      97            0 :         notifyRequests.emplace_back(std::make_tuple(yCtrlId, yId, 0));
      98            0 :         notifyRequests.emplace_back(std::make_tuple(yId, yCtrlId, 0));
      99              :     }
     100              : 
     101            0 :     HCCL_DEBUG(
     102              :         "[InsTempReduceMesh2D] Create notifies request: "
     103              :         "totalNotifyReqNum[%u], ctrlNotfiyReqNum[%u], xNotifyReqNum[%u], yNotifyReqNum[%u]",
     104              :         totalNotifyReqNum, ctrlNotfiyReqNum, xNotifyReqNum, yNotifyReqNum);
     105              : 
     106            0 :     return notifyRequests;
     107            0 : }
     108              : 
     109            0 : HcclResult InsTempReduceMesh2D::CalcResLinksConcurrMesh(
     110              :     const RankId myRank, const u32 tempRankSize, const std::vector<std::vector<RankId>>& tempVTopo,
     111              :     const u32 linkNumBtwPeers, AlgTempResReq& tempResReq) const
     112              : {
     113              :     (void)tempRankSize;
     114              :     u32 myAlgRank;
     115            0 :     for (u32 dim = 0; dim < tempVTopo.size(); dim++) {
     116            0 :         CHK_RET(GetAlgRank(myRank, tempVTopo[dim], myAlgRank));
     117            0 :         for (u32 queIdx = 0; queIdx < tempVTopo[dim].size() - 1; queIdx++) {
     118            0 :             RankId neighborRank = tempVTopo[dim][(myAlgRank + 1 + queIdx) % (tempVTopo[dim].size())];
     119            0 :             tempResReq.links[neighborRank] = linkNumBtwPeers;
     120              :         }
     121              :     }
     122            0 :     return HcclResult::HCCL_SUCCESS;
     123              : }
     124              : 
     125            0 : u32 InsTempReduceMesh2D::CalcScratchMultiple(BufferType inBuffType, BufferType outBuffType)
     126              : {
     127              :     (void)inBuffType;
     128              :     (void)outBuffType;
     129              : 
     130              :     // 数据会在2个维度间切换通信,选择最大的维度切分scratch方便数据处理
     131            0 :     u32 scratchMultiple = max(tempVTopo_.at(AXIS_X).size(), tempVTopo_.at(AXIS_Y).size());
     132            0 :     HCCL_INFO("[InsTempReduceMesh2D] Scratch multiple is [%u]", scratchMultiple);
     133            0 :     return scratchMultiple;
     134              : }
     135              : 
     136            0 : HcclResult InsTempReduceMesh2D::GenExtIns(
     137              :     const TempFuncs& tempFuncs, const TemplateDataParams& templateDataParams, const ResLinks& tempLinks,
     138              :     std::vector<InsQuePtr>& tempInsQues)
     139              : {
     140              :     (void)tempFuncs;
     141            0 :     HCCL_INFO("[InsTempReduceMesh2D] GenExtIns start rank[%d]", myRank_);
     142              : 
     143            0 :     CHK_RET(CalcParams(templateDataParams));
     144              : 
     145              :     // 单卡场景可以直接Input拷贝到Output,单独判断
     146            0 :     if (tempRankSize_ == 1) {
     147            0 :         CHK_RET(LocalCopyFromInputToOutput(templateDataParams, tempInsQues));
     148            0 :         return HcclResult::HCCL_SUCCESS;
     149              :     }
     150              : 
     151              :     // 将队列分为2组,一组负责X轴向通信,一组负责Y轴向通信,两组中的第一条流兼任控制流
     152            0 :     std::vector<InsQuePtr> ctrlTempInsQues;
     153            0 :     std::vector<InsQuePtr> xTempInsQues;
     154            0 :     std::vector<InsQuePtr> yTempInsQues;
     155            0 :     CHK_RET(SplitInsQues(tempInsQues, ctrlTempInsQues, xTempInsQues, yTempInsQues));
     156              : 
     157            0 :     CHK_RET(PreSyncInterQueues(ctrlTempInsQues)); // XY轴并行启动
     158              : 
     159            0 :     if (u32(myRank_) == root_) {
     160              :         // 数据片A第一步通信
     161            0 :         CHK_RET(GatherFromInput(SLICE_A, AXIS_X, tempLinks, xTempInsQues));
     162            0 :         CHK_RET(ReduceToScratch(SLICE_A, AXIS_X, xTempInsQues));
     163              :         // 数据片B第一步通信
     164            0 :         CHK_RET(GatherFromInput(SLICE_B, AXIS_Y, tempLinks, yTempInsQues));
     165            0 :         CHK_RET(ReduceToScratch(SLICE_B, AXIS_Y, yTempInsQues));
     166              :         // X轴和Y轴控制流同步,然后交换处理数据
     167            0 :         CHK_RET(PreSyncInterQueues(ctrlTempInsQues));
     168            0 :         CHK_RET(PostSyncInterQueues(ctrlTempInsQues));
     169              :         // 数据片A第二步通信
     170            0 :         CHK_RET(GatherFromScratch(SLICE_A, AXIS_Y, tempLinks, yTempInsQues));
     171            0 :         CHK_RET(ReduceToOutput(SLICE_A, AXIS_Y, yTempInsQues));
     172              :         // 数据片B第二步通信
     173            0 :         CHK_RET(GatherFromScratch(SLICE_B, AXIS_X, tempLinks, xTempInsQues));
     174            0 :         CHK_RET(ReduceToOutput(SLICE_B, AXIS_X, xTempInsQues));
     175            0 :     } else if (axisRank_[AXIS_X] == axisRoot_[AXIS_X]) {
     176              :         // 数据片A通信
     177            0 :         CHK_RET(GatherFromInput(SLICE_A, AXIS_X, tempLinks, xTempInsQues));
     178            0 :         CHK_RET(ReduceToScratch(SLICE_A, AXIS_X, xTempInsQues));
     179            0 :         CHK_RET(SendFromScratch(SLICE_A, AXIS_Y, tempLinks, xTempInsQues));
     180              :         // 数据片B通信
     181            0 :         CHK_RET(SendFromInput(SLICE_B, AXIS_Y, tempLinks, yTempInsQues));
     182            0 :     } else if (axisRank_[AXIS_Y] == axisRoot_[AXIS_Y]) {
     183              :         // 数据片A通信
     184            0 :         CHK_RET(SendFromInput(SLICE_A, AXIS_X, tempLinks, xTempInsQues));
     185              :         // 数据片B通信
     186            0 :         CHK_RET(GatherFromInput(SLICE_B, AXIS_Y, tempLinks, yTempInsQues));
     187            0 :         CHK_RET(ReduceToScratch(SLICE_B, AXIS_Y, yTempInsQues));
     188            0 :         CHK_RET(SendFromScratch(SLICE_B, AXIS_X, tempLinks, yTempInsQues));
     189              :     } else {
     190              :         // 数据片A通信
     191            0 :         CHK_RET(SendFromInput(SLICE_A, AXIS_X, tempLinks, xTempInsQues));
     192              :         // 数据片B通信
     193            0 :         CHK_RET(SendFromInput(SLICE_B, AXIS_Y, tempLinks, yTempInsQues));
     194              :     }
     195              : 
     196            0 :     CHK_RET(PostSyncInterQueues(ctrlTempInsQues)); // 返回主流
     197              : 
     198            0 :     HCCL_INFO("[InsTempReduceMesh2D] GenExtIns finished rank[%d]", myRank_);
     199              : 
     200            0 :     return HcclResult::HCCL_SUCCESS;
     201            0 : }
     202              : 
     203            0 : HcclResult InsTempReduceMesh2D::CalcParams(const TemplateDataParams& templateDataParams)
     204              : {
     205            0 :     axisRankSize_[AXIS_X] = tempVTopo_.at(AXIS_X).size();
     206            0 :     axisRankSize_[AXIS_Y] = tempVTopo_.at(AXIS_Y).size();
     207            0 :     axisRank_[AXIS_X] = u32(myRank_) % axisRankSize_[AXIS_X];
     208            0 :     axisRank_[AXIS_Y] = u32(myRank_) / axisRankSize_[AXIS_X];
     209            0 :     axisRoot_[AXIS_X] = root_ % axisRankSize_[AXIS_X];
     210            0 :     axisRoot_[AXIS_Y] = root_ / axisRankSize_[AXIS_X];
     211              : 
     212            0 :     u32 dataTypeSize = DataTypeSizeGet(dataType_);
     213              :     // 用count均分,防止数据截断;并且保证在奇数情况下SLICE_A的切分比SLICE_B大
     214            0 :     sliceSize_[SLICE_A] = (templateDataParams.sliceSize / dataTypeSize + 1) / SLICE_NUM * dataTypeSize;
     215            0 :     sliceSize_[SLICE_B] = templateDataParams.sliceSize - sliceSize_[SLICE_A];
     216              : 
     217            0 :     sliceInputBaseOffset_[SLICE_A] = templateDataParams.buffInfo.inBuffBaseOff;
     218            0 :     sliceInputBaseOffset_[SLICE_B] = sliceInputBaseOffset_[SLICE_A] + sliceSize_[SLICE_A];
     219              : 
     220            0 :     sliceOutputBaseOffset_[SLICE_A] = templateDataParams.buffInfo.outBuffBaseOff;
     221            0 :     sliceOutputBaseOffset_[SLICE_B] = sliceOutputBaseOffset_[SLICE_A] + sliceSize_[SLICE_A];
     222              : 
     223              :     // Scratch切分时,上下两部分都按照最大的轴向RankSize来切分,从而保证数据换轴通信时有足够的暂存Buffer来做确定性计算
     224            0 :     u32 maxAxisRankSize = max(axisRankSize_[AXIS_X], axisRankSize_[AXIS_Y]);
     225            0 :     sliceScratchBaseOffset_[SLICE_A] = templateDataParams.buffInfo.scratchBuffBaseOff;
     226            0 :     sliceScratchBaseOffset_[SLICE_B] = sliceScratchBaseOffset_[SLICE_A] + sliceSize_[SLICE_A] * maxAxisRankSize;
     227              : 
     228            0 :     return HcclResult::HCCL_SUCCESS;
     229              : }
     230              : 
     231            0 : HcclResult InsTempReduceMesh2D::SplitInsQues(
     232              :     std::vector<InsQuePtr>& tempInsQues, std::vector<InsQuePtr>& ctrlTempInsQues, std::vector<InsQuePtr>& xTempInsQues,
     233              :     std::vector<InsQuePtr>& yTempInsQues)
     234              : {
     235            0 :     u32 expectQueNum = axisRankSize_[AXIS_X] + axisRankSize_[AXIS_Y];
     236            0 :     CHK_PRT_RET(
     237              :         tempInsQues.size() != expectQueNum,
     238              :         HCCL_ERROR(
     239              :             "[InsTempReduceMesh2D] The count of queues is invalid, expect [%u], now is [%u]", expectQueNum,
     240              :             tempInsQues.size()),
     241              :         HcclResult::HCCL_E_INTERNAL);
     242              : 
     243            0 :     ctrlTempInsQues.emplace_back(tempInsQues.at(0));
     244            0 :     ctrlTempInsQues.emplace_back(tempInsQues.at(axisRankSize_[AXIS_X]));
     245            0 :     xTempInsQues = std::vector<InsQuePtr>(tempInsQues.begin(), tempInsQues.begin() + axisRankSize_[AXIS_X]);
     246            0 :     yTempInsQues = std::vector<InsQuePtr>(tempInsQues.begin() + axisRankSize_[AXIS_X], tempInsQues.end());
     247              : 
     248            0 :     HCCL_INFO(
     249              :         "[InsTempReduceMesh2D] splitInsQues success, ctrlTempInsQuesNum[%zu], xTempInsQuesNum[%zu], "
     250              :         "yTempInsQuesNum[%zu]",
     251              :         ctrlTempInsQues.size(), xTempInsQues.size(), yTempInsQues.size());
     252              : 
     253            0 :     return HcclResult::HCCL_SUCCESS;
     254              : }
     255              : 
     256            0 : HcclResult InsTempReduceMesh2D::LocalCopyFromInputToOutput(
     257              :     const TemplateDataParams& templateDataParams, std::vector<InsQuePtr>& tempInsQues) const
     258              : {
     259            0 :     DataSlice srcLocalSlice(BufferType::INPUT, 0, templateDataParams.sliceSize);
     260            0 :     DataSlice dstLocalSlice(BufferType::OUTPUT, 0, templateDataParams.sliceSize);
     261            0 :     CHK_PRT_RET(
     262              :         LocalCopy(tempInsQues[0], srcLocalSlice, dstLocalSlice),
     263              :         HCCL_ERROR("[InsTempReduceMesh2D] LocalCopy data failed"), HcclResult::HCCL_E_INTERNAL);
     264            0 :     return HcclResult::HCCL_SUCCESS;
     265              : }
     266              : 
     267            0 : HcclResult InsTempReduceMesh2D::GatherFromInput(
     268              :     const u32 slice, const u32 axis, const ResLinks& tempLinks, std::vector<InsQuePtr>& axisTempInsQues)
     269              : {
     270            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Gather from input start.");
     271              : 
     272            0 :     CHK_PRT_RET(
     273              :         axisTempInsQues.empty(), HCCL_ERROR("[InsTempReduceMesh2D][GatherFromInput] axisTempInsQues is empty."),
     274              :         HcclResult::HCCL_E_INTERNAL);
     275            0 :     CHK_PTR_NULL(axisTempInsQues[0]);
     276            0 :     u64 sliceSize = sliceSize_[slice];
     277            0 :     u64 sliceScratchBaseOffset = sliceScratchBaseOffset_[slice];
     278              : 
     279            0 :     DataSlice srcDataSlice(BufferType::INPUT, sliceInputBaseOffset_[slice], sliceSize);
     280              : 
     281            0 :     if (axisTempInsQues.size() > 1) {
     282            0 :         CHK_RET(PreSyncInterQueues(axisTempInsQues));
     283              :     }
     284              : 
     285              :     // 主队列本地拷贝,从Input拷贝到Scratch
     286            0 :     DataSlice dstLocalSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRoot_[axis] * sliceSize, sliceSize);
     287            0 :     CHK_PRT_RET(
     288              :         LocalCopy(axisTempInsQues[0], srcDataSlice, dstLocalSlice),
     289              :         HCCL_ERROR("[InsTempReduceMesh2D] LocalCopy data failed"), HcclResult::HCCL_E_INTERNAL);
     290              : 
     291              :     // 从队列负责接收来自其它rank的数据
     292            0 :     u32 queIdx = 1;
     293            0 :     for (u32 axisRank = 0; axisRank < tempVTopo_.at(axis).size(); ++axisRank) {
     294            0 :         RankId rmtRank = tempVTopo_.at(axis).at(axisRank);
     295            0 :         if (rmtRank == myRank_) {
     296            0 :             continue;
     297              :         }
     298              : 
     299            0 :         const LinkData& recvLink = tempLinks.at(rmtRank).at(0);
     300              :         // 按照发送rank的序号来计算接收数据存放的偏移
     301            0 :         DataSlice dstDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRank * sliceSize, sliceSize);
     302            0 :         SlicesList recvSlicesList({srcDataSlice}, {dstDataSlice});
     303            0 :         DataInfo recvInfo(recvLink, recvSlicesList);
     304            0 :         CHK_PRT_THROW(
     305              :             queIdx >= axisTempInsQues.size(),
     306              :             HCCL_ERROR(
     307              :                 "[InsTempReduceMesh2D] queIdx[%u] is bigger than axisTempInsQues size[%zu].", queIdx,
     308              :                 axisTempInsQues.size()),
     309              :             InvalidParamsException, "queIdx is invalid");
     310            0 :         CHK_PRT_RET(
     311              :             Recv(recvInfo, axisTempInsQues[queIdx], 0, true, DmaMode::PUT),
     312              :             HCCL_ERROR("[InsTempReduceMesh2D] Recv data failed"), HcclResult::HCCL_E_INTERNAL);
     313              : 
     314            0 :         queIdx++;
     315            0 :     }
     316              : 
     317            0 :     if (axisTempInsQues.size() > 1) {
     318            0 :         CHK_RET(PostSyncInterQueues(axisTempInsQues));
     319              :     }
     320              : 
     321            0 :     return HcclResult::HCCL_SUCCESS;
     322              : }
     323              : 
     324            0 : HcclResult InsTempReduceMesh2D::GatherFromScratch(
     325              :     const u32 slice, const u32 axis, const ResLinks& tempLinks, std::vector<InsQuePtr>& axisTempInsQues)
     326              : {
     327            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Gather from scratch start");
     328              : 
     329            0 :     u64 sliceSize = sliceSize_[slice];
     330            0 :     u64 sliceScratchBaseOffset = sliceScratchBaseOffset_[slice];
     331              : 
     332            0 :     DataSlice srcDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRoot_[axis] * sliceSize, sliceSize);
     333              : 
     334            0 :     if (axisTempInsQues.size() > 1) {
     335            0 :         CHK_RET(PreSyncInterQueues(axisTempInsQues));
     336              :     }
     337              : 
     338              :     // 主队列本地拷贝,从Scratch拷贝到Output
     339            0 :     DataSlice dstLocalSlice(BufferType::OUTPUT, sliceOutputBaseOffset_[slice], sliceSize);
     340            0 :     CHK_PRT_RET(
     341              :         LocalCopy(axisTempInsQues[0], srcDataSlice, dstLocalSlice),
     342              :         HCCL_ERROR("[InsTempReduceMesh2D] LocalCopy data failed"), HcclResult::HCCL_E_INTERNAL);
     343              : 
     344              :     // 从队列负责接收来自其它rank的数据
     345            0 :     u32 queIdx = 1;
     346            0 :     for (u32 axisRank = 0; axisRank < tempVTopo_.at(axis).size(); ++axisRank) {
     347            0 :         RankId rmtRank = tempVTopo_.at(axis).at(axisRank);
     348            0 :         if (rmtRank == myRank_) {
     349            0 :             continue;
     350              :         }
     351              : 
     352            0 :         const LinkData& recvLink = tempLinks.at(rmtRank).at(0);
     353              :         // 按照发送rank的序号来计算接收数据存放的偏移
     354            0 :         DataSlice dstDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRank * sliceSize, sliceSize);
     355            0 :         SlicesList recvSlicesList({srcDataSlice}, {dstDataSlice});
     356            0 :         DataInfo recvInfo(recvLink, recvSlicesList);
     357              : 
     358            0 :         CHK_PRT_RET(
     359              :             Recv(recvInfo, axisTempInsQues[queIdx], 0, true, DmaMode::PUT),
     360              :             HCCL_ERROR("[InsTempReduceMesh2D] Recv data failed"), HcclResult::HCCL_E_INTERNAL);
     361              : 
     362            0 :         queIdx++;
     363            0 :     }
     364              : 
     365            0 :     if (axisTempInsQues.size() > 1) {
     366            0 :         CHK_RET(PostSyncInterQueues(axisTempInsQues));
     367              :     }
     368              : 
     369            0 :     return HcclResult::HCCL_SUCCESS;
     370              : }
     371              : 
     372            0 : HcclResult InsTempReduceMesh2D::SendFromInput(
     373              :     const u32 slice, const u32 axis, const ResLinks& tempLinks, std::vector<InsQuePtr>& axisTempInsQues)
     374              : {
     375            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Send from input start");
     376              : 
     377            0 :     u64 sliceSize = sliceSize_[slice];
     378              : 
     379            0 :     RankId rmtRank = tempVTopo_.at(axis).at(axisRoot_[axis]);
     380            0 :     const LinkData& sendLink = tempLinks.at(rmtRank).at(0);
     381              : 
     382            0 :     DataSlice srcDataSlice(BufferType::INPUT, sliceInputBaseOffset_[slice], sliceSize);
     383              :     DataSlice dstDataSlice(
     384            0 :         BufferType::SCRATCH, sliceScratchBaseOffset_[slice] + axisRank_[axis] * sliceSize, sliceSize);
     385            0 :     SlicesList sendSlicesList({srcDataSlice}, {dstDataSlice});
     386            0 :     DataInfo sendInfo(sendLink, sendSlicesList);
     387              : 
     388            0 :     CHK_PRT_RET(
     389              :         Send(sendInfo, axisTempInsQues[0], 0, true, DmaMode::PUT), HCCL_ERROR("[InsTempReduceMesh2D] Send data failed"),
     390              :         HcclResult::HCCL_E_INTERNAL);
     391              : 
     392            0 :     return HcclResult::HCCL_SUCCESS;
     393            0 : }
     394              : 
     395            0 : HcclResult InsTempReduceMesh2D::SendFromScratch(
     396              :     const u32 slice, const u32 axis, const ResLinks& tempLinks, std::vector<InsQuePtr>& axisTempInsQues)
     397              : {
     398            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Send from scratch start");
     399              : 
     400            0 :     u64 sliceSize = sliceSize_[slice];
     401            0 :     u64 sliceScratchBaseOffset = sliceScratchBaseOffset_[slice];
     402              : 
     403            0 :     RankId rmtRank = tempVTopo_.at(axis).at(axisRoot_[axis]);
     404            0 :     const LinkData& sendLink = tempLinks.at(rmtRank).at(0);
     405              : 
     406            0 :     DataSlice srcDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRoot_[axis] * sliceSize, sliceSize);
     407            0 :     DataSlice dstDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRank_[axis] * sliceSize, sliceSize);
     408            0 :     SlicesList sendSlicesList({srcDataSlice}, {dstDataSlice});
     409            0 :     DataInfo sendInfo(sendLink, sendSlicesList);
     410              : 
     411            0 :     CHK_PRT_RET(
     412              :         Send(sendInfo, axisTempInsQues[0], 0, true, DmaMode::PUT), HCCL_ERROR("[InsTempReduceMesh2D] Send data failed"),
     413              :         HcclResult::HCCL_E_INTERNAL);
     414              : 
     415            0 :     return HcclResult::HCCL_SUCCESS;
     416            0 : }
     417              : 
     418              : HcclResult
     419            0 : InsTempReduceMesh2D::ReduceToScratch(const u32 slice, const u32 axis, std::vector<InsQuePtr>& axisTempInsQues)
     420              : {
     421            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Reduce to scratch start");
     422              : 
     423            0 :     u64 sliceSize = sliceSize_[slice];
     424            0 :     u64 sliceScratchBaseOffset = sliceScratchBaseOffset_[slice];
     425              : 
     426              :     // 数据规约到scratch时,下一步会交换处理另一片数据,因此数据规约至axisRoot_[1-axis]的偏移位置,便于后续数据搬运
     427            0 :     DataSlice dstDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + axisRoot_[1 - axis] * sliceSize, sliceSize);
     428              : 
     429              :     // 另一轴Root值大于等于当前轴的RankSize时,需要将数据规约至原本无数据的区域,需要先拷贝第一片数据
     430            0 :     bool needLocalCopy = axisRoot_[1 - axis] >= axisRankSize_[axis];
     431            0 :     if (needLocalCopy) {
     432            0 :         DataSlice srcLocalSlice(BufferType::SCRATCH, sliceScratchBaseOffset, sliceSize);
     433            0 :         CHK_PRT_RET(
     434              :             LocalCopy(axisTempInsQues[0], srcLocalSlice, dstDataSlice),
     435              :             HCCL_ERROR("[InsTempReduceMesh2D] LocalCopy data failed"), HcclResult::HCCL_E_INTERNAL);
     436              : 
     437            0 :         for (u32 sliceId = 1; sliceId < axisRankSize_[axis]; ++sliceId) {
     438            0 :             DataSlice srcDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + sliceId * sliceSize, sliceSize);
     439            0 :             CHK_PRT_RET(
     440              :                 LocalReduce(axisTempInsQues[0], srcDataSlice, dstDataSlice, dataType_, redOp_),
     441              :                 HCCL_ERROR("[InsTempReduceMesh2D] Local reduce data failed"), HcclResult::HCCL_E_INTERNAL);
     442              :         }
     443              : 
     444            0 :         return HcclResult::HCCL_SUCCESS;
     445              :     }
     446              : 
     447              :     // 另一轴Root值小于当前轴RankSize时,按照数据片顺序逐个Reduce
     448            0 :     for (u32 sliceId = 0; sliceId < axisRankSize_[axis]; ++sliceId) {
     449            0 :         if (sliceId == axisRoot_[1 - axis]) {
     450            0 :             continue;
     451              :         }
     452            0 :         DataSlice srcDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + sliceId * sliceSize, sliceSize);
     453            0 :         CHK_PRT_RET(
     454              :             LocalReduce(axisTempInsQues[0], srcDataSlice, dstDataSlice, dataType_, redOp_),
     455              :             HCCL_ERROR("[InsTempReduceMesh2D] Local reduce data failed"), HcclResult::HCCL_E_INTERNAL);
     456              :     }
     457              : 
     458            0 :     return HcclResult::HCCL_SUCCESS;
     459              : }
     460              : 
     461            0 : HcclResult InsTempReduceMesh2D::ReduceToOutput(const u32 slice, const u32 axis, std::vector<InsQuePtr>& axisTempInsQues)
     462              : {
     463            0 :     HCCL_DEBUG("[InsTempReduceMesh2D] Reduce to output start");
     464              : 
     465            0 :     u64 sliceSize = sliceSize_[slice];
     466            0 :     u64 sliceScratchBaseOffset = sliceScratchBaseOffset_[slice];
     467              : 
     468            0 :     DataSlice dstDataSlice(BufferType::OUTPUT, sliceOutputBaseOffset_[slice], sliceSize);
     469              : 
     470            0 :     for (u32 sliceId = 0; sliceId < axisRankSize_[axis]; ++sliceId) {
     471            0 :         if (sliceId == axisRoot_[axis]) { // 跳过轴向root的数据片,这一片已经提前拷贝至Output
     472            0 :             continue;
     473              :         }
     474            0 :         DataSlice srcDataSlice(BufferType::SCRATCH, sliceScratchBaseOffset + sliceId * sliceSize, sliceSize);
     475            0 :         CHK_PRT_RET(
     476              :             LocalReduce(axisTempInsQues[0], srcDataSlice, dstDataSlice, dataType_, redOp_),
     477              :             HCCL_ERROR("[InsTempReduceMesh2D] Local reduce data failed"), HcclResult::HCCL_E_INTERNAL);
     478              :     }
     479              : 
     480            0 :     return HcclResult::HCCL_SUCCESS;
     481              : }
     482              : 
     483              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1