LCOV - code coverage report
Current view: top level - base_comm/resources/comm_engine_res/threads - cpu_ts_thread.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.6 % 186 176
Test Date: 2026-08-18 17:47:01 Functions: 95.8 % 24 23

            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 "cpu_ts_thread.h"
      12              : #include "hccl_common.h"
      13              : #include "adapter_rts.h"
      14              : 
      15              : namespace hccl {
      16              : const std::unordered_map<HcclDataType, aclDataType> hccl2rtDataTypeMap = {
      17              :     {HCCL_DATA_TYPE_INT8, ACL_INT8},    {HCCL_DATA_TYPE_INT16, ACL_INT16}, {HCCL_DATA_TYPE_INT32, ACL_INT32},
      18              :     {HCCL_DATA_TYPE_FP16, ACL_FLOAT16}, {HCCL_DATA_TYPE_FP32, ACL_FLOAT},  {HCCL_DATA_TYPE_BFP16, ACL_BF16},
      19              : };
      20              : 
      21              : const std::unordered_map<HcclReduceOp, aclrtReduceKind> hccl2rtReduceOpMap = {
      22              :     {HCCL_REDUCE_SUM, ACL_RT_MEMCPY_SDMA_AUTOMATIC_SUM},
      23              :     {HCCL_REDUCE_MAX, ACL_RT_MEMCPY_SDMA_AUTOMATIC_MAX},
      24              :     {HCCL_REDUCE_MIN, ACL_RT_MEMCPY_SDMA_AUTOMATIC_MIN},
      25              : };
      26              : 
      27           11 : CpuTsThread::CpuTsThread(rtStream_t rtStream, uint32_t notifyNum, const NotifyLoadType notifyLoadType)
      28           11 :     : rtStream_(rtStream),
      29           11 :       notifyNum_(notifyNum),
      30           11 :       notifyLoadType_(notifyLoadType)
      31           11 : {}
      32              : 
      33           99 : CpuTsThread::CpuTsThread(StreamType streamType, uint32_t notifyNum, const NotifyLoadType notifyLoadType)
      34           99 :     : streamType_(streamType),
      35           99 :       notifyNum_(notifyNum),
      36           99 :       notifyLoadType_(notifyLoadType)
      37           99 : {}
      38              : 
      39          110 : CpuTsThread::~CpuTsThread() { DeInit(); }
      40              : 
      41           90 : HcclResult CpuTsThread::Init()
      42              : {
      43              :     // Host 侧初始化
      44           90 :     CHK_RET(GetRunSideIsDevice(isDeviceSide_));
      45           89 :     CHK_RET(hrtGetDeviceType(devType_));
      46           89 :     if (!isDeviceSide_) {
      47              :         s32 deviceLogicId;
      48           88 :         CHK_RET(hrtGetDevice(&deviceLogicId));
      49           88 :         CHK_RET(hrtGetDevicePhyIdByIndex(static_cast<uint32_t>(deviceLogicId), devId_));
      50           88 :         if (streamType_ == StreamType::STREAM_TYPE_DEVICE || notifyLoadType_ == NotifyLoadType::DEVICE_NOTIFY) {
      51            3 :             return HCCL_E_NOT_SUPPORT;
      52              :         }
      53           85 :         if (rtStream_ == nullptr) {
      54           76 :             stream_.reset(new (std::nothrow) Stream(streamType_));
      55           76 :             CHK_SMART_PTR_NULL(stream_);
      56           76 :             rtStream_ = stream_->ptr();
      57              :         } else {
      58            9 :             stream_.reset(new (std::nothrow) Stream(rtStream_));
      59            9 :             CHK_SMART_PTR_NULL(stream_);
      60              :         }
      61           85 :         notifys_.reserve(notifyNum_);
      62          267 :         for (uint32_t idx = 0; idx < notifyNum_; idx++) {
      63          184 :             notifys_.emplace_back(nullptr);
      64          184 :             notifys_[idx].reset(new (std::nothrow) LocalNotify());
      65          184 :             CHK_SMART_PTR_NULL(notifys_[idx]);
      66          184 :             CHK_RET(notifys_[idx]->Init(notifyLoadType_));
      67          182 :             if (devType_ != DevType::DEV_TYPE_950 && devType_ != DevType::DEV_TYPE_960) {
      68           55 :                 CHK_RET(notifys_[idx]->SetIpc());
      69              :             }
      70              :         }
      71           83 :         return HCCL_SUCCESS;
      72              :     } else {
      73            1 :         return HCCL_E_NOT_SUPPORT;
      74              :     }
      75              : }
      76              : 
      77          113 : HcclResult CpuTsThread::DeInit()
      78              : {
      79          113 :     streamType_ = StreamType::STREAM_TYPE_RESERVED;
      80          113 :     notifyNum_ = 0;
      81          113 :     stream_ = nullptr;
      82          113 :     notifys_.clear();
      83          113 :     return HCCL_SUCCESS;
      84              : }
      85              : 
      86            2 : std::string& CpuTsThread::GetUniqueId()
      87              : {
      88            2 :     if (!uniqueIdStr_.empty()) {
      89            0 :         return uniqueIdStr_;
      90              :     }
      91            2 :     return UpdateUniqueId();
      92              : }
      93              : 
      94           13 : std::string& CpuTsThread::UpdateUniqueId()
      95              : {
      96              :     // 序列化信息
      97           13 :     uniqueIdStr_ = std::string();
      98           13 :     std::ostringstream oss;
      99           13 :     StreamType streamType = StreamType::STREAM_TYPE_DEVICE;
     100           13 :     oss.write(reinterpret_cast<const char_t*>(&streamType), sizeof(streamType));
     101           13 :     oss.write(reinterpret_cast<const char_t*>(&notifyLoadType_), sizeof(notifyLoadType_));
     102           13 :     oss.write(reinterpret_cast<const char_t*>(&devId_), sizeof(devId_));
     103           13 :     oss.write(reinterpret_cast<const char_t*>(&notifyNum_), sizeof(notifyNum_));
     104              : 
     105              :     // 临时申请一条流,用于在device侧资源展开时initStream
     106           13 :     if (streamDevice_ == nullptr) {
     107            9 :         streamDevice_.reset(new (std::nothrow) Stream(streamType));
     108              :     }
     109           13 :     if (streamDevice_ == nullptr) {
     110            0 :         HCCL_ERROR("[CpuTsThread][%s]reset stream failed, stream type[%d]", __func__, streamType);
     111            0 :         return uniqueIdStr_;
     112              :     }
     113              : 
     114           13 :     uint64_t size = sizeof(SqCqeContext);
     115           13 :     if (sqCqeContext_.ptr() == nullptr) {
     116            9 :         sqCqeContext_ = DeviceMem::alloc(size);
     117              :     }
     118           13 :     if (sqCqeContext_.ptr() == nullptr) {
     119            0 :         HCCL_ERROR("[CpuTsThread][%s]alloc mem failed, mem size[%llu]", __func__, size);
     120            0 :         return uniqueIdStr_;
     121              :     }
     122           13 :     HcclResult ret = hrtMemSet(sqCqeContext_.ptr(), size, size);
     123           13 :     if (ret != HCCL_SUCCESS) {
     124            0 :         HCCL_ERROR("[CpuTsThread][%s]mem set failed, mem size[%llu], ptr[%p]", __func__, size, sqCqeContext_.ptr());
     125            0 :         return uniqueIdStr_;
     126              :     }
     127              : 
     128           13 :     HcclStreamParam streamParam;
     129           13 :     streamParam.streamInfo.streamIds = streamDevice_->id();
     130           13 :     streamParam.streamInfo.sqIds = streamDevice_->sqId();
     131           13 :     streamParam.streamInfo.cqIds = streamDevice_->cqId();
     132           13 :     streamParam.streamInfo.logicCqids = streamDevice_->logicCqId();
     133           13 :     streamParam.sqCqContextAddr = reinterpret_cast<uint64_t>(sqCqeContext_.ptr());
     134           13 :     streamParam.sqCqContextSize = sqCqeContext_.size();
     135           13 :     oss.write(reinterpret_cast<const char_t*>(&streamParam), sizeof(streamParam));
     136              : 
     137           13 :     ret = HCCL_SUCCESS;
     138           66 :     for (uint32_t idx = 0; idx < notifyNum_; idx++) {
     139              :         HcclSignalInfo notifyInfo;
     140           53 :         ret = notifys_[idx]->GetNotifyData(notifyInfo);
     141           53 :         if (ret != HCCL_SUCCESS) {
     142            0 :             HCCL_ERROR("[AicpuTsThread][UpdateUniqueId]GetNotifyData failed, ret[%d]", ret);
     143            0 :             uniqueIdStr_ = std::string();
     144            0 :             return uniqueIdStr_;
     145              :         }
     146           53 :         HCCL_INFO(
     147              :             "[AicpuTsThread][UpdateUniqueId]get local notify data success, resId[%u], tsId:%d, devId[%u]",
     148              :             notifyInfo.resId, notifyInfo.tsId, notifyInfo.devId);
     149           53 :         oss.write(reinterpret_cast<const char_t*>(&notifyInfo), sizeof(notifyInfo));
     150              :     }
     151           13 :     HCCL_DEBUG("[AicpuTsThread][UpdateUniqueId] stream[%p], notifyNum[%u]", stream_->ptr(), notifyNum_);
     152              : 
     153           13 :     uniqueIdStr_ = oss.str();
     154           13 :     return uniqueIdStr_;
     155           13 : }
     156              : 
     157           54 : uint32_t CpuTsThread::GetNotifyNum() const { return notifyNum_; }
     158              : 
     159            7 : LocalNotify* CpuTsThread::GetNotify(uint32_t index) const
     160              : {
     161            7 :     if (index >= notifyNum_) {
     162            2 :         HCCL_ERROR(
     163              :             "[CpuTsThread][GetNotify] notifyNum[%u], index[%u] out of range[0, %u]", notifyNum_, index, notifyNum_ - 1);
     164            2 :         return nullptr;
     165              :     }
     166            5 :     return notifys_[index].get();
     167              : }
     168              : 
     169           17 : bool CpuTsThread::IsDeviceA5() const { return devType_ == DevType::DEV_TYPE_950 || devType_ == DevType::DEV_TYPE_960; }
     170              : 
     171              : // A3 Stream
     172           54 : Stream* CpuTsThread::GetStream() const { return stream_.get(); }
     173              : 
     174              : // A5 Stream
     175            1 : void* CpuTsThread::GetStreamLitePtr() const
     176              : {
     177            1 :     return nullptr; // Not implemented
     178              : }
     179              : 
     180            1 : void CpuTsThread::LaunchTask() const { return; }
     181              : 
     182            1 : void CpuTsThread::TryLaunchTask() const
     183              : {
     184            1 :     HCCL_DEBUG("[%s] CpuTsThread does not support TryLaunchTask, skip", __func__);
     185            1 :     return;
     186              : }
     187              : 
     188              : // Local Data Plane Functions
     189            2 : HcclResult CpuTsThread::LocalNotifyRecord([[maybe_unused]] uint32_t notifyId) const
     190              : {
     191            2 :     HCCL_ERROR("[CpuTsThread][%s]not support", __func__);
     192            2 :     return HCCL_E_NOT_SUPPORT;
     193              : }
     194              : 
     195            2 : HcclResult CpuTsThread::LocalNotifyWait([[maybe_unused]] uint32_t notifyId) const
     196              : {
     197            2 :     HCCL_ERROR("[CpuTsThread][%s]not support", __func__);
     198            2 :     return HCCL_E_NOT_SUPPORT;
     199              : }
     200              : 
     201              : HcclResult
     202            2 : CpuTsThread::LocalNotifyRecord([[maybe_unused]] ThreadHandle dstThread, [[maybe_unused]] uint32_t dstNotifyIdx) const
     203              : {
     204              : #ifndef CCL_KERNEL_AICPU
     205            2 :     u64 beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
     206            2 :     HCCL_INFO("[%s]dstThread[0x%llu], dstNotifyIdx[%u].", __func__, dstThread, dstNotifyIdx);
     207            2 :     CHK_PRT_RET(
     208              :         !IsDeviceA5(), HCCL_ERROR("[CpuTsThread][%s]only support A5", __func__),
     209              :         HCCL_E_NOT_SUPPORT); // 只支持A5, 其他场景调用HcclLocalNotifyRecord
     210              : 
     211            1 :     Stream* stream = GetStream();
     212            1 :     CHK_PTR_NULL(stream);
     213            1 :     Thread* const dstThreadPtr = reinterpret_cast<Thread*>(dstThread);
     214            1 :     CHK_PTR_NULL(dstThreadPtr);
     215            1 :     LocalNotify* dstNotify = dstThreadPtr->GetNotify(dstNotifyIdx);
     216            1 :     CHK_PTR_NULL(dstNotify);
     217              : 
     218            1 :     HcclResult ret = dstNotify->Post(*stream);
     219            1 :     CHK_PRT_RET(
     220              :         ret != HCCL_SUCCESS,
     221              :         HCCL_ERROR("[%s]fail, dstThread[0x%llx], dstNotifyIdx[%u].", __func__, dstThread, dstNotifyIdx), ret);
     222              : 
     223              :     HcclSignalInfo signalInfo;
     224            1 :     CHK_RET(dstNotify->GetNotifyData(signalInfo));
     225            1 :     CHK_RET(ReportHostNotifyRecordTask(signalInfo.resId, beginTime, isMaster_));
     226              : #endif
     227            1 :     return HCCL_SUCCESS;
     228              : }
     229              : 
     230            2 : HcclResult CpuTsThread::LocalNotifyWait([[maybe_unused]] uint32_t notifyIdx, [[maybe_unused]] uint32_t timeOut) const
     231              : {
     232              : #ifndef CCL_KERNEL_AICPU
     233            2 :     u64 beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
     234            2 :     HCCL_INFO("[%s]notifyIdx[%u], timeOut[%u s].", __func__, notifyIdx, timeOut);
     235            2 :     CHK_PRT_RET(
     236              :         !IsDeviceA5(), HCCL_ERROR("[CpuTsThread][%s]only support A5", __func__),
     237              :         HCCL_E_NOT_SUPPORT); // 只支持A5, 其他场景调用HcclLocalNotifyWait
     238              : 
     239            1 :     Stream* stream = GetStream();
     240            1 :     CHK_PTR_NULL(stream);
     241            1 :     LocalNotify* notify = GetNotify(notifyIdx);
     242            1 :     CHK_PTR_NULL(notify);
     243              : 
     244            1 :     HcclResult ret = notify->Wait(*stream, timeOut);
     245            1 :     CHK_PRT_RET(
     246              :         ret != HCCL_SUCCESS, HCCL_ERROR("[%s]fail, notifyIdx[%u], timeOut[%u s].", __func__, notifyIdx, timeOut), ret);
     247              : 
     248              :     HcclSignalInfo signalInfo;
     249            1 :     CHK_RET(notify->GetNotifyData(signalInfo));
     250            1 :     CHK_RET(ReportHostNotifyWaitTask(signalInfo.resId, beginTime, isMaster_));
     251              : #endif
     252            1 :     return HCCL_SUCCESS;
     253              : }
     254              : 
     255            5 : HcclResult CpuTsThread::LocalCopy(
     256              :     [[maybe_unused]] void* dst, [[maybe_unused]] const void* src, [[maybe_unused]] uint64_t sizeByte) const
     257              : {
     258              : #ifndef CCL_KERNEL_AICPU
     259            5 :     u64 beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
     260            5 :     HCCL_INFO("[%s]dst[%p], src[%p], sizeByte[%llu].", __func__, dst, src, sizeByte);
     261            5 :     CHK_PRT_RET(
     262              :         !IsDeviceA5(), HCCL_ERROR("[CpuTsThread][%s]only support A5", __func__),
     263              :         HCCL_E_NOT_SUPPORT); // 只支持A5, 其他场景调用HcclLocalCopy
     264              : 
     265            4 :     if (sizeByte == 0 || src == dst) {
     266            2 :         HCCL_INFO("[CpuTsThread][%s]skip, dst[%p] equals src[%p] or len[%llu] equals 0", __func__, dst, src, sizeByte);
     267            2 :         return HCCL_SUCCESS;
     268              :     }
     269              : 
     270            2 :     Stream* stream = GetStream();
     271            2 :     CHK_PTR_NULL(stream);
     272            2 :     CHK_RET(hrtMemAsyncCopy(
     273              :         dst, sizeByte, src, sizeByte, HcclRtMemcpyKind::HCCL_RT_MEMCPY_KIND_DEVICE_TO_DEVICE, stream->ptr()));
     274              : 
     275            1 :     CHK_RET(ReportHostLocalCopyTask(dst, src, sizeByte, beginTime, isMaster_));
     276              : #endif
     277            1 :     return HCCL_SUCCESS;
     278              : }
     279              : 
     280            5 : HcclResult CpuTsThread::LocalReduce(
     281              :     [[maybe_unused]] void* dst, [[maybe_unused]] const void* src, [[maybe_unused]] uint64_t sizeByte,
     282              :     [[maybe_unused]] HcommDataType dataType, [[maybe_unused]] HcommReduceOp reduceOp) const
     283              : {
     284              : #ifndef CCL_KERNEL_AICPU
     285            5 :     u64 beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
     286            5 :     HCCL_INFO(
     287              :         "[%s]dst[%p], src[%p], sizeByte[%llu], dataType[%d], reduceOp[%d].", __func__, dst, src, sizeByte, dataType,
     288              :         reduceOp);
     289            5 :     CHK_PRT_RET(
     290              :         !IsDeviceA5(), HCCL_ERROR("[CpuTsThread][%s]only support A5", __func__),
     291              :         HCCL_E_NOT_SUPPORT); // 只支持A5, 其他场景调用HcclLocalCopyReduce
     292              : 
     293            4 :     auto dataTypeIt = hccl2rtDataTypeMap.find(static_cast<HcclDataType>(dataType));
     294            4 :     if (dataTypeIt == hccl2rtDataTypeMap.end()) {
     295            1 :         HCCL_ERROR(
     296              :             "[%s]data type[%s] is not supported", __func__,
     297              :             GetDataTypeEnumStr(static_cast<HcclDataType>(dataType)).c_str());
     298            1 :         return HCCL_E_PARA;
     299              :     }
     300              : 
     301            3 :     auto reduceOpIt = hccl2rtReduceOpMap.find(static_cast<HcclReduceOp>(reduceOp));
     302            3 :     if (reduceOpIt == hccl2rtReduceOpMap.end()) {
     303            1 :         HCCL_ERROR(
     304              :             "[%s]reduceOp[%s] is not supported", __func__,
     305              :             GetReduceOpEnumStr(static_cast<HcclReduceOp>(reduceOp)).c_str());
     306            1 :         return HCCL_E_PARA;
     307              :     }
     308              : 
     309            2 :     Stream* stream = GetStream();
     310            2 :     CHK_PTR_NULL(stream);
     311            2 :     CHK_RET(hrtReduceAsync(dst, sizeByte, src, sizeByte, reduceOpIt->second, dataTypeIt->second, stream->ptr()));
     312            1 :     CHK_RET(ReportHostLocalReduceTask(dst, src, sizeByte, dataType, reduceOp, beginTime, isMaster_));
     313              : #endif
     314            1 :     return HCCL_SUCCESS;
     315              : }
     316           10 : bool CpuTsThread::GetMaster() const { return isMaster_; }
     317              : 
     318            4 : void CpuTsThread::SetIsMaster(bool isMaster) { isMaster_ = isMaster; }
     319              : 
     320           13 : HcclResult CpuTsThread::SupplementNotify(uint32_t notifyNum)
     321              : {
     322           13 :     if (streamType_ == StreamType::STREAM_TYPE_DEVICE || notifyLoadType_ == NotifyLoadType::DEVICE_NOTIFY) {
     323            2 :         HCCL_ERROR("[%s]Does not support this interface.", __func__);
     324            2 :         return HCCL_E_NOT_SUPPORT;
     325              :     }
     326           11 :     HCCL_INFO("[%s]supplement notifyNum[%u], notifyNum_[%u]", __func__, notifyNum, notifyNum_);
     327              : 
     328           11 :     u32 currentNotifyNum = notifyNum_;
     329           11 :     notifyNum_ += notifyNum;
     330           11 :     notifys_.reserve(notifyNum_);
     331           28 :     for (uint32_t idx = currentNotifyNum; idx < notifyNum_; idx++) {
     332           17 :         notifys_.emplace_back(nullptr);
     333           17 :         notifys_[idx].reset(new (std::nothrow) LocalNotify());
     334           17 :         CHK_SMART_PTR_NULL(notifys_[idx]);
     335           17 :         CHK_RET(notifys_[idx]->Init(notifyLoadType_));
     336           17 :         if (devType_ != DevType::DEV_TYPE_950 && devType_ != DevType::DEV_TYPE_960) {
     337            3 :             CHK_RET(notifys_[idx]->SetIpc());
     338              :         }
     339              :     }
     340              : 
     341           11 :     uniqueIdStr_.clear();
     342           11 :     UpdateUniqueId();
     343           11 :     return HCCL_SUCCESS;
     344              : }
     345              : } // namespace hccl
        

Generated by: LCOV version 2.0-1