Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 118 additions & 20 deletions primus_turbo/pytorch/kernels/activation/geglu_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,31 @@
import torch
import triton

from primus_turbo.triton.activation.bias_geglu_kernel import (
bias_geglu_bwd_kernel,
bias_geglu_fwd_kernel,
bias_geglu_with_mask_bwd_kernel,
bias_geglu_with_mask_fwd_kernel,
)
from primus_turbo.triton.activation.geglu_kernel import (
geglu_bwd_kernel,
geglu_fwd_kernel,
geglu_with_mask_bwd_kernel,
geglu_with_mask_fwd_kernel,
)

MASK_BLOCK_SIZE = 8192

def geglu_fwd_with_probs(x: torch.Tensor, probs: torch.Tensor, row_mask: Optional[torch.Tensor] = None):
num_tokens, double_hidden_size = x.size()

probs = probs.unsqueeze(-1)
# ── Weighted GeGLU (with probs/weights) ──────────────────────────────────────


out = torch.empty(num_tokens, double_hidden_size // 2, dtype=x.dtype, device=x.device)
def geglu_fwd(x: torch.Tensor, probs: torch.Tensor, row_mask: Optional[torch.Tensor] = None):
num_tokens, double_hidden_size = x.size()
probs = probs.unsqueeze(-1)
alloc_fn = torch.zeros if row_mask is not None else torch.empty
out = alloc_fn(num_tokens, double_hidden_size // 2, dtype=x.dtype, device=x.device)
load_width = triton.next_power_of_2(double_hidden_size // 2)

if row_mask is None:
grid = (num_tokens,)
Expand All @@ -34,13 +45,11 @@ def geglu_fwd_with_probs(x: torch.Tensor, probs: torch.Tensor, row_mask: Optiona
stride_x_token=x.stride(0),
stride_probs_token=probs.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=triton.next_power_of_2(double_hidden_size // 2),
LOAD_WIDTH=load_width,
)
else:
assert row_mask.is_cuda, "row_mask must be a CUDA tensor"

BLOCK_SIZE = 8192
grid = (BLOCK_SIZE,)
grid = (MASK_BLOCK_SIZE,)
geglu_with_mask_fwd_kernel[grid](
x,
probs,
Expand All @@ -50,23 +59,24 @@ def geglu_fwd_with_probs(x: torch.Tensor, probs: torch.Tensor, row_mask: Optiona
stride_x_token=x.stride(0),
stride_probs_token=probs.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=triton.next_power_of_2(double_hidden_size // 2),
BLOCK_SIZE=BLOCK_SIZE,
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
)

return out


def geglu_bwd_with_probs(
def geglu_bwd(
grad_out: torch.Tensor,
x: torch.Tensor,
probs: torch.Tensor,
row_mask: Optional[torch.Tensor] = None,
):
num_tokens, hidden_size = grad_out.size()

grad_x = torch.empty_like(x)
grad_probs = torch.empty_like(probs)
alloc_fn = torch.zeros_like if row_mask is not None else torch.empty_like
grad_x = alloc_fn(x)
grad_probs = alloc_fn(probs)
load_width = triton.next_power_of_2(hidden_size)

if row_mask is None:
grid = (num_tokens,)
Expand All @@ -82,13 +92,11 @@ def geglu_bwd_with_probs(
stride_probs_token=probs.stride(0),
stride_grad_x_token=grad_x.stride(0),
stride_grad_probs_token=grad_probs.stride(0),
LOAD_WIDTH=triton.next_power_of_2(hidden_size),
LOAD_WIDTH=load_width,
)
else:
assert row_mask.is_cuda, "row_mask must be a CUDA tensor"

BLOCK_SIZE = 8192
grid = (BLOCK_SIZE,)
grid = (MASK_BLOCK_SIZE,)
geglu_with_mask_bwd_kernel[grid](
grad_out,
x,
Expand All @@ -102,8 +110,98 @@ def geglu_bwd_with_probs(
stride_probs_token=probs.stride(0),
stride_grad_x_token=grad_x.stride(0),
stride_grad_probs_token=grad_probs.stride(0),
LOAD_WIDTH=triton.next_power_of_2(hidden_size),
BLOCK_SIZE=BLOCK_SIZE,
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
)

return grad_x, grad_probs


# ── Bias GeGLU ───────────────────────────────────────────────────────────────


def bias_geglu_fwd(
x: torch.Tensor,
bias: Optional[torch.Tensor] = None,
row_mask: Optional[torch.Tensor] = None,
) -> torch.Tensor:
num_tokens, double_hidden_size = x.size()
alloc_fn = torch.zeros if row_mask is not None else torch.empty
out = alloc_fn(num_tokens, double_hidden_size // 2, dtype=x.dtype, device=x.device)
has_bias = bias is not None
load_width = triton.next_power_of_2(double_hidden_size // 2)

if row_mask is None:
grid = (num_tokens,)
bias_geglu_fwd_kernel[grid](
x,
bias,
out,
num_tokens=num_tokens,
stride_x_token=x.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=load_width,
HAS_BIAS=has_bias,
)
else:
grid = (MASK_BLOCK_SIZE,)
bias_geglu_with_mask_fwd_kernel[grid](
x,
bias,
row_mask,
out,
num_tokens=num_tokens,
stride_x_token=x.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
HAS_BIAS=has_bias,
)

return out


def bias_geglu_bwd(
grad_out: torch.Tensor,
x: torch.Tensor,
bias: Optional[torch.Tensor] = None,
row_mask: Optional[torch.Tensor] = None,
) -> torch.Tensor:
num_tokens, hidden_size = grad_out.size()
alloc_fn = torch.zeros_like if row_mask is not None else torch.empty_like
grad_x = alloc_fn(x)
has_bias = bias is not None
load_width = triton.next_power_of_2(hidden_size)

if row_mask is None:
grid = (num_tokens,)
bias_geglu_bwd_kernel[grid](
grad_out,
x,
bias,
grad_x,
num_tokens=num_tokens,
stride_grad_out_token=grad_out.stride(0),
stride_x_token=x.stride(0),
stride_grad_x_token=grad_x.stride(0),
LOAD_WIDTH=load_width,
HAS_BIAS=has_bias,
)
else:
grid = (MASK_BLOCK_SIZE,)
bias_geglu_with_mask_bwd_kernel[grid](
grad_out,
x,
bias,
row_mask,
grad_x,
num_tokens=num_tokens,
stride_grad_out_token=grad_out.stride(0),
stride_x_token=x.stride(0),
stride_grad_x_token=grad_x.stride(0),
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
HAS_BIAS=has_bias,
)

return grad_x
106 changes: 106 additions & 0 deletions primus_turbo/pytorch/kernels/activation/gelu_impl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
###############################################################################
# Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved.
#
# See LICENSE for license information.
###############################################################################

from typing import Optional

import torch
import triton

from primus_turbo.triton.activation.bias_gelu_kernel import (
bias_gelu_bwd_kernel,
bias_gelu_fwd_kernel,
bias_gelu_with_mask_bwd_kernel,
bias_gelu_with_mask_fwd_kernel,
)

MASK_BLOCK_SIZE = 8192


def bias_gelu_fwd(
x: torch.Tensor,
bias: Optional[torch.Tensor] = None,
row_mask: Optional[torch.Tensor] = None,
) -> torch.Tensor:
num_tokens, hidden_size = x.size()
alloc_fn = torch.zeros_like if row_mask is not None else torch.empty_like
out = alloc_fn(x)
has_bias = bias is not None
load_width = triton.next_power_of_2(hidden_size)
Comment on lines +22 to +30

if row_mask is None:
grid = (num_tokens,)
bias_gelu_fwd_kernel[grid](
x,
bias,
out,
num_tokens=num_tokens,
stride_x_token=x.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=load_width,
HAS_BIAS=has_bias,
)
else:
grid = (MASK_BLOCK_SIZE,)
bias_gelu_with_mask_fwd_kernel[grid](
x,
bias,
row_mask,
out,
num_tokens=num_tokens,
stride_x_token=x.stride(0),
stride_out_token=out.stride(0),
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
HAS_BIAS=has_bias,
)

return out


def bias_gelu_bwd(
grad_out: torch.Tensor,
x: torch.Tensor,
bias: Optional[torch.Tensor] = None,
row_mask: Optional[torch.Tensor] = None,
) -> torch.Tensor:
num_tokens, hidden_size = grad_out.size()
alloc_fn = torch.zeros_like if row_mask is not None else torch.empty_like
grad_x = alloc_fn(x)
has_bias = bias is not None
load_width = triton.next_power_of_2(hidden_size)
Comment on lines +62 to +71

if row_mask is None:
grid = (num_tokens,)
bias_gelu_bwd_kernel[grid](
grad_out,
x,
bias,
grad_x,
num_tokens=num_tokens,
stride_grad_out_token=grad_out.stride(0),
stride_x_token=x.stride(0),
stride_grad_x_token=grad_x.stride(0),
LOAD_WIDTH=load_width,
HAS_BIAS=has_bias,
)
else:
grid = (MASK_BLOCK_SIZE,)
bias_gelu_with_mask_bwd_kernel[grid](
grad_out,
x,
bias,
row_mask,
grad_x,
num_tokens=num_tokens,
stride_grad_out_token=grad_out.stride(0),
stride_x_token=x.stride(0),
stride_grad_x_token=grad_x.stride(0),
LOAD_WIDTH=load_width,
BLOCK_SIZE=MASK_BLOCK_SIZE,
HAS_BIAS=has_bias,
)

return grad_x
Loading
Loading