一键导入
triton-ascend-case-reduction-amin-atomic
原子操作归约(amin)优化:非reduce轴很小时将reduce轴映射多核,提供循环内/外两种原子操作方案(减少存储vs减少竞争),通过二次切分+计算重组提升性能,适用于M<<N(如16×262144)的极端shape比例场景
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
原子操作归约(amin)优化:非reduce轴很小时将reduce轴映射多核,提供循环内/外两种原子操作方案(减少存储vs减少竞争),通过二次切分+计算重组提升性能,适用于M<<N(如16×262144)的极端shape比例场景
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
矩阵乘法矩阵乘法 A[M, K] @ B[K, N] = C[M, N]中,大K维度矩阵乘法(K>>M,N)优化:针对M/N较小但K极大(如M=N=256,K=131072)的场景,Split-K切分K维度并行化、Workspace+Reduce替代全局同步,实现显著性能提升
Triton Ascend hard API restrictions and forbidden syntax. MUST-follow rules that apply to every kernel: forbidden control flow (return/break/continue/lambda/while), tensor slice/index restrictions, scalar conversion rules, BLOCK_SIZE upper bound. Violating any of these produces a compile or runtime error on Ascend.
Triton Ascend 性能优化通用策略: BLOCK_SIZE 选择 (1024-2048 for elementwise, must be <65536), grid configuration (use VEC_CORE_NUM / CUBE_CORE_NUM, 2D/3D grid for matmul / conv / reduce, 1D grid + inner loop for elementwise / pointwise), 256B alignment for memory transfers, autotune block-size patterns, fp16 / fp32 precision conversion. Bind via keywords like matmul, elementwise, reduce, block_size, grid, autotune, alignment, fp16, fp32, tile, interleaved-loop, cube-core, vec-core.
通过 adaptive_search 或 evolve 搜索式 workflow 生成优化算子。 后台 silent mode 执行,轮询监控进度。
适用于归约(reduce)类算子和含归约子步骤的复合算子(如归一化)的优化指南。典型算子包括:sum, mean, max, min, prod, argmax, argmin, cumsum, cumprod, softmax, logsoftmax, layernorm, rmsnorm, groupnorm, instancenorm, batchnorm, l1norm, l2norm, frobeniusnorm, var, std, average_pooling, sum_pooling 等。特别重要:当归约维度不是最后一维(如 dim=1 归约 shape=[B,F,D1,D2]),需要正确处理多维索引和两阶段归约。包含 PyTorch normalized_shape 多轴归一化语义说明。不适用于纯逐元素运算或矩阵乘法。如果算子是损失函数(先逐元素计算再全局归约),应选择 elementwise-reduce-fused 指南。
CPU C++ 算子核心概念、标准结构模式、KernelBench 代码规范和内嵌扩展方法
| name | triton-ascend-case-reduction-amin-atomic |
| description | 原子操作归约(amin)优化:非reduce轴很小时将reduce轴映射多核,提供循环内/外两种原子操作方案(减少存储vs减少竞争),通过二次切分+计算重组提升性能,适用于M<<N(如16×262144)的极端shape比例场景 |
| category | case |
| version | 1.0.0 |
| metadata | {"backend":"ascend","dsl":"triton_ascend","hardware":"Atlas A2, Atlas A3"} |
# 简单方式:非reduce轴映射多核
grid = lambda meta: (triton.cdiv(M, meta['BLOCK_SIZE_M']),)
# 错误:优化方式:reduce轴映射多核
grid = lambda meta: (triton.cdiv(N, meta['BLOCK_SIZE_N']),)
# Kernel内对列进行二次切分
for n_start in range(0, BLOCK_SIZE_N, SUB_BLOCK_SIZE_N):
n_offsets = pid * BLOCK_SIZE_N + n_start + tl.arange(0, SUB_BLOCK_SIZE_N)
# 简单方式:循环内多次归约
row_min = float('inf')
for n_start in range(0, BLOCK_SIZE_N, SUB_BLOCK_SIZE_N):
错误:curr_min = tl.min(data_block, 1)
row_min = tl.minimum(curr_min, row_min)
# 正确:优化方式:维护矩阵结构
curr_min = tl.full((BLOCK_SIZE_M, SUB_BLOCK_SIZE_N), float('inf'), dtype=tl.float32)
for n_start in range(0, BLOCK_SIZE_N, SUB_BLOCK_SIZE_N):
curr_min = tl.minimum(data_block, curr_min)
row_min = tl.min(curr_min, 1)
for m_start in range(0, M, BLOCK_SIZE_M):
m_offsets = m_start + tl.arange(0, BLOCK_SIZE_M)
mmask = m_offsets < M
curr_min = tl.full((BLOCK_SIZE_M, SUB_BLOCK_SIZE_N), float('inf'), dtype=tl.float32)
for n_start in range(0, BLOCK_SIZE_N, SUB_BLOCK_SIZE_N):
n_offsets = pid * BLOCK_SIZE_N + n_start + tl.arange(0, SUB_BLOCK_SIZE_N)
nmask = n_offsets < N
mask = (mmask[:, None]) & (nmask[None, :])
block_ptrs = in_ptr0 + m_offsets[:,None] * in_stride0 + n_offsets[None,:] * in_stride1
data_block = tl.load(block_ptrs, mask=mask, other=float('inf'))
curr_min = tl.minimum(data_block, curr_min)
row_min = tl.min(curr_min, 1)
output_ptrs = out_ptr0 + m_offsets * out_stride0
tl.atomic_min(output_ptrs, row_min, mask=mmask) # 每块立即原子操作
特点:
all_row_min = tl.full((M,), float('inf'), dtype=tl.float32) # 预分配完整数组
for m_start in range(0, M, BLOCK_SIZE_M):
m_offsets = m_start + tl.arange(0, BLOCK_SIZE_M)
mmask = m_offsets < M
curr_min = tl.full((BLOCK_SIZE_M, SUB_BLOCK_SIZE_N), float('inf'), dtype=tl.float32)
for n_start in range(0, BLOCK_SIZE_N, SUB_BLOCK_SIZE_N):
n_offsets = pid * BLOCK_SIZE_N + n_start + tl.arange(0, SUB_BLOCK_SIZE_N)
nmask = n_offsets < N
mask = (mmask[:, None]) & (nmask[None, :])
block_ptrs = in_ptr0 + m_offsets[:,None] * in_stride0 + n_offsets[None,:] * in_stride1
data_block = tl.load(block_ptrs, mask=mask, other=float('inf'))
curr_min = tl.minimum(data_block, curr_min)
row_min = tl.min(curr_min, 1)
curr_block_size_m = tl.minimum(BLOCK_SIZE_M, M - m_start)
all_row_min = tl.insert_slice(all_row_min, row_min, [m_start], [curr_block_size_m], [1]) # 暂存中间结果
output_ptrs = out_ptr0 + tl.arange(0, M) * out_stride0
tl.atomic_min(output_ptrs, all_row_min) # 最后统一原子操作
特点:
@triton.autotune(
configs=[
# (AI core=40)
# grid=32<40, UB用满
triton.Config({'BLOCK_SIZE_M': 8, 'BLOCK_SIZE_N': 8192, 'SUB_BLOCK_SIZE_N': 1024}), # M切分较小,UB用满
triton.Config({'BLOCK_SIZE_M': 16, 'BLOCK_SIZE_N': 8192, 'SUB_BLOCK_SIZE_N': 512}), # M切分调大至16,N的SUB切分调小至512,防止超UB
],
key=[...],
restore_value=['out_ptr0'], # autotune 必须加 restore_value
)