ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PyPTO-Gym 长轴 Scan/Cumulative 与超 UB 规约的分块进位(Block + Carry)调试实战

PyPTO-Gym 长轴 Scan/Cumulative 与超 UB 规约的分块进位(Block + Carry)调试实战 PyPTO-Gym 长轴 Scan/Cumulative 与超 UB 规约的分块进位Block Carry调试实战【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym本文是 PyPTO-Gym 仓库中pypto-general-debug技能包调试文档《Large-axis scan / cumulative UB-exceeding reduction》scan-and-reduction.md对应 DEBUG_GUIDEBOOK.md §9.21的展开版。它面向在 Ascend NPU 上基于 PyPTO 编写融合算子的开发者解决一个高频致命问题当pypto.cumsum/pypto.cumprod等原生 scan/cumulative 算子沿长轴执行、或某个原生规约算子的单算子 UB 占用超出预算时编译期报F40005UB 溢出而逐元素循环的错误修复又会导致宿主崩溃或超时。读完本文你将掌握分块扫描轴 跨块进位Block-the-axis carry这一标准修复范式如何根据 UB 预算选择块长T、如何在pypto.loop中组织带跨块依赖的循环、为什么T是 view 形状而非 vec tile 尺寸以及该模式在 pypto-kernel-design-format.md §9c 中的规范地位。何时打开本文症状与适用边界本文对应的调试入口在 scan-and-reduction.md它是pypto-general-debug技能包的路由索引 DEBUG_GUIDEBOOK.md 中的§9.21节。技能包要求遇到卡死或不透明失败时先通过DEBUG_GUIDEBOOK.md的 Quick map: situation → leaf file 表路由到唯一的叶子文件再只读该文件§9.21 对应的路由触发条件有两条在 scan/cumulative 或长轴规约上出现F40005UB 分配超限或正打算对某个轴逐元素做 scan正准备写pypto.cumsum/pypto.cumprod对长轴做 scan。该模式的适用范围有明确边界原文给出如下Scope适用原生 scan/cumulative 算子pypto.cumsum、pypto.cumprod、cumsum_reverse、masked_cumsum等沿长轴执行或原生规约算子的单算子 UB 占用超过预算不适用算子本身能放进 UB 预算的场景——此时不需要引入分块进位机制直接对整轴调用原生算子即可。症状从编译期 F40005 到运行期崩溃编译期UB 分配失败当对整条长轴一次性应用原生 scan 算子时编译阶段直接报 UB 分配失败ErrCode F40005! TENSOR_MEMORY_ALLOCATION. Alloc tensor size [256000] exceeds MEM_UB size [196608]!错误信息中的256000是申请的张量字节数196608是 MEM_UB 可用字节数192 KB。同类故障也可能表现为L0A/L0B/L0C/L1 size exceeded、tile 对齐失败或 tile shape 未设置此时应转向 tile-shapes.md 处理。运行期宿主崩溃、挂死或超时如果开发者用逐元素循环绕开编译错误见下文反模式编译虽然通过但运行期会出现SLAB_ADD_CACHE_FAILED → segfault / process killed或者运行永不结束——例如 4 小时 benchmark 超时、缺失产物文件。根因原生 scan 的工作区随轴长线性增长工作区 ≈ 轴长 × 64 字节原生 scan 算子的内部工作区workspace与轴长成正比。以pypto.cumsum为例约64 字节/轴元素≈ 16× FP32用于并行树形扫描的各级中间结果因此4000 长的轴需要约 256 KB 内部工作区 192 KB UB 预算UB 硬上限 ≈3072 个 FP32 元素192 KB ÷ 4 字节对整轴一次性应用算子 → 编译期必然失败F40005。反模式逐元素循环的任务爆炸pypto.view([1, 1])逐位置循环在数值上正确但会产生axis_len × batch个任务——例如 4000 × 128 ≈512K 个任务直接耗尽宿主侧调度资源表现为SLAB_ADD_CACHE_FAILED 段错误或长时间超时。这与 pypto-kernel-design-format.md §9c 记录的 BAD #2 反模式完全一致。修复范式分块扫描轴 跨块进位核心思路把长轴切分为长度为T的块使得算子逐块的 UB 占用落在预算内cumsum 取T1000时约 64 KB 192 KB。然后只对少数块做循环用pypto.view切出真实的[.., T]块在块上应用原生算子把运行累加器running accumulator跨块传递。标准实现原文核心代码# ✅ block the scan axis; native op per block; carry across blocks def _op_kernel_impl(x, out): # x, out: [B, D] (D large, e.g. 4000) B x.shape[0] # SymbolicScalar (dynamic batch) D 4000; T 1000; NB D // T # T fits per-block UB; NB small (4) for b in pypto.loop(B, namebatch): carry pypto.full([1, 1], 0.0, pypto.DT_FP32) # running accumulator # block loop carries a cross-block dependency - submit_before_loopTrue (only NB iters) for t in pypto.loop(NB, nameblock, unroll_list[1], submit_before_loopTrue): blk pypto.view(x, [1, T], [b, t * T]) # real [1, T] block (NOT [1,1]) scan pypto.cumsum(blk, dim1) # native op on the block scan[:] scan carry # fold in running carry ([1,1]-[1,T]) pypto.assemble(scan, [b, t * T], out) carry[:] pypto.view(scan, [1, 1], [0, T - 1]) # block tail new running total逐行解读代码行作用关键点B x.shape[0]动态 batch 维返回SymbolicScalar运行期才解析的实际批量D 4000; T 1000; NB D // T分块参数块长T必须满足逐块 UB 预算NB只有 4循环次数少carry pypto.full([1, 1], 0.0, pypto.DT_FP32)运行累加器每个 batch 行独立初始化跨块复用pypto.loop(NB, ..., submit_before_loopTrue)块循环存在跨块依赖必须submit_before_loopTrueunroll_list[1]保持循环不被展开pypto.view(x, [1, T], [b, t * T])切真实块是真正的[1, T]块不是[1, 1]标量pypto.cumsum(blk, dim1)块上原生算子逐块 UB 已在预算内scan[:] scan carry折叠进位[1,1]广播到[1,T]pypto.assemble(scan, [b, t * T], out)写回输出view 形状与 offsets 维度匹配carry[:] pypto.view(scan, [1, 1], [0, T - 1])更新进位块尾元素 新的运行累计和两个必须绕开的反模式# ❌ BAD #1 — native op on the whole axis at once → UB OOM (F40005: 256000 196608) scan pypto.cumsum(x, dim1) # 4000-long workspace blows the UB budget # ❌ BAD #2 — element-by-element loop over the large axis → task explosion / host crash / timeout for j in pypto.loop(D, submit_before_loopTrue): # D4000 iters × B ~512K tasks x_col pypto.view(x, [1, 1], [b, j]) # one scalar per iter (SLAB_ADD_CACHE_FAILED segfault)BAD #1 直接对 4000 长轴调用pypto.cumsum(x, dim1)工作区 256 KB 撑爆 192 KB UB编译报F40005BAD #2 把循环数推到 512K 级宿主调度资源耗尽。块长 T 的选取原则选取能整除轴长的最大T且逐块 UB 在预算内cumsum FP32 场景T ≲ 3000即 UB 硬上限 3072 个 FP32 元素的约 97% 以内常用取值 1000 / 800 / 500原文示例用T1000单块约 64 KB留足余量。关键澄清块长 T ≠ vec tile 尺寸这是最容易踩坑的认知误区。原文明确强调T是 view 形状不是 vec tile。上述核心里程碑代码在set_vec_tile_shapes(16, 16)这样的小 vec tile 下也能通过编译——正确性来自分块结构而非 tile 取值不要把 tile 尺寸与T耦合不要改动正常的 vec tile 规则每轴[16, 64]、rank 匹配、单算子 UB 适配。详见 tile-shapes.md。这与 pypto-kernel-design-format.md §9c 的结语一致这是一个 loop/view 结构规则独立于 vec-tile 尺寸。源码级佐证从调试叶子到规范与设计原则调试叶子文件在技能包中的定位scan-and-reduction.md 是pypto-general-debug技能包SKILL.md的聚焦叶子文件之一。技能包要求按DEBUG_GUIDEBOOK.md的路由表只读匹配的叶子避免一次性加载整个 playbook。§9.21 在 Quick map: situation → leaf file 表中明确指向本文件。规范级实现骨架分块进位模式在算子开发技能包中拥有规范地位pypto-kernel-design-format.md §9c Blocked scan / cumulative (carry) pattern — for UB-exceeding scan/reduction only 完整收录了同样的好/坏示例并给出两条配套约束JIT 图内唯一允许的循环是pypto.looplint 规则 OL57S0 级块分解等结构性循环必须用pypto.loop且迭代间存在依赖时加submit_before_loopTruePythonfor/while会在构图期展开迭代破坏框架的 tiling/并行并膨胀编译时间批维在宿主侧折叠§9b把前导 batch 维折叠成 2D让核心算子保持低秩避免高维 matmul 的 tiling 复杂度。设计层原则pypto-op-design/SKILL.md §3.0 的第 4 条数据流原则逐块处理 跨块进位是本文模式的设计级依据与 dataflow.md 中的分页、共享存储和尾块约束互相呼应。知识库中的相关实现pypto-pro-op-kb 提供了两个相关视角vec-scan-prefix-dependent.md向量单元上实现前缀依赖扫描的完整指南运行极值扫描、累积 min/max/sum、torch.cummin等。文中明确指出pypto 没有 scan 原语、也没有寄存器到寄存器的 lane shufflevf.shift_left/right是位运算而非 lane 移动cumsum_matmul_impl.py在 plPyPTO-Pro无 scan 算子的前提下把 cumsum 改写为x UU 为上三角全 1 矩阵的 cube 算子实现覆盖 FP32[8192, 128]。值得注意的是这种三角矩阵改写只对组合子cumsum成立——cumprod需要 log 域改写且要求元素严格为正logcumsumexp根本不是 matmul。实战检查清单判断是否命中原生 scan/规约沿长轴执行、单算子 UB 超预算、或正打算逐元素扫描 → 使用本文模式否则直接整轴调用。选T整除轴长的最大块长逐块 UB 192 KBcumsum FP32 取T ≲ 3000常用 1000/800/500。组织循环batch 维pypto.loop(B)块循环pypto.loop(NB, unroll_list[1], submit_before_loopTrue)跨块依赖必须加 submit 标志。切块要真实pypto.view(x, [1, T], [b, t*T])必须是[1, T]严禁退回[1, 1]逐元素。进位传播块尾view(scan, [1, 1], [0, T-1])写入carry下一块先scan carry再写回。不要动 vec tileT与 tile 尺寸解耦沿用[16, 64]每轴、rank 匹配、单算子 UB 适配的正常规则。禁止 Python 循环JIT 图内只用pypto.loopOL57结构性块分解同样遵守。参考与延伸阅读调试入口 scan-and-reduction.md§9.21与路由索引 DEBUG_GUIDEBOOK.md规范骨架 pypto-kernel-design-format.md §9c设计原则 pypto-op-design/SKILL.md §3.0 与 dataflow.md配套知识 vec-scan-prefix-dependent.md向量单元扫描、cumsum_matmul_impl.pymatmul 改写 cumsum相关调试 tile-shapes.md、pypto-view.md、error-codes.md【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址: https://gitcode.com/cann/pypto-gym创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表