LCOV - code coverage report
Current view: top level - coll_communicator_mgr/resource_mgr/local/my_rank/comm_engine/threads - thread_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.1 % 374 322
Test Date: 2026-08-04 10:52:23 Functions: 100.0 % 23 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 "thread_manager.h"
      12              : #include <cstring>
      13              : #include "aicpu_launch_manager.h"
      14              : #include "independent_op.h"
      15              : #include "comm_engine_utils.h"
      16              : #include "hcomm_res.h"
      17              : 
      18              : namespace hccl {
      19              : 
      20              : 
      21          334 : ThreadMgr::ThreadMgr(uint32_t threadNum, uint32_t notifyNumPerThread, std::string commId, 
      22          334 :     aclrtBinHandle binHandle, const ManagerCallbacks& callbacks) : threadNum_(threadNum), notifyNumPerThread_(notifyNumPerThread), 
      23          334 :     commId_(commId), binHandle_(binHandle), callbacks_(callbacks){}
      24              : 
      25          334 : ThreadMgr::~ThreadMgr()
      26              : {
      27          334 :     auto it = dedicatedThreadMap_.find(HCCL_DED_THREAD_TYPE_AICPU_LAUNCH);
      28          334 :     if (it != dedicatedThreadMap_.end()) {
      29            5 :         ThreadHandle thread = it->second;
      30            5 :         HcommThreadFree(&thread, 1);
      31              :     }
      32          334 : }
      33              : 
      34           64 : uint64_t ThreadMgr::GetMaxNotifyTotal()
      35              : {
      36              :     // 如果没设定最大值,设置一下
      37           64 :     uint64_t maxNotifyTotal = 0;
      38           64 :     if (threadNum_ == HCCL_COMM_THREADNUM_CONFIG_NOT_SET &&
      39           13 :         notifyNumPerThread_ == HCCL_COMM_NOTIFY_NUM_PER_THREAD_CONFIG_NOT_SET) {
      40           13 :         maxNotifyTotal = HCCL_THREAD_NOTIFY_MAX_NUM;
      41           13 :         threadNum_ = SIGNAL_DEV_STREAM_MAX_NUM;
      42           13 :         notifyNumPerThread_ = HCCL_THREAD_NOTIFY_MAX_NUM;
      43              :     } else {
      44           51 :         maxNotifyTotal = static_cast<uint64_t>(threadNum_) * static_cast<uint64_t>(notifyNumPerThread_);
      45           51 :         maxNotifyTotal = maxNotifyTotal > HCCL_THREAD_NOTIFY_MAX_NUM ? HCCL_THREAD_NOTIFY_MAX_NUM : maxNotifyTotal;
      46              :     }
      47           64 :     return maxNotifyTotal;
      48              : }
      49              : 
      50           38 : HcclResult ThreadMgr::CheckNotifyNum(CommEngine engine, uint32_t threadNum, uint32_t notifyNumPerThread)
      51              : {
      52           38 :     uint64_t maxNotifyTotal = GetMaxNotifyTotal();
      53           38 :     const uint64_t used = usedNotifyNum_;
      54           38 :     uint64_t remainNotifyQuota = (maxNotifyTotal > used) ? (maxNotifyTotal - used) : 0;
      55           38 :     uint64_t needNotifyTotal = static_cast<uint64_t>(threadNum) * static_cast<uint64_t>(notifyNumPerThread);
      56           38 :     if (remainNotifyQuota < needNotifyTotal  || notifyNumPerThread > notifyNumPerThread_ ||
      57              :         maxNotifyTotal > HCCL_THREAD_NOTIFY_MAX_NUM) {
      58            1 :         HCCL_ERROR("[ThreadMgr][%s] Notify quota exhausted: remainQuota[%llu], total[%llu], used[%llu], need[%llu], " 
      59              :             "setPreNum[%u], allocPreNum[%u]", __func__, remainNotifyQuota, maxNotifyTotal, used, needNotifyTotal,
      60              :             notifyNumPerThread_, notifyNumPerThread);
      61            1 :         return HCCL_E_UNAVAIL;
      62              :     }
      63              : 
      64           37 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] HcclThreadAcquire quota: engine[%s], "
      65              :         "remainNotifyQuota[%llu]", __func__, commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), remainNotifyQuota);
      66           37 :     return HCCL_SUCCESS;
      67              : }
      68              : 
      69           26 : HcclResult ThreadMgr::CheckThreadNum(CommEngine engine, uint32_t threadNum, uint32_t notifyNumPerThread)
      70              : {
      71           26 :     GetMaxNotifyTotal();
      72           26 :     uint32_t remainQuota = (threadNum_ > threads_.size()) ? (threadNum_ - threads_.size()) : 0;
      73           26 :     if (remainQuota == 0 || threadNum > remainQuota) {
      74            0 :         HCCL_ERROR("[ThreadMgr][%s] Threads quota exhausted: remainQuota[%u], need[%u].",
      75              :             __func__, remainQuota, threadNum);
      76            0 :         return HCCL_E_UNAVAIL;
      77              :     }
      78              : 
      79           26 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] HcclThreadAcquire quota: engine[%s] threadNum[%u].",
      80              :         __func__, commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), remainQuota);
      81           26 :     return CheckNotifyNum(engine, threadNum, notifyNumPerThread);
      82              : }
      83              : 
      84            6 : HcclResult ThreadMgr::SupplementNotify(CommEngine engine, std::vector<std::shared_ptr<Thread>> &needSupplementThread)
      85              : {
      86            6 :     HcclResult ret = HCCL_E_INTERNAL;
      87              :     // thread资源 AICPU侧展开
      88            6 :     if ((engine == COMM_ENGINE_AICPU) && needSupplementThread.size() > 0) {
      89            2 :         if (!callbacks_.getAicpuCommState()) {
      90            0 :             HCCL_INFO("ThreadMgr::SupplementNotify kernelLaunchAicpuCommInit start");
      91            0 :             ret = callbacks_.kernelLaunchAicpuCommInit();
      92            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS, 
      93              :                 HCCL_ERROR("[%s] kernelLaunchAicpuCommInit failed, return [%d].", __func__, ret), ret);
      94            0 :             callbacks_.setAicpuCommState(true);
      95              :         }
      96              : 
      97            2 :         std::unique_ptr<ThreadHandle[]> threadHandle;
      98            2 :         EXCEPTION_CATCH(threadHandle = std::make_unique<ThreadHandle[]>(needSupplementThread.size()),
      99              :             return HCCL_E_PTR);
     100            8 :         for (size_t i = 0; i < needSupplementThread.size(); ++i) {
     101            6 :             threadHandle[i] = hostToDeviceThreadHandle_[reinterpret_cast<ThreadHandle>(needSupplementThread[i].get())];
     102              :         }
     103            2 :         HCCL_INFO("ThreadMgr::SupplementNotify ThreadKernelLaunchForComm start needSupplementThread size[%zu]",
     104              :             needSupplementThread.size());
     105            2 :         ret = AicpuLaunchMgr::SupplementNotifyKernelLaunch(needSupplementThread, commId_, threadHandle, binHandle_);
     106            2 :         HCCL_INFO("ThreadMgr::SupplementNotify ThreadKernelLaunchForComm end");
     107            2 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     108              :             HCCL_ERROR("[ThreadMgr][SupplementNotify] AiCpuKernelLaunch failed, return [%d].", ret), ret);
     109            2 :     }
     110            6 :     return HCCL_SUCCESS;
     111              : }
     112              : 
     113            6 : HcclResult ThreadMgr::SupplementNotify(CommEngine engine, uint32_t threadNum, ThreadType type,
     114              :     const ThreadConfig *config)
     115              : {
     116              :     NotifyLoadType notifyLoadType;
     117            6 :     CHK_RET(GetNotifyLoadType(engine, type, notifyLoadType));
     118            6 :     std::vector<std::shared_ptr<Thread>> &threads = engineToThreadsMap_[std::make_pair(engine, type)];
     119            6 :     std::vector<std::shared_ptr<Thread>> needSupplementThread;
     120            6 :     HcclResult ret = HCCL_E_INTERNAL;
     121            6 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] threadNum[%zu] notifyLoadType[%d]",
     122              :         __func__, commId_.c_str(), threads.size(), static_cast<int32_t>(notifyLoadType));
     123              : 
     124            6 :     DevType devType = DevType::DEV_TYPE_COUNT;
     125            6 :     CHK_RET(hrtGetDeviceType(devType));
     126            0 :     u32 aicpuHostNotify = ((devType == DevType::DEV_TYPE_950 || devType == DevType::DEV_TYPE_960) &&
     127            6 :                            (engine == COMM_ENGINE_AICPU)) ? 1 : 0;
     128              : 
     129           22 :     for (size_t i = 0; i < threads.size() && i < threadNum; ++i) {
     130           16 :         HCCL_INFO("[ThreadMgr][%s] Hcom[%s] AicpuTsThread[%u] notifyLoadType[%d] notifyNum[%u]",
     131              :             __func__, commId_.c_str(), static_cast<uint32_t>(i), static_cast<int32_t>(notifyLoadType), config[i].notifyNumPerThread);
     132           16 :         u32 notifyNum = threads[i]->GetNotifyNum() >= aicpuHostNotify ?
     133           16 :             (threads[i]->GetNotifyNum() - aicpuHostNotify) : 0;
     134           16 :         if (config[i].notifyNumPerThread > notifyNum) {
     135           12 :             u32 supplementNotifyNum = config[i].notifyNumPerThread - notifyNum;
     136           12 :             CHK_RET(CheckNotifyNum(engine, 1, supplementNotifyNum));
     137           12 :             ret = threads[i]->SupplementNotify(supplementNotifyNum);
     138           12 :             if (ret != HCCL_SUCCESS) {
     139            0 :                 HCCL_ERROR("[ThreadMgr][%s] Failed to supplement notify[%u] on thread index[%u], ret[%d]",
     140              :                     __func__, supplementNotifyNum, i, ret);
     141            0 :                 return ret;
     142              :             }
     143           12 :             needSupplementThread.push_back(threads[i]);
     144           12 :             usedNotifyNum_ += supplementNotifyNum;
     145              :         }
     146              :     }
     147            6 :     CHK_RET(SupplementNotify(engine, needSupplementThread));
     148            6 :     return HCCL_SUCCESS;
     149            6 : }
     150              : 
     151           14 : HcclResult ThreadMgr::SupplementThread(CommEngine engine, std::vector<std::shared_ptr<Thread>> &newThreads,
     152              :     std::unique_ptr<ThreadHandle[]> &hostHandle)
     153              : {
     154              :     // thread资源 AICPU侧展开
     155           14 :     if (engine == COMM_ENGINE_AICPU) {
     156            4 :         HcclResult ret = HCCL_E_INTERNAL;
     157            4 :         if (!callbacks_.getAicpuCommState()) {
     158            0 :             HCCL_INFO("ThreadMgr::HcclAllocThreadRes kernelLaunchAicpuCommInit start");
     159            0 :             ret = callbacks_.kernelLaunchAicpuCommInit();
     160            0 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     161              :                 HCCL_ERROR("[%s] kernelLaunchAicpuCommInit failed, return [%d].", __func__, ret), ret);
     162            0 :             callbacks_.setAicpuCommState(true);
     163              :         }
     164              : 
     165            4 :         EXCEPTION_CATCH(hostHandle = std::make_unique<ThreadHandle[]>(newThreads.size()),
     166              :             return HCCL_E_PTR);
     167            4 :         HCCL_INFO("ThreadMgr::HcclAllocThreadRes ThreadKernelLaunchForComm start");
     168            4 :         ret = AicpuLaunchMgr::ThreadKernelLaunchForComm(newThreads, commId_, hostHandle, binHandle_);
     169            4 :         HCCL_INFO("ThreadMgr::HcclAllocThreadRes ThreadKernelLaunchForComm end");
     170            4 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     171              :             HCCL_ERROR("[ThreadMgr][HcclThreadAcquire] AiCpuKernelLaunch failed, return [%d].", ret), ret);
     172              :     }
     173           14 :     return HCCL_SUCCESS;
     174              : }
     175              : 
     176           14 : HcclResult ThreadMgr::SupplementThread(CommEngine engine, uint32_t supplementThreadNum, ThreadType type,
     177              :     const ThreadConfig *config)
     178              : {
     179              :     NotifyLoadType notifyLoadType;
     180              :     StreamType streamType;
     181           14 :     CHK_RET(GetNotifyLoadType(engine, type, notifyLoadType));
     182           14 :     CHK_RET(GetStreamType(engine, type, streamType));
     183           14 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] supplementThreadNum[%u] notifyLoadType[%d], streamType[%d]", __func__, 
     184              :         commId_.c_str(), supplementThreadNum, static_cast<int32_t>(notifyLoadType), static_cast<int32_t>(streamType));
     185           14 :     std::vector<std::shared_ptr<Thread>> newThreads;
     186           14 :     newThreads.reserve(supplementThreadNum);
     187           14 :     HcclResult ret = HCCL_E_INTERNAL;
     188              : 
     189           33 :     for (uint32_t i = 0; i < supplementThreadNum; ++i) {
     190           19 :         std::shared_ptr<Thread> handle;
     191           19 :         HCCL_INFO("[ThreadMgr][%s] Hcom[%s] [%u]notifyLoadType[%d], streamType[%d] notifyNum[%u]", __func__, 
     192              :             commId_.c_str(), i, static_cast<int32_t>(notifyLoadType),
     193              :             static_cast<int32_t>(streamType), config[i].notifyNumPerThread);
     194           19 :         CHK_RET(CheckThreadNum(engine, 1, config[i].notifyNumPerThread));
     195           19 :         CHK_RET(CreateThread(engine, streamType, config[i].notifyNumPerThread, notifyLoadType, handle));
     196           19 :         ret = handle->Init();
     197           19 :         if (ret != HCCL_SUCCESS) {
     198            0 :             HCCL_ERROR("[ThreadMgr][HcclThreadAcquire] Failed to init thread index[%u], ret[%d]", i, ret);
     199            0 :             return ret;
     200              :         }
     201           19 :         usedNotifyNum_ += config[i].notifyNumPerThread;
     202           19 :         newThreads.emplace_back(std::move(handle));
     203           19 :     }
     204              : 
     205           14 :     std::unique_ptr<ThreadHandle[]> hostHandle;
     206           14 :     CHK_RET(SupplementThread(engine, newThreads, hostHandle));
     207           14 :     threads_.reserve(threads_.size() + newThreads.size());
     208           14 :     auto iter = engineToThreadsMap_.find(std::make_pair(engine, type));
     209           14 :     if (iter == engineToThreadsMap_.end()) {
     210            0 :         HCCL_ERROR("[SupplementThread] engine+type pair not found in engineToThreadsMap_ "
     211              :             "engine[%d], type[%d].", engine, type);
     212            0 :         return HCCL_E_INTERNAL;
     213              :     }
     214           14 :     auto &threadVec = iter->second;
     215           14 :     threadVec.reserve(threadVec.size() + newThreads.size());
     216           14 :     threadVec.insert(threadVec.end(), newThreads.begin(), newThreads.end());
     217           14 :     threads_.insert(threads_.end(), newThreads.begin(), newThreads.end());
     218              : 
     219           14 :     if (engine == COMM_ENGINE_AICPU) {
     220            9 :         for (size_t i = 0; i < newThreads.size(); ++i) {
     221            5 :             ThreadHandle cpuTsHandle = reinterpret_cast<ThreadHandle>(newThreads[i].get());
     222            5 :             newThreads[i]->AddThreadHandleToMap(engine, hostHandle[i]);
     223            5 :             hostToDeviceThreadHandle_[cpuTsHandle] = hostHandle[i];
     224            5 :             threadHandleOthersToCpu_[hostHandle[i]] = cpuTsHandle;
     225              :         }
     226              :     }
     227           14 :     return HCCL_SUCCESS;
     228           14 : }
     229              : 
     230           16 : HcclResult ThreadMgr::HcclThreadAcquireV2(CommEngine engine, uint32_t threadNum, ThreadType type,
     231              :     const ThreadConfig *config, ThreadHandle *threads, std::vector<uint32_t> &threadId)
     232              : {
     233           16 :     CHK_PTR_NULL(threads);
     234           16 :     CHK_PTR_NULL(config);
     235           16 :     if (threadNum == 0) {
     236            0 :         HCCL_ERROR("[ThreadMgr][HcclThreadAcquire] threadNum is 0");
     237            0 :         return HCCL_E_PARA;
     238              :     }
     239              : 
     240           51 :     for (u32 i = 0; i < threadNum; ++i) {
     241           35 :         CHK_PRT_RET(config[i].header.magicWord != HCOMM_THREAD_CONFIG_MAGIC_WORD,
     242              :             HCCL_ERROR("[ThreadMgr][%s] config[%u] magicWord[0x%x] mismatch, expected[0x%x]",
     243              :             __func__, i, config[i].header.magicWord, HCOMM_THREAD_CONFIG_MAGIC_WORD), HCCL_E_PARA);
     244              :     }
     245              : 
     246           16 :     std::lock_guard<std::mutex> lock(threadMutex_);
     247           16 :     std::lock_guard<std::mutex> lockMap(threadMapMutex_);
     248           16 :     std::lock_guard<std::mutex> engineToThreadMtx(engineToThreadMutex_);
     249           16 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] HcclThreadAcquire begin, max: engine[%s] threadNum[%u],"
     250              :         "notifyPerThread[%u], need: threadNum[%u], threadType[%d]",
     251              :         __func__, commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), threadNum_, notifyNumPerThread_, threadNum, static_cast<int32_t>(type));
     252              : 
     253              :     // 1、thread上的notify数量不够,需要给thread补充notify
     254           16 :     auto it = engineToThreadsMap_.find(std::make_pair(engine, type));
     255           16 :     if (it == engineToThreadsMap_.end()) {
     256           10 :         it = engineToThreadsMap_.emplace(std::make_pair(engine, type), std::vector<std::shared_ptr<Thread>>{}).first;
     257              :     }
     258           16 :     auto &threadVec = it->second;
     259           16 :     if (threadVec.size() > 0) {
     260              :         // 调用补充函数,如果engine是COMM_ENGINE_AICPU,需要去device恢复
     261            6 :         CHK_RET(SupplementNotify(engine, threadNum, type, config));
     262              :     }
     263              : 
     264              :     // 2、补充thread
     265           16 :     if (threadVec.size() < threadNum) {
     266           14 :         u32 supplementThreadNum = threadNum - threadVec.size();
     267              :         // 调用补充函数,如果engine是COMM_ENGINE_AICPU,需要去device恢复
     268           14 :         CHK_RET(SupplementThread(engine, supplementThreadNum, type, &config[threadVec.size()]));
     269              :     }
     270              :     // 3、返回threadHandle和id
     271           51 :     for (u32 idx = 0; idx < threadNum; idx++) {
     272           35 :         ThreadHandle handle = reinterpret_cast<ThreadHandle>(threadVec[idx].get());
     273           35 :         threads[idx] = (engine == COMM_ENGINE_AICPU) ?
     274           13 :             hostToDeviceThreadHandle_[handle] : handle;
     275           35 :         uint32_t id = threadVec[idx]->GetStream()->sqId();
     276           35 :         HCCL_DEBUG("[%s]idx[%u] threadHandle[%llu] thread id = [%u]", __func__, idx, threads[idx], id);
     277           35 :         threadId.push_back(id);
     278              : 
     279           35 :         std::lock_guard<std::mutex> threadhandleToThreadMtx(threadhandleToThreadMutex_);
     280           35 :         threadMap_[threads[idx]] = threadVec[idx];
     281           35 :     }
     282              : 
     283           16 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] HcclThreadAcquire done: engine[%s] threadNum[%u]%s",
     284              :         __func__, commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), threadNum,
     285              :         (engine == COMM_ENGINE_AICPU) ? " (AICPU token ready)" : "");
     286           16 :     return HCCL_SUCCESS;
     287           16 : }
     288              : 
     289            5 : HcclResult ThreadMgr::CreateAndInitThreads(CommEngine engine, StreamType streamType,
     290              :     NotifyLoadType notifyLoadType, uint32_t threadNum, const ThreadConfig *config,
     291              :     std::vector<std::shared_ptr<Thread>> &newThreads)
     292              : {
     293           11 :     for (uint32_t i = 0; i < threadNum; ++i) {
     294            7 :         std::shared_ptr<Thread> handle;
     295            7 :         HCCL_INFO("[ThreadMgr][%s] Hcom[%s] AicpuTsThread notifyLoadType[%d], streamType[%d], notifyPerThread[%u]",
     296              :                 __func__, commId_.c_str(), static_cast<int32_t>(notifyLoadType), static_cast<int32_t>(streamType),
     297              :                 config[i].notifyNumPerThread);
     298            7 :         CHK_RET(CheckThreadNum(engine, 1, config[i].notifyNumPerThread));
     299            6 :         CHK_RET(CreateThread(engine, streamType, config[i].notifyNumPerThread, notifyLoadType, handle));
     300            6 :         HcclResult ret = handle->Init();
     301            6 :         if (ret != HCCL_SUCCESS) {
     302            0 :             HCCL_ERROR("[ThreadMgr][HcclThreadAcquire] Failed to init thread index %u", i);
     303            0 :             return ret;
     304              :         }
     305            6 :         usedNotifyNum_ += config[i].notifyNumPerThread;
     306            6 :         newThreads.emplace_back(std::move(handle));
     307            7 :     }
     308            4 :     return HCCL_SUCCESS;
     309              : }
     310              : 
     311            4 : HcclResult ThreadMgr::AssignThreadHandles(CommEngine engine,
     312              :     std::vector<std::shared_ptr<Thread>> &newThreads, ThreadHandle *threads,
     313              :     std::unique_ptr<ThreadHandle[]> &hostHandle)
     314              : {
     315            4 :     if (engine == COMM_ENGINE_AICPU) {
     316            0 :         CHK_RET(SupplementThread(engine, newThreads, hostHandle));
     317            0 :         for (size_t i = 0; i < newThreads.size(); ++i) {
     318            0 :             threads[i] = hostHandle[i];
     319            0 :             HCCL_INFO("[ThreadMgr][%s] aicpu threadArray[%u] = [%llu]", __func__, i, threads[i]);
     320              :         }
     321              :     } else {
     322           10 :         for (size_t i = 0; i < newThreads.size(); ++i) {
     323            6 :             threads[i] = reinterpret_cast<ThreadHandle>(newThreads[i].get());
     324            6 :             HCCL_INFO("[ThreadMgr][%s] host threadArray[%u] = [%llu]", __func__, i, threads[i]);
     325              :         }
     326              :     }
     327            4 :     return HCCL_SUCCESS;
     328              : }
     329              : 
     330            4 : HcclResult ThreadMgr::StoreThreadsAndBuildHandleMap(CommEngine engine,
     331              :     std::vector<std::shared_ptr<Thread>> &newThreads,
     332              :     std::unique_ptr<ThreadHandle[]> &hostHandle)
     333              : {
     334            4 :     auto threadsIt = threads_.insert(threads_.end(),
     335              :                     std::make_move_iterator(newThreads.begin()),
     336              :                     std::make_move_iterator(newThreads.end()));
     337              : 
     338            4 :     if (engine == COMM_ENGINE_AICPU) {
     339            0 :         for (size_t i = 0; i < newThreads.size(); ++i, ++threadsIt) {
     340            0 :             ThreadHandle cpuTsHandle = reinterpret_cast<ThreadHandle>((*threadsIt).get());
     341            0 :             (*threadsIt)->AddThreadHandleToMap(engine, hostHandle[i]);
     342            0 :             hostToDeviceThreadHandle_[cpuTsHandle] = hostHandle[i];
     343            0 :             threadHandleOthersToCpu_[hostHandle[i]] = cpuTsHandle;
     344              :         }
     345              :     }
     346            4 :     return HCCL_SUCCESS;
     347              : }
     348              : 
     349            5 : HcclResult ThreadMgr::HcclThreadAcquire(CommEngine engine, uint32_t threadNum, ThreadType type,
     350              :     const ThreadConfig *config, ThreadHandle *threads, std::vector<uint32_t> &threadId)
     351              : {
     352            5 :     CHK_PTR_NULL(threads);
     353            5 :     CHK_PTR_NULL(config);
     354            5 :     std::lock_guard<std::mutex> lock(threadMutex_);
     355            5 :     std::lock_guard<std::mutex> lockMap(threadMapMutex_);
     356            5 :     HCCL_INFO("[ThreadMgr][%s] Hcom[%s] HcclThreadAcquire begin, max: engine[%d] threadNum[%u],"
     357              :         "notifyPerThread[%u], need: threadNum[%u], threadType[%d]",
     358              :         __func__, commId_.c_str(), engine, threadNum_, notifyNumPerThread_, threadNum, static_cast<int32_t>(type));
     359              : 
     360            5 :     if (threadNum == 0) {
     361            0 :         HCCL_ERROR("[ThreadMgr][HcclThreadAcquire] threadNum is 0");
     362            0 :         return HCCL_E_PARA;
     363              :     }
     364              : 
     365           12 :     for (u32 i = 0; i < threadNum; ++i) {
     366            7 :         CHK_PRT_RET(config[i].header.magicWord != HCOMM_THREAD_CONFIG_MAGIC_WORD,
     367              :             HCCL_ERROR("[ThreadMgr][%s] config[%u] magicWord[0x%x] mismatch, expected[0x%x]",
     368              :                 __func__, i, config[i].header.magicWord, HCOMM_THREAD_CONFIG_MAGIC_WORD), HCCL_E_PARA);
     369              :     }
     370              : 
     371              :     NotifyLoadType notifyLoadType;
     372              :     StreamType streamType;
     373            5 :     CHK_RET(GetNotifyLoadType(engine, type, notifyLoadType));
     374            5 :     CHK_RET(GetStreamType(engine, type, streamType));
     375              : 
     376            5 :     std::vector<std::shared_ptr<Thread>> newThreads;
     377            5 :     newThreads.reserve(threadNum);
     378            5 :     CHK_RET(CreateAndInitThreads(engine, streamType, notifyLoadType, threadNum, config, newThreads));
     379              : 
     380            4 :     std::unique_ptr<ThreadHandle[]> hostHandle;
     381            4 :     CHK_RET(AssignThreadHandles(engine, newThreads, threads, hostHandle));
     382              : 
     383           10 :     for (size_t i = 0; i < newThreads.size(); ++i) {
     384            6 :         uint32_t id = newThreads[i]->GetStream()->id();
     385            6 :         HCCL_DEBUG("[%s] thread id = [%u]", __func__, id);
     386            6 :         threadId.push_back(id);
     387              :     }
     388            4 :     threads_.reserve(threads_.size() + newThreads.size());
     389            4 :     CHK_RET(StoreThreadsAndBuildHandleMap(engine, newThreads, hostHandle));
     390              : 
     391            4 :     HCCL_INFO("[ThreadMgr][HcclThreadAcquire] Hcom[%s] HcclThreadAcquire done: engine[%s] threadNum[%u]%s",
     392              :         commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), threadNum, (engine == COMM_ENGINE_AICPU) ? " (AICPU token ready)" : "");
     393            4 :     return HCCL_SUCCESS;
     394            5 : }
     395              : 
     396            4 : HcclResult ThreadMgr::HcclGetNotifyNumInThread(ThreadHandle thread, uint32_t *notifyNum)
     397              : {
     398            4 :     CHK_PTR_NULL(notifyNum);
     399            4 :     Thread* hcclThread = reinterpret_cast<Thread*>(thread);
     400            4 :     CHK_PTR_NULL(hcclThread);
     401            3 :     *notifyNum = hcclThread->GetNotifyNum();
     402            3 :     HCCL_INFO("[ThreadMgr] Hcom[%s] HcclGetNotifyNumInThread done: notifyPerThread[%u]",
     403              :         commId_.c_str(),  *notifyNum);
     404            3 :     return HCCL_SUCCESS;
     405              : }
     406              : 
     407            3 : HcclResult ThreadMgr::HcclThreadAcquireWithStream(CommEngine engine,
     408              :     rtStream_t stream, uint32_t notifyNum, ThreadHandle *thread)
     409              : {
     410            3 :     CHK_PTR_NULL(thread);
     411              : 
     412            3 :     if (mainThread_.find(stream) != mainThread_.end()) {
     413            0 :         if (mainThread_[stream]->GetNotifyNum() < notifyNum) {
     414            0 :             u32 supplementNotifyNum = notifyNum - mainThread_[stream]->GetNotifyNum();
     415            0 :             CHK_RET(mainThread_[stream]->SupplementNotify(supplementNotifyNum));
     416              :         }
     417            0 :         *thread = reinterpret_cast<ThreadHandle>(mainThread_[stream].get());
     418            0 :         return HCCL_SUCCESS;
     419              :     }
     420              : 
     421              :     NotifyLoadType notifyLoadType;
     422            3 :     CHK_RET(CommHostEngineToNotifyLoadType(engine, notifyLoadType));
     423            3 :     std::shared_ptr<CpuTsThread> handle;
     424            3 :     EXCEPTION_CATCH(handle = std::make_shared<CpuTsThread>(stream, notifyNum, notifyLoadType), return HCCL_E_PTR);
     425            3 :     CHK_RET(handle->Init());
     426            3 :     handle->SetIsMaster(true);
     427              : 
     428              :     // 返回第一个句柄
     429            3 :     std::lock_guard<std::mutex> lock(mainThreadMutex_);
     430            3 :     mainThread_.emplace(stream, std::move(handle));
     431            3 :     *thread = reinterpret_cast<ThreadHandle>(mainThread_[stream].get());
     432            3 :     std::lock_guard<std::mutex> threadhandleToThreadMtx(threadhandleToThreadMutex_);
     433            3 :     threadMap_[*thread] = mainThread_[stream];
     434            3 :     HCCL_INFO("[ThreadMgr] Hcom[%s] HcclThreadAcquireWithStream done: engine[%s] stream[%p],"
     435              :         "notifyNum[%u]", commId_.c_str(), GetEnumToString(GetCommEngineStatusStrMap(), engine).c_str(), stream, notifyNum);
     436            3 :     return HCCL_SUCCESS;
     437            3 : }
     438              : 
     439            2 : HcclResult ThreadMgr::ThreadExportToCommEngineCpu(uint32_t threadNum, const ThreadHandle *threads, ThreadHandle *exportedThreads)
     440              : {
     441            2 :     std::lock_guard<std::mutex> lock(threadMapMutex_);
     442            3 :     for (u32 i = 0; i < threadNum; i++) {
     443            2 :         if (threadHandleOthersToCpu_.find(threads[i]) == threadHandleOthersToCpu_.end()) {
     444            1 :             HCCL_ERROR("[CommEngineResMgr]%s Unknown ThreadHandle[%llu]", __func__, threads[i]);
     445            1 :             return HCCL_E_PARA;
     446              :         }
     447            1 :         exportedThreads[i] = threadHandleOthersToCpu_[threads[i]];
     448              :     }
     449            1 :     return HCCL_SUCCESS;
     450            2 : }
     451              : 
     452            4 : HcclResult ThreadMgr::GetExportedThread(const ThreadHandle threadHandle, CommEngine commEngine, Thread *&exportedThread, std::shared_ptr<Thread> &threadOut)
     453              : {
     454            4 :     Thread *threadPtr = reinterpret_cast<Thread *>(threadHandle);
     455            4 :     for (auto &thread : threads_) {
     456            0 :         if (thread.get() == threadPtr) {
     457            0 :             exportedThread = thread->FindThreadByCommEngine(commEngine);
     458            0 :             threadOut = thread;
     459            0 :             return HCCL_SUCCESS;
     460              :         }
     461              :     }
     462              : 
     463            4 :     for (auto &pair : mainThread_) {
     464            2 :         if (pair.second.get() == threadPtr) {
     465            2 :             exportedThread = pair.second->FindThreadByCommEngine(commEngine);
     466            2 :             threadOut = pair.second;
     467            2 :             return HCCL_SUCCESS;
     468              :         }
     469              :     }
     470              : 
     471            2 :     HCCL_ERROR("[ThreadMgr][%s]Unknown ThreadHandle[%llu]", __func__, threadHandle);
     472            2 :     return HCCL_E_PARA;
     473              : }
     474              : 
     475            4 : HcclResult ThreadMgr::ThreadExportToCommEngineAicpu(uint32_t threadNum, const ThreadHandle *threads, CommEngine dstCommEngine, ThreadHandle *exportedThreads)
     476              : {
     477            4 :     std::vector<std::shared_ptr<Thread>> hostThreads;
     478            4 :     std::vector<u32> index;
     479              :     Thread *exportedThread;
     480            6 :     for (u32 i = 0; i < threadNum; i++) {
     481            4 :         std::shared_ptr<Thread> handle;
     482            4 :         CHK_RET(GetExportedThread(threads[i], dstCommEngine, exportedThread, handle));
     483            2 :         if (exportedThread != nullptr) {
     484            0 :             exportedThreads[i] = reinterpret_cast<ThreadHandle>(exportedThread);
     485            0 :             continue;
     486              :         } else {
     487            2 :             hostThreads.push_back(handle);
     488            2 :             index.push_back(i);
     489              :         }
     490            4 :     }
     491            2 :     if (!hostThreads.empty()) {
     492            2 :         std::lock_guard<std::mutex> lock(threadMapMutex_);
     493            2 :         if (!callbacks_.getAicpuCommState()) {
     494            1 :             HcclResult ret = callbacks_.kernelLaunchAicpuCommInit();
     495            1 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     496              :                         HCCL_ERROR("[%s] kernelLaunchAicpuCommInit failed, return [%d].", __func__, ret), ret);
     497            1 :             callbacks_.setAicpuCommState(true);
     498              :         }
     499            2 :         std::unique_ptr<ThreadHandle[]> aicpuHandle;
     500            2 :         EXCEPTION_CATCH(aicpuHandle = std::make_unique<ThreadHandle[]>(hostThreads.size()),
     501              :                          return HCCL_E_PTR);
     502            2 :         uint64_t beginTime = Hccl::DlProfFunction::GetInstance().dlMsprofSysCycleTime();
     503            2 :         HcclResult ret = AicpuLaunchMgr::ThreadKernelLaunchForComm(hostThreads, commId_, aicpuHandle, binHandle_);
     504            2 :         CHK_PRT_RET(ret != HCCL_SUCCESS,
     505              :                     HCCL_ERROR("[ThreadMgr][HcclThreadExportToCommEngine] AiCpuKernelLaunch failed, return [%d].", ret), ret);
     506            2 :         if (callbacks_.reportProfilingKernel != nullptr) {
     507            2 :             ret = callbacks_.reportProfilingKernel(beginTime, "RunAicpuIndOpThreadInit");
     508            1 :             CHK_PRT_RET(ret != HCCL_SUCCESS,
     509              :                 HCCL_ERROR("[ThreadMgr][HcclThreadExportToCommEngine] ReportProfilingAiCpuKernelLaunch failed, return [%d].", ret), ret);
     510              :         }
     511            4 :         for (size_t i = 0; i < hostThreads.size(); ++i) {
     512            2 :             exportedThreads[index[i]] = aicpuHandle[i];
     513            2 :             CHK_RET(hostThreads[i]->AddThreadHandleToMap(dstCommEngine, aicpuHandle[i]));
     514            2 :             threadHandleOthersToCpu_[aicpuHandle[i]] = threads[index[i]];
     515            2 :             HCCL_INFO("[ThreadMgr][%s] aicpu threadArray[%u] = [%llu]", __func__, i, aicpuHandle[i]);
     516              :         }
     517            2 :     }
     518            2 :     return HCCL_SUCCESS;
     519            4 : }
     520              : 
     521            6 : HcclResult ThreadMgr::HcclThreadExportToCommEngine(uint32_t threadNum, const ThreadHandle *threads, CommEngine dstCommEngine, ThreadHandle *exportedThreads)
     522              : {
     523            6 :     switch (dstCommEngine) {
     524            2 :     case COMM_ENGINE_CPU_TS:
     525              :     case COMM_ENGINE_CPU:
     526              :     case COMM_ENGINE_CCU:
     527            2 :         CHK_RET(ThreadExportToCommEngineCpu(threadNum, threads, exportedThreads));
     528            1 :         break;
     529            4 :     case COMM_ENGINE_AICPU:
     530              :     case COMM_ENGINE_AICPU_TS:
     531            4 :         CHK_RET(ThreadExportToCommEngineAicpu(threadNum, threads, dstCommEngine, exportedThreads));
     532            2 :         break;
     533            0 :     case COMM_ENGINE_AIV:
     534              :     default:
     535            0 :         HCCL_ERROR("[ThreadMgr] Unknown comm engine type: %s", GetEnumToString(GetCommEngineStatusStrMap(), dstCommEngine).c_str());
     536            0 :         return HCCL_E_PARA;
     537              :     }
     538            3 :     return HCCL_SUCCESS;
     539              : }
     540              : 
     541            4 : HcclResult ThreadMgr::HcclThreadResGetInfo(ThreadHandle thread, ThreadResType resType, uint32_t infoLen, void **info)
     542              : {
     543            4 :     CHK_PRT_RET(resType != ThreadResType::THREAD_RES_TYPE_STREAM, HCCL_ERROR("[%s] failed. resType[%d] is not supported.", 
     544              :         __func__, static_cast<int32_t>(resType)), HCCL_E_NOT_SUPPORT);
     545              : 
     546            3 :     std::lock_guard<std::mutex> threadhandleToThreadMtx(threadhandleToThreadMutex_);
     547            3 :     auto it = threadMap_.find(thread);
     548            3 :     CHK_PRT_RET(it == threadMap_.end(), 
     549              :         HCCL_ERROR("[%s] failed to find handle mapping in threadMap_, thread[0x%llx].", __func__, thread), HCCL_E_NOT_FOUND);
     550            2 :     std::shared_ptr<Thread> threadPtr = it->second;
     551            2 :     CHK_PTR_NULL(threadPtr);
     552            2 :     if (resType == ThreadResType::THREAD_RES_TYPE_STREAM) {
     553            2 :         CHK_PRT_RET(infoLen != sizeof(ThreadResTypeStream), HCCL_ERROR("[%s] failed. infoLen[%u] is mismatch sizeof(ThreadResTypeStream)[%zu]", 
     554              :                     __func__, infoLen, sizeof(ThreadResTypeStream)), HCCL_E_PARA);
     555            1 :         CHK_PTR_NULL(threadPtr->GetStream());
     556            1 :         ThreadResTypeStream stream = threadPtr->GetStream()->ptr();
     557            1 :         CHK_PTR_NULL(stream);
     558            1 :         *info = stream;
     559              :     } else {
     560            0 :         HCCL_ERROR("[%s] unsupported resType[%d]", __func__, static_cast<int32_t>(resType));
     561            0 :         return HCCL_E_NOT_SUPPORT;
     562              :     }
     563            1 :     HCCL_INFO("[%s] success. thread[0x%llx] resType[%d] info[%p]", __func__, thread, static_cast<int32_t>(resType), *info);
     564            1 :     return HCCL_SUCCESS;
     565            3 : }
     566              : 
     567           10 : HcclResult ThreadMgr::HcclUnfoldThreadAcquire(HcclDedicatedThreadType useType, uint32_t notifyNumPerThread, ThreadHandle *thread)
     568              : {
     569           10 :     CHK_PRT_RET(thread == nullptr, HCCL_ERROR("[%s] thread is null", __func__), HCCL_E_PTR);
     570           10 :     auto it = dedicatedThreadMap_.find(useType);
     571           10 :     if (it != dedicatedThreadMap_.end()) {
     572            4 :         *thread = it->second;
     573            4 :         HCCL_INFO("[%s] reuse dedicated thread, dedThreadType[%u], thread[0x%llx]", __func__, useType, *thread);
     574            4 :         CHK_RET(SupplementThreadNotify(*thread, notifyNumPerThread));
     575              :     } else {
     576            6 :         if (useType == HCCL_DED_THREAD_TYPE_AICPU_LAUNCH_GE) {
     577            1 :             *thread = 0;
     578            1 :             HCCL_WARNING("[%s] dedicated thread not found, dedThreadType[%u], return threadHandle[0]", __func__, useType);
     579            1 :             return HCCL_SUCCESS;
     580              :         }
     581            5 :         CommEngine engine = CommEngine::COMM_ENGINE_CPU;
     582            5 :         uint32_t notifyNumPerThreadVec[1] = { notifyNumPerThread };
     583            5 :         HcclResult ret = static_cast<HcclResult>(HcommThreadAlloc(engine, 1, notifyNumPerThreadVec, thread));
     584            5 :         if (ret != HCCL_SUCCESS) {
     585            0 :             HCCL_ERROR("[%s] Failed to cache dedicated thread, dedThreadType[%u], ret[%d]", __func__, useType, ret);
     586            0 :             return ret;
     587              :         }
     588            5 :         dedicatedThreadMap_[useType] = *thread;
     589              :     }
     590            9 :     return HCCL_SUCCESS;
     591              : }
     592              : 
     593           10 : HcclResult ThreadMgr::HcclDedicatedThreadAcquire(HcclDedicatedThreadType useType, uint32_t notifyNumPerThread, ThreadHandle *thread) 
     594              : { 
     595           10 :     CHK_PRT_RET(thread == nullptr, HCCL_ERROR("[%s] thread is null", __func__), HCCL_E_PTR);
     596           10 :     CHK_PRT_RET(useType == HCCL_DED_THREAD_TYPE_INVALID, HCCL_ERROR("[%s] dedThreadType is invalid", __func__), HCCL_E_PARA);
     597           10 :     HCCL_INFO("Entry-%s: dedThreadType[%u] notifyNumPerThread[%u]", __func__, useType, notifyNumPerThread); 
     598              : 
     599           10 :     std::lock_guard<std::mutex> lock(dedicatedThreadMutex_);
     600           10 :     if (useType == HCCL_DED_THREAD_TYPE_AICPU_LAUNCH || useType == HCCL_DED_THREAD_TYPE_AICPU_LAUNCH_GE) {
     601           10 :         CHK_RET(HcclUnfoldThreadAcquire(useType, notifyNumPerThread, thread));
     602           10 :     } else {
     603            0 :         HCCL_ERROR("[%s] unsupport dedThreadType[%u]", __func__, useType);
     604            0 :         return HCCL_E_NOT_SUPPORT;
     605              :     }
     606              : 
     607           10 :     HCCL_INFO("[%s] success, useType[%u], thread[0x%llx], notifyNumPerThread[%u]", __func__, useType, *thread, 
     608              :         notifyNumPerThread); 
     609           10 :     return HCCL_SUCCESS; 
     610           10 : }
     611              : }
        

Generated by: LCOV version 2.0-1