LCOV - code coverage report
Current view: top level - legacy/ascend950/framework/communicator/aicpu - hdc_lite.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.4 % 86 76
Test Date: 2026-08-18 17:47:01 Functions: 85.7 % 7 6

            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 "hdc_lite.h"
      12              : #include <chrono>
      13              : #include "log.h"
      14              : 
      15              : namespace Hccl {
      16              : constexpr u32 HCCL_HDC_CONTROL_WORDS = 2;
      17              : constexpr u32 HCCL_HDC_HEAD_POS = 2;
      18              : constexpr u32 HCCL_HDC_TAIL_POS = 1;
      19              : 
      20            0 : inline u32* HcclHdcGetControlWordAddr(void* base, u64 size, u32 pos)
      21              : {
      22            0 :     return reinterpret_cast<u32*>(reinterpret_cast<u8*>((base)) + size - pos * sizeof(pos));
      23              : }
      24              : 
      25           19 : HcclResult HDCommunicateLite::Init(const struct HDCommunicateParams& params)
      26              : {
      27           19 :     CHK_PRT_RET(
      28              :         (params.devMemSize == 0), HCCL_ERROR("[HDCommunicateLite][InitDevice]Invalid devMemSize=%u", params.devMemSize),
      29              :         HCCL_E_PARA);
      30           19 :     void* deviceAddr = reinterpret_cast<void*>(params.deviceAddr);
      31           19 :     CHK_PTR_NULL(deviceAddr);
      32           19 :     readCacheAddr = reinterpret_cast<void*>(params.readCacheAddr);
      33           19 :     CHK_PTR_NULL(readCacheAddr);
      34           19 :     devMem = std::make_unique<Buffer>(reinterpret_cast<uintptr_t>(deviceAddr), params.devMemSize);
      35           19 :     buffLen = params.buffLen;
      36           19 :     flag = params.flag;
      37              : 
      38              :     headCntAddr
      39           19 :         = HcclHdcGetControlWordAddr(reinterpret_cast<void*>(devMem->GetAddr()), devMem->GetSize(), HCCL_HDC_HEAD_POS);
      40              :     tailCntAddr
      41           19 :         = HcclHdcGetControlWordAddr(reinterpret_cast<void*>(devMem->GetAddr()), devMem->GetSize(), HCCL_HDC_TAIL_POS);
      42              : 
      43           57 :     HCCL_INFO(
      44              :         "[HDCommunicateLite][Init] buffLen=%u, flag=%u, readCacheAddr=%p, headCntAddr=%p, tailCntAddr=%p", buffLen,
      45              :         flag, readCacheAddr, headCntAddr, tailCntAddr);
      46           19 :     return HCCL_SUCCESS;
      47              : }
      48              : 
      49           13 : HcclResult HDCommunicateLite::Put(u32 offset, u32 length, u8* value)
      50              : {
      51           13 :     if (length == 0) {
      52            0 :         return HCCL_SUCCESS;
      53              :     }
      54           13 :     CHK_PTR_NULL(value);
      55           13 :     if ((flag == HCCLV2_HDC_TYPE_H2D)) {
      56            0 :         HCCL_ERROR("[HDCommunicateLite][Put]Invalid usage, flag=%u", flag);
      57            0 :         return HCCL_E_PARA;
      58              :     }
      59           13 :     CHK_PRT_RET(
      60              :         (static_cast<u64>(offset) + length > buffLen),
      61              :         HCCL_ERROR("[HDCommunicateLite][Put]Invalid length, offset=%u, length=%u", offset, length), HCCL_E_PARA);
      62           13 :     std::unique_lock<std::mutex> lock(shmLock);
      63           13 :     return Write(offset, length, value);
      64           13 : }
      65              : 
      66        19971 : HcclResult HDCommunicateLite::Get(u32 offset, u32 length, u8* value)
      67              : {
      68        19971 :     if (length == 0) {
      69            0 :         return HCCL_SUCCESS;
      70              :     }
      71        19971 :     CHK_PTR_NULL(value);
      72        19971 :     CHK_PRT_RET(
      73              :         (static_cast<u64>(offset) + length > buffLen),
      74              :         HCCL_ERROR(
      75              :             "[HDCommunicateLite][Get]Invalid length, offset=%u, length=%u, befferLen=%u", offset, length, buffLen),
      76              :         HCCL_E_PARA);
      77        19971 :     std::unique_lock<std::mutex> lock(shmLock);
      78        19971 :     return Read(offset, length, value);
      79        19971 : }
      80              : 
      81              : #pragma GCC push_options
      82              : #pragma GCC optimize("O0")
      83           13 : HcclResult HDCommunicateLite::Write(u32 offset, u32 length, u8* value)
      84              : {
      85           13 :     if (length == 0) {
      86            0 :         return HCCL_SUCCESS;
      87              :     }
      88           13 :     CHK_PTR_NULL(value);
      89           13 :     u32 head = *headCntAddr;
      90           13 :     head++;
      91           13 :     *headCntAddr = head;
      92              : 
      93           52 :     auto ret = memcpy_s(
      94           13 :         reinterpret_cast<u8*>(devMem->GetAddr()) + offset,
      95           13 :         devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32) - offset, value, length);
      96           13 :     CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][Write]memcpy_s failed, return[%d].", ret), HCCL_E_INTERNAL);
      97              : 
      98           13 :     u32 tail = *tailCntAddr;
      99           13 :     tail++;
     100           13 :     *tailCntAddr = tail;
     101              : 
     102           13 :     return HCCL_SUCCESS;
     103              : }
     104              : 
     105        19971 : HcclResult HDCommunicateLite::Read(u32 offset, u32 length, u8* value)
     106              : {
     107        19971 :     if (length == 0) {
     108            0 :         return HCCL_SUCCESS;
     109              :     }
     110        19971 :     CHK_PTR_NULL(value);
     111        19971 :     u32* cachedTailCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     112        19971 :     volatile u32 cachedTailCnt = *cachedTailCntAddr;
     113        19971 :     volatile u32 tailCnt = 0;
     114        19971 :     tailCnt = *tailCntAddr;
     115              : 
     116        19971 :     if (cachedTailCnt != tailCnt) {
     117              :         // 默认HDC超时时间为10s
     118           11 :         CHK_RET(UpdateCache(10));
     119              :     }
     120        19971 :     auto ret = memcpy_s(value, length, static_cast<u8*>(readCacheAddr) + offset, length);
     121        19971 :     CHK_PRT_RET(ret != EOK, HCCL_ERROR("[HDCommunicateLite][Read]memcpy_s failed, return[%d].", ret), HCCL_E_INTERNAL);
     122        19971 :     return HCCL_SUCCESS;
     123              : }
     124              : 
     125           11 : HcclResult HDCommunicateLite::UpdateCache(u32 timeoutSec)
     126              : {
     127           11 :     void* srcBaseAddr = reinterpret_cast<void*>(devMem->GetAddr());
     128           11 :     u32* srcHeadCntAddr = HcclHdcGetControlWordAddr(srcBaseAddr, devMem->GetSize(), HCCL_HDC_HEAD_POS);
     129           11 :     u32* srcTailCntAddr = HcclHdcGetControlWordAddr(srcBaseAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     130           11 :     u32* cachedHeadCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_HEAD_POS);
     131           11 :     u32* cachedTailCntAddr = HcclHdcGetControlWordAddr(readCacheAddr, devMem->GetSize(), HCCL_HDC_TAIL_POS);
     132              : 
     133           11 :     s32 ret = 0;
     134           11 :     auto startTime = std::chrono::steady_clock::now();
     135           11 :     auto timeout = std::chrono::seconds(timeoutSec);
     136              :     while (1) {
     137              :         // step1: cache尾计数
     138           11 :         ret = memcpy_s(cachedTailCntAddr, sizeof(u32), srcTailCntAddr, sizeof(u32));
     139           11 :         CHK_PRT_RET(
     140              :             ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     141              :             HCCL_E_INTERNAL);
     142              : 
     143              :         // step2: cache数据
     144           33 :         ret = memcpy_s(
     145           11 :             readCacheAddr, devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32), srcBaseAddr,
     146           11 :             devMem->GetSize() - HCCL_HDC_CONTROL_WORDS * sizeof(u32));
     147           11 :         CHK_PRT_RET(
     148              :             ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     149              :             HCCL_E_INTERNAL);
     150              : 
     151              :         // step3:cache头计数
     152           11 :         ret = memcpy_s(cachedHeadCntAddr, sizeof(u32), srcHeadCntAddr, sizeof(u32));
     153           11 :         CHK_PRT_RET(
     154              :             ret != EOK, HCCL_ERROR("[HDCommunicateLite][UpdateCache]memcpy_s failed, return[%d].", ret),
     155              :             HCCL_E_INTERNAL);
     156              : 
     157           11 :         volatile u32 cachedHeadCnt = *cachedHeadCntAddr;
     158           11 :         volatile u32 cachedTailCnt = *cachedTailCntAddr;
     159              : 
     160           11 :         if (cachedHeadCnt == cachedTailCnt) {
     161           11 :             break;
     162              :         }
     163            0 :         CHK_PRT_RET(
     164              :             ((std::chrono::steady_clock::now() - startTime) >= timeout),
     165              :             HCCL_WARNING("[HDCommunicateLite][UpdateCache]get remote data timeout[%u s].", timeoutSec), HCCL_E_AGAIN);
     166            0 :     }
     167           11 :     return HCCL_SUCCESS;
     168              : }
     169              : #pragma GCC pop_options
     170              : 
     171              : } // namespace Hccl
        

Generated by: LCOV version 2.0-1