forked from flagos-ai/FlagGems
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathleaky_relu.py
More file actions
153 lines (126 loc) · 4.55 KB
/
Copy pathleaky_relu.py
File metadata and controls
153 lines (126 loc) · 4.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import logging
import torch
import triton
import triton.language as tl
from flag_gems.runtime import torch_device_fn
from flag_gems.utils import pointwise_dynamic
logger = logging.getLogger(__name__)
_FALLBACK_KEYSET = torch._C.DispatchKeySet(
torch._C.DispatchKey.CompositeExplicitAutograd
)
@pointwise_dynamic(is_tensor=[True, False], promotion_methods=[(0, "DEFAULT")])
@triton.jit
def leaky_relu_fallback(x, negative_slope):
return tl.where(x > 0, x, x * negative_slope)
@triton.autotune(
configs=[
triton.Config({"BLOCK_SIZE": 1024}, num_warps=4),
triton.Config({"BLOCK_SIZE": 1024}, num_warps=8),
triton.Config({"BLOCK_SIZE": 2048}, num_warps=8),
triton.Config({"BLOCK_SIZE": 4096}, num_warps=4),
triton.Config({"BLOCK_SIZE": 4096}, num_warps=8),
triton.Config({"BLOCK_SIZE": 8192}, num_warps=4),
triton.Config({"BLOCK_SIZE": 8192}, num_warps=8),
triton.Config({"BLOCK_SIZE": 16384}, num_warps=4),
triton.Config({"BLOCK_SIZE": 16384}, num_warps=8),
],
key=["n_elements"],
)
@triton.jit
def leaky_relu_kernel_fp16(
x_ptr, out_ptr, negative_slope, n_elements, BLOCK_SIZE: tl.constexpr
):
pid = tl.program_id(axis=0)
block_start = pid * BLOCK_SIZE
offsets = block_start + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
x = tl.load(x_ptr + offsets, mask=mask)
y = tl.where(x > 0, x, x * negative_slope)
tl.store(out_ptr + offsets, y, mask=mask)
@triton.autotune(
configs=[
triton.Config({"BLOCK_SIZE": 1024}, num_warps=4),
triton.Config({"BLOCK_SIZE": 1024}, num_warps=8),
triton.Config({"BLOCK_SIZE": 4096}, num_warps=8),
triton.Config({"BLOCK_SIZE": 8192}, num_warps=8),
triton.Config({"BLOCK_SIZE": 16384}, num_warps=4),
triton.Config({"BLOCK_SIZE": 32768}, num_warps=8),
],
key=["n_elements"],
)
@triton.jit
def leaky_relu_kernel_fp32(
x_ptr, out_ptr, negative_slope, n_elements, BLOCK_SIZE: tl.constexpr
):
pid = tl.program_id(axis=0)
block_start = pid * BLOCK_SIZE
offsets = block_start + tl.arange(0, BLOCK_SIZE)
mask = offsets < n_elements
x = tl.load(x_ptr + offsets, mask=mask)
y = tl.where(x > 0, x, x * negative_slope)
tl.store(out_ptr + offsets, y, mask=mask)
def _get_fast_kernel(inp):
if inp.dtype in (torch.float16, torch.bfloat16):
return leaky_relu_kernel_fp16
if inp.dtype == torch.float32:
return leaky_relu_kernel_fp32
return None
def _leaky_relu_contiguous(inp, negative_slope, out):
n_elements = inp.numel()
if n_elements == 0:
return out
kernel = _get_fast_kernel(inp)
if kernel is None:
return leaky_relu_fallback(inp, negative_slope, out0=out)
grid = lambda meta: (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)
with torch_device_fn.device(inp.device.index):
kernel[grid](
inp,
out,
negative_slope,
n_elements,
)
return out
def _can_use_fast_path(inp):
return (
inp.layout == torch.strided
and inp.is_cuda
and not inp.is_quantized
and not inp.is_complex()
and inp.is_contiguous()
)
def leaky_relu(inp, negative_slope=0.01):
logger.debug("GEMS LEAKY_RELU")
if _can_use_fast_path(inp):
return _leaky_relu_contiguous(inp, negative_slope, torch.empty_like(inp))
if not inp.is_cuda or inp.is_complex():
return torch.ops.aten.leaky_relu.default.redispatch(
_FALLBACK_KEYSET, inp, negative_slope
)
return leaky_relu_fallback(inp, negative_slope)
def leaky_relu_(inp, negative_slope=0.01):
logger.debug("GEMS LEAKY_RELU_")
if _can_use_fast_path(inp):
return _leaky_relu_contiguous(inp, negative_slope, inp)
if not inp.is_cuda or inp.is_complex():
return torch.ops.aten.leaky_relu_.default.redispatch(
_FALLBACK_KEYSET, inp, negative_slope
)
return leaky_relu_fallback(inp, negative_slope, out0=inp)
def leaky_relu_out(inp, negative_slope=0.01, *, out):
logger.debug("GEMS LEAKY_RELU_OUT")
if (
not _can_use_fast_path(inp)
or out.layout != torch.strided
or out.device != inp.device
or out.dtype != inp.dtype
):
return torch.ops.aten.leaky_relu.out.redispatch(
_FALLBACK_KEYSET, inp, negative_slope, out=out
)
if out.shape != inp.shape:
out.resize_(inp.shape)
if out.is_contiguous():
return _leaky_relu_contiguous(inp, negative_slope, out)
leaky_relu_fallback(inp, negative_slope, out0=out)
return out