LCOV - code coverage report
Current view: top level - legacy/ascend910/platform/comm_primitive - hccl_dispatcher_ctx.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 64.8 % 159 103
Test Date: 2026-08-18 17:47:01 Functions: 80.0 % 10 8

            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 "hccl_dispatcher_ctx.h"
      12              : #include "dispatcher_ctx.h"
      13              : #include "dispatcher_aicpu_pub.h"
      14              : #include <unordered_map>
      15              : #include "adapter_rts_common.h"
      16              : 
      17              : // 多个通信域能并发跑通信算子,一个通信域只绑定一个dispatch_ctx线程变量
      18              : // 若不用通信域绑定线程变量,需要创建默认dispatch_ctx
      19              : static std::unordered_map<std::string, DispatcherCtxPtr> g_ctx;
      20              : std::mutex g_mtx; // 考虑已有的universal_map,或读写锁
      21              : thread_local DispatcherCtxPtr gDispatcherCtx = nullptr;
      22              : 
      23         1068 : bool FindDispatcherByCommId(DispatcherCtxPtr* ctx, const char* commId)
      24              : {
      25         1068 :     if (commId == nullptr) {
      26            0 :         HCCL_ERROR("[%s] find dispatcher fail, commId is nullptr", __func__);
      27            0 :         return false;
      28              :     }
      29         1068 :     std::lock_guard<std::mutex> lock(g_mtx);
      30         1069 :     std::string commIdkey = std::string(commId);
      31         1069 :     auto it = g_ctx.find(commIdkey);
      32         1069 :     if (it != g_ctx.end()) {
      33          538 :         *ctx = it->second;
      34          538 :         HCCL_INFO("[%s] commIdkey[%s] has been bound with ctx[%p]", __func__, commIdkey.c_str(), *ctx);
      35          538 :         return true;
      36              :     }
      37          531 :     *ctx = nullptr;
      38          531 :     HCCL_WARNING("[%s] commIdkey[%s] not found, ctx return nullptr", __func__, commIdkey.c_str());
      39          531 :     return false;
      40         1069 : }
      41              : 
      42          418 : bool DeleteDispatcherByCommId(const char* commId)
      43              : {
      44          418 :     if (commId == nullptr) {
      45            0 :         HCCL_ERROR("[%s] delete dispatcher fail, commId is nullptr", __func__);
      46            0 :         return false;
      47              :     }
      48          418 :     std::lock_guard<std::mutex> lock(g_mtx);
      49          418 :     std::string commIdkey = std::string(commId);
      50          418 :     auto it = g_ctx.find(commIdkey);
      51          418 :     if (it != g_ctx.end()) {
      52          418 :         HCCL_INFO("[%s] ctx[%p] has been bound by commId[%s]", __func__, it->second, commIdkey.c_str());
      53          418 :         g_ctx.erase(it);
      54          418 :         return true;
      55              :     }
      56            0 :     HCCL_WARNING("[%s] ctx has not been bound by commId[%s]", __func__, commIdkey.c_str());
      57            0 :     return false;
      58          418 : }
      59              : 
      60          422 : HcclResult BindDispatcherCtxWithComm(DispatcherCtxPtr ctx, const char* commId)
      61              : {
      62          422 :     CHK_PTR_NULL(commId);
      63          422 :     std::lock_guard<std::mutex> lock(g_mtx);
      64          422 :     std::string commIdkey = std::string(commId);
      65          422 :     auto it = g_ctx.find(commIdkey);
      66          422 :     if (it != g_ctx.end()) {
      67            3 :         HCCL_WARNING("[%s] commId[%s] has been bound", __func__, commIdkey.c_str());
      68            3 :         return HCCL_E_PARA;
      69              :     }
      70          419 :     g_ctx[commIdkey] = ctx;
      71          419 :     HCCL_INFO("[%s] ctx[%p] bind commId[%s] success", __func__, ctx, commIdkey.c_str());
      72          419 :     return HCCL_SUCCESS;
      73          422 : }
      74              : 
      75          423 : HcclResult CreateDispatcherCtx(DispatcherCtxPtr* ctx, u32 devPhyId, const char* commId)
      76              : {
      77          423 :     CHK_PTR_NULL(commId);
      78          423 :     CHK_PRT_RET(devPhyId == INVALID_UINT, HCCL_ERROR("[CreateCtx] devPhyId invalid"), HCCL_E_PARA);
      79          422 :     CHK_PTR_NULL(ctx);
      80          422 :     hccl::DispatcherCtx* Ctx_tmp = new (std::nothrow) hccl::DispatcherCtx(devPhyId);
      81          422 :     CHK_PTR_NULL(Ctx_tmp);
      82              :     // 创建ctx,内部创建dispatcher和notify pool实例  目前没有pool
      83          422 :     HcclResult ret = Ctx_tmp->Init();
      84          422 :     if (ret != HCCL_SUCCESS) {
      85            0 :         delete Ctx_tmp;
      86            0 :         HCCL_ERROR("[CreateCtx] CTX init fail");
      87            0 :         return ret;
      88              :     }
      89              : 
      90          422 :     ret = BindDispatcherCtxWithComm(Ctx_tmp, commId);
      91              :     // 如果存在,销毁创建的DispatcherCtx,返回存在的DispatcherCtx
      92          422 :     if (ret != HCCL_SUCCESS) {
      93            3 :         Ctx_tmp->Destroy();
      94            3 :         delete Ctx_tmp;
      95              :         // 查找已有ctx
      96            2 :         if (!FindDispatcherByCommId(ctx, commId)) {
      97            0 :             HCCL_ERROR("[CreateCtx] Bind fail AND no existing ctx for commId[%s]", commId);
      98            0 :             return HCCL_E_NOT_FOUND; // 明确返回错误,而非SUCCESS
      99              :         }
     100            3 :         gDispatcherCtx = *ctx;
     101            3 :         HCCL_WARNING("[CreateCtx] CTX bind fail, reuse existing ctx[%p] commId[%s]", *ctx, commId);
     102            3 :         return HCCL_SUCCESS;
     103              :     }
     104          419 :     *ctx = Ctx_tmp;
     105          419 :     gDispatcherCtx = Ctx_tmp;
     106          419 :     HCCL_INFO("[CreateCtx] CTX create success, ctx[%p] commId[%s]", *ctx, commId);
     107          419 :     return HCCL_SUCCESS;
     108              : }
     109              : 
     110          121 : bool DeleteCommIdByDispatcherCtx(DispatcherCtxPtr ctx)
     111              : {
     112          121 :     std::lock_guard<std::mutex> lock(g_mtx);
     113          121 :     for (const auto& pair : g_ctx) {
     114            1 :         if (pair.second == ctx) {
     115            1 :             HCCL_INFO("[%s] ctx[%p] bound with commId[%s], delete it", __func__, ctx, pair.first.c_str());
     116            1 :             g_ctx.erase(pair.first);
     117            1 :             return true;
     118              :         }
     119              :     }
     120          120 :     HCCL_WARNING("[%s] no commId bound with ctx[%p]", __func__, ctx);
     121          120 :     return false;
     122          121 : }
     123              : 
     124              : // 调用方有可能通过SetDispatcherCtx设置默认线程变量
     125              : // 传入commId是为了快速索引并释放g_ctx中的内容
     126              : // 不分成两个接口,防止重复释放
     127          539 : HcclResult DestroyDispatcherCtx(DispatcherCtxPtr ctx, const char* commId)
     128              : {
     129              :     static std::mutex deleteMutex_;
     130          539 :     const std::lock_guard<std::mutex> lock(deleteMutex_);
     131          539 :     CHK_PTR_NULL(commId);
     132          539 :     CHK_PTR_NULL(ctx);
     133          539 :     HCCL_INFO("[DestroyCtx] Destroy Ctx, ctx[%p] commId[%s]", ctx, commId);
     134          539 :     if (gDispatcherCtx == ctx) {
     135          420 :         gDispatcherCtx = nullptr;
     136              :     } else {
     137          119 :         HCCL_WARNING("[DestroyCtx] gDispatcherCtx[%p] and ctx[%p] do not match.", gDispatcherCtx, ctx);
     138              :     }
     139              : 
     140          539 :     DispatcherCtxPtr otherCtx = nullptr;
     141              :     // 若找到commId绑定的dispatch_ctx,解除绑定后销毁dispatch_ctx
     142              :     // 若找不到commId绑定的dispatch_ctx,查找map中
     143          539 :     if (LIKELY(FindDispatcherByCommId(&otherCtx, commId))) {
     144          418 :         DeleteDispatcherByCommId(commId);
     145              :     } else {
     146          121 :         bool hasFound = DeleteCommIdByDispatcherCtx(ctx);
     147          121 :         if (!hasFound) {
     148          120 :             HCCL_WARNING("[DestroyCtx] ctx[%p] not found by commId[%s], it may have been destroyed", ctx, commId);
     149          120 :             return HCCL_SUCCESS;
     150              :         }
     151            1 :         HCCL_WARNING("[DestroyCtx] ctx[%p] not found by commId[%s], just destroy", ctx, commId);
     152              :     }
     153          419 :     hccl::DispatcherCtx* Ctx_tmp = reinterpret_cast<hccl::DispatcherCtx*>(ctx);
     154          419 :     HcclResult ret = Ctx_tmp->Destroy();
     155          419 :     if (ret != HCCL_SUCCESS) {
     156            0 :         HCCL_ERROR("[DestroyCtx] CTX Destroy fail");
     157              :     }
     158          419 :     delete Ctx_tmp;
     159          419 :     ctx = nullptr;
     160          419 :     return ret;
     161          539 : }
     162              : 
     163              : // 设置当前的线程变量dispatcherCtx,必须先调用CreateDispatcherCtx
     164              : // 同一个通信域不可以切换dispatcherCtx
     165            0 : HcclResult SetDispatcherCtx(const DispatcherCtxPtr ctx)
     166              : {
     167            0 :     HCCL_INFO("[%s], param: ctx[%p]", __func__, ctx);
     168            0 :     CHK_PTR_NULL(ctx);
     169            0 :     gDispatcherCtx = ctx;
     170            0 :     return HCCL_SUCCESS;
     171              : }
     172              : 
     173              : // 获取当前设置的线程变量dispatcherCtx,必须先调用CreateDispatcherCtx
     174           22 : DispatcherCtxPtr GetDispatcherCtx(const char* commId)
     175              : {
     176           22 :     if (UNLIKELY(commId == nullptr)) {
     177            0 :         HCCL_ERROR("[%s] get dispatcher fail, commId is nullptr", __func__);
     178            0 :         return nullptr;
     179              :     }
     180           22 :     HCCL_DEBUG("[%s], commId[%s]", __func__, commId);
     181           22 :     if (LIKELY((gDispatcherCtx != nullptr))) {
     182           21 :         HCCL_INFO("[%s], gDispatcherCtx[%p] exist, commId[%s]", __func__, gDispatcherCtx, commId);
     183           21 :         return gDispatcherCtx;
     184              :     }
     185              :     DispatcherCtxPtr ctx;
     186            1 :     if (FindDispatcherByCommId(&ctx, commId)) {
     187            0 :         HCCL_INFO("[%s], ctx[%p] found in g_ctx, commId[%s]", __func__, ctx, commId);
     188            0 :         gDispatcherCtx = ctx;
     189            0 :         return ctx;
     190              :     }
     191            1 :     return nullptr;
     192              : }
     193              : 
     194            0 : HcclResult SetDispatcherCtxOpIdx(u32 opRingBufferIdx)
     195              : {
     196            0 :     HCCL_INFO("%s start, %u", __func__, opRingBufferIdx);
     197            0 :     hccl::DispatcherCtx* ctx_temp = reinterpret_cast<hccl::DispatcherCtx*>(GetDispatcherCtx());
     198            0 :     CHK_PTR_NULL(ctx_temp);
     199            0 :     hccl::DispatcherAiCpu* dispatcherPtr = reinterpret_cast<hccl::DispatcherAiCpu*>(ctx_temp->GetDispatcher());
     200            0 :     CHK_PTR_NULL(dispatcherPtr);
     201            0 :     dispatcherPtr->SetOpRingBufferIdx(opRingBufferIdx);
     202            0 :     return HCCL_SUCCESS;
     203              : }
     204              : 
     205            7 : HcclResult AcquireDispatcherCtx(DispatcherCtxPtr* ctx, const char* commId)
     206              : {
     207            7 :     CHK_PTR_NULL(commId);
     208            7 :     DispatcherCtxPtr ctxPtr = GetDispatcherCtx(commId);
     209            7 :     if (ctxPtr != nullptr) {
     210            7 :         *ctx = ctxPtr;
     211            7 :         HCCL_INFO("[AcquireCtx] CTX get success, ctx[%p] commId[%s]", *ctx, commId);
     212            7 :         return HCCL_SUCCESS;
     213              :     }
     214            0 :     s32 deviceLogicId = 0;
     215            0 :     CHK_RET(hrtGetDevice(&deviceLogicId));
     216            0 :     u32 devPhyId = INVALID_UINT;
     217            0 :     CHK_RET(hrtGetDevicePhyIdByIndex(deviceLogicId, devPhyId));
     218            0 :     CHK_PRT_RET(devPhyId == INVALID_UINT, HCCL_ERROR("[CreateCtx] devPhyId invalid"), HCCL_E_PARA);
     219            0 :     CHK_PTR_NULL(ctx);
     220            0 :     hccl::DispatcherCtx* Ctx_tmp = new (std::nothrow) hccl::DispatcherCtx(devPhyId);
     221            0 :     CHK_PTR_NULL(Ctx_tmp);
     222            0 :     HcclResult ret = Ctx_tmp->Init();
     223            0 :     if (ret != HCCL_SUCCESS) {
     224            0 :         delete Ctx_tmp;
     225            0 :         HCCL_ERROR("[AcquireCtx] CTX init fail");
     226            0 :         return ret;
     227              :     }
     228              : 
     229              :     // 如果存在,销毁创建的DispatcherCtx,返回存在的DispatcherCtx
     230            0 :     if (BindDispatcherCtxWithComm(Ctx_tmp, commId) != HCCL_SUCCESS) {
     231            0 :         Ctx_tmp->Destroy();
     232            0 :         delete Ctx_tmp;
     233              :         // 查找已有ctx
     234            0 :         if (!FindDispatcherByCommId(ctx, commId)) {
     235            0 :             HCCL_ERROR("[AcquireCtx] Bind fail AND no existing ctx for commId[%s]", commId);
     236            0 :             return HCCL_E_NOT_FOUND; // 明确返回错误,而非SUCCESS
     237              :         }
     238            0 :         gDispatcherCtx = *ctx;
     239            0 :         HCCL_WARNING("[AcquireCtx] CTX bind fail, reuse existing ctx[%p] commId[%s]", *ctx, commId);
     240            0 :         return HCCL_SUCCESS;
     241              :     }
     242              : 
     243            0 :     *ctx = Ctx_tmp;
     244            0 :     gDispatcherCtx = Ctx_tmp;
     245            0 :     HCCL_INFO("[AcquireCtx] CTX create success, ctx[%p] commId[%s]", *ctx, commId);
     246            0 :     return HCCL_SUCCESS;
     247              : }
        

Generated by: LCOV version 2.0-1