LCOV - code coverage report
Current view: top level - legacy/ascend910/common/health - rank_consistentcy_checker.cc (source / functions) Coverage Total Hit
Test: coverage.info Lines: 71.0 % 348 247
Test Date: 2026-08-17 10:19:35 Functions: 70.3 % 37 26

            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 "calc_crc.h"
      12              : #include "rank_consistentcy_checker.h"
      13              : #include "env_config.h"
      14              : 
      15              : namespace hccl {
      16              : 
      17          590 : RankConsistentcyChecker::RankConsistentcyChecker()
      18          590 :     : cannVersion_{0},
      19          590 :       cannVerCheckSwitch_(false),
      20          590 :       cannVerInfoRecordFlag_(false),
      21          590 :       configFileExist_(false)
      22          590 : {}
      23              : 
      24          590 : RankConsistentcyChecker::~RankConsistentcyChecker() = default;
      25              : 
      26         1927 : RankConsistentcyChecker& RankConsistentcyChecker::GetInstance(s32 deviceLogicId)
      27              : {
      28         2512 :     static RankConsistentcyChecker instance[MAX_MODULE_DEVICE_NUM];
      29         1929 :     if (deviceLogicId == HOST_DEVICE_ID) {
      30            0 :         HCCL_INFO("[GetInstance] deviceLogicId[-1] is HOST_DEVICE_ID");
      31            0 :         return instance[0];
      32              :     }
      33         1929 :     hrtGetDeviceRefresh(&deviceLogicId);
      34         1930 :     HCCL_INFO("[GetInstance] get deviceLogicId[%d]", deviceLogicId);
      35         1931 :     CHK_PRT_RET(
      36              :         (static_cast<u32>(deviceLogicId) >= MAX_MODULE_DEVICE_NUM || deviceLogicId < 0),
      37              :         HCCL_WARNING("[R]deviceLogicId[%d] is invalid", deviceLogicId), instance[0]);
      38              : 
      39         1929 :     return instance[deviceLogicId];
      40              : }
      41              : 
      42              : // gather
      43            0 : HcclResult RankConsistentcyChecker::RecordOpPara(
      44              :     HcclCMDType opCMD, const std::string& tag, u64 count, HcclDataType dataType, u32 root, u64 inCclBufferSize,
      45              :     u64 outCclBufferSize, const char* group, u32 crc, u32 aivCoreLimit)
      46              : {
      47            0 :     return RecordOpPara(
      48              :         opCMD, tag, count, dataType, HCCL_REDUCE_RESERVED, root, 0, 0, 0, inCclBufferSize, outCclBufferSize, group, crc,
      49            0 :         aivCoreLimit);
      50              : }
      51              : 
      52              : // reduce
      53           76 : HcclResult RankConsistentcyChecker::RecordOpPara(
      54              :     HcclCMDType opCMD, const std::string& tag, u64 count, HcclDataType dataType, HcclReduceOp op, u32 root,
      55              :     u64 inCclBufferSize, u64 outCclBufferSize, const char* group, u32 crc, u8 deterministic, u32 aivCoreLimit)
      56              : {
      57           76 :     return RecordOpPara(
      58           76 :         opCMD, tag, count, dataType, op, root, 0, 0, 0, inCclBufferSize, outCclBufferSize, group, crc, aivCoreLimit);
      59              : }
      60              : 
      61              : // send && receive
      62            0 : HcclResult RankConsistentcyChecker::RecordOpPara(
      63              :     HcclCMDType opCMD, const std::string& tag, u64 count, HcclDataType dataType, u32 rank, u32 srTag, u32 selfRank,
      64              :     u64 inCclBufferSize, u64 outCclBufferSize, const char* group, u32 crc)
      65              : {
      66            0 :     return RecordOpPara(
      67              :         opCMD, tag, count, dataType, HCCL_REDUCE_RESERVED, 0, rank, srTag, selfRank, inCclBufferSize, outCclBufferSize,
      68            0 :         group, crc);
      69              : }
      70              : 
      71              : // batchsendrecv
      72            0 : HcclResult RankConsistentcyChecker::RecordOpPara(
      73              :     HcclCMDType opCMD, const std::string& tag, u64 inCclBufferSize, u64 outCclBufferSize, const char* group, u32 crc)
      74              : {
      75            0 :     return RecordOpPara(
      76              :         opCMD, tag, 0, HCCL_DATA_TYPE_RESERVED, HCCL_REDUCE_RESERVED, 0, 0, 0, 0, inCclBufferSize, outCclBufferSize,
      77            0 :         group, crc);
      78              : }
      79              : 
      80              : // reduce scatter v && AllGather v
      81            0 : HcclResult RankConsistentcyChecker::RecordOpPara(
      82              :     HcclCMDType opCMD, const std::string& tag, const void* counts, const void* displs, const u32 rankSize,
      83              :     HcclDataType dataType, HcclReduceOp op, u64 inCclBufferSize, u64 outCclBufferSize, const char* group, u32 crc,
      84              :     u8 deterministic, u32 aivCoreLimit)
      85              : {
      86            0 :     CHK_RET(RecordOpPara(
      87              :         opCMD, tag, 0, dataType, op, 0, 0, 0, 0, inCclBufferSize, outCclBufferSize, group, crc, aivCoreLimit));
      88            0 :     CHK_RET(RecordVaringOpPara(tag, counts, displs, rankSize));
      89            0 :     return HCCL_SUCCESS;
      90              : }
      91              : 
      92            0 : HcclResult RankConsistentcyChecker::RecordVaringOpPara(
      93              :     const std::string& tag, const void* counts, const void* displs, const u32 rankSize)
      94              : {
      95              :     u32 countsCrc;
      96            0 :     CHK_RET(CalcRawDataCrc(static_cast<const char_t*>(counts), rankSize * sizeof(u64), countsCrc));
      97            0 :     crcRecords_[tag][HcclCrcRecordType::HCCL_CRC_RECORD_VARING_COUNTS] = countsCrc;
      98              : 
      99              :     u32 displsCrc;
     100            0 :     CHK_RET(CalcRawDataCrc(static_cast<const char_t*>(displs), rankSize * sizeof(u64), displsCrc));
     101            0 :     crcRecords_[tag][HcclCrcRecordType::HCCL_CRC_RECORD_VARING_DISPLACEMENTS] = displsCrc;
     102            0 :     return HCCL_SUCCESS;
     103              : }
     104              : 
     105           24 : HcclResult RankConsistentcyChecker::DelOpPara(const std::string& tag)
     106              : {
     107           24 :     std::lock_guard<std::mutex> lock(mutex_);
     108           24 :     CHK_PRT_RET(
     109              :         !cmdInfoMap_.erase(tag),
     110              :         HCCL_ERROR(
     111              :             "[RankConsistentcyChecker][DelOpPara]CMD info for tag[%s] does not exist, delete fail.", tag.c_str()),
     112              :         HCCL_E_INTERNAL);
     113           24 :     CHK_PRT_RET(
     114              :         !infoFlagCmdMap_.erase(tag),
     115              :         HCCL_ERROR(
     116              :             "[RankConsistentcyChecker][DelOpPara]CMD info flag cmd for tag[%s] does not exist, delete fail.",
     117              :             tag.c_str()),
     118              :         HCCL_E_INTERNAL);
     119           24 :     crcRecords_.erase(tag);
     120           24 :     return HCCL_SUCCESS;
     121           24 : }
     122              : 
     123          236 : HcclResult RankConsistentcyChecker::RecordVerInfo(const std::string& versionInfo)
     124              : {
     125          236 :     std::lock_guard<std::mutex> lock(mutex_);
     126              :     // Only record once, in case of multiple calls while other process is reading CANN version information
     127              :     // in CompareFrame func and get the intermediate state.
     128          236 :     if (cannVerInfoRecordFlag_) {
     129          231 :         HCCL_INFO("[RankConsistentcyChecker][RecordVerInfo]Cann version information has been recorded.");
     130          231 :         return HCCL_SUCCESS;
     131              :     }
     132              : 
     133            5 :     u32 strLen = versionInfo.length();
     134            5 :     s32 sRet = memset_s(cannVersion_, MAX_CANN_VERSION_LEN + 1, 0, MAX_CANN_VERSION_LEN + 1);
     135            5 :     CHK_PRT_RET(
     136              :         sRet != EOK,
     137              :         HCCL_WARNING(
     138              :             "[RankConsistentcyChecker][RecordVerInfo]memory set 0 fail for version str "
     139              :             "array. return[%d].",
     140              :             sRet),
     141              :         HCCL_SUCCESS);
     142              : 
     143            5 :     CHK_PRT_RET(strLen == 0, HCCL_WARNING("[Record][CannVersion] version information str is empty."), HCCL_SUCCESS);
     144              : 
     145            5 :     CHK_PRT_RET(
     146              :         strLen >= MAX_CANN_VERSION_LEN,
     147              :         HCCL_WARNING("[Record][CannVersion]"
     148              :                      "length of version information str is too long."),
     149              :         HCCL_SUCCESS);
     150            5 :     sRet = strncpy_s(cannVersion_, MAX_CANN_VERSION_LEN + 1, versionInfo.c_str(), strLen);
     151            5 :     CHK_PRT_RET(
     152              :         sRet != EOK, HCCL_WARNING("[Record][CannVersion] call strncpy_s failed, return [%d].", sRet), HCCL_SUCCESS);
     153              : 
     154            5 :     cannVerInfoRecordFlag_ = true;
     155            5 :     return HCCL_SUCCESS;
     156          236 : }
     157              : 
     158         1055 : u64 RankConsistentcyChecker::GetRankConsistentDataLength() { return sizeof(HcclCheckInfo); }
     159              : 
     160            0 : void RankConsistentcyChecker::RecordProtocolType(ProtocolType protocolType)
     161              : {
     162            0 :     HCCL_INFO("[RankConsistentcyChecker][RecordProtocolType]protocolType set to [%d].", static_cast<s32>(protocolType));
     163            0 :     protocolType_ = protocolType;
     164            0 :     return;
     165              : }
     166              : 
     167            4 : HcclResult RankConsistentcyChecker::GetCheckFrame(u8* destBuf, u64 maxDestBuf, const std::string& tag)
     168              : {
     169            4 :     CHK_PTR_NULL(destBuf);
     170              :     // 要发送的校验帧
     171            4 :     HcclCheckInfo checkInfo;
     172            4 :     u64 checkInfoLen = sizeof(checkInfo);
     173            4 :     HcclResult ret = GenerateCheckFrame(checkInfo, tag);
     174            4 :     checkInfo.cmdInfo.selfRank = 0; // 自身的group rank 不做校验,置0
     175            4 :     CHK_PRT_RET(
     176              :         ret != HCCL_SUCCESS,
     177              :         HCCL_ERROR(
     178              :             "[RankConsistentcyChecker][GetCheckFrame]generate check frame fail. "
     179              :             "return[%d]",
     180              :             ret),
     181              :         ret);
     182              : 
     183            4 :     s32 sret = memcpy_s(destBuf, maxDestBuf, &checkInfo, checkInfoLen);
     184            4 :     CHK_PRT_RET(
     185              :         sret != EOK,
     186              :         HCCL_ERROR(
     187              :             "[RankConsistentcyChecker][GetCheckFrame]frame len[%llu] is bigger than "
     188              :             "dest buffer len[%llu].",
     189              :             checkInfoLen, maxDestBuf),
     190              :         HCCL_E_INTERNAL);
     191            4 :     return HCCL_SUCCESS;
     192              : }
     193              : 
     194            0 : HcclResult RankConsistentcyChecker::CheckFrameRecv(const u8* recvBuf, u32 recvBufLen, const std::string& tag)
     195              : {
     196              : #ifndef HCCD
     197            0 :     if ((GetExternalInconsistentCheckSwitch() == InconsistentCheckMode::OFF)
     198            0 :         || (GetExternalInconsistentCheckSwitch() == InconsistentCheckMode::FIRST
     199            0 :             && inconsistentCheckFirstDone_ == true)) {
     200            0 :         return HCCL_SUCCESS;
     201              :     }
     202              : #endif
     203            0 :     CHK_PTR_NULL(recvBuf);
     204            0 :     CHK_PRT_RET(
     205              :         recvBufLen == 0 || recvBufLen > MAX_FRAME_LEN,
     206              :         HCCL_ERROR(
     207              :             "[RankConsistentcyChecker][CheckFrameRecv] errNo[0x%016llx] recvBufLen is wrong.",
     208              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL)),
     209              :         HCCL_E_INTERNAL);
     210              : 
     211            0 :     CHK_PRT_RET(
     212              :         recvBufLen < sizeof(HcclCheckInfo),
     213              :         HCCL_ERROR(
     214              :             "[RankConsistentcyChecker][CheckFrameRecv] errNo[0x%016llx] recvBufLen[%u]is less than "
     215              :             "check info[%zu].",
     216              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL), recvBufLen, sizeof(HcclCheckInfo)),
     217              :         HCCL_E_PARA);
     218              : 
     219            0 :     HcclCheckInfo checkInfoRecv;
     220              :     // 对固定长度的全局数组变量,结构体变量进行初始化和拷贝,可以不用检查初始化安全函数返回值
     221            0 :     (void)memset_s(&checkInfoRecv, sizeof(HcclCheckInfo), 0, sizeof(HcclCheckInfo));
     222            0 :     (void)memcpy_s(&checkInfoRecv, sizeof(HcclCheckInfo), recvBuf, sizeof(HcclCheckInfo));
     223              : 
     224            0 :     HcclCheckInfo checkInfo;
     225            0 :     CHK_RET(GenerateCheckFrame(checkInfo, tag));
     226            0 :     if (checkInfo.cmdInfo.cmdType == HcclCMDType::HCCL_CMD_SEND) {
     227            0 :         checkInfo.cmdInfo.cmdType = HcclCMDType::HCCL_CMD_RECEIVE;
     228            0 :         checkInfo.cmdInfo.rank = checkInfo.cmdInfo.selfRank;
     229            0 :     } else if (checkInfo.cmdInfo.cmdType == HcclCMDType::HCCL_CMD_RECEIVE) {
     230            0 :         checkInfo.cmdInfo.cmdType = HcclCMDType::HCCL_CMD_SEND;
     231            0 :         checkInfo.cmdInfo.rank = checkInfo.cmdInfo.selfRank;
     232              :     }
     233              : 
     234            0 :     checkInfo.cmdInfo.selfRank = 0; // 自身的子group rank 不做校验
     235            0 :     if (CompareFrame(checkInfo, checkInfoRecv)) {
     236            0 :         return HCCL_E_INTERNAL;
     237              :     }
     238              : 
     239            0 :     HCCL_INFO(
     240              :         "[RankConsistentcyChecker][CheckFrameRecv] check success, len of frame[%u], len of check data[%zu].",
     241              :         recvBufLen, sizeof(checkInfo));
     242            0 :     return HCCL_SUCCESS;
     243              : }
     244              : 
     245           62 : void RankConsistentcyChecker::ClearCheckInfo()
     246              : {
     247           62 :     configFileExist_ = false;
     248           62 :     cannVerInfoRecordFlag_ = false;
     249           62 :     ClearCrcInfo();
     250              :     {
     251           62 :         std::lock_guard<std::mutex> lock(mutex_);
     252           62 :         cmdInfoMap_.clear();
     253           62 :         infoFlagCmdMap_.clear();
     254           62 :     }
     255              :     // 相关规范的例外场景,对固定数组的memset_s可以不判断返回值
     256           62 :     (void)memset_s(cannVersion_, MAX_CANN_VERSION_LEN + 1, 0, MAX_CANN_VERSION_LEN + 1);
     257           62 :     protocolType_ = ProtocolType::RESERVED;
     258           62 :     return;
     259              : }
     260              : 
     261          236 : HcclResult RankConsistentcyChecker::CalcStringCrc(const char* str, u32& crc)
     262              : {
     263              :     // 计算字符串CRC
     264          236 :     HcclResult ret = CalcCrc::HcclCalcCrc(str, strlen(str), crc);
     265          236 :     CHK_PRT_RET(
     266              :         ret != HCCL_SUCCESS,
     267              :         HCCL_ERROR(
     268              :             "[RankConsistentcyChecker][CalcStringCrc] errNo[0x%016llx] calc string crc error",
     269              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL)),
     270              :         HCCL_E_INTERNAL);
     271              : 
     272          236 :     HCCL_DEBUG("[RankConsistentcyChecker][CalcStringCrc] result crc[%u].", crc);
     273          236 :     return HCCL_SUCCESS;
     274              : }
     275              : 
     276            0 : HcclResult RankConsistentcyChecker::CalcRawDataCrc(const void* ptr, u64 length, u32& crc)
     277              : {
     278              :     // 计算内存数据块CRC
     279            0 :     HcclResult ret = CalcCrc::HcclCalcCrc(static_cast<const char*>(ptr), length, crc);
     280            0 :     CHK_PRT_RET(
     281              :         ret != HCCL_SUCCESS,
     282              :         HCCL_ERROR(
     283              :             "[RankConsistentcyChecker][CalcRawDataCrc] errNo[0x%016llx] calc string crc error",
     284              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL)),
     285              :         HCCL_E_INTERNAL);
     286              : 
     287            0 :     HCCL_DEBUG("[RankConsistentcyChecker][CalcRawDataCrc] result crc[%u].", crc);
     288            0 :     return HCCL_SUCCESS;
     289              : }
     290              : 
     291          240 : void RankConsistentcyChecker::SetCheckCannVersionSwitch(const bool cannVerCheckSwitch)
     292              : {
     293          240 :     cannVerCheckSwitch_ = cannVerCheckSwitch;
     294          240 :     return;
     295              : }
     296              : 
     297              : // private
     298           77 : HcclResult RankConsistentcyChecker::RecordOpPara(
     299              :     HcclCMDType opCMD, const std::string& tag, u64 count, HcclDataType dataType, HcclReduceOp op, u32 root, u32 rank,
     300              :     u32 srTag, u32 selfRank, u64 inCclBufferSize, u64 outCclBufferSize, const char* group, u32 crc, u8 deterministic,
     301              :     u32 aivCoreLimit)
     302              : {
     303           77 :     HcclCMDInfo cmdInfo;
     304              :     // 相关规范的例外场景,对固定数组的memset_s可以不判断返回值
     305           77 :     (void)memset_s(&cmdInfo, sizeof(cmdInfo), 0, sizeof(cmdInfo));
     306              : 
     307           77 :     cmdInfo.cmdType = opCMD;
     308           77 :     s32 sRet = strncpy_s(cmdInfo.tag, TAG_MAX_LEN + 1, tag.c_str(), tag.length());
     309           77 :     CHK_PRT_RET(
     310              :         sRet != EOK,
     311              :         HCCL_ERROR(
     312              :             "[RankConsistentcyChecker][RecordOpPara]errNo[0x%016llx] strlen[%u] of tag is "
     313              :             "longer than buffer[%u].",
     314              :             HCCL_ERROR_CODE(HCCL_E_PARA), tag.length(), TAG_MAX_LEN),
     315              :         HCCL_E_PARA);
     316              : 
     317           77 :     cmdInfo.count = count;
     318           77 :     cmdInfo.dataType = dataType;
     319              : 
     320           77 :     std::string strGroup = (group == nullptr) ? HCCL_WORLD_GROUP : group;
     321           74 :     sRet = strncpy_s(cmdInfo.group, GROUP_NAME_MAX_LEN + 1, strGroup.c_str(), strGroup.length());
     322           74 :     CHK_PRT_RET(
     323              :         sRet != EOK,
     324              :         HCCL_ERROR(
     325              :             "[RankConsistentcyChecker][RecordOpPara]errNo[0x%016llx] strlen[%u] group is "
     326              :             "longer than buffer[%u].",
     327              :             HCCL_ERROR_CODE(HCCL_E_PARA), strGroup.length(), GROUP_NAME_MAX_LEN),
     328              :         HCCL_E_PARA);
     329              : 
     330           74 :     cmdInfo.op = op;
     331           74 :     cmdInfo.root = root;
     332           74 :     cmdInfo.rank = rank;
     333           74 :     cmdInfo.srTag = srTag;
     334           74 :     cmdInfo.selfRank = selfRank;
     335           74 :     cmdInfo.inCclBufferSize = inCclBufferSize;
     336           74 :     cmdInfo.outCclBufferSize = outCclBufferSize;
     337           74 :     cmdInfo.aivCoreLimit = aivCoreLimit;
     338           74 :     cmdInfo.deterministic = deterministic;
     339              : 
     340           74 :     std::lock_guard<std::mutex> lock(mutex_);
     341           77 :     cmdInfoMap_[tag] = cmdInfo;
     342           74 :     infoFlagCmdMap_[tag] = true;
     343           74 :     crcRecords_[tag][HcclCrcRecordType::HCCL_CRC_RECORD_RANKTABLE] = crc;
     344              : 
     345           69 :     return HCCL_SUCCESS;
     346           69 : }
     347              : 
     348            0 : HcclResult RankConsistentcyChecker::GetOpParaByTag(const std::string& tag, HcclCMDInfo& CMDInfoOutput)
     349              : {
     350            0 :     auto getResult = cmdInfoMap_.find(tag);
     351            0 :     CHK_PRT_RET(
     352              :         getResult == cmdInfoMap_.end(),
     353              :         HCCL_ERROR(
     354              :             "[RankConsistentcyChecker][GetOpParaByTag]There is not any CMD information for tag[%s]", tag.c_str()),
     355              :         HCCL_E_INTERNAL);
     356            0 :     CMDInfoOutput = getResult->second;
     357            0 :     return HCCL_SUCCESS;
     358              : }
     359              : 
     360            0 : HcclResult RankConsistentcyChecker::GetCrcByTag(const std::string& tag, HcclCRCInfo& crcInfo)
     361              : {
     362            0 :     const auto recordsIter = crcRecords_.find(tag);
     363            0 :     CHK_PRT_RET(
     364              :         recordsIter == crcRecords_.end(),
     365              :         HCCL_ERROR("[RankConsistentcyChecker][GetCrcByTag]There is not any CRC information for tag[%s]", tag.c_str()),
     366              :         HCCL_E_INTERNAL);
     367            0 :     crcInfo.crcNum = 0;
     368            0 :     const auto& tagRecords = recordsIter->second;
     369            0 :     for (const auto& record : tagRecords) {
     370            0 :         crcInfo.crcArray[crcInfo.crcNum++] = record.second;
     371            0 :         HCCL_DEBUG("[RankConsistentcyChecker][GetCrcByTag]Append crc[%u] for tag[%s].", record.second, tag.c_str());
     372              :     }
     373              : 
     374            0 :     HCCL_INFO(
     375              :         "[RankConsistentcyChecker][GetCrcByTag]After adding crc for tag[%s], crcNum set to [%u].", tag.c_str(),
     376              :         crcInfo.crcNum);
     377            0 :     return HCCL_SUCCESS;
     378              : }
     379              : 
     380            3 : HcclResult RankConsistentcyChecker::GenerateCheckFrame(HcclCheckInfo& checkInfo, const std::string& tag)
     381              : {
     382              :     // 初始化用于发送的BUFFER
     383              :     // 对入参的结构体变量指向的内存进行初始化时,使用了变量的结构体类型大小进行初始化,
     384              :     // 如果指针不为空,可以不检查初始化安全函数的返回值
     385            3 :     u64 checkInfoLen = sizeof(HcclCheckInfo);
     386            3 :     (void)memset_s(&checkInfo, checkInfoLen, 0, checkInfoLen);
     387              : 
     388              :     // 添加CRC字段到校验帧
     389            4 :     u32 crcLen = crcTable_.size();
     390            4 :     checkInfo.crcInfoGlobal.configFileExist_ = configFileExist_;
     391            4 :     if (crcLen != 0) {
     392            0 :         CHK_PRT_RET(
     393              :             crcLen > MAX_CRC_LEN,
     394              :             HCCL_ERROR("[RankConsistentcyChecker][GenerateCheckFrame]crc num[%u] is too big.", crcLen),
     395              :             HCCL_E_INTERNAL);
     396            0 :         checkInfo.crcInfoGlobal.crcNum = crcLen;
     397            0 :         CHK_RET(GetCrc(crcLen, &checkInfo.crcInfoGlobal.crcArray[0]));
     398              :     }
     399              :     // 添加CMD参数信息到校验帧
     400              :     {
     401            4 :         std::lock_guard<std::mutex> lock(mutex_);
     402            4 :         auto getResult = infoFlagCmdMap_.find(tag);
     403            4 :         if (getResult != infoFlagCmdMap_.end()) {
     404            0 :             CHK_PRT_RET(
     405              :                 GetOpParaByTag(tag, checkInfo.cmdInfo) != HCCL_SUCCESS,
     406              :                 HCCL_ERROR("[RankConsistentcyChecker][GenerateCheckFrame]get Op para by tag[%s] fail.", tag.c_str()),
     407              :                 HCCL_E_INTERNAL);
     408            0 :             checkInfo.crcInfoOp.configFileExist_ = configFileExist_;
     409              :             // 添加CRC字段到校验帧
     410            0 :             CHK_PRT_RET(
     411              :                 GetCrcByTag(tag, checkInfo.crcInfoOp) != HCCL_SUCCESS,
     412              :                 HCCL_ERROR(
     413              :                     "[RankConsistentcyChecker][GenerateCheckFrame]get ranktable crc by tag[%s] fail.", tag.c_str()),
     414              :                 HCCL_E_INTERNAL);
     415              :         }
     416            4 :     }
     417              :     // 添加HCCL版本信息到校验帧
     418            4 :     if (cannVerInfoRecordFlag_) {
     419            0 :         HCCL_DEBUG("[RankConsistentcyChecker][GenerateCheckFrame] CANN version information is [%s].", cannVersion_);
     420            0 :         s32 sret = memcpy_s(checkInfo.version, MAX_CANN_VERSION_LEN + 1, cannVersion_, strlen(cannVersion_));
     421            0 :         CHK_PRT_RET(
     422              :             sret != EOK,
     423              :             HCCL_ERROR(
     424              :                 "[RankConsistentcyChecker][GenerateCheckFrame] memcpy CANN version information failed, "
     425              :                 "errorno [%d].",
     426              :                 sret),
     427              :             HCCL_E_MEMORY);
     428              :     }
     429              :     // 添加拉远通信传输类型校验
     430              :     // 910* 不会配置isTcpMode,因此910*在此处的待校验值是一致的
     431            4 :     checkInfo.protocolType = protocolType_;
     432            4 :     HCCL_INFO("[RankConsistentcyChecker][GenerateCheckFrame] loc protocolType is [%d].", checkInfo.protocolType);
     433              : 
     434            4 :     return HCCL_SUCCESS;
     435              : }
     436              : 
     437           29 : bool RankConsistentcyChecker::CompareSection(const char* pRawData, const char* recvBuf, u32 len)
     438              : {
     439        11741 :     for (u32 i = 0; i < len; i++) {
     440        11715 :         if (*(pRawData + i) != *(recvBuf + i)) {
     441            3 :             return false;
     442              :         }
     443              :     }
     444           26 :     return true;
     445              : }
     446              : 
     447           18 : bool RankConsistentcyChecker::CompareCrcInfo(
     448              :     const HcclCMDInfo& hcclCMDInfo, HcclCRCInfo& crcInfo, HcclCRCInfo& crcInfoRecv)
     449              : {
     450           18 :     bool bIsDiff = false;
     451              :     // 检校验整体是否一致
     452           18 :     if (!CompareSection(
     453              :             reinterpret_cast<char_t*>(&crcInfo), reinterpret_cast<char_t*>(&crcInfoRecv), sizeof(crcInfo))) {
     454            2 :         bIsDiff = true;
     455              :         // 检查每种CRC类型是否一致
     456            4 :         for (auto i = 0U; i < crcInfo.crcNum; ++i) {
     457            2 :             if (crcInfo.crcArray[i] != crcInfoRecv.crcArray[i]) {
     458            2 :                 ReportCrcCheckFailed(
     459              :                     hcclCMDInfo, static_cast<HcclCrcRecordType>(i), crcInfo.crcArray[i], crcInfoRecv.crcArray[i]);
     460              :             }
     461              :         }
     462              :     }
     463           18 :     return bIsDiff;
     464              : }
     465              : 
     466            0 : void RankConsistentcyChecker::ReportCmdInfoCheckFailed(
     467              :     const HcclCMDInfo& hcclCMDInfo, const std::string& paraName, const std::string& localPara,
     468              :     const std::string& remotePara) const
     469              : {
     470            0 :     ReportCommonError(hcclCMDInfo, paraName, localPara, remotePara, "CMD information");
     471            0 : }
     472              : 
     473            3 : void RankConsistentcyChecker::ReportCmdInfoCheckFailed(
     474              :     const HcclCMDInfo& hcclCMDInfo, const std::string& paraName, uint32_t localPara, uint32_t remotePara)
     475              : {
     476            3 :     ReportCommonError(hcclCMDInfo, paraName, std::to_string(localPara), std::to_string(remotePara), "CMD information");
     477            3 : }
     478              : 
     479            2 : void RankConsistentcyChecker::ReportCrcCheckFailed(
     480              :     const HcclCMDInfo& hcclCMDInfo, HcclCrcRecordType crcType, const uint32_t localCrc, const uint32_t remoteCrc) const
     481              : {
     482            2 :     const auto crcTypeStr = GetCRCTypeEnumStr(crcType);
     483            2 :     ReportCommonError(hcclCMDInfo, crcTypeStr, std::to_string(localCrc), std::to_string(remoteCrc), "CRC check");
     484            2 : }
     485              : 
     486            5 : void RankConsistentcyChecker::ReportCommonError(
     487              :     const HcclCMDInfo& hcclCMDInfo, const std::string& paraName, const std::string& localParaStr,
     488              :     const std::string& remoteParaStr, const std::string& errorMsg) const
     489              : {
     490            5 :     std::string opInfo = "Unknown";
     491           15 :     for (const auto& pair : HCCL_OPTYPE_NAME_MAP) {
     492           15 :         if (pair.second == hcclCMDInfo.cmdType) {
     493            5 :             opInfo = std::string(pair.first);
     494            5 :             break;
     495              :         }
     496              :     }
     497          100 :     RPT_INPUT_ERR(
     498              :         true, "EI0005", std::vector<std::string>({"ccl_op", "group", "para_name", "local_para", "remote_para"}),
     499              :         std::vector<std::string>({opInfo, hcclCMDInfo.group, paraName, localParaStr, remoteParaStr}));
     500            5 :     HCCL_ERROR(
     501              :         "[%s][%s]%s %s check fail. local[%s], remote[%s]", LOG_KEYWORDS_INIT_CHANNEL.c_str(),
     502              :         LOG_KEYWORDS_PARAMETER_CONFLICT.c_str(), errorMsg.c_str(), paraName.c_str(), localParaStr.c_str(),
     503              :         remoteParaStr.c_str());
     504           15 : }
     505              : 
     506            1 : void RankConsistentcyChecker::CompareCmdInfo(HcclCheckInfo& checkInfo, HcclCheckInfo& checkInfoRecv)
     507              : {
     508            1 :     auto localInfo = &checkInfo.cmdInfo;
     509            1 :     auto remoteInfo = &checkInfoRecv.cmdInfo;
     510              : 
     511            1 :     if (!CompareSection(localInfo->tag, remoteInfo->tag, TAG_MAX_LEN + 1)) {
     512            0 :         ReportCmdInfoCheckFailed(*localInfo, "tag", localInfo->tag, remoteInfo->tag);
     513              :     }
     514              : 
     515            1 :     if (localInfo->cmdType != remoteInfo->cmdType) {
     516            2 :         ReportCmdInfoCheckFailed(
     517            1 :             *localInfo, "cmdType", static_cast<uint32_t>(localInfo->cmdType),
     518            1 :             static_cast<uint32_t>(remoteInfo->cmdType));
     519              :     }
     520              : 
     521            1 :     if (localInfo->count != remoteInfo->count) {
     522            3 :         ReportCmdInfoCheckFailed(*localInfo, "count", localInfo->count, remoteInfo->count);
     523              :     }
     524              : 
     525            1 :     if (localInfo->dataType != remoteInfo->dataType) {
     526            2 :         ReportCmdInfoCheckFailed(
     527            1 :             *localInfo, "dataType", static_cast<uint32_t>(localInfo->dataType),
     528            1 :             static_cast<uint32_t>(remoteInfo->dataType));
     529              :     }
     530              : 
     531            1 :     if (localInfo->op != remoteInfo->op) {
     532            0 :         ReportCmdInfoCheckFailed(
     533            0 :             *localInfo, "op", static_cast<uint32_t>(localInfo->op), static_cast<uint32_t>(remoteInfo->op));
     534              :     }
     535              : 
     536            1 :     if (!CompareSection(localInfo->group, remoteInfo->group, GROUP_NAME_MAX_LEN + 1)) {
     537            0 :         ReportCmdInfoCheckFailed(*localInfo, "group", localInfo->group, remoteInfo->group);
     538              :     }
     539              : 
     540            1 :     if (localInfo->root != remoteInfo->root) {
     541            0 :         ReportCmdInfoCheckFailed(*localInfo, "root", localInfo->root, remoteInfo->root);
     542              :     }
     543              : 
     544            1 :     if (localInfo->rank != remoteInfo->rank) {
     545            0 :         ReportCmdInfoCheckFailed(*localInfo, "rank", localInfo->rank, remoteInfo->rank);
     546              :     }
     547              : 
     548            1 :     if (localInfo->srTag != remoteInfo->srTag) {
     549            0 :         ReportCmdInfoCheckFailed(*localInfo, "srTag", localInfo->srTag, remoteInfo->srTag);
     550              :     }
     551              : 
     552            1 :     if (localInfo->inCclBufferSize != remoteInfo->inCclBufferSize) {
     553            0 :         ReportCmdInfoCheckFailed(
     554            0 :             *localInfo, "inCclBufferSize", localInfo->inCclBufferSize, remoteInfo->inCclBufferSize);
     555              :     }
     556              : 
     557            1 :     if (localInfo->outCclBufferSize != remoteInfo->outCclBufferSize) {
     558            0 :         ReportCmdInfoCheckFailed(
     559            0 :             *localInfo, "outCclBufferSize", localInfo->outCclBufferSize, remoteInfo->outCclBufferSize);
     560              :     }
     561              : 
     562            1 :     if (localInfo->aivCoreLimit != remoteInfo->aivCoreLimit) {
     563            0 :         ReportCmdInfoCheckFailed(*localInfo, "aivCoreLimit", localInfo->aivCoreLimit, remoteInfo->aivCoreLimit);
     564              :     }
     565              : 
     566            1 :     if (localInfo->deterministic != remoteInfo->deterministic) {
     567            0 :         ReportCmdInfoCheckFailed(*localInfo, "deterministic", localInfo->deterministic, remoteInfo->deterministic);
     568              :     }
     569              : 
     570            1 :     return;
     571              : }
     572              : 
     573           18 : std::vector<std::string_view> Split(const std::string& str, char delimiter)
     574              : {
     575           18 :     std::vector<std::string_view> parts;
     576           18 :     std::string_view sv(str);
     577           18 :     size_t start = 0;
     578          238 :     for (size_t i = 0; i <= sv.size(); ++i) {
     579          220 :         if (i == sv.size() || sv[i] == delimiter) {
     580           33 :             parts.push_back(sv.substr(start, i - start));
     581           33 :             start = i + 1;
     582              :         }
     583              :     }
     584           18 :     return parts;
     585            0 : }
     586              : 
     587            9 : std::vector<std::string> GetVersionErrMessage(const std::string& localVersion, const std::string& remoteVersion)
     588              : {
     589            9 :     std::vector<std::string> versionErrMessage;
     590            9 :     auto localVersionParts = Split(localVersion, '_');
     591            9 :     auto remoteVersionParts = Split(remoteVersion, '_');
     592           18 :     std::string localHcommVersion = localVersionParts.size() > 0 ? std::string(localVersionParts[0]) : "empty";
     593           20 :     std::string localHcclVersion = localVersionParts.size() > 1 ? std::string(localVersionParts[1]) : "empty";
     594           18 :     std::string remoteHcommVersion = remoteVersionParts.size() > 0 ? std::string(remoteVersionParts[0]) : "empty";
     595           20 :     std::string remoteHcclVersion = remoteVersionParts.size() > 1 ? std::string(remoteVersionParts[1]) : "empty";
     596              : 
     597            9 :     bool hcommDiff = (localHcommVersion != remoteHcommVersion);
     598            9 :     bool hcclDiff = (localHcclVersion != remoteHcclVersion);
     599            9 :     if (hcommDiff && !hcclDiff) {
     600              :         // 将版本号拆分为hcomm版本号和hccl版本号, 构造ErrMessage
     601              :         // The %s versions are inconsistent. The local %s, while the remote %s.
     602              :         versionErrMessage
     603           25 :             = {"Toolkit (cann-hcomm)", "version is " + localHcommVersion, "version is " + remoteHcommVersion};
     604            4 :     } else if (!hcommDiff && hcclDiff) {
     605            5 :         versionErrMessage = {"ops (cann-hccl)", "version is " + localHcclVersion, "version is " + remoteHcclVersion};
     606            3 :     } else if (hcommDiff && hcclDiff) {
     607              :         versionErrMessage
     608            8 :             = {"Toolkit (cann-hcomm) and ops (cann-hccl)",
     609            4 :                "Toolkit (cann-hcomm) version is " + localHcommVersion + " and ops (cann-hccl) version is "
     610              :                    + localHcclVersion,
     611            4 :                "Toolkit (cann-hcomm) version is " + remoteHcommVersion + " and ops (cann-hccl) version is "
     612           10 :                    + remoteHcclVersion};
     613              :     } else {
     614              :         // 拆分版本号字符串失败, 构造为原版的ErrMessage
     615              :         // The HCCL versions are inconsistent. The local version is %s, while the remote version is %s.
     616            1 :         HCCL_ERROR("[RankConsistentcyChecker][GetVersionErrMessage]Failed to split the version string.");
     617            5 :         versionErrMessage = {"HCCL", "version is " + localVersion, "version is " + remoteVersion};
     618              :     }
     619            9 :     return versionErrMessage;
     620           31 : }
     621              : 
     622            8 : void RankConsistentcyChecker::CompareVersion(const HcclCheckInfo& local, const HcclCheckInfo& remote, bool& isDiff)
     623              : {
     624           16 :     std::string localCannVersion = local.version;
     625            8 :     std::string remoteCannVersion = remote.version;
     626            8 :     if (localCannVersion.empty() || remoteCannVersion.empty()) { // cann版本信息读取失败,返回告警
     627            1 :         HCCL_WARNING(
     628              :             "[RankConsistentcyChecker][CompareFrame] CANN version str is empty. local_version %s, "
     629              :             "remote_version %s.",
     630              :             local.version, remote.version);
     631            7 :     } else if (localCannVersion != remoteCannVersion) { // cann版本信息读取成功,且版本不一致
     632            5 :         const char* ascendHomePath = std::getenv("ASCEND_HOME_PATH");
     633              :         std::string versionFilePath
     634           10 :             = (ascendHomePath != nullptr) ? std::string(ascendHomePath) + "/share/info/hccl/version.info" : "unknown";
     635            5 :         auto versionErrMessage = GetVersionErrMessage(localCannVersion, remoteCannVersion);
     636              :         // GetVersionErrMessage函数内部已保证versionErrMessage.size() == 3
     637           70 :         RPT_INPUT_ERR(
     638              :             true, "EI0008", std::vector<std::string>({"inconsistent_package", "local_version", "remote_version"}),
     639              :             std::vector<std::string>(
     640              :                 {versionErrMessage[0], versionErrMessage[1] + " (version file: " + versionFilePath + ")",
     641              :                  versionErrMessage[2]}));
     642            5 :         HCCL_ERROR(
     643              :             "[%s][%s] errNo[0x%016llx] Inconsistent %s Versions. The local %s, while the remote %s.",
     644              :             LOG_KEYWORDS_INIT_CHANNEL.c_str(), LOG_KEYWORDS_VERSION_CONFLICT.c_str(), HCCL_ERROR_CODE(HCCL_E_INTERNAL),
     645              :             versionErrMessage[0].c_str(), versionErrMessage[1].c_str(), versionErrMessage[2].c_str());
     646            5 :         isDiff = true;
     647            5 :     }
     648           18 : }
     649              : 
     650            9 : bool RankConsistentcyChecker::CompareFrame(HcclCheckInfo& checkInfo, HcclCheckInfo& checkInfoRecv)
     651              : {
     652            9 :     bool bIsDiff = false;
     653            9 :     if (CompareCrcInfo(checkInfo.cmdInfo, checkInfo.crcInfoGlobal, checkInfoRecv.crcInfoGlobal)) {
     654            1 :         HCCL_ERROR(
     655              :             "[RankConsistentcyChecker][CompareFrame]errNo[0x%016llx] CRC check fail, please check the "
     656              :             "rankTable file and hccl_config file.",
     657              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL));
     658            1 :         bIsDiff = true;
     659              :     }
     660            9 :     if (CompareCrcInfo(checkInfo.cmdInfo, checkInfo.crcInfoOp, checkInfoRecv.crcInfoOp)) {
     661            1 :         HCCL_ERROR(
     662              :             "[RankConsistentcyChecker][CompareFrame]errNo[0x%016llx] Op CRC check fail, please check the op"
     663              :             " parameters, rankTable file and hccl_config file.",
     664              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL));
     665            1 :         bIsDiff = true;
     666              :     }
     667            9 :     if (!CompareSection(
     668            9 :             reinterpret_cast<char_t*>(&checkInfo.cmdInfo), reinterpret_cast<char_t*>(&checkInfoRecv.cmdInfo),
     669              :             sizeof(checkInfo.cmdInfo))) {
     670            1 :         CompareCmdInfo(checkInfo, checkInfoRecv);
     671            1 :         HCCL_ERROR(
     672              :             "[RankConsistentcyChecker][CompareFrame]errNo[0x%016llx] CMD check fail", HCCL_ERROR_CODE(HCCL_E_INTERNAL));
     673            1 :         bIsDiff = true;
     674              :     }
     675            9 :     HCCL_INFO(
     676              :         "loc protocolType is [%d], rem protocolType is [%d].", checkInfo.protocolType, checkInfoRecv.protocolType);
     677            9 :     if (checkInfo.protocolType != checkInfoRecv.protocolType) {
     678            1 :         HCCL_ERROR(
     679              :             "[RankConsistentcyChecker][CompareFrame]errNo[0x%016llx] ProtocolType check fail",
     680              :             HCCL_ERROR_CODE(HCCL_E_INTERNAL));
     681            1 :         bIsDiff = true;
     682              :     }
     683              : 
     684              :     // Cann版本校验,只在集合通信场景校验CANN版本
     685            9 :     if (cannVerCheckSwitch_) {
     686            8 :         CompareVersion(checkInfo, checkInfoRecv, bIsDiff);
     687              :     }
     688              : #ifndef HCCD
     689            9 :     if (GetExternalInconsistentCheckSwitch() == InconsistentCheckMode::FIRST) {
     690            9 :         inconsistentCheckFirstDone_ = true;
     691              :     }
     692              : #endif
     693            9 :     return bIsDiff;
     694              : }
     695              : 
     696            9 : HcclResult RankConsistentcyChecker::AddCrc(const u32 crcValue)
     697              : {
     698            9 :     HCCL_DEBUG("crcValue[%u].", crcValue);
     699            9 :     crcTable_.push_back(crcValue);
     700            9 :     HCCL_DEBUG("num[%llu].", crcTable_.size());
     701            9 :     return HCCL_SUCCESS;
     702              : }
     703              : 
     704           63 : HcclResult RankConsistentcyChecker::ClearCrcInfo(void)
     705              : {
     706           63 :     this->crcTable_.clear();
     707           63 :     if (this->crcTable_.size() != 0) {
     708            0 :         HCCL_ERROR("[Clear][CrcInfo]errNo[0x%016llx] clear crcTable_ is failed", HCCL_ERROR_CODE(HCCL_E_INTERNAL));
     709            0 :         return HCCL_E_INTERNAL;
     710              :     }
     711           63 :     return HCCL_SUCCESS;
     712              : }
     713              : 
     714            1 : HcclResult RankConsistentcyChecker::GetCrc(u32 num, u32* crcAddr)
     715              : {
     716            1 :     CHK_PTR_NULL(crcAddr);
     717            1 :     HCCL_DEBUG("num[%u], crc[%u].", num, *crcAddr);
     718              : 
     719            1 :     if (num == 0) {
     720            0 :         HCCL_ERROR("[Get][Crc]errNo[0x%016llx] In get crc the value of num is 0", HCCL_ERROR_CODE(HCCL_E_PARA));
     721            0 :         return HCCL_E_PARA;
     722              :     }
     723              : 
     724            1 :     if (num != crcTable_.size()) {
     725            0 :         HCCL_ERROR(
     726              :             "[Get][Crc]errNo[0x%016llx] num error inputNum[%u], localNum[%llu]", HCCL_ERROR_CODE(HCCL_E_INTERNAL), num,
     727              :             crcTable_.size());
     728            0 :         return HCCL_E_INTERNAL;
     729              :     }
     730              : 
     731            4 :     for (u32 i = 0; i < num; i++) {
     732            3 :         crcAddr[i] = crcTable_[i];
     733              :     }
     734            1 :     return HCCL_SUCCESS;
     735              : }
     736              : } // namespace hccl
        

Generated by: LCOV version 2.0-1