Skip to content

Commit ef794b3

Browse files
yzw1128Dongxu-H
authored andcommitted
[KernelGen][metax] Add mvlgamma_ vendor specialization with constexpr P optimization (#233)
Co-authored-by: yzw1128 <yzw1128@users.noreply.github.com> Co-authored-by: Dongxu-H <dxhan@baai.ac.cn>
1 parent 21dd87c commit ef794b3

2 files changed

Lines changed: 104 additions & 0 deletions

File tree

src/flag_gems/runtime/backend/_metax/ops/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .matmul_int8 import matmul_int8
2929
from .min import min, min_dim
3030
from .mm import mm, mm_out
31+
from .mvlgamma_ import mvlgamma_
3132
from .new_ones import new_ones
3233
from .nonzero import nonzero
3334
from .nonzero_numpy import nonzero_numpy
@@ -88,6 +89,7 @@
8889
"masked_fill_",
8990
"min_dim",
9091
"min",
92+
"mvlgamma_",
9193
"mm",
9294
"mm_out",
9395
"new_ones",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Copyright 2026, The FlagOS Contributors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License")
4+
# you may not use this file except in compliance with the License
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# Generated by KernelGen: https://github.com/flagos-ai/KernelGen
16+
17+
import logging
18+
19+
import torch
20+
import triton
21+
import triton.language as tl
22+
23+
from flag_gems.runtime import torch_device_fn
24+
from flag_gems.utils import tl_extra_shim
25+
26+
logger = logging.getLogger(__name__)
27+
28+
29+
@triton.jit
30+
def mvlgamma_kernel(
31+
x_ptr,
32+
n_elements,
33+
BLOCK_SIZE: tl.constexpr,
34+
P: tl.constexpr,
35+
):
36+
"""Muxi-optimized 1D kernel for mvlgamma_.
37+
38+
P is a tl.constexpr so the Triton compiler generates only the
39+
needed number of lgamma calls via tl.static_range(P), eliminating
40+
dead computation for small p values.
41+
"""
42+
pid = tl.program_id(0)
43+
block_start = pid * BLOCK_SIZE
44+
offsets = block_start + tl.arange(0, BLOCK_SIZE)
45+
mask = offsets < n_elements
46+
47+
x = tl.load(x_ptr + offsets, mask=mask, other=0.0)
48+
x_f32 = x.to(tl.float32)
49+
50+
LOG_PI = 1.1447298858494002
51+
LOG_PI_OVER_4 = LOG_PI / 4.0
52+
constant_term = P * (P - 1) * LOG_PI_OVER_4
53+
54+
# Compile-time loop: exactly P iterations, zero dead lgamma calls.
55+
sum_term = tl.zeros_like(x_f32)
56+
for k in tl.static_range(P):
57+
sum_term += tl_extra_shim.lgamma(x_f32 - 0.5 * k)
58+
59+
result = constant_term + sum_term
60+
tl.store(x_ptr + offsets, result.to(x.dtype), mask=mask)
61+
62+
63+
def mvlgamma_(*args, **kwargs):
64+
"""In-place multivariate log-gamma function, optimized for Metax GPUs.
65+
66+
Uses a hand-crafted 1D contiguous Triton kernel with P as a
67+
constexpr, so the compiler generates exactly p lgamma calls per
68+
element with zero dead-code overhead.
69+
"""
70+
logger.debug("GEMS_METAX MVLGAMMA_")
71+
72+
x = args[0]
73+
p = args[1] if len(args) > 1 else kwargs.get("p", 1)
74+
75+
if not isinstance(x, torch.Tensor):
76+
raise TypeError("mvlgamma_ expects a torch.Tensor as the first argument")
77+
78+
if not isinstance(p, int) or p < 1:
79+
raise ValueError("p must be a positive integer")
80+
81+
if p > 12:
82+
raise ValueError("p must be <= 12 for this implementation")
83+
84+
n_elements = x.numel()
85+
if n_elements == 0:
86+
return x
87+
88+
# For non-contiguous tensors, create a contiguous copy, operate on
89+
# it, and copy back to preserve in-place semantics.
90+
if not x.is_contiguous():
91+
y = x.contiguous()
92+
grid = (triton.cdiv(n_elements, 1024),)
93+
with torch_device_fn.device(y.device):
94+
mvlgamma_kernel[grid](y, n_elements, BLOCK_SIZE=1024, P=p)
95+
x.copy_(y)
96+
return x
97+
98+
grid = (triton.cdiv(n_elements, 1024),)
99+
with torch_device_fn.device(x.device):
100+
mvlgamma_kernel[grid](x, n_elements, BLOCK_SIZE=1024, P=p)
101+
102+
return x

0 commit comments

Comments
 (0)