当前位置: 首页 > news >正文

CANN/cannbot-skills: 进阶通用切分技术

进阶:通用切分(任意 ubSplitAxis / 大 shape / 尾块非对齐)

【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体,本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills

主文档:broadcast_design.md | 参考代码:code/broadcast_common.hComputeTiling

入门样例(broadcast_add)已切换到本文的通用切分。本文解释为什么不能写死ubSplitAxis=0,以及通用切分的完整公式——这是把指导用到真实大 shape(如 cann-bench case 4 int32 8192×8192、case 10 fp16 363×367×373)的关键。

1. 为什么不能写死 ubSplitAxis=0

写死「尾轴整条进 UB、沿 0 轴切」只在尾轴元素数 ≤ elemNum时成立。真实 case 的尾轴常远超 UB:

场景问题
尾轴 rowLen > elemNum(如 8192 fp32)一整行放不进 UB,必须切到尾轴内部
大 shape 无广播(BRC_NONE)同样会尾轴超 UB,需与广播输入一样的多轴切分
高维 shape切分轴可能落在中间某轴,dimProductBeforeUbInner不再等于ubOuter

2. 通用切分算法(ComputeTiling

切分对象是输出 shape。从尾轴向外累乘,找能塞进 UB 的最内切分轴;若连尾轴一行都放不下,则切尾轴本身。

// 1) 选切分轴:从尾轴向外,尽量把内层整轴塞进 UB int splitAxis = 0; int64_t innerBelow = 1; // innerBelow = ∏ outputDims[splitAxis+1 .. rank-1] for (int ax = rank - 1; ax >= 0; ax--) { if (innerBelow * outputDims[ax] > elemNum) { splitAxis = ax; break; } innerBelow *= outputDims[ax]; splitAxis = ax; } // 2) 切分大小 if (innerBelow > elemNum) { // 连一行都放不下 → 切尾轴本身 ubSplitAxis = rank - 1; innerBelow = 1; ubFormer = elemNum; // 每块 elemNum 个元素 } else { ubSplitAxis = splitAxis; ubFormer = elemNum / innerBelow; // 一次放几行 } ubFormer = clamp(ubFormer, 1, outputDims[ubSplitAxis]); ubOuter = ceil(outputDims[ubSplitAxis] / ubFormer); ubTail = outputDims[ubSplitAxis] - (ubOuter - 1) * ubFormer;

关键:dimProductBeforeUbInner通用公式

dimProductBeforeUbInner = (∏ outputDims[0 .. ubSplitAxis-1]) × ubOuter // = UB tile 总数
  • ubSplitAxis = 0:∏(空)=1 → 退化为ubOuter(即入门样例的特例)。
  • ubSplitAxis = rank-1(切尾轴):∏ outputDims[0..rank-2] × ubOuter

这个值喂给GetAxesIndices/GetGmOffsetubSplitAxis≠0 时必须用通用公式,否则下标还原全错。完整实现见ComputeTiling

多核

totalTiles = dimProductBeforeUbInner; blockFormer = ceil(totalTiles / coreNum); // 先按核数算每核最多几个 tile blockNum = ceil(totalTiles / blockFormer); // 再回收用不上的核 blockTail = totalTiles - (blockNum-1)*blockFormer; // ∈[1, blockFormer]

顺序很关键:若先blockNum=min(coreNum,totalTiles)blockFormer=ceil(totalTiles/blockNum),会出现blockTail<0(如 totalTiles=100、coreNum=64 → blockFormer=2、blockTail=-26),非尾核处理越界 tile。必须先定 blockFormer 再回收核。

3. 尾块非 32B 对齐

ubTail = splitDim - (ubOuter-1)*ubFormer往往不是 alignEle 的倍数(如质数 shape、大 shape 展平)。处理方式:

  • 搬运DataCopyPadblockLen字节计,内部自动 pad 到 32B;非对齐尾块直接传真实长度即可,无需手动 mask/padding(DataCopyPadCompact已如此)。
  • 计算Add/Broadcast等矢量指令的count传真实元素数,AscendC 处理非对齐尾数;不要按对齐数多算,否则踩到相邻 tile。
  • 输出DataCopyPad写回同样传真实tile字节,不会越界写。

即:连续布局下尾块非对齐全部由 DataCopyPad 兜底,开发者不需要额外分支。仅当用DataCopy(非 Pad)搬非对齐数据时才需自己 padding。

4. 大 shape 无广播(BRC_NONE)

无广播的大 shape(cann-bench case 4/5/6)和广播输入共用同一套切分ComputeTiling只看输出 shape,与是否广播无关。BRC_NONE 输入在 kernel 走CopyInPlain,其len = rows * inputStrides[ubSplitAxis],因 stride 与输出一致即为tile,天然支持尾轴被切。所以"无广播但 shape 很大"无需特殊处理——切分通用化后自动覆盖。

5. NDDMA 在 ubSplitAxis≠0 的参数装配

MakeNddmaParams/BroadcastNddma已按ubSplitAxis参数化,ubSplitSize语义是「切分轴方向本 tile 的元素/行数」:

  • ubSplitAxis = 0ubSplitSize = rows(行数)。
  • ubSplitAxis = rank-1(切尾轴):ubSplitSize = ubFormer(尾轴一段的元素数),axisInsideUb = NDDMA_DIM-1,只填切分轴一维 + 高位补 1。

axisInsideUb = NDDMA_DIM - (shapeLen - ubSplitAxis):rank 越大、切分轴越靠外,需补的 size=1 高位轴越少。前置条件rank = shapeLen - ubSplitAxis ≤ NDDMA_DIM(5);超过时 Host 选型回退 ③(PickBroadcastMode),官方 atvoss 则走 with-loop NDDMA(本样例未实现)。

6. cann-bench case 对照

caseshape / dtype切分结果(ComputeTiling)
4int32 8192×8192尾轴 8192 > elemNum → 切尾轴(ubSplitAxis=1),ubFormer=elemNum;无广播走 BRC_NONE
7/8/9质数非对齐 shapeubTail 非对齐 → DataCopyPad 自动兜底
10fp16 363×367×373尾轴 373 若 ≤ elemNum 则切中间轴(ubSplitAxis=1),dimProductBeforeUbInner=363×ubOuter

这些 case 现在都能由通用切分覆盖;写死 ubSplitAxis=0 的旧样例会在 case 4/10 上因「一行放不进 UB」失败。

【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体,本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/1195139/

相关文章:

  • usrsctp高级特性:部分可靠性传输与无序交付详解
  • AI百宝箱自动化测试:确保资源抓取准确性的完整测试方案
  • 长沙市雨花区 上门安装、修缮|维小达 开关插座、灯具、洗菜盆、无损家装安装、门窗柜体、锁具卫浴、厨卫五金龙头、踢脚线一站式拆装维修养护服务 - 一点传媒
  • 2026节庆派对用品、气球装饰外贸独立站搭建公司怎么选?八项结构化评估指南,含零代码SAAS、源码定制交付
  • 车载测试培训防坑指南:从CAN总线到Autosar实战技能解析
  • 3个理由选择spotify-downloader:永久保存Spotify音乐的完整指南
  • 武汉家电维修售后质保哪家强:2026年江岸区江汉区对比 - 简单到家
  • MusicFree终极使用指南:重新定义你的移动音乐体验
  • 为什么Mamba-UNet比传统UNet和Transformer更高效?深度解析
  • 小程序毕设项目:基于 SpringBoot + 微信小程序的饮食健康记录分析系统 基于 SpringBoot 的健身饮食助手小程序的设计与实现 (源码+文档,讲解、调试运行,定制等)
  • ChatGPT写论文到底靠不靠谱?实测17所高校查重系统后,我发现了这4个致命陷阱
  • Moonraker:免费开源的3D打印API服务器终极指南
  • 小程序毕设项目: 基于 SpringBoot + 微信小程序的个性化旅游推荐小程序 基于 SpringBoot 的文旅信息展示服务平台的设计与实现(源码+文档,讲解、调试运行,定制等)
  • AI时代英语自学革命:用ChatGPT构建个性化学习闭环(含Prompt工程+纠错反馈+CEFR分级追踪)
  • 深度解析openeuler/peking_university_2021:北京大学2021创新实践课程全记录
  • 如何从0~1持续提升自己的学习力?
  • AM574x VIP接口时序配置实战:从IOSET选择到手动延迟调优
  • STM32 CAN过滤器实战:从单ID过滤到多ID范围接收的配置策略
  • MSP430FR59xx端口复用配置实战:从硬件原理到引脚规划
  • IDR项目终极指南:NeurIPS 2020突破性3D重建技术全解析
  • pyloudnorm部署指南:从开发环境到生产环境的完整配置
  • Spring Boot微服务电商项目实战:从环境搭建到K8s部署
  • 提升Music Flamingo Think-2601-HF性能的3大技巧:Flash Attention 2与Torch Compile加速指南
  • 亨得利中国官方维保网络全解析|最新门店地址及客服电话权威收录(2026年7月最新) - 亨得利中国服务中心
  • R3nzSkin国服换肤神器:三步解锁英雄联盟全皮肤体验
  • 多维聚合的数据操纵本质:空间折叠与动态切片
  • 上海汽车车衣哪家正规 官方资质核验方法及门店推荐 - 信息热点
  • Laravel Options 核心功能详解:option() 助手函数的10种用法
  • 《电驱动桥(Electric Drive Axle)》全解析
  • 汽车级FPD-Link III解串器DS90UH940N-Q1:原理、设计与调试实战