LCOV - code coverage report
Current view: top level - coll_communicator_mgr/resource_mgr/local/my_rank/comm_mems - comm_mem_manager.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 52.1 % 117 61
Test Date: 2026-08-18 17:47:01 Functions: 62.5 % 8 5

            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 "comm_mem_manager.h"
      12              : namespace hccl {
      13              : 
      14          235 : void CommMemMgr::CommSetHcclBufferManager(CCLBufferManager& bufferManager) { bufferManager_ = &bufferManager; }
      15              : 
      16            7 : HcclResult CommMemMgr::GetHcclBuffer(CommBuffer* buffer)
      17              : {
      18            7 :     CHK_PTR_NULL(buffer);
      19            7 :     CHK_PTR_NULL(bufferManager_);
      20            7 :     std::lock_guard<std::mutex> lock(bufferMutex_);
      21            7 :     void* temp = nullptr;
      22            7 :     uint64_t tempSize = 0;
      23            7 :     HcclResult ret = bufferManager_->GetIndependentOpCCLbuffer(temp, tempSize);
      24            7 :     CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[GetHcclBuffer] GetHcclBuffer failed"), ret);
      25            7 :     buffer->addr = temp;
      26            7 :     buffer->size = tempSize;
      27            7 :     return HCCL_SUCCESS;
      28            7 : }
      29              : 
      30              : // 绑定:opTag -> 句柄(幂等)
      31            9 : HcclResult CommMemMgr::CommRegMem(const std::string& memTag, const HcclMem& mem, HcclRegMemAttr attr, void** memHandle)
      32              : {
      33            9 :     CHK_PRT_RET(
      34              :         memHandle == nullptr, HCCL_ERROR("[CommRegMem] memHandle is null. tag[%s]", memTag.c_str()), HCCL_E_PARA);
      35            9 :     CHK_PRT_RET(
      36              :         mem.addr == nullptr || mem.size == 0,
      37              :         HCCL_ERROR("[CommRegMem] invalid mem. addr[%p] size[%llu]", mem.addr, mem.size), HCCL_E_PARA);
      38              : 
      39              :     // 组装句柄(仅域内管理,无进程级注册)
      40            9 :     Handle h;
      41            9 :     EXCEPTION_CATCH(h = std::make_shared<HcclMemoryHandle>(), return HCCL_E_PTR);
      42            9 :     h->addr = mem.addr;
      43            9 :     h->size = static_cast<uint64_t>(mem.size);
      44            9 :     h->memType = static_cast<HcclMemType>(mem.type);
      45            9 :     h->attr = attr;
      46              : 
      47            9 :     const auto key = MakeKey(mem.addr, static_cast<size_t>(mem.size));
      48              : 
      49            9 :     std::lock_guard<std::mutex> addLock(memMutex_);
      50            9 :     auto& reg = tagRegs_[memTag];
      51              : 
      52              :     // 同tag内做区间冲突/幂等复用
      53            9 :     auto res = reg.table.Add(key, h);
      54            9 :     if (!res.second) {
      55              :         // 只能用 Find 的返回值来判定:
      56              :         // - 等于(全集命中):Find(key).first == true(允许,Add 内已 ref)
      57              :         // - 子集/超集/交集:Find(key).first 可能为 true(子) 或 false(交/超/空),但都属于冲突!
      58            0 :         auto f = reg.table.Find(key);
      59            0 :         if (!f.first || !(f.second && f.second->addr == mem.addr && f.second->size == mem.size)) {
      60            0 :             HCCL_ERROR("[CommRegMem] overlap in tag[%s], key=%s", memTag.c_str(), key.ToString().c_str());
      61            0 :             return HCCL_E_PARA;
      62              :         }
      63              :         // HcclRegMemAttr不同时更新
      64            0 :         if (f.second->attr.value != attr.value) {
      65            0 :             HCCL_WARNING("[CommRegMem] inconsistent attr for same mem. tag[%s]", memTag.c_str());
      66            0 :             f.second->attr.value = attr.value;
      67              :         }
      68              :         // 复用已有句柄:直接用 Find 返回的 buffer,避免解引用 res.first(可能是 end())
      69            0 :         h = f.second;
      70            0 :     }
      71              : 
      72              :     // 幂等加入绑定列表(同memHandle不重复)
      73            9 :     auto& vec = opBindings_[memTag];
      74            9 :     bool exists = std::any_of(vec.begin(), vec.end(), [&h](const Handle& x) {
      75            1 :         return x && (x.get() == h.get());
      76              :     });
      77            9 :     if (!exists)
      78            9 :         vec.emplace_back(h);
      79              : 
      80            9 :     *memHandle = h.get();
      81            9 :     HCCL_INFO("[CommRegMem] ok. tag[%s] memHandle[%p] size[%llu]", memTag.c_str(), *memHandle, h->size);
      82            9 :     return HCCL_SUCCESS;
      83            9 : }
      84              : 
      85              : // 解绑:在该通信域实例内,移除“指定算子(memTag)”下的该句柄
      86            0 : HcclResult CommMemMgr::CommUnregMem(const std::string& memTag, const void* memHandle)
      87              : {
      88            0 :     CHK_PRT_RET(memHandle == nullptr, HCCL_ERROR("[CommUnregMem] memHandle is null"), HCCL_E_PARA);
      89            0 :     CHK_PRT_RET(memTag.empty(), HCCL_ERROR("[CommUnregMem] memTag is null or empty"), HCCL_E_PARA);
      90              : 
      91            0 :     std::lock_guard<std::mutex> addLock(memMutex_);
      92              : 
      93            0 :     auto itTag = opBindings_.find(memTag);
      94            0 :     CHK_PRT_RET(
      95              :         itTag == opBindings_.end(), HCCL_WARNING("[CommUnregMem] tag[%s] not found in bindings", memTag.c_str()),
      96              :         HCCL_E_NOT_FOUND);
      97              : 
      98            0 :     auto& vec = itTag->second;          // vector<Handle> under this tag
      99            0 :     auto& reg = tagRegs_[itTag->first]; // TagRegistry for this tag
     100            0 :     size_t unboundCount = 0;            // 本次解绑命中的句柄个数(即便 Del 未真正擦除也计数)
     101            0 :     size_t erasedCount = 0;             // RmaBufferMgr::Del 返回 true 的次数(ref 归零而“擦除”)
     102              : 
     103            0 :     vec.erase(
     104            0 :         std::remove_if(
     105              :             vec.begin(), vec.end(),
     106            0 :             [&](const Handle& h) {
     107            0 :                 if (!h || h.get() != memHandle)
     108            0 :                     return false;
     109            0 :                 const auto key = MakeKey(h->addr, static_cast<size_t>(h->size));
     110              :                 try {
     111            0 :                     if (reg.table.Del(key)) {
     112            0 :                         ++erasedCount; // 该 key 的引用归零并从表中移除
     113              :                     }
     114            0 :                 } catch (const std::out_of_range&) {
     115            0 :                     HCCL_ERROR(
     116              :                         "[CommUnregMem] tag[%s] key not found on Del (maybe already removed)", itTag->first.c_str());
     117            0 :                 }
     118              : 
     119            0 :                 ++unboundCount; // 从绑定列表移除,无论 Del 是否真正擦除
     120            0 :                 return true;    // erase-remove:删除该 handle
     121              :             }),
     122            0 :         vec.end());
     123              : 
     124              :     // 若该 tag 已无绑定,可按需清理映射条目(以及空表)
     125            0 :     if (vec.empty()) {
     126            0 :         opBindings_.erase(itTag);
     127            0 :         if (reg.table.size() == 0) {
     128            0 :             tagRegs_.erase(std::string(memTag));
     129              :         }
     130              :     }
     131              : 
     132            0 :     CHK_PRT_RET(
     133              :         unboundCount == 0, HCCL_WARNING("[CommUnregMem] tag[%s] memHandle[%p] not found", memTag.c_str(), memHandle),
     134              :         HCCL_E_NOT_FOUND);
     135              : 
     136            0 :     HCCL_INFO(
     137              :         "[CommUnregMem] tag[%s] memHandle[%p] unbound=%zu, erased=%zu", memTag.c_str(), memHandle, unboundCount,
     138              :         erasedCount);
     139            0 :     return HCCL_SUCCESS;
     140            0 : }
     141              : 
     142            0 : HcclResult CommMemMgr::CommGetLocalRegMemByTag(const std::string& tag, std::vector<HcclMem>& memVec)
     143              : {
     144            0 :     std::lock_guard<std::mutex> lock(memMutex_);
     145            0 :     auto it = opBindings_.find(tag);
     146            0 :     if (it == opBindings_.end()) {
     147            0 :         HCCL_INFO("[CommMemMgr] tag[%s] key not found", tag.c_str());
     148            0 :         return HCCL_SUCCESS;
     149              :     }
     150              : 
     151            0 :     const auto& vec = it->second;
     152            0 :     memVec.reserve(vec.size());
     153            0 :     for (const auto& handle : vec) {
     154              :         HcclMem mem;
     155            0 :         mem.addr = handle->addr;
     156            0 :         mem.size = handle->size;
     157            0 :         mem.type = handle->memType;
     158            0 :         memVec.push_back(mem);
     159              :     }
     160            0 :     return HCCL_SUCCESS;
     161            0 : }
     162              : 
     163            8 : HcclResult CommMemMgr::CommGetLocalRegMemByHandles(
     164              :     const HcclMemHandle* memHandles, uint32_t memHandleNum, std::vector<HcclMem>& memVec)
     165              : {
     166            8 :     if (memHandleNum == 0) {
     167            1 :         return HCCL_SUCCESS;
     168              :     }
     169            7 :     CHK_PTR_NULL(memHandles);
     170              : 
     171            6 :     std::lock_guard<std::mutex> lock(memMutex_);
     172            6 :     memVec.clear();
     173            6 :     memVec.reserve(memHandleNum);
     174              : 
     175           14 :     for (uint32_t i = 0; i < memHandleNum; ++i) {
     176           10 :         bool found = false;
     177           13 :         for (const auto& tagBinding : opBindings_) {
     178           15 :             for (const auto& handle : tagBinding.second) {
     179           12 :                 if (handle != nullptr && handle.get() == memHandles[i]) {
     180              :                     HcclMem mem;
     181            8 :                     mem.addr = handle->addr;
     182            8 :                     mem.size = handle->size;
     183            8 :                     mem.type = handle->memType;
     184            8 :                     memVec.push_back(mem);
     185            8 :                     found = true;
     186            8 :                     break;
     187              :                 }
     188              :             }
     189           11 :             if (found) {
     190            8 :                 break;
     191              :             }
     192              :         }
     193           10 :         if (!found) {
     194            2 :             HCCL_ERROR("[CommGetLocalRegMemByHandles] memHandle[%p] not found in any tag", memHandles[i]);
     195            2 :             return HCCL_E_NOT_FOUND;
     196              :         }
     197              :     }
     198            4 :     return HCCL_SUCCESS;
     199            6 : }
     200              : } // namespace hccl
        

Generated by: LCOV version 2.0-1