Skip to content

Commit ed4625e

Browse files
committed
[KernelGen][MThreads] Add functional_sym_constrain_range_for_size Moore Threads specialized operator
1 parent b44d2fd commit ed4625e

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
from .erfinv_ import erfinv_
3838
from .flip import flip
3939
from .fmod_ import fmod_, fmod_scalar_, fmod_tensor_
40+
from .functional_sym_constrain_range_for_size import (
41+
_functional_sym_constrain_range_for_size,
42+
)
4043
from .gather import gather, gather_backward
4144
from .histc import histc
4245
from .im2col import im2col
@@ -95,6 +98,7 @@
9598
from .zeros_like import zeros_like
9699

97100
__all__ = [
101+
"_functional_sym_constrain_range_for_size",
98102
"amax",
99103
"all",
100104
"all_dim",
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Copyright 2026 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+
import logging
16+
17+
import torch
18+
import triton
19+
import triton.language as tl
20+
21+
from flag_gems.ops._functional_sym_constrain_range_for_size import (
22+
_functional_sym_constrain_range_for_size as default__functional_sym_constrain_range_for_size,
23+
)
24+
from flag_gems.runtime import torch_device_fn
25+
from flag_gems.utils import libentry
26+
27+
logger = logging.getLogger(
28+
f'flag_gems.runtime.backend._mthreads.ops.{__name__.split(".")[-1]}'
29+
)
30+
31+
_SUPPORTED_DTYPES = {torch.float16, torch.bfloat16, torch.float32}
32+
33+
34+
@triton.jit
35+
def _copy_kernel(
36+
src_ptr,
37+
dst_ptr,
38+
n_elements,
39+
BLOCK_SIZE: tl.constexpr,
40+
):
41+
pid = tl.program_id(0)
42+
num_progs = tl.num_programs(0)
43+
first = pid * BLOCK_SIZE
44+
step = num_progs * BLOCK_SIZE
45+
for off in range(first, n_elements, step):
46+
offsets = off + tl.arange(0, BLOCK_SIZE)
47+
mask = offsets < n_elements
48+
val = tl.load(src_ptr + offsets, mask=mask, eviction_policy="evict_first")
49+
tl.store(dst_ptr + offsets, val, mask=mask, eviction_policy="evict_first")
50+
51+
52+
# Element-size-specialized tile configs (probed on MTT S5000):
53+
# 2-byte types (fp16/bf16) peak with 4096-elem/4-warp tiles; 4-byte types
54+
# (fp32) peak with 2048-elem/4-warp tiles. Large copies use a persistent
55+
# grid-stride launch capped at _MAX_BLOCKS to amortize block scheduling.
56+
_BLOCK_2B = 4096
57+
_BLOCK_4B = 2048
58+
_NUM_WARPS = 4
59+
_TINY = 1024 # single-block-style launch for tiny tensors
60+
_MAX_BLOCKS = 960
61+
62+
63+
def _functional_sym_constrain_range_for_size(*args, **kwargs):
64+
logger.debug("GEMS_MTHREADS _FUNCTIONAL_SYM_CONSTRAIN_RANGE_FOR_SIZE")
65+
# Find the dep_token tensor argument; if absent or not a musa tensor of supported dtype, fall back.
66+
dep_token = next(
67+
(arg for arg in args if isinstance(arg, torch.Tensor)),
68+
next(
69+
(value for value in kwargs.values() if isinstance(value, torch.Tensor)),
70+
None,
71+
),
72+
)
73+
if dep_token is None:
74+
return default__functional_sym_constrain_range_for_size(*args, **kwargs)
75+
if (
76+
not isinstance(dep_token, torch.Tensor)
77+
or dep_token.device.type != "musa"
78+
or dep_token.dtype not in _SUPPORTED_DTYPES
79+
or not dep_token.is_contiguous()
80+
or dep_token.numel() == 0
81+
):
82+
return default__functional_sym_constrain_range_for_size(*args, **kwargs)
83+
output = torch.empty_like(dep_token)
84+
n_elements = dep_token.numel()
85+
if dep_token.element_size() <= 2:
86+
block = _BLOCK_2B
87+
else:
88+
block = _BLOCK_4B
89+
if n_elements < _TINY:
90+
block = _TINY
91+
blocks = triton.cdiv(n_elements, block)
92+
if blocks > _MAX_BLOCKS:
93+
grid = (_MAX_BLOCKS,)
94+
else:
95+
grid = (blocks,)
96+
with torch_device_fn.device(dep_token.device):
97+
_copy_kernel[grid](
98+
dep_token, output, n_elements, BLOCK_SIZE=block, num_warps=_NUM_WARPS
99+
)
100+
return output
101+
102+
103+
__all__ = ["_functional_sym_constrain_range_for_size"]

0 commit comments

Comments
 (0)