submission 99078
Petr_Rocoss · python · License unknown
Use it
Vendorable · source mirrored · license unknownView source →
No package. Vendor the mirrored source: 150 lines, June 9 Researcher Reciprocity License v1.0.
submission_elite_v1.py
curl "https://kernelindex.com/api/v1/implementations/kernelbot-conv2d-v2-99078?include=source"interfacepython
Compatibility
measured onNVIDIA A100
declared hardwareNVIDIA A100
architecturessm_80
dtypesfp32
Benchmark evidence
1 measurement across 1 GPU, fastest first.
Operation / workload
Hardware
Latency
Rank
Observed
Reported · How evidence levels are derived →
Source and license
sourceavailable
revision digestsha256:c635057b13b820abc88749a6333c3b59afe7298c35b0a6314ac1e36d968eb3cd
license declaredunknown
license concludedunknown
authorsPetr_Rocoss
imported2026-08-15
Techniques
Extracted from the mirrored source by pattern, never inferred. Each row cites its line.
autotune
@triton.autotune(num-warps = 8
triton.Config({'BLOCK_H': 4, 'BLOCK_W': 128}, num_warps=8, num_stages=4),stages = 4
triton.Config({'BLOCK_H': 4, 'BLOCK_W': 128}, num_warps=8, num_stages=4),Kernel source
submission_elite_v1.py150 lines
import torch
import triton
import triton.language as tl
# Добавляем BLOCK_H в конфигурации автотюнинга
@triton.autotune(
configs=[
# Конфигурации для больших тензоров (A100/H100)
triton.Config({'BLOCK_H': 4, 'BLOCK_W': 128}, num_warps=8, num_stages=4),
triton.Config({'BLOCK_H': 8, 'BLOCK_W': 64}, num_warps=8, num_stages=4),
triton.Config({'BLOCK_H': 2, 'BLOCK_W': 256}, num_warps=8, num_stages=3),
# Конфигурации для средних размеров / L4
triton.Config({'BLOCK_H': 4, 'BLOCK_W': 64}, num_warps=4, num_stages=4),
triton.Config({'BLOCK_H': 2, 'BLOCK_W': 128}, num_warps=4, num_stages=4),
# Fallback для маленьких размеров
triton.Config({'BLOCK_H': 1, 'BLOCK_W': 32}, num_warps=2, num_stages=2),
],
key=['W_OUT', 'H_OUT', 'C_IN', 'K'],
)
@triton.jit
def conv2d_kernel_tiled(
input_ptr, weight_ptr, output_ptr,
stride_in_n, stride_in_c, stride_in_h, stride_in_w,
stride_w_out, stride_w_in, stride_w_h, stride_w_w,
stride_out_n, stride_out_c, stride_out_h, stride_out_w,
H_IN, W_IN, H_OUT, W_OUT, C_IN, C_OUT, K,
BLOCK_H: tl.constexpr, BLOCK_W: tl.constexpr
):
"""
Супер-оптимизированное ядро с 2D-блокировкой (H x W).
Обрабатывает прямоугольный тайл выхода за один раз.
"""
# Grid IDs
pid_w = tl.program_id(0)
pid_h = tl.program_id(1)
pid_z = tl.program_id(2)
# Декодируем Batch и Output Channel
batch_idx = pid_z // C_OUT
out_ch = pid_z % C_OUT
# --- 1. Координаты и маски (2D) ---
# Output Height offsets: [BLOCK_H, 1]
offs_h = pid_h * BLOCK_H + tl.arange(0, BLOCK_H)
mask_h = offs_h < H_OUT
# Output Width offsets: [1, BLOCK_W]
offs_w = pid_w * BLOCK_W + tl.arange(0, BLOCK_W)
mask_w = offs_w < W_OUT
# --- 2. Базовые указатели ---
# Указатель на начало Output для текущего Batch/Channel
# output[b, c, h, w] -> используем 2D broadcasting для записи
dst_base = output_ptr + batch_idx * stride_out_n + out_ch * stride_out_c
# Указатель на начало Input для текущего Batch
# Input: [batch, cin, h, w]
src_base = input_ptr + batch_idx * stride_in_n
# Указатель на начало Weights для текущего Out Channel
# Weight: [cout, cin, kh, kw]
wei_base = weight_ptr + out_ch * stride_w_out
# --- 3. Аккумулятор (Register File) ---
# Теперь это 2D массив [BLOCK_H, BLOCK_W]
acc = tl.zeros([BLOCK_H, BLOCK_W], dtype=tl.float32)
# --- 4. Основной цикл ---
for cin in range(C_IN):
# Сдвигаем указатели на текущий входной канал
src_ch = src_base + cin * stride_in_c
wei_ch = wei_base + cin * stride_w_in
for kh in range(K):
# Pre-calc смещения по вертикали для входа
# Input H index = (offs_h + kh)
# Broadcasting: (BLOCK_H, 1)
curr_h_in = offs_h[:, None] + kh
src_row_ptr = src_ch + curr_h_in * stride_in_h
# Смещение веса по высоте
wei_row_ptr = wei_ch + kh * stride_w_h
for kw in range(K):
# --- A. Загрузка Веса (Scalar broadcast) ---
# Загружаем 1 скаляр, используем для всего блока [BLOCK_H, BLOCK_W]
wei_val = tl.load(wei_row_ptr + kw * stride_w_w)
# --- B. Загрузка Входа (2D Block Load) ---
# Input W index = (offs_w + kw)
# Ptr = src_row_ptr (зависит от H) + (W смещение)
# Размерность: [BLOCK_H, 1] + [1, BLOCK_W] -> [BLOCK_H, BLOCK_W]
src_ptrs = src_row_ptr + (offs_w[None, :] + kw) * stride_in_w
# Маска: проверяем валидность H (выхода) и W (выхода)
# Примечание: padding=0, stride=1 гарантируют, что если output внутри границ,
# то input (out + k) тоже внутри границ (при валидных размерах тензоров).
# Используем комбинированную маску mask_h & mask_w
val_in = tl.load(src_ptrs, mask=(mask_h[:, None] & mask_w[None, :]), other=0.0)
# --- C. FMA ---
acc = acc + val_in * wei_val
# --- 5. Запись результата ---
# Output Ptr: dst_base + h * stride_h + w * stride_w
offs_out = dst_base + offs_h[:, None] * stride_out_h + offs_w[None, :] * stride_out_w
tl.store(offs_out, acc, mask=(mask_h[:, None] & mask_w[None, :]))
def custom_kernel(data):
input_tensor, kernel, output_tensor = data
# Обеспечиваем memory layout
if not input_tensor.is_contiguous():
input_tensor = input_tensor.contiguous()
if not kernel.is_contiguous():
kernel = kernel.contiguous()
batch, c_in, h_in, w_in = input_tensor.shape
c_out, _, k_h, k_w = kernel.shape
h_out = h_in - k_h + 1
w_out = w_in - k_w + 1
# Grid Calculation
# X: Тайлы по ширине
# Y: Тайлы по высоте (теперь делим на BLOCK_H!)
# Z: Batch * OutChannels
grid = lambda META: (
triton.cdiv(w_out, META['BLOCK_W']),
triton.cdiv(h_out, META['BLOCK_H']),
batch * c_out
)
conv2d_kernel_tiled[grid](
input_tensor, kernel, output_tensor,
*input_tensor.stride(),
*kernel.stride(),
*output_tensor.stride(),
h_in, w_in, h_out, w_out,
c_in, c_out, k_h,
)
return output_tensor
scrolls · 150 lines total
Source code from GPU Mode and the KernelBot dataset · June 9 Researcher Reciprocity License v1.0
Changes from previous submission
Against this author's previous submission submission 99066.
⋯ 1 unchanged linesimport tritonimport triton.language as tl+ # Добавляем BLOCK_H в конфигурации автотюнинга@triton.autotune(configs=[- # Оптимизировано для A100/H100/B200/L4- triton.Config({'BLOCK_H': 2, 'BLOCK_W': 128}, num_warps=8, num_stages=3),- triton.Config({'BLOCK_H': 4, 'BLOCK_W': 64}, num_warps=8, num_stages=4),- triton.Config({'BLOCK_H': 1, 'BLOCK_W': 256}, num_warps=8, num_stages=2),- triton.Config({'BLOCK_H': 8, 'BLOCK_W': 32}, num_warps=4, num_stages=5),+ # Конфигурации для больших тензоров (A100/H100)+ triton.Config({'BLOCK_H': 4, 'BLOCK_W': 128}, num_warps=8, num_stages=4),+ triton.Config({'BLOCK_H': 8, 'BLOCK_W': 64}, num_warps=8, num_stages=4),+ triton.Config({'BLOCK_H': 2, 'BLOCK_W': 256}, num_warps=8, num_stages=3),++ # Конфигурации для средних размеров / L4+ triton.Config({'BLOCK_H': 4, 'BLOCK_W': 64}, num_warps=4, num_stages=4),+ triton.Config({'BLOCK_H': 2, 'BLOCK_W': 128}, num_warps=4, num_stages=4),++ # Fallback для маленьких размеров+ triton.Config({'BLOCK_H': 1, 'BLOCK_W': 32}, num_warps=2, num_stages=2),],- key=['H_OUT', 'W_OUT', 'C_IN', 'K'],+ key=['W_OUT', 'H_OUT', 'C_IN', 'K'],)@triton.jit- def conv2d_kernel(+ def conv2d_kernel_tiled(input_ptr, weight_ptr, output_ptr,stride_in_n, stride_in_c, stride_in_h, stride_in_w,stride_w_out, stride_w_in, stride_w_h, stride_w_w,⋯ 1 unchanged linesH_IN, W_IN, H_OUT, W_OUT, C_IN, C_OUT, K,BLOCK_H: tl.constexpr, BLOCK_W: tl.constexpr):- """Оптимизированное ядро Conv2D с 2D тайлингом."""+ """+ Супер-оптимизированное ядро с 2D-блокировкой (H x W).+ Обрабатывает прямоугольный тайл выхода за один раз.+ """- # --- Позиция выходного тайла ---+ # Grid IDspid_w = tl.program_id(0)pid_h = tl.program_id(1)pid_z = tl.program_id(2)+ # Декодируем Batch и Output Channelbatch_idx = pid_z // C_OUTout_ch = pid_z % C_OUT- # Стартовые позиции тайла [BLOCK_H, BLOCK_W]- h_start = pid_h * BLOCK_H- w_start = pid_w * BLOCK_W+ # --- 1. Координаты и маски (2D) ---- # Индексы с правильными формами для broadcasting- h_offs = tl.arange(0, BLOCK_H)[:, None] # [BLOCK_H, 1]- w_offs = tl.arange(0, BLOCK_W)[None, :] # [1, BLOCK_W]+ # Output Height offsets: [BLOCK_H, 1]+ offs_h = pid_h * BLOCK_H + tl.arange(0, BLOCK_H)+ mask_h = offs_h < H_OUT- # Маски для граничных тайлов (обе размерности!)- h_mask = (h_start + h_offs) < H_OUT- w_mask = (w_start + w_offs) < W_OUT- tile_mask = h_mask & w_mask # [BLOCK_H, BLOCK_W]+ # Output Width offsets: [1, BLOCK_W]+ offs_w = pid_w * BLOCK_W + tl.arange(0, BLOCK_W)+ mask_w = offs_w < W_OUT- # --- Базовые указатели ---- out_base = output_ptr + batch_idx * stride_out_n + out_ch * stride_out_c- in_base = input_ptr + batch_idx * stride_in_n+ # --- 2. Базовые указатели ---++ # Указатель на начало Output для текущего Batch/Channel+ # output[b, c, h, w] -> используем 2D broadcasting для записи+ dst_base = output_ptr + batch_idx * stride_out_n + out_ch * stride_out_c++ # Указатель на начало Input для текущего Batch+ # Input: [batch, cin, h, w]+ src_base = input_ptr + batch_idx * stride_in_n++ # Указатель на начало Weights для текущего Out Channel+ # Weight: [cout, cin, kh, kw]wei_base = weight_ptr + out_ch * stride_w_out- # Аккумулятор [BLOCK_H, BLOCK_W]+ # --- 3. Аккумулятор (Register File) ---+ # Теперь это 2D массив [BLOCK_H, BLOCK_W]acc = tl.zeros([BLOCK_H, BLOCK_W], dtype=tl.float32)- # --- Основной цикл свертки ---- # cin (внешний) -> kh -> kw для максимальной локальности- for cin in tl.range(0, C_IN, num_stages=3):- in_c_ptr = in_base + cin * stride_in_c- wei_c_ptr = wei_base + cin * stride_w_in+ # --- 4. Основной цикл ---+ for cin in range(C_IN):+ # Сдвигаем указатели на текущий входной канал+ src_ch = src_base + cin * stride_in_c+ wei_ch = wei_base + cin * stride_w_infor kh in range(K):- # Сдвиг по высоте для входа- in_h_ptr = in_c_ptr + (h_start + h_offs + kh) * stride_in_h+ # Pre-calc смещения по вертикали для входа+ # Input H index = (offs_h + kh)+ # Broadcasting: (BLOCK_H, 1)+ curr_h_in = offs_h[:, None] + kh+ src_row_ptr = src_ch + curr_h_in * stride_in_h+ # Смещение веса по высоте+ wei_row_ptr = wei_ch + kh * stride_w_h+for kw in range(K):- # Вес (скаляр, broadcasted автоматически)- wei = tl.load(wei_c_ptr + kh * stride_w_h + kw * stride_w_w)+ # --- A. Загрузка Веса (Scalar broadcast) ---+ # Загружаем 1 скаляр, используем для всего блока [BLOCK_H, BLOCK_W]+ wei_val = tl.load(wei_row_ptr + kw * stride_w_w)- # Загрузка тайла входа [BLOCK_H, BLOCK_W]- # Позиция: (out_h + kh, out_w + kw)- in_ptrs = in_h_ptr + (w_start + w_offs + kw) * stride_in_w- in_tile = tl.load(in_ptrs, mask=tile_mask, other=0.0)+ # --- B. Загрузка Входа (2D Block Load) ---+ # Input W index = (offs_w + kw)+ # Ptr = src_row_ptr (зависит от H) + (W смещение)+ # Размерность: [BLOCK_H, 1] + [1, BLOCK_W] -> [BLOCK_H, BLOCK_W]+ src_ptrs = src_row_ptr + (offs_w[None, :] + kw) * stride_in_w- # FMA- acc += in_tile * wei-- # --- Запись результата ---- out_ptrs = out_base + (h_start + h_offs) * stride_out_h + (w_start + w_offs) * stride_out_w- tl.store(out_ptrs, acc, mask=tile_mask)+ # Маска: проверяем валидность H (выхода) и W (выхода)+ # Примечание: padding=0, stride=1 гарантируют, что если output внутри границ,+ # то input (out + k) тоже внутри границ (при валидных размерах тензоров).+ # Используем комбинированную маску mask_h & mask_w+ val_in = tl.load(src_ptrs, mask=(mask_h[:, None] & mask_w[None, :]), other=0.0)++ # --- C. FMA ---+ acc = acc + val_in * wei_val+ # --- 5. Запись результата ---+ # Output Ptr: dst_base + h * stride_h + w * stride_w+ offs_out = dst_base + offs_h[:, None] * stride_out_h + offs_w[None, :] * stride_out_w+ tl.store(offs_out, acc, mask=(mask_h[:, None] & mask_w[None, :]))+def custom_kernel(data):- """Обертка для запуска ядра."""input_tensor, kernel, output_tensor = data- # Гарантируем контигуозность- input_tensor = input_tensor.contiguous()- kernel = kernel.contiguous()- output_tensor = output_tensor.contiguous()+ # Обеспечиваем memory layout+ if not input_tensor.is_contiguous():+ input_tensor = input_tensor.contiguous()+ if not kernel.is_contiguous():+ kernel = kernel.contiguous()batch, c_in, h_in, w_in = input_tensor.shape- c_out, _, k_h, _ = kernel.shape+ c_out, _, k_h, k_w = kernel.shape- # Выходные размерыh_out = h_in - k_h + 1- w_out = w_in - k_h + 1+ w_out = w_in - k_w + 1- # Grid: (width_blocks, height_blocks, batch*C_out)+ # Grid Calculation+ # X: Тайлы по ширине+ # Y: Тайлы по высоте (теперь делим на BLOCK_H!)+ # Z: Batch * OutChannelsgrid = lambda META: (triton.cdiv(w_out, META['BLOCK_W']),triton.cdiv(h_out, META['BLOCK_H']),batch * c_out)- # Запуск- conv2d_kernel[grid](+ conv2d_kernel_tiled[grid](input_tensor, kernel, output_tensor,*input_tensor.stride(),*kernel.stride(),
scrolls · 196 diff lines total
Best evidence level for this revision: reported
JSON