* Copyright (c) 2025 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#include <cmath>
#include "reduce_parallel_executor.h"
#include "coll_alg_v2_exec_registry.h"
#include "ins_temp_all_gather_mesh_1D.h"
#include "ins_temp_all_gather_nhr.h"
#include "ins_temp_reduce_scatter_mesh_1D.h"
#include "ins_temp_reduce_scatter_nhr.h"
#if CANN_VERSION_NUM >= CANN_VERSION(9, 0, 0)
#include "ccu_temp_all_gather_mesh_1D_mem2mem.h"
#include "ccu_temp_all_gather_nhr_1D_mem2mem.h"
#include "ccu_temp_reduce_scatter_mesh_1D_mem2mem.h"
#include "ccu_temp_reduce_scatter_nhr_1D_mem2mem.h"
#endif
#include "topo_match_multilevel.h"
#include "topo_match_ubx.h"
#include "topo_match_pcie_mix.h"
#include "topo_match_squeeze_2d.h"
namespace ops_hccl {
constexpr int INT_0 = 0;
constexpr int INT_1 = 1;
constexpr int INT_2 = 2;
constexpr int INT_3 = 3;
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::ReduceParallelExecutor()
{}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult
ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::CalcAlgHierarchyInfo(
HcclComm comm, TopoInfoWithNetLayerDetails *topoInfo, AlgHierarchyInfoForAllLevel &algHierarchyInfo)
{
CHK_PTR_NULL(topoInfo);
AlgTopoMatch topoMatch;
CHK_RET(topoMatch.MatchTopo(comm, topoInfo, algHierarchyInfo));
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::CalcRes(
HcclComm comm, const OpParam ¶m, const TopoInfoWithNetLayerDetails *topoInfo,
const AlgHierarchyInfoForAllLevel &algHierarchyInfo, AlgResourceRequest &resourceRequest)
{
CHK_PTR_NULL(topoInfo);
myRank_ = topoInfo->userRank;
HCCL_INFO("[ReduceParallelExecutor] CalcRes start, rank[%d]", myRank_);
std::vector<std::vector<u32>> temp0HierarchyInfo;
std::vector<std::vector<u32>> temp1HierarchyInfo;
if(topoInfo->level0Topo == Level0Shape::MESH_1D_CLOS && !topoInfo->level0PcieMix) {
temp0HierarchyInfo = {algHierarchyInfo.infos[0][0]};
std::vector<u32> closRanks;
u32 meshSize = algHierarchyInfo.infos[0][0].size();
for(auto rank : algHierarchyInfo.infos[0][1]) {
if(rank % meshSize == topoInfo->userRank % meshSize) {
closRanks.push_back(rank);
}
}
temp1HierarchyInfo = {closRanks};
} else {
temp0HierarchyInfo = algHierarchyInfo.infos[0];
temp1HierarchyInfo = algHierarchyInfo.infos[1];
}
algTemplatePtrArr_.at(0).at(0) =
std::make_shared<AlgTemplate0>(param, topoInfo->userRank, temp0HierarchyInfo);
algTemplatePtrArr_.at(0).at(1) =
std::make_shared<AlgTemplate1>(param, topoInfo->userRank, temp1HierarchyInfo);
algTemplatePtrArr_.at(1).at(0) =
std::make_shared<AlgTemplate2>(param, topoInfo->userRank, temp0HierarchyInfo);
algTemplatePtrArr_.at(1).at(1) =
std::make_shared<AlgTemplate3>(param, topoInfo->userRank, temp1HierarchyInfo);
AlgResourceRequest reduceScatterIntraTempRequest;
AlgResourceRequest reduceScatterInterTempRequest;
AlgResourceRequest allGatherIntraTempRequest;
AlgResourceRequest allGatherInterTempRequest;
AlgResourceRequest intraTempRequestFinal;
AlgResourceRequest interTempRequestFinal;
CHK_RET(algTemplatePtrArr_.at(0).at(0)->CalcRes(comm, param, topoInfo, reduceScatterIntraTempRequest));
CHK_RET(algTemplatePtrArr_.at(0).at(1)->CalcRes(comm, param, topoInfo, reduceScatterInterTempRequest));
CHK_RET(algTemplatePtrArr_.at(1).at(0)->CalcRes(comm, param, topoInfo, allGatherIntraTempRequest));
CHK_RET(algTemplatePtrArr_.at(1).at(1)->CalcRes(comm, param, topoInfo, allGatherInterTempRequest));
for (auto &KernelInfo : reduceScatterIntraTempRequest.ccuKernelInfos) {
KernelInfo.resGroup = 0;
}
for (auto &KernelInfo : reduceScatterInterTempRequest.ccuKernelInfos) {
KernelInfo.resGroup = 0;
}
for (auto &KernelInfo : allGatherIntraTempRequest.ccuKernelInfos) {
KernelInfo.resGroup = 1;
}
for (auto &KernelInfo : allGatherInterTempRequest.ccuKernelInfos) {
KernelInfo.resGroup = 1;
}
u32 slaveThreadNumIntraMax = 0;
if (reduceScatterIntraTempRequest.slaveThreadNum >= allGatherIntraTempRequest.slaveThreadNum) {
slaveThreadNumIntraMax = reduceScatterIntraTempRequest.slaveThreadNum;
intraTempRequestFinal.notifyNumPerThread = reduceScatterIntraTempRequest.notifyNumPerThread;
} else {
slaveThreadNumIntraMax = allGatherIntraTempRequest.slaveThreadNum;
intraTempRequestFinal.notifyNumPerThread = allGatherIntraTempRequest.notifyNumPerThread;
}
u32 slaveThreadNumInterMax = 0;
if (reduceScatterInterTempRequest.slaveThreadNum >= allGatherInterTempRequest.slaveThreadNum) {
slaveThreadNumInterMax = reduceScatterInterTempRequest.slaveThreadNum;
interTempRequestFinal.notifyNumPerThread = reduceScatterInterTempRequest.notifyNumPerThread;
} else {
slaveThreadNumInterMax = allGatherInterTempRequest.slaveThreadNum;
interTempRequestFinal.notifyNumPerThread = allGatherInterTempRequest.notifyNumPerThread;
}
resourceRequest.notifyNumOnMainThread = stageSize_;
resourceRequest.slaveThreadNum = stageSize_ + slaveThreadNumIntraMax + stageSize_ + slaveThreadNumInterMax;
resourceRequest.notifyNumPerThread.emplace_back(reduceScatterIntraTempRequest.notifyNumOnMainThread + 1);
resourceRequest.notifyNumPerThread.emplace_back(allGatherIntraTempRequest.notifyNumOnMainThread + 1);
resourceRequest.notifyNumPerThread.insert(resourceRequest.notifyNumPerThread.end(),
intraTempRequestFinal.notifyNumPerThread.begin(),
intraTempRequestFinal.notifyNumPerThread.end());
resourceRequest.notifyNumPerThread.emplace_back(reduceScatterInterTempRequest.notifyNumOnMainThread + 1);
resourceRequest.notifyNumPerThread.emplace_back(allGatherInterTempRequest.notifyNumOnMainThread + 1);
resourceRequest.notifyNumPerThread.insert(resourceRequest.notifyNumPerThread.end(),
interTempRequestFinal.notifyNumPerThread.begin(),
interTempRequestFinal.notifyNumPerThread.end());
if (param.engine != COMM_ENGINE_CCU) {
resourceRequest.channels.emplace_back(reduceScatterIntraTempRequest.channels.at(0));
resourceRequest.channels.emplace_back(reduceScatterInterTempRequest.channels.at(0));
} else {
HCCL_INFO("[ReduceParallelExecutor][CalcRes] reduceScatterIntraTemp has [%d] kernels.", reduceScatterIntraTempRequest.ccuKernelNum[0]);
resourceRequest.ccuKernelInfos.insert(resourceRequest.ccuKernelInfos.end(),
reduceScatterIntraTempRequest.ccuKernelInfos.begin(),
reduceScatterIntraTempRequest.ccuKernelInfos.end());
resourceRequest.ccuKernelNum.emplace_back(reduceScatterIntraTempRequest.ccuKernelNum[0]);
HCCL_INFO("[ReduceParallelExecutor][CalcRes] reduceScatterInterTemp has [%d] kernels.", reduceScatterInterTempRequest.ccuKernelNum[0]);
resourceRequest.ccuKernelInfos.insert(resourceRequest.ccuKernelInfos.end(),
reduceScatterInterTempRequest.ccuKernelInfos.begin(),
reduceScatterInterTempRequest.ccuKernelInfos.end());
resourceRequest.ccuKernelNum.emplace_back(reduceScatterInterTempRequest.ccuKernelNum[0]);
HCCL_INFO("[ReduceParallelExecutor][CalcRes] allGatherIntraTemp has [%d] kernels.", allGatherIntraTempRequest.ccuKernelNum[0]);
resourceRequest.ccuKernelInfos.insert(resourceRequest.ccuKernelInfos.end(),
allGatherIntraTempRequest.ccuKernelInfos.begin(),
allGatherIntraTempRequest.ccuKernelInfos.end());
resourceRequest.ccuKernelNum.emplace_back(allGatherIntraTempRequest.ccuKernelNum[0]);
HCCL_INFO("[ReduceParallelExecutor][CalcRes] allGatherInterTemp has [%d] kernels.", allGatherInterTempRequest.ccuKernelNum[0]);
resourceRequest.ccuKernelInfos.insert(resourceRequest.ccuKernelInfos.end(),
allGatherInterTempRequest.ccuKernelInfos.begin(),
allGatherInterTempRequest.ccuKernelInfos.end());
resourceRequest.ccuKernelNum.emplace_back(allGatherInterTempRequest.ccuKernelNum[0]);
}
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::CalcLocalRoot()
{
CHK_PRT_RET(root_ >= rankSize_,
HCCL_ERROR("[ReduceParallelExecutor][CalcLocalRoot] root[%u] is out of rankSize[%u]", root_, rankSize_),
HcclResult::HCCL_E_INTERNAL);
CHK_PRT_RET(intraLocalRankSize_ == 0,
HCCL_ERROR("[ReduceParallelExecutor][CalcLocalRoot] intraLocalRankSize_ is 0"),
HcclResult::HCCL_E_INTERNAL);
CHK_PRT_RET(interLocalRankSize_ == 0,
HCCL_ERROR("[ReduceParallelExecutor][CalcLocalRoot] interLocalRankSize_ is 0"),
HcclResult::HCCL_E_INTERNAL);
rankIdxLevel0_ = myRank_ % intraLocalRankSize_;
rankIdxLevel1_ = myRank_ / intraLocalRankSize_;
intraLocalRoot_ = root_ / intraLocalRankSize_ * intraLocalRankSize_ + rankIdxLevel0_;
interLocalRoot_ = root_ % intraLocalRankSize_ + rankIdxLevel1_ * intraLocalRankSize_;
HCCL_INFO("[ReduceParallelExecutor][CalcLocalRoot] myRank[%d] intraLocalRoot[%u] interLocalRoot[%u]",
myRank_,
intraLocalRoot_,
interLocalRoot_);
return HcclResult::HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
uint64_t ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::GetRankSize(
const std::vector<std::vector<u32>> &vTopo) const
{
uint64_t count = 1;
for (const auto &i : vTopo) {
count *= i.size();
}
return count;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::Orchestrate(
const OpParam ¶m, const AlgResourceCtxSerializable &resCtx)
{
HCCL_INFO("[ReduceParallelExecutor][Orchestrate] Orchestrate Start");
maxTmpMemSize_ = resCtx.cclMem.size;
myRank_ = resCtx.topoInfo.userRank;
threads_ = resCtx.threads;
CHK_PTR_NULL(param.inputPtr);
CHK_PTR_NULL(param.outputPtr);
param_ = param;
CHK_PTR_NULL(resCtx.cclMem.addr);
resCtx_ = resCtx;
HCCL_INFO("[ReduceParallelExecutor][Orchestrate] threads_ size[%d]", threads_.size());
if (param.engine != CommEngine::COMM_ENGINE_AIV && param.engine != CommEngine::COMM_ENGINE_CCU) {
std::vector<std::map<u32, std::vector<ChannelInfo>>> remoteRankToChannelInfo;
CHK_RET(RestoreChannelMap(resCtx, remoteRankToChannelInfo));
intraLinks_ = remoteRankToChannelInfo.at(0);
interLinks_ = remoteRankToChannelInfo.at(1);
}
dataCount_ = param_.DataDes.count;
dataType_ = param_.DataDes.dataType;
dataTypeSize_ = DATATYPE_SIZE_TABLE[param_.DataDes.dataType];
root_ = param.root;
vTopo_ = resCtx.algHierarchyInfo.infos;
if(resCtx.topoInfo.level0Topo == Level0Shape::MESH_1D_CLOS && !resCtx.topoInfo.level0PcieMix) {
temp0HierarchyInfo_ = {resCtx.algHierarchyInfo.infos[0][0]};
std::vector<u32> closRankList;
u32 meshSize = resCtx.algHierarchyInfo.infos[0][0].size();
for(auto rank : resCtx.algHierarchyInfo.infos[0][1]) {
if(rank % meshSize == resCtx.topoInfo.userRank % meshSize) {
closRankList.push_back(rank);
}
}
temp1HierarchyInfo_ = {closRankList};
} else {
temp0HierarchyInfo_ = resCtx.algHierarchyInfo.infos[0];
temp1HierarchyInfo_ = resCtx.algHierarchyInfo.infos[1];
}
vTopo_ = {temp0HierarchyInfo_, temp1HierarchyInfo_};
intraLocalRankSize_ = GetRankSize(temp0HierarchyInfo_);
interLocalRankSize_ = GetRankSize(temp1HierarchyInfo_);
rankSize_ = intraLocalRankSize_ * interLocalRankSize_;
HCCL_DEBUG("[ReduceParallelExecutor][Orchestrate] myRank[%u], intraLocalRankSize_[%u], interLocalRankSize_[%u]",
myRank_,
intraLocalRankSize_,
interLocalRankSize_);
CHK_RET(CalcLocalRoot());
algTemplatePtrArr_.at(0).at(0) = std::make_shared<AlgTemplate0>(param, myRank_, temp0HierarchyInfo_);
algTemplatePtrArr_.at(0).at(1) = std::make_shared<AlgTemplate1>(param, myRank_, temp1HierarchyInfo_);
algTemplatePtrArr_.at(1).at(0) = std::make_shared<AlgTemplate2>(param, myRank_, temp0HierarchyInfo_);
algTemplatePtrArr_.at(1).at(1) = std::make_shared<AlgTemplate3>(param, myRank_, temp1HierarchyInfo_);
if (param.engine == CommEngine::COMM_ENGINE_AICPU_TS) {
algTemplatePtrArr_.at(0).at(1)->SetchannelsPerRank(interLinks_);
algTemplatePtrArr_.at(1).at(1)->SetchannelsPerRank(interLinks_);
}
CHK_RET(OrchestrateImpl());
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2,
AlgTemplate3>::PrepareResForStage(u32 stage)
{
std::array<std::array<AlgResourceRequest, stepSize_>, stageSize_> tempRequestArr;
std::array<u32, stageSize_> intraThreadsNum;
for (u32 stageIdx = 0; stageIdx < stageSize_; stageIdx++) {
for (u32 stepIdx = 0; stepIdx < stepSize_; stepIdx++) {
algTemplatePtrArr_.at(stageIdx).at(stepIdx)->GetRes(tempRequestArr.at(stageIdx).at(stepIdx));
}
intraThreadsNum.at(stageIdx) = tempRequestArr.at(stageIdx).at(0).slaveThreadNum + 1;
}
u32 intraThreadsNumMax = std::max(intraThreadsNum.at(0), intraThreadsNum.at(1));
u32 interThreadsNumMax = std::max(tempRequestArr.at(0).at(1).slaveThreadNum + 1,
tempRequestArr.at(1).at(1).slaveThreadNum + 1);
u32 expectedThreadsNum = 1 + stageSize_ + (intraThreadsNumMax - 1) + stageSize_ + (interThreadsNumMax - 1);
CHK_PRT_RET(threads_.size() < expectedThreadsNum,
HCCL_ERROR("[ReduceParallelExecutor][PrepareRes] act:[%u] exp:[%u]", threads_.size(), expectedThreadsNum),
HcclResult::HCCL_E_INTERNAL);
intraThreads_ = {threads_.at(1 + stage)};
intraThreads_.insert(intraThreads_.end(), threads_.begin() + stageSize_ + 1,
threads_.begin() + stageSize_ + intraThreadsNum.at(stage));
interThreads_ = {threads_.at(intraThreadsNumMax + stageSize_ + stage)};
interThreads_.insert(interThreads_.end(), threads_.begin() + intraThreadsNumMax + stageSize_ + stageSize_,
threads_.end());
mainThread_ = threads_.at(0);
templateMainThreads_ = {intraThreads_.at(0), interThreads_.at(0)};
syncNotifyOnTemplates_ = {tempRequestArr.at(stage).at(0).notifyNumOnMainThread,
tempRequestArr.at(stage).at(1).notifyNumOnMainThread};
syncNotifyOnMain_ = {0, 1};
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2,
AlgTemplate3>::PrepareResForStage2(u32 stage)
{
u32 stageNum = 2;
if (param_.engine == COMM_ENGINE_CCU) {
tempAlgResArr_.at(stage * stageNum).ccuKernels.clear();
tempAlgResArr_.at(stage * stageNum + 1).ccuKernels.clear();
if (stage == 0) {
tempAlgResArr_.at(stage * stageNum).ccuKernels.insert(
tempAlgResArr_.at(stage * stageNum).ccuKernels.end(),
resCtx_.ccuKernels.begin(),
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0]);
tempAlgResArr_.at(stage * stageNum + 1).ccuKernels.insert(
tempAlgResArr_.at(stage * stageNum + 1).ccuKernels.end(),
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0],
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0] + resCtx_.ccuKernelNum[1]);
} else {
tempAlgResArr_.at(stage * stageNum).ccuKernels.insert(
tempAlgResArr_.at(stage * stageNum).ccuKernels.end(),
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0] + resCtx_.ccuKernelNum[1],
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0] + resCtx_.ccuKernelNum[1] + resCtx_.ccuKernelNum[2]);
tempAlgResArr_.at(stage * stageNum + 1).ccuKernels.insert(
tempAlgResArr_.at(stage * stageNum + 1).ccuKernels.end(),
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0] + resCtx_.ccuKernelNum[1] + resCtx_.ccuKernelNum[2],
resCtx_.ccuKernels.begin() + resCtx_.ccuKernelNum[0] + resCtx_.ccuKernelNum[1] + resCtx_.ccuKernelNum[2] + resCtx_.ccuKernelNum[3]);
}
} else {
tempAlgResArr_.at(stage * INT_2).channels = intraLinks_;
tempAlgResArr_.at(stage * INT_2 + INT_1).channels = interLinks_;
}
tempAlgResArr_.at(stage * INT_2).threads = intraThreads_;
tempAlgResArr_.at(stage * INT_2).aivCommInfoPtr = resCtx_.aivCommInfoPtr;
tempAlgResArr_.at(stage * INT_2 + INT_1).threads = interThreads_;
tempAlgResArr_.at(stage * INT_2 + INT_1).aivCommInfoPtr = resCtx_.aivCommInfoPtr;
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
TemplateDataParams ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2,
AlgTemplate3>:: GenDataParamsTempAlg(u32 dataSliceIdx, u32 stageIdx, u32 stepIdx, bool isInter)
{
TemplateDataParams dataParams;
bool isFirstStep = (stageIdx == 0 && stepIdx == 0);
dataParams.buffInfo.inBuffType = isFirstStep ? BufferType::INPUT : BufferType::HCCL_BUFFER;
dataParams.buffInfo.outBuffType = BufferType::HCCL_BUFFER;
dataParams.buffInfo.hcclBuffType = BufferType::HCCL_BUFFER;
const u64 inputBufferOffset = dataOffsetPerLoop_.at(dataSliceIdx);
u64 totalCount = dataCountPerLoop_.at(dataSliceIdx);
const u64 dataSliceBaseOffset = dataSliceIdx == 0 ? 0 : dataCountPerLoop_.at(0) * dataTypeSize_;
u64 dataOffset = dataSliceBaseOffset;
if ((stageIdx ^ stepIdx) == 1) {
const u32 othLocalRankSize = isInter ? intraLocalRankSize_ : interLocalRankSize_;
const std::map<u32, u32> &othTempVirtRankMap = virtRankMap_.at(!isInter);
const u32 othLocalRankIdx = othTempVirtRankMap.at(myRank_);
const u64 trivialSize = dataCountPerLoop_.at(dataSliceIdx) / othLocalRankSize * dataTypeSize_;
const u64 tailSize = dataCountPerLoop_.at(dataSliceIdx) * dataTypeSize_ - (othLocalRankSize - 1) * trivialSize;
dataOffset = dataSliceBaseOffset + othLocalRankIdx * trivialSize;
totalCount = ((othLocalRankIdx + 1 == othLocalRankSize) ? tailSize : trivialSize) / dataTypeSize_;
}
const u64 totalSize = totalCount * dataTypeSize_;
dataParams.buffInfo.inputPtr = isFirstStep ? param_.inputPtr : resCtx_.cclMem.addr;
dataParams.buffInfo.inputSize = isFirstStep ? param_.inputSize : resCtx_.cclMem.size;
dataParams.buffInfo.outputPtr = resCtx_.cclMem.addr;
dataParams.buffInfo.outputSize = resCtx_.cclMem.size;
dataParams.buffInfo.hcclBuff = resCtx_.cclMem;
dataParams.buffInfo.hcclBuffSize = resCtx_.cclMem.size;
const u32 localRankSize = isInter ? interLocalRankSize_ : intraLocalRankSize_;
u64 trivialSize = totalCount / localRankSize * dataTypeSize_;
dataParams.tailSize = totalSize - (localRankSize - 1) * trivialSize;
dataParams.sliceSize = trivialSize;
dataParams.count = dataParams.sliceSize / dataTypeSize_;
if (stageIdx == 0 && !isInter) {
dataParams.buffInfo.hcclBuffBaseOff = (dataCountPerLoop_.at(0) + dataCountPerLoop_.at(1)) * dataTypeSize_;
} else {
dataParams.buffInfo.hcclBuffBaseOff = dataOffset;
}
if (isFirstStep) {
dataParams.buffInfo.inBuffBaseOff = inputBufferOffset;
dataParams.buffInfo.outBuffBaseOff = dataSliceBaseOffset;
} else {
dataParams.buffInfo.inBuffBaseOff = dataOffset;
dataParams.buffInfo.outBuffBaseOff = dataOffset;
}
dataParams.inputSliceStride = dataParams.sliceSize;
dataParams.outputSliceStride = dataParams.sliceSize;
dataParams.repeatNum = 1;
dataParams.inputRepeatStride = 0;
dataParams.outputRepeatStride = 0;
return dataParams;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult
ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::OrchestrateImpl()
{
for (u32 stage = 0; stage < stageSize_; stage++) {
for (u32 isInter = 0; isInter < dataSplitPart_; isInter++) {
HCCL_INFO("[ReduceParallelExecutor][OrchestrateImpl] stage[%u] isInter[%u] [%s]",
stage,
isInter,
algTemplatePtrArr_.at(stage).at(isInter)->Describe().c_str());
}
}
multipleDimensionSplitRatio_ = param_.opConfig.multipleDimensionSplitRatio;
std::array<long double, dataSplitPart_> dataSplitSize{multipleDimensionSplitRatio_, 1.0 - multipleDimensionSplitRatio_};
HCCL_INFO("[ReduceParallelExecutor] dataSplitSize is %Lf, %Lf", dataSplitSize[0], dataSplitSize[1]);
const long double scratchMultipleIntra = std::max(dataSplitSize.at(0), dataSplitSize.at(1) / interLocalRankSize_);
const long double totalScratchMultiple = scratchMultipleIntra + 1.0;
const u64 scratchMemBlockSize = maxTmpMemSize_ / totalScratchMultiple;
CHK_PRT_RET(dataTypeSize_ == 0, "[ReduceParallelExecutor][OrchestrateImpl] dataTypeSize_ is 0", HCCL_E_INTERNAL);
u64 maxCountPerLoop = scratchMemBlockSize / dataTypeSize_;
if (param_.engine != CommEngine::COMM_ENGINE_AICPU_TS) {
maxCountPerLoop = std::min<u64>(scratchMemBlockSize, UB_MAX_DATA_SIZE) / dataTypeSize_;
}
CHK_PRT_RET(maxCountPerLoop == 0, "[ReduceParallelExecutor][OrchestrateImpl] maxCountPerLoop is 0", HCCL_E_INTERNAL);
const u32 loopTimes = dataCount_ / maxCountPerLoop + ((dataCount_ % maxCountPerLoop == 0) ? 0 : 1);
for (u32 isInter = 0; isInter < dataSplitPart_; isInter++) {
for (u32 localRank = 0; localRank < vTopo_.at(isInter).at(0).size(); localRank++) {
const u32 globalRank = vTopo_.at(isInter).at(0).at(localRank);
virtRankMap_.at(isInter)[globalRank] = localRank;
}
}
CHK_RET(OrchestrateLoop(loopTimes, maxCountPerLoop));
HCCL_INFO("[ReduceParallelExecutor][OrchestrateImpl] myRank[%d] End.", myRank_);
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult
ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::OrchestrateLoop(
u32 loopTimes, u64 maxCountPerLoop)
{
u64 alignSize = AICPU_ALIGN_SIZE;
u64 processedCount = 0;
u32 loopIndex = 0;
while (processedCount < dataCount_) {
u64 remainingCount = dataCount_ - processedCount;
u32 remainingLoopTimes = (loopIndex < loopTimes) ? (loopTimes - loopIndex) : 1;
u64 currCount = (remainingCount + remainingLoopTimes - 1) / remainingLoopTimes;
currCount = std::min(currCount, maxCountPerLoop);
u64 currCountPart0 = static_cast<u64>(currCount * multipleDimensionSplitRatio_);
u64 currCountPart1 = currCount - currCountPart0;
if (remainingLoopTimes > 1) {
u64 alignedCountPart0 = currCountPart0;
u64 alignedCountPart1 = currCountPart1;
alignedCountPart0 = alignedCountPart0 * dataTypeSize_ / alignSize * alignSize / dataTypeSize_;
alignedCountPart1 = alignedCountPart1 * dataTypeSize_ / alignSize * alignSize / dataTypeSize_;
if (alignedCountPart0 + alignedCountPart1 > 0) {
currCountPart0 = alignedCountPart0;
currCountPart1 = alignedCountPart1;
}
}
CHK_PRT_RET(currCountPart0 + currCountPart1 == 0,
HCCL_ERROR("[ReduceParallelExecutor][OrchestrateLoop] currCount is 0"),
HcclResult::HCCL_E_INTERNAL);
dataCountPerLoop_.at(0) = currCountPart0;
dataCountPerLoop_.at(1) = currCountPart1;
u64 currProcessedCount = currCountPart0 + currCountPart1;
dataOffsetPerLoop_.at(0) = processedCount * dataTypeSize_;
dataOffsetPerLoop_.at(1) = dataOffsetPerLoop_.at(0) + dataCountPerLoop_.at(0) * dataTypeSize_;
u32 stageNum = 2;
for (u32 stageIdx = 0; stageIdx < stageNum; stageIdx++) {
CHK_RET(PrepareResForStage(stageIdx));
CHK_RET(PrepareResForStage2(stageIdx));
for (u32 stepIdx = 0; stepIdx < stageNum; stepIdx++) {
CHK_RET(OrchestrateStep(stageIdx, stepIdx));
#ifndef AICPU_COMPILE
if (loopTimes == 1 && param_.engine == CommEngine::COMM_ENGINE_CCU) {
if (stageIdx == 0 && stepIdx == 0) {
ccuKernelLaunchNumRSIntra0_ = tempAlgResArr_.at(INT_0).submitInfos.size();
ccuKernelLaunchNumRSInter1_ = tempAlgResArr_.at(INT_1).submitInfos.size();
} else if (stageIdx == 0 && stepIdx == 1) {
ccuKernelLaunchNumRSIntra1_ = tempAlgResArr_.at(INT_0).submitInfos.size() - ccuKernelLaunchNumRSIntra0_;
ccuKernelLaunchNumRSInter0_ = tempAlgResArr_.at(INT_1).submitInfos.size() - ccuKernelLaunchNumRSInter1_;
} else if (stageIdx == 1 && stepIdx == 0) {
ccuKernelLaunchNumAGIntra1_ = tempAlgResArr_.at(INT_2).submitInfos.size();
ccuKernelLaunchNumAGInter0_ = tempAlgResArr_.at(INT_3).submitInfos.size();
} else if (stageIdx == 1 && stepIdx == 1 && param_.opMode != OpMode::OFFLOAD) {
ccuKernelLaunchNumAGIntra0_ = tempAlgResArr_.at(INT_2).submitInfos.size() - ccuKernelLaunchNumAGIntra1_;
ccuKernelLaunchNumAGInter1_ = tempAlgResArr_.at(INT_3).submitInfos.size() - ccuKernelLaunchNumAGInter0_;
CHK_RET(FastLaunchSaveCtx());
}
}
#endif
}
}
if (myRank_ == root_) {
const DataSlice srcSlice(resCtx_.cclMem.addr, 0, currProcessedCount * dataTypeSize_);
const DataSlice dstSlice(param_.outputPtr, processedCount * dataTypeSize_, currProcessedCount * dataTypeSize_);
CHK_RET(LocalCopy(threads_.at(0), srcSlice, dstSlice));
}
processedCount += currProcessedCount;
loopIndex++;
}
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult
ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::OrchestrateStep(
u32 stageIdx, u32 stepIdx)
{
CHK_RET(PreSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnTemplates_));
for (u32 dataSliceIdx = 0; dataSliceIdx < dataSplitPart_; dataSliceIdx++) {
bool isInter = (stageIdx == 1) ^ (stepIdx == 1) ^ (dataSliceIdx == 1);
CHK_RET(RunTemplate(dataSliceIdx, stageIdx, stepIdx, isInter));
}
CHK_RET(PostSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnMain_));
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,
typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::RunTemplate(
u32 dataSliceIdx, u32 stageIdx, u32 stepIdx, bool isInter)
{
if (dataCountPerLoop_.at(dataSliceIdx) == 0) {
return HCCL_SUCCESS;
}
const TemplateDataParams dataParams = GenDataParamsTempAlg(dataSliceIdx, stageIdx, stepIdx, isInter);
CHK_RET(algTemplatePtrArr_.at(stageIdx).at(isInter)->KernelRun(param_, dataParams, tempAlgResArr_.at(stageIdx == 0 ? (stepIdx == dataSliceIdx ? 0 : 1) : (stepIdx == dataSliceIdx ? 3 : 2))));
return HCCL_SUCCESS;
}
#ifndef AICPU_COMPILE
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::FastLaunchSaveCtx()
{
HCCL_INFO("[ReduceParallelExecutor][FastLaunchSaveCtx] loopTimes==1, save fast launch ctx.");
u32 threadNum = threads_.size();
u32 ccuKernelNum = ccuKernelLaunchNumRSIntra1_ + ccuKernelLaunchNumRSInter0_ + ccuKernelLaunchNumRSIntra0_ + ccuKernelLaunchNumRSInter1_ +
ccuKernelLaunchNumAGIntra1_ + ccuKernelLaunchNumAGInter0_ + ccuKernelLaunchNumAGIntra0_ + ccuKernelLaunchNumAGInter1_;
if (ccuKernelNum < 1) {
HCCL_INFO("[ReduceParallelExecutor][FastLaunchSaveCtx] ccu kernel num is 0, no need to save.");
return HCCL_SUCCESS;
}
HCCL_INFO("[ReduceParallelExecutor][FastLaunchSaveCtx] threadNum[%llu], ccuKernelNum[%llu]", threadNum, ccuKernelNum);
u64 size = CcuFastLaunchCtx::GetCtxSize(threadNum, ccuKernelNum);
void *ctxPtr = nullptr;
HCCL_INFO("[ReduceParallelExecutor][FastLaunchSaveCtx] Tag[%s], size[%llu]", param_.fastLaunchTag, size);
CHK_RET(HcclEngineCtxCreate(param_.hcclComm, param_.fastLaunchTag, CommEngine::COMM_ENGINE_CCU, size, &ctxPtr));
CcuFastLaunchCtx *ccuFastLaunchCtx = reinterpret_cast<CcuFastLaunchCtx*>(ctxPtr);
CHK_SAFETY_FUNC_RET(strcpy_s(ccuFastLaunchCtx->algName, sizeof(ccuFastLaunchCtx->algName), param_.algName));
HCCL_INFO("[ReduceParallelExecutor][FastLaunchSaveCtx] algName[%s]", ccuFastLaunchCtx->algName);
ccuFastLaunchCtx->threadNum = threadNum;
ccuFastLaunchCtx->notifyNumOnMainThread = resCtx_.notifyNumOnMainThread;
ThreadHandle *threads = ccuFastLaunchCtx->GetThreadHandlePtr();
for (u32 i = 0; i < threadNum; i++) {
threads[i] = threads_[i];
}
u32 templateIdx = 0;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumRSIntra0_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumRSInter1_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumRSInter0_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumRSIntra1_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumAGInter0_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumAGIntra1_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumAGIntra0_;
ccuFastLaunchCtx->ccuKernelNum[templateIdx++] = ccuKernelLaunchNumAGInter1_;
CcuKernelSubmitInfo *kernelSubmitInfos = ccuFastLaunchCtx->GetCcuKernelSubmitInfoPtr();
u32 kernelIdx = 0;
for (u32 i = 0; i < ccuKernelLaunchNumRSIntra0_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(0).submitInfos[i];
}
for (u32 i = 0; i < ccuKernelLaunchNumRSInter1_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(1).submitInfos[i];
}
for (u32 i = ccuKernelLaunchNumRSInter1_; i < ccuKernelLaunchNumRSInter0_ + ccuKernelLaunchNumRSInter1_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(1).submitInfos[i];
}
for (u32 i = ccuKernelLaunchNumRSIntra0_; i < ccuKernelLaunchNumRSIntra1_ + ccuKernelLaunchNumRSIntra0_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(0).submitInfos[i];
}
for (u32 i = 0; i < ccuKernelLaunchNumAGInter0_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(3).submitInfos[i];
}
for (u32 i = 0; i < ccuKernelLaunchNumAGIntra1_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(2).submitInfos[i];
}
for (u32 i = ccuKernelLaunchNumAGIntra1_; i < ccuKernelLaunchNumAGIntra0_ + ccuKernelLaunchNumAGIntra1_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(2).submitInfos[i];
}
for (u32 i = ccuKernelLaunchNumAGInter0_; i < ccuKernelLaunchNumAGInter0_ + ccuKernelLaunchNumAGInter1_; i++) {
kernelSubmitInfos[kernelIdx++] = tempAlgResArr_.at(3).submitInfos[i];
}
return HCCL_SUCCESS;
}
template <typename AlgTopoMatch, typename AlgTemplate0, typename AlgTemplate1, typename AlgTemplate2,typename AlgTemplate3>
HcclResult ReduceParallelExecutor<AlgTopoMatch, AlgTemplate0, AlgTemplate1, AlgTemplate2, AlgTemplate3>::FastLaunch(
const OpParam ¶m, const CcuFastLaunchCtx *ctx)
{
algTemplatePtrArr_.at(0).at(0) = std::make_shared<AlgTemplate0>();
algTemplatePtrArr_.at(0).at(1) = std::make_shared<AlgTemplate1>();
algTemplatePtrArr_.at(1).at(0) = std::make_shared<AlgTemplate2>();
algTemplatePtrArr_.at(1).at(1) = std::make_shared<AlgTemplate3>();
TemplateFastLaunchCtx tempFastLaunchCtxIntra0, tempFastLaunchCtxInter0;
TemplateFastLaunchCtx tempFastLaunchCtxInter1, tempFastLaunchCtxIntra1;
TemplateFastLaunchCtx tempFastLaunchCtxIntra01, tempFastLaunchCtxInter01;
TemplateFastLaunchCtx tempFastLaunchCtxInter11, tempFastLaunchCtxIntra11;
TemplateResource templateAlgResIntra, templateAlgResInter;
ThreadHandle *threads = ctx->GetThreadHandlePtr();
threads_.assign(threads, threads + ctx->threadNum);
PrepareResForStage(0);
CcuKernelSubmitInfo *ccuKernelSubmitInfos = ctx->GetCcuKernelSubmitInfoPtr();
HCCL_INFO("[ReduceParallelExecutor][FastLaunch] Intra0 ccuKernelNum[%llu]", ctx->ccuKernelNum[0]);
CHK_RET(PreSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnTemplates_));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxIntra0, param.inputPtr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxIntra0.threads = intraThreads_;
tempFastLaunchCtxIntra0.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[0]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[0];
CHK_RET(algTemplatePtrArr_.at(0).at(0)->FastLaunch(param, tempFastLaunchCtxIntra0));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxInter1, param.inputPtr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxInter1.threads = interThreads_;
tempFastLaunchCtxInter1.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[1]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[1];
CHK_RET(algTemplatePtrArr_.at(0).at(1)->FastLaunch(param, tempFastLaunchCtxInter1));
CHK_RET(PostSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnMain_));
CHK_RET(PreSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnTemplates_));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxInter0, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxInter0.threads = interThreads_;
tempFastLaunchCtxInter0.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[2]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[2];
CHK_RET(algTemplatePtrArr_.at(0).at(1)->FastLaunch(param, tempFastLaunchCtxInter0));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxIntra1, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxIntra1.threads = intraThreads_;
tempFastLaunchCtxIntra1.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[3]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[3];
CHK_RET(algTemplatePtrArr_.at(0).at(0)->FastLaunch(param, tempFastLaunchCtxIntra1));
CHK_RET(PostSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnMain_));
PrepareResForStage(1);
CHK_RET(PreSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnTemplates_));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxInter01, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxInter01.threads = interThreads_;
tempFastLaunchCtxInter01.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[4]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[4];
CHK_RET(algTemplatePtrArr_.at(1).at(1)->FastLaunch(param, tempFastLaunchCtxInter01));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxIntra11, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxIntra11.threads = intraThreads_;
tempFastLaunchCtxIntra11.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[5]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[5];
CHK_RET(algTemplatePtrArr_.at(1).at(0)->FastLaunch(param, tempFastLaunchCtxIntra11));
CHK_RET(PostSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnMain_));
CHK_RET(PreSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnTemplates_));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxIntra01, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxIntra01.threads = intraThreads_;
tempFastLaunchCtxIntra01.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[6]);
ccuKernelSubmitInfos += ctx->ccuKernelNum[6];
CHK_RET(algTemplatePtrArr_.at(1).at(0)->FastLaunch(param, tempFastLaunchCtxIntra01));
CHK_RET(SetTempFastLaunchAddr(tempFastLaunchCtxInter11, param.hcclBuff.addr, param.hcclBuff.addr, param.hcclBuff));
tempFastLaunchCtxInter11.threads = interThreads_;
tempFastLaunchCtxInter11.ccuKernelSubmitInfos.assign(ccuKernelSubmitInfos, ccuKernelSubmitInfos + ctx->ccuKernelNum[7]);
CHK_RET(algTemplatePtrArr_.at(1).at(1)->FastLaunch(param, tempFastLaunchCtxInter11));
CHK_RET(PostSyncInterThreads(mainThread_, templateMainThreads_, syncNotifyOnMain_));
HCCL_INFO("[ReduceParallelExecutor][FastLaunch] param.userRank[%u]", param.userRank);
HCCL_INFO("[ReduceParallelExecutor][FastLaunch] param.root[%u]", param.root);
if (param.userRank == param.root) {
HCCL_INFO("[ReduceParallelExecutor][FastLaunch] LocalCopy");
const DataSlice srcSlice(param.hcclBuff.addr, 0, param.DataDes.count * DATATYPE_SIZE_TABLE[param.DataDes.dataType]);
const DataSlice dstSlice(param.outputPtr, 0, param.DataDes.count * DATATYPE_SIZE_TABLE[param.DataDes.dataType]);
CHK_RET(LocalCopy(threads_.at(0), srcSlice, dstSlice));
}
HCCL_INFO("[ReduceParallelExecutor][FastLaunch] End.");
return HCCL_SUCCESS;
}
#endif
#if CANN_VERSION_NUM >= CANN_VERSION(9, 0, 0)
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, ReduceParallelMesh1DNHR, ReduceParallelExecutor,
TopoMatchMultilevel, InsTempReduceScatterMesh1D, InsTempReduceScatterNHR, InsTempAllGatherMesh1D,
InsTempAllGatherNHR);
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, ReduceParallelMesh1DNHRUBX, ReduceParallelExecutor,
TopoMatchUBX, InsTempReduceScatterMesh1D, InsTempReduceScatterNHR, InsTempAllGatherMesh1D,
InsTempAllGatherNHR);
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, ReduceParallelMesh1DNHRPcie, ReduceParallelExecutor,
TopoMatchPcieMix, InsTempReduceScatterMesh1D, InsTempReduceScatterNHR, InsTempAllGatherMesh1D, InsTempAllGatherNHR);
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, ReduceParallelNHRNHRUboe, ReduceParallelExecutor,
TopoMatchSqueeze2D, InsTempReduceScatterNHR, InsTempReduceScatterNHR, InsTempAllGatherNHR, InsTempAllGatherNHR);
#endif
#ifndef AICPU_COMPILE
#if CANN_VERSION_NUM >= CANN_VERSION(9, 0, 0)
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, CcuReduceParallelMesh1DNHR, ReduceParallelExecutor,
TopoMatchMultilevel, CcuTempReduceScatterMesh1DMem2Mem, CcuTempReduceScatterNHR1DMem2Mem, CcuTempAllGatherMesh1DMem2Mem, CcuTempAllGatherNHR1DMem2Mem);
REGISTER_EXECUTOR_BY_FOUR_TEMPS(HcclCMDType::HCCL_CMD_REDUCE, CcuReduceParallelMesh1DNHRUBX, ReduceParallelExecutor,
TopoMatchUBX, CcuTempReduceScatterMesh1DMem2Mem, CcuTempReduceScatterNHR1DMem2Mem, CcuTempAllGatherMesh1DMem2Mem, CcuTempAllGatherNHR1DMem2Mem);
#endif
#endif
}