Merged
fullmeshv2 flag轮询与搬出优化 #15481
fullmeshv2 flag轮询与搬出优化 #15481
Merged
zhong-zixinAdd on 9 days ago
zhong-zixinCollaborators
9 days ago

描述

  • 批量搬入 A5 fullmesh_v2 接收 flag 并生成位图,复用片段就绪判断,减少逐片段检查与重复判定
  • 将多个已就绪片段的 payload 集中搬入后统一等待,通过双缓冲衔接输出,减少逐片段搬运同步;串行和非串行接收路径共用此实现

串行专家计数同时改为连续块搬运,保留 Scalar 消费所需的 MTE2_S,删除无 Vector 消费者的 MTE2_V。

关联的Issue

关联 Issue #7275

测试

本地验证、二级冒烟

文档更新

不涉及

类型标签


以下为 2026-11-07 独立源码检视报告。源码链接已绑定固定提交,报告引用的辅助检查记录仅保留文件名,未作为附件发布。

fullmeshv2_ready_batch 独立源码检视报告

检视日期:2026-11-07。

结论:完整差异中未发现已证实的新增功能缺陷,也未发现新增风格违反。 在文档支持的 Ascend 950 / DAV_3510 普通与串行路径中,批量就绪判断、数据搬入/搬出、双缓冲复用及最终清理的依赖链能够闭合;新的 UB 布局可由容量和对齐公式证明。此结论来自源码、API 实现和数学检查,不是编译或设备验收结论。

实际部署 SDK 的 CompareScalar 实现、保留 UB 编译选项及硬件行为尚未验证,详见后文。

1. 版本、范围与证据

项目 冻结值
Worktree /tmp/ops-fullmesh-ready-batch-rebase-20261106
分支 fullmeshv2_ready_batch
HEAD 2e66dd201b80abaaee0b08398620a450d8f619e5
基线 e66f7133131527427832bffd6be296087ed8c8cd
完整差异 1 个 Kernel 头文件,157 行新增、99 行删除
差异文件 mc2/moe_distribute_dispatch_v2/op_kernel/arch35/moe_distribute_dispatch_v2_a5_full_mesh.h
可读 API 实现 /home/zerozill/.openclaw/projects/asc-devkit,版本 672a659aa82d72c4b843a21d714e73fa28e143ed

检视覆盖完整 Git diff,并追踪 Host 约束、公共量化与通信实现、公开 API V2/V3/V4 到内部 Kernel 的调用关系。同步脚本对 HEAD 和基线各扫描 13 个相关文件。工作树检查为干净,git diff --check 通过。

以下简称用于精确定位,行号均为上述 HEAD:

简称 源码
K A5 full mesh Kernel
H Host tiling
Q 公共量化实现
D 可读 asc-devkit 实现

主要改动是:批量收集 flag 并生成位图,按位图搬入多个已就绪片段,再统一搬出;将原逐片段接收函数拆成 LoadDataFlags、CheckDataArriveWithFlag、LoadReadyData、CopyOut;减少接收工作区;串行计数搬运改为等价连续块,并删除无 Vector 消费者的同步。

2. 发现分类

分类 数量/结论
已证实的新增功能缺陷 0
已证实的新增风格违反 0
既有风格项 2 处同行声明多个变量,P3,不影响功能
未完成的运行验证 实际 SDK/编译选项、设备精度、并发与性能,见第 8 节

71 条适用功能/通用条款与 19 条风格条款的结果见 条款汇总(clause_report.md)。其中 PASS 仅表示本次差异未违反相应条款,包含内容筛查后的不适用分支;不能解读为整个仓库通过完整产品验收。

2.1 既有风格项

P3,已证实,非新增。 K:2294 的 uint32_t srcExpertId, dstPosition, copyCnt; 来自基线的五变量声明,本次仅删去两个变量;K:2191 的两个 GlobalTensor<float> 同行声明从原接收函数保留。均不符合“一行声明一个变量”的风格规则,可在后续整理时拆开。未发现由本次拆分产生的死函数、只写不读字段或重复完整计算链。

3. 流水同步与 buffer 生命周期

令 b=blockCntPerToken_,P=480b 为一个 token 的紧凑 payload 字节数。每批最多处理 64 个源片段;未就绪片段保留其 UB 槽位。

数据/资源 Producer → Consumer/复用者 同步与依据 判定
flagRecvTensor_ MTE2 收 flag → V 比较 K:2106 → 2116 MTE2_V → 2118 CompareScalar RAW 闭合
flagReadyTensor_ V 比较 → S 读位图 K:2122 V_S → 2140 GetValue RAW 闭合
下一批 flag 工作区 前批比较读写 → 下批覆盖 V_S 等待 V 的读写完成;其后 Scalar 读取/控制流再发起下一批 DMA/比较 未见 flag 工作区循环复用缺边
ping/pong payload 上次 MTE3 输出读取 → 新 MTE2 覆盖 K:2164–2167,先消费同 ID 的 MTE3_V,再 V_MTE2 Set/Wait WAR 闭合
本批 payload 全部已就绪 MTE2 搬入 → MTE3 输出 K:2324–2325 一次 MTE2_MTE3;之后 K:2337 CopyOut RAW 闭合
可选 expertScales 暂存 token/scales/索引 MTE3 读取 → MTE2 写权重 → MTE3 输出权重 K:2224–2228 MTE3_MTE2、MTE2_MTE3 复用前后均有完成依赖
两个 payload buffer 最后一次使用 最后 MTE3 输出 → V 清理工作区 K:2348 发布 MTE3_V,K:2353–2356 drain;K:2263 才 Duplicate 清理不会提前覆盖
清零 flag 数据 V Duplicate → MTE3 清 GM flag K:2264 V_MTE3 → 2280 DataCopy RAW 闭合
串行专家计数 MTE2 计数搬入 → S 累加 → MTE3 写输出 K:2518 MTE2_S;K:2536 S_MTE3 删除的 MTE2_V 无对应 V 消费者

GetValue 与 LocalTensor::operator() 的此处访问属于 Scalar。V_S 不能代替 MTE3 完成,因此 payload 复用和结束清理分别保留了明确的 MTE3 完成依赖。固定事件 ID 为 0/1;事件资源按方向区分,接收循环内的 SyncFunc<MTE2_V/V_S> 不与持有中的 MTE3_V release 冲突。发送阶段的事件已在其尾部排空后进入接收阶段。

设实际成功接收批次数为 B:

  • MTE3_V 发布次数为 B。
  • 第三批起复用等待次数为 max(B−2,0)。
  • 退出 drain 次数为 min(B,2),两项之和恰为 B。
  • 没有就绪片段的轮询既不消费 release,也不增加 copyBatchId;首次等待只发生在即将搬入第一个已就绪片段时。

因此“1 处 Set、2 处 Wait”这一静态调用点计数不是事件不平衡的证据。未见新增跨核同步或通信协议发布顺序的变化。

4. UB 容量、对齐与 Host 配置

4.1 新布局的通用证明

K:2295–2309 取 T=tBufRealSize_、m=floor(T/(993b))、F=bm:

区域 字节数 起始偏移
ping 480F 0
pong 480F 480F
ready 位图 align32(F) 960F
收到的 flag 32F 960F+align32(F)

总量为 992F+align32(F)=align32(993F)。当 T 为 32B 对齐且非负时,由 993F≤T 得总量 ≤T。所有区域起点均 32B 对齐,GetWithOffset 的 size 已按对应元素大小换算。该证明不依赖 token 恰好填满 64/128/256B,也不依赖固定 AIV 核数。

布局不越界与 m>0 是两个条件,后者分别沿非串行和串行入口证明如下。

4.2 普通 Host 域与非串行路径

Host 校验包括 2≤P_ep≤1024(H:608–628)、专家数 E≤2048(H:751–780)、S<P_ep、L=E/(P_ep−S)>0 且 P_ep×L≤4096(H:977–993)、1024≤H≤8192(H:1093–1096)、每源最多 512 token(H:940–960、1003)。还需满足其 dtype、量化、输出 shape、窗口及其他 UB 检查;这些范围并非可以任意笛卡尔积组合。

K:2373–2421 在 Reset 后只分配本阶段对象。令 C=aivUsedCumSum_≤8,s=sendNum_≤4096。无需假定典型 56/64 核,即可保守放大:

  • 前缀区 ≤align32(4×(s+8))≤16416B。
  • 三个 expert 元数据区合计 ≤3×16384=49152B。
  • scalar 与两个状态区合计 ≤32+2×8×32=544B。
  • 核 0 额外计数区 ≤align32(4×2048)+align32(8×2048)=24576B。

所以 T≥U−64−90688=U−90752。对 950 资料中的每 AIV 可用 U=253952B,有 T≥163200B,不存在减法下溢。

类型可达性不能只按全局注册表判断:op_host/moe_distribute_dispatch_v2_def.cpp:100/123 的 INT32 列属于 A6 配置,默认注册第 166/184 行也包含 INT32;但 A5 的 op_host/op_tiling/arch35/moe_distribute_dispatch_v2_tiling_arch35.cpp:1255–1279 查询 moe_distribute_dispatch_tiling_helper.h:72–95 的 QUANT_MODE_MAP,其中没有 INT32 输出,查无即拒绝。另一 tiling 入口第 379–390、1036–1038 行检查同一表;两个 arch35 Kernel 入口的 dtype 分支也均未实例化 INT32。因此该注册列不属于本次 A5 full mesh 的有效配置,以下 2H 上界有对应的 Host 可达性限制。详细证据见 dtype 适用域核对(dtype_scope.md)。

Q:63–117 与 K:477–486 给出 token 打包尺寸。对支持类型,输出至多 2H 字节,输入附带 scale 至多 4H;其余 per-token/per-group/MX 对齐及元数据也受 6H+64 的放大界覆盖。因此 b≤ceil((6×8192+64)/480)=103,单 token 原始预算 993b≤102279B<T。即使再放大为输出与 scale 各 4H,得到 b≤137,仍有 993b≤136041B<T。故该路径 m≥1。

平台值来自 Host 的 GetCoreMemSize(UB)(H:2531–2535);上述 248KiB 数值由架构资料支持,未读取本次设备返回值。对其他平台描述,应重新代入 U,不能把证明变成代码中的硬编码容量。

4.3 串行路径

串行选择条件为 axisMaxBS≤32、原始 EP 小于 16、且非 scaling-down(K:417–418)。BufferInitSerial 在 K:2427–2441 保留既有固定区,再形成剩余接收区。

H:1973–2018 的 CheckSerialReceiveUbSizeA5 按实际平台 UB,累加固定区、保留区及至少一 token 的旧接收需求,超过预算则拒绝。旧需求包含 960b+align256(4b)+32b;新需求为 960b+align32(b)+32b,前者不小于后者。Host 固定区计算对共享专家路径也使用保守状态数。因此既有 Host 检查仍足以保证新路径至少容纳一 token。

4.4 其他边界

在上述合法域内,F=bm≤floor(253952/993)=255。因此新 flag/payload DMA 的 blockCount=b×copyCnt≤255,输出 copyCnt≤255,均未接近 uint16 窄化边界或普通 DataCopy 的 4095 上限。串行计数连续块的 statusNum≤4096,放在 uint16 blockLen 中合法。

最大累计 token 数受 4096×512=2097152 约束,三元组元素偏移不超过 6291456。一个来源段内 finish×hCommuSize 的保守上界为 512×103×512=27000832。大窗口 section 及 expandX 总偏移使用 64 位计算。与此次改动相关的窄化、位移及乘法未发现溢出条件。

5. 位图 API、尾部与有效位

K:2116–2122 调用的是带 mask/repeat 参数的 CompareScalar 重载,前置 SetMaskCount、随后 SetMaskNorm;不能套用另一个 count 重载要求 count 字节数为 256B 整倍数的限制。

可读 DAV_3510 实现 kernel_operator_vec_cmp_impl.h:478 在 CounterMode 中按 ceil(mask/64) 迭代,使用 UpdateMask<float> 和带 mask 的 LoadAlign<DATA_BLOCK_COPY>。对应 API 说明全无效的 32B 块不读取。这里 mask 为 N×8 个 float,恰好覆盖 N 个完整 32B flag 块,尾部不会无条件多读一个 256B 向量。

比较将 8 个 float 的判断压成 1 字节。实现按每轮 8B 写位图,尾部实际存储量 8ceil(N/8)≤align32(F);Scalar 的最后一次 uint64 读取也落在该预留区内。K:2130–2145 用 0x0101010101010101 只检查每个 flag 块首 float 的比较位;尾字通过 flagNum 和 offset 限制,未把无效高位参与就绪判断。

片段 mask 的移位范围为 0..63,字节检查移位范围为 0..56。没有移位 64 位、误读尾部位或把 flag 的其他七个 float 当成协议必要条件的情况。

上述结论绑定可读 D 版本。实际部署头文件及 --cce-disable-asc-reserved-ubuf 等编译选项未确认,不能从可读兼容实现推断所有 SDK 组合都可编译。

6. 数据搬运、索引与输出语义

6.1 三轮片段遍历的一致性

LoadDataFlags、LoadReadyData、输出循环均以同一片段范围、同一 min(left,m−tokenNum) 递进。未就绪片段仍累计 tokenNum,后面的已就绪片段使用原槽位;left 为零的片段三处都跳过。最多 64 个片段包括中间零项,位索引使用 index−beginIndex,没有把位图序号与非零片段序号混用。

源 section 都由 GetLocalWindowSrcDataBlockIdx 计算,payload 与 flag 使用相同的 expertFinishNumTensor_×hCommuSize_。目的位置仍为对应源片段的接收前缀加已完成数量,和谁先 ready 无关。每片段输出完成指令提交后才更新 finish/left。入口只将有 token 的片段加入有效表,validNum 为零时调用者退出,不会因最初的全零片段使 finishNum 永远不足。

6.2 DataCopy/DataCopyPad 的单位

  • flag 普通 DataCopy 的 {copyCnt×b,1,15,0} 以 32B 为长度/stride 单位,每次取 32B flag、跨过 480B payload。
  • payload DataCopyPad 的 {copyCnt×b,480,32,0} 中 blockLen 和 GM stride 为字节,每块读 480B、跳过 32B flag,在 UB 紧排。
  • 输出 DataCopyPad 的 UB stride 为 32B 单位,Normal 模式将每个 blockLen 向 32B 取整。

令输出字段有效长度为 L,token 步距为 P=480b。K:2194–2204 使用的 UB 步距为:

32×ceil(L/32)+32×floor((P−L)/32)=P。

该等式覆盖非 32B 对齐的 h、FP4 打包、MX scales、单 float scale 和 12B 三元组。Q:342–373 按量化模式选择字段起始偏移,与此步距一致。没有因尾部向下取整 stride 而逐 token 累积错位。

6.3 可选 expertScales 的覆盖范围

K:2220–2229 每个 4B 专家权重搬入 UB 后占一个 32B 槽,覆盖当前片段开头 32×copyCnt 字节。当前片段长度为 480b×copyCnt,所以覆盖范围始终包含在本片段中,不会破坏后续已预取片段。覆盖前等待本片段 token/scales/索引的 MTE3 读取完成,覆盖后等待 MTE2 完成才输出。下一片段有自己的 UB 起点。

6.4 串行计数与公开接口

K:2514–2518 从 {statusNum,1,0,0} 改成 {1,statusNum,0,0},覆盖的连续字节均为 statusNum×32。后续消费者均为 Scalar GetValue,保留 MTE2_S 足够;数量或前缀和输出逻辑未变。

公开 V2/V3/V4 经共享 base 路由,内部 V3 的 A5 Kernel 也包含本头文件。逐项核对 expandX、dynamicScales、assistInfo、expertTokenNums、epRecvCounts、expandScales 及确定性语义,未发现新输出契约偏差。详细对照及调用位置见 设计与精简性核查(style_design_results/design_notes.md)。A2 设计说明没有用于推断 A5 的 packet 或 UB 约束。

7. 脚本候选与静态检查

同步扫描 HEAD 产生 6 个红线、6 个高等级、25 个性能及 1 个信息候选;基线分别为 6、7、25、1。HEAD 的 12 个红线/高等级候选均有基线同类模式。已逐项区分模板参数、调用点计数、跨迭代配对、分支对称及不同数据区访问,未把脚本候选直接当作缺陷。完整原文与人工判断见 同步候选附录(sync_candidates.md)。

两个版本的图分析器均返回 findings=[];它是正则前端,无法据此证明跨函数、模板和循环回边完整正确。第 3 节的人工数据流追踪是必要补充。

纯 Python 数学检查结果:

检查 规模 结果
UB 分区/对齐/位图尾存储 817408 组,T 为 32..253952 的 32B 步长,b 为 1..103 通过;m>0 另由 Host 证明
64 位就绪字的有效 byte/bit 与尾部 492200 组 通过
三阶段片段区间、空洞与偏移一致性 5000 组确定性随机样本 通过
双缓冲 release/acquire 次数 4096 个成功批次数 通过

结果见 static_math_checks.json,脚本见 static_math_checks.py。另用边界工具检查主要偏移乘法,见 numeric_bounds.txt。这些只验证离散数学模型,不模拟硬件时序,也不是设备测试。

workflow.line_verify.py 处理 90 个 YAML,无 FAIL/SUSPICIOUS 项需要修正;条款拼接已完成。报告中的重点源码位置另与冻结源码核对。

8. 验证局限与后续验收重点

  1. 没有 CANN 编译、模拟器或设备执行。 不能确认实际编译器的重载选择、代码生成、硬件 flag 发布可见性、跨 rank 进展、精度与性能。
  2. 实际 SDK 未核实。 本机可见 CANN 安装路径为失效链接,API 论证绑定上述 asc-devkit 版本;动态 API 日落列表查询因 DNS 失败未取得结果。未据此判定 CompareScalar 已下线,也未宣称实际工具链兼容。
  3. 平台实值未读取。 Host 动态查询 UB/AIV;常规路径证明给出 U 的公式,并代入资料中的 950 248KiB。设备或平台描述若不同,应按真实 U 复核。
  4. 运行时外部契约有前提。 通信 context、expertIds、跨 rank 属性及窗口内容须符合 API 和通信协议;源码检查未覆盖外部数据被破坏的情形。
  5. 源码检查不承诺性能收益。 批处理减少部分同步和比较调用,但就绪分布、片段数、单片段长度与可选 expertScales 会改变实际流水;需要实测才能定量评价。

后续设备验收宜覆盖普通/串行、共享/路由专家、有无 expertScales、各支持量化模式、非对齐 H、最大片段数、64 片段边界、部分就绪和多轮复用,尤其检查尾部地址与并发。此处仅列验收重点,没有声称这些设备用例已执行。

9. 证据索引

  • 完整 diff(full.diff)、扫描清单(scan_manifest.json)、代码概要(code_summary.md)。
  • API 预研与文档定位(api_prestudy.md)、逐条 API 核查(api_clause_results)。
  • 同步原始候选与判定(sync_candidates.md)、HEAD 同步输出(head_sync_audit.json)、基线同步输出(base_sync_audit.json)。
  • HEAD 数据流输出(head_ascendc_flow_analyzer.json)、基线数据流输出(base_ascendc_flow_analyzer.json)。
  • 条款汇总(clause_report.md)、逐条结构化结果(file_j6uok2)、风格及设计对照(style_design_results/design_notes.md)。
  • 检查计划及适用性(review_plan.md)、流程工具记录(workflow_verification.txt)、数学检查结果(static_math_checks.json)。
likedislike
Pull Request has been successfully merged by CANN-robot.
(Thank you for zhong-zixin's contribution.)
Zzhong-zixinCollaborators
9 days ago Created pull request, commit 65a628d6
CANN-robotCANN-robotCollaborators
9 days ago Added label: stat/needs-squash
CANN-robotCANN-robotCollaborators
9 days ago Added label: cann-cla/yes
CANN-robot
CANN-robotCollaborators
9 days ago Comments:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.


PR Approval Progress

✅ Congratulations! All modules have met the lgtm and approve requirements.

Module Approval Details

module lgtm status approve status
mc2 ✅ 刘丹, chenjunjian11 (2/2) ✅ 刘丹 (1/1)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

zhong-zixin, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
CANN-robotCANN-robotCollaborators
9 days ago Set zzg_code,monologue815,zhu-mingzhe71,jiang-lirui,Allan_Yu,yayahello,wang-minbo,tgwsakiko_,liudan12,chenjunjian11,yangzeheng,liuboxi,ryan_li,luobaiqing,mabing1118,dingwei002,macech,chuguowei,huangshuai59,adamlwang as approver
20 event messages are collapsed here。 See more
CANN-robotCANN-robotCollaborators
9 days ago Added label: cann-cla/yes
chen-linxin4Collaborators8 days agoStart code review2
mc2/moe_distribute_dispatch_v2/op_kernel/arch35/moe_distribute_dispatch_v2_a5_full_mesh.h
@@ -2113,0 +2137,4 @@
2137+ uint32_t flagNum = endFlag - beginFlag;
2138+ flagNum = flagNum > flagsPerWord - offset ? flagsPerWord - offset : flagNum;
2139+ uint64_t expected = readyMask >> ((flagsPerWord - flagNum) * BITS_PER_BYTE);
2140+ uint64_t flags = flagReadyTensor_.GetValue(beginFlag / flagsPerWord) >> (offset * BITS_PER_BYTE);
chen-linxin48 days agoComments:

【review】
问题分类:正确性
位置:mc2/moe_distribute_dispatch_v2/op_kernel/arch35/moe_distribute_dispatch_v2_a5_full_mesh.h:2140,代码:uint64_t flags = flagReadyTensor_.GetValue(beginFlag / flagsPerWord) >> (offset * BITS_PER_BYTE);
问题:CompareScalar 按每个浮点元素写入一个字节结果,而 beginFlag 表示 32B 标志块序号;当前索引没有乘以 UB_ALIGN_DATA_COUNT,导致第二个及后续标志块读取的是前一块结果中的填充字节,而不是对应 32B 块的首个比较结果。
可能导致的结果:当一个 token 或一批 token 包含多个 32B 标志块时,即使后续块已经就绪,检查也会读到填充的 0 值并判定未就绪,持续跳过已到达数据,造成输出长期等待或无法完成。
建议的修改方法:按 CompareScalar 结果的实际布局,将 beginFlag/offset 换算为每个 32B 块对应的 UB_ALIGN_DATA_COUNT 个字节(或在生成比较结果时直接压缩为每块一个字节),再按块序号构造 readyMask。

likedislike
zhong-zixinCollaborators
6 days ago Comments:

已核对 Ascend 950 / DAV_3510 的 CompareScalar 实现,这里的结果是每个 float 对应一个 bit,而不是一个 byte。

每个 32B flag 块包含 8 个 float,比较后恰好对应一个 byte:

readyByte[j].bit[r] = (flagRecvTensor_[8*j+r] == 1.0F)

当前调用先进入 Counter 模式,按实际的 tokenNum * blockCntPerToken_ * 8 个 float 比较。DAV_3510 实现每轮比较 64 个 float,StoreUnAlign 将比较结果打包为 8B 并连续推进目的地址,跨轮也没有额外的填充间隔。因此 beginFlag 已经是结果的 byte 下标,GetValue(beginFlag / 8) 配合右移 (beginFlag % 8) * 8 正好取出对应 flag 块;再乘 UB_ALIGN_DATA_COUNT 会导致索引错误。

依据:CompareScalar 的 DAV_3510 实现、StoreUnAlign 的 MaskReg 打包说明、Compares 的按 bit 输出说明。

Cchen-linxin4Collaborators
8 days ago Resolved final issue
chen-linxin4Collaborators8 days agoStart code review2
mc2/moe_distribute_dispatch_v2/op_kernel/arch35/moe_distribute_dispatch_v2_a5_full_mesh.h
@@ -2246,2 +2300,2 @@
2246- return;
2247- }
2300+ uint32_t dataBufferSize = static_cast<uint32_t>(packedTokenSize * maxCopyTokenCnt);
2301+ uint32_t flagReadySize = Ceil(blockCntPerToken_ * maxCopyTokenCnt, UB_ALIGN) * UB_ALIGN;
chen-linxin48 days agoComments:

【review】
问题分类:安全
位置:mc2/moe_distribute_dispatch_v2/op_kernel/arch35/moe_distribute_dispatch_v2_a5_full_mesh.h:2301,代码:uint32_t flagReadySize = Ceil(blockCntPerToken_ * maxCopyTokenCnt, UB_ALIGN) * UB_ALIGN;
问题:maxCopyTokenCnt 的预算在上一行只按每个 token 增加 sizeof(uint8_t),但 flagReadySize 实际会把所有 token 的位图一次性向 UB_ALIGN 向上取整;同时旧实现用于回算 totalBufferSize 并递减 maxCopyTokenCnt 的容量校验已删除。
可能导致的结果:当 blockCntPerToken_ * maxCopyTokenCnt 不是 UB_ALIGN 的整数倍且 TBuf 剩余空间小于补齐量时,flagReadyTensor_ 会与 flagRecvTensor_ 或后续 UB 区域重叠,CompareScalar 写入越过 TBuf 分配范围,触发非法内存访问并破坏同一 kernel 的其他临时数据。
建议的修改方法:按 flagReadySize 的实际向上取整结果计算总占用,并在确定 maxCopyTokenCnt 后验证 2 * dataBufferSize + flagReadySize + flagRecvSize <= tBufRealSize_;若不满足则递减批大小后再初始化各 LocalTensor。

likedislike
zhong-zixinCollaborators
6 days ago Comments:

已核对两条接收入口,tBufRealSize_ 都是 32B 对齐的剩余 UB 预算。这里的位图取整已被总预算覆盖,不会因为最后补齐而越界。

令 T=tBufRealSize_,b=blockCntPerToken_,n=floor(T/(993*b)),M=b*n。两份 payload、接收 flag 和 ready 位图的实际总占用为:

2 * 480M + 32M + align32(M)
= 992M + align32(M)
= align32(993M)
<= T

最后一步成立是因为 993M <= T,且 T 已按 32B 对齐。payload 区和接收 flag 区本身也都按 32B 对齐,各区按实际大小连续分配,不存在所述重叠。

非串行入口从对齐后的 UB 总预算减去各个 32B 对齐区域;串行入口根据 TPipe 分配区域的物理首尾地址计算已用空间,再减去对齐保留区,所以两条入口均满足上述前提。旧实现还包含按 256B 取整的 ReduceSum 工作区,需要额外回算;现在位图仅按 32B 取整,因此不需要恢复递减批大小的循环。

代码位置:接收工作区布局及两条初始化路径。

Cchen-linxin4Collaborators
8 days ago Resolved final issue
Zzhong-zixinCollaborators
6 days ago Modify description of pull request
Zzhong-zixinCollaborators
6 days ago Modify description of pull request
zhong-zixinCollaborators
6 days ago Comments:

compile

likedislike
Zzhong-zixinCollaborators
6 days ago Pre merge succeeded (commit_id: 958447152562b36feb8ecd5109c774eabd6c0d90)
CANN-robot
CANN-robotCollaborators
6 days ago Comments:
🚀 CI 流水线已启动
📋 执行详情: 点击查看流水线
likedislike
CANN-robotCANN-robotCollaborators
6 days ago Added label: ci-pipeline-running
CANN-robotCANN-robotCollaborators
6 days ago Removed label: ci-pipeline-running
CANN-robotCANN-robotCollaborators
6 days ago Added label: ci-pipeline-passed
Zzhong-zixinCollaborators
5 days ago Draft state has been cancelled
chenjianjun11Collaborators
5 days ago Comments:

/lgtm

likedislike
Zzhong-zixinCollaborators
5 days ago Modify description of pull request
liudan12Collaborators
5 days ago Comments:

/lgtm
/approve

likedislike
CANN-robotCANN-robotCollaborators
5 days ago Added label: lgtmapproved
CANN-robotCANN-robotCollaborators
5 days ago Closed associated issue
CANN-robotCANN-robotCollaborators
5 days ago Merged pull request