| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
engram support training Co-authored-by: luozhonglin222<luozhonglin1@huawei.com> # message auto-generated for no-merge-commit merge: !8914 merge master into master engram support training Created-by: luozhonglin222 Commit-by: luozhonglin222 Merged-by: cann-robot Description: ## 描述 engram算子支持训练HOST代码,前向复用现有接口,增加相应参数,反向增加新接口 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/3838 ## 测试 本地验证 ## 文档更新 不涉及 ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: # PR #8914 代码检视报告 ## 检视概览 - **PR URL**:https://gitcode.com/cann/ops-transformer/pull/8914 - **算子名**:engram_fetch_grad / engram_fetch_train / elastic_buffer - **代码侧别**:Kernel + Tiling + 混合(torch_extension) - **变更文件数**:21 - **文件组数**:6(K1, K2, H1, H2, S, E) - **总条例数**:346 - **检视时间**:2026-07-21 - **检视模式**:大型 PR 检视(21 文件 > 10 阈值) ## 检视统计 | 状态 | 条例数 | 占比 | |------|--------|------| | PASS | 341 | 98.6% | | FAIL(发现问题) | 5 | 1.4% | | SUSPICIOUS(需关注) | 0 | 0% | ### 逐文件组统计 | 文件组 | 侧别 | 文件数 | PASS | FAIL | |--------|------|--------|------|------| | engram_fetch_grad_kernel_G1 (K1) | Kernel | 3 | 27 | 0 | | engram_fetch_train_kernel_G1 (K2) | Kernel | 3 | 37 | 0 | | engram_fetch_grad_host_G1 (H1) | Tiling | 3 | 66 | 2 | | engram_fetch_train_host_G1 (H2) | Tiling | 3 | 70 | 2 | | shared (S) | 混合 | 6 | 61 | 1 | | elastic_buffer (E) | 混合 | 3 | 80 | 0 | | **合计** | — | **21** | **341** | **5** | ### 系统性风险 **SEC-4.1 / TOPK-7 在 H1 和 H2 中均失败**:两个 Tiling 侧文件组(engram_fetch_grad 和 engram_fetch_train)均存在 sendCounts/recvLocalEntry(或 sendCountsOut/recvLocalEntryOut)的 dim(0) 值未做非负/范围校验的问题。两个算子的 tiling 代码结构高度相似,校验缺失模式相同,建议全局排查并统一修复。 --- ## 发现问题(HIGH 置信度) ### 1. [engram_fetch_grad_host_G1] SEC-4.1 外部输入数据需要做合法性校验 - **问题描述**:sendCounts 的 dim(0) 和 recvLocalEntry 的 dim(0) 作为外部输入(来自 graph shape)仅校验了维度数(1D),未对 dim(0) 的值做合法性校验,违反 SEC-4.1「外部输入数据需要做合法性校验且确保校验范围正确」。同一函数中 commContext(行 206 GetDim(0) <= 0)和 gradFetched(行 221 numTokens < 0、行 226 hiddenDim <= 0)均对 dim 值做了显式校验,sendCounts/recvLocalEntry 缺失同类校验,形成不一致的安全缺口。 **风险链路 1(sendCounts)**:dim(0) 若为负值或超过 UINT32_MAX,行 260 static_cast<uint32_t> 会发生窄化截断/回绕,rankSize 变为巨大错误值 → SetBlockDim 和 workspace 计算均受影响。 **风险链路 2(recvLocalEntry)**:dim(0) 赋值给 int64_t totalRecv(行 281),若为负值则保留负数 → wsRecvGrad = totalRecv * hiddenBytes 为负 → wsTotal 求和可能为负 → static_cast<size_t>(wsTotal) 将负数回绕为极大 size_t 值,导致 workspace 申请异常。 - **代码片段**(mc2/engram_fetch_grad/op_host/op_tiling/engram_fetch_grad_tiling.cpp 行 251-281): cpp // sendCounts: 1D (W,) const gert::StorageShape *sendCountsShape = context->GetInputShape(IN_SEND_COUNTS); OP_TILING_CHECK(sendCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCounts", (std::to_string(sendCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCounts must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsShape->GetStorageShape().GetDim(0)); // recvCounts: 1D (W,) const gert::StorageShape *recvCountsShape = context->GetInputShape(IN_RECV_COUNTS); OP_TILING_CHECK(recvCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvCounts", (std::to_string(recvCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvCounts must be 1D."), return ge::GRAPH_FAILED); // recvLocalEntry: 1D (R,) const gert::StorageShape *recvLocalEntryShape = context->GetInputShape(IN_RECV_LOCAL_ENTRY); OP_TILING_CHECK(recvLocalEntryShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvLocalEntry"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvLocalEntryShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvLocalEntry", (std::to_string(recvLocalEntryShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvLocalEntry must be 1D."), return ge::GRAPH_FAILED); totalRecv = recvLocalEntryShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:SEC-4.1 要求外部输入数据需做合法性校验,sendCounts dim(0) 直接 cast uint32_t、recvLocalEntry dim(0) 直接赋值 int64_t,均无值范围校验 - (+30%) 上下文防御缺失:同函数内 commContext/gradFetched 均有非负校验,唯独 sendCounts/recvLocalEntry 缺失 - (+20%) PR 归属:新增文件,全部行在 diff 变更范围内 - (+15%) 数据流风险:rankSize 负值回绕 / totalRecv 负值导致 workspace 回绕为巨大值 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**: 1. 在行 260 之前增加 sendCounts dim(0) 值校验(> 0) 2. 在行 281 之前增加 recvLocalEntry dim(0) 值校验(>= 0) 3. 参照同函数内 commContext/gradFetched 的校验模式 --- ### 2. [engram_fetch_grad_host_G1] TOPK-7 融合规则/InferShape/Tiling 外部输入校验 - **问题描述**:TOPK-7 要求「Tiling 外部输入使用时必须进行合法性校验」,校验内容包括「Shape 维度是否合法(不为负数、不超过限制)」。sendCounts dim(0) 和 recvLocalEntry dim(0) 作为外部输入被提取后直接使用,未做非负/范围校验。同函数内 commContext dim0(<=0 校验)、gradFetched dim0(<0 校验)、hiddenDim(<=0 校验)均有非负防御,唯独 sendCounts 和 recvLocalEntry 缺失。此问题与 SEC-4.1 同构。 - **代码片段**(mc2/engram_fetch_grad/op_host/op_tiling/engram_fetch_grad_tiling.cpp 行 251-281): cpp // sendCounts: 1D (W,) const gert::StorageShape *sendCountsShape = context->GetInputShape(IN_SEND_COUNTS); OP_TILING_CHECK(sendCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCounts", (std::to_string(sendCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCounts must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsShape->GetStorageShape().GetDim(0)); // ...(recvLocalEntry 同理) totalRecv = recvLocalEntryShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:TOPK-7 要求 Shape 维度不为负数 - (+30%) 上下文防御缺失:同函数内其他 tensor 均有非负校验 - (+20%) PR 归属:新增文件 - (+15%) 数据流风险:负值 dim0 经 static_cast 回绕或以负 int64_t 传播至 workspace 计算 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**:与 SEC-4.1 同一问题,修复方案一致。 --- ### 3. [engram_fetch_train_host_G1] SEC-4.1 外部输入数据需要做合法性校验 - **问题描述**:CheckTensorDim 中 sendCountsOut 和 recvLocalEntryOut 的 dim0 值作为外部输入未做范围校验。rankSize(uint32_t)通过 static_cast 从 int64_t 缩窄转换,若 dim0 为负或超过 UINT32_MAX 将静默截断/回绕为巨大值;totalRecv(int64_t)未校验非负,若为负值将导致 wsLocalData = totalRecv * hiddenBytes 为负,进而 wsTotal 为负,再经 static_cast<size_t>(wsTotal) 回绕为约 1.8e19 的巨大 workspace 申请。同函数内 commContextShape dim0 > 0(行 188)、numTokens >= 0(行 202)、numRecvOutShape dim0 == 1(行 272)均已校验,此处校验明显不一致。 - **代码片段**(mc2/engram_fetch_train/op_host/op_tiling/engram_fetch_train_tiling.cpp 行 235-262): cpp const gert::StorageShape *sendCountsOutShape = context->GetOutputShape(OUT_SEND_COUNTS); OP_TILING_CHECK(sendCountsOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCountsOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCountsOut", (std::to_string(sendCountsOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCountsOut must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsOutShape->GetStorageShape().GetDim(0)); const gert::StorageShape *recvCountsOutShape = context->GetOutputShape(OUT_RECV_COUNTS); OP_TILING_CHECK(recvCountsOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvCountsOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvCountsOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvCountsOut", (std::to_string(recvCountsOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvCountsOut must be 1D."), return ge::GRAPH_FAILED); const gert::StorageShape *recvLocalEntryOutShape = context->GetOutputShape(OUT_RECV_LOCAL_ENTRY); OP_TILING_CHECK(recvLocalEntryOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvLocalEntryOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvLocalEntryOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvLocalEntryOut", (std::to_string(recvLocalEntryOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvLocalEntryOut must be 1D."), return ge::GRAPH_FAILED); totalRecv = recvLocalEntryOutShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:外部 shape dim 值未做范围/非负校验 - (+30%) 上下文防御缺失:作用域内仅校验 dim 数,无 dim 值范围校验 - (+20%) PR 归属:新文件,全量代码均在 diff 范围 - (+15%) 数据流风险:rankSize 缩窄截断 / totalRecv 负值 → workspace 回绕 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**: 1. 在行 243 前增加 sendCountsOut dim(0) 非负及 <= UINT32_MAX 校验 2. 在行 262 前增加 recvLocalEntryOut dim(0) >= 0 校验 3. 参照同函数内 numTokens(行 202-205)的校验模式 --- ### 4. [engram_fetch_train_host_G1] TOPK-7 融合规则/InferShape/Tiling 外部输入校验 - **问题描述**:与 SEC-4.1 同一问题。TOPK-7 要求 Tiling 外部输入的 Shape 维度不为负数、不超过限制。sendCountsOut dim0(赋值给 rankSize,缩窄为 uint32_t)和 recvLocalEntryOut dim0(赋值给 totalRecv)均未做非负/范围校验。同函数内 commContextShape dim0 > 0(行 188)、indicesShape numTokens >= 0(行 202)均已校验,存在校验不一致。 - **代码片段**(mc2/engram_fetch_train/op_host/op_tiling/engram_fetch_train_tiling.cpp 行 235-262):(同 SEC-4.1) - **假设检验证据**: - (+40%) 规范违反:Tiling 外部 shape dim 值未做非负/范围校验 - (+30%) 上下文防御缺失:仅校验 dim 数无 dim 值校验 - (+20%) PR 归属:新文件全量在 diff 范围 - (+15%) 数据流风险:rankSize 缩窄截断 / totalRecv 负值 → work See merge request: cann/ops-transformer!8914 | 2 个月前 | |
Engram算子codecheck Co-authored-by: luozhonglin222<luozhonglin1@huawei.com> # message auto-generated for no-merge-commit merge: !12800 merge master into master Engram算子codecheck Created-by: luozhonglin222 Commit-by: luozhonglin222 Merged-by: cann-robot Description: ## 描述 修改codecheck ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [x] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12800 | 6 天前 | |
mc2: megamoe/engram/moe_ep版本门限改用VERSION_NUM;mega_moe BypassDCache改回ByPass旧名 Co-authored-by: gitcode_lijd<lijiandong20@huawei.com> # message auto-generated for no-merge-commit merge: !13092 merge fix_3 into master mc2: megamoe/engram/moe_ep版本门限改用VERSION_NUM;mega_moe BypassDCache改回ByPass旧名 Created-by: gitcode_lijd Commit-by: gitcode_lijd Merged-by: cann-robot Description: ## 描述 两部分改动: **1. 版本门限改用 VERSION_NUM(19 文件)** moe_ep_dispatch / moe_ep_combine(含 epilogue)、engram_fetch / engram_fetch_grad / engram_fetch_wait、megamoe 系列 kernel 侧 devkit/hcomm 版本门限统一改为 ASC_DEVKIT_VERSION_NUM >= 90200000 && HCOMM_VERSION_NUM >= 90200000。 原因:MAJOR/MINOR 宏无法区分 beta 与正式版(9.2.0-beta.2 与 9.2.0 正式版均为 9.2),beta 包会误放行编译依赖新接口(Hcomm BufDesc/BatchHandle 等批量 API)的 kernel 而报错。VERSION_NUM 编码包含预发布标识(9.2.0-beta.2 为 90199802,小于正式版 90200000),改后仅在 9.2.0 正式版及以上使能,beta 编译为空壳。 **2. mega_moe BypassDCache API 改回旧名(10 文件、34 处)** master 新提交(cd5e2b21d 等 4 笔)按 9.2.0 正式版头文件使用了新名 ReadGmBypassDCache / WriteGmBypassDCache,而 beta2 头文件只有旧名 ReadGmByPassDCache / WriteGmByPassDCache。9.2.0 正式版中新旧名共存(旧名为 deprecated 转发别名,功能等价,2027/12/30 后移除),改回旧名后两个版本均可编译,功能不变。 ## 验证 - 9.2.0-beta.2:engram×3 + moe_ep×4 + mega_moe 全部编译通过(mega_moe 改名后已在另一环境验证) - 9.2.0 正式版:moe_ep 系列、mega_moe 编译通过(旧名仅产生 deprecation 警告) - pre-commit 全钩子通过 9.2.0 分支同改动见 PR !13242。 See merge request: cann/ops-transformer!13092 | 11 小时前 | |
mc2:UT测试950命名清理——测试名/soc输入/mock设置改arch口径(Dav3510/3510) Co-authored-by: gitcode_lijd<lijiandong20@huawei.com> # message auto-generated for no-merge-commit merge: !12458 merge fix_2 into master mc2:UT测试950命名清理——测试名/soc输入/mock设置改arch口径(Dav3510/3510) Created-by: gitcode_lijd Commit-by: gitcode_lijd Merged-by: cann-robot Description: 关联Issue https://gitcode.com/cann/ops-transformer/issues/5147 ## 摘要 mc2 UT 测试侧 950 命名清理(与代码侧清理 PR #12455 拆分提交):测试名、soc 输入值、mock 平台设置统一 arch 口径。单笔提交,24 文件 +105/-105,零行为变化。 ## 改动明细 ### 1. UT 测试名统一(~35 处) gtest 测试名/fixture 类为测试二进制内部标识(全仓无 gtest_filter/脚本引用),测试体本已 arch 口径: - Ascend950LaunchCcuCommMode → Dav3510LaunchCcuCommMode(×10,all_gather_matmul + matmul_all_reduce 系) - Ascend950GetWorkspaceSize/NullCommMode/LaunchAicpuCommMode/Int4Weight → Dav3510*(×8) - moe_distribute_dispatch_v2:fixture ...V2950Test → ...V2Dav3510Test + 4 个测试名 - engram_fetch / engram_fetch_grad / mega_moe:小写 ascend950_* → dav3510_*(×17) - 2 处注释同步 ### 2. UT soc 输入口径统一(1 文件 18 处) - matmul_reduce_scatter/tests/ut/op_host/arch35:"Ascend910_95" → "3510" - 背景:Ascend910_95 为 950 内部名,tiling 执行器 socToArch 表无此键——NpuArch 资源被注入空串(带病通过);仓内 arch35 UT 主流写法为 "3510" 或 "Ascend950";改后正确注入 NpuArch=3510,与 #12347 口径一致 ### 3. UT mock 设置统一(18 文件 42 处) - op::SetPlatformSocVersion(op::SocVersion::ASCEND950) → op::SetPlatformNpuArch(Ops::Base::DAV_3510) - stub 侧两接口殊途同归(SetPlatformNpuArch 内部查表 DAV_3510→ASCEND950 再设 g_socVersion),行为完全等价;arch 写法为仓内主流 - param.soc 数据驱动路径(CSV→枚举)不动 ### 4. 版权头补齐(8 文件) - 首轮 CI 的 OAT 检查(License Header Invalid ×8)拦截了 8 个**存量旧版版权头**文件(Copyright (c) Huawei... All rights reserved. 旧模板,其一为畸形 /* *)——master 上的历史遗留,因文件进 PR 被 staged 才暴露 - 已统一替换为仓内标准头(与同 PR 通过检查的其余 16 文件同款) ## 语义等价性 - 测试名/mock 设置:内部标识与等价接口替换,断言与覆盖路径不变 - soc 输入:"Ascend910_95"→"3510" 经本地验证 23 tests PASSED(matmul_reduce_scatter op_host UT,含全部 expectTilingKey 断言) ## 范围说明 - tests 之外的代码侧清理(死函数/标识符/文件名/注释/def 局部变量)见 **#12455** - torch_extension 与 tools 目录整体不动;tests 中的合法 soc 字符串值("Ascend950" 输入)保留 See merge request: cann/ops-transformer!12458 | 10 天前 | |
engram support training Co-authored-by: luozhonglin222<luozhonglin1@huawei.com> # message auto-generated for no-merge-commit merge: !8914 merge master into master engram support training Created-by: luozhonglin222 Commit-by: luozhonglin222 Merged-by: cann-robot Description: ## 描述 engram算子支持训练HOST代码,前向复用现有接口,增加相应参数,反向增加新接口 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/3838 ## 测试 本地验证 ## 文档更新 不涉及 ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: # PR #8914 代码检视报告 ## 检视概览 - **PR URL**:https://gitcode.com/cann/ops-transformer/pull/8914 - **算子名**:engram_fetch_grad / engram_fetch_train / elastic_buffer - **代码侧别**:Kernel + Tiling + 混合(torch_extension) - **变更文件数**:21 - **文件组数**:6(K1, K2, H1, H2, S, E) - **总条例数**:346 - **检视时间**:2026-07-21 - **检视模式**:大型 PR 检视(21 文件 > 10 阈值) ## 检视统计 | 状态 | 条例数 | 占比 | |------|--------|------| | PASS | 341 | 98.6% | | FAIL(发现问题) | 5 | 1.4% | | SUSPICIOUS(需关注) | 0 | 0% | ### 逐文件组统计 | 文件组 | 侧别 | 文件数 | PASS | FAIL | |--------|------|--------|------|------| | engram_fetch_grad_kernel_G1 (K1) | Kernel | 3 | 27 | 0 | | engram_fetch_train_kernel_G1 (K2) | Kernel | 3 | 37 | 0 | | engram_fetch_grad_host_G1 (H1) | Tiling | 3 | 66 | 2 | | engram_fetch_train_host_G1 (H2) | Tiling | 3 | 70 | 2 | | shared (S) | 混合 | 6 | 61 | 1 | | elastic_buffer (E) | 混合 | 3 | 80 | 0 | | **合计** | — | **21** | **341** | **5** | ### 系统性风险 **SEC-4.1 / TOPK-7 在 H1 和 H2 中均失败**:两个 Tiling 侧文件组(engram_fetch_grad 和 engram_fetch_train)均存在 sendCounts/recvLocalEntry(或 sendCountsOut/recvLocalEntryOut)的 dim(0) 值未做非负/范围校验的问题。两个算子的 tiling 代码结构高度相似,校验缺失模式相同,建议全局排查并统一修复。 --- ## 发现问题(HIGH 置信度) ### 1. [engram_fetch_grad_host_G1] SEC-4.1 外部输入数据需要做合法性校验 - **问题描述**:sendCounts 的 dim(0) 和 recvLocalEntry 的 dim(0) 作为外部输入(来自 graph shape)仅校验了维度数(1D),未对 dim(0) 的值做合法性校验,违反 SEC-4.1「外部输入数据需要做合法性校验且确保校验范围正确」。同一函数中 commContext(行 206 GetDim(0) <= 0)和 gradFetched(行 221 numTokens < 0、行 226 hiddenDim <= 0)均对 dim 值做了显式校验,sendCounts/recvLocalEntry 缺失同类校验,形成不一致的安全缺口。 **风险链路 1(sendCounts)**:dim(0) 若为负值或超过 UINT32_MAX,行 260 static_cast<uint32_t> 会发生窄化截断/回绕,rankSize 变为巨大错误值 → SetBlockDim 和 workspace 计算均受影响。 **风险链路 2(recvLocalEntry)**:dim(0) 赋值给 int64_t totalRecv(行 281),若为负值则保留负数 → wsRecvGrad = totalRecv * hiddenBytes 为负 → wsTotal 求和可能为负 → static_cast<size_t>(wsTotal) 将负数回绕为极大 size_t 值,导致 workspace 申请异常。 - **代码片段**(mc2/engram_fetch_grad/op_host/op_tiling/engram_fetch_grad_tiling.cpp 行 251-281): cpp // sendCounts: 1D (W,) const gert::StorageShape *sendCountsShape = context->GetInputShape(IN_SEND_COUNTS); OP_TILING_CHECK(sendCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCounts", (std::to_string(sendCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCounts must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsShape->GetStorageShape().GetDim(0)); // recvCounts: 1D (W,) const gert::StorageShape *recvCountsShape = context->GetInputShape(IN_RECV_COUNTS); OP_TILING_CHECK(recvCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvCounts", (std::to_string(recvCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvCounts must be 1D."), return ge::GRAPH_FAILED); // recvLocalEntry: 1D (R,) const gert::StorageShape *recvLocalEntryShape = context->GetInputShape(IN_RECV_LOCAL_ENTRY); OP_TILING_CHECK(recvLocalEntryShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvLocalEntry"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvLocalEntryShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvLocalEntry", (std::to_string(recvLocalEntryShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvLocalEntry must be 1D."), return ge::GRAPH_FAILED); totalRecv = recvLocalEntryShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:SEC-4.1 要求外部输入数据需做合法性校验,sendCounts dim(0) 直接 cast uint32_t、recvLocalEntry dim(0) 直接赋值 int64_t,均无值范围校验 - (+30%) 上下文防御缺失:同函数内 commContext/gradFetched 均有非负校验,唯独 sendCounts/recvLocalEntry 缺失 - (+20%) PR 归属:新增文件,全部行在 diff 变更范围内 - (+15%) 数据流风险:rankSize 负值回绕 / totalRecv 负值导致 workspace 回绕为巨大值 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**: 1. 在行 260 之前增加 sendCounts dim(0) 值校验(> 0) 2. 在行 281 之前增加 recvLocalEntry dim(0) 值校验(>= 0) 3. 参照同函数内 commContext/gradFetched 的校验模式 --- ### 2. [engram_fetch_grad_host_G1] TOPK-7 融合规则/InferShape/Tiling 外部输入校验 - **问题描述**:TOPK-7 要求「Tiling 外部输入使用时必须进行合法性校验」,校验内容包括「Shape 维度是否合法(不为负数、不超过限制)」。sendCounts dim(0) 和 recvLocalEntry dim(0) 作为外部输入被提取后直接使用,未做非负/范围校验。同函数内 commContext dim0(<=0 校验)、gradFetched dim0(<0 校验)、hiddenDim(<=0 校验)均有非负防御,唯独 sendCounts 和 recvLocalEntry 缺失。此问题与 SEC-4.1 同构。 - **代码片段**(mc2/engram_fetch_grad/op_host/op_tiling/engram_fetch_grad_tiling.cpp 行 251-281): cpp // sendCounts: 1D (W,) const gert::StorageShape *sendCountsShape = context->GetInputShape(IN_SEND_COUNTS); OP_TILING_CHECK(sendCountsShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCounts"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCounts", (std::to_string(sendCountsShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCounts must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsShape->GetStorageShape().GetDim(0)); // ...(recvLocalEntry 同理) totalRecv = recvLocalEntryShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:TOPK-7 要求 Shape 维度不为负数 - (+30%) 上下文防御缺失:同函数内其他 tensor 均有非负校验 - (+20%) PR 归属:新增文件 - (+15%) 数据流风险:负值 dim0 经 static_cast 回绕或以负 int64_t 传播至 workspace 计算 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**:与 SEC-4.1 同一问题,修复方案一致。 --- ### 3. [engram_fetch_train_host_G1] SEC-4.1 外部输入数据需要做合法性校验 - **问题描述**:CheckTensorDim 中 sendCountsOut 和 recvLocalEntryOut 的 dim0 值作为外部输入未做范围校验。rankSize(uint32_t)通过 static_cast 从 int64_t 缩窄转换,若 dim0 为负或超过 UINT32_MAX 将静默截断/回绕为巨大值;totalRecv(int64_t)未校验非负,若为负值将导致 wsLocalData = totalRecv * hiddenBytes 为负,进而 wsTotal 为负,再经 static_cast<size_t>(wsTotal) 回绕为约 1.8e19 的巨大 workspace 申请。同函数内 commContextShape dim0 > 0(行 188)、numTokens >= 0(行 202)、numRecvOutShape dim0 == 1(行 272)均已校验,此处校验明显不一致。 - **代码片段**(mc2/engram_fetch_train/op_host/op_tiling/engram_fetch_train_tiling.cpp 行 235-262): cpp const gert::StorageShape *sendCountsOutShape = context->GetOutputShape(OUT_SEND_COUNTS); OP_TILING_CHECK(sendCountsOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "sendCountsOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(sendCountsOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "sendCountsOut", (std::to_string(sendCountsOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of sendCountsOut must be 1D."), return ge::GRAPH_FAILED); rankSize = static_cast<uint32_t>(sendCountsOutShape->GetStorageShape().GetDim(0)); const gert::StorageShape *recvCountsOutShape = context->GetOutputShape(OUT_RECV_COUNTS); OP_TILING_CHECK(recvCountsOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvCountsOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvCountsOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvCountsOut", (std::to_string(recvCountsOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvCountsOut must be 1D."), return ge::GRAPH_FAILED); const gert::StorageShape *recvLocalEntryOutShape = context->GetOutputShape(OUT_RECV_LOCAL_ENTRY); OP_TILING_CHECK(recvLocalEntryOutShape == nullptr, OP_LOGE_WITH_INVALID_INPUT(nodeName, "recvLocalEntryOut"), return ge::GRAPH_FAILED); OP_TILING_CHECK(recvLocalEntryOutShape->GetStorageShape().GetDimNum() != DIM_ONE, OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON(nodeName, "recvLocalEntryOut", (std::to_string(recvLocalEntryOutShape->GetStorageShape().GetDimNum()) + "D").c_str(), "The shape dim of recvLocalEntryOut must be 1D."), return ge::GRAPH_FAILED); totalRecv = recvLocalEntryOutShape->GetStorageShape().GetDim(0); - **假设检验证据**: - (+40%) 规范违反:外部 shape dim 值未做范围/非负校验 - (+30%) 上下文防御缺失:作用域内仅校验 dim 数,无 dim 值范围校验 - (+20%) PR 归属:新文件,全量代码均在 diff 范围 - (+15%) 数据流风险:rankSize 缩窄截断 / totalRecv 负值 → workspace 回绕 - 自信值 = 105% ≥ 70% → 判定违规 - **修复建议**: 1. 在行 243 前增加 sendCountsOut dim(0) 非负及 <= UINT32_MAX 校验 2. 在行 262 前增加 recvLocalEntryOut dim(0) >= 0 校验 3. 参照同函数内 numTokens(行 202-205)的校验模式 --- ### 4. [engram_fetch_train_host_G1] TOPK-7 融合规则/InferShape/Tiling 外部输入校验 - **问题描述**:与 SEC-4.1 同一问题。TOPK-7 要求 Tiling 外部输入的 Shape 维度不为负数、不超过限制。sendCountsOut dim0(赋值给 rankSize,缩窄为 uint32_t)和 recvLocalEntryOut dim0(赋值给 totalRecv)均未做非负/范围校验。同函数内 commContextShape dim0 > 0(行 188)、indicesShape numTokens >= 0(行 202)均已校验,存在校验不一致。 - **代码片段**(mc2/engram_fetch_train/op_host/op_tiling/engram_fetch_train_tiling.cpp 行 235-262):(同 SEC-4.1) - **假设检验证据**: - (+40%) 规范违反:Tiling 外部 shape dim 值未做非负/范围校验 - (+30%) 上下文防御缺失:仅校验 dim 数无 dim 值校验 - (+20%) PR 归属:新文件全量在 diff 范围 - (+15%) 数据流风险:rankSize 缩窄截断 / totalRecv 负值 → work See merge request: cann/ops-transformer!8914 | 2 个月前 |