LCOV - code coverage report
Current view: top level - legacy/ascend910/algorithm/base/alg_template/temp_reduce_scatter - reduce_scatter_ring.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 2.9 % 278 8
Test Date: 2026-08-04 10:52:23 Functions: 25.0 % 16 4

            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 "reduce_scatter_ring.h"
      12              : #include "alg_template_register.h"
      13              : 
      14              : namespace hccl {
      15           34 : ReduceScatterRing::ReduceScatterRing(const HcclDispatcher dispatcher)
      16           34 :     : AlgTemplateBase(dispatcher)
      17              : {
      18           34 : }
      19              : 
      20           59 : ReduceScatterRing::~ReduceScatterRing()
      21              : {
      22           59 : }
      23              : 
      24           25 : HcclResult ReduceScatterRing::Prepare(u64 reduceAttrBitMap, HcomCollOpInfo *opInfo)
      25              : {
      26              :     (void)opInfo;
      27           25 :     reduceAttr_ = reduceAttrBitMap;
      28           25 :     return HCCL_SUCCESS;
      29              : }
      30              : 
      31            0 : HcclResult ReduceScatterRing::RunVectorSourceReducer(const LINK &link, const std::vector<Slice> &txSlices,
      32              :                                                      const std::vector<Slice> &txSlicetemp)
      33              : {
      34              :     /* 1、对外reduce_scatter,output的大小为每块数据*rank_size。只能发送到对端地址偏移为0开始。
      35              :       2、allreduce中使用reduce_scatter,output与Input大小相等,接收和发送偏移相等都为slice.offset */
      36            0 :     std::vector<SenderMemoryInfo> txMems;
      37            0 :     for (u32 i = 0; i < txSlices.size(); i++) {
      38            0 :         DeviceMem srcMem = inputMem_.range(txSlices[i].offset, txSlices[i].size);
      39            0 :         HCCL_DEBUG(" send inputmem range[%llu], size[%llu] tx dstmem offset[%llu]", txSlices[i].offset,
      40              :             txSlices[i].size, txSlicetemp[i].offset);
      41            0 :         txMems.emplace_back(SenderMemoryInfo{baseOffset_ + txSlicetemp[i].offset, srcMem});
      42            0 :     }
      43            0 :     CHK_RET(senderInfo_->run(link, txMems, stream_));
      44              : 
      45            0 :     return HCCL_SUCCESS;
      46            0 : }
      47              : 
      48            0 : HcclResult ReduceScatterRing::RunVectorDestRducer(const LINK &link, const std::vector<Slice> &rxSlices,
      49              :                                                   const std::vector<Slice> &rxSlicetemp)
      50              : {
      51            0 :     std::vector<ReducerMemoryInfo> rxReduceMems;
      52            0 :     for (u32 i = 0; i < rxSlices.size(); i++) {
      53            0 :         DeviceMem dstMem = inputMem_.range(rxSlices[i].offset, rxSlices[i].size);
      54            0 :         DeviceMem srcMemTemp = scratchMem_.range(rxSlicetemp[i].offset, rxSlicetemp[i].size);
      55            0 :         HCCL_DEBUG("rcv offset[%llu], size[%llu] ,then reduce with offset[%llu] size[%llu] ",
      56              :             rxSlicetemp[i].offset, rxSlicetemp[i].size, rxSlices[i].offset, rxSlices[i].size);
      57            0 :         rxReduceMems.emplace_back(ReducerMemoryInfo{baseOffset_ + rxSlices[i].offset, dstMem, dstMem, srcMemTemp});
      58            0 :     }
      59            0 :     CHK_RET(reducerInfo_->run(dispatcher_, link, rxReduceMems, stream_));
      60              : 
      61            0 :     return HCCL_SUCCESS;
      62            0 : }
      63              : 
      64            0 : HcclResult ReduceScatterRing::RunSourceReducer(const LINK &link, const Slice &txSlice, const Slice &txSlicetemp)
      65              : {
      66              :     /* 1、对外reduce_scatter,output的大小为每块数据*rank_size。只能发送到对端地址偏移为0开始。
      67              :       2、allreduce中使用reduce_scatter,output与Input大小相等,接收和发送偏移相等都为slice.offset */
      68            0 :     DeviceMem srcMem = inputMem_.range(txSlice.offset, txSlice.size);
      69            0 :     HCCL_DEBUG(" send inputmem range[%llu], size[%llu] tx dstmem offset[%llu]", txSlice.offset, txSlice.size,
      70              :         txSlicetemp.offset);
      71            0 :     CHK_RET(senderInfo_->run(link, baseOffset_ + txSlicetemp.offset, srcMem, stream_));
      72              : 
      73            0 :     return HCCL_SUCCESS;
      74            0 : }
      75              : 
      76            0 : HcclResult ReduceScatterRing::RunDestRducer(const LINK &link, const Slice &rxSlice, const Slice &rxSlicetemp)
      77              : {
      78            0 :     DeviceMem dstMem = inputMem_.range(rxSlice.offset, rxSlice.size);
      79            0 :     DeviceMem srcMemTemp = scratchMem_.range(rxSlicetemp.offset, rxSlicetemp.size);
      80            0 :     HCCL_DEBUG("rcv offset[%llu], size[%llu] ,then reduce with "
      81              :         "offset[%llu] size[%llu] ",
      82              :         rxSlicetemp.offset, rxSlicetemp.size, rxSlice.offset, rxSlice.size);
      83            0 :     CHK_RET(reducerInfo_->run(dispatcher_, link, baseOffset_ + rxSlice.offset, dstMem, dstMem, srcMemTemp, stream_));
      84              : 
      85            0 :     return HCCL_SUCCESS;
      86            0 : }
      87              : 
      88            0 : HcclResult ReduceScatterRing::RunAsync(const u32 rank, const u32 rankSize, const std::vector<LINK> &links)
      89              : {
      90              :     // 判断stream, dispatcher是否为空
      91            0 :     CHK_SMART_PTR_NULL(dispatcher_);
      92            0 :     CHK_PTR_NULL(stream_.ptr());
      93            0 :     if (!outputMem_ || !inputMem_) {
      94            0 :         HCCL_ERROR("[ReduceScatterRing][RunAsync]rank[%u] run_async inputmem or outputmem is null", rank);
      95            0 :         return HCCL_E_PTR;
      96              :     }
      97            0 :     HCCL_INFO("ReduceScatterRing run: rank[%u] ranksize[%u] inputMem[%p] outputMem[%p] count[%llu]",
      98              :         rank, rankSize, inputMem_.ptr(), outputMem_.ptr(), count_);
      99              : 
     100              :     // 判断rank_size == 1
     101            0 :     if (rankSize == 1) {
     102            0 :         if (inputMem_ != outputMem_) {
     103            0 :             return HcclD2DMemcpyAsync(dispatcher_, outputMem_, inputMem_, stream_);
     104              :         }
     105            0 :         HCCL_DEBUG("[ReduceScatterRing]rankSize is 1, RunAsync success");
     106            0 :         return HCCL_SUCCESS;
     107              :     }
     108              : 
     109              :     // 创建reducer & sender
     110            0 :     senderInfo_.reset(new (std::nothrow) Sender(dataType_, reductionOp_, reduceAttr_));
     111            0 :     CHK_SMART_PTR_NULL(senderInfo_);
     112              : 
     113            0 :     reducerInfo_.reset(new (std::nothrow) Reducer(dataType_, reductionOp_, reduceAttr_));
     114            0 :     CHK_SMART_PTR_NULL(reducerInfo_);
     115              : 
     116            0 :     if (links.size() < rankSize) {
     117            0 :         HCCL_ERROR("[ReduceScatterRing][RunAsync]rank[%u] link size[%llu] is less than rank size[%u]",
     118              :             rank, links.size(), rankSize);
     119            0 :         return HCCL_E_INTERNAL;
     120              :     }
     121              : 
     122            0 :     u32 ringPrevRank = (rank + rankSize - 1) % rankSize;
     123            0 :     linkLeft_ = links[ringPrevRank];
     124            0 :     CHK_SMART_PTR_NULL(linkLeft_);
     125              : 
     126            0 :     u32 ringNextRank = (rank + 1) % rankSize;
     127            0 :     HCCL_DEBUG("[ReduceScatterRing][RunAsync]ringPrevRank is %u, ringNextRank is %u", ringPrevRank, ringNextRank);
     128            0 :     linkRight_ = links[ringNextRank];
     129            0 :     CHK_SMART_PTR_NULL(linkRight_);
     130              : 
     131            0 :     u32 unitSize = DataUnitSize(dataType_);
     132            0 :     if (unitSize == 0) {
     133            0 :         HCCL_ERROR("[ReduceScatterRing][RunAsync]rank[%u] unit data size is zero", rank);
     134            0 :         return HCCL_E_INTERNAL;
     135              :     }
     136              : 
     137            0 :     std::vector<Slice> outputSlices(slices_);
     138              : 
     139            0 :     if (slices_.size() == 0) {
     140            0 :         slices_.resize(rankSize);
     141            0 :         outputSlices.resize(rankSize);
     142              : 
     143              :         // 生成std::vector<Slice> slices_
     144            0 :         u64 sliceSize = count_ * unitSize;
     145              : 
     146            0 :         for (u32 i = 0; i < rankSize; i++) {
     147            0 :             slices_[i].size = sliceSize;
     148            0 :             slices_[i].offset = (i * sliceSize);
     149              : 
     150            0 :             outputSlices[i].size = sliceSize;
     151            0 :             outputSlices[i].offset = (inputMem_.size() > outputMem_.size()) ? 0 : (i * sliceSize);
     152            0 :             HCCL_DEBUG("rank[%u], slices[%u].offset=[%llu], slices[%u].size=[%llu] outputSlices[%u].offset=[%llu], \
     153              :                 outputSlices[%u].size=[%llu] ", rank, i, slices_[i].offset, i, slices_[i].size, i, \
     154              :                        outputSlices[i].offset, i, outputSlices[i].size);
     155              :         }
     156              :     }
     157              : 
     158              :     // 运行reduce-scatter, ring算法
     159              :     // 单环场景下 nicRankList_ 长度默认为 8。
     160              :     // 多环场景下 nicRankList_ 长度为网口数量。此时若 rankSize != nicRankList_ 则为网口裁剪场景
     161            0 :     if (rankSize != HCCL_NIC_MAX_NUM || nicRankList_.size() == HCCL_NIC_MAX_NUM) {
     162              :         // 非网口裁剪场景:
     163            0 :         CHK_RET(RunReduceScatter(rank, rankSize, slices_, outputSlices));
     164              :     } else {
     165              :         // 网口裁剪场景:当前仅在 910A 8P_RING (4环),且网口不满配情况下使用
     166            0 :         CHK_RET(ReduceScatterSlicesPrep(rankSize, nicRankList_.size()));
     167              : 
     168            0 :         CHK_RET(RunReduceScatterChunk(rank, rankSize, slices_, outputSlices));
     169              :     }
     170              : 
     171            0 :     if (barrierSwitchOn_) {
     172              :         // 执行barrier,保证数据收发完成
     173            0 :         CHK_RET(ExecuteBarrier(linkLeft_, linkRight_));
     174              :     }
     175              : 
     176            0 :     HCCL_INFO("ReduceScatterRing finished: rank[%u]", rank);
     177            0 :     return HCCL_SUCCESS;
     178            0 : }
     179              : 
     180            0 : HcclResult ReduceScatterRing::RunReduceScatter(const u32 rank, const u32 rankSize,
     181              :                                                const std::vector<Slice> &inputSlices,
     182              :                                                const std::vector<Slice> &outputSlices)
     183              : {
     184            0 :     bool bRetSize = (inputSlices.size() < rankSize);
     185            0 :     CHK_PRT_RET(bRetSize,
     186              :         HCCL_ERROR("[Run][ReduceScatter]rank[%u] inputslice size[%llu] is less than rank size[%u]",
     187              :             rank, inputSlices.size(), rankSize), HCCL_E_INTERNAL);
     188              : 
     189            0 :     bRetSize = (outputSlices.size() < rankSize);
     190            0 :     HCCL_DEBUG("[Run][ReduceScatter]ReduceScatterRing for bRetSize is %d", bRetSize);
     191            0 :     CHK_PRT_RET(bRetSize,
     192              :         HCCL_ERROR("[Run][ReduceScatter]rank[%u] outputslice size[%llu] is less than rank size[%u]",
     193              :             rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     194              : 
     195            0 :     HcclResult ret = HCCL_SUCCESS;
     196              : 
     197            0 :     u32 sliceSize = inputSlices.size() / rankSize;
     198              : 
     199              :     // 获取rx_slice, 首先向本rank前2个rank处发ack消息
     200            0 :     u32 rxSliceIndex = (rank + rankSize - 2) % rankSize;
     201            0 :     HCCL_DEBUG("rank[%u] outputslice[%u] size[%llu] will tx_ack to left", rank, rxSliceIndex,
     202              :         outputSlices[rxSliceIndex].size);
     203              : 
     204            0 :     CHK_RET(linkLeft_->TxAck(stream_)); // NotifyRecord
     205              : 
     206              :     // reduce源操作, 获取tx_slice,从本rank前一rank开始接收ack
     207            0 :     u32 txSliceIndex = (rank + rankSize - 1) % rankSize;
     208            0 :     HCCL_DEBUG("rank[%u] inputSlices[%u] will rx_ack", rank, txSliceIndex);
     209              : 
     210            0 :     CHK_RET(linkRight_->RxAck(stream_)); // NotifyWait
     211              : 
     212            0 :     std::vector<Slice> txInputSegsSlice;
     213            0 :     std::vector<Slice> txOutputSegsSlice;
     214            0 :     for (u32 j = 0; j < sliceSize; j++) {
     215            0 :         txInputSegsSlice.push_back(inputSlices[txSliceIndex * sliceSize + j]);
     216            0 :         txOutputSegsSlice.push_back(outputSlices[txSliceIndex * sliceSize + j]);
     217              :     }
     218            0 :     ret = RunVectorSourceReducer(linkRight_, txInputSegsSlice, txOutputSegsSlice); // NotifyRecord
     219            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS,
     220              :         HCCL_ERROR("[Run][ReduceScatter]rank[%u] txSliceIndex[%u] Reducer src run failed.", rank, txSliceIndex), ret);
     221              : 
     222              :     // 本rank既当reduce源, 也当reduce操作的目的
     223            0 :     for (u32 i = 0; i < (rankSize - 2); i++) { // 中间rank_size - 2次传输
     224              :         // reduce目的操作
     225            0 :         HCCL_DEBUG("rank[%u] round[%u] use sliceindex[%u] inputSlicesoffset[%llu] "
     226              :             "size[%llu] outputSlices offset[%llu] rcv and reduce",
     227              :             rank, i, rxSliceIndex, inputSlices[rxSliceIndex].offset, inputSlices[rxSliceIndex].size,
     228              :             outputSlices[rxSliceIndex].offset);
     229              : 
     230            0 :         std::vector<Slice> rxInputSegsSlice;
     231            0 :         std::vector<Slice> rxOutputSegsSlice;
     232            0 :         HCCL_DEBUG("[ReduceScatterRing]RunReduceScatter for sliceSize is %u", sliceSize);
     233            0 :         for (u32 j = 0; j < sliceSize; j++) {
     234            0 :             rxInputSegsSlice.push_back(inputSlices[rxSliceIndex * sliceSize + j]);
     235            0 :             rxOutputSegsSlice.push_back(outputSlices[rxSliceIndex * sliceSize + j]);
     236              :         }
     237            0 :         ret = RunVectorDestRducer(linkLeft_, rxInputSegsSlice, rxOutputSegsSlice);
     238              : 
     239            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     240              :             HCCL_ERROR("[Run][ReduceScatter]rank[%u] round[%u] rxSlice[%u] Reducer dst run failed", rank, i,
     241              :             rxSliceIndex),
     242              :             ret);
     243              : 
     244            0 :         ret = linkLeft_->RxWaitDone(stream_);
     245            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Run][ReduceScatter]RxWaitDone failed"), ret);
     246            0 :         ret = linkRight_->TxWaitDone(stream_);
     247            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Run][ReduceScatter]TxWaitDone failed"), ret);
     248              : 
     249              :         // 获取rx_slice
     250            0 :         rxSliceIndex = (rxSliceIndex + rankSize - 1) % rankSize;
     251              : 
     252            0 :         HCCL_DEBUG("rank[%u] round[%u] outputslice[%u] will tx_ack ", rank, i, rxSliceIndex);
     253            0 :         ret = linkLeft_->TxAck(stream_);
     254            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Run][ReduceScatter]rank[%u] round[%u] tx ack failed", rank, i),
     255              :             ret);
     256              : 
     257              :         // reduce源操作, 获取tx_slice
     258            0 :         txSliceIndex = (txSliceIndex + rankSize - 1) % rankSize;
     259            0 :         HCCL_DEBUG("rank[%u] round[%u] use sliceindex[%u] rx ack ", rank, i, txSliceIndex);
     260            0 :         ret = linkRight_->RxAck(stream_);
     261            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     262              :             HCCL_ERROR("[Run][ReduceScatter]rank[%u] round[%u] rx ack run failed", rank, i), ret);
     263              : 
     264            0 :         std::vector<Slice> txInputSegsSlice;
     265            0 :         std::vector<Slice> txOutputSegsSlice;
     266            0 :         for (u32 j = 0; j < sliceSize; j++) {
     267            0 :             txInputSegsSlice.push_back(inputSlices[txSliceIndex * sliceSize + j]);
     268            0 :             txOutputSegsSlice.push_back(outputSlices[txSliceIndex * sliceSize + j]);
     269              :         }
     270            0 :         ret = RunVectorSourceReducer(linkRight_, txInputSegsSlice, txOutputSegsSlice);
     271            0 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     272              :             HCCL_ERROR("[Run][ReduceScatter]rank[%u] round[%u] Reducer src run failed", rank, i), ret);
     273            0 :     }
     274              : 
     275              :     /* * 末尾传输, 本rank只当reduce目的, 根据单buffer还是双buffer来决定如何搬移
     276              :         当前简化处理, 只考虑单buffer的场景, 双buffer则在run_async中多拷贝一次 */
     277            0 :     std::vector<ReducerMemoryInfo> rxReduceMems;
     278            0 :     for (u32 i = 0; i < sliceSize; i++) {
     279              :         DeviceMem dstMem =
     280            0 :             outputMem_.range(outputSlices[rank * sliceSize + i].offset, outputSlices[rank * sliceSize + i].size);
     281              :         // reduce目的操作
     282              :         DeviceMem srcMem =
     283            0 :             inputMem_.range(inputSlices[rank * sliceSize + i].offset, inputSlices[rank * sliceSize + i].size);
     284              :         DeviceMem scratchMem =
     285            0 :             scratchMem_.range(outputSlices[rank * sliceSize + i].offset, outputSlices[rank * sliceSize + i].size);
     286            0 :         HCCL_DEBUG("final reduce rank[%u] reduce with inputMem_ offset[%llu] to ouput_mem_ offset[%llu] size[%llu]",
     287              :             rank, inputSlices[rank * sliceSize + i].offset, outputSlices[rank * sliceSize + i].offset,
     288              :             outputSlices[rank * sliceSize + i].size);
     289            0 :         rxReduceMems.emplace_back(ReducerMemoryInfo{baseOffset_ + inputSlices[rank * sliceSize + i].offset,
     290              :             srcMem, dstMem, scratchMem});
     291            0 :     }
     292            0 :     CHK_RET(reducerInfo_->run(dispatcher_, linkLeft_, rxReduceMems, stream_));
     293              : 
     294            0 :     ret = linkLeft_->RxWaitDone(stream_);
     295            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Run][ReduceScatter]RxWaitDone failed"), ret);
     296            0 :     ret = linkRight_->TxWaitDone(stream_);
     297            0 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Run][ReduceScatter]TxWaitDone failed"), ret);
     298              : 
     299            0 :     return HCCL_SUCCESS;
     300            0 : }
     301              : 
     302            0 : HcclResult ReduceScatterRing::RunReduceScatterChunk(const u32 rank, const u32 rankSize,
     303              :     const std::vector<Slice> &inputSlices, const std::vector<Slice> &outputSlices)
     304              : {
     305            0 :     bool bRetSize = (inputSlices.size() < rankSize);
     306            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[Run][ReduceScatterChunk]rank[%u] inputslice size[%llu] is less than rank "\
     307              :         "size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     308              : 
     309            0 :     bRetSize = (outputSlices.size() < rankSize);
     310            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[Run][ReduceScatterChunk]rank[%u] outputslice size[%llu] is less than rank "\
     311              :         "size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     312              : 
     313              :     HcclResult ret;
     314            0 :     u32 sendSliceLen = rankSliceLists_[rank].size();
     315            0 :     u32 chunkSize = HCCL_NIC_MAX_NUM / nicRankList_.size();
     316            0 :     if (sendSliceLen >= chunkSize) {
     317            0 :         CHK_RET(HeadReduceScatterChunk(rank, rankSize, inputSlices, outputSlices));
     318            0 :         for (u32 midRankIdx = 1; midRankIdx < sendSliceLen - 1; midRankIdx++) {
     319            0 :             ret = MidReduceScatterChunk(rank, rankSize, midRankIdx, inputSlices, outputSlices);
     320            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     321              :                 HCCL_ERROR("[Run][ReduceScatterChunk]rank[%u] run mid[%u] ReduceScatter chunk failed",
     322              :                     rank, midRankIdx), HCCL_E_INTERNAL);
     323              :         }
     324              :     }
     325            0 :     CHK_RET(TailReduceScatterChunk(rank, rankSize, sendSliceLen - 1, inputSlices, outputSlices));
     326            0 :     std::vector<u32>::iterator iterNic = std::find(nicRankList_.begin(), nicRankList_.end(), rank);
     327            0 :     if (iterNic != nicRankList_.end()) {
     328            0 :         u32 nicIdx = distance(nicRankList_.begin(), iterNic);
     329            0 :         u32 rxSliceIndex = nicIdx * chunkSize;
     330            0 :         if (outputSlices[rxSliceIndex].size > 0) {
     331            0 :             ret = RunDestRducer(linkLeft_, inputSlices[rxSliceIndex], outputSlices[rxSliceIndex]);
     332            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     333              :                 HCCL_ERROR("[Run][ReduceScatterChunk]rank[%u] rxSlice[%u] Reducer dst run "\
     334              :                     "failed", rank, rxSliceIndex), ret);
     335              :         }
     336            0 :         for (u32 chunkIdx = 1; chunkIdx < chunkSize; chunkIdx++) {
     337            0 :             rxSliceIndex = nicIdx * chunkSize + chunkIdx;
     338            0 :             if (outputSlices[rxSliceIndex].size > 0) {
     339            0 :                 CHK_RET(linkLeft_->TxAck(stream_));
     340              : 
     341            0 :                 ret = RunDestRducer(linkLeft_, inputSlices[rxSliceIndex], outputSlices[rxSliceIndex]);
     342            0 :                 CHK_PRT_RET(ret != HCCL_SUCCESS,
     343              :                     HCCL_ERROR("[Run][ReduceScatterChunk]rank[%u] rxSlice[%u] Reducer dst "\
     344              :                         "run failed", rank, rxSliceIndex), ret);
     345              :             }
     346              :         }
     347              :     }
     348            0 :     return HCCL_SUCCESS;
     349              : }
     350              : 
     351            0 : HcclResult ReduceScatterRing::HeadReduceScatterChunk(u32 rank, u32 rankSize, const std::vector<Slice> &inputSlices,
     352              :                                                      const std::vector<Slice> &outputSlices)
     353              : {
     354            0 :     bool bRetSize = (inputSlices.size() < rankSize);
     355            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][HeadReduceScatterChunk]rank[%u] inputslice size[%llu] is "\
     356              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     357              : 
     358            0 :     bRetSize = (outputSlices.size() < rankSize);
     359            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][HeadReduceScatterChunk]rank[%u] outputslice size[%llu] is "\
     360              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     361              : 
     362            0 :     u32 rxSliceIndex = rankSliceLists_[rank][0];
     363            0 :     u32 txSliceIndex = rxSliceIndex;
     364            0 :     std::vector<u32> preRankSlices(rankSliceLists_[(rank - 1 + rankSize) % rankSize]);
     365            0 :     std::vector<u32>::iterator iterSlice = std::find(preRankSlices.begin(), preRankSlices.end(), rxSliceIndex);
     366            0 :     if (iterSlice != preRankSlices.end()) {
     367            0 :         if (outputSlices[rxSliceIndex].size > 0) {
     368            0 :             CHK_RET(linkLeft_->TxAck(stream_));
     369              : 
     370            0 :             HcclResult ret = RunDestRducer(linkLeft_, inputSlices[rxSliceIndex], outputSlices[rxSliceIndex]);
     371            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     372              :                 HCCL_ERROR("[ReduceScatterRing][HeadReduceScatterChunk]rank[%u] rxSlice[%u] "\
     373              :                 "Reducer dst run failed", rank, rxSliceIndex), ret);
     374              :         }
     375              :     }
     376            0 :     iterSlice = std::find(preRankSlices.begin(), preRankSlices.end(), rankSliceLists_[rank][1]);
     377            0 :     if (iterSlice != preRankSlices.end()) {
     378            0 :         CHK_RET(MidReduceScatterChunk(rank, rankSize, 0, inputSlices, outputSlices));
     379              :     } else {
     380            0 :         if (inputSlices[txSliceIndex].size > 0) {
     381            0 :             CHK_RET(linkRight_->RxAck(stream_));
     382              : 
     383            0 :             CHK_RET(RunSourceReducer(linkRight_, inputSlices[txSliceIndex], outputSlices[txSliceIndex]));
     384              :         }
     385              :     }
     386            0 :     return HCCL_SUCCESS;
     387            0 : }
     388              : 
     389            0 : HcclResult ReduceScatterRing::MidReduceScatterChunk(u32 rank, u32 rankSize, u32 sliceIdx,
     390              :     const std::vector<Slice> &inputSlices, const std::vector<Slice> &outputSlices)
     391              : {
     392            0 :     bool bRetSize = (inputSlices.size() < rankSize);
     393            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][MidReduceScatterChunk]rank[%u] inputslice size[%llu] is "\
     394              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     395              : 
     396            0 :     bRetSize = (outputSlices.size() < rankSize);
     397            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][MidReduceScatterChunk]rank[%u] outputslice size[%llu] is "\
     398              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     399              : 
     400              :     HcclResult ret;
     401            0 :     u32 rxSliceIndex = rankSliceLists_[rank][sliceIdx + 1];
     402            0 :     u32 txSliceIndex = rankSliceLists_[rank][sliceIdx];
     403            0 :     std::vector<u32> preRankSlices(rankSliceLists_[(rank - 1 + rankSize) % rankSize]);
     404            0 :     std::vector<u32>::iterator iterSlice = std::find(preRankSlices.begin(), preRankSlices.end(), rxSliceIndex);
     405            0 :     if (iterSlice != preRankSlices.end()) {
     406            0 :         if (outputSlices[rxSliceIndex].size > 0) {
     407            0 :             CHK_RET(linkLeft_->TxAck(stream_));
     408              :         }
     409            0 :         if (inputSlices[txSliceIndex].size > 0) {
     410            0 :             CHK_RET(linkRight_->RxAck(stream_));
     411              : 
     412            0 :             CHK_RET(RunSourceReducer(linkRight_, inputSlices[txSliceIndex], outputSlices[txSliceIndex]));
     413              :         }
     414            0 :         if (outputSlices[rxSliceIndex].size > 0) {
     415            0 :             ret = RunDestRducer(linkLeft_, inputSlices[rxSliceIndex], outputSlices[rxSliceIndex]);
     416            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     417              :                 HCCL_ERROR("[ReduceScatterRing][MidReduceScatterChunk]rank[%u] rxSlice[%u] "\
     418              :                     "Reducer dst run failed", rank, rxSliceIndex), ret);
     419              :         }
     420              :     } else {
     421            0 :         if (inputSlices[txSliceIndex].size > 0) {
     422            0 :             CHK_RET(linkRight_->RxAck(stream_));
     423              : 
     424            0 :             CHK_RET(RunSourceReducer(linkRight_, inputSlices[txSliceIndex], outputSlices[txSliceIndex]));
     425              :         }
     426              :     }
     427            0 :     return HCCL_SUCCESS;
     428            0 : }
     429              : 
     430            0 : HcclResult ReduceScatterRing::TailReduceScatterChunk(u32 rank, u32 rankSize, u32 sliceIdx,
     431              :     const std::vector<Slice> &inputSlices, const std::vector<Slice> &outputSlices)
     432              : {
     433            0 :     bool bRetSize = (inputSlices.size() < rankSize);
     434            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][TailReduceScatterChunk]rank[%u] inputslice size[%llu] is "\
     435              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     436              : 
     437            0 :     bRetSize = (outputSlices.size() < rankSize);
     438            0 :     CHK_PRT_RET(bRetSize, HCCL_ERROR("[ReduceScatterRing][TailReduceScatterChunk]rank[%u] outputslice size[%llu] is "\
     439              :         "less than rank size[%u]", rank, outputSlices.size(), rankSize), HCCL_E_INTERNAL);
     440              : 
     441            0 :     std::vector<u32> preRankSlices(rankSliceLists_[(rank - 1 + rankSize) % rankSize]);
     442            0 :     std::vector<u32>::iterator iterNic = std::find(nicRankList_.begin(), nicRankList_.end(), rank);
     443            0 :     if (iterNic != nicRankList_.end()) {
     444            0 :         u32 nicIdx = distance(nicRankList_.begin(), iterNic);
     445            0 :         u32 rxSliceIndex = HCCL_NIC_MAX_NUM / nicRankList_.size() * nicIdx;
     446            0 :         if (outputSlices[rxSliceIndex].size > 0) {
     447            0 :             CHK_RET(linkLeft_->TxAck(stream_));
     448              :         }
     449              :     }
     450            0 :     if (rankSliceLists_[rank].size() > 0) {
     451            0 :         u32 txSliceIndex = rankSliceLists_[rank][sliceIdx];
     452            0 :         if (inputSlices[txSliceIndex].size > 0) {
     453            0 :             CHK_RET(linkRight_->RxAck(stream_));
     454              : 
     455            0 :             CHK_RET(RunSourceReducer(linkRight_, inputSlices[txSliceIndex], outputSlices[txSliceIndex]));
     456              :         }
     457              :     }
     458            0 :     return HCCL_SUCCESS;
     459            0 : }
     460              : 
     461            0 : HcclResult ReduceScatterRing::ReduceScatterSlicesPrep(u32 rankSize, u32 nicSize)
     462              : {
     463            0 :     u32 chunkSize = HCCL_NIC_MAX_NUM / nicSize;
     464            0 :     for (u32 rankIdx = 0; rankIdx < rankSize; rankIdx++) {
     465            0 :         std::vector<u32> sliceList;
     466            0 :         for (u32 nicDis = 1; nicDis < rankSize; nicDis++) {
     467            0 :             std::vector<u32>::iterator iterNic;
     468            0 :             u32 nicIdx = (rankIdx + rankSize - nicDis) % rankSize;
     469            0 :             iterNic = std::find(nicRankList_.begin(), nicRankList_.end(), nicIdx);
     470            0 :             if (iterNic != nicRankList_.end()) {
     471            0 :                 u32 nicListIdx = distance(nicRankList_.begin(), iterNic);
     472            0 :                 for (u32 chunkIdx = 0; chunkIdx < chunkSize; chunkIdx++) {
     473            0 :                     sliceList.push_back(chunkSize * nicListIdx + chunkIdx);
     474              :                 }
     475              :             }
     476              :         }
     477            0 :         rankSliceLists_.push_back(sliceList);
     478            0 :     }
     479            0 :     HCCL_DEBUG("[ReduceScatterRing]ReduceScatterSlicesPrep success");
     480            0 :     return HCCL_SUCCESS;
     481              : }
     482              : 
     483            0 : HcclResult ReduceScatterRing::GetNslbAdjInfo(const u32 rank, const u32 rankSize,
     484              :                                              const std::vector<LINK> &links, AdjInfo& nslbAdjInfo)
     485              : {
     486            0 :     u32 ringNextRank = (rank + 1) % rankSize;
     487            0 :     LINK nslbNext = links[ringNextRank];
     488            0 :     if (nslbAdjInfo.nsAdjInfo.size() > 0) {
     489            0 :         nslbAdjInfo.nsAdjInfo[0].dstLocalRankId = (rank + 1) % rankSize;
     490              :     } else {
     491            0 :         NslbDpAdjInfo adjInfoStep = {0};
     492            0 :         nslbAdjInfo.dstRankNum = 1;
     493            0 :         adjInfoStep.dstLocalRankId = nslbNext->GetRemoteRank();
     494            0 :         adjInfoStep.phaseId = 1;
     495            0 :         adjInfoStep.rev = 0;
     496            0 :         nslbAdjInfo.nsAdjInfo.push_back(adjInfoStep);
     497              :     }
     498            0 :     return HCCL_SUCCESS;
     499            0 : }
     500              : 
     501              : REGISTER_TEMPLATE(TemplateType::TEMPLATE_REDUCESCATTER_RING, ReduceScatterRing);
     502              : }  // namespace hccl
        

Generated by: LCOV version 2.0-1