资讯动态

PyPTO-Gym 算子设计文档规范:基于 pypto-pro-op-design 模板的 R0–R8 迭代式方案设计

发布时间:2026/9/20 12:38:49 来源:尧图企业网站定制
人工智能大模型算子库AI 技能/插件【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址https://gitcode.com/cann/pypto-gym点击查看免费下载导读本文是 CANN/pypto-gym 仓库中pypto-pro-op-design技能模板design-template.md的完整技术解读。该模板是 PyPTO-Pro 算子设计中「产出 DESIGN.md」的权威骨架它以 R0–R8 共 9 轮迭代式约束收敛为核心从 Module 划分、API 映射、Tile 规划、片上空间布局到循环/Section 结构、分核策略、跨核同步、尾块处理、目标测试 case 与综合评估最终汇总为一张可供 coder 直接施工的 Tile 数据流全景图。读完本文你将掌握这套模板每一个章节§0–§10的填写规则、与之配套的 SKILL.md 迭代流程以及DESIGN_BINDINGS.json、module_interfaces.yaml等机器可读交付物的合同约束能够独立为任意 PyPTO-Pro 算子产出「结论 推导过程 证据来源」三要素齐全、可直接翻译为 kernel 代码的设计文档。一、模板的定位从 SPEC 到 kernel 的「施工合同」在 PyPTO-Pro 算子开发流程中DESIGN.md位于资料探索EXPLORE_REPORT.md、PRO_MATERIAL_INDEX.md与 kernel 实现pypto-pro-op-develop之间是设计验收通过后的实现合同。模板首页即声明了设计的输入来源基于 SPECcustom/{op}/SPEC.md——公式、shape、dtype、动态轴等算子规格基于 EXPLORE_REPORTcustom/{op}/EXPLORE_REPORT.md——API 映射与约束§3、相似样例§4、教程指导§5、Tile/同步策略建议§6、环境常量快照§7如 UB 容量、event_id 上限、对齐要求。模板开头的Knowledge Bindings一节明确了设计与知识库的绑定方式完整、机器可读的 requirement 清单见DESIGN_BINDINGS.json模板对应物为 design-bindings-template.json而 DESIGN.md 正文只记录 R0–R8 的实际设计决策不复制 Binding 分组或 requirement 表格每条活动 requirement 的planned_location必须准确指向对应决策及最终test_op.py的 file/symbol。模板通过 10 个章节§0–§10对应 9 轮迭代R0–R8其中 R7.5 专管测试 case 规划概览如下章节输出轮次核心问题§0 Module 划分R0计算流拆成几个 Module各自属于哪个 Section§1 API 映射R1每个数学步骤用哪些 API数值安全边界如何§2 Tile 规划R2每个 tile 的 shape/dtype/内存空间/layout/缓冲深度§3 片上空间布局R3tile 落在哪个片上地址容量与对齐是否满足§4 循环与 Section 结构R4Module 如何放入 section循环如何嵌套§5 分核策略R5work item 如何分配到各物理核§6 核间同步R6Cube/Vector 跨执行域依赖如何同步§7 尾块处理R7维度不整除 tile 尺寸时怎么办§8 目标测试 caseR7.5交给 develop 验证的具体 shape 是哪几个§9 综合评估R8整体设计是否准确、可靠、泛化§10 Tile 数据流全景图R8 之后全部数据流的单页全景设计是问题驱动的迭代不是线性填表。SKILL.md 的核心原则强调每个决策必须包含结论 推导过程 证据来源每轮发现的矛盾必须回溯修正前序决策不允许累积到 R8 再处理运行证据推翻设计时须返回design_violation由编排器重新调度设计修订。二、§0 Module 划分R0先数据依赖再 Section 边界2.1 维度契约——所有后续轮次的前提模板要求在设计任何 Module 之前先确认 kernel 的输入/输出维度契约不属于 Module 划分本身按 SPEC 明确 kernel 接收的真实 rank、shape、stride 和输出形态。SPEC 要求支持 1D 或任意多维时必须设计 kernel 内的索引/stride 映射不能让 host 通过 reshape 等张量操作把输入归一化也不能默默只实现 2D。模板以表格形式记录适配规则SPEC 输入 shapekernel 接收kernel 内索引/stride 映射输出形态1D[L]原始[L]直接按 L 索引不做 host reshapeSPEC 要求形态2D[M,N]原始[M,N]按原始 stride/offset 访问SPEC 要求形态2.2 划分依据与 Module 列表Module 是设计文档中对计算流程的逻辑划分不是 PyPTO Pro 的语法结构见 module_partitioning.md。划分分两步第一步按数据依赖确定边界。对于相邻两步 A 和 BB 必须等 A 遍历完完整归约轴或其他完整数据范围、并基于 A 的最终结果开始新的遍历或独立计算阶段时 → 拆成两个 ModuleA 处理完当前 Tile 后 B 能在同一层循环内立即消费且两步属于同一 Section → 通常放同一 ModuleA、B 之间只有少量同域计算没有插入其他 Section 或独立计算阶段 → 可放同一 ModuleB 只是紧接着对 A 的归约结果做汇总或简单处理不需要重新遍历完整数据范围 → 可留在 A 所在的 Module。以稳定 Softmax沿 N 轴分块为例常规实现需要三次完整遍历后两次都依赖前一次得到的最终结果因此按三次遍历划分Module 1 遍历全部 N Tile 求每行m max(x)Module 2 重新遍历求s sum(exp(x - m))Module 3 再遍历写出y exp(x - m) / s。采用 Online Softmax 时可在一次遍历中同时维护m与s通过m_new max(m, tile_max)、s_new s * exp(m - m_new) sum(exp(tile - m_new))更新最终缩减为两个 Module。模板中还强调A 的结果是否需要保存不能单独决定 Module 边界——即使 A、B 可以连续执行若合并后 UB 等片上空间放不下同时存活的数据也必须拆分。第二步按 Section 边界继续拆分。一个 Module 只能属于一个 SectionL1/L0A/L0B/L0C 上的矩阵路径含 GM→L1、L1→L0A/L0B、矩阵乘、L0C 写回归 Cube SectionVecUB上的搬运和向量计算归 Vector Section使用 VF 时外层 Kernel 负责 GM↔UB 搬运pl.vector_function负责 UB↔寄存器交换与寄存器计算pl.quant/pl.dequant走 V 流水归 Vector Sectionpl.move/pl.store对 Acc 结果做随路量化/反量化时走 FIX 流水归 Cube Section。模板特别提醒Scaling只是量化参数使用的片上缓冲区不是独立 Section不能看到MemorySpace.Scaling就新建 Module。2.3 归约轴容量结论与 Module 级数据流模板要求含归约算子时必填「归约轴是否可能超单 tile」若动态轴范围可能跨多个 tile须写明多 Tile 归约方案常规多遍 / 在线统计加输出两遍 / 其他逐遍写明遍历范围、状态和依据单 tile 装得下则写「不涉及」。最后用 ASCII 示意图标注 Module 间的数据流向、中间数据所在空间、传递 API 及 Cube/Vector 之间的同步方式。R0 的机器可读产物是module_interfaces.yamlsingle source of truth包含module_count、is_fusion同时含 cube 和 vec section →true隐含module_count 2、has_cross_core、modules[]id/name/description/section/golden_steps/inputs/outputs/golden_stage_fn、final_outputs与composition_verificationatol/rtol/seeds/shapes。骨架由脚本生成见 gen_module_interfaces.pypython ./scripts/gen_module_interfaces.py custom/op/op_golden_cpu.py \ --spec custom/op/SPEC.md --op op \ --design custom/op/DESIGN.md custom/op/module_interfaces.yaml脚本自动解析 golden 函数签名并填充schema_version/op/primary_inputs/composition_verificationarchitect 负责填写标TODO的判断部分产出后用 validate_module_yaml.py 自验。三、§1 API 映射R1冻结每个 Vector 步骤的唯一实现3.1 数学步骤到 API 调用链API 映射从数学公式出发但公式不能直接决定 Kernel 写法详见 api_mapping_and_tile_planning.md。首先确定每一步由 Cube 还是 Vector 执行再确定 Tile 的 shape、dtype、内存空间与 layout。以稳定 Softmax 为例核心数据依赖为x ── reduce_max(N) ── max │ │ └──────── subtract ── exp ── reduce_sum(N) ── sum │ exp ───────── divide ── outCube 路径受硬件数据通路硬性约束pl.matmul(dst, lhs, rhs)要求lhs位于 LeftL0A、rhs位于 RightL0B、dst位于 AccL0C一次矩阵乘通常展开为GM → Mat(L1) → Left/Right(L0A/L0B) → matmul/matmul_acc → Acc(L0C) → store/move → GM 或 UB。VF 路径则是GM → pl.load → Vec(UB) → vf.load* → Register File → vf.* → vf.store* → Vec(UB) → pl.store → GM。模板要求按$CANNBOT_CONFIG_ROOT/references/performance-constraints.md中的「强制 2Vector 默认使用 VF」为每个 Vector 步骤冻结唯一实现并记录vector_selection字段vector_selection: step: 本 §1 中的哪一步 implementation: vf | tile_op api_sequence: vf.* 或 pl.* API 序列 decision_reason: default_vf | kb_template_required kb_template_evidence: default_vf 写 n/atile_op 写已选 KB 路径、明确要求的原文/片段 target_version: 目标软件/框架版本 applicable_conditions: dtype/shape/layout/算子条件随后按 Module 写出 API 调用序列含每个 API 的来源API 文档路径或 EXPLORE_REPORT §4 定位的官方指定算子。数学公式通常省略搬运与表示转换API 调用链还必须补充GM/L1/L0/UB/寄存器之间的搬运、dtype/layout 转换与归约结果广播、动态尾块使用的set_validshape/VF mask/fillpad、Cube 与 Vector 之间传递中间结果所需的数据通路GM workspace 或move支持的片上通路。3.2 超越函数数值安全边界模板条件性要求仅当 API 链含 exp/log/sqrt/reciprocal/tanh 等超越/非线性函数时填写数值安全边界表例如API输入理论范围目标 dtype 上限是否溢出防护措施expx 无上界x11 时 exp 溢出fp16 ≈ 65504exp(11.09)≈65504 → inf → NaN先减最大值再 exp或归一化省去分母防护措施必须来自算子定义或明确规格不能为了通过测试给普通除法擅自加入epsilon或改变边界语义。模板还强调窄 dtypefp16/bf16下平方、同量级相乘、长轴累加的中间值量级上界分析若超出范围升位宽的vf.astype应落在产生增长的那一步之前而非归约之前。四、§2 Tile 规划R2关键常量、Tile 属性与槽位访问4.1 关键常量定义模板要求列出所有编译期常量coder 必须逐字使用涉及 Cube 的 tile 尺寸须满足 EXPLORE_REPORT §7 记录的对齐要求# ── 算子关键常量coder 必须逐字使用 ── TS {S_tile} # S 方向 tile 尺寸 TD {D_tile} # D 方向 tile 尺寸 TS_HALF {S_half} # subblock 半尺寸 (如有 dual_split) SCALE 1.0 / sqrt({D_logical}) # 缩放因子若算子有 scale 步骤关键注意若某维度实际值固定且小于 tile 尺寸如 D64 对齐到 TD128tile shape 用 TD 声明运行时通过 §7 的set_validshape限制有效区域公式常量如 SCALE必须使用实际维度值而非 tile 尺寸。4.2 Tile 属性表与 TileGroup 槽位访问每个 tile 的 shape 由其所参与的 API 操作数要求决定模板的 Tile 属性表覆盖用途、变量名、shape、dtype、内存空间Vec(UB)/Mat(L1)/Left(L0A)/Right(L0B)/Acc(L0C)、layout、大小、备注。TileGroup 槽位访问表要求记录depth和逐 Tile 的 mutex 配置避免漏掉「单 Tile 多 ID」以及「不配置 mutex 元数据」的情况。运行时下标不会自动取模采用group[i]时必须给出i始终位于[0, depth)的依据。模板还条件性要求填写tile_dimsstride 注意事项仅当使用load_tiletile_dims[d0, d1]覆盖多维度时填写大 stride 可能影响性能。4.3 make_tile_group 与 make_tile 的分工这是两条实现约束之一设计阶段须在 R3 落实所有需要 buffer 切换/轮转的 tile 一律用make_tile_groupauto_mutexmake_tile仅限单次使用 scratch tile写入一次、读取一次不参与轮转不跨循环迭代保留。禁止用make_tile 手动sync_src/sync_dst管理 buffer 轮转。make_tile_group的槽位数由depth确定mutex_ids描述每个 Tile 携带的 mutex ID。参考 api_mapping_and_tile_planning.md 中的配置示例配置对应的 Tile 数每个 Tile 的 mutex IDmutex_ids[0]1Tile 0[0]mutex_ids[0, 1]2Tile 0[0]Tile 1[1]mutex_ids[[0, 1]]1Tile 0[0, 1]单 Tile 多 IDmutex_ids[[0, 2], [1, 3]]2Tile 0[0, 2]Tile 1[1, 3]注意省略depth时必须提供非空mutex_ids框架用其长度推导槽位数mutex_idsNone或[]时无法推导槽位数必须填写depth。TileGroup 的访问方式分为四类next()游标前进一格、current()游标不变、previous()取前一槽位、group[i]不读取也不修改游标。显式下标适合「同一轮同时指明当前槽位和预取槽位」「生产者与消费者按同一slot_idx访问共享缓冲」等场景group[i]与next()混用时两套游标状态要分别推导。五、§3 片上空间布局R3逐空间独立寻址、精确到字节5.1 地址映射表与最高地址上界每个 MemorySpace独立寻址、独立限容——地址各自从0x00000起算同一 addr 在不同空间是不同物理位置L0A/L0B/L0C 同用addr0x0000互不冲突。模板按内存空间分节填写地址映射表地址统一使用半开区间[起始字节, 结束字节)生命周期重叠的 tile 地址不得相交。含 cube/matmul 的算子须补 L1(Mat)/L0A(Left)/L0B(Right)/L0C(Acc) 各节。各空间容量结论须给出百分比{max(结束字节不含)} / {EXPLORE_REPORT §7 对应容量}容量取 §7 探测记录§7 未记录则回退 material-explore 补测不臆测。按照 onchip_memory_layout.md各 MemorySpace 的编译期地址对齐要求为Vec/Mat/ScaleLeft/ScaleRight32BLeft/Right512BAcc64B。TileGroup 使用单个基地址时第i个槽位按slot[i].addr base i × slot_size展开须检查每个base i × slot_size而不是只查base。5.2 地址复用条件与专项检查两个逻辑 Tile 只有同时满足以下条件才能复用地址位于同一 MemorySpace 且区间能容纳完整物理大小生命周期不重叠或同步保证新写入发生在旧数据最后一次读取之后核内跨 Pipe 复用具有正确的 mutex 关系或显式核内同步跨 Cube/Vector 复用具有 R6 定义的 READY/RELEASE 同步。mutex_id是同步元数据不负责分配地址也不检查容量取值范围[0, 31]。R3 还需执行专项检查MX scale 地址按ScaleLeftAddr[i] LeftAddr[i] 4、ScaleRightAddr[i] RightAddr[i] 4计算独立逻辑地址域不从数据空间扣容量对计划并行访问的 Mat Tile 检查 L1 Bank 冲突A5 的 1:2 混合 Kernel 中两个 AIV 各自拥有本地 Vec 地址域UB 分别检查、不能相加比较。六、§4 循环与 Section 结构R4从结果单元确定循环层次6.1 Module 放入 Section 与结果单元R4 依据 loop_design.md 把 §0 确定的 Module 放入具体 Section 代码结构相邻同域 Module 可以顺序写在同一个 Section 中Cube Module 和 Vector Module 分别放入pl.section_cube()和pl.section_vector()两个 Section 共享的 TileGroup 在 Section 之前声明。若 API 数据通路与 §0 记录的 Section 归属冲突回到 R0 修正 Module 划分。确定循环层次的关键是先确定结果单元——循环一次要完成的输出。例如逐元素算子以一个输出 Tile 为结果单元沿 N 轴 Softmax 以一行块为结果单元行内所有 N Tile 属于同一归约Matmul 以[M_tile, N_tile]输出块为结果单元所有 K Tile 共同更新其 Acc 状态。6.2 循环嵌套、动态上界与分核信息模板要求记录Module/Section 对应关系、结果单元、跨 Tile 状态生命周期初始化位置、更新方式、使用位置、Section 结构section_vector/section_cube的数量与顺序、循环相对 Section 的位置、循环嵌套参照样例说明 M-tile/N-tile 关系、动态循环上界如n_tiles (N TILE_N - 1) // TILE_N静态 shape 写固定值及来源、分核信息核编号、核数及获取位置。两种典型循环形式# 扁平任务循环二维输出 Tile 坐标展平成一维任务编号 for task_id in pl.range(core_idx, m_tiles * n_tiles, core_num): m_idx task_id // n_tiles n_idx task_id % n_tiles ... # 行/列两层循环同一行的多个 Tile 共享数据或状态 for m_idx in pl.range(core_idx, m_tiles, core_num): for n_idx in pl.range(0, n_tiles, 1): ...分核信息取决于 Section 所在执行域仅 Cube/仅 Vector 用pl.get_block_idx()/pl.get_block_num()混合 Kernel 的 Vector Section 按全部 AIV 分工时core_num 为pl.get_block_num() * pl.get_subblock_num()pl.get_block_idx()返回展平后的全局 AIV 核编号。模板要求填写「主要参考样例」EXPLORE_REPORT §4 定位的官方指定算子路径、可复用结构点与补充参考official_samples.md 清单。6.3 CV 并行流水设计is_fusiontrue时必填模板指出当前框架提供自动 CV 并行流水功能须读取$PYPTO_DEVKIT_DIR/docs/guide/programming_guide/pro/advanced_programming/auto_parallel_pipeline.md并逐项核对「使用约束」全部满足时推荐自动流水任一不满足时记录具体条款并按 cv_fusion_pipeline.md 采用手动流水。流水结构必须在编排 Stage 3 冻结不得留到 Stage 5 才引入。需填写的内容包括流水实现auto/manual及约束核对结果、自动流水配置stage 函数及顺序、跨核 TileGroup 的fwd_ids/bwd_ids、串行精度验证配置、候选与初始preload、pipeline_generated.py复核位置、流水编号第一阶段每次交给下一阶段的数据范围、task_id递增位置、阶段链、逐交接的 1:2 分工、阶段延迟表、上下文循环缓冲、预加载轮数与缓冲深度、流水启动/稳定运行/末尾剩余阶段、槽位初始可写状态。手动流水的核心是任务错位Cube 和 Vector 在同一轮处理不同编号的任务同一任务内部仍按原有数据依赖顺序执行。四阶段QK(Cube) → P(Vector) → PV(Cube) → GU(Vector)样例的阶段延迟为0/1/2/3采用 3 轮预加载时第 3 轮起进入稳定运行段四个阶段分别处理QK(3)、P(2)、PV(1)、GU(0)最后一个真实任务后 Cube 再运行 2 轮、Vector 再运行 3 轮完成剩余阶段。通用多阶段流水的延迟计算规则为第一阶段delay 0某执行域第一次出现delay 上一阶段 delay 1同一执行域再次出现delay 同执行域上一阶段 delay preload。上下文循环缓冲深度取max_delay 1。七、§5 分核策略R5恰好 1 次 launch 合同R5 的权威依据是$PYPTO_DEVKIT_DIR/docs/guide/programming_guide/pro/development/tile_based_python_programming/multi_core_partitioning_and_Tiling.md。模板要求填写分核方式strided loop——扁平切pl.range(core_id, m_tiles*n_tiles, num_cores)或二维切外range(core_id, m_tiles, num_cores) 内range(0, n_tiles, 1) 选择理由host 侧 block_dim仅 Vector Kernel 使用vector_core_numCube 或混合 Kernel 使用core_numtotal_tasks 0时block_dim min(max_blocks, total_tasks)total_tasks 0时仅允许经目标验证的block_dim1空工作单次启动否则报design_violation禁止block_dim0或跳过启动交付 launch 合同恰好 1 次唯一 kernel{kernel_symbol}由{wrapper_symbol}在 host 循环外调用一次若做不到记录证据并返回failure_category: design_violation不得填写多 launch fallbackTensorList ABI不涉及则 N/A冻结合同中的有限L_MAX及B_MAXL_MAX、每槽有限元素数上限N_MAX对所有DT_INT32派生式的安全性、只生成一组B_MAX个固定槽位、每个 TensorList 形参逐槽展开为独立 Ptr 参数、wrapper 对真实槽位校验和n_i0填充、地址值不进入 tiling 数据A5 CV 的两个 Vector subblock 分工切分轴、各自的索引范围、尾块归属和工作量两个 Vector subblock 的结果依赖无依赖可独立处理存在归约依赖时说明为何不能改切非归约轴、GM 部分结果的 shape 与地址、最终合并者。模板特别强调 TensorList 类算子的per-tensor launch是「最常见也最贵的设计错误」基线是一次融合调用逐 tensor launch 会把融合消除的开销又加回来。八、§6 核间同步R6READY/RELEASE 双向协议与 event_id 分配8.1 cross_core 涉及判定R6 是条件性章节仅当 Cube 与 Vector 之间有数据依赖或存在需要INTER_BLOCK、INTER_SUBBLOCK、UNICAST_BLOCK处理的依赖时填写否则填「不涉及 cross_core」。Section 数量本身不是判断依据。判定流程见 cross_core_synchronization.md消费者读取本次 Kernel 中由另一执行域或另一 Block/subblock 写入的数据时需要 cross-core 同步同执行域内依赖由带非空mutex_ids的 TileGroup 配合auto_mutex管理未配置时手工插入核内同步sync_src/sync_dstVF 函数内局部读写顺序用vf.mem_bar配置matmul phase时 M 与 FIX 之间由unit_flag配对。8.2 同步点、事件表与 event_id模板的同步点表按数据方向和物理槽位记录就绪/释放事件READY为生产者→消费者set 在最后一次写后、wait 在第一次读前RELEASE为消费者→生产者set 在最后一次读后、wait 在下一次覆盖前。pipe表示执行 set/wait 的硬件流水不表示 Section 名称取值由同步点紧邻的数据操作决定Cube 将 Acc 写入 GM workspace、Vector 再从 GM 加载到 UB 时用FIX → MTE2Cube 将 Acc 搬到 Vec 后由 Vector 计算时用FIX → VVector 通过 MTE3 写入 Mat、Cube 再搬入 L0 时用MTE3 → MTE1。event_id 分配表要求取值范围[0, 16)动态表达式的全部运行时取值也必须在范围内一对 set 和 wait 必须使用相同的 ID 与sync_mode前一个信号由配对 wait 消费后 ID 才可以复用。sync_mode语义AIC 与两个 AIV 子核协同用INTRA_BLOCK两个 AIV 子核之间用INTER_SUBBLOCK跨物理 block 用INTER_BLOCK只与一个 AIV 子核同步用UNICAST_BLOCK。event_id与mutex_id是两套独立机制数值相同不会自动建立联系也不能相互替代。手动同步的设计关系模板要求引用slot_idx task_idx % depth、tile shared_group[slot_idx]、READY READY_IDS[slot_idx]、RELEASE RELEASE_IDS[slot_idx]。循环复用缓冲时Vector 在主循环前为每个空槽位预发 RELEASE 事件表示初始可写每轮 Cube 写完后 set READY、Vector 读完后 set RELEASE、Cube 下一次覆盖前 wait RELEASE。模板还要求检查事件配对每个 wait 必须对应同一方向、同一槽位、同一轮次的 set所有执行路径都必须保证配对 set 最终执行等待关系不能形成环覆盖零次、一次、整除和尾块迭代中的事件配对。九、§7 尾块处理R7物理 shape 固定、有效 shape 随块变化R7 的权威依据是$PYPTO_DEVKIT_DIR/docs/guide/programming_guide/pro/development/tile_based_python_programming/tail_block_handling.md核心模型是Tile 的物理 shape 固定有效 shape 随当前块变化。模板要求填入以下代码# ceiling division 计算 tile 数必须向上取整用 N//TILE 直接整除会漏掉尾块 m_tile_num (M TS - 1) // TS n_tile_num (N TD - 1) // TD # 循环内计算尾块有效尺寸并告知硬件set_validshape 有状态每轮都要重设 valid_m pl.min(M - m_off, TS) # 满 tile TS, 尾块 余数 valid_n pl.min(N - n_off, TD) pl.set_validshape(tile_a, [valid_m, valid_n]) # 运行时告知硬件还需填写compactNone/1/2按数据通路和 API 约束说明依据普通 Vec ND 尾块通常不需要无效区域是否会被读取否 → 不填充是 → 按计算语义选择pad并执行fillpad矩阵尾块是否填充由具体数据路径和 API 约束决定。注意fillpad当前只支持 Vec Tile不能用于 Mat/Left/Right 操作数。十、§8 目标测试 caseR7.5基于 tile 切分的具体 shapeR7.5 要求基于 R2 tile 尺寸与 R7 尾块方案确定具体测试 shapedevelop 直接实现这些 case不再自行重算。若 SPEC/用户已有目标 case 在其基础上追加无用户指定 case 时直接确定不询问用户。至少 4 个基础 case单轴算子按例外处理并说明原因case 名具体 shape覆盖场景design 适配确认test_{op}_aligned[TILE_A, TILE_B]全整除✅ / 不适配→回溯轮次test_{op}_tail[TILE_A 尾块余数, TILE_B]单轴尾块✅ / ...test_{op}_tail2d[TILE_A 尾块余数, TILE_B - 尾块余数]双轴尾块✅ / ...test_{op}_multitile[2~3 × TILE_A 尾块余数, TILE_B - 尾块余数]跨多 tile 尾块最小规模勿放大✅ / ...关键原则逐个验证 design 可适配若某 case 适配不了必须回溯对应轮次具体解决尾块缺陷回 R7、循环边界错误回 R4、归约轴超单 tile 回 R0不得反过来删改 case 迁就 design若算子凑不出 4 个有区分度的 case以覆盖到的边界类别为准不为凑数量制造冗余用例。十一、§9 综合评估R8三张检查表 迭代规则R8 综合评估从三个维度对 R0–R7 的全部输出做交叉验证orchestrator 以评估表中无 ❌ 作为设计通过判据准确性检查API 调用链完整覆盖数学公式§4 已参照官方样例确定循环与 Section 结构含样例路径与结构说明数据依赖正确Module 顺序 sync 点dtype 精度满足要求如 FP32 matmul 累加归约类 API 的[M,1]/[1,N]输出已设layoutAcc tile 物理 M×N×dtype_bytes ≥ fractalFP32 ≥ 1024 bytes动态轴含极小维度时尤需检查。泛化性检查目标测试 case≥4已按 tile 切分确定具体 shape 且逐个验证尾块处理正确ceiling division set_validshape归约轴超单 tile 时已给出覆盖完整归约轴的方案循环边界正确超越函数在 dtype 范围内无溢出跨 tile 状态初始化/持久化正确cross_core 同步方案正确。一致性检查R0–R7 输出无矛盾所有决策有证据支撑R3 片上地址范围与逐空间容量检查通过tile_dims使用时已关注大 stride 影响条件性检查若 §6 填「不涉及 cross_core」则确认不存在 Cube↔Vector 或跨 Block/subblock 的数据依赖。迭代规则来自 SKILL.md发现问题数 ≤ 3修复后重新走 R8问题数 3回到问题最早出现的轮次重新过后续轮最多 5 次完整 R0–R8 迭代。评估结论记录「整体通过/需修改」「限制条件」如不支持尾块、需 M 整除完整 M-tile 尺寸等与「修改记录」修改内容、轮次、原因。十二、§10 Tile 数据流全景图给 coder 的施工合同R8 通过后将 R0–R7 各轮产出串联为一张完整的 tile 级数据流图标注每一块 tile 的流向从哪里读取、经过哪些操作转换、写入哪里。模板给出了绘图骨架{按实际算子的 tile 流向绘制} GM ─[load_tile]→ tile_a ─→ {操作} → {输出tile} → ... ↓ {操作}({输出tile}, {持久化tile}) ↓ {持久化tile} → tile_a → {操作} → ... → tile_out ↓ GM ←[store_tile]─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘图例约定[load_tile]为 MTE2 搬运GM → UB[store_tile]为 MTE3 搬运UB → GM→为 V 流水线操作并标注 API 名---表示数据跨 Module 持久化tile 在不同 Module 间不被覆盖├─表示同一 Module 内分支同一数据被多次使用。验证规则全景图中每一块 tile 和每一个操作都必须能在 R3 的地址映射表、R1 的 API 序列中找到对应条目缺失或矛盾则回溯修正。SKILL.md 明确Tile 数据流图是给 coder 的施工合同——coder 拿到 DESIGN.md 应能确定 kernel 的完整结构与关键决策API 签名等细节以 API 文档原文为准确认EXPLORE_REPORT 仅为派生的先行速查不作签名权威。十三、配套交付物与强制规则13.1 DESIGN_BINDINGS.json 结构合同除了 DESIGN.md设计阶段还产出custom/op/DESIGN_BINDINGS.json。按 design-bindings-template.json 与 SKILL.md 的合同根对象含schema_version整数1与bindings数组Binding 含class_id、selection_field只能是optional_patterns或required_constraints、reference、selection_reason、requirements非空数组requirement 含req_id、kind、source_anchors、status、class_evidence、invariant、planned_location、verification_method。kind status只允许precondition met、obligation applies、obligation not_triggered、validation_scope applies四种组合其中obligation applies是活动项每个 Binding 至少一条其invariant与planned_location为非空字符串。DESIGN.md 只链接 JSON不复制 Binding 表。13.2 wrapper 边界强制规则模板中的「Wrapper 边界外操作」必须填写空。按照 SKILL.md 与 wrapper-boundary.mdcast、slice、transpose、pad、concat 以及任何数据形状/dtype 处理必须放进pl.jitkernel 内部wrapper 只做参数校验、读取 KB 约束列明的只读元数据、纯 Python 整数推导、torch.empty分配输出和一次 kernel 启动。模板给出反面样例——一次 kernel 启动外面包了四个被计时的 device 算子.to(torch.float32)、movedim().contiguous()等kernel 被写成只接受「规范化的 FP32 连续 2-D 输入」于是 host 被迫去生产它「这份便利按全价计费」。设计阶段必须kernel 接口按真实输入定义原始 dtype、原始 layout、原始 rank需要的轴变换用 stride/offset 索引在 tile 循环里表达不用movedim/permute/contiguousdtype 转换在 tile load/store 时用pl.casttile 级或vf.astype寄存器级完成不在 host 上.to()整个张量没有vf.cast这个 API尾块用pl.set_validshape不在 host 上 pad 到 tile 整数倍。注意方向wrapper 也不得承担算子的算术实现验收的 anti-cheat 会判 FAIL要求是「形状/dtype 处理进 kernel」不是「计算搬到 host」。十四、总结与使用建议design-template.md作为 PyPTO-Pro 算子设计的权威模板其价值在于把「可执行的 kernel 方案」强制拆解为 10 个可独立验证、可交叉回溯的设计决策章节R0 定 Module 边界与维度契约R1 冻结 API 链与数值边界R2 定 tile 规格与缓冲深度R3 落到精确到字节的片上地址R4 组织循环与 SectionR5 定分核与单次 launch 合同R6 设计跨核 READY/RELEASE 协议R7 处理尾块R7.5 冻结测试 caseR8 用三张检查表做验收最后以 §10 全景图作为 coder 的施工合同。配合 SKILL.md 的迭代流程、references 目录下的六份专题设计指南module_partitioning.md、api_mapping_and_tile_planning.md、onchip_memory_layout.md、loop_design.md、cross_core_synchronization.md、cv_fusion_pipeline.md以及gen_module_interfaces.py、validate_module_yaml.py、test_module_contract.py等校验脚本这套模板构成了从 SPEC 到 kernel 的完整设计证据链。实际使用时建议进入 R0 前先读取performance-constraints.md落实两条实现约束每个决策优先参考 EXPLORE_REPORT §4 定位的官方指定算子复用成熟模式拥有最高优先级严格遵循「结论 推导过程 证据来源」三要素任何无法落到代码的决策都应标记为待回溯项直到 R8 评估表全绿。赞分享人工智能大模型算子库AI 技能/插件【免费下载链接】pypto-gymPyPTO-Gym 是基于 PyPTO 编程框架构建的算子与模型样例仓库项目地址https://gitcode.com/cann/pypto-gym点击查看免费下载相关推荐PyPTO-Gym 算子设计 R0 阶段Module 划分方法论与实战指南PyPTO Gym 算子设计 R0 阶段Module 划分方法论与实战指南 Module 划分是 PyPTO Pro 算子 tile 级方案设计pypto人工智能大模型算子库AI 技能/插件pypto-gym 中的 SK-14 通用多矩阵乘骨架PyPTO 多 MatMul 算子设计的兜底范式pypto gym 中的 SK 14 通用多矩阵乘骨架PyPTO 多 MatMul 算子设计的兜底范式 SK 14General Multi MatMul人工智能大模型算子库AI 技能/插件PyPTO-Gym 深度编排 Stage 5 性能优化子代理pypto-pro-op-optimizer 的边界、执行与交接规范PyPTO Gym 深度编排 Stage 5 性能优化子代理pypto pro op optimizer 的边界、执行与交接规范 本文围绕 CANN / Py人工智能大模型算子库AI 技能/插件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价