LCOV - code coverage report
Current view: top level - legacy/ascend950/service/collective/alg/coll_alg_factory/alg_ccu_context/scatter - ccu_context_scatter_mesh2d.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 295 0
Test Date: 2026-08-18 17:47:01 Functions: 0.0 % 21 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 "ccu_context_scatter_mesh2d.h"
      12              : #include "ccu_instruction_scatter_mesh2d.h"
      13              : 
      14              : namespace Hccl {
      15              : 
      16              : constexpr int VAR_IDX_0 = 0; // transport远端变量,一个transport当前最多只能有3个Var
      17              : constexpr int VAR_IDX_1 = 1;
      18              : constexpr int VAR_IDX_2 = 2;
      19              : constexpr int CKE_IDX_0 = 0; // 专门给后同步使用
      20              : constexpr int CKE_IDX_1 = 1; // 前同步使用
      21              : constexpr int CKE_IDX_2 = 2; // 前同步使用
      22              : constexpr int CKE_IDX_3 = 3; // 前同步使用
      23              : constexpr int CKE_AXIS = 4;  // 给die间同步使用
      24              : constexpr int DIM_NUM = 2;
      25              : constexpr int ZERO = 0;
      26              : constexpr int DIM_X = 0;
      27              : constexpr int DIM_Y = 1;
      28              : 
      29            0 : CcuContextScatterMesh2D::CcuContextScatterMesh2D(
      30            0 :     const CcuCtxArg& arg, const std::vector<CcuTransport*>& transports, const CcuTransportGroup& group)
      31            0 :     : CcuContextAlgBase(arg, transports, group)
      32              : {
      33            0 :     const CcuCtxArgScatterMesh2D* ctxArg = dynamic_cast<const CcuCtxArgScatterMesh2D*>(&arg);
      34            0 :     if (ctxArg == nullptr) {
      35            0 :         THROW<NullPtrException>(StringFormat("CcuContextScatterMesh2D::ctxArg ptr is null"));
      36              :     }
      37            0 :     rankId_ = ctxArg->rankId_;
      38            0 :     dimSize_ = ctxArg->dimSize_; // vector, dimSize_[0]表示X轴的rank数,dimSize_[1]表示Y轴的rank数
      39            0 :     axisId_ = ctxArg->axisId_;   // 由外部传入,指明当前在X轴或者Y轴的CCU上
      40            0 :     rankSize_ = ctxArg->rankSize_;
      41            0 :     root_ = ctxArg->root_;
      42              :     // 参数校验
      43            0 :     if (transports.size() == 0) {
      44            0 :         THROW<NullPtrException>(StringFormat("CcuContextScatterMesh2D transports is empty"));
      45              :     }
      46            0 :     if (dimSize_.size() != DIM_NUM || dimSize_[0] == ZERO || dimSize_[1] == ZERO || rankSize_ == ZERO
      47            0 :         || axisId_ >= DIM_NUM) {
      48            0 :         THROW<NullPtrException>(StringFormat("[CcuContextScatterMesh2D]ctxArg params is invalid"));
      49              :     }
      50              : 
      51              :     // 分解出当前Rank的行列坐标
      52            0 :     dimId_.emplace_back(rankId_ % dimSize_[0]); // dimId_[0]表示在X轴1Dmesh拓扑中的localId
      53            0 :     dimId_.emplace_back(rankId_ / dimSize_[0]); // dimId_[1]表示在Y轴1Dmesh拓扑中的localId
      54              : 
      55              :     // 分解出Root的行列坐标
      56            0 :     rootDimId_.emplace_back(root_ % dimSize_[0]);
      57            0 :     rootDimId_.emplace_back(root_ / dimSize_[0]);
      58              : 
      59            0 :     localId_ = dimId_[axisId_];
      60            0 :     localSize_ = dimSize_[axisId_];
      61              : 
      62            0 :     localAxisSignal_ = CreateMaskSignal();
      63              : 
      64            0 :     localAxisSignalName_ = "CcuContextScatter2DAxisSync_" + std::to_string(axisId_);
      65            0 :     anotherAxisSignalName_ = "CcuContextScatter2DAxisSync_" + std::to_string(1 - axisId_);
      66              : 
      67            0 :     HCCL_INFO(
      68              :         "[ContextScatter2DMesh.init] rankId_[%llu], dimSize_[0][%llu], dimSize_[1][%llu], axisId_[%llu], "
      69              :         "root_[%llu], localId_[%llu], localSize_[%llu] ",
      70              :         rankId_, dimSize_[0], dimSize_[1], axisId_, root_, localId_, localSize_);
      71            0 : }
      72              : 
      73            0 : bool CcuContextScatterMesh2D::SameRowWithRoot()
      74              : {
      75            0 :     bool directConnected = false;
      76            0 :     if (dimId_[DIM_Y] == rootDimId_[DIM_Y]) {
      77            0 :         directConnected = true;
      78              :     }
      79            0 :     return directConnected;
      80              : }
      81              : 
      82            0 : bool CcuContextScatterMesh2D::SameColumnWithRoot()
      83              : {
      84            0 :     bool directConnected = false;
      85            0 :     if (dimId_[DIM_X] == rootDimId_[DIM_X]) {
      86            0 :         directConnected = true;
      87              :     }
      88            0 :     return directConnected;
      89              : }
      90              : 
      91            0 : void CcuContextScatterMesh2D::PrepareVariables()
      92              : {
      93            0 :     u32 transportId = 0;
      94            0 :     CHK_PRT_RET(
      95              :         transports.size() < localSize_,
      96              :         HCCL_ERROR("[CcuContextScatterMesh2D] transports size is less than localSize"), );
      97            0 :     input_ = CreateVariable();
      98            0 :     sliceSize_ = CreateVariable();
      99            0 :     stride_ = CreateVariable();
     100            0 :     for (u64 id = 0; id < localSize_; id++) {
     101            0 :         if (id == localId_) {
     102            0 :             scratch_.push_back(CreateVariable());
     103            0 :             output_.push_back(CreateVariable());
     104            0 :             token_.push_back(CreateVariable());
     105              :         } else { // 非本地,使用远端Variable
     106            0 :             CHK_PRT_RET(
     107              :                 transports[transportId] == nullptr,
     108              :                 HCCL_ERROR("[CcuContextScatterMesh2D] Algorithm transport ptr is null"), );
     109            0 :             scratch_.push_back(CreateVariable((*transports[transportId]), VAR_IDX_0));
     110            0 :             output_.push_back(CreateVariable((*transports[transportId]), VAR_IDX_1));
     111            0 :             token_.push_back(CreateVariable((*transports[transportId]), VAR_IDX_2));
     112            0 :             transportId++;
     113              :         }
     114              :     }
     115            0 :     axisSliceSize_.push_back(CreateVariable());
     116            0 :     axisSliceSize_.push_back(CreateVariable());
     117              : 
     118            0 :     ExportMaskSignal(localAxisSignal_, localAxisSignalName_);      // 将本地的信号export出去
     119            0 :     anotherAxisSignal_ = ImportMaskSignal(anotherAxisSignalName_); // 导入另一个die的mask信号
     120            0 :     curGoSize_ = CreateGroupOpSize();
     121            0 :     return;
     122              : }
     123              : 
     124            0 : void CcuContextScatterMesh2D::LoadArgs()
     125              : {
     126              :     // 模板中的可变入参
     127              :     // 地址相关参数:input_,output_,scratch_, token_
     128              :     // 数据相关参数:sliceSize_, stride_,  axisSliceSize_ (axisSliceSize[DIM_X]为slice中通过x轴先传输的部分)
     129              :     // 顺序:inputAddr, outputAddr, scratchAddr, tokenInfo, sliceSize, stride, xSliceSize, ySliceSize
     130            0 :     Load(input_);
     131            0 :     Load(output_[localId_]);
     132            0 :     Load(token_[localId_]);
     133            0 :     Load(scratch_[localId_]);
     134            0 :     Load(sliceSize_);
     135            0 :     Load(stride_);
     136            0 :     Load(axisSliceSize_[DIM_X]);
     137            0 :     Load(axisSliceSize_[DIM_Y]);
     138            0 :     Load(curGoSize_);
     139            0 :     return;
     140              : }
     141              : 
     142            0 : void CcuContextScatterMesh2D::PreSync()
     143              : {
     144            0 :     uint16_t selfBit = 1 << localId_; // 本rank的mask
     145            0 :     uint16_t allBit = ((1 << localSize_) - 1) & (~(1 << localId_));
     146              : 
     147            0 :     for (auto t : transports) {
     148            0 :         if (t == nullptr) {
     149            0 :             THROW<NullPtrException>(StringFormat("CcuContextScatterMesh2D::PreSync, transport ptr is null"));
     150              :         }
     151            0 :         WriteVariableWithSignal(
     152            0 :             *t, scratch_[localId_], VAR_IDX_0, CKE_IDX_1,
     153              :             selfBit); // 传递CCLBuf信息, 把自己的CCLbuf给所有对端
     154            0 :         WriteVariableWithSignal(*t, output_[localId_], VAR_IDX_1, CKE_IDX_2, selfBit); // 传递output信息
     155            0 :         WriteVariableWithSignal(*t, token_[localId_], VAR_IDX_2, CKE_IDX_3, selfBit);  // 传递token信息
     156              :     }
     157              : 
     158            0 :     GroupWait(*transportGroup, CKE_IDX_1, allBit); // 等齐所有对端的信息
     159            0 :     GroupWait(*transportGroup, CKE_IDX_2, allBit);
     160            0 :     GroupWait(*transportGroup, CKE_IDX_3, allBit);
     161            0 :     return;
     162              : }
     163              : 
     164            0 : void CcuContextScatterMesh2D::Sync(uint32_t ckeId)
     165              : {
     166            0 :     uint16_t selfBit = 1 << localId_; // 本rank的mask
     167            0 :     uint16_t allBit = ((1 << localSize_) - 1) & (~(1 << localId_));
     168              : 
     169            0 :     for (auto t : transports) {
     170            0 :         if (t == nullptr) {
     171            0 :             THROW<NullPtrException>(StringFormat("CcuContextScatterMesh2D::PostSync, transport ptr is null"));
     172              :         }
     173            0 :         RemotePost(*t, ckeId, selfBit);
     174              :     }
     175              : 
     176            0 :     GroupWait(*transportGroup, ckeId, allBit);
     177            0 :     return;
     178              : }
     179              : 
     180            0 : void CcuContextScatterMesh2D::AxisSync(uint32_t signalIndex)
     181              : {
     182            0 :     if (signalIndex > 1) {
     183            0 :         THROW<InvalidParamsException>(StringFormat("[CcuContextScatterMesh2D] Unexpected SignalInex[%u]", signalIndex));
     184              :     }
     185            0 :     LocalCtxPost(anotherAxisSignal_, 1 << (axisId_ + signalIndex * DIM_NUM));
     186            0 :     LocalWait(localAxisSignal_, 1 << (1 - axisId_ + signalIndex * DIM_NUM));
     187            0 :     return;
     188              : }
     189              : 
     190              : // 每次调用,准备好1D范围内,所有需要传递的src和dst,size固定为(localSize-1)
     191            0 : void CcuContextScatterMesh2D::CcuWrite1DMesh(
     192              :     std::vector<CcuRep::Memory>& src, std::vector<CcuRep::Memory>& dst, CcuRep::Variable& size)
     193              : {
     194            0 :     CcuRep::MaskSignal locMask = CreateMaskSignal();
     195            0 :     uint16_t allBitWithoutLocal = ((1 << localSize_) - 1) & (~(1 << src.size()));
     196            0 :     uint64_t transportId = 0;
     197            0 :     for (uint16_t r = 0; r < src.size(); r++) {
     198            0 :         CCU_IF(size == 0) { LocalPost(locMask, 1 << r); }
     199            0 :         CCU_IF(size != 0) { Write(*transports[transportId], dst[r], src[r], size, locMask, 1 << r); }
     200            0 :         transportId++;
     201              :     }
     202              :     // 等写完所有对端
     203            0 :     LocalWait(locMask, allBitWithoutLocal);
     204            0 :     return;
     205            0 : }
     206              : 
     207            0 : uint64_t CcuContextScatterMesh2D::CoordinateToGlobalId(uint32_t x, uint32_t y)
     208              : {
     209            0 :     uint64_t id = 0;
     210            0 :     if (axisId_ == DIM_X) {
     211            0 :         id = x + y * dimSize_[0];
     212              :     } else {
     213            0 :         id = y + x * dimSize_[0];
     214              :     }
     215            0 :     return id;
     216              : }
     217              : 
     218              : // a = a + i * b
     219            0 : void CcuContextScatterMesh2D::CcuMultiply(CcuRep::Memory& a, CcuRep::Variable& b, uint64_t i) const
     220              : {
     221            0 :     for (uint64_t j = 0; j < i; j++) {
     222            0 :         a.addr += b;
     223              :     }
     224            0 :     return;
     225              : }
     226              : 
     227            0 : void CcuContextScatterMesh2D::RelaySendFor1D(
     228              :     std::vector<CcuRep::Memory>& relaySrc, std::vector<CcuRep::Memory>& relayDst, uint64_t j)
     229              : {
     230            0 :     uint64_t globalId = 0;
     231            0 :     relaySrc.clear();
     232            0 :     relayDst.clear();
     233            0 :     for (uint64_t i = 0; i < dimSize_[axisId_]; i++) {
     234            0 :         if (i != dimId_[axisId_]) {
     235              :             // 准备中转数据
     236            0 :             CcuRep::Memory src = CreateMemory();
     237            0 :             CcuRep::Memory dst = CreateMemory();
     238            0 :             src.token = token_[i];
     239            0 :             dst.token = token_[i];
     240              :             // i,j的顺序为先本轴(axisId), 再另外一个轴(anotherAxisId)
     241            0 :             globalId = CoordinateToGlobalId(i, j);
     242            0 :             HCCL_INFO(
     243              :                 "[CcuContextScatterMesh2D][PrepareRootSendInfo] src globalId[%llu], curRank[%u], j[%llu], i[%llu] ",
     244              :                 globalId, rankId_, j, i);
     245            0 :             src.addr = input_;
     246            0 :             CcuMultiply(src, stride_, globalId); // src偏移:src +=  stride_ * globalId
     247            0 :             dst.addr = scratch_[i];
     248            0 :             CcuMultiply(
     249            0 :                 dst, sliceSize_,
     250              :                 globalId); // dst偏移, dst为scratch,没有stride相关,dst += sliceSize_ * globalId
     251            0 :             if (axisId_ == DIM_Y) {
     252            0 :                 src.addr += axisSliceSize_[DIM_X];
     253            0 :                 dst.addr += axisSliceSize_[DIM_X];
     254              :             }
     255            0 :             relaySrc.emplace_back(src);
     256            0 :             relayDst.emplace_back(dst);
     257            0 :         }
     258              :     }
     259            0 :     HCCL_INFO(
     260              :         "[CcuContextScatterMesh2D][PrepareRootSendInfo] relaySrcSize[%zu], relayDstSize_[%zu] ", relaySrc.size(),
     261              :         relayDst.size());
     262            0 :     CcuWrite1DMesh(relaySrc, relayDst, axisSliceSize_[axisId_]);
     263            0 :     return;
     264              : }
     265              : 
     266              : // ********************************************
     267              : // 准备Root需要发送的“中转”地址,并发送
     268              : // relaySrc: “中转”数据,从Root的inputAddr发送到同轴其他卡的scratchAddr
     269              : // relayDst: 对端的scratchAddr
     270              : // ********************************************
     271            0 : void CcuContextScatterMesh2D::PrepareAndTransferRootRelayInfo(
     272              :     std::vector<CcuRep::Memory>& relaySrc, std::vector<CcuRep::Memory>& relayDst)
     273              : {
     274            0 :     HCCL_INFO("[CcuContextScatterMesh2D][PrepareRootSendInfo] start axisId_[%llu]", axisId_);
     275              :     // 准备中转数据: i 为所有对端,负责中转数据,所有数据均发至i上; j为中转目的地
     276            0 :     HCCL_INFO(
     277              :         "[CcuContextScatterMesh2D][PrepareRootSendInfo] axisId[%llu], dimSize_[%llu] ", axisId_, dimSize_[1 - axisId_]);
     278            0 :     for (uint64_t j = 0; j < dimSize_[1 - axisId_]; j++) {
     279            0 :         if (j != dimId_[1 - axisId_]) {
     280            0 :             RelaySendFor1D(relaySrc, relayDst, j);
     281              :         }
     282              :     }
     283            0 :     HCCL_INFO("[CcuContextScatterMesh2D][PrepareRootSendInfo] Done axisId_[%llu]", axisId_);
     284            0 :     return;
     285              : }
     286              : 
     287              : // directSrc:“直达”数据,从root的inputAddr发送到同轴其他卡的outputAddr
     288              : // directDst; 对端的outputAddr
     289            0 : void CcuContextScatterMesh2D::PrepareAndTransferRootDirectInfo(
     290              :     std::vector<CcuRep::Memory>& directSrc, std::vector<CcuRep::Memory>& directDst)
     291              : {
     292            0 :     uint64_t globalId = 0;
     293              :     // 准备直达数据,直达数据只在自己的axisId上做1D的发送
     294              :     // i为要发送直达数据的对端, 不包含本地
     295            0 :     directSrc.clear();
     296            0 :     directDst.clear();
     297            0 :     for (uint64_t i = 0; i < dimSize_[axisId_]; i++) {
     298            0 :         if (i != dimId_[axisId_]) {
     299            0 :             CcuRep::Memory src = CreateMemory();
     300            0 :             CcuRep::Memory dst = CreateMemory();
     301            0 :             src.token = token_[i];
     302            0 :             dst.token = token_[i];
     303            0 :             globalId = CoordinateToGlobalId(i, dimId_[1 - axisId_]);
     304            0 :             HCCL_INFO(
     305              :                 "[CcuContextScatterMesh2D][PrepareRootSendInfo] src globalId[%u], curRank[%u]", globalId, rankId_);
     306            0 :             src.addr = input_;
     307            0 :             CcuMultiply(src, stride_, globalId);
     308            0 :             dst.addr = output_[i]; // output只有一片,不需要偏移
     309            0 :             directSrc.emplace_back(src);
     310            0 :             directDst.emplace_back(dst);
     311            0 :         }
     312              :     }
     313            0 :     CcuWrite1DMesh(directSrc, directDst, sliceSize_);
     314            0 :     return;
     315              : }
     316              : 
     317            0 : void CcuContextScatterMesh2D::LocalTransfer()
     318              : {
     319            0 :     CcuRep::MaskSignal locMask = CreateMaskSignal();
     320            0 :     CcuRep::Memory src = CreateMemory();
     321            0 :     CcuRep::Memory dst = CreateMemory();
     322            0 :     src.token = token_[localId_];
     323            0 :     dst.token = token_[localId_];
     324            0 :     src.addr = input_;
     325            0 :     if (axisId_ == DIM_Y) {
     326            0 :         src.addr += axisSliceSize_[DIM_X];
     327              :     }
     328              : 
     329            0 :     CcuMultiply(src, stride_, root_);
     330            0 :     dst.addr = output_[localId_];
     331              : 
     332            0 :     if (axisId_ == DIM_Y) {
     333            0 :         dst.addr += axisSliceSize_[DIM_X];
     334              :     }
     335            0 :     HCCL_DEBUG("[CcuContextScatterMesh2D] use GroupCopy");
     336            0 :     GroupCopy(dst, src, curGoSize_);
     337              : 
     338            0 :     return;
     339            0 : }
     340              : 
     341              : // 准备转发节点,需要的转发数据地址
     342            0 : void CcuContextScatterMesh2D::RelaySend(std::vector<CcuRep::Memory>& relaySrc, std::vector<CcuRep::Memory>& relayDst)
     343              : {
     344              :     uint64_t globalId;
     345            0 :     relaySrc.clear();
     346            0 :     relayDst.clear();
     347            0 :     for (uint64_t i = 0; i < dimSize_[axisId_]; i++) {
     348            0 :         if (i != dimId_[axisId_]) {
     349            0 :             CcuRep::Memory src = CreateMemory();
     350            0 :             CcuRep::Memory dst = CreateMemory();
     351            0 :             src.token = token_[i];
     352            0 :             dst.token = token_[i];
     353            0 :             globalId = CoordinateToGlobalId(i, dimId_[1 - axisId_]);
     354            0 :             HCCL_INFO(
     355              :                 "[CcuContextScatterMesh2D][PrepareRelaySendInfo] src globalId[%llu], curRank[%u], axisId[%llu], "
     356              :                 "i:[%llu], localId[%llu]",
     357              :                 globalId, rankId_, axisId_, i, localId_);
     358            0 :             src.addr = scratch_[localId_];
     359            0 :             CcuMultiply(src, sliceSize_, globalId);
     360            0 :             dst.addr = output_[i]; // output只有一片,不需要偏移
     361            0 :             if (axisId_ == DIM_X) {
     362            0 :                 src.addr += axisSliceSize_[DIM_X];
     363            0 :                 dst.addr += axisSliceSize_[DIM_X];
     364              :             }
     365            0 :             relaySrc.emplace_back(src);
     366            0 :             relayDst.emplace_back(dst);
     367            0 :         }
     368              :     }
     369            0 :     CcuWrite1DMesh(relaySrc, relayDst, axisSliceSize_[1 - axisId_]);
     370            0 :     return;
     371              : }
     372              : 
     373              : // *************************************************
     374              : // root的行为模式说明: X轴和Y轴行为一致;都是给1DMesh的其他卡发数据, 任一轴的行为:
     375              : // 1) 前同步
     376              : // 2)给与本轴mesh直连卡发“中转”数据
     377              : // 3)后同步
     378              : // 4)轴同步
     379              : // 5)前同步
     380              : // 6)给与本轴mesh直连卡发“直达”数据
     381              : // 7)后同步
     382              : // 8)轴同步,与4)中成对使用,保证正确性
     383              : // *************************************************
     384            0 : void CcuContextScatterMesh2D::RootSendAlgorithm()
     385              : {
     386            0 :     HCCL_INFO("[CcuContextScatterMesh2D][RootSendAlgorithm] Start");
     387            0 :     PrepareVariables();
     388            0 :     LoadArgs();
     389              :     // step1
     390            0 :     PreSync();
     391              : 
     392              :     // 准备"直达"&“中转”传输地址
     393            0 :     std::vector<CcuRep::Memory> directSrc;
     394            0 :     std::vector<CcuRep::Memory> directDst;
     395            0 :     std::vector<CcuRep::Memory> relaySrc;
     396            0 :     std::vector<CcuRep::Memory> relayDst;
     397            0 :     PrepareAndTransferRootRelayInfo(relaySrc, relayDst);
     398              : 
     399            0 :     Sync(CKE_IDX_0); // 后同步
     400            0 :     AxisSync(0);
     401              :     // step2
     402            0 :     Sync(CKE_IDX_1); // 前同步的功能
     403              : 
     404            0 :     PrepareAndTransferRootDirectInfo(directSrc, directDst);
     405            0 :     LocalTransfer();
     406              : 
     407            0 :     Sync(CKE_IDX_0); // 后同步
     408            0 :     AxisSync(1);     // 轴同步
     409            0 :     HCCL_INFO("[CcuContextScatterMesh2D][RootSendAlgorithm] Step2 AxisSync Done");
     410            0 :     return;
     411            0 : }
     412              : 
     413              : // *****************************************
     414              : // 与Root同行或同列的rank
     415              : // step1: 与Root同行的只有ccuX有,与Root同列的只有ccuY有;(目前先搞所有卡都有)
     416              : // 1) 前同步
     417              : // 2)后同步
     418              : // step2:收直达数据(同行的ccuX有,同列的ccuY有);发step1收到的中转数据(同行的ccuY有,同列的ccuX有)
     419              : // 3)轴同步
     420              : // 4)前同步
     421              : // 5)发中转数据
     422              : // 6)后同步
     423              : // 7)轴同步
     424              : // *****************************************
     425            0 : void CcuContextScatterMesh2D::RelaySendAlgorithm()
     426              : {
     427            0 :     HCCL_INFO("[CcuContextScatterMesh2D][RelaySendAlgorithm] Start");
     428            0 :     PrepareVariables();
     429            0 :     LoadArgs();
     430              : 
     431              :     // step1:
     432            0 :     PreSync();       // 前同步
     433            0 :     Sync(CKE_IDX_0); // 后同步
     434            0 :     AxisSync(0);
     435              : 
     436              :     // step2:
     437              :     // 与Root同行的ccuX,或者 与Root同列的ccuY;才有step2的收直达数据
     438            0 :     if ((SameRowWithRoot() && axisId_ == DIM_X) or (SameColumnWithRoot() && axisId_ == DIM_Y)) {
     439            0 :         HCCL_INFO(
     440              :             "[CcuContextScatterMesh2D][RelaySendAlgorithm][1 actual Relay] into Relay action, axisId[%llu], "
     441              :             "isSameRowWithRoot[%d], isSameColwithRoot[%d], myRank[%llu], root[%llu]",
     442              :             axisId_, SameRowWithRoot(), SameColumnWithRoot(), rankId_, root_);
     443            0 :         Sync(CKE_IDX_1); // 前同步
     444            0 :         Sync(CKE_IDX_0); // 后同步
     445              :     }
     446              :     // 与Root同行的ccuY,或者 与Root同列的ccuX;才有step2的发中转数据
     447            0 :     if ((SameRowWithRoot() && axisId_ == DIM_Y) or (SameColumnWithRoot() && axisId_ == DIM_X)) {
     448            0 :         HCCL_INFO(
     449              :             "[CcuContextScatterMesh2D][RelaySendAlgorithm][2 actual Relay] into Relay action, axisId[%llu], "
     450              :             "isSameRowWithRoot[%d], isSameColwithRoot[%d], myRank[%llu], root[%llu]",
     451              :             axisId_, SameRowWithRoot(), SameColumnWithRoot(), rankId_, root_);
     452            0 :         Sync(CKE_IDX_1); // 前同步
     453              : 
     454              :         // 准备"直达"&“中转”传输地址
     455            0 :         std::vector<CcuRep::Memory> relaySrc;
     456            0 :         std::vector<CcuRep::Memory> relayDst;
     457            0 :         RelaySend(relaySrc, relayDst);
     458              : 
     459            0 :         Sync(CKE_IDX_0); // 后同步
     460            0 :     }
     461            0 :     AxisSync(1);
     462            0 :     HCCL_INFO("[CcuContextScatterMesh2D][RelaySendAlgorithm] step2 Done");
     463            0 :     return;
     464              : }
     465              : 
     466            0 : void CcuContextScatterMesh2D::NonDirectRecvAlgorithm()
     467              : {
     468            0 :     HCCL_INFO(
     469              :         "[CcuContextScatterMesh2D][NonDirectRecvAlgorithm] start, dimIdX_[%llu], dimIdY_[%llu]", dimId_[0], dimId_[1]);
     470            0 :     PrepareVariables();
     471            0 :     LoadArgs();
     472            0 :     PreSync();       // 前同步
     473            0 :     Sync(CKE_IDX_0); // 后同步
     474            0 :     AxisSync(0);
     475            0 :     Sync(CKE_IDX_1); // 前同步
     476            0 :     Sync(CKE_IDX_0); // 后同步
     477            0 :     AxisSync(1);
     478            0 :     HCCL_INFO(
     479              :         "[CcuContextScatterMesh2D][NonDirectRecvAlgorithm] Done, dimIdX_[%llu], dimIdY_[%llu]", dimId_[0], dimId_[1]);
     480            0 :     return;
     481              : }
     482              : 
     483            0 : void CcuContextScatterMesh2D::Algorithm()
     484              : {
     485            0 :     HCCL_INFO("[ccuScatterMesh2D_context] ScatterMesh2D run");
     486              :     // 分3种角色讨论,1)root; 2)与root同行同列的; 3)非直连的
     487            0 :     if (rankId_ == root_) {
     488              :         // root节点,X轴与Y轴的行为一致
     489            0 :         RootSendAlgorithm();
     490            0 :         return;
     491            0 :     } else if (SameRowWithRoot() or SameColumnWithRoot()) {
     492            0 :         RelaySendAlgorithm();
     493            0 :         return;
     494              :     } else {
     495              :         // 非直连
     496            0 :         NonDirectRecvAlgorithm();
     497            0 :         return;
     498              :     }
     499              :     HCCL_INFO("[ccuScatterMesh2D_context] ScatterMesh2D end");
     500              :     return;
     501              : }
     502              : 
     503            0 : std::vector<uint64_t> CcuContextScatterMesh2D::GeneArgs(const CcuTaskArg& arg)
     504              : {
     505            0 :     const CcuTaskArgScatterMesh2D* taskArg = dynamic_cast<const CcuTaskArgScatterMesh2D*>(&arg);
     506            0 :     if (taskArg == nullptr) {
     507            0 :         THROW<NullPtrException>(StringFormat("CcuContextScatterMesh2D::taskArg ptr is null"));
     508              :     }
     509              : 
     510            0 :     uint64_t inputAddr = taskArg->inputAddr_;
     511            0 :     uint64_t outputAddr = taskArg->outputAddr_;
     512            0 :     uint64_t tokenInfo = taskArg->token_;
     513            0 :     uint64_t scratchAddr = taskArg->scratchAddr_;
     514              : 
     515            0 :     uint64_t sliceSize = taskArg->sliceSize_;
     516            0 :     uint64_t stride = taskArg->stride_;
     517            0 :     uint64_t xSliceSize = taskArg->xSliceSize_;
     518            0 :     uint64_t ySliceSize = taskArg->ySliceSize_;
     519              : 
     520            0 :     auto xSliceGoSize = CalGoSize(xSliceSize);
     521            0 :     auto ySliceGoSize = CalGoSize(ySliceSize);
     522            0 :     auto curGosize = (axisId_ == DIM_X) ? xSliceGoSize : ySliceGoSize;
     523              : 
     524            0 :     HCCL_INFO(
     525              :         "[CcuContextScatterMesh2DAlgo] inputAddr[%llu], outputAddr[%llu], scratchAddr[%llu], sliceSize[%llu], "
     526              :         "stride[%llu], xSliceSize[%llu], ySliceSize[%llu] ",
     527              :         inputAddr, outputAddr, scratchAddr, sliceSize, stride, xSliceSize, ySliceSize);
     528              :     // 8个参数
     529              :     return {inputAddr,  outputAddr, tokenInfo,    scratchAddr,  sliceSize,    stride,
     530            0 :             xSliceSize, ySliceSize, curGosize[0], curGosize[1], curGosize[2], curGosize[3]};
     531            0 : }
     532              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1