已关闭
[Bug]: mssanitizer检测triton tl.dot()时出现OOB误报 #190
Naputao创建于  8月19日关闭于  9月14日
Naputao
Naputao
8月19日 创建

在提交新问题之前,请确保您已经在社区中搜索过相关问题,并使用了社区中提供的资源/工具后,仍未找到满意的解决方式。

⚠️ 安全信息提醒:请仔细检查提供的文本内容,确保其不包含敏感数据信息,包括但不限于:

  • API 令牌或密钥
  • 密码或身份验证凭证
  • 私有网址或接口地址
  • 个人或机密数据
  • ...

在分享配置信息或代码示例时,请将敏感信息脱敏处理,或使用 <TOKEN> 等占位符替代原有内容。

环境信息

Debian GNU/Linux 12 (bookworm)
Ascend950PR
npu-smi Version 25.7.t6 
mssanitizer 26.1.0-a9b9e9ea5c701cc8939017999fdd02c2e15905c2
msopscommon b4ffdb3d6ba7acdb7bbfcf359f6e4dd5b587a4f4
ascend-cann-950-ops                              9.1.0-beta.3  
ascend-cann-toolkit                              9.1.0-beta.3   
triton                       3.2.0
triton_ascend                3.2.2+dev20260724063007
torch                        2.7.1+cpu
torch_npu                    2.7.1.post4.dev20260327
Python 3.11.2

🐛 问题描述

这个 kernel 的核心作用是:对输入 s 在每个 chunk 内沿时间维做前缀累加。

triton源码

# Triton memcheck 用例: 05_rwkv6_cumsum_oob_memcheck
# 自包含复现 FLA 的 chunk_rwkv6_fwd_cumsum_kernel 在 mssanitizer memcheck 下报出的
# GM 写越界 (out of bounds of size 4)。
#
# 形状对齐 chunk_dplr_delta_rule 默认 smoke: B=1, T=64, H=1, S(=D)=64,
#   chunk_size(BT)=16, scale=RCP_LN2。grid=(cdiv(S,BS), cdiv(T,BT), B*H)。
#
# RUN: TRITON_DISABLE_LINE_INFO=false mssanitizer -t memcheck python 05_rwkv6_cumsum_oob_memcheck.py 

import torch
import torch_npu  # noqa: F401
import triton
import triton.language as tl

# fla.ops.utils.constant.RCP_LN2
RCP_LN2 = 1.4426950216

@triton.jit(do_not_specialize=['T'])
def chunk_rwkv6_fwd_cumsum_kernel(
    s,
    oi,
    oe,
    scale,
    cu_seqlens,
    chunk_indices,
    T,
    H: tl.constexpr,
    S: tl.constexpr,
    BT: tl.constexpr,
    BS: tl.constexpr,
):
    # 获取当前 program 在 S、T、BH 三个维度上的索引
    i_s, i_t, i_bh = tl.program_id(0), tl.program_id(1).to(tl.int64), tl.program_id(2).to(tl.int64)
    # 解析 batch 和 head 索引
    i_b, i_h = i_bh // H, i_bh % H
    # 当前 batch 的序列起止位置
    bos, eos = i_b * T, i_b * T + T
    # chunk 内部时间索引
    o_i = tl.arange(0, BT)
    # 包含对角线的下三角矩阵
    m_i = tl.where(o_i[:, None] >= o_i[None, :], 1., 0.).to(tl.float32)
    # 不包含对角线的下三角矩阵
    m_e = tl.where(o_i[:, None] > o_i[None, :], 1., 0.).to(tl.float32)
    # 当前 program 对应的全局 T 维索引
    o_t = i_t * BT + tl.arange(0, BT)
    # 当前 program 对应的全局 S 维索引
    o_s = i_s * BS + tl.arange(0, BS)
    # 有效范围 mask
    m_s = (o_t[:, None] < T) & (o_s[None, :] < S)
    # 输入 s 的地址
    p_s = s + (bos * H + i_h) * S + o_t[:, None] * (H*S) + o_s[None, :]
    # 输出 oi 的地址
    p_oi = oi + (bos * H + i_h) * S + o_t[:, None] * (H*S) + o_s[None, :]
    # 输出 oe 的地址
    p_oe = oe + (bos * H + i_h) * S + o_t[:, None] * (H*S) + o_s[None, :]
    # 加载当前 [BT, BS] 数据块
    b_s = tl.load(p_s, mask=m_s, other=0.0).to(tl.float32)
    # inclusive 前缀和
    b_oi = tl.dot(m_i, b_s)
    # exclusive 前缀和
    b_oe = tl.dot(m_e, b_s)
    # 缩放结果
    b_oi = b_oi * scale
    b_oe = b_oe * scale
    # 写回 inclusive 结果
    tl.store(
        p_oi,
        b_oi.to(p_oi.dtype.element_ty, fp_downcast_rounding="rtne"),
        mask=m_s,
    )
    # 写回 exclusive 结果
    tl.store(
        p_oe,
        b_oe.to(p_oe.dtype.element_ty, fp_downcast_rounding="rtne"),
        mask=m_s,
    )

def main():
    B, T, H, S = 1, 64, 1, 64
    BT = 16              # chunk_dplr_delta_rule 默认 chunk_size=16
    BS = 32              # 单个 autotune tiling; 越界与 BS 具体取值无关
    NT = triton.cdiv(T, BT)

    # gk gate, 形状 [B, T, H, S] (S == D)
    g = torch.randn(B, T, H, S, dtype=torch.float32, device="npu")
    gi = torch.empty_like(g, dtype=torch.float)
    ge = torch.empty_like(g, dtype=torch.float)

    grid = (triton.cdiv(S, BS), NT, B * H)
    chunk_rwkv6_fwd_cumsum_kernel[grid](
        g,
        gi,
        ge,
        RCP_LN2,
        None,       # cu_seqlens
        None,       # chunk_indices
        T=T,
        H=H,
        S=S,
        BT=BT,
        BS=BS,
    )
    torch.npu.synchronize()
    # 强制一次 host 可见使用, 保证异步写入在退出前被检查
    gi.sum().item()
    ge.sum().item()
    print(f"[rwkv6_cumsum] kernel launched (B={B}, T={T}, H={H}, S={S}, BT={BT}, BS={BS})")

if __name__ == "__main__":
    main()

运行命令

TRITON_DISABLE_LINE_INFO=false PYTORCH_NO_NPU_MEMORY_CACHING=ON mssanitizer -t memcheck python 05_rwkv6_cumsum_oob_memcheck.py

运行结果

debian-95-31(@:):workspace# mssanitizer -t memcheck python */05_rwkv6_cumsum_oob_memcheck.py 
=================================================================
                   >>>>>   MindStudio   <<<<<
    THE END-TO-END TOOLCHAIN TO UNLEASH HUAWEI ASCEND COMPUTE
=================================================================

[mssanitizer] logging to file: ./mindstudio_sanitizer_log/mssanitizer_20260819150039_173494.log
[W819 15:00:40.964687556 FunctionLoader.cpp:48] Warning: LD_PRELOAD detected, FunctionLoader prefers RTLD_DEFAULT for symbol resolution. (function operator())
[mssanitizer] Start memcheck sanitizer on kernel StatelessNormal_b0a1e88610ecbf2fa919f6bb9815f061_high_performance_100
[mssanitizer] Sanitizer finished on kernel StatelessNormal_b0a1e88610ecbf2fa919f6bb9815f061_high_performance_100. No error detected.
[mssanitizer] Start memcheck sanitizer on kernel chunk_rwkv6_fwd_cumsum_kernel
====== WARNING: out of bounds of size 4
======    at 0x120116f98000 on GM when writing data in chunk_rwkv6_fwd_cumsum_kernel
======    in block aic(1) on device 0
======    code in pc current 0x280 (serialNo:404)
======    #0 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:50:16
======    #1 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:158:52
======    #2 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:263:3
======    #3 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:730:1
======    #4 */05_rwkv6_cumsum_oob_memcheck.py:68:23
======    #5 */05_rwkv6_cumsum_oob_memcheck.py:68:23

[mssanitizer] Sanitizer finished on kernel chunk_rwkv6_fwd_cumsum_kernel. See all detected errors above.
[mssanitizer] Start memcheck sanitizer on kernel ReduceSum_float32_int64_high_performance_5143
[mssanitizer] Sanitizer finished on kernel ReduceSum_float32_int64_high_performance_5143. No error detected.
[mssanitizer] Start memcheck sanitizer on kernel ReduceSum_float32_int64_high_performance_5143
[mssanitizer] Sanitizer finished on kernel ReduceSum_float32_int64_high_performance_5143. No error detected.
[rwkv6_cumsum] kernel launched (B=1, T=64, H=1, S=64, BT=16, BS=32)

npuir

// -----// IR Dump After GraphSyncSolver (hivm-graph-sync-solver) //----- //
func.func @chunk_rwkv6_fwd_cumsum_kernel_mix_aiv(%arg0: memref<?xi8, #hivm.address_space<gm>> {hacc.arg_type = #hacc.arg_type<sync_block_lock>}, %arg1: memref<?xi8, #hivm.address_space<gm>> {hacc.arg_type = #hacc.arg_type<workspace>}, %arg2: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 0 : i32}, %arg3: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 1 : i32}, %arg4: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 1 : i32}, %arg5: f32, %arg6: i32, %arg7: i32, %arg8: i32, %arg9: i32) attributes {SyncBlockLockArgIdx = 0 : i64, WorkspaceArgIdx = 1 : i64, func_dyn_memref_args = dense<[true, true, true, true, true, false, false, false, false, false]> : vector<10xi1>, hacc.entry, hacc.function_kind = #hacc.function_kind<DEVICE>, hivm.func_core_type = #hivm.func_core_type<AIV>, hivm.part_of_mix, hivm.vf_mode = #hivm.vf_mode<SIMD>, mix_mode = "mix", parallel_mode = "simd"} {
  %c7360_i64 = arith.constant 7360 : i64
  %c6336_i64 = arith.constant 6336 : i64
  %c2048_i64 = arith.constant 2048 : i64
  %c4288_i64 = arith.constant 4288 : i64
  %c2240_i64 = arith.constant 2240 : i64
  %c1152_i64 = arith.constant 1152 : i64
  %c0_i64 = arith.constant 0 : i64
  %c8 = arith.constant 8 : index
  %c56_i32 = arith.constant 56 : i32
  %c16_i64 = arith.constant 16 : i64
  %c32_i32 = arith.constant 32 : i32
  %c64_i64 = arith.constant 64 : i64
  %c64 = arith.constant 64 : index
  %c16 = arith.constant 16 : index
  %c32 = arith.constant 32 : index
  %c0 = arith.constant 0 : index
  %c1 = arith.constant 1 : index
  %c2 = arith.constant 2 : index
  %0 = arith.muli %arg7, %arg8 : i32
  %1 = arith.muli %0, %arg9 : i32
  %2 = hivm.hir.get_block_idx -> i64
  %3 = arith.trunci %2 : i64 to i32
  %4 = arith.index_cast %1 : i32 to index
  %5 = hivm.hir.pointer_cast(%c0_i64) : memref<16xi32, #hivm.address_space<ub>>
  call @chunk_rwkv6_fwd_cumsum_kernel_mix_aiv_outlined_vf_2(%5) {hivm.vector_function, no_inline} : (memref<16xi32, #hivm.address_space<ub>>) -> ()
  %6 = arith.extsi %arg6 : i32 to i64
  %7 = arith.index_cast %arg6 : i32 to index
  %8 = hivm.hir.get_sub_block_idx -> i64
  %9 = arith.index_cast %8 : i64 to index
  %10 = affine.apply affine_map<()[s0] -> (s0 * 8)>()[%9]
  annotation.mark %1 {logical_block_num} : i32
  %11 = hivm.hir.pointer_cast(%c64_i64) : memref<2x17x8x1xf32, #hivm.address_space<ub>>
  %subview = memref.subview %11[0, 0, 0, 0] [2, 8, 8, 1] [1, 1, 1, 1] : memref<2x17x8x1xf32, #hivm.address_space<ub>> to memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>>
  %12 = hivm.hir.pointer_cast(%c1152_i64) : memref<2x17x8x1xf32, #hivm.address_space<ub>>
  %subview_0 = memref.subview %12[0, 0, 0, 0] [2, 8, 8, 1] [1, 1, 1, 1] : memref<2x17x8x1xf32, #hivm.address_space<ub>> to memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>>
  call @chunk_rwkv6_fwd_cumsum_kernel_mix_aiv_outlined_vf_1(%9, %5, %subview, %subview_0) {hivm.vector_function, no_inline} : (index, memref<16xi32, #hivm.address_space<ub>>, memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>>, memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>>) -> ()
  hivm.hir.set_flag[<PIPE_V>, <PIPE_MTE3>, <EVENT_ID0>]
  %expand_shape = memref.expand_shape %subview [[0], [1, 2], [3]] output_shape [2, 1, 8, 8] : memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>> into memref<2x1x8x8xf32, strided<[136, 64, 8, 1]>, #hivm.address_space<ub>>
  %expand_shape_1 = memref.expand_shape %subview_0 [[0], [1, 2], [3]] output_shape [2, 1, 8, 8] : memref<2x8x8xf32, strided<[136, 8, 1]>, #hivm.address_space<ub>> into memref<2x1x8x8xf32, strided<[136, 64, 8, 1]>, #hivm.address_space<ub>>
  hivm.hir.sync_block_set[<VECTOR>, <PIPE_V>, <PIPE_FIX>] flag = 1
  hivm.hir.sync_block_set[<VECTOR>, <PIPE_V>, <PIPE_FIX>] flag = 1
  hivm.hir.wait_flag[<PIPE_V>, <PIPE_MTE3>, <EVENT_ID0>]
  hivm.hir.set_flag[<PIPE_MTE3>, <PIPE_V>, <EVENT_ID0>]
  scf.for %arg10 = %3 to %1 step %c56_i32  : i32 {
    %13 = hivm.hir.pointer_cast(%c2240_i64) : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %13 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<0>, hivm.tiling_dim = 1 : index, tiledAlloc} : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %13 {hivm.cv_pipelined_multi_buffer} : memref<2x8x32xf32, #hivm.address_space<ub>>
    %14 = hivm.hir.pointer_cast(%c4288_i64) : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %14 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<1>, hivm.tiling_dim = 1 : index, tiledAlloc} : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %14 {hivm.cv_pipelined_multi_buffer} : memref<2x8x32xf32, #hivm.address_space<ub>>
    %15 = hivm.hir.pointer_cast(%c0_i64) : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %15 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<2>, hivm.tiling_dim = -1 : index} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %15 {hivm.cv_pipelined_multi_buffer} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    %16 = hivm.hir.pointer_cast(%c2048_i64) : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %16 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<3>, hivm.tiling_dim = -1 : index} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %16 {hivm.cv_pipelined_multi_buffer} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    %17 = arith.index_cast %arg10 : i32 to index
    %18 = affine.apply affine_map<(d0)[s0] -> ((-d0 + s0) ceildiv 28)>(%17)[%4]
    %19 = arith.minui %18, %c2 : index
    scf.for %arg11 = %c0 to %19 step %c1 {
      %subview_2 = memref.subview %16[%arg11, 0, 0, 0, 0] [1, 2, 1, 16, 8] [1, 1, 1, 1, 1] : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>> to memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      %subview_3 = memref.subview %subview_2[0, 0, %10, 0] [2, 1, 8, 8] [1, 1, 1, 1] {to_be_bubbled_slice} : memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>> to memref<2x1x8x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      %subview_4 = memref.subview %15[%arg11, 0, 0, 0, 0] [1, 2, 1, 16, 8] [1, 1, 1, 1, 1] : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>> to memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      %subview_5 = memref.subview %subview_4[0, 0, %10, 0] [2, 1, 8, 8] [1, 1, 1, 1] {to_be_bubbled_slice} : memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>> to memref<2x1x8x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      %collapse_shape = memref.collapse_shape %expand_shape [[0, 1], [2, 3]] : memref<2x1x8x8xf32, strided<[136, 64, 8, 1]>, #hivm.address_space<ub>> into memref<2x64xf32, strided<[136, 1]>, #hivm.address_space<ub>>
      %collapse_shape_6 = memref.collapse_shape %subview_5 [[0, 1], [2, 3]] : memref<2x1x8x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>> into memref<2x64xf32, strided<[128, 1], offset: ?>, #hivm.address_space<cbuf>>
      hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
      hivm.hir.pipe_barrier[<PIPE_MTE3>]
      hivm.hir.copy ins(%collapse_shape : memref<2x64xf32, strided<[136, 1]>, #hivm.address_space<ub>>) outs(%collapse_shape_6 : memref<2x64xf32, strided<[128, 1], offset: ?>, #hivm.address_space<cbuf>>) {"hivm.inserted-copy", tiled_op}
      hivm.hir.sync_block_set[<VECTOR>, <PIPE_MTE3>, <PIPE_MTE1>] flag = 0
      %collapse_shape_7 = memref.collapse_shape %expand_shape_1 [[0, 1], [2, 3]] : memref<2x1x8x8xf32, strided<[136, 64, 8, 1]>, #hivm.address_space<ub>> into memref<2x64xf32, strided<[136, 1]>, #hivm.address_space<ub>>
      %collapse_shape_8 = memref.collapse_shape %subview_3 [[0, 1], [2, 3]] : memref<2x1x8x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>> into memref<2x64xf32, strided<[128, 1], offset: ?>, #hivm.address_space<cbuf>>
      hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
      hivm.hir.copy ins(%collapse_shape_7 : memref<2x64xf32, strided<[136, 1]>, #hivm.address_space<ub>>) outs(%collapse_shape_8 : memref<2x64xf32, strided<[128, 1], offset: ?>, #hivm.address_space<cbuf>>) {"hivm.inserted-copy", tiled_op}
      hivm.hir.sync_block_set[<VECTOR>, <PIPE_MTE3>, <PIPE_MTE1>] flag = 5
    } {hivm.loop_core_type = #hivm.tcore_type<VECTOR>, multibuffer_unroll_factor = 2 : i32}
    scf.for %arg11 = %c0 to %19 step %c1 {
      %20 = affine.apply affine_map<(d0)[s0] -> (d0 * 28 + s0)>(%arg11)[%17]
      %21 = arith.index_cast %20 : index to i32
      %22 = arith.remsi %21, %arg7 : i32
      %23 = arith.divsi %21, %arg7 : i32
      %24 = arith.remsi %23, %arg8 : i32
      %25 = arith.divsi %21, %0 : i32
      %26 = arith.remsi %25, %arg9 : i32
      %27 = arith.extsi %24 : i32 to i64
      %28 = arith.extsi %26 : i32 to i64
      %29 = arith.muli %28, %6 : i64
      %30 = arith.muli %27, %c16_i64 : i64
      %31 = arith.muli %22, %c32_i32 : i32
      %32 = arith.muli %29, %c64_i64 : i64
      %33 = arith.index_cast %32 : i64 to index
      %34 = arith.index_cast %30 : i64 to index
      %35 = affine.apply affine_map<()[s0] -> (s0 + 16)>()[%34]
      %36 = arith.index_cast %31 : i32 to index
      %37 = affine.apply affine_map<()[s0, s1, s2] -> (s0 + s1 + s2 * 64)>()[%36, %33, %34]
      %38 = affine.apply affine_map<()[s0] -> (s0 + 32)>()[%36]
      %reinterpret_cast = memref.reinterpret_cast %arg3 to offset: [%37], sizes: [16, 32], strides: [64, 1] : memref<?xf32, #hivm.address_space<gm>> to memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      %reinterpret_cast_2 = memref.reinterpret_cast %arg4 to offset: [%37], sizes: [16, 32], strides: [64, 1] : memref<?xf32, #hivm.address_space<gm>> to memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      %39 = arith.maxsi %34, %7 : index
      %40 = arith.minsi %35, %39 : index
      %41 = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%40, %34]
      %42 = arith.maxsi %36, %c64 : index
      %43 = arith.minsi %38, %42 : index
      %44 = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%43, %36]
      %45 = arith.minsi %41, %c16 : index
      %46 = arith.maxsi %45, %c0 : index
      %47 = arith.minsi %44, %c32 : index
      %48 = arith.maxsi %47, %c0 : index
      %49 = hivm.hir.pointer_cast(%c6336_i64) : memref<8x32xf32, #hivm.address_space<ub>>
      %50 = hivm.hir.pointer_cast(%c7360_i64) : memref<8x32xf32, #hivm.address_space<ub>>
      hivm.hir.sync_block_wait[<VECTOR>, <PIPE_FIX>, <PIPE_V>] flag = 4
      hivm.hir.wait_flag[<PIPE_MTE3>, <PIPE_V>, <EVENT_ID0>]
      func.call @chunk_rwkv6_fwd_cumsum_kernel_mix_aiv_outlined_vf_0(%13, %arg11, %arg5, %14, %49, %50) {hivm.vector_function, no_inline} : (memref<2x8x32xf32, #hivm.address_space<ub>>, index, f32, memref<2x8x32xf32, #hivm.address_space<ub>>, memref<8x32xf32, #hivm.address_space<ub>>, memref<8x32xf32, #hivm.address_space<ub>>) -> ()
      hivm.hir.set_flag[<PIPE_V>, <PIPE_MTE3>, <EVENT_ID0>]
      hivm.hir.sync_block_set[<VECTOR>, <PIPE_V>, <PIPE_FIX>] flag = 1
      %51 = arith.minsi %10, %46 : index
      %52 = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%46, %51]
      %53 = arith.minsi %52, %c8 : index
      %subview_3 = memref.subview %49[0, 0] [%53, %48] [1, 1] : memref<8x32xf32, #hivm.address_space<ub>> to memref<?x?xf32, strided<[32, 1]>, #hivm.address_space<ub>>
      %subview_4 = memref.subview %reinterpret_cast[%10, 0] [%53, %48] [1, 1] : memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>> to memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      hivm.hir.wait_flag[<PIPE_V>, <PIPE_MTE3>, <EVENT_ID0>]
      hivm.hir.store ins(%subview_3 : memref<?x?xf32, strided<[32, 1]>, #hivm.address_space<ub>>) outs(%subview_4 : memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>) {tiled_op}
      %subview_5 = memref.subview %50[0, 0] [%53, %48] [1, 1] : memref<8x32xf32, #hivm.address_space<ub>> to memref<?x?xf32, strided<[32, 1]>, #hivm.address_space<ub>>
      %subview_6 = memref.subview %reinterpret_cast_2[%10, 0] [%53, %48] [1, 1] : memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>> to memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      hivm.hir.store ins(%subview_5 : memref<?x?xf32, strided<[32, 1]>, #hivm.address_space<ub>>) outs(%subview_6 : memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>) {tiled_op}
      hivm.hir.set_flag[<PIPE_MTE3>, <PIPE_V>, <EVENT_ID0>]
    } {hivm.loop_core_type = #hivm.tcore_type<VECTOR>, multibuffer_unroll_factor = 2 : i32}
  } {cv_unrolled_loop}
  hivm.hir.wait_flag[<PIPE_MTE3>, <PIPE_V>, <EVENT_ID0>]
  hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
  hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
  hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
  hivm.hir.sync_block_wait[<VECTOR>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
  hivm.hir.pipe_barrier[<PIPE_ALL>]
  return
}

// -----// IR Dump After GraphSyncSolver (hivm-graph-sync-solver) //----- //
func.func @chunk_rwkv6_fwd_cumsum_kernel_mix_aic(%arg0: memref<?xi8, #hivm.address_space<gm>> {hacc.arg_type = #hacc.arg_type<sync_block_lock>}, %arg1: memref<?xi8, #hivm.address_space<gm>> {hacc.arg_type = #hacc.arg_type<workspace>}, %arg2: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 0 : i32}, %arg3: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 1 : i32}, %arg4: memref<?xf32, #hivm.address_space<gm>> {tt.divisibility = 16 : i32, tt.tensor_kind = 1 : i32}, %arg5: f32, %arg6: i32, %arg7: i32, %arg8: i32, %arg9: i32) attributes {SyncBlockLockArgIdx = 0 : i64, WorkspaceArgIdx = 1 : i64, func_dyn_memref_args = dense<[true, true, true, true, true, false, false, false, false, false]> : vector<10xi1>, hacc.entry, hacc.function_kind = #hacc.function_kind<DEVICE>, hivm.func_core_type = #hivm.func_core_type<AIC>, hivm.part_of_mix, hivm.vf_mode = #hivm.vf_mode<SIMD>, mix_mode = "mix", parallel_mode = "simd"} {
  %c0_i64 = arith.constant 0 : i64
  %c6144_i64 = arith.constant 6144 : i64
  %c4096_i64 = arith.constant 4096 : i64
  %c2048_i64 = arith.constant 2048 : i64
  %c0_i64_0 = arith.constant 0 : i64
  %c4288_i64 = arith.constant 4288 : i64
  %c2240_i64 = arith.constant 2240 : i64
  %true = arith.constant true
  %c1 = arith.constant 1 : index
  %c0 = arith.constant 0 : index
  %c32 = arith.constant 32 : index
  %c16 = arith.constant 16 : index
  %c64 = arith.constant 64 : index
  %c64_i64 = arith.constant 64 : i64
  %c32_i32 = arith.constant 32 : i32
  %c16_i64 = arith.constant 16 : i64
  %cst = arith.constant 0.000000e+00 : f32
  %c2 = arith.constant 2 : index
  %c56_i32 = arith.constant 56 : i32
  %0 = arith.muli %arg7, %arg8 : i32
  %1 = arith.muli %0, %arg9 : i32
  annotation.mark %1 {logical_block_num} : i32
  %2 = hivm.hir.get_block_idx -> i64
  %3 = arith.trunci %2 : i64 to i32
  %4 = arith.index_cast %1 : i32 to index
  %5 = arith.extsi %arg6 : i32 to i64
  %6 = arith.index_cast %arg6 : i32 to index
  hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
  hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
  hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
  hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
  hivm.hir.set_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID1>]
  hivm.hir.set_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID2>]
  hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID0>]
  hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID1>]
  hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID2>]
  hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID3>]
  hivm.hir.set_flag[<PIPE_M>, <PIPE_MTE1>, <EVENT_ID0>]
  hivm.hir.set_flag[<PIPE_M>, <PIPE_MTE1>, <EVENT_ID1>]
  scf.for %arg10 = %3 to %1 step %c56_i32  : i32 {
    %7 = hivm.hir.pointer_cast(%c2240_i64) : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %7 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<0>, hivm.tiling_dim = 1 : index, tiledAlloc} : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %7 {hivm.cv_pipelined_multi_buffer} : memref<2x8x32xf32, #hivm.address_space<ub>>
    %8 = hivm.hir.pointer_cast(%c4288_i64) : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %8 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<1>, hivm.tiling_dim = 1 : index, tiledAlloc} : memref<2x8x32xf32, #hivm.address_space<ub>>
    annotation.mark %8 {hivm.cv_pipelined_multi_buffer} : memref<2x8x32xf32, #hivm.address_space<ub>>
    %9 = hivm.hir.pointer_cast(%c0_i64_0) : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %9 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<2>, hivm.tiling_dim = -1 : index} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %9 {hivm.cv_pipelined_multi_buffer} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    %10 = hivm.hir.pointer_cast(%c2048_i64) : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %10 {effects = ["write", "read"], hivm.tightly_coupled_buffer = #hivm.tightly_coupled_buffer<3>, hivm.tiling_dim = -1 : index} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    annotation.mark %10 {hivm.cv_pipelined_multi_buffer} : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>>
    %11 = arith.index_cast %arg10 : i32 to index
    %12 = affine.apply affine_map<(d0)[s0] -> ((-d0 + s0) ceildiv 28)>(%11)[%4]
    %13 = arith.minui %12, %c2 : index
    scf.for %arg11 = %c0 to %13 step %c1 {
      %14 = hivm.hir.multi_buffer_counter -> i64
      %c2_i64 = arith.constant 2 : i64
      %15 = arith.remui %14, %c2_i64 : i64
      %16 = arith.index_cast %15 : i64 to index
      %17 = arith.index_cast %16 : index to i1
      %c2_i64_1 = arith.constant 2 : i64
      %c3_i64 = arith.constant 3 : i64
      %18 = arith.select %17, %c2_i64_1, %c3_i64 : i64
      %19 = arith.index_cast %16 : index to i1
      %c0_i64_2 = arith.constant 0 : i64
      %c1_i64 = arith.constant 1 : i64
      %20 = arith.select %19, %c0_i64_2, %c1_i64 : i64
      %21 = arith.index_cast %16 : index to i1
      %c1_i64_3 = arith.constant 1 : i64
      %c2_i64_4 = arith.constant 2 : i64
      %22 = arith.select %21, %c1_i64_3, %c2_i64_4 : i64
      %23 = hivm.hir.pointer_cast(%c2048_i64, %c6144_i64) : memref<2x1x16x16xf32, #hivm.address_space<cc>>
      annotation.mark %23 {hivm.multi_buffer = 2 : i32} : memref<2x1x16x16xf32, #hivm.address_space<cc>>
      %24 = hivm.hir.pointer_cast(%c0_i64_0, %c4096_i64) : memref<2x1x16x16xf32, #hivm.address_space<cc>>
      annotation.mark %24 {hivm.multi_buffer = 2 : i32} : memref<2x1x16x16xf32, #hivm.address_space<cc>>
      %25 = hivm.hir.pointer_cast(%c4096_i64, %c6144_i64) : memref<4x1x16x8xf32, #hivm.address_space<cbuf>>
      annotation.mark %25 {hivm.multi_buffer = 2 : i32} : memref<4x1x16x8xf32, #hivm.address_space<cbuf>>
      %subview = memref.subview %8[%arg11, 0, 0] [1, 8, 32] [1, 1, 1] : memref<2x8x32xf32, #hivm.address_space<ub>> to memref<8x32xf32, strided<[32, 1], offset: ?>, #hivm.address_space<ub>>
      %subview_5 = memref.subview %7[%arg11, 0, 0] [1, 8, 32] [1, 1, 1] : memref<2x8x32xf32, #hivm.address_space<ub>> to memref<8x32xf32, strided<[32, 1], offset: ?>, #hivm.address_space<ub>>
      %26 = affine.apply affine_map<(d0)[s0] -> (d0 * 28 + s0)>(%arg11)[%11]
      %27 = arith.index_cast %26 : index to i32
      %28 = arith.remsi %27, %arg7 : i32
      %29 = arith.divsi %27, %arg7 : i32
      %30 = arith.remsi %29, %arg8 : i32
      %31 = arith.divsi %27, %0 : i32
      %32 = arith.remsi %31, %arg9 : i32
      %33 = arith.extsi %30 : i32 to i64
      %34 = arith.extsi %32 : i32 to i64
      %35 = arith.muli %34, %5 : i64
      %36 = arith.muli %33, %c16_i64 : i64
      %37 = arith.muli %28, %c32_i32 : i32
      %38 = arith.muli %35, %c64_i64 : i64
      %39 = arith.index_cast %38 : i64 to index
      %40 = arith.index_cast %36 : i64 to index
      %41 = arith.index_cast %37 : i32 to index
      %42 = affine.apply affine_map<()[s0, s1, s2] -> (s0 + s1 + s2 * 64)>()[%41, %39, %40]
      %reinterpret_cast = memref.reinterpret_cast %arg2 to offset: [%42], sizes: [16, 32], strides: [64, 1] : memref<?xf32, #hivm.address_space<gm>> to memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      %43 = affine.apply affine_map<()[s0] -> (s0 + 16)>()[%40]
      %44 = arith.maxsi %40, %6 : index
      %45 = arith.minsi %43, %44 : index
      %46 = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%45, %40]
      %47 = affine.apply affine_map<()[s0] -> (s0 + 32)>()[%41]
      %48 = arith.maxsi %41, %c64 : index
      %49 = arith.minsi %47, %48 : index
      %50 = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%49, %41]
      %51 = arith.minsi %46, %c16 : index
      %52 = arith.maxsi %51, %c0 : index
      %53 = arith.minsi %50, %c32 : index
      %54 = arith.maxsi %53, %c0 : index
      %55 = arith.cmpi slt, %52, %c16 : index
      %56 = arith.cmpi slt, %54, %c32 : index
      %57 = arith.ori %55, %56 : i1
      %subview_6 = memref.subview %reinterpret_cast[0, 0] [%52, %54] [1, 1] : memref<16x32xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>> to memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>
      %58 = affine.apply affine_map<()[s0] -> (s0 ceildiv 16)>()[%52]
      %59 = affine.apply affine_map<()[s0] -> (s0 ceildiv 8)>()[%54]
      %subview_7 = memref.subview %25[0, 0, 0, 0] [%59, %58, 16, 8] [1, 1, 1, 1] : memref<4x1x16x8xf32, #hivm.address_space<cbuf>> to memref<?x?x16x8xf32, strided<[128, 128, 8, 1]>, #hivm.address_space<cbuf>>
      scf.if %57 {
        hivm.hir.set_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID0>]
        %collapse_shape = memref.collapse_shape %25 [[0, 1, 2, 3]] : memref<4x1x16x8xf32, #hivm.address_space<cbuf>> into memref<512xf32, #hivm.address_space<cbuf>>
        hivm.hir.wait_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID0>]
        hivm.hir.vbrc ins(%cst : f32) outs(%collapse_shape : memref<512xf32, #hivm.address_space<cbuf>>)
        hivm.hir.pipe_barrier[<PIPE_MTE2>]
      } {hivm.unlikely_condition}
      hivm.hir.wait_flag[<PIPE_MTE1>, <PIPE_MTE2>, %22]
      hivm.hir.nd2nz {dst_continuous} ins(%subview_6 : memref<?x?xf32, strided<[64, 1], offset: ?>, #hivm.address_space<gm>>) outs(%subview_7 : memref<?x?x16x8xf32, strided<[128, 128, 8, 1]>, #hivm.address_space<cbuf>>)
      hivm.hir.set_flag[<PIPE_MTE2>, <PIPE_MTE1>, <EVENT_ID0>]
      %subview_8 = memref.subview %9[%arg11, 0, 0, 0, 0] [1, 2, 1, 16, 8] [1, 1, 1, 1, 1] : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>> to memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      hivm.hir.sync_block_wait[<CUBE>, <PIPE_MTE3>, <PIPE_MTE1>] flag = 0
      hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, %20]
      %c-1_i64 = arith.constant -1 : i64
      hivm.hir.mmadL1 {already_set_real_mkn, fixpipe_for_result_already_inserted = true, normalized_in_L0C} ins(%subview_8, %25, %true, %c16, %c16, %c32 : memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>, memref<4x1x16x8xf32, #hivm.address_space<cbuf>>, i1, index, index, index) outs(%24 : memref<2x1x16x16xf32, #hivm.address_space<cc>>) sync_related_args(%c-1_i64, %c0_i64, %c-1_i64, %c-1_i64, %c-1_i64, %c-1_i64, %c-1_i64 : i64, i64, i64, i64, i64, i64, i64)
      hivm.hir.set_flag[<PIPE_M>, <PIPE_FIX>, <EVENT_ID0>]
      hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 3
      hivm.hir.sync_block_wait[<CUBE>, <PIPE_V>, <PIPE_FIX>] flag = 1
      hivm.hir.wait_flag[<PIPE_M>, <PIPE_FIX>, <EVENT_ID0>]
      hivm.hir.pipe_barrier[<PIPE_FIX>]
      hivm.hir.fixpipe {dma_mode = #hivm.dma_mode<nz2nd>} ins(%24 : memref<2x1x16x16xf32, #hivm.address_space<cc>>) outs(%subview_5 : memref<8x32xf32, strided<[32, 1], offset: ?>, #hivm.address_space<ub>>) dual_dst_mode = <ROW_SPLIT>
      hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, %20]
      %subview_9 = memref.subview %10[%arg11, 0, 0, 0, 0] [1, 2, 1, 16, 8] [1, 1, 1, 1, 1] : memref<2x2x1x16x8xf32, #hivm.address_space<cbuf>> to memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>
      hivm.hir.sync_block_wait[<CUBE>, <PIPE_MTE3>, <PIPE_MTE1>] flag = 5
      hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, %18]
      %c-1_i64_10 = arith.constant -1 : i64
      hivm.hir.mmadL1 {already_set_real_mkn, fixpipe_for_result_already_inserted = true, normalized_in_L0C} ins(%subview_9, %25, %true, %c16, %c16, %c32 : memref<2x1x16x8xf32, strided<[128, 128, 8, 1], offset: ?>, #hivm.address_space<cbuf>>, memref<4x1x16x8xf32, #hivm.address_space<cbuf>>, i1, index, index, index) outs(%23 : memref<2x1x16x16xf32, #hivm.address_space<cc>>) sync_related_args(%c-1_i64_10, %c-1_i64_10, %c-1_i64_10, %22, %c-1_i64_10, %c-1_i64_10, %c-1_i64_10 : i64, i64, i64, i64, i64, i64, i64)
      hivm.hir.set_flag[<PIPE_M>, <PIPE_FIX>, <EVENT_ID0>]
      hivm.hir.sync_block_set[<CUBE>, <PIPE_MTE1>, <PIPE_MTE3>] flag = 2
      hivm.hir.wait_flag[<PIPE_M>, <PIPE_FIX>, <EVENT_ID0>]
      hivm.hir.fixpipe {dma_mode = #hivm.dma_mode<nz2nd>} ins(%23 : memref<2x1x16x16xf32, #hivm.address_space<cc>>) outs(%subview : memref<8x32xf32, strided<[32, 1], offset: ?>, #hivm.address_space<ub>>) dual_dst_mode = <ROW_SPLIT>
      hivm.hir.set_flag[<PIPE_FIX>, <PIPE_M>, %18]
      hivm.hir.sync_block_set[<CUBE>, <PIPE_FIX>, <PIPE_V>] flag = 4
    } {hivm.loop_core_type = #hivm.tcore_type<CUBE>, multibuffer_unroll_factor = 2 : i32}
  } {cv_unrolled_loop}
  hivm.hir.wait_flag[<PIPE_M>, <PIPE_MTE1>, <EVENT_ID0>]
  hivm.hir.wait_flag[<PIPE_M>, <PIPE_MTE1>, <EVENT_ID1>]
  hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID0>]
  hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID1>]
  hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID2>]
  hivm.hir.wait_flag[<PIPE_FIX>, <PIPE_M>, <EVENT_ID3>]
  hivm.hir.wait_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID1>]
  hivm.hir.wait_flag[<PIPE_MTE1>, <PIPE_MTE2>, <EVENT_ID2>]
  hivm.hir.sync_block_wait[<CUBE>, <PIPE_V>, <PIPE_FIX>] flag = 1
  hivm.hir.sync_block_wait[<CUBE>, <PIPE_V>, <PIPE_FIX>] flag = 1
  hivm.hir.pipe_barrier[<PIPE_ALL>]
  return
}

bisheng: warning: the flag '--cce-aicore-input-parameter-size=1536' has been deprecated and will be ignored [-Wunused-command-line-argument]
bisheng: warning: the flag '--cce-aicore-input-parameter-size=1536' has been deprecated and will be ignored [-Wunused-command-line-argument]
ld.lld: warning: -z separate-code and -z separate-loadable-segments will be ignored

欢迎加入社区,感谢您对社区的贡献 🎉!

likedislike
went_code
went_code成员
8月19日 评论:

👋 您好,欢迎向 MindStudio-Sanitizer 提交 Issue!
我们已收到您的反馈,感谢你对开源社区的支持。🎉

📅 处理时效 维护团队将在工作日 24 小时内查看并回复您的问题。
🔍 自助排查(推荐优先查看) 在等待回复期间,您可以先查阅以下资源,多数问题可快速解决:

💡 **为了更快定位问题,请您确保 Issue 包含:

  1. 清晰的问题描述
  2. 可复现的操作步骤
  3. 相关日志、截图或环境信息
    我们会尽快跟进,感谢您的理解与配合!
likedislike
ascend-robotascend-robot成员
8月19日 添加了label:bug
liusa002成员
8月21日 评论:

你好,已收到问题反馈,分析定位中。

likedislike
Naputao
Naputao
8月24日 评论:

新的最小化测试用例

"""Even smaller reproducer: single tl.dot, N split, minimal dims.

Strips the triangular matrix (uses ones), shrinks M/K to one fractal (16),
keeps only the essential: an [M,K] @ [K,N] matmul whose N is split across
programs (grid.x>1) writing a compact fp32 GM output.
"""
import os
import torch, torch_npu  # noqa: F401
import triton
import triton.language as tl


@triton.jit
def k(a, b, o, N: tl.constexpr, M: tl.constexpr, K: tl.constexpr, BN: tl.constexpr):
    i = tl.program_id(0)
    om = tl.arange(0, M)
    ok = tl.arange(0, K)
    on = i * BN + tl.arange(0, BN)
    a_t = tl.load(a + om[:, None] * K + ok[None, :]).to(tl.float32)
    b_t = tl.load(b + ok[:, None] * N + on[None, :], mask=on[None, :] < N, other=0.0).to(tl.float32)
    o_t = tl.dot(a_t, b_t)
    tl.store(o + om[:, None] * N + on[None, :], o_t, mask=on[None, :] < N)


def main():
    M = int(os.environ.get("M", "16"))
    K = int(os.environ.get("K", "16"))
    N = int(os.environ.get("N", "32"))
    BN = int(os.environ.get("BN", "16"))
    dev = "npu"
    a = torch.randn(M, K, device=dev, dtype=torch.bfloat16)
    b = torch.randn(K, N, device=dev, dtype=torch.bfloat16)
    o = torch.empty(M, N, device=dev, dtype=torch.float)
    grid = (triton.cdiv(N, BN),)
    print(f"REPRO M={M} K={K} N={N} BN={BN} grid.x={grid[0]} split={'YES' if grid[0]>1 else 'NO'}")
    k[grid](a, b, o, N=N, M=M, K=K, BN=BN, num_warps=4, num_stages=2)
    torch.npu.synchronize()
    print("REPRO done")


if __name__ == "__main__":
    main()

运行结果

debian-95-31(@:):workspace# TRITON_DISABLE_LINE_INFO=false mssanitizer python3 A/xpu-ai-stack-hw-npu/mssanitizer/triton/FLA/repro_min2
.py 
=================================================================
                   >>>>>   MindStudio   <<<<<
    THE END-TO-END TOOLCHAIN TO UNLEASH HUAWEI ASCEND COMPUTE
=================================================================

[mssanitizer] logging to file: ./mindstudio_sanitizer_log/mssanitizer_20260824190016_2198342.log
[W824 19:00:17.371394834 FunctionLoader.cpp:48] Warning: LD_PRELOAD detected, FunctionLoader prefers RTLD_DEFAULT for symbol resolution. (function operator())
[mssanitizer] Start memcheck sanitizer on kernel StatelessNormal_9c8573a88cba4fd81bb9851413a4ebba_high_performance_100
[mssanitizer] Sanitizer finished on kernel StatelessNormal_9c8573a88cba4fd81bb9851413a4ebba_high_performance_100. No error detected.
[mssanitizer] Start memcheck sanitizer on kernel StatelessNormal_9c8573a88cba4fd81bb9851413a4ebba_high_performance_100
REPRO M=16 K=16 N=32 BN=16 grid.x=2 split=YES
[mssanitizer] Sanitizer finished on kernel StatelessNormal_9c8573a88cba4fd81bb9851413a4ebba_high_performance_100. No error detected.
[mssanitizer] Start memcheck sanitizer on kernel k
REPRO done
====== WARNING: out of bounds of size 4
======    at 0x12004d798000 on GM when writing data in k
======    in block aic(1) on device 0
======    code in pc current 0x1ac (serialNo:186)
======    #0 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:50:16
======    #1 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:158:52
======    #2 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:263:3
======    #3 /usr1/npuir-a5/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:730:1
======    #4 /workspace/A/xpu-ai-stack-hw-npu/mssanitizer/triton/FLA/repro_min2.py:21:22
======    #5 /workspace/A/xpu-ai-stack-hw-npu/mssanitizer/triton/FLA/repro_min2.py:21:22

[mssanitizer] Sanitizer finished on kernel k. See all detected errors above.
likedislike
went_codewent_code成员
8月26日 将 liusa002 设为负责人
liusa002成员
9月3日 评论:

@Naputao
【结论】非误报,是NPU-IR的实现存在竞争问题,已与NPU-IR同事确认是问题,通过issue 509跟踪。

【分析】out of bounds是指多核踩踏,即多个核访问同一块内存,可能存在数据踩踏,告警等级为WARNING(含义说明见文档),需要结合竞争检测进一步分析。如果多核之间有正确同步,则竞争检测不会报告警,WARNING可忽略;如果缺少同步,则竞争检测会报ERROR,说明确实存在多核踩踏。

使用竞争检测拉起脚本,确实会报ERROR,说明WARNING的结论准确。
竞争检测拉起方式:

export TRITON_ENABLE_SANITIZER=1
export TRITON_ALWAYS_COMPILE=1
export PYTORCH_NO_NPU_MEMORY_CACHING=1
mssanitizer -t racecheck python3 repro_min2.py

out of bounds拉起方式和打屏:
mssanitizer python3 repro_min2.py

====== WARNING: out of bounds of size 4
======    at 0x1201b555e000 on GM when writing data in k
======    in block aic(1) on device 0
======    code in pc current 0x1f0 (serialNo:277)
======    #0 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:42:14
======    #1 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:157:48
======    #2 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:326:3
======    #3 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:846:1
======    #4 /home/triton_test/internal:0:0
======    #5 /home/triton_test/repro_min2.py:21:22

竞争检测打屏(仅截取部分用于展示):

====== ERROR: Potential RAW hazard detected at GM in k:
======    PIPE_S Write at RAW()+0x1201b559e000 in block 0 (aic) on device 0 at pc current 0x1f0 (serialNo:293)
======    #0 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:42:14
======    #1 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:157:48
======    #2 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:326:3
======    #3 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:846:1
======    #4 /home/triton_test/internal:0:0
======    #5 /home/triton_test/repro_min2.py:21:22
======    PIPE_S Read at RAW()+0x1201b559e000 in block 1 (aic) on device 0 at pc current 0x1ac (serialNo:437)
======    #0 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:42:20
======    #1 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:157:48
======    #2 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:326:3
======    #3 /usr1/npuir-a3/bishengir/lib/Template/lib/RegBase/Cube/LocalMmad.cpp:846:1
======    #4 /home/triton_test/internal:0:0
======    #5 /home/triton_test/repro_min2.py:21:22

out of bounds和竞争检测都报在NPU-IR的源码LocalMmad.cpp:42中(调用栈与你的不同,是因为NPU-IR版本不同,bishengir-compile --version可查看版本):

__aicore__ inline uint32_t getL1MmadPingPongId() {
  static uint32_t pingPongId = 1;
  pingPongId = 1 - pingPongId;
  return pingPongId;
}

pingPongId = 1 - pingPongId; <---报在这一行。
static 变量在 .data/.rodata 段上,runtime 会映射到GM。并且runtime 装载二进制的时候不同核的 .text/.data/.rodata 是同一份。pingPongId被声明为static,运行时地址在GM上,不同核访问同一块地址,且硬件不会自动保证跨核的Scalar流水同步。因此认为存在多核踩踏和读写/写写竞争。

likedislike
liusa002成员
9月3日 评论:

/label add resolved

likedislike
ascend-robotascend-robot成员
9月3日 添加了label:resolved
ascend-robot
ascend-robot成员
9月10日 评论:

您好,当前Issue标记为resolved且有一段时间未进一步更新,因此我们将其标记为'stale'(闲置)状态。若您认为这是误操作,可通过添加任意评论来去除'stale'标签。标记为stale的Issue在4天内无更新活动将自动关闭。

likedislike
ascend-robotascend-robot成员
9月10日 添加了label:stale
ascend-robotascend-robot成员
9月14日 关闭了 issue
ascend-robotascend-robot成员
9月14日 issue状态由 TODO 改变为 DONE