尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
CANN 昇腾设备端 Tiling 实战:AI CPU Tiling 下沉样例 aicpu_device_tiling 最短路径解析
CANN 昇腾设备端 Tiling 实战AI CPU Tiling 下沉样例 aicpu_device_tiling 最短路径解析【免费下载链接】cann-samplesCANN高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samplesaicpu_device_tiling是 CANN 开源仓库 cann-samples 里演示Tiling 下沉的最小完整样例设备侧的 AI CPU 算子负责计算 tiling把结果写进设备内存AI Core 算子再从同一块内存读取 tiling 并分派模板执行 computeHost 只做下发编排。跑通它你手里就多了一套跨核任务编排的可复用骨架——双 stream event 保序、DataStoreBarrier保证可见性、tiling 值驱动 AI Core 模板分派。先给结论设备端 tiling 相对传统做法改动的是谁算、结果走哪条路而不是算法本身。维度传统 Host 端 tiling设备端 Tiling 下沉本样例tiling 在哪算Host CPU设备侧 AI CPUaicpu_tiling.aicputiling 结果路径Host 算完 → 回传 → 随 kernel 再次下发直接写入设备内存AI Core 原地读取Host–Device 交互多次往返tiling 与 compute 被 Host 强串行一次传参与数据设备侧自主编排tiling → computeHost 负担tiling 逻辑复杂时 Host CPU 反而成瓶颈Host 退化为纯编排者支持环境一张表对清硬件、CANN 版本与架构参数结论先行这个样例只能在三类硬件上跑且CMAKE_ASC_ARCHITECTURES必须与硬件对得上选错架构参数是构建失败的第一大原因。硬件产品CANN 最低版本编译架构参数CMAKE_ASC_ARCHITECTURESAtlas A2 训练/推理系列、Atlas A3 训练/推理系列 CANN 9.0.0dav-2201默认值Ascend 950PR / Ascend 950DT CANN 9.1.0dav-3510该参数经 CMakeLists.txt 里的--npu-arch${CMAKE_ASC_ARCHITECTURES}透传给 ASC 编译器编译出的 kernel 与硬件不匹配时构建或运行阶段就会直接失败。动手前先确认自己机器上的卡属于哪一档这是后面一切的前提。最短路径从配置环境变量到看到 5 行日志结论先行样例没有第三方依赖选对架构参数后几分钟内就能看到完整输出。以下在Samples/0_Introduction/04_aicpu/00_device_tiling/aicpu_device_tiling/目录下执行source ${install_path}/cann/set_env.sh # ${install_path} 为 CANN 安装目录默认 /usr/local/Ascend mkdir -p build cd build cmake -DCMAKE_ASC_ARCHITECTURESdav-2201 .. # 950 系列请改用 dav-3510 make -j ./demo运行./demo后预期输出恰好 5 行MyAicpuKernel inited MyAicpuKernel inited type 1 mode 2 len 4 end! Hello World: int mode 2 len 4 m 10. Hello World: int mode 2 len 4 m 10. Hello World: int mode 2 len 4 m 10.日志与代码分支逐行对账第 1 行MyAicpuKernel入口打印AI CPU 内核开始执行第 2 行type1, mode2, len4写入完成、且已越过DataStoreBarrier()tiling 结果对 AI Core 可见第 3~5 行AI Core 侧命中type1 mode2 len4分支执行hello_world_implint, 2, 4其中m 10正是 Host 端用aclrtMemset填充为 10 再经aclrtMemcpyH2D 拷贝的输入值同一行打 3 次是因为内核声明了__mix__(1, 2)1 个 Cube 2 个 Vector 执行单元各自执行一次打印。看到这 5 行AI CPU 写 → AI Core 读闭环即已成立。如果只出现前 2 行而后 3 行缺失同步或下发环节断了直接按第 4 节踩坑清单逐条排查。机制白盒拆解按数据流顺序走 5 个环节这一节不按文件读代码而是沿参数包组装 → 跨流同步 → AI CPU 写 tiling → 屏障可见 → AI Core 读 tiling 分派的链路逐环拆每环看三样东西关键代码、为什么必须这样设计、缺了会怎样。Host 端先立契约再组装 KernelArgs 参数包kernel_args.h是两个内核共同 include 的布局契约TilingInfo是 tiling 的计算产物KernelArgs是携带数据指针与 tiling 指针的参数包namespace KernelInfo { struct TilingInfo { int8_t type; int8_t mode; int8_t len; }; struct KernelArgs { uint32_t* xDevice; uint32_t* yDevice; uint32_t* zDevice; TilingInfo* ti; // 与 aicore 共享用于 tiling 选择同步 }; }接着 main.asc 分配内存并组装参数包错误码检查已省略void* zDevice; void* ti; void* zHost; aclrtMalloc((void**)zDevice, 4096, ACL_MEM_MALLOC_HUGE_FIRST); aclrtMalloc((void**)ti, 4096, ACL_MEM_MALLOC_HUGE_FIRST); aclrtMallocHost((void**)zHost, 4096); aclrtMemset((void*)ti, 4096, 0, 4096); aclrtMemset((void*)zHost, 4096, 10, 4096); aclrtMemcpy(zDevice, 4096, zHost, 4096, ACL_MEMCPY_HOST_TO_DEVICE); struct KernelInfo::KernelArgs args {0}; args.xDevice (uint32_t*)zDevice; args.yDevice args.xDevice 1; args.zDevice args.yDevice 1; args.ti (KernelInfo::TilingInfo*)ti;为什么必须这样设计ti就是 tiling 结果的交接区——AI CPU 写它、AI Core 读它而ti的下发前清零保证读取方拿到的永远是确定值args整包同时作为 AI CPU 内核的入参保证两核指向同一段设备内存。缺了会怎样不对ti清零一旦 AI CPU 内核因任何原因没跑到写入语句AI Core 读到的是未初始化随机值——可能命中错误模板分支也可能两个分支都不命中而静默空跑。这类问题比崩溃难定位得多。双 stream event给两个内核排上先后关键代码event此前已用aclrtCreateEventExWithFlag(event, ACL_EVENT_SYNC)创建MyAicpuKernel1, 0, aicpu_stream(args); aclrtRecordEvent(event, aicpu_stream); aclrtStreamWaitEvent(aicore_stream, event); hello_world_do(1, aicore_stream, (uint8_t*)zDevice, (uint8_t*)ti);为什么必须这样设计两个内核跑在两条互相独立的 stream 上stream 之间天然没有顺序只有aclrtRecordEvent在 aicpu_stream 上标记tiling 任务完成、再由aclrtStreamWaitEvent让 aicore_stream 阻塞等待该 event才锁死先写完 tiling后启动 AI Core。另外注意...内核调用符对__aicpu__与__aicore__两种内核是同一套下发语法第三参指定 stream这正是跨核编排的语法基础。缺了会怎样删掉这两行 event 代码两条 stream 并行竞争AI Core 完全可能在 tiling 写入前执行读到全 0 的ti、一个分支都不命中——现象就是日志只剩 AI CPU 的 2 行这是乱序最典型的症状。AI CPU 端写入 tiling再用屏障刷可见性aicpu_tiling.aicpu 的内核体全部代码__global__ __aicpu__ uint32_t MyAicpuKernel(KernelInfo::KernelArgs args) { AscendC::printf(MyAicpuKernel inited\n); args.ti-type 1; args.ti-mode 2; args.ti-len 4; AscendC::DataStoreBarrier(); AscendC::printf(MyAicpuKernel inited type %u mode %u len %u end!\n, args.ti-type, args.ti-mode, args.ti-len); return 0; }为什么必须这样设计__global__ __aicpu__声明入口运行在 AI CPU 上与 AI Core 内核的__global__ __aicore__对称这里 type/mode/len 取三个常量替身真实的分块求解结果写完之后AscendC::DataStoreBarrier()这道内存屏障是把写入刷给后续读取方AI Core 算子的显式动作也是设备端 tiling 正确性的关键一环。缺了会怎样不挂屏障写入可能尚未对读取方生效AI Core 就会读到旧值脏值。现象是时好时坏有时 Hello World 打了错误的变体、有时干脆不打偶发问题绝大多数都出在可见性上。AI Core 端运行时读 tiling按值分派模板aicore_kernel.asc 的分派主体template typename T, int8_t mode, int8_t len __mix__(1, 2) __global__ __aicore__ void hello_world(__gm__ uint8_t* m, __gm__ uint8_t* TilingPtr) { __gm__ struct KernelInfo::TilingInfo* ti (__gm__ struct KernelInfo::TilingInfo*)TilingPtr; if (ti-type 0 ti-mode 1 ti-len 2) { hello_world_implfloat, 1, 2(m); } else if (ti-type 1 ti-mode 2 ti-len 4) { hello_world_implint, 2, 4(m); } }入口处把TilingPtr强转为__gm__ TilingInfo*从设备内存读出 AI CPU 写入的 type/mode/len——Tiling 下沉的消费端到此闭环。内层hello_world_impl用if constexpr (std::is_same_vT, ...)在编译期裁掉无关类型分支运行时只做廉价的 tiling 比较外层包装hello_world_do内部执行hello_worldint, 10, 201, 0, stream(m, ti)模板参数是编译期常量tiling 值是运行期变量二者靠分支比较绑定到具体 kernel 变体。为什么必须这样设计这就是tiling 决定 kernel 变体的最小范式——一次下发同一份 kernel 二进制运行时按 tiling 值选择变体编译期裁剪保证未命中分支零开销。缺了会怎样只要共享头文件双端布局出现任何偏差见踩坑 5这里的读取必然错位且分支不命中不报错、只是静默空跑问题在编译期完全无感知。踩坑清单5 个高频坑按现象 → 根因 → 修复过一遍⚠️架构参数与硬件不匹配现象cmake/make 阶段直接构建失败或产物无法在该卡上运行根因CMAKE_ASC_ARCHITECTURES未按硬件选择A2/A3 用dav-2201950 系列用dav-3510修复编译前核对硬件型号显式传入对应参数不要依赖默认值。⚠️漏掉内存屏障AI Core 读到脏值现象偶发读到全 0 或旧值Hello World 不打或打错变体根因AI CPU 写完 tiling 后没有AscendC::DataStoreBarrier()写入未对读取方生效修复tiling 写入之后、内核返回之前必须挂屏障当作写操作的一部分而不是可选优化。⚠️漏掉 stream 依赖执行乱序现象日志只有 AI CPU 的 2 行AI Core 无输出根因删除或未建aclrtRecordEventaclrtStreamWaitEvent两条 stream 并行竞争修复恢复 event 依赖链让 aicore_stream 在 tiling 写入完成后才启动内核。实验性编译选项的兼容性风险现象当前 toolkit 上编译正常更换 CANN 版本后构建失败根因--cce-aicpu-launch-with-interfaceAI CPU 接口式 launch在 CMakeLists.txt 中明确标注为实验性选项未来兼容性与支持性不作保证修复把它当作版本敏感开关对待升级 CANN 后先跑通本样例再动其他工程。共享头文件双端不同步现象双端都编译通过运行时 AI Core 读到的 tiling 值必然错位根因kernel_args.h是唯一的内存布局契约只改了.aicpu或.asc一侧的字段理解修复结构体字段或顺序的任何变更都在同一头文件里做提交时确认 AI CPU、AI Core、Host 三个使用方同时生效。从样例到真实算子把常量 tiling 换成真实分块求解这个样例的骨架可以直接当模板用替换真实 tiling 时按下面四处动刀aicpu_tiling.aicpu把type/mode/len 1/2/4换成真实求解逻辑——基于输入 shape、UB 容量等算出 block 数与 tile 大小后写入ti这是唯一需要动计算逻辑的文件kernel_args.hTilingInfo按真实算子扩充字段如 block 数、每 block 尺寸KernelArgs补充 AI CPU 做分块所需的输入 shape 参数记住任何字段变更必须双端同步这正是踩坑 5 的正面实践aicore_kernel.asc为新 tiling 组合增加模板分支if链变长后可换成tiling 值 → 变体的映射结构让分派可读可控main.asc真实算子若需要多 block 下发调整1, 0, stream的配置参数即可event 依赖链与收尾同步释放的顺序保持不变。继续深入的仓库内资源相对路径Samples/0_Introduction/04_aicpu/README.mdAI CPU 样例总览了解 AI CPU 算子的定位边界Samples/0_Introduction/04_aicpu/00_device_tiling/README.md本样例原始说明含__mix__与日志次数对照Samples/0_Introduction/01_simd_cpp_api/README.mdAI Core 算子开发样例集替换真实分块后做对照开发cmake/ascend.cmakeCANN 工具链查找逻辑与 Bisheng 编译器配置排查构建问题时先看这里。【免费下载链接】cann-samplesCANN高性能实战演进样例与体系化调优知识库项目地址: https://gitcode.com/cann/cann-samples创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

canmatrix解码性能抖动排查:DBC属性类型如何拖慢十倍速度

canmatrix解码性能抖动排查:DBC属性类型如何拖慢十倍速度

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/21 1:40:36
Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答 【免费下载链接】front-end-interview-handbook Front End interview preparation materials for busy engineers (updated for 2026) 项目地址: https://gitcode.com/GitHub_Tr…

📅 2026/10/21 1:35:36
从零实现旋转电压矢量:SVPWM与SPWM的工程实践指南

从零实现旋转电压矢量:SVPWM与SPWM的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/10/21 1:35:36
MORE NEWS

更多资讯

📰

Rensheng d jngrjeg《人生的境界》汉语拼音字母标调拼写实测案例

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

【化学实验室|14】HarmonyOS ArkTS 主导航实战:统一页面入口、返回路径和参数校验

一个应用有四个底部页签、二十多个二级页面时,导航问题通常不会先表现为编译错误,而会变成更难复现的用户故障:点击“全部实验”偶尔没有切换选中态;新增一个页签后,首页快捷入口跳到了错误页面;桌面卡片传…

📰

【信息科学与工程学】计算机科学与自动化——第二十四篇 编译器05

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

【化学实验室|15】HarmonyOS ArkTS 本地状态持久化实战:让保存、删除和页面返回后的数据即时一致

本地应用最容易出现一种“看起来已经成功”的数据故障:用户点击收藏,图标立刻亮了;返回收藏页,却没有这条数据。删除笔记后列表立即消失,重新进入页面又恢复。连续点击两次收藏,最终状态与最后一次操作相反…

📰

如何读穿招聘简章?工业通信嵌入式岗位情报拆解指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

自动驾驶黄埔军校:4500人培养体系与行业技术扩散

在自动驾驶这行混久了,你会发现一个很有意思的现象:圈子里提到“黄埔军校”四个字,大家不用解释就知道说的是哪家。前阵子跟几个老朋友闲聊,有人随口说了句“现在从那儿出来的,加起来得有4500人了”,在场的…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬