2df59c50创建于 2019年2月5日历史提交
/**
 * Copyright (c) 2026 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.
 */

/*!
 * \file hccl_aicpu.h
 * \brief
 */
#ifndef IMPL_V220_HCCL_AICPU_H
#define IMPL_V220_HCCL_AICPU_H

#include "../../common/hccl_aicpu_impl.h"

namespace AscendC {
template <const auto& config>
template <bool commit>
__aicore__ inline HcclHandle
HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::BatchWrite(GM_ADDR batchWriteInfo, uint32_t itemNum,
        uint16_t queueID)
{
    return CommonPrepareImpl<true>(
        {HcclCMDType::HCCL_CMD_BATCH_WRITE, batchWriteInfo, batchWriteInfo, itemNum, static_cast<HcclDataType>(queueID),
         static_cast<HcclDataType>(queueID), static_cast<HcclReduceOp>(queueID + GetBlockIdx() * queueNum_)});
}

template <const auto& config>
template <bool commit>
__aicore__ inline HcclHandle HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::AlltoAllvWrite(
    GM_ADDR usrIn, GM_ADDR sendOffsets, GM_ADDR sendSizes, uint64_t remoteWinOffset, uint64_t localDataSize)
{
    CommonPrepareParam commonPrepareParam = {
        HcclCMDType::HCCL_CMD_HALF_ALLTOALLV,
        usrIn,
        usrIn,
        localDataSize,
        HCCL_DATA_TYPE_INT8,
        HCCL_DATA_TYPE_INT8,
        HCCL_REDUCE_RESERVED,
        0,
        1,
        {},
        {reinterpret_cast<uint64_t>(sendOffsets), reinterpret_cast<uint64_t>(sendSizes), remoteWinOffset}};

    return CommonPrepareImpl<commit>(commonPrepareParam);
}

template<const auto &config>
__aicore__ inline void
HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::InterHcclGroupSync(int8_t srcGroupID, HcclHandle srcHandleID)
{
    ASCENDC_HCCL_API_ASSERT(
        curVersion_ != HcclTilingVersion::INVALID_TILING_VERSION, { return; },
        "Call InterHcclGroupSync failed, ensure Hccl::Init func has been called successfully!");
    CommonPrepareParam param;
    param.commType.msgType = ControlMsgType::HCCL_CMD_INTER_GROUP_SYNC;
    SendMsgToServer(0U, param, srcGroupID, srcHandleID);
    ++(curMsgPosition_[0U]);
    ASCENDC_HCCL_API_ASSERT(
        curMsgPosition_[0U] < HCCL_MSG_CNT, { return; }, "Message amount exceeds the maximum value when sync group.");
    if (workingFlag_) {
        UpdateControlMsgCount(hcclMsgArea_, ControlMsgType::HCCL_CMD_INTER_GROUP_SYNC);
    }
}

template <const auto& config>
__aicore__ inline GM_ADDR HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::GetWindowsInAddr(uint32_t rankId)
{
    ASCENDC_HCCL_API_ASSERT(
        rankId < GetRankDim(), { return nullptr; }, "GetWindowsInAddr failed, rankId[%u], expected less than[%u]",
        rankId, GetRankDim());
    if (devType_ != HCCL_ASCEND910B) {
        __gm__ HcclContextDef::HcclOpResParam* hcclContext = (__gm__ HcclContextDef::HcclOpResParam*)hcclContext_;
        if (rankId == hcclContext->rankId) {
            return reinterpret_cast<GM_ADDR>(hcclContext->localWindowsIn);
        } else {
            const auto addr = GetRemoteRankAddrs(hcclContext, rankId);
            return reinterpret_cast<GM_ADDR>(addr != nullptr ? addr->windowsIn : 0UL);
        }
    } else {
        if (hcclContext_->multiFlag == 0U) {
            return (GM_ADDR)hcclContext_->windowsIn[rankId];
        } else {
            if (rankId == hcclContext_->rankId) {
                return (GM_ADDR)(hcclContext_->data[rankId].localInput.addr);
            } else {
                return (GM_ADDR)(hcclContext_->data[rankId].remoteInput.addr);
            }
        }
    }
}

template <const auto& config>
__aicore__ inline GM_ADDR HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::GetWindowsOutAddr(uint32_t rankId)
{
    ASCENDC_HCCL_API_ASSERT(
        rankId < GetRankDim(), { return nullptr; }, "GetWindowsOutAddr failed, rankId[%u], expected less than[%u]",
        rankId, GetRankDim());
    if (devType_ != HCCL_ASCEND910B) {
        __gm__ HcclContextDef::HcclOpResParam* hcclContext = (__gm__ HcclContextDef::HcclOpResParam*)hcclContext_;
        if (rankId == hcclContext->rankId) {
            return reinterpret_cast<GM_ADDR>(hcclContext->localWindowsOut);
        } else {
            const auto addr = GetRemoteRankAddrs(hcclContext, rankId);
            return reinterpret_cast<GM_ADDR>(addr != nullptr ? addr->windowsOut : 0UL);
        }
    } else {
        if (hcclContext_->multiFlag == 0U) {
            return (GM_ADDR)hcclContext_->windowsOut[rankId];
        } else {
            if (rankId == hcclContext_->rankId) {
                return (GM_ADDR)(hcclContext_->data[rankId].localOutput.addr);
            } else {
                return (GM_ADDR)(hcclContext_->data[rankId].remoteOutput.addr);
            }
        }
    }
}

template <const auto &config>
__aicore__ inline void
HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::Init(GM_ADDR context, __gm__ void *initTiling)
{
    HcclTilingVersion version;
    if (initTiling != nullptr) {
        version = HcclTilingVersion::NEW_TILING_VERSION;
        auto initTilingPtr = static_cast<__gm__ Mc2InitTilingInner*>(initTiling);
        debugMode_ = initTilingPtr->debugMode;
        queueNum_ = initTilingPtr->queueNum;
        devType_ = initTilingPtr->devType;
    } else {
        version = HcclTilingVersion::DEPRECATED_TILING_VERSION;
        devType_ = HCCL_ASCEND910B;
    }

    hcclContext_ = (__gm__ HcclCombineOpParam *)context;
    ASCENDC_HCCL_API_ASSERT(hcclContext_ != nullptr, { return; }, "Init Hccl failed, context addr is nullptr.");
    InitInner(hcclContext_->workSpace, version);
}

template <const auto& config>
__aicore__ inline void HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::InitV2(
    GM_ADDR context, const void* initTiling)
{
    ASCENDC_HCCL_API_ASSERT(initTiling != nullptr, { return; },
                            "Call InitV2 failed, ensure initTiling is not nullptr!");
    const Mc2InitTilingInner *initTilingPtr = static_cast<const Mc2InitTilingInner *>(initTiling);
    debugMode_ = initTilingPtr->debugMode;
    queueNum_ = initTilingPtr->queueNum;
    devType_ = initTilingPtr->devType;
    tilingBaseAddr_ = reinterpret_cast<uint64_t>(initTiling);

    hcclContext_ = (__gm__ HcclCombineOpParam *)context;
    ASCENDC_HCCL_API_ASSERT(hcclContext_ != nullptr, { return; }, "Init Hccl failed, context addr is nullptr.");
    InitInner(hcclContext_->workSpace, HcclTilingVersion::ONLINE_COMPILATION_TILING_VERSION);
}

template <const auto& config>
__aicore__ inline int32_t HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::SetCcTiling(
    __gm__ void* ccOpTilingData)
{
    ASCENDC_HCCL_API_ASSERT(
        curVersion_ == HcclTilingVersion::NEW_TILING_VERSION, { return HCCL_FAILED; },
        "Call SetCcTiling failed, ensure Hccl::InitV1 func has been called successfully!");
    ASCENDC_HCCL_API_ASSERT(
        ccOpTilingData != nullptr, { return HCCL_FAILED; },
        "Call SetCcTiling failed, ensure ccOpTilingData is not nullptr");
    const uint32_t opType = (static_cast<__gm__ Mc2CcTilingInner*>(ccOpTilingData))->opType;
    ASCENDC_HCCL_API_ASSERT(
        opType < static_cast<uint32_t>(HcclCMDType::HCCL_CMD_ALL), { return HCCL_FAILED; },
        "Call SetCcTiling failed, ensure cmdType is valid");
    KERNEL_LOG(KERNEL_INFO, "CmdType = %d, ccOpTilingData = %lu ", opType, reinterpret_cast<uint64_t>(ccOpTilingData));
    ccOpTilingDataTable_[opType] = reinterpret_cast<uint64_t>(ccOpTilingData);
    return HCCL_SUCCESS;
}

template <const auto& config>
__aicore__ inline int32_t HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::SetCcTilingV2(uint64_t offset)
{
    ASCENDC_HCCL_API_ASSERT(
        curVersion_ == HcclTilingVersion::ONLINE_COMPILATION_TILING_VERSION, { return HCCL_FAILED; },
        "Call SetCcTiling failed, ensure Hccl::InitV2 func has been called successfully!");
    const uint32_t opType = (reinterpret_cast<Mc2CcTilingInner*>(tilingBaseAddr_ + offset))->opType;
    ASCENDC_HCCL_API_ASSERT(
        opType < static_cast<uint32_t>(HcclCMDType::HCCL_CMD_ALL), { return HCCL_FAILED; },
        "Call SetCcTiling failed, ensure cmdType is valid");
    ccOpTilingDataTable_[opType] = offset;
    return HCCL_SUCCESS;
}

template<const auto &config>
__aicore__ inline uint32_t HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::GetRankDim() {
    ASCENDC_HCCL_API_ASSERT(hcclContext_ != nullptr, { return UINT32_MAX; },
                            "Call GetRankDim failed, ensure InitV2 or Init has been called!");
    return hcclContext_->rankNum;
}

template <const auto& config>
template <ScopeType type>
__aicore__ inline void HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::QueueBarrier(uint16_t queueID)
{
    CommonPrepareParam param;
    param.commType.msgType = ControlMsgType::HCCL_CMD_BARRIER;
    SendMsgToServer(queueID, param);
    ++(curMsgPosition_[queueID]);
    ASCENDC_HCCL_API_ASSERT(
        curMsgPosition_[queueID] < HCCL_MSG_CNT, { return; }, "Message amount exceeds the maximum value when barrier.");
    if (workingFlag_) {
        UpdateControlMsgCount(hcclMsgArea_, ControlMsgType::HCCL_CMD_BARRIER);
    }
}

template <const auto& config>
template <bool sync>
__aicore__ inline int32_t HcclImpl<HcclServerType::HCCL_SERVER_TYPE_AICPU, config>::Iterate(
    HcclHandle handleId, uint16_t* seqSlices, uint16_t seqSliceLen)
{
    ASCENDC_HCCL_API_ASSERT(
        curVersion_ == HcclTilingVersion::NEW_TILING_VERSION ||
            curVersion_ == HcclTilingVersion::ONLINE_COMPILATION_TILING_VERSION,
        { return HCCL_FAILED; }, "Initialization has not been done properly.");
    ASCENDC_HCCL_API_ASSERT(
        seqSlices != nullptr && seqSliceLen != 0U, { return HCCL_FAILED; }, "Invalid param for Iterate.");
    const uint16_t stepSize = GetStepSizeByHandle(handleId);
    const uint16_t stepsPerRepeat = GetStepCntsPerRepeatByHandle(handleId);
    ASCENDC_HCCL_API_ASSERT(
        stepSize > 0U && stepsPerRepeat > 1U, { return HCCL_FAILED; }, "Handle id %d is not for fine-grained.",
        handleId);
    uint16_t& curSlice = handleId2CurrSliceId_[handleId];
    KERNEL_LOG(
        KERNEL_INFO, "The step size for handle %d is %u, current slice and total slices are %u/%u.", handleId, stepSize,
        curSlice, stepsPerRepeat);

    // Only for All2AllV + pairwise
    if (curSlice >= stepsPerRepeat * handleIdRepeat_[handleId]) {
        KERNEL_LOG(KERNEL_INFO, "The step id %u for handle id %d reach the maximum.", handleId, curSlice);
        return 0;
    }
    const uint16_t slicesPerRepeat = stepsPerRepeat;
    const uint32_t rankId = GetRankId();
    const uint32_t rankDim = GetRankDim();
    ASCENDC_HCCL_API_ASSERT(
        rankDim != 0U, { return HCCL_FAILED; }, "Invalid rank-dim.");
    for (uint16_t i = 0U; i < seqSliceLen; ++i) {
        if constexpr (sync) {
            if ((curSlice + 1) % stepSize == 0) {
                (void)Wait(handleId);
            }
            seqSlices[i] = (rankId + rankDim - curSlice % slicesPerRepeat) % rankDim;
        } else {
            seqSlices[i] = (rankId + curSlice % slicesPerRepeat) % rankDim;
        }
        ++curSlice;
    }
    return seqSliceLen;
}
}

#endif