Skip to content

Commit 8bfa13a

Browse files
authored
[FlagGems Operator Development Competition] Add asinh operator (#2251) (#2441)
1 parent 511aab9 commit 8bfa13a

16 files changed

Lines changed: 559 additions & 145 deletions

File tree

src/flag_gems/__init__.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,14 @@ def torch_ge(v):
4343
("_index_put_impl_", _index_put_impl_),
4444
("_is_all_true", _is_all_true),
4545
("_log_softmax", log_softmax),
46+
("_log_softmax.out", log_softmax_out),
4647
("_log_softmax_backward_data", log_softmax_backward),
48+
("_log_softmax_backward_data.out", log_softmax_backward_out),
4749
("_safe_softmax", _safe_softmax),
4850
("_softmax", softmax),
51+
("_softmax.out", softmax_out),
4952
("_softmax_backward_data", softmax_backward),
53+
("_softmax_backward_data.out", softmax_backward_out),
5054
(
5155
"_to_copy",
5256
to_copy,
@@ -65,11 +69,15 @@ def torch_ge(v):
6569
("add.Tensor", add),
6670
("add_.Tensor", add_),
6771
("addcdiv", addcdiv),
72+
("addcdiv.out", addcdiv_out),
6873
("addcmul", addcmul),
74+
("addcmul.out", addcmul_out),
6975
("addmv", addmv),
7076
("addmv.out", addmv_out),
7177
("addmm", addmm),
7278
("addmm.out", addmm_out),
79+
("addmm.dtype", addmm_dtype),
80+
("addmm.dtype_out", addmm_dtype_out),
7381
("addr", addr),
7482
("alias_copy", alias_copy),
7583
("all", all),
@@ -122,6 +130,7 @@ def torch_ge(v):
122130
("bmm", bmm),
123131
("bmm.out", bmm_out),
124132
("cat", cat),
133+
("cat.out", cat_out),
125134
("celu", celu),
126135
("celu_", celu_),
127136
("ceil", ceil),
@@ -394,8 +403,8 @@ def torch_ge(v):
394403
("rms_norm", rms_norm),
395404
("roll", roll),
396405
("round", round),
397-
("round.out", round_out),
398406
("round_", round_),
407+
("round.out", round_out),
399408
("rrelu_with_noise_backward", rrelu_with_noise_backward),
400409
("rsqrt", rsqrt),
401410
("rsqrt_", rsqrt_),
@@ -497,6 +506,16 @@ def torch_ge(v):
497506
func_name = fn.__name__ if hasattr(fn, "__name__") else str(fn)
498507
FULL_CONFIG_BY_FUNC.setdefault(func_name, []).append(_item)
499508

509+
# Friendly names for only_enable(include=[...]) when the registered impl is *.out
510+
for _alias, _target in (
511+
("softmax", "softmax_out"),
512+
("softmax_backward", "softmax_backward_out"),
513+
("log_softmax", "log_softmax_out"),
514+
("log_softmax_backward", "log_softmax_backward_out"),
515+
):
516+
if _target in FULL_CONFIG_BY_FUNC:
517+
FULL_CONFIG_BY_FUNC.setdefault(_alias, []).extend(FULL_CONFIG_BY_FUNC[_target])
518+
500519

501520
def enable(
502521
lib=aten_lib,

src/flag_gems/ops/__init__.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
from flag_gems.ops.acos import acos
1010
from flag_gems.ops.act_quant import act_quant_triton
1111
from flag_gems.ops.add import add, add_
12-
from flag_gems.ops.addcdiv import addcdiv
13-
from flag_gems.ops.addcmul import addcmul
14-
from flag_gems.ops.addmm import addmm, addmm_out
12+
from flag_gems.ops.addcdiv import addcdiv, addcdiv_out
13+
from flag_gems.ops.addcmul import addcmul, addcmul_out
14+
from flag_gems.ops.addmm import addmm, addmm_dtype, addmm_dtype_out, addmm_out
1515
from flag_gems.ops.addmv import addmv, addmv_out
1616
from flag_gems.ops.addr import addr
1717
from flag_gems.ops.alias_copy import alias_copy, alias_copy_out
@@ -42,7 +42,7 @@
4242
)
4343
from flag_gems.ops.avg_pool2d import avg_pool2d, avg_pool2d_backward
4444
from flag_gems.ops.avg_pool3d import avg_pool3d, avg_pool3d_backward
45-
from flag_gems.ops.baddbmm import baddbmm
45+
from flag_gems.ops.baddbmm import baddbmm, baddbmm_out
4646
from flag_gems.ops.batch_norm import batch_norm, batch_norm_backward
4747
from flag_gems.ops.bernoulli_ import bernoulli_
4848
from flag_gems.ops.bitwise_and import (
@@ -63,7 +63,7 @@
6363
)
6464
from flag_gems.ops.bitwise_right_shift import bitwise_right_shift
6565
from flag_gems.ops.bmm import bmm, bmm_out
66-
from flag_gems.ops.cat import cat
66+
from flag_gems.ops.cat import cat, cat_out
6767
from flag_gems.ops.ceil import ceil, ceil_, ceil_out
6868
from flag_gems.ops.celu import celu, celu_
6969
from flag_gems.ops.clamp import (
@@ -176,7 +176,12 @@
176176
from flag_gems.ops.log1p_ import log1p_
177177
from flag_gems.ops.log10 import log10, log10_, log10_out
178178
from flag_gems.ops.log_sigmoid import log_sigmoid
179-
from flag_gems.ops.log_softmax import log_softmax, log_softmax_backward
179+
from flag_gems.ops.log_softmax import (
180+
log_softmax,
181+
log_softmax_backward,
182+
log_softmax_backward_out,
183+
log_softmax_out,
184+
)
180185
from flag_gems.ops.logaddexp import logaddexp, logaddexp_out
181186
from flag_gems.ops.logical_and import logical_and, logical_and_
182187
from flag_gems.ops.logical_not import logical_not
@@ -288,7 +293,12 @@
288293
from flag_gems.ops.slice_backward import slice_backward
289294
from flag_gems.ops.slice_scatter import slice_scatter
290295
from flag_gems.ops.soft_margin_loss import soft_margin_loss, soft_margin_loss_out
291-
from flag_gems.ops.softmax import softmax, softmax_backward
296+
from flag_gems.ops.softmax import (
297+
softmax,
298+
softmax_backward,
299+
softmax_backward_out,
300+
softmax_out,
301+
)
292302
from flag_gems.ops.softplus import softplus
293303
from flag_gems.ops.softshrink import softshrink, softshrink_out
294304
from flag_gems.ops.sort import sort, sort_stable
@@ -360,8 +370,12 @@
360370
"add",
361371
"add_",
362372
"addcdiv",
373+
"addcdiv_out",
363374
"addcmul",
375+
"addcmul_out",
364376
"addmm",
377+
"addmm_dtype",
378+
"addmm_dtype_out",
365379
"addmm_out",
366380
"addmv",
367381
"addmv_out",
@@ -398,6 +412,7 @@
398412
"avg_pool3d",
399413
"avg_pool3d_backward",
400414
"baddbmm",
415+
"baddbmm_out",
401416
"batch_norm",
402417
"batch_norm_backward",
403418
"bernoulli_",
@@ -418,6 +433,7 @@
418433
"bmm",
419434
"bmm_out",
420435
"cat",
436+
"cat_out",
421437
"ceil",
422438
"ceil_",
423439
"ceil_out",
@@ -567,6 +583,8 @@
567583
"log_sigmoid",
568584
"log_softmax",
569585
"log_softmax_backward",
586+
"log_softmax_backward_out",
587+
"log_softmax_out",
570588
"log1p_",
571589
"logaddexp",
572590
"logaddexp_out",
@@ -708,6 +726,8 @@
708726
"soft_margin_loss_out",
709727
"softmax",
710728
"softmax_backward",
729+
"softmax_backward_out",
730+
"softmax_out",
711731
"softplus",
712732
"softshrink",
713733
"softshrink_out",

src/flag_gems/ops/addcdiv.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ def addcdiv_kernel(x, t1, t2, value):
1616
return x + value * (t1 / t2)
1717

1818

19-
def addcdiv(inp, tensor1, tensor2, value=1.0, out=None):
20-
logger.debug("GEMS ADDCDIV FORWARD")
21-
22-
if out is None:
23-
out = torch.empty_like(inp)
24-
19+
def addcdiv_out(inp, tensor1, tensor2, *, value=1.0, out):
20+
logger.debug("GEMS ADDCDIV_OUT")
2521
addcdiv_kernel(inp, tensor1, tensor2, value, out0=out)
26-
2722
return out
23+
24+
25+
def addcdiv(inp, tensor1, tensor2, value=1.0):
26+
"""Functional entry; CUDA may dispatch here without hitting ``addcdiv.out``."""
27+
logger.debug("GEMS ADDCDIV")
28+
out = torch.empty_like(inp)
29+
return addcdiv_kernel(inp, tensor1, tensor2, value, out0=out)

src/flag_gems/ops/addcmul.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@ def addcmul_forward(x, t1, t2, value):
1616
return x + value * t1 * t2
1717

1818

19-
def addcmul(inp, tensor1, tensor2, *, value=1.0, out=None):
20-
logger.debug("GEMS ADDCMUL FORWARD")
21-
if out is not None:
22-
broadcast_shape = torch.broadcast_shapes(
23-
inp.shape, tensor1.shape, tensor2.shape
24-
)
25-
if list(out.shape) != list(broadcast_shape):
26-
out.resize_(broadcast_shape)
27-
addcmul_forward(inp, tensor1, tensor2, value, out0=out)
28-
return out
29-
else:
30-
return addcmul_forward(inp, tensor1, tensor2, value)
19+
def addcmul_out(inp, tensor1, tensor2, *, value=1.0, out):
20+
logger.debug("GEMS ADDCMUL_OUT")
21+
broadcast_shape = torch.broadcast_shapes(inp.shape, tensor1.shape, tensor2.shape)
22+
if list(out.shape) != list(broadcast_shape):
23+
out.resize_(broadcast_shape)
24+
addcmul_forward(inp, tensor1, tensor2, value, out0=out)
25+
return out
26+
27+
28+
def addcmul(inp, tensor1, tensor2, *, value=1.0):
29+
"""Functional entry; keep alongside ``addcmul.out`` for dispatch coverage."""
30+
logger.debug("GEMS ADDCMUL")
31+
broadcast_shape = torch.broadcast_shapes(inp.shape, tensor1.shape, tensor2.shape)
32+
dtype = torch.promote_types(
33+
inp.dtype, torch.promote_types(tensor1.dtype, tensor2.dtype)
34+
)
35+
out = torch.empty(broadcast_shape, device=inp.device, dtype=dtype)
36+
return addcmul_out(inp, tensor1, tensor2, value=value, out=out)

src/flag_gems/ops/addmm.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,39 @@ def addmm_out(bias, mat1, mat2, *, beta=1, alpha=1, out=None):
193193
IS_FP64=mat1.dtype == torch.float64,
194194
)
195195
return out
196+
197+
198+
def addmm_dtype(bias, mat1, mat2, out_dtype, *, beta=1, alpha=1):
199+
logger.debug("GEMS ADDMM_DTYPE")
200+
out = torch.empty(
201+
(mat1.shape[0], mat2.shape[1]),
202+
device=mat1.device,
203+
dtype=out_dtype,
204+
)
205+
return addmm_dtype_out(bias, mat1, mat2, out_dtype, beta=beta, alpha=alpha, out=out)
206+
207+
208+
def addmm_dtype_out(bias, mat1, mat2, out_dtype, *, beta=1, alpha=1, out):
209+
logger.debug("GEMS ADDMM_DTYPE_OUT")
210+
if mat1.dtype != mat2.dtype:
211+
raise RuntimeError(
212+
f"mat1 and mat2 must have the same dtype, but got {mat1.dtype} and {mat2.dtype}"
213+
)
214+
if out.dtype != out_dtype:
215+
raise RuntimeError(
216+
"out_dtype must be the same as the dtype of the provided out tensor"
217+
)
218+
if not (
219+
out_dtype == mat1.dtype
220+
or (
221+
out_dtype == torch.float32 and mat1.dtype in (torch.float16, torch.bfloat16)
222+
)
223+
):
224+
raise RuntimeError(
225+
"out_dtype must be the same as input dtype or fp32 for fp16/bf16 inputs"
226+
)
227+
if bias.dtype != out_dtype and bias.dtype != mat1.dtype:
228+
raise RuntimeError("self dtype must match either out_dtype or mat1 dtype")
229+
230+
bias_c = bias.to(out_dtype)
231+
return addmm_out(bias_c, mat1, mat2, beta=beta, alpha=alpha, out=out)

src/flag_gems/ops/baddbmm.py

Lines changed: 51 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,38 @@ def baddbmm_kernel(
138138
tl.store(o_ptrs, o, mask=mask_c)
139139

140140

141+
def _baddbmm_launch(bias, A, B, beta, alpha, out):
142+
batch, M, K = A.shape
143+
_, _, N = B.shape
144+
A = A.contiguous()
145+
B = B.contiguous()
146+
bbias = torch.broadcast_to(bias, (batch, M, N)).contiguous()
147+
bias_batch_stride = bbias.stride(0)
148+
bias_M_stride = bbias.stride(1)
149+
bias_N_stride = bbias.stride(-1)
150+
151+
grid = lambda meta: (
152+
triton.cdiv(meta["M"], meta["TILE_M"]),
153+
triton.cdiv(meta["N"], meta["TILE_N"]),
154+
batch,
155+
)
156+
with torch_device_fn.device(A.device):
157+
baddbmm_kernel[grid](
158+
A,
159+
B,
160+
out,
161+
bbias,
162+
alpha,
163+
beta,
164+
M,
165+
N,
166+
K,
167+
bias_batch_stride=bias_batch_stride,
168+
bias_M_stride=bias_M_stride,
169+
bias_N_stride=bias_N_stride,
170+
)
171+
172+
141173
class BaddbmmFunction(torch.autograd.Function):
142174
@staticmethod
143175
def forward(ctx, bias, A, B, beta, alpha):
@@ -149,36 +181,8 @@ def forward(ctx, bias, A, B, beta, alpha):
149181

150182
batch, M, K = A.shape
151183
_, _, N = B.shape
152-
A = A.contiguous()
153-
B = B.contiguous()
154184
out = torch.empty((batch, M, N), dtype=A.dtype, device=A.device)
155-
156-
bbias = torch.broadcast_to(bias, (batch, M, N)).contiguous()
157-
bias_batch_stride = bbias.stride(0)
158-
bias_M_stride = bbias.stride(1)
159-
bias_N_stride = bbias.stride(-1)
160-
161-
grid = lambda meta: (
162-
triton.cdiv(meta["M"], meta["TILE_M"]),
163-
triton.cdiv(meta["N"], meta["TILE_N"]),
164-
batch,
165-
)
166-
with torch_device_fn.device(A.device):
167-
baddbmm_kernel[grid](
168-
A,
169-
B,
170-
out,
171-
bbias,
172-
alpha,
173-
beta,
174-
M,
175-
N,
176-
K,
177-
bias_batch_stride=bias_batch_stride,
178-
bias_M_stride=bias_M_stride,
179-
bias_N_stride=bias_N_stride,
180-
IS_FP64=A.dtype == torch.float64,
181-
)
185+
_baddbmm_launch(bias, A, B, beta, alpha, out)
182186
return out
183187

184188
@staticmethod
@@ -239,6 +243,24 @@ def compute_B_grad(A, d_output, alpha):
239243
return grad_B
240244

241245

246+
def baddbmm_out(bias, A, B, *, beta=1.0, alpha=1.0, out):
247+
logger.debug("GEMS BADDBMM_OUT")
248+
batch, M, K = A.shape
249+
_, _, N = B.shape
250+
assert (
251+
out.shape == (batch, M, N) and out.dtype == A.dtype
252+
), "Incompatible output shape or dtype for baddbmm.out"
253+
_baddbmm_launch(
254+
bias.contiguous(),
255+
A.contiguous(),
256+
B.contiguous(),
257+
beta,
258+
alpha,
259+
out,
260+
)
261+
return out
262+
263+
242264
def baddbmm(bias, A, B, beta=1.0, alpha=1.0):
243265
return BaddbmmFunction.apply(
244266
bias.contiguous(),

0 commit comments

Comments
 (0)