调度、同步与调试【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills1. 循环原语T.serial(N) / T.serial(start, end, step)普通 for 循环。for i in T.serial(N): # 0..N-1 for i in T.serial(0, N, 2): # 0, 2, 4, ...T.unroll(N)针对小循环次数进行循环展开。TileLang 将展开提示传递给 TIR。for k in T.unroll(K_TILE): acc a[k] * b[k]While 循环循环条件需要是 TIR expression。TileLang 检测出死循环会编译报错。i 0 while i N: ... if done: break i 1Break 和 Continue在 T.serial/T.unroll/T.Parallel/while 循环中均可使用。2. T.Pipelined实现计算/搬运的流水线并行通过预取来掩盖内存访问延迟。语法for var in T.Pipelined(range, num_stagesN): ...range迭代次数num_stages预取阶段数小于 range-1 的正整数核内流水线Intra-corefor k in T.Pipelined(loop_k, num_stages2): T.copy(A[bx * block_M, k * block_K], A_L1) T.copy(B[k * block_K, by * block_N], B_L1) T.barrier_all() if k 0: T.gemm_v0(A_L1, B_L1, C_L0, initTrue) else: T.gemm_v0(A_L1, B_L1, C_L0) T.barrier_all()num_stages2时执行顺序TimeCopy A/BComputet₀copy_A_0, copy_B_0t₁copy_A_1, copy_B_1t₂copy_A_2, copy_B_2gemm_0t₃copy_A_3, copy_B_3gemm_1t₄gemm_2t₅gemm_3核间流水线Inter-coreCube 和 Vector 核之间的流水并行for k in T.Pipelined(T.ceildiv(seq_len, block_N), num_stages2): T.copy(K[bz, by, k * block_N:(k 1) * block_N, :], k_l1) T.gemm_v0(q_l1, k_l1, acc_s_l0c, transpose_BTrue, initTrue) T.copy(acc_s_l0c, workspace_1[cid, :, :]) T.tile.fill(acc_s_ub, 0.0) T.copy(workspace_1[cid, vid * block_M // 2:vid * block_M // 2 block_M // 2, :], acc_s_ub_) T.tile.add(acc_s_ub, acc_s_ub, acc_s_ub_) T.tile.mul(acc_s_ub, acc_s_ub, sm_scale) ...注意核间流水线与核内流水线不能同时开启使用核间流水线必须开启tl.ascend_auto_cv_combine: True,tl.ascend_auto_cross_core_sync: True3. T.Persistent优化数据块在 AI Core 间的调度使相邻数据块交由同一 AI Core 处理提高缓存命中率。for bx, by in T.Persistent(domain, wave_size, index): ...参数domain迭代空间wave_sizewave 大小通常为 core_numindex当前核的索引通常为 cid示例来自 Programming Guidewith T.Kernel(m_num * n_num, is_npuTrue) as (cid, _): A_L1 T.alloc_shared((block_M, K_L1), dtype) B_L1 T.alloc_shared((K_L1, block_N), dtype) C_L0 T.alloc_fragment((block_M, block_N), accum_dtype) for bx, by in T.Persistent([T.ceildiv(M, block_M), T.ceildiv(N, block_N)], core_num, cid): loop_k T.ceildiv(K, K_L1) for k in T.serial(loop_k): T.copy(A[bx * block_M, k * K_L1], A_L1) T.copy(B[k * K_L1, by * block_N], B_L1) T.gemm_v0(A_L1, B_L1, C_L0, init(k 0)) T.copy(C_L0, C[bx * block_M, by * block_N])4. 同步原语核内同步API说明T.set_flag(src, dst, eventId)设置核内流水线同步标志producer 完成通知T.wait_flag(src, dst, eventId)等待核内流水线同步标志consumer 阻塞等待T.barrier_all()所有管线的全局屏障T.pipe_barrier(pipe)特定管线的屏障如MTE3,VT.sync_all()全局同步管线名称fix,mte1,mte2,mte3,m,vT.set_flag(mte2, v, 0) T.wait_flag(mte2, v, 0)核间同步API说明T.set_cross_flag(pipe, flag)设置核间同步标志T.wait_cross_flag(flag)等待核间同步标志# Cube 核完成后通知 Vector 核 T.set_cross_flag(MTE3, 0) T.wait_cross_flag(0)set_cross_flag源码ascend.py:114还支持第三个参数mode默认 2控制同步范围0所有 AIC/AIV 之间1同组 AIV 之间2同组 AIC 和 AIV 之间。5. T.Scope用于标注代码块的执行域。with T.Scope(C): # Cube 域 ... with T.Scope(V): # Vector 域 ...6. 调试工具T.printf(format_str, *args)设备端格式化打印类似 C 语言 printf。Buffer 参数自动转换为 access pointer。格式说明符%d/%i整数,%f浮点,%x十六进制,%s字符串,%p指针建议使用%xT.printf(fmt %s %d\n, string, 0x123)T.dump_tensor(tensor, desc, dump_size, shape_info())转储指定 Tensor 的内容。参数tensor要转储的张量支持 ub_buffer、l1_buffer、l0c_buffer、global_bufferdesc用户自定义附加信息uint32如行号方便区分多处 dumpdump_size转储的元素数量shape_infoshape 信息元组可选用于格式化输出T.printf(A_L1:\n) T.dump_tensor(A_L1, 111, 64) # 不带 shape T.dump_tensor(A_L1, 111, 64, (8, 8)) # 带 shape_info 格式化输出查看生成的 AscendC 代码func tile_add(M, N, block_M, block_N) print(f{func.get_kernel_source()})注意T.printf 和 T.dump_tensor 是设备端调试工具主机端直接使用 Pythonprint。调试完成后应移除避免影响性能。7. 性能调优工具msProf# 上板性能分析 msprof op --kernel-nameyour_kernel_func_name python your_kernel_script.py # 仿真性能分析 msprof op simulator --soc-versionascend_version --kernel-nameyour_kernel_func_name python your_kernel_script.pymsProf 可展示计算内存热力图、Roofline 瓶颈分析图、Cache 热力图、通算流水图、算子代码热点图。【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考