一键导入
triton-cuda-elementwise
逐元素算子(element-wise)优化策略,包括 add/mul/relu/sigmoid/tanh/gelu/exp/log 等操作的向量化实现和融合技巧。适用于实现激活函数、逐元素运算、广播操作等向量模式算子的 CUDA 内核代码生成场景
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
逐元素算子(element-wise)优化策略,包括 add/mul/relu/sigmoid/tanh/gelu/exp/log 等操作的向量化实现和融合技巧。适用于实现激活函数、逐元素运算、广播操作等向量模式算子的 CUDA 内核代码生成场景
用 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-cuda-elementwise |
| description | 逐元素算子(element-wise)优化策略,包括 add/mul/relu/sigmoid/tanh/gelu/exp/log 等操作的向量化实现和融合技巧。适用于实现激活函数、逐元素运算、广播操作等向量模式算子的 CUDA 内核代码生成场景 |
| category | implementation |
| version | 1.0.0 |
| metadata | {"backend":"cuda","dsl":"triton_cuda","operator_patterns":"elementwise","algorithms":"add, mul, relu, sigmoid, tanh, gelu, exp, log, div, sub, sqrt, pow"} |
适用于逐元素独立计算的算子
算术运算: add, mul, div, sub, pow
激活函数: relu, sigmoid, tanh(需用 tl.extra.cuda.libdevice.tanh), gelu, silu, swish
数学函数: exp, log, sqrt, sin, cos, abs
张量在内存中连续存储时,可用一维指针遍历,避免多维索引开销。
方案 1: 转连续 + 一维访问(推荐)
class ModelNew(torch.nn.Module):
def __init__(self):
super().__init__()
def forward(self, input_tensor):
# 非连续张量转为连续(一次性开销)
if not input_tensor.is_contiguous():
input_tensor = input_tensor.contiguous()
output_tensor = torch.empty_like(input_tensor)
n_elements = input_tensor.numel()
grid = (triton.cdiv(n_elements, BLOCK_SIZE),)
elementwise_kernel[grid](input_tensor, output_tensor, n_elements, BLOCK_SIZE)
return output_tensor
@triton.jit
def elementwise_kernel(input_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
data = tl.load(input_ptr + offsets, mask=mask)
result = compute(data) # 你的计算逻辑
tl.store(output_ptr + offsets, result, mask=mask)
优势:
.contiguous() 一次性开销 vs stride 每次访问都有开销方案 2: 使用 stride 访问(不推荐)
仅当无法调用 .contiguous() 时使用。
Element-wise 算子通常使用较少的 warp:
@triton.autotune(
configs=[
triton.Config({'BLOCK_SIZE': 1024}, num_warps=4),
triton.Config({'BLOCK_SIZE': 512}, num_warps=2),
triton.Config({'BLOCK_SIZE': 2048}, num_warps=8),
],
key=['n_elements'],
restore_value=['output_ptr'], # 必须:列出所有输出指针参数名
)
@triton.jit
def optimized_kernel(input_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
data = tl.load(input_ptr + offsets, mask=mask)
result = compute(data)
tl.store(output_ptr + offsets, result, mask=mask)
当输入 shape 很大时,确保有足够的 block 来覆盖所有元素:
@triton.jit
def large_elementwise_kernel(
input_ptr, output_ptr, n_elements,
BLOCK_SIZE: tl.constexpr,
):
pid = tl.program_id(0)
num_pids = tl.num_programs(0)
# 每个程序处理多个块(grid stride loop)
for block_start in range(pid * BLOCK_SIZE, n_elements, num_pids * BLOCK_SIZE):
offsets = block_start + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
data = tl.load(input_ptr + offsets, mask=mask)
result = compute(data)
tl.store(output_ptr + offsets, result, mask=mask)
# 启动:限制 Grid 大小
num_blocks = min(triton.cdiv(n_elements, BLOCK_SIZE), 65535)
grid = (num_blocks,)
large_elementwise_kernel[grid](input_tensor, output_tensor, n_elements, BLOCK_SIZE=1024)
对于简单的 element-wise 算子,可以通过更大的 BLOCK_SIZE 来增加每个线程的工作量,提高计算密度:
@triton.jit
def vectorized_kernel(input_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
# 更大的 BLOCK_SIZE 允许编译器进行更好的向量化
data = tl.load(input_ptr + offsets, mask=mask)
result = tl.maximum(data, 0.0) # ReLU
tl.store(output_ptr + offsets, result, mask=mask)
import torch
import triton
import triton.language as tl
@triton.jit
def relu_kernel(input_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
data = tl.load(input_ptr + offsets, mask=mask)
result = tl.maximum(data, 0.0)
tl.store(output_ptr + offsets, result, mask=mask)
class ModelNew(torch.nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
if not x.is_contiguous():
x = x.contiguous()
output = torch.empty_like(x)
n_elements = x.numel()
BLOCK_SIZE = 1024
grid = (triton.cdiv(n_elements, BLOCK_SIZE),)
relu_kernel[grid](x, output, n_elements, BLOCK_SIZE)
return output
import torch
import triton
import triton.language as tl
import math
@triton.jit
def gelu_kernel(input_ptr, output_ptr, n_elements, BLOCK_SIZE: tl.constexpr):
pid = tl.program_id(0)
offsets = pid * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
x = tl.load(input_ptr + offsets, mask=mask)
# GELU(x) = 0.5 * x * (1 + tanh(sqrt(2/pi) * (x + 0.044715 * x^3)))
x_cubed = x * x * x
inner = 0.7978845608 * (x + 0.044715 * x_cubed) # sqrt(2/pi) ≈ 0.7978845608
result = 0.5 * x * (1.0 + tl.extra.cuda.libdevice.tanh(inner))
tl.store(output_ptr + offsets, result, mask=mask)
class ModelNew(torch.nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
if not x.is_contiguous():
x = x.contiguous()
output = torch.empty_like(x)
n_elements = x.numel()
grid = (triton.cdiv(n_elements, 1024),)
gelu_kernel[grid](x, output, n_elements, BLOCK_SIZE=1024)
return output