/assign @gcw_dFpssWuk


问题2.2 在hccl/src/ops/all_to_all_v/all_to_all_v_op.cc的CalcInputOutputSize函数保证偏移不会溢出


问题2.3 maxDataCountPerLoop由u64数据类型的maxDataSizePerLoop除以dataTypeSize_得到,所以相乘后不会溢出


问题3.1 dataTypeSize_由查表得到,表中数据确认无0,rankSize_由算子入口校验,hccl/src/ops/all_to_all_v/all_to_all_v_op.cc中HcomCheckUserRank函数可确保其不为0


问题3.2 factor由u32类型相加,已确保最小值为4


问题3.3 已确认290行有检查是否为0


问题4.1 已确认62行检查algHierarchyInfo.infos[0].size()为2


问题4.2 同问题4.1


问题4.3 已确认103行检查resCtx.channels.size()为1


问题4.4 hccl/src/ops/op_common/op_common.cc:591行thread[0]已赋值,又在1033行push_back threadNum个thread,threadNum可由hccl/src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc:208行确保最小为1,所以threads.size()大于等于2


问题5.2 已确认在hccl/src/ops/all_to_all_v/all_to_all_v_op.cc的CheckAlltoAllVInputPara中进行空指针校验


问题5.4 已确认inputPtr和outputPtr均来自sendBuf和recvBuf,在算子入口处已检查


问题7.1 同步失败后报错算子调用侧会进行资源回收


问题7.3 算法编排中会进行偏移计算,确保不对共享资源进行冲突访问


问题7.3 此处线程非系统资源线程概念,由业务侧保证有效性


AllToAllV 代码检视报告(详细版)
检视模块:
src/ops/all_to_all_v/检视模式:条款级精确检视
1. 检视概览
问题分布:
2. 无符号整数运算不回绕
检视结果:FAIL | 置信度:HIGH (85%)
问题1:乘法运算无溢出保护
文件:
src/ops/all_to_all_v/selector/alltoall_auto_selector.cc行号:67-68, 114-115
问题代码:
67: uint32_t dataTypeSize = DATATYPE_SIZE_TABLE[opParam.all2AllDataDes.sendType]; 68: uint64_t dataSize = opParam.all2AllDataDes.sendCount * dataTypeSize;问题描述:
sendCount和dataTypeSize都是 uint 类型修复建议:
uint32_t dataTypeSize = DATATYPE_SIZE_TABLE[opParam.all2AllDataDes.sendType]; if (dataTypeSize == 0 || opParam.all2AllDataDes.sendCount == 0) { HCCL_ERROR("dataTypeSize or sendCount is zero"); return HCCL_E_PARA; } if (opParam.all2AllDataDes.sendCount > UINT64_MAX / dataTypeSize) { HCCL_ERROR("dataSize overflow detected"); return HCCL_E_PARA; } uint64_t dataSize = opParam.all2AllDataDes.sendCount * dataTypeSize;问题2:计算偏移无溢出保护
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:161-164
问题代码:
161: u64 curSendCounts = *(static_cast<const u64 *>(param.all2AllVDataDes.sendCounts) + j); 162: u64 curSendDispls = *(static_cast<const u64 *>(param.all2AllVDataDes.sdispls) + j); 163: localSendRecvInfo_.sendCounts[j] = curSendCounts; 164: localSendRecvInfo_.sendDispls[j] = curSendDispls;问题描述:
curSendDispls是否会导致地址计算溢出修复建议:
u64 curSendCounts = *(static_cast<const u64 *>(param.all2AllVDataDes.sendCounts) + j); u64 curSendDispls = *(static_cast<const u64 *>(param.all2AllVDataDes.sdispls) + j); // 检查偏移值是否合理 if (curSendDispls + curSendCounts > param.inputSize) { HCCL_ERROR("sendDispls + sendCounts exceeds inputSize"); return HCCL_E_PARA; } localSendRecvInfo_.sendCounts[j] = curSendCounts; localSendRecvInfo_.sendDispls[j] = curSendDispls;问题3:数据大小计算无保护
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:305-307
问题代码:
305: tempAlgParams.inputSliceStride = maxDataCountPerLoop * dataTypeSize_; 306: // 这里用来放每张卡之间的stride大小 307: tempAlgParams.outputSliceStride = maxSendOrRecvDataCount * dataTypeSize_;问题描述:
maxDataCountPerLoop * dataTypeSize_可能溢出修复建议:
if (dataTypeSize_ == 0) { HCCL_ERROR("dataTypeSize_ is zero"); return HCCL_E_PARA; } if (maxDataCountPerLoop > UINT64_MAX / dataTypeSize_) { HCCL_ERROR("inputSliceStride overflow"); return HCCL_E_PARA; } tempAlgParams.inputSliceStride = maxDataCountPerLoop * dataTypeSize_;3. 除法/余数运算除零保护
检视结果:FAIL | 置信度:HIGH (90%)
问题1:除法运算除零风险
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:282-284
问题代码:
282: u64 maxDataCountPerLoop = maxDataSizePerLoop / dataTypeSize_; // 发往单卡的数据count 283: if (param.engine == CommEngine::COMM_ENGINE_AIV) { 284: maxDataCountPerLoop = maxDataCountPerLoop / rankSize_;问题描述:
dataTypeSize_和rankSize_均可能为0修复建议:
if (dataTypeSize_ == 0) { HCCL_ERROR("dataTypeSize_ is zero, cannot divide"); return HCCL_E_PARA; } u64 maxDataCountPerLoop = maxDataSizePerLoop / dataTypeSize_; if (param.engine == CommEngine::COMM_ENGINE_AIV) { if (rankSize_ == 0) { HCCL_ERROR("rankSize_ is zero, cannot divide"); return HCCL_E_PARA; } maxDataCountPerLoop = maxDataCountPerLoop / rankSize_; }问题2:切分算法除零风险
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc行号:115-117, 143
问题代码:
115: uint32_t factorMesh = rankSize_ - 1; 116: uint32_t factorClos = CONST_4; 117: uint32_t factor = factorMesh + factorClos; 143: sendRecvInfoFirst.sendCounts[i] = localSendRecvInfo_.sendCounts[i] / factor * factorClos;问题描述:
factor是否为0rankSize_ == 1时,factorMesh = 0,但factor = CONST_4 = 4,不会除零修复建议:
uint32_t factor = factorMesh + factorClos; if (factor == 0) { HCCL_ERROR("factor is zero, cannot divide"); return HCCL_E_PARA; } sendRecvInfoFirst.sendCounts[i] = localSendRecvInfo_.sendCounts[i] / factor * factorClos;问题3:循环计算除零
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:301-302
问题代码:
301: u64 loopTimes = maxSendOrRecvDataCount / maxDataCountPerLoop + 302: static_cast<u64>(maxSendOrRecvDataCount % maxDataCountPerLoop != 0);问题描述:
maxDataCountPerLoop是否为0maxDataCountPerLoop == 0,但防御不完整修复建议:
if (maxDataCountPerLoop == 0) { HCCL_ERROR("maxDataCountPerLoop is zero"); return HCCL_E_PARA; } u64 loopTimes = maxSendOrRecvDataCount / maxDataCountPerLoop + static_cast<u64>(maxSendOrRecvDataCount % maxDataCountPerLoop != 0);4. 数组索引校验
检视结果:FAIL | 置信度:HIGH (95%)
问题1:访问 infos[0] 未检查边界
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:56-59, 69-79
问题代码:
56: if (algHierarchyInfo.infos.size() == 0) { 57: HCCL_ERROR("algHierarchyInfo level num is zero!"); 58: return HCCL_E_PARA; 59: } ... 69: tempAlgHierachyInfo.push_back(algHierarchyInfo.infos[0][1]);问题描述:
infos.size() == 0infos[0].size() >= 2infos[0][1]可能越界修复建议:
if (algHierarchyInfo.infos.size() == 0 || algHierarchyInfo.infos[0].size() < 2) { HCCL_ERROR("algHierarchyInfo.infos size invalid"); return HCCL_E_PARA; } tempAlgHierachyInfo.push_back(algHierarchyInfo.infos[0][1]);问题2:访问 infos[0] 和 infos[1] 未检查
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:71-78
问题代码:
71: CHK_PRT_RET(algHierarchyInfo.infos[0][1].size() >= algHierarchyInfo.infos[1][0].size(), 72: HCCL_ERROR("..."), algHierarchyInfo.infos[1][0].size()), 73: HCCL_E_PARA); 74: tempAlgHierachyInfo.push_back(algHierarchyInfo.infos[0][1]); 75: tempAlgHierachyInfo.push_back(algHierarchyInfo.infos[1][0]);问题描述:
infos[1]前未检查infos.size() >= 2修复建议:
if (algHierarchyInfo.infos.size() < 2) { HCCL_ERROR("algHierarchyInfo.infos size < 2"); return HCCL_E_PARA; } CHK_PRT_RET(algHierarchyInfo.infos[0][1].size() >= algHierarchyInfo.infos[1][0].size(), HCCL_ERROR("size mismatch"), HCCL_E_PARA);问题3:访问 channels[0] 未检查
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:107-111
问题代码:
107: remoteRankToChannelInfo_.resize(CONST_ONE); 108: for (auto &channel : resCtx.channels[0]) { 109: u32 remoteRank = channel.remoteRank; 110: remoteRankToChannelInfo_[0][remoteRank].push_back(channel); 111: }问题描述:
resCtx.channels[0]前未检查channels.size()修复建议:
if (resCtx.channels.size() == 0) { HCCL_ERROR("channels size is zero"); return HCCL_E_PARA; } remoteRankToChannelInfo_.resize(CONST_ONE); for (auto &channel : resCtx.channels[0]) { ... }问题4:访问 threads[1] 未检查
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc行号:136, 310-311
问题代码:
136: std::vector<ThreadHandle> subThreads = {resCtx.threads[1]}; ... 310: templateAlgResMesh.threads.push_back(resCtx.threads[1]);问题描述:
threads[1]前未检查threads.size() >= 2修复建议:
if (resCtx.threads.size() < 2) { HCCL_ERROR("threads size < 2"); return HCCL_E_PARA; } std::vector<ThreadHandle> subThreads = {resCtx.threads[1]};5. 外部输入合法性校验
检视结果:FAIL | 置信度:HIGH (90%)
问题1:topoInfo 指针未判空
文件:
src/ops/all_to_all_v/selector/alltoallv_auto_selector.cc行号:26-29
问题代码:
26: HCCL_DEBUG("[AlltoAllVAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo->topoLevelNums); 27: (void)opParam; 28: (void)configAlgMap; 29: if (topoInfo->topoLevelNums > 1) {问题描述:
topoInfo指针成员修复建议:
if (topoInfo == nullptr) { HCCL_ERROR("[AlltoAllVAutoSelector] topoInfo is nullptr"); return SelectorStatus::NOT_MATCH; } HCCL_DEBUG("[AlltoAllVAutoSelector][%s] start, topoInfo levelNum[%u]", __func__, topoInfo->topoLevelNums);问题2:外部数据强转使用
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:159-171
问题代码:
159: for (u32 j = 0; j < rankSize_; j++) { 160: // Send info 161: u64 curSendCounts = *(static_cast<const u64 *>(param.all2AllVDataDes.sendCounts) + j); 162: u64 curSendDispls = *(static_cast<const u64 *>(param.all2AllVDataDes.sdispls) + j);问题描述:
sendCounts和sdispls未判空修复建议:
if (param.all2AllVDataDes.sendCounts == nullptr || param.all2AllVDataDes.sdispls == nullptr) { HCCL_ERROR("sendCounts or sdispls is nullptr"); return HCCL_E_PARA; } for (u32 j = 0; j < rankSize_; j++) { u64 curSendCounts = *(static_cast<const u64 *>(param.all2AllVDataDes.sendCounts) + j); u64 curSendDispls = *(static_cast<const u64 *>(param.all2AllVDataDes.sdispls) + j); }问题3:param.varData 指针未判空
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_sole_executor.cc行号:133-136
问题代码:
133: const u64* data = reinterpret_cast<const u64*>(param.varData); 134: // 从varData把值取出来 135: for (u64 i = 0; i < ALL_TO_ALL_V_VECTOR_NUM * rankSize_; i++) { 136: HCCL_INFO("OrchestrateLoop, param.varData[%u] is [%u]", i, data[i]);问题描述:
param.varData未判空修复建议:
if (param.varData == nullptr) { HCCL_ERROR("param.varData is nullptr"); return HCCL_E_PARA; } const u64* data = reinterpret_cast<const u64*>(param.varData);问题4:buffInfo 指针检查不一致
文件:
src/ops/all_to_all_v/template/ccu/ccu_temp_all_to_all_v_mesh2die.cc行号:121-124
问题代码:
121: CHK_PRT_RET(buffInfo.inputPtr == nullptr || buffInfo.outputPtr == nullptr, 122: HCCL_ERROR("..."), buffInfo.inputPtr, buffInfo.outputPtr), 123: HcclResult::HCCL_E_PTR);问题描述:
修复建议:
统一所有模板文件中的指针检查逻辑,在入口处统一检查:
if (buffInfo.inputPtr == nullptr || buffInfo.outputPtr == nullptr) { HCCL_ERROR("buffer pointer is nullptr"); return HCCL_E_PTR; }7. 访问临界资源需要保护
检视结果:FAIL | 置信度:HIGH (85%)
问题1:线程同步返回值未检查完整
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc行号:339, 351
问题代码:
339: CHK_RET(PreSyncInterThreads(mainThread, subThreads, notifyIdxMainToSub)); ... 351: CHK_RET(PostSyncInterThreads(mainThread, subThreads, notifyIdxSubToMain));问题描述:
CHK_RET检查返回值修复建议:
HcclResult ret = PreSyncInterThreads(mainThread, subThreads, notifyIdxMainToSub); if (ret != HCCL_SUCCESS) { HCCL_ERROR("PreSyncInterThreads failed, ret=%d", ret); // 添加恢复逻辑或清理资源 return ret; }问题2:共享资源访问未完全保护
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc行号:341-349
问题代码:
341: ret = algTemplateClos->KernelRun(param, tempAlgParamsClos, templateAlgResClos); 342: CHK_PRT_RET(ret != HCCL_SUCCESS, ...); 343: 344: ret = algTemplateMesh->KernelRun(param, tempAlgParamsMesh, templateAlgResMesh); 345: CHK_PRT_RET(ret != HCCL_SUCCESS, ...);问题描述:
param.inputPtr/outputPtr修复建议:
确认
inputPtr/outputPtr的并发访问是否需要锁保护:// 如果需要保护,添加锁机制 std::lock_guard<std::mutex> lock(bufferMutex); ret = algTemplateClos->KernelRun(param, tempAlgParamsClos, templateAlgResClos);问题3:线程数组构建未检查
文件:
src/ops/all_to_all_v/executor/ins_v2_all_to_all_v_concurrent_executor.cc行号:334-337
问题代码:
334: ThreadHandle mainThread = resCtx.threads[0]; 335: std::vector<ThreadHandle> subThreads = {resCtx.threads[1]}; 336: std::vector<u32> notifyIdxMainToSub = {0}; 337: std::vector<u32> notifyIdxSubToMain = {0};问题描述:
threads[0]和threads[1]修复建议:
if (resCtx.threads.size() < 2) { HCCL_ERROR("threads size < 2"); return HCCL_E_PARA; } // 检查线程句柄是否有效 if (!IsValidThread(resCtx.threads[0]) || !IsValidThread(resCtx.threads[1])) { HCCL_ERROR("thread handle invalid"); return HCCL_E_PARA; } ThreadHandle mainThread = resCtx.threads[0]; std::vector<ThreadHandle> subThreads = {resCtx.threads[1]};8. 问题严重性分类
HIGH 严重级别(14个,需立即修复)
MEDIUM 严重级别(3个,建议修复)
9. 修复优先级建议
第一优先级(立即修复)
除零保护
数组边界检查
指针判空
乘法溢出保护
第二优先级(建议修复)
线程同步完整性
共享资源保护
总结
主要问题:
建议: