| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
dispatch/combine训练算子支持epilogue异步调用 Co-authored-by: zhong-zixin<zhongzixin@huawei.com> # message auto-generated for no-merge-commit merge: !12114 merge feat/elastic-buffer-defer-epilogue into master dispatch/combine训练算子支持epilogue异步调用 Created-by: zhong-zixin Commit-by: zhong-zixin Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> 为 ElasticBuffer.dispatch/combine 新增 async_with_compute_stream=True 模式:主阶段下发后立即返回 event 对象,用户可在同流插入独立计算,再调用 event.current_stream_wait() 提交 epilogue 并取回结果。 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> 关联Issue [#5459](https://gitcode.com/cann/ops-transformer/issues/5459) ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> 本地验证,二级冒烟 ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> 更新了mc2/common/docs/torchapi_ElasticBuffer.md ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [x] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: # PR #12114 检视报告:dispatch/combine 训练算子支持 epilogue 异步调用 | 项目 | 内容 | |------|------| | PR | https://gitcode.com/cann/ops-transformer/pull/12114(zhong-zixin:feat/elastic-buffer-defer-epilogue → cann:master,状态 Open) | | 检视基线 | merge-base 9578ac8c0,PR head 988163303(2 个提交:2a2c08404 支持延后提交 MoE epilogue;988163303 epilogue 退出前排空尾部发送完成) | | 变更范围 | 7 个文件,+313/-62:elastic_buffer.py(事件对象与 API)、新增 moe_ep_send_completion.h(DrainChannels,+44)、moe_ep_dispatch.h / moe_ep_combine.h(WQE CQE 配置)、两个 epilogue 头(接入 drain)、torchapi_ElasticBuffer.md(API 文档) | | 模块 | mc2(moe_ep_dispatch / moe_ep_combine / moe_ep_*_epilogue / common) | | 结论 | **无阻塞性缺陷**。1 项性能确认(中)、1 项文档完善建议(低,可选)、3 项信息级记录(第 3、4 项为一致性/边界讨论,不构成缺陷) | --- ## 1. 变更内容概述 本 PR 为 ElasticBuffer.dispatch/combine 新增 async_with_compute_stream=True 模式:主阶段下发后立即返回 event 对象,用户可在同流插入独立计算,再调用 event.current_stream_wait() 提交 epilogue 并取回结果。 **Python 侧(elastic_buffer.py)**: - 新增 _EPEpilogueEvent(记录发起流、完成事件、回调、keepalive 引用)与模块级 WeakSet 登记;_reserve_moe_epilogue 在主阶段下发**前**登记占用,部分失败时保留资源并禁止重试(_attempted/_completion_recorded/_callback is not None 三态检查)。 - dispatch/combine 在 async_with_compute_stream=False 时行为不变(闭包立即执行);True 时返回 event,epilogue 延后到 wait 时提交。combine 的 _checked_handle_metadata_buffer 由两次调用合并为一次(该函数为纯校验、返回 handle.recv_metadata_buffer,幂等,无行为变化)。 - _check_moe_epilogue_events:同通信组的下一次 dispatch/combine(含同步模式)前强制先 wait;设备未完成时强制同流;query() 完成后惰性 _release。destroy() 强制"先 wait → 逐事件 synchronize → 再销毁 runtime"。 - _ensure_moe_config 增加 destroyed 检查。 **内核侧**: - 新增 mc2/common/op_kernel/moe_ep_send_completion.h:DrainChannels(context, worldSize, pipe) —— PipeBarrier<PIPE_ALL> + pipe->Reset() + 512B UB 初始化 Hcomm,按 GetBlockIdx() 平铺分配排空 [0, worldSize*channelsPerRank) 全部通道(跳过自 rank),末尾对 context 做 DataCacheCleanAndInvalid(ENTIRE_DATA_CACHE)发布。 - moe_ep_dispatch.h:新增 LAST_DATA_CFG(cqe=1)用于每通道末批数据写;NOTIFY_CFG cqe 0→1(odr 5→6,与末尾 notify 一致);零 token 早退路径改用 NOTIFY_CFG。 - moe_ep_combine.h:CHANNEL_FLAG_WQE_CONFIG cqe 0→1;SendRemoteMetadataSlot 增加 lastToken 参数,range 末笔 payload 请求 CQE。 - 两个 epilogue 的 Process() 末尾无条件调用 DrainChannels。 ## 2. 正确性验证(逐项确认,均通过) | # | 检查项 | 结论 | |---|--------|------| | 1 | **Drain 通道覆盖** | 两个 epilogue 入口(.cpp)对所有 block 无条件调用 Process(),DrainChannels 位于 Process() 末尾(早退 return 均在其之前闭合);for (index = GetBlockIdx(); index < worldSize*channelsPerRank; index += GetBlockNum()) 覆盖全部通道。自 rank 通道句柄在 host 侧未填充(GetHcclCommChannel 跳过 peer==self),index / channelsPerRank == epRankId 的跳过是**必需**的,已正确实现 | | 2 | **CQE 覆盖(dispatch)** | 每个远端 (dstRank, channel):有 token 时末批 LAST_DATA_CFG + 末尾 NOTIFY_CFG 均带 CQE;零 token / 越界时早退 NOTIFY_CFG 带 CQE。count 阶段(WriteWithNotifyNbi<DATA_CFG>,无 CQE)仅走 channel 0,与发送阶段同核同通道、SQ FIFO 有序,被后续 CQE 覆盖。jettyCntPerRank = min(dispatchNotifyCount_, channelsPerRank_) 可能少于总通道数,未用通道 cqHead 不增长,drain 立即返回 | | 3 | **CQE 覆盖(combine)** | 每个远端 (rank, channel) 无论 range 是否为空都发布 flag(publishesChannelFlag 独立于 sendsTokens/actualA_),CHANNEL_FLAG_WQE_CONFIG 带 CQE;非空 range 末笔 payload 另有 CQE。低 AIV 分支(splitRankTokens==false)按 stride 走 channel 0,同样有 flag CQE | | 4 | **Drain 语义** | Hcomm<UBC_CTP>::Drain(ChannelHandle) → PollCq(channel, channelEntity->cqHead),cqHead 为通道累计 CQE 计数(每次 cqe=1 的 WQE 递增),一次 drain 等待**全部**未决 CQE——同通道多笔 CQE(末笔 + flag + 高水位检查点)均被覆盖,不会只消费一笔 | | 5 | **跨 kernel 可见性** | epilogue 读主阶段核写的 channelEntity->cqHead 跨 kernel 排空,与仓内既有先例 engram_fetch → engram_fetch_wait(独立 wait kernel 排空前一 kernel 的发送)同构 | | 6 | **TPipe::Reset() 复用** | kernel 中途 Reset() + InitBuffer(512) 有既有先例(batch_mat_mul_reduce_scatter_allto_all.h、sort_lib.h);512 == 仓内 HCOMM_INIT_SIZE == 库侧 HCOMM_URMA_TMP_BUF_SIZE 下限,恰好满足;调用点位于各 epilogue 全部计算完成之后 | | 7 | **末笔判定** | chunkStart + i + 1U == rangeEnd(combine,chunk 循环内绝对终点)与 processed + batchCnt == tokenNum && i + 1U == batchGroup(dispatch,末轮末 SQE)均无差一错误 | | 8 | **事件生命周期** | reserve 先于主阶段下发(主阶段/分配失败 → 事件残留 + 明确"不可重试"报错,资源保留);_release 仅作用于已 record 的事件,且同时从实例强引用列表与全局 WeakSet 移除(无双重释放路径);event._owner 强引用使 GC 无法在延后操作存活期间回收 Buffer(C++ 析构不会抢先执行);keepalive 集合覆盖闭包全部张量引用,x/输入在发送完成前不被释放 | | 9 | **流一致性** | ACLNN_CMD 经 c10_npu::getCurrentNPUStream() 下发,与事件捕获/校验的 torch.npu.current_stream() 一致;commStream_(池化流)仅用于 engram 路径,MoE 路径不受影响 | | 10 | **死锁风险** | flag/notify 均由主阶段 kernel 提交(epilogue 启动前已入 SQ),URMA 引擎独立于 AIV 推进,epilogue 的 flag 等待与 drain 均不构成 AIV 级循环等待 | | 11 | **文档与示例** | 签名、参数、输出说明与实现一致;示例满足全部约束(同流 mm、独立数据、do_cpu_sync=False) | 另外确认:drain 同时**修复了同步路径的潜在隐患**——旧代码 combine epilogue 退出不等待本 rank 发送完成(旧注释"final ordered flag is submitted without waiting here"),combine 返回后立即复用/覆写输入 x 的内存可能损坏在途 URMA 读;新 drain 使"epilogue kernel 退出 ⇒ 本 rank 全部发送完成"成立。该隐患在默认(同步)路径本就存在,因此无条件 drain 对默认路径同样是正确性修复(见第 3 节中-2)。NOTIFY_CFG 早退路径 odr 5→6 后与末尾 notify 语义一致,无风险。 ## 3. 问题清单 ### [低-1] async 模式下 do_cpu_sync=True 的 host count 等待未在文档中交叉说明 do_cpu_sync 与 async_with_compute_stream 控制不同层面,同时开启合法且有意义: - do_cpu_sync=True 时 dispatch() 在返回 event 前等待 count(elastic_buffer.py:1114 → _get_dispatch_recv_count → spin_wait(),:1555-1564),以按实际接收量分配输出;False 时输出按最大容量预分配(:1560-1564)。 - async_with_compute_stream=True 只决定 epilogue 提交时机,与 do_cpu_sync 无冲突:event 照常返回、epilogue 照常延后(:1153-1156)。 - 该行为为刻意设计(elastic_buffer.py:1113 注释:"count等待和输出分配仍在dispatch内完成,仅延后Epilogue及结果组装")。 建议(文档完善,可选):torchapi_ElasticBuffer.md:382-383 对两个参数各自的说明准确,但未交叉提及——可在 async_with_compute_stream 的参数说明中补一句"do_cpu_sync=False 可避免返回 event 前的 host 等待(代价是输出按最大容量预分配)"。 ### [中-2] 默认(同步)路径新增 CQE + 无条件 drain:行为变更确认,性能代价待量化 每笔 flag/notify 请求 CQE(moe_ep_combine.h CHANNEL_FLAG_WQE_CONFIG cqe 0→1;moe_ep_dispatch.h NOTIFY_CFG cqe 0→1、新增 LAST_DATA_CFG),两个 epilogue Process() 末尾无条件 DrainChannels——默认路径的发送完成边界由旧的"不等待、靠后续算子 flag 链传递"变为"epilogue kernel 退出前显式等待本 rank 全部发送完成"。 无条件启用是正确性修复而非可选优化:默认路径同样存在发送输入提前复用风险(见第 2 节末尾),仅 async 调用时启用 drain 会重新暴露该隐患。 待确认事项:同步路径的额外代价(每通道每调用至少多一笔 CQE + kernel 末尾排空等待)尚无量化数据(现有 profiling 仅验证插入顺序,未量化默认路径代价)。建议合入前补一组标准训练循环吞吐/时延对比(同 batch/拓扑,开/关本 PR);若代价显著,再评估降低 CQE 粒度的方案。 ### [信息-3] DrainChannels 无 channelsPerRank 钳制:正常路径无越界,属防御风格讨论 - host 侧通道数计算:context.channelsPerRank = 1U,仅当 !hasUbGPeer && rankDim < MOE_CHANNEL_HANDLE_NUM(64) 时取 64 / rankDim(elastic_buffer.cpp:64、elastic_buffer.cpp:1395-1398)。 - host 侧在填充通道前已有显式校验 TORCH_CHECK(context.channelsPerRank <= HCCL_MAX_RANK_SIZE / rankDim)(elastic_buffer.cpp:1400-1402),违反该不变量的 context 无法经正常 host 路径进入内核;DrainChannels 对 hcommHandle[HCCL_MAX_RANK_SIZE=1024] 的最大索引 rankDim*channelsPerRank - 1 < 1024,无越界。 - moe_ep_dispatch.h:326-327 的内核侧钳制属对 device 可见 context 的纵深防御;在 DrainChannels 中加同款"异常时钳制为 1"并不能保证按实际通道布局正确排空(钳制后仅覆盖每 rank 0 号通道),并非明确更优。 结论:无可触发缺陷,仅为防御风格是否对齐的讨论项,不要求修改。 ### [信息-4] destroy() 不检查同组其他实例的延后操作:共享池保留语义下不构成缺陷 - C++ Destroy() 对 MoE 通信 buffer 仅解除本实例引用、不释放物理内存:该 buffer 按 tag 注册进 HCCL 通信域(HcclCommMemReg 无反注册接口),地址被引擎 ctx(含其他 rank 缓存的 epHcclBuffer[])引用,无法销毁;物理内存由进程级共享池按 tag 保留,同 group 重建 ElasticBuffer 时复用(elastic_buffer.cpp:1992-1999,注释明确)。 - 因此实例 A 销毁不会释放实例 B 正在使用的窗口;B 的延后操作所需 event 引用与输入张量均由 B 自身 Python 对象持有。 - A 的 Destroy() 内部 EngramBarrier(true, true) 含全设备同步,对 B 的在途操作仅构成同步等待,无破坏性。 结论:无缺陷,不要求修改。 ### [信息-5] PR 未附带 UT/ST:覆盖缺口 本 PR 无新增 UT/ST;新增公开 API(event 对象、wait 语义、错误路径)与内核协议变更(CQE/drain)中,异常路径与多实例场景无自动化覆盖。 已有实机验证(CQE 正反对照实验、4 卡精度 60/60、24 组 profiling 时序)暂不覆盖上述场景。PR 页 CI 标签为 ci-pipeline-failed,建议复核是否与本补丁相关。 建议补充用例(优先级从高到低):未 wait 即发起下一操作被拦截、wait 后重复调用返回缓存结果、destroy 前未 wait 报错、跨流调用报错、async round-trip 基本功能、同组多实例并发场景。 ## 4. 结论 | 维度 | 评价 | |------|------| | 功能正确性 | 内核协议(末笔 CQE 覆盖、通道全覆盖排空、SQ FIFO 传递)与 Python 状态机(占用登记、失败不可重试、惰性释放、销毁前同步)逐项推演成立 | | 同步路径兼容性 | 行为变更为正确性修复(x 复用隐患),无条件 drain 合理;性能代价待基准量化(中-2) | | API/文档 | 示例与约束描述准确;建议补一句 async 与 do_cpu_sync 的交叉说明(低-1,可选) | | 测试 | 覆盖缺口维持(信息-5):实机验证不覆盖异常路径与多实例场景 | **总体:无阻塞合入的功能缺陷。合入前建议完成默认路径性能对比(中-2)并补齐基本异常路径用例(信息-5);低-1 为可选文档完善;信息-3、4 不构成缺陷,仅作记录。** See merge request: cann/ops-transformer!12114 | 9 天前 | |
fix(mc2): bug修复 Co-authored-by: gitcode_lijd<lijiandong20@huawei.com> # message auto-generated for no-merge-commit merge: !12471 merge fix into master fix(mc2): bug修复 Created-by: gitcode_lijd Commit-by: gitcode_lijd Merged-by: cann-robot Description: 关联Issue https://gitcode.com/cann/ops-transformer/issues/5497 ## 描述 修复深度代理扫描(A5/DV120)发现的 3 处缺陷,经复核均为真实问题(复核过程排除了扫描器对 OP_TILING_CHECK 宏方向的误读风险,详见文末误报说明)。改动均为补齐校验/判空,不改变正常路径行为: **1. tools/bandwidth_test:拷贝长度 uint16 截断(BUG-039,High,可静默触发)** kernel 侧 ProcessToken 将单行 hidden 字节数强转为 DataCopyParams.blockLen(uint16): cpp DataCopyParams xCopyParams = {1U, static_cast<uint16_t>(axisH_ * sizeof(XType)), 0U, 0U}; DataCopyParams hCommuCopyOutParams = {1U, static_cast<uint16_t>(hAlignSize_), 0U, 0U}; tiling 侧对 dataSize 无上限(CheckInputTensorShape 仅查 >0,CheckWinSize 仅约束窗口总量,大单行轻松通过)。fp16 下 **dataSize=32768 → 65536 字节 → 截断为 0**,DataCopyPad 变成零拷贝,**静默产出错误带宽数据**(32768 正是测试常用整数值);该算子无 UT/example 兜底。修复:tiling 阶段拦截单行 32B 对齐后字节数 ≤ 65535。 **2. tools/bandwidth_test:可选属性空指针解引用(BUG-040,Medium)** BandwidthTestTilingFuncImpl 对 OPTIONAL 属性 aiv_num(默认 -1)的 GetAttrPointer 结果直接解引用。aclnn 路径该属性总被显式设置,但图模式调用方未设置时 GetAttrPointer 可返回空指针。仓内惯例即对 OPTIONAL 属性判空(如 combine_setup 的 commAlg、all_gather_matmul_v3 的 hccl_buffer_size)。修复:判空后回退 platformAivNum(与默认值 -1 语义一致),attrs 补充判空。 **3. mc2/common/op_api:epRankSize 越界写防护(BUG-016,Low)** Mc2Context::CreatMc2Context 获取 epRankSize_ 后无上限校验,GetHcclCommResource 按其循环写定长 epHcclBuffer_[HCCL_MAX_RANK_SIZE=1024]。同仓姊妹路径 torch_extension/csrc/comm_context.cpp:494 对同一数据已有 TORCH_CHECK(rankSize <= HCCL_MAX_RANK_SIZE),op_api 路径独缺。修复:补充 epRankSize_ <= HCCL_MAX_RANK_SIZE 校验,与姊妹路径口径对齐(实际可达性受 HCCL 通信域 rank 上限约束,属对齐性防护)。 ## 扫描项 BUG-029/030 核实为误报(不修改代码) 扫描报告认为 combine_setup/teardown(arch35)的 moeExpertNum % (epWorldSize - sharedExpertRankNum) 存在除零风险。核实为**不可达**: - OP_TILING_CHECK 宏语义为"条件为真即报错"(错误条件),现有检查 OP_TILING_CHECK((*sharedExpertRankNumPtr != 0), ..., "0") 的含义是 **sharedExpertRankNum 必须为 0**(非 0 即拒绝),扫描器将其误读为"非零校验"; - 与算子文档 Ascend 950DT 约束一致:"当前不支持共享专家,仅能传入0"(aclnnMoeDistributeCombineSetup.md 约束小节;参数表中 [0, epWorldSize/2] 为通用/目标范围); - UT 佐证:正常用例全部传 0 且期望 GRAPH_SUCCESS,非 0 用例期望 GRAPH_FAILED; - 因此除数恒为 epWorldSize ∈ {2,4,8},永不为 0。 ## 影响面 仅新增入参校验拦截非法配置,合法配置行为不变。 See merge request: cann/ops-transformer!12471 | 9 天前 | |
MC2:NpuArch常量代数解决静态编译依赖 Co-authored-by: chenyifan<chenyifan66@h-partners.com> # message auto-generated for no-merge-commit merge: !11781 merge rr_soc_version into master MC2:NpuArch常量代数解决静态编译依赖 Created-by: mutex_lock Commit-by: chenyifan Merged-by: cann-robot Description: ## 描述 将 mc2 / common 中平台架构判断从 NpuArch::DAV_xxx 枚举取值,统一迁移为 opbase 提供的常量 Ops::Base::DAV_xxx(头文件 op_host/util/op_const_def.h),消除对 platform/soc_spec.h 中枚举定义的静态编译依赖。 主要改动: 1. 升级 opbase 依赖(cmake/third_party/opbase.cmake 中 OPBASE_TAG_ID)。 2. mc2 算子 tiling / op_api / infershape / gen_task,以及 common 公共头(如 tiling_util、tiling_base、tiling_templates_registry、aclnn_platform)中,NpuArch::DAV_xxx 替换为 Ops::Base::DAV_xxx。 3. 相关文件去掉 #include "platform/soc_spec.h",改为 #include "op_host/util/op_const_def.h";op_api 侧仅引入常量定义,避免连带引入 platform_util.h 与 aclnn 日志宏冲突。 4. UT stub(tests/ut/framework_normal/op_api/stub/opdev/platform.h)保留 NpuArch 枚举类型,并同步 stub Ops::Base::DAV_xxx 常量,保证单测可编译运行。 不新增/删除业务接口,仅做 NpuArch 常量代数与 include 收敛。 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/5147 ## 测试 A2/A3/A5 RDV ## 文档更新 ## 类型标签 - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [x] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [x] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [x] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!11781 | 18 天前 | |
提取公共逻辑并清理重复代码 Co-authored-by: lizhenyu<lizhenyu69@huawei.com> # message auto-generated for no-merge-commit merge: !12288 merge cleancode into master 提取公共逻辑并清理重复代码 Created-by: ailealter Commit-by: lizhenyu Merged-by: cann-robot Description: ## 描述 本次修改针对 AllGatherMatmulV2 及相关 MC2 算子中的重复代码进行重构。在不改变原有处理流程和功能行为的前提下,将可复用逻辑提取到 mc2/common。 主要改动如下: 1. 提取 Matmul V2 算子定义公共逻辑,包括动态 AICore 配置和 Scale 数据类型配置。 2. 提取 Matmul 输出数据类型推导逻辑。 3. 提取 AIV 模式公共 tiling 能力,包括: - M/K/N 条件范围匹配; - AIV 平台信息获取; - Matmul Scale 数据类型校验; - HCCL Buffer 大小校验。 4. 提取 AIV Kernel 公共能力,包括: - GM/UB 数据搬运; - AIV/AIC 同步; - Matmul block swizzle 索引计算; - Matmul 输入矩阵 padding 及相关同步处理; - AIV 模式反量化公共处理。 5. AllGatherMatmulV2 保留算子特有的 tiling 策略、转置处理、INT4 尺寸处理和执行流程,通过公共接口复用基础能力。 6. 更新 AllToAllMatmul、MatmulAllToAll 和 MatmulReduceScatterV2 中对应的重复实现,使其调用公共接口。 7. 增加公共 tiling 源文件的 CMake 编译配置。 本次修改以 AllGatherMatmulV2 重复代码整改为主,同时对使用相同基础能力的相关 MC2 算子进行调用侧适配。未修改 experimental 路径及 A5 专用实现。 ## 关联的 Issue [issue5576](https://gitcode.com/cann/ops-transformer/issues/5576) 本次修改用于整改 AllGatherMatmulV2 及相关 MC2 算子的重复代码问题。 ## 测试 - 已完成本地代码格式及基础提交检查。 - A2 RDV 验证通过。 - 已完成 A3 ATK 用例验证; - A5 路径未修改,不在本次验证范围内。 ## 文档更新 本次未修改用户文档和 README,仅进行代码重构、公共逻辑提取及相关调用侧适配。 ## 类型标签 - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [x] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [x] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12288 | 7 天前 | |
提取公共逻辑并清理重复代码 Co-authored-by: lizhenyu<lizhenyu69@huawei.com> # message auto-generated for no-merge-commit merge: !12288 merge cleancode into master 提取公共逻辑并清理重复代码 Created-by: ailealter Commit-by: lizhenyu Merged-by: cann-robot Description: ## 描述 本次修改针对 AllGatherMatmulV2 及相关 MC2 算子中的重复代码进行重构。在不改变原有处理流程和功能行为的前提下,将可复用逻辑提取到 mc2/common。 主要改动如下: 1. 提取 Matmul V2 算子定义公共逻辑,包括动态 AICore 配置和 Scale 数据类型配置。 2. 提取 Matmul 输出数据类型推导逻辑。 3. 提取 AIV 模式公共 tiling 能力,包括: - M/K/N 条件范围匹配; - AIV 平台信息获取; - Matmul Scale 数据类型校验; - HCCL Buffer 大小校验。 4. 提取 AIV Kernel 公共能力,包括: - GM/UB 数据搬运; - AIV/AIC 同步; - Matmul block swizzle 索引计算; - Matmul 输入矩阵 padding 及相关同步处理; - AIV 模式反量化公共处理。 5. AllGatherMatmulV2 保留算子特有的 tiling 策略、转置处理、INT4 尺寸处理和执行流程,通过公共接口复用基础能力。 6. 更新 AllToAllMatmul、MatmulAllToAll 和 MatmulReduceScatterV2 中对应的重复实现,使其调用公共接口。 7. 增加公共 tiling 源文件的 CMake 编译配置。 本次修改以 AllGatherMatmulV2 重复代码整改为主,同时对使用相同基础能力的相关 MC2 算子进行调用侧适配。未修改 experimental 路径及 A5 专用实现。 ## 关联的 Issue [issue5576](https://gitcode.com/cann/ops-transformer/issues/5576) 本次修改用于整改 AllGatherMatmulV2 及相关 MC2 算子的重复代码问题。 ## 测试 - 已完成本地代码格式及基础提交检查。 - A2 RDV 验证通过。 - 已完成 A3 ATK 用例验证; - A5 路径未修改,不在本次验证范围内。 ## 文档更新 本次未修改用户文档和 README,仅进行代码重构、公共逻辑提取及相关调用侧适配。 ## 类型标签 - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [x] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [x] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12288 | 7 天前 | |
feat: mc2 算子 golden 迁移到 transformer 仓 Co-authored-by: qzzzy1<qiziyu2@huawei.com> # message auto-generated for no-merge-commit merge: !10590 merge master into master feat: mc2 算子 golden 迁移到 transformer 仓 Created-by: qzzzy1 Commit-by: qzzzy1 Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!10590 | 1 个月前 | |
engram推理 减少sf热点判断 && 优化分核和buffer深度 Co-authored-by: wuchenhao<wuchenhao6@huawei.com> # message auto-generated for no-merge-commit merge: !12459 merge engram-fetch-wait-local-copy-rebase into master engram推理 减少sf热点判断 && 优化分核和buffer深度 Created-by: wuchenhao123 Commit-by: wuchenhao Merged-by: cann-robot Description: ## 描述 engram推理优化 1.优化核函数分核,提高n buffer深度 2.sf的热点判断改为模板参数 ## 关联的Issue https://gitcode.com/cann/ops-transformer/issues/5569 ## 测试 本地测试 ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [X] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [ ] 🧹 代码清理 - [ ] ❓ 其他,请描述: - [ ] 代码检视报告 项目名称:ops-transformer_backward PR !12459 (engram-fetch-wait-local-copy-rebase) 检视模块:engram_fetch 推理分核优化 + SF 模板化 + buffer 调优(7个文件) 检视人:Turing Team 检视日期:2026-09-21 PR 分支:engram-fetch-wait-local-copy-rebase,3 commits(047ae5a54 / 75e67d854 / ce88522db) 检视范围 mc2/engram_fetch/op_kernel/engram_fetch_utils.h Kernel/公共 cpp-secure.md, cpp-general.md mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h Kernel cpp-secure.md, ascendc-api.md mc2/engram_fetch/op_kernel/arch35/engram_fetch_wait_arch35.h Kernel cpp-secure.md mc2/engram_fetch/op_kernel/arch35/engram_fetch.cpp Kernel cpp-secure.md mc2/engram_fetch/op_kernel/engram_fetch_tiling_key.h Kernel - mc2/engram_fetch/op_host/op_tiling/arch35/engram_fetch_tiling.cpp Tiling cpp-secure.md, cpp-general.md mc2/common/torch_extension/elastic_buffer.py Host(Python) python-secure.md 检视概览 统计项 数值 发现问题总数 2 个确认 + 4 个存疑 严重级(CRITICAL) 0 个 中等级(MEDIUM) 1 个(问题2,极端形态) 轻微级(LOW) 1 个(问题1,极端形态) 核心结论:分核逻辑(GetCoreAssignment 重写)除零/越界/溢出推导全部闭合,fetch/wait 两侧通道覆盖配对正确;SF 模板化口径差在当前 host 成对派生合同下无风险。1 个 uint32 窄化防御缺口(极端形态不可达)+ 1 个模板口径差需按建议补防御;4 个存疑项供自主判断。 ================================================================================ 问题详情及修改建议 -------------------------------------------------------------------------------- 问题ID:ISSUE-001 | 严重级别:LOW(极端形态防御缺口)|检查项 MCR-02 假设检验过程 代码段:EngramFetchArch35::Init() 中 tileBytes_ 计算 假设:H0: 该代码段是安全的 证据序号 证据类型 规范ID 证据描述 分值增量 累计自信值 1 规范违反 2.1/2.2 int64 hiddenBytes_ 直接 static_cast<uint32_t> 窄化, +40% 40% >UINT32_MAX 回绕;Ceil(x,32)*32 在 x 接近 UINT32_MAX 时 uint32 乘法回绕 2 上下文防御缺失 2.1 tiling 侧仅校验 hiddenBytes <= INT64_MAX,无 UINT32_MAX 校验 +30% 70% 3 数据流追踪 2.1 hiddenBytes = hiddenDim * bytesPerElem,仅 INT64_MAX 约束 +25% 95% 结论:自信值 95% > 60%,推翻 H0。但触发需单行 hiddenBytes_ >= 4GB(现实 hidden 在 MB 量级,框架/显存不可能支撑),判定为极端形态防御缺口,LOW。 关联规范:cpp-secure.md 2.1 有符号整数运算不溢出 / 2.2 无符号整数运算不回绕;红线3 代码路径:mc2/engram_fetch/op_kernel/arch35/engram_fetch_arch35.h:174 问题类型:整型窄化回绕(极端形态) 问题代码: tileBytes_ = AscendC::Ceil(static_cast<uint32_t>(hiddenBytes_), UB_ALIGN) * UB_ALIGN; 影响:回绕到 0 时 relay 缓冲零容量、LocalCopySlice 每轮 thisLen=0 死循环; 回绕到小值时缓冲容量低估。正常业务形态不受影响。 修改建议 修改前(kernel 侧): tileBytes_ = AscendC::Ceil(static_cast<uint32_t>(hiddenBytes_), UB_ALIGN) * UB_ALIGN; 修改后(推荐在 tiling 侧补校验,engram_fetch_tiling.cpp 的 hiddenBytes 计算处): OP_TILING_CHECK(tilingData.hiddenBytes > static_cast<int64_t>(UINT32_MAX), OP_LOGE(nodeName, "hiddenBytes exceeds uint32 range: %ld", tilingData.hiddenBytes), return ge::GRAPH_FAILED); 修改说明:一行 tiling 校验早失败,覆盖回绕域;kernel 代码不动。与 MC2 专项检视 意见 MCR-02 一致。 -------------------------------------------------------------------------------- 问题ID:ISSUE-002 | 严重级别:MEDIUM(口径差疑点,当前合同下无风险)|检查项 MCR-03 假设检验过程 代码段:SetTilingKey() 的 hasSf 计算 + Process<HasSf> 模板选择 假设:H0: 模板选择与运行时状态一致 证据序号 证据类型 规范ID 证据描述 分值增量 累计自信值 1 规范违反 4.1 原运行时判断(numSfPacks>0 且双 GM 指针非空)被 tiling +40% 40% 描述符存在性近似替代,OPTIONAL 输入缺席形态依赖框架合同 2 上下文防御缺失 4.1 HAS_SF 模板下 kernel 不再保留 GM 指针判空兜底 +30% 70% 结论:自信值 70% > 60%,推翻 H0(形式上)。但证据有效性校验:host 侧 (elastic_buffer.py/C++)sf_table 与 fetched_sf 由同一 sf 对象成对派生,无 SF 时 传 1-D 空 tensor(torch.empty(0),非 nullptr),GetDimNum()==2 判别稳定; 唯一"2D且dim1>0但零数据"入口是 numTokens==0,kernel 早退。当前合同下不可达, 降级为 MEDIUM 存疑确认项。 关联规范:cpp-secure.md 4.1 外部输入合法性校验 代码路径:mc2/engram_fetch/op_host/op_tiling/arch35/engram_fetch_tiling.cpp:576-580 问题代码: bool hasSf = sfTableDesc != nullptr && sfTableShape != nullptr && fetchedSfDesc != nullptr && fetchedSfShape != nullptr && fetchedSfShape->GetStorageShape().GetDimNum() == DIM_TWO && fetchedSfShape->GetStorageShape().GetDim(1) > 0; 影响:若未来调用方破坏"成对同现同缺"合同(2D shape 但 GM 空),HAS_SF 模板下 GatherSf 解引用空 GM → 核 fault;NO_SF 模板下 fetchedSf 不被搬运。 修改建议 1. aclnn 包装层加成对性校验(elastic_buffer.cpp 的 EngramFetch/EngramFetchTrain): TORCH_CHECK(sfTable.sizes().size() == fetchedSf.sizes().size(), "sfTable and fetchedSf must be provided as a pair"); 2. 补三类形态端到端回归:有SF / 无SF(1-D空tensor) / 空shape 3. 回复 reviewer:当前 host 成对派生合同 + 1-D 空 tensor 判别,判定逻辑无需修改 ================================================================================ 存疑项(供自主判断) -------------------------------------------------------------------------------- 存疑-1 | fp8 无 SF 组合被禁用的兼容性 代码路径:mc2/common/torch_extension/elastic_buffer.py:799-809 问题代码: if sf is not None: ... storage dtype must be float8_e4m3fn/float8_e5m2 when sf is provided ... else: ... storage dtype must be bfloat16/float16/float32 when sf is not provided ... 描述:本次改动将 dtype 集合按有无 sf 分叉,语义上合理(SF 仅配 FP8 量化), 但为破坏性变更:存量调用方若使用 fp8 storage 不带 sf(kernel 本身支持纯字节 拷贝),升级后会被拦截。需业务确认是否存在该用法;若存在需放开 else 分支 包含 fp8 类型。 -------------------------------------------------------------------------------- 存疑-2 | fetch/wait blockDim 一致性是 drain 通道覆盖的隐含约束 代码路径:engram_fetch_arch35.h / engram_fetch_wait_arch35.h 的 GetCoreAssignment 调用 描述:fetch 侧用通道 [0, usedChannelPerRank),wait 侧 drain 同集合;两侧 usedChannelPerRank = (totalBlocks-1)/(numRanks-1) 依赖各自 GetBlockNum()。 当前两侧 tiling 均 SetBlockDim(GetCoreNumAiv()) → 一致成立。若未来任一侧 blockDim 调整导致不等 → wait 漏 drain 通道 → URMA 读永不完成 → drain 超时。 建议:在两侧 tiling 或文档中固化"fetch/wait blockDim 必须一致"的约束注释。 -------------------------------------------------------------------------------- 存疑-3 | GatherSf 的 UB->GM DataCopyPad 参数结构体(既有代码,非本PR引入) 代码路径:engram_fetch_arch35.h:487-488 问题代码: AscendC::DataCopyExtParams sfCopyOut{1U, sfBytes, 0U, 0U, 0U}; AscendC::DataCopyPad(sfDstGm, sfTmp, sfCopyOut); 描述:UB->GM 方向按 ascendc-api.md API-10 应使用 DataCopyParams(blockLen 字节), 同文件 LocalCopySlice(510行) 用 DataCopyParams{1, u16(thisLen), 0, 0}。GatherSf 用 DataCopyExtParams(5字段)传 UB->GM 方向。该代码为既有实现(非本PR引入), 编译可过说明重载存在,但与 API-10 推荐形态不一致,且与同文件正确用法不统一。 曾疑似与 SF 推理 drain 超时相关(已回退修复,原因待查)。建议查阅 ascendc-docs 确认 UB->GM 的 ExtParams 重载语义后统一写法。 -------------------------------------------------------------------------------- 存疑-4 | GetCoreAssignment 函数自身无 totalBlocks>=numRanks 前提守卫 代码路径:engram_fetch_utils.h:73-92 问题代码: uint32_t usedChannelPerRank = (totalBlocks - 1U) / (numRanks - 1U); 描述:当 totalBlocks < numRanks 时商为 0,后续 aivId / usedChannelPerRank 除零。 当前 3 个调用点(ScatterByRank/FetchByRank/wait Process)均有 totalBlocks >= numRanks_ 守卫,按 cpp-secure.md 2.3 Kernel 侧排除规则 (__aicore__ 函数参数由调用者保证)判 PASS。但函数语义新增了隐含前提 (旧实现任意输入安全),建议加 ascendc_assert(totalBlocks >= numRanks) 自文档化。 ================================================================================ 合规项确认 检查项 规范 结果 说明 除零保护 红线1 PASS GetCoreAssignment: numRanks<=1 早退 + 商>=1 推导; 调用点 totalBlocks>=numRanks 守卫 数组越界 红线2 PASS hcommHandle[assignedRank*CPR+idxInRank]: idxInRank<usedChannel<=CPR, assignedRank<numRanks 溢出/回绕 红线3 ISSUE-001(极端形态)+ 问题1 指针判空 红线4 PASS sfTableDesc/Shape/FetchedSfDesc/Shape 全判空 变量初始化 红线5 PASS tileBytes_{TILE_BYTES_INFER_MAX} 类内初始化 资源匹配 红线6 PASS AllocTensor/FreeTensor、MakeBatchHandle/Commit 配对 UB 容量预算 API-3 PASS usedUb 含 tileBytes*6;indicesBatch 按 21B/索引 预留 6 个 scatter 缓冲,数学自洽 uint16_t 截断 1.1 PASS mte3 blockLen u16(thisLen<=24KB)、u16(sfBytes<=2KB) 均 <65535 switch/LOG API 11.x PASS OP_LOGD %lu/%d 与实参类型匹配 TQueBind 深度 API-6 PASS RELAY_BUFFER_NUM_INFER=6 配对使用,144KB 预算安全 模板组合 - PASS 2 mode x 2 hasSf = 4 变体,tiling_key 声明/选择一致 fallback 分支配对 - PASS ScatterByRank/FetchByRank/wait fallback 的 ownerRank 步进与 rankOffsets 读写配对一致 报告生成时间:2026-09-21 报告状态:已完成检视;2 个问题 + 4 个存疑项待处理决策 See merge request: cann/ops-transformer!12459 | 7 天前 | |
clean code: ffn_to_attention 和 attention_to_ffn 算子clean code Co-authored-by: lsh<linshuohao@huawei.com> # message auto-generated for no-merge-commit merge: !12645 merge fix/clean-code-attention_to_ffn into master clean code: ffn_to_attention 和 attention_to_ffn 算子clean code Created-by: github_33317658 Commit-by: lsh Merged-by: cann-robot Description: ## 描述 <!--在这里详细描述你的改动,包括改动的原因和所采取的方法。--> clean code: fix attention_to_ffn , fnn_to_attention 超大函数和重复函数 ## 关联的Issue <!-- 如果这个PR是为了解决特定的Issue,请在这里提供Issue链接。例如:关联Issue #000--> <!-- 如果这个PR是为了解决特定的问题单,请在这里描述问题单单号。--> ## 测试 <!--描述进行了哪些测试来验证你的改动。包括但不限于二级冒烟、算子泛化等。--> https://gitcode.com/github_33317658/mc2_test 测试工程中测试  ## 文档更新 <!--如果这个PR包含文档的更新,请在这里指出。例如:更新了README.md文件。--> ## 类型标签 <!-- [x] 表示选中 --> - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [ ] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [x] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12645 | 6 天前 | |
提取公共逻辑并清理重复代码 Co-authored-by: lizhenyu<lizhenyu69@huawei.com> # message auto-generated for no-merge-commit merge: !12288 merge cleancode into master 提取公共逻辑并清理重复代码 Created-by: ailealter Commit-by: lizhenyu Merged-by: cann-robot Description: ## 描述 本次修改针对 AllGatherMatmulV2 及相关 MC2 算子中的重复代码进行重构。在不改变原有处理流程和功能行为的前提下,将可复用逻辑提取到 mc2/common。 主要改动如下: 1. 提取 Matmul V2 算子定义公共逻辑,包括动态 AICore 配置和 Scale 数据类型配置。 2. 提取 Matmul 输出数据类型推导逻辑。 3. 提取 AIV 模式公共 tiling 能力,包括: - M/K/N 条件范围匹配; - AIV 平台信息获取; - Matmul Scale 数据类型校验; - HCCL Buffer 大小校验。 4. 提取 AIV Kernel 公共能力,包括: - GM/UB 数据搬运; - AIV/AIC 同步; - Matmul block swizzle 索引计算; - Matmul 输入矩阵 padding 及相关同步处理; - AIV 模式反量化公共处理。 5. AllGatherMatmulV2 保留算子特有的 tiling 策略、转置处理、INT4 尺寸处理和执行流程,通过公共接口复用基础能力。 6. 更新 AllToAllMatmul、MatmulAllToAll 和 MatmulReduceScatterV2 中对应的重复实现,使其调用公共接口。 7. 增加公共 tiling 源文件的 CMake 编译配置。 本次修改以 AllGatherMatmulV2 重复代码整改为主,同时对使用相同基础能力的相关 MC2 算子进行调用侧适配。未修改 experimental 路径及 A5 专用实现。 ## 关联的 Issue [issue5576](https://gitcode.com/cann/ops-transformer/issues/5576) 本次修改用于整改 AllGatherMatmulV2 及相关 MC2 算子的重复代码问题。 ## 测试 - 已完成本地代码格式及基础提交检查。 - A2 RDV 验证通过。 - 已完成 A3 ATK 用例验证; - A5 路径未修改,不在本次验证范围内。 ## 文档更新 本次未修改用户文档和 README,仅进行代码重构、公共逻辑提取及相关调用侧适配。 ## 类型标签 - [ ] 🐛 Bug修复 - [ ] ✨ 新特性 - [ ] ⚡ 性能优化 - [x] ♻️ 重构 - [ ] 🧪 测试 - [ ] 📦 构建/CI - [ ] 🔧 配置变更 - [ ] 📝 文档更新 - [ ] ⬆️ 依赖升级 - [ ] 🔒 安全修复 - [x] 🧹 代码清理 - [ ] ❓ 其他,请描述: See merge request: cann/ops-transformer!12288 | 7 天前 |