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

Generated by: LCOV version 2.0-1