cumo 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +590 -152
- data/CHANGELOG.md +63 -0
- data/README.md +245 -0
- data/bench/cumo_probe.rb +1 -1
- data/cumo.gemspec +7 -1
- data/ext/cumo/cuda/cudnn.c +18 -0
- data/ext/cumo/cuda/cudnn_impl.cpp +60 -14
- data/ext/cumo/cuda/driver.c +11 -9
- data/ext/cumo/cuda/memory_pool_impl.cpp +32 -22
- data/ext/cumo/cuda/memory_pool_impl.hpp +3 -1
- data/ext/cumo/cuda/memory_pool_impl_test.cpp +19 -25
- data/ext/cumo/cuda/runtime.c +56 -0
- data/ext/cumo/cumo.c +4 -0
- data/ext/cumo/extconf.rb +2 -0
- data/ext/cumo/include/cumo/bit_reduce_kernel.h +6 -6
- data/ext/cumo/include/cumo/check.h +11 -3
- data/ext/cumo/include/cumo/cuda/cudnn.h +43 -6
- data/ext/cumo/include/cumo/cuda/runtime.h +2 -0
- data/ext/cumo/include/cumo/indexer.h +16 -0
- data/ext/cumo/include/cumo/intern.h +11 -0
- data/ext/cumo/include/cumo/narray.h +1 -0
- data/ext/cumo/include/cumo/reduce_kernel.h +283 -54
- data/ext/cumo/include/cumo/row_kernel.h +202 -0
- data/ext/cumo/include/cumo/row_method.h +149 -0
- data/ext/cumo/include/cumo/template_kernel.h +26 -0
- data/ext/cumo/include/cumo/types/bf16_def.h +82 -0
- data/ext/cumo/include/cumo/types/bf16_def_kernel.h +28 -0
- data/ext/cumo/include/cumo/types/bf16_macro.h +14 -0
- data/ext/cumo/include/cumo/types/bf16_macro_kernel.h +19 -0
- data/ext/cumo/include/cumo/types/bfloat.h +22 -0
- data/ext/cumo/include/cumo/types/bfloat_kernel.h +16 -0
- data/ext/cumo/include/cumo/types/bit.h +2 -0
- data/ext/cumo/include/cumo/types/bit_kernel.h +2 -0
- data/ext/cumo/include/cumo/types/complex_macro.h +2 -0
- data/ext/cumo/include/cumo/types/complex_macro_kernel.h +2 -0
- data/ext/cumo/include/cumo/types/f16_macro.h +191 -0
- data/ext/cumo/include/cumo/types/f16_macro_kernel.h +214 -0
- data/ext/cumo/include/cumo/types/float_def.h +8 -0
- data/ext/cumo/include/cumo/types/float_def_kernel.h +8 -0
- data/ext/cumo/include/cumo/types/float_macro.h +26 -17
- data/ext/cumo/include/cumo/types/float_macro_kernel.h +26 -19
- data/ext/cumo/include/cumo/types/half_macro.h +6 -180
- data/ext/cumo/include/cumo/types/half_macro_kernel.h +6 -185
- data/ext/cumo/include/cumo/types/robj_macro.h +2 -0
- data/ext/cumo/include/cumo/types/xint_macro.h +2 -6
- data/ext/cumo/include/cumo/types/xint_macro_kernel.h +2 -0
- data/ext/cumo/include/cumo.h +2 -2
- data/ext/cumo/narray/data.c +15 -6
- data/ext/cumo/narray/data_kernel.cu +110 -0
- data/ext/cumo/narray/gen/def/bfloat.rb +57 -0
- data/ext/cumo/narray/gen/def/bit.rb +12 -1
- data/ext/cumo/narray/gen/def/dcomplex.rb +12 -1
- data/ext/cumo/narray/gen/def/dfloat.rb +11 -1
- data/ext/cumo/narray/gen/def/hfloat.rb +11 -1
- data/ext/cumo/narray/gen/def/int16.rb +12 -1
- data/ext/cumo/narray/gen/def/int32.rb +12 -1
- data/ext/cumo/narray/gen/def/int64.rb +12 -1
- data/ext/cumo/narray/gen/def/int8.rb +12 -1
- data/ext/cumo/narray/gen/def/robject.rb +12 -1
- data/ext/cumo/narray/gen/def/scomplex.rb +12 -1
- data/ext/cumo/narray/gen/def/sfloat.rb +11 -1
- data/ext/cumo/narray/gen/def/uint16.rb +12 -1
- data/ext/cumo/narray/gen/def/uint32.rb +12 -1
- data/ext/cumo/narray/gen/def/uint64.rb +12 -1
- data/ext/cumo/narray/gen/def/uint8.rb +12 -1
- data/ext/cumo/narray/gen/narray_def.rb +35 -6
- data/ext/cumo/narray/gen/spec.rb +14 -14
- data/ext/cumo/narray/gen/tmpl/accum_arg.c +1 -1
- data/ext/cumo/narray/gen/tmpl/accum_binary.c +63 -5
- data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +29 -13
- data/ext/cumo/narray/gen/tmpl/accum_index.c +1 -1
- data/ext/cumo/narray/gen/tmpl/batch_norm.c +4 -4
- data/ext/cumo/narray/gen/tmpl/batch_norm_backward.c +5 -5
- data/ext/cumo/narray/gen/tmpl/binary.c +3 -9
- data/ext/cumo/narray/gen/tmpl/complex_accum_kernel.cu +15 -5
- data/ext/cumo/narray/gen/tmpl/conv.c +90 -123
- data/ext/cumo/narray/gen/tmpl/conv_grad_w.c +91 -83
- data/ext/cumo/narray/gen/tmpl/conv_transpose.c +90 -123
- data/ext/cumo/narray/gen/tmpl/cum.c +8 -7
- data/ext/cumo/narray/gen/tmpl/cum_kernel.cu +7 -6
- data/ext/cumo/narray/gen/tmpl/fixed_batch_norm.c +4 -4
- data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +22 -10
- data/ext/cumo/narray/gen/tmpl/gemm.c +11 -41
- data/ext/cumo/narray/gen/tmpl/layer_norm.c +38 -0
- data/ext/cumo/narray/gen/tmpl/layer_norm_kernel.cu +54 -0
- data/ext/cumo/narray/gen/tmpl/lib.c +1 -0
- data/ext/cumo/narray/gen/tmpl/lib_kernel.cu +1 -0
- data/ext/cumo/narray/gen/tmpl/median.c +1 -1
- data/ext/cumo/narray/gen/tmpl/poly.c +0 -3
- data/ext/cumo/narray/gen/tmpl/poly_kernel.cu +1 -1
- data/ext/cumo/narray/gen/tmpl/pooling_backward.c +3 -2
- data/ext/cumo/narray/gen/tmpl/pooling_forward.c +3 -2
- data/ext/cumo/narray/gen/tmpl/quantize_symmetric.c +74 -0
- data/ext/cumo/narray/gen/tmpl/quantize_symmetric_kernel.cu +67 -0
- data/ext/cumo/narray/gen/tmpl/rand.c +9 -9
- data/ext/cumo/narray/gen/tmpl/rand_kernel.cu +9 -9
- data/ext/cumo/narray/gen/tmpl/rand_norm.c +4 -4
- data/ext/cumo/narray/gen/tmpl/rand_norm_kernel.cu +7 -7
- data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +6 -6
- data/ext/cumo/narray/gen/tmpl/rms_norm.c +38 -0
- data/ext/cumo/narray/gen/tmpl/rms_norm_kernel.cu +57 -0
- data/ext/cumo/narray/gen/tmpl/softmax.c +21 -0
- data/ext/cumo/narray/gen/tmpl/softmax_kernel.cu +157 -0
- data/ext/cumo/narray/gen/tmpl/sort.c +9 -32
- data/ext/cumo/narray/gen/tmpl/sort_index.c +16 -95
- data/ext/cumo/narray/gen/tmpl/store_array.c +12 -9
- data/ext/cumo/narray/gen/tmpl/store_from.c +1 -16
- data/ext/cumo/narray/gen/tmpl_bit/mask.c +11 -11
- data/ext/cumo/narray/gen/tmpl_bit/store_array.c +5 -9
- data/ext/cumo/narray/gen/tmpl_bit/where.c +50 -11
- data/ext/cumo/narray/gen/tmpl_bit/where2.c +11 -12
- data/ext/cumo/narray/gen/tmpl_bit/where_kernel.cu +1 -2
- data/ext/cumo/narray/index.c +35 -25
- data/ext/cumo/narray/index_kernel.cu +27 -0
- data/ext/cumo/narray/math.c +40 -8
- data/ext/cumo/narray/narray.c +85 -15
- data/ext/cumo/narray/ndloop.c +210 -5
- data/ext/cumo/narray/sort_kernel.cu +61 -41
- data/ext/cumo/narray/struct.c +3 -0
- data/lib/cumo/cuda/cudnn.rb +1 -1
- data/lib/cumo/narray/extra.rb +2 -2
- data/test/bfloat_test.rb +238 -0
- data/test/bit_test.rb +52 -14
- data/test/cuda/memory_pool_test.rb +8 -7
- data/test/cuda/runtime_test.rb +25 -0
- data/test/cudnn_test.rb +108 -24
- data/test/extra_test.rb +1 -1
- data/test/fused_test.rb +587 -0
- data/test/math_test.rb +182 -2
- data/test/narray_alt_coverage_test.rb +1 -0
- data/test/narray_test.rb +344 -22
- data/test/test_helper.rb +1 -0
- metadata +32 -5
- data/ext/cumo/narray/gen/tmpl/qsort.c +0 -205
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/* The body both 16 bit types share.
|
|
2
|
+
*
|
|
3
|
+
* half and bfloat16 compute in float and differ only in how they convert, so
|
|
4
|
+
* the includer names the conversions and this file is written in terms of them.
|
|
5
|
+
* cumo/types/half_macro.h and bf16_macro.h are the two includers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#define m_zero CUMO_F_TO_F16(0.0f)
|
|
9
|
+
#define m_one CUMO_F_TO_F16(1.0f)
|
|
10
|
+
|
|
11
|
+
#define m_num_to_data(x) cumo_na_ruby_num_to_f16(x)
|
|
12
|
+
#define m_data_to_num(x) rb_float_new(CUMO_F16_TO_F(x))
|
|
13
|
+
|
|
14
|
+
#define m_from_double(x) CUMO_D_TO_F16((double)(x))
|
|
15
|
+
#define m_from_real(x) CUMO_D_TO_F16((double)(x))
|
|
16
|
+
#define m_from_sint(x) CUMO_D_TO_F16((double)(x))
|
|
17
|
+
#define m_from_int32(x) CUMO_D_TO_F16((double)(x))
|
|
18
|
+
#define m_from_int64(x) CUMO_D_TO_F16((double)(x))
|
|
19
|
+
#define m_from_uint32(x) CUMO_D_TO_F16((double)(x))
|
|
20
|
+
#define m_from_uint64(x) CUMO_D_TO_F16((double)(x))
|
|
21
|
+
|
|
22
|
+
#define m_add(x,y) CUMO_F_TO_F16(CUMO_F16_TO_F(x)+CUMO_F16_TO_F(y))
|
|
23
|
+
#define m_sub(x,y) CUMO_F_TO_F16(CUMO_F16_TO_F(x)-CUMO_F16_TO_F(y))
|
|
24
|
+
#define m_mul(x,y) CUMO_F_TO_F16(CUMO_F16_TO_F(x)*CUMO_F16_TO_F(y))
|
|
25
|
+
#define m_div(x,y) CUMO_F_TO_F16(CUMO_F16_TO_F(x)/CUMO_F16_TO_F(y))
|
|
26
|
+
#define m_div_check(x,y) (CUMO_F16_TO_F(y)==0)
|
|
27
|
+
|
|
28
|
+
static inline float cumo_f16_floored_mod(float x, float y)
|
|
29
|
+
{
|
|
30
|
+
float r = fmodf(x,y);
|
|
31
|
+
if (r != 0 && ((r < 0) != (y < 0))) {
|
|
32
|
+
r += y;
|
|
33
|
+
}
|
|
34
|
+
return r;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#define m_mod(x,y) CUMO_F_TO_F16(cumo_f16_floored_mod(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
38
|
+
#define m_divmod(x,y,a,b) \
|
|
39
|
+
{float cumo_f16_x = CUMO_F16_TO_F(x), cumo_f16_y = CUMO_F16_TO_F(y); \
|
|
40
|
+
float cumo_f16_b = fmodf(cumo_f16_x,cumo_f16_y); \
|
|
41
|
+
float cumo_f16_a = roundf((cumo_f16_x-cumo_f16_b)/cumo_f16_y); \
|
|
42
|
+
if (cumo_f16_b != 0 && ((cumo_f16_b < 0) != (cumo_f16_y < 0))) { \
|
|
43
|
+
cumo_f16_b += cumo_f16_y; cumo_f16_a -= 1; \
|
|
44
|
+
} \
|
|
45
|
+
a = CUMO_F_TO_F16(cumo_f16_a); b = CUMO_F_TO_F16(cumo_f16_b);}
|
|
46
|
+
#define m_pow(x,y) CUMO_F_TO_F16(powf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
47
|
+
#define m_pow_int(x,y) CUMO_F_TO_F16(cumo_f16_pow_int(CUMO_F16_TO_F(x),(int)(y)))
|
|
48
|
+
|
|
49
|
+
#define m_abs(x) CUMO_F_TO_F16(fabsf(CUMO_F16_TO_F(x)))
|
|
50
|
+
#define m_minus(x) CUMO_F_TO_F16(-CUMO_F16_TO_F(x))
|
|
51
|
+
#define m_reciprocal(x) CUMO_F_TO_F16(1.0f/CUMO_F16_TO_F(x))
|
|
52
|
+
#define m_square(x) CUMO_F_TO_F16(CUMO_F16_TO_F(x)*CUMO_F16_TO_F(x))
|
|
53
|
+
#define m_floor(x) CUMO_F_TO_F16(floorf(CUMO_F16_TO_F(x)))
|
|
54
|
+
#define m_round(x) CUMO_F_TO_F16(roundf(CUMO_F16_TO_F(x)))
|
|
55
|
+
#define m_ceil(x) CUMO_F_TO_F16(ceilf(CUMO_F16_TO_F(x)))
|
|
56
|
+
#define m_trunc(x) CUMO_F_TO_F16(truncf(CUMO_F16_TO_F(x)))
|
|
57
|
+
#define m_rint(x) CUMO_F_TO_F16(rintf(CUMO_F16_TO_F(x)))
|
|
58
|
+
#define m_sign(x) CUMO_F_TO_F16(cumo_f16_sign(CUMO_F16_TO_F(x)))
|
|
59
|
+
#define m_copysign(x,y) CUMO_F_TO_F16(copysignf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
60
|
+
#define m_signbit(x) signbit(CUMO_F16_TO_F(x))
|
|
61
|
+
#define m_modf(x,y,z) {float cumo_f16_i; float cumo_f16_f = modff(CUMO_F16_TO_F(x),&cumo_f16_i); y = CUMO_F_TO_F16(cumo_f16_f); z = CUMO_F_TO_F16(cumo_f16_i);}
|
|
62
|
+
|
|
63
|
+
#define m_eq(x,y) (CUMO_F16_TO_F(x)==CUMO_F16_TO_F(y))
|
|
64
|
+
#define m_ne(x,y) (CUMO_F16_TO_F(x)!=CUMO_F16_TO_F(y))
|
|
65
|
+
#define m_gt(x,y) (CUMO_F16_TO_F(x)>CUMO_F16_TO_F(y))
|
|
66
|
+
#define m_ge(x,y) (CUMO_F16_TO_F(x)>=CUMO_F16_TO_F(y))
|
|
67
|
+
#define m_lt(x,y) (CUMO_F16_TO_F(x)<CUMO_F16_TO_F(y))
|
|
68
|
+
#define m_le(x,y) (CUMO_F16_TO_F(x)<=CUMO_F16_TO_F(y))
|
|
69
|
+
|
|
70
|
+
#define m_isnan(x) isnan(CUMO_F16_TO_F(x))
|
|
71
|
+
#define m_isinf(x) isinf(CUMO_F16_TO_F(x))
|
|
72
|
+
#define m_isposinf(x) (isinf(CUMO_F16_TO_F(x)) && signbit(CUMO_F16_TO_F(x))==0)
|
|
73
|
+
#define m_isneginf(x) (isinf(CUMO_F16_TO_F(x)) && signbit(CUMO_F16_TO_F(x)))
|
|
74
|
+
#define m_isfinite(x) isfinite(CUMO_F16_TO_F(x))
|
|
75
|
+
|
|
76
|
+
#define not_nan(x) (CUMO_F16_TO_F(x)==CUMO_F16_TO_F(x))
|
|
77
|
+
|
|
78
|
+
#define m_mulsum_init INT2FIX(0)
|
|
79
|
+
|
|
80
|
+
#define m_sprintf(s,x) sprintf(s,"%g",CUMO_F16_TO_F(x))
|
|
81
|
+
|
|
82
|
+
#define m_sqrt(x) CUMO_F_TO_F16(sqrtf(CUMO_F16_TO_F(x)))
|
|
83
|
+
#define m_cbrt(x) CUMO_F_TO_F16(cbrtf(CUMO_F16_TO_F(x)))
|
|
84
|
+
#define m_log(x) CUMO_F_TO_F16(logf(CUMO_F16_TO_F(x)))
|
|
85
|
+
#define m_log2(x) CUMO_F_TO_F16(log2f(CUMO_F16_TO_F(x)))
|
|
86
|
+
#define m_log10(x) CUMO_F_TO_F16(log10f(CUMO_F16_TO_F(x)))
|
|
87
|
+
#define m_exp(x) CUMO_F_TO_F16(expf(CUMO_F16_TO_F(x)))
|
|
88
|
+
#define m_exp2(x) CUMO_F_TO_F16(exp2f(CUMO_F16_TO_F(x)))
|
|
89
|
+
#ifdef HAVE_EXP10
|
|
90
|
+
#define m_exp10(x) CUMO_F_TO_F16(exp10f(CUMO_F16_TO_F(x)))
|
|
91
|
+
#else
|
|
92
|
+
#define m_exp10(x) CUMO_F_TO_F16(powf(10.0f,CUMO_F16_TO_F(x)))
|
|
93
|
+
#endif
|
|
94
|
+
#define m_expm1(x) CUMO_F_TO_F16(expm1f(CUMO_F16_TO_F(x)))
|
|
95
|
+
#define m_log1p(x) CUMO_F_TO_F16(log1pf(CUMO_F16_TO_F(x)))
|
|
96
|
+
|
|
97
|
+
#define m_sin(x) CUMO_F_TO_F16(sinf(CUMO_F16_TO_F(x)))
|
|
98
|
+
#define m_cos(x) CUMO_F_TO_F16(cosf(CUMO_F16_TO_F(x)))
|
|
99
|
+
#define m_tan(x) CUMO_F_TO_F16(tanf(CUMO_F16_TO_F(x)))
|
|
100
|
+
#define m_asin(x) CUMO_F_TO_F16(asinf(CUMO_F16_TO_F(x)))
|
|
101
|
+
#define m_acos(x) CUMO_F_TO_F16(acosf(CUMO_F16_TO_F(x)))
|
|
102
|
+
#define m_atan(x) CUMO_F_TO_F16(atanf(CUMO_F16_TO_F(x)))
|
|
103
|
+
#define m_sinh(x) CUMO_F_TO_F16(sinhf(CUMO_F16_TO_F(x)))
|
|
104
|
+
#define m_cosh(x) CUMO_F_TO_F16(coshf(CUMO_F16_TO_F(x)))
|
|
105
|
+
#define m_tanh(x) CUMO_F_TO_F16(tanhf(CUMO_F16_TO_F(x)))
|
|
106
|
+
#define m_asinh(x) CUMO_F_TO_F16(asinhf(CUMO_F16_TO_F(x)))
|
|
107
|
+
#define m_acosh(x) CUMO_F_TO_F16(acoshf(CUMO_F16_TO_F(x)))
|
|
108
|
+
#define m_atanh(x) CUMO_F_TO_F16(atanhf(CUMO_F16_TO_F(x)))
|
|
109
|
+
#define m_atan2(x,y) CUMO_F_TO_F16(atan2f(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
110
|
+
#define m_hypot(x,y) CUMO_F_TO_F16(hypotf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
111
|
+
#define m_sinc(x) CUMO_F_TO_F16(cumo_f16_sinc(CUMO_F16_TO_F(x)))
|
|
112
|
+
|
|
113
|
+
#define m_erf(x) CUMO_F_TO_F16(erff(CUMO_F16_TO_F(x)))
|
|
114
|
+
#define m_erfc(x) CUMO_F_TO_F16(erfcf(CUMO_F16_TO_F(x)))
|
|
115
|
+
#define m_gelu(x) CUMO_F_TO_F16(cumo_f16_gelu(CUMO_F16_TO_F(x)))
|
|
116
|
+
#define m_gelu_tanh(x) CUMO_F_TO_F16(cumo_f16_gelu_tanh(CUMO_F16_TO_F(x)))
|
|
117
|
+
#define m_silu(x) CUMO_F_TO_F16(cumo_f16_silu(CUMO_F16_TO_F(x)))
|
|
118
|
+
#define m_ldexp(x,y) CUMO_F_TO_F16(cumo_f16_ldexp(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
119
|
+
#define m_frexp(x,exp) CUMO_F_TO_F16(frexpf(CUMO_F16_TO_F(x),exp))
|
|
120
|
+
|
|
121
|
+
static inline float cumo_f16_pow_positive_int(float x, unsigned int p)
|
|
122
|
+
{
|
|
123
|
+
float r = 1.0f;
|
|
124
|
+
switch (p) {
|
|
125
|
+
case 0: return 1.0f;
|
|
126
|
+
case 1: return x;
|
|
127
|
+
case 2: return x*x;
|
|
128
|
+
case 3: return x*x*x;
|
|
129
|
+
case 4: x = x*x; return x*x;
|
|
130
|
+
}
|
|
131
|
+
if (p > 64) return powf(x, (float)p);
|
|
132
|
+
while (p) {
|
|
133
|
+
if (p & 1) r *= x;
|
|
134
|
+
x *= x;
|
|
135
|
+
p >>= 1;
|
|
136
|
+
}
|
|
137
|
+
return r;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
static inline float cumo_f16_pow_int(float x, int p)
|
|
141
|
+
{
|
|
142
|
+
if (p < 0) return 1.0f / cumo_f16_pow_positive_int(x, -(unsigned int)p);
|
|
143
|
+
return cumo_f16_pow_positive_int(x, (unsigned int)p);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static inline float cumo_f16_ldexp(float x, float y)
|
|
147
|
+
{
|
|
148
|
+
if (!(y == y)) return y;
|
|
149
|
+
if (y > 64.0f) y = 64.0f;
|
|
150
|
+
if (y < -64.0f) y = -64.0f;
|
|
151
|
+
return ldexpf(x, (int)y);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static inline float cumo_f16_sinc(float x)
|
|
155
|
+
{
|
|
156
|
+
return (x==0) ? 1.0f : (sinf(x)/x);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static inline float cumo_f16_sign(float x)
|
|
160
|
+
{
|
|
161
|
+
return (x==0) ? 0.0f : ((x>0) ? 1.0f : ((x<0) ? -1.0f : x));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static inline dtype cumo_na_ruby_num_to_f16(VALUE x)
|
|
165
|
+
{
|
|
166
|
+
return CUMO_D_TO_F16(NIL_P(x) ? nan("") : NUM2DBL(x));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static inline dtype f_seq(dtype x, dtype y, double c)
|
|
170
|
+
{
|
|
171
|
+
return CUMO_F_TO_F16(CUMO_F16_TO_F(x) + CUMO_F16_TO_F(y) * (float)c);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
#include "real_accum.h"
|
|
175
|
+
|
|
176
|
+
static inline float cumo_f16_gelu(float x)
|
|
177
|
+
{
|
|
178
|
+
return 0.5f * x * (1.0f + erff(x * (float)CUMO_M_SQRT1_2));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// The approximation GPT-2 and the transformers after it were trained with.
|
|
182
|
+
static inline float cumo_f16_gelu_tanh(float x)
|
|
183
|
+
{
|
|
184
|
+
return 0.5f * x * (1.0f + tanhf((float)CUMO_M_SQRT_2_OVER_PI * (x + (float)CUMO_GELU_TANH_CUBIC * x * x * x)));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// x * sigmoid(x) as one division, cumo having no sigmoid to call.
|
|
188
|
+
static inline float cumo_f16_silu(float x)
|
|
189
|
+
{
|
|
190
|
+
return x / (1.0f + expf(-x));
|
|
191
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/* The body both 16 bit types share.
|
|
2
|
+
*
|
|
3
|
+
* half and bfloat16 compute in float and differ only in how they convert, so
|
|
4
|
+
* the includer names the conversions and this file is written in terms of them.
|
|
5
|
+
* cumo/types/half_macro_kernel.h and bf16_macro_kernel.h are the two includers.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include <string.h>
|
|
9
|
+
|
|
10
|
+
#define m_zero CUMO_F_TO_F16(0.0f)
|
|
11
|
+
#define m_one CUMO_F_TO_F16(1.0f)
|
|
12
|
+
|
|
13
|
+
#define m_from_double(x) CUMO_D_TO_F16((double)(x))
|
|
14
|
+
#define m_from_real(x) CUMO_D_TO_F16((double)(x))
|
|
15
|
+
#define m_from_sint(x) CUMO_D_TO_F16((double)(x))
|
|
16
|
+
#define m_from_int32(x) CUMO_D_TO_F16((double)(x))
|
|
17
|
+
#define m_from_int64(x) CUMO_D_TO_F16((double)(x))
|
|
18
|
+
#define m_from_uint32(x) CUMO_D_TO_F16((double)(x))
|
|
19
|
+
#define m_from_uint64(x) CUMO_D_TO_F16((double)(x))
|
|
20
|
+
|
|
21
|
+
// Overloaded rather than substituted, so that a scan or a reduction can apply
|
|
22
|
+
// the same rule to its own wider accumulator.
|
|
23
|
+
__host__ __device__ static inline float cumo_f16_add(float x, float y) { return x + y; }
|
|
24
|
+
__host__ __device__ static inline float cumo_f16_sub(float x, float y) { return x - y; }
|
|
25
|
+
__host__ __device__ static inline float cumo_f16_mul(float x, float y) { return x * y; }
|
|
26
|
+
__host__ __device__ static inline float cumo_f16_div(float x, float y) { return x / y; }
|
|
27
|
+
__host__ __device__ static inline bool cumo_f16_not_nan(float x) { return x == x; }
|
|
28
|
+
__host__ __device__ static inline dtype cumo_f16_add(dtype x, dtype y) { return CUMO_F_TO_F16(CUMO_F16_TO_F(x) + CUMO_F16_TO_F(y)); }
|
|
29
|
+
__host__ __device__ static inline dtype cumo_f16_sub(dtype x, dtype y) { return CUMO_F_TO_F16(CUMO_F16_TO_F(x) - CUMO_F16_TO_F(y)); }
|
|
30
|
+
__host__ __device__ static inline dtype cumo_f16_mul(dtype x, dtype y) { return CUMO_F_TO_F16(CUMO_F16_TO_F(x) * CUMO_F16_TO_F(y)); }
|
|
31
|
+
__host__ __device__ static inline dtype cumo_f16_div(dtype x, dtype y) { return CUMO_F_TO_F16(CUMO_F16_TO_F(x) / CUMO_F16_TO_F(y)); }
|
|
32
|
+
__host__ __device__ static inline bool cumo_f16_not_nan(dtype x) { return CUMO_F16_TO_F(x) == CUMO_F16_TO_F(x); }
|
|
33
|
+
|
|
34
|
+
#define m_add(x,y) cumo_f16_add(x,y)
|
|
35
|
+
#define m_sub(x,y) cumo_f16_sub(x,y)
|
|
36
|
+
#define m_mul(x,y) cumo_f16_mul(x,y)
|
|
37
|
+
#define m_div(x,y) cumo_f16_div(x,y)
|
|
38
|
+
#define m_div_check(x,y) (CUMO_F16_TO_F(y)==0)
|
|
39
|
+
|
|
40
|
+
__host__ __device__ static inline float cumo_f16_floored_mod(float x, float y)
|
|
41
|
+
{
|
|
42
|
+
float r = fmodf(x,y);
|
|
43
|
+
if (r != 0 && ((r < 0) != (y < 0))) {
|
|
44
|
+
r += y;
|
|
45
|
+
}
|
|
46
|
+
return r;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#define m_mod(x,y) CUMO_F_TO_F16(cumo_f16_floored_mod(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
50
|
+
#define m_divmod(x,y,a,b) \
|
|
51
|
+
{float cumo_f16_x = CUMO_F16_TO_F(x), cumo_f16_y = CUMO_F16_TO_F(y); \
|
|
52
|
+
float cumo_f16_b = fmodf(cumo_f16_x,cumo_f16_y); \
|
|
53
|
+
float cumo_f16_a = roundf((cumo_f16_x-cumo_f16_b)/cumo_f16_y); \
|
|
54
|
+
if (cumo_f16_b != 0 && ((cumo_f16_b < 0) != (cumo_f16_y < 0))) { \
|
|
55
|
+
cumo_f16_b += cumo_f16_y; cumo_f16_a -= 1; \
|
|
56
|
+
} \
|
|
57
|
+
a = CUMO_F_TO_F16(cumo_f16_a); b = CUMO_F_TO_F16(cumo_f16_b);}
|
|
58
|
+
#define m_pow(x,y) CUMO_F_TO_F16(powf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
59
|
+
#define m_pow_int(x,y) CUMO_F_TO_F16(cumo_f16_pow_int(CUMO_F16_TO_F(x),(int)(y)))
|
|
60
|
+
|
|
61
|
+
#define m_abs(x) CUMO_F_TO_F16(fabsf(CUMO_F16_TO_F(x)))
|
|
62
|
+
#define m_minus(x) CUMO_F_TO_F16(-CUMO_F16_TO_F(x))
|
|
63
|
+
#define m_reciprocal(x) CUMO_F_TO_F16(1.0f/CUMO_F16_TO_F(x))
|
|
64
|
+
#define m_square(x) CUMO_F_TO_F16(CUMO_F16_TO_F(x)*CUMO_F16_TO_F(x))
|
|
65
|
+
#define m_floor(x) CUMO_F_TO_F16(floorf(CUMO_F16_TO_F(x)))
|
|
66
|
+
#define m_round(x) CUMO_F_TO_F16(roundf(CUMO_F16_TO_F(x)))
|
|
67
|
+
#define m_ceil(x) CUMO_F_TO_F16(ceilf(CUMO_F16_TO_F(x)))
|
|
68
|
+
#define m_trunc(x) CUMO_F_TO_F16(truncf(CUMO_F16_TO_F(x)))
|
|
69
|
+
#define m_rint(x) CUMO_F_TO_F16(rintf(CUMO_F16_TO_F(x)))
|
|
70
|
+
#define m_sign(x) CUMO_F_TO_F16(cumo_f16_sign(CUMO_F16_TO_F(x)))
|
|
71
|
+
#define m_copysign(x,y) CUMO_F_TO_F16(copysignf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
72
|
+
#define m_signbit(x) signbit(CUMO_F16_TO_F(x))
|
|
73
|
+
#define m_modf(x,y,z) {float cumo_f16_i; float cumo_f16_f = modff(CUMO_F16_TO_F(x),&cumo_f16_i); y = CUMO_F_TO_F16(cumo_f16_f); z = CUMO_F_TO_F16(cumo_f16_i);}
|
|
74
|
+
|
|
75
|
+
#define m_eq(x,y) (CUMO_F16_TO_F(x)==CUMO_F16_TO_F(y))
|
|
76
|
+
#define m_ne(x,y) (CUMO_F16_TO_F(x)!=CUMO_F16_TO_F(y))
|
|
77
|
+
#define m_gt(x,y) (CUMO_F16_TO_F(x)>CUMO_F16_TO_F(y))
|
|
78
|
+
#define m_ge(x,y) (CUMO_F16_TO_F(x)>=CUMO_F16_TO_F(y))
|
|
79
|
+
#define m_lt(x,y) (CUMO_F16_TO_F(x)<CUMO_F16_TO_F(y))
|
|
80
|
+
#define m_le(x,y) (CUMO_F16_TO_F(x)<=CUMO_F16_TO_F(y))
|
|
81
|
+
|
|
82
|
+
#define m_isnan(x) isnan(CUMO_F16_TO_F(x))
|
|
83
|
+
#define m_isinf(x) isinf(CUMO_F16_TO_F(x))
|
|
84
|
+
#define m_isposinf(x) (isinf(CUMO_F16_TO_F(x)) && signbit(CUMO_F16_TO_F(x))==0)
|
|
85
|
+
#define m_isneginf(x) (isinf(CUMO_F16_TO_F(x)) && signbit(CUMO_F16_TO_F(x)))
|
|
86
|
+
#define m_isfinite(x) isfinite(CUMO_F16_TO_F(x))
|
|
87
|
+
|
|
88
|
+
#define not_nan(x) cumo_f16_not_nan(x)
|
|
89
|
+
|
|
90
|
+
#define m_mulsum_init m_zero
|
|
91
|
+
|
|
92
|
+
#define m_sprintf(s,x) sprintf(s,"%g",CUMO_F16_TO_F(x))
|
|
93
|
+
|
|
94
|
+
#define m_sqrt(x) CUMO_F_TO_F16(sqrtf(CUMO_F16_TO_F(x)))
|
|
95
|
+
#define m_cbrt(x) CUMO_F_TO_F16(cbrtf(CUMO_F16_TO_F(x)))
|
|
96
|
+
#define m_log(x) CUMO_F_TO_F16(logf(CUMO_F16_TO_F(x)))
|
|
97
|
+
#define m_log2(x) CUMO_F_TO_F16(log2f(CUMO_F16_TO_F(x)))
|
|
98
|
+
#define m_log10(x) CUMO_F_TO_F16(log10f(CUMO_F16_TO_F(x)))
|
|
99
|
+
#define m_exp(x) CUMO_F_TO_F16(expf(CUMO_F16_TO_F(x)))
|
|
100
|
+
#define m_exp2(x) CUMO_F_TO_F16(exp2f(CUMO_F16_TO_F(x)))
|
|
101
|
+
#ifdef HAVE_EXP10
|
|
102
|
+
#define m_exp10(x) CUMO_F_TO_F16(exp10f(CUMO_F16_TO_F(x)))
|
|
103
|
+
#else
|
|
104
|
+
#define m_exp10(x) CUMO_F_TO_F16(powf(10.0f,CUMO_F16_TO_F(x)))
|
|
105
|
+
#endif
|
|
106
|
+
#define m_expm1(x) CUMO_F_TO_F16(expm1f(CUMO_F16_TO_F(x)))
|
|
107
|
+
#define m_log1p(x) CUMO_F_TO_F16(log1pf(CUMO_F16_TO_F(x)))
|
|
108
|
+
|
|
109
|
+
#define m_sin(x) CUMO_F_TO_F16(sinf(CUMO_F16_TO_F(x)))
|
|
110
|
+
#define m_cos(x) CUMO_F_TO_F16(cosf(CUMO_F16_TO_F(x)))
|
|
111
|
+
#define m_tan(x) CUMO_F_TO_F16(tanf(CUMO_F16_TO_F(x)))
|
|
112
|
+
#define m_asin(x) CUMO_F_TO_F16(asinf(CUMO_F16_TO_F(x)))
|
|
113
|
+
#define m_acos(x) CUMO_F_TO_F16(acosf(CUMO_F16_TO_F(x)))
|
|
114
|
+
#define m_atan(x) CUMO_F_TO_F16(atanf(CUMO_F16_TO_F(x)))
|
|
115
|
+
#define m_sinh(x) CUMO_F_TO_F16(sinhf(CUMO_F16_TO_F(x)))
|
|
116
|
+
#define m_cosh(x) CUMO_F_TO_F16(coshf(CUMO_F16_TO_F(x)))
|
|
117
|
+
#define m_tanh(x) CUMO_F_TO_F16(tanhf(CUMO_F16_TO_F(x)))
|
|
118
|
+
#define m_asinh(x) CUMO_F_TO_F16(asinhf(CUMO_F16_TO_F(x)))
|
|
119
|
+
#define m_acosh(x) CUMO_F_TO_F16(acoshf(CUMO_F16_TO_F(x)))
|
|
120
|
+
#define m_atanh(x) CUMO_F_TO_F16(atanhf(CUMO_F16_TO_F(x)))
|
|
121
|
+
#define m_atan2(x,y) CUMO_F_TO_F16(atan2f(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
122
|
+
#define m_hypot(x,y) CUMO_F_TO_F16(hypotf(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
123
|
+
#define m_sinc(x) CUMO_F_TO_F16(cumo_f16_sinc(CUMO_F16_TO_F(x)))
|
|
124
|
+
|
|
125
|
+
#define m_erf(x) CUMO_F_TO_F16(erff(CUMO_F16_TO_F(x)))
|
|
126
|
+
#define m_erfc(x) CUMO_F_TO_F16(erfcf(CUMO_F16_TO_F(x)))
|
|
127
|
+
#define m_gelu(x) CUMO_F_TO_F16(cumo_f16_gelu(CUMO_F16_TO_F(x)))
|
|
128
|
+
#define m_gelu_tanh(x) CUMO_F_TO_F16(cumo_f16_gelu_tanh(CUMO_F16_TO_F(x)))
|
|
129
|
+
#define m_silu(x) CUMO_F_TO_F16(cumo_f16_silu(CUMO_F16_TO_F(x)))
|
|
130
|
+
#define m_ldexp(x,y) CUMO_F_TO_F16(cumo_f16_ldexp(CUMO_F16_TO_F(x),CUMO_F16_TO_F(y)))
|
|
131
|
+
#define m_frexp(x,exp) CUMO_F_TO_F16(frexpf(CUMO_F16_TO_F(x),exp))
|
|
132
|
+
|
|
133
|
+
__host__ __device__ static inline float cumo_f16_pow_positive_int(float x, unsigned int p)
|
|
134
|
+
{
|
|
135
|
+
float r = 1.0f;
|
|
136
|
+
switch (p) {
|
|
137
|
+
case 0: return 1.0f;
|
|
138
|
+
case 1: return x;
|
|
139
|
+
case 2: return x*x;
|
|
140
|
+
case 3: return x*x*x;
|
|
141
|
+
case 4: x = x*x; return x*x;
|
|
142
|
+
}
|
|
143
|
+
if (p > 64) return powf(x, (float)p);
|
|
144
|
+
while (p) {
|
|
145
|
+
if (p & 1) r *= x;
|
|
146
|
+
x *= x;
|
|
147
|
+
p >>= 1;
|
|
148
|
+
}
|
|
149
|
+
return r;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
__host__ __device__ static inline float cumo_f16_pow_int(float x, int p)
|
|
153
|
+
{
|
|
154
|
+
if (p < 0) return 1.0f / cumo_f16_pow_positive_int(x, -(unsigned int)p);
|
|
155
|
+
return cumo_f16_pow_positive_int(x, (unsigned int)p);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// The bit-pattern intrinsics are device-only before CUDA 12, so the bits are
|
|
159
|
+
// taken the way a host caller can take them too.
|
|
160
|
+
__host__ __device__ static inline dtype cumo_f16_step_down(dtype h)
|
|
161
|
+
{
|
|
162
|
+
unsigned short b;
|
|
163
|
+
dtype r;
|
|
164
|
+
memcpy(&b, &h, sizeof(b));
|
|
165
|
+
if (b == 0x0000u) {
|
|
166
|
+
b = 0x8001u;
|
|
167
|
+
} else {
|
|
168
|
+
b = (unsigned short)((b & 0x8000u) ? (b + 1) : (b - 1));
|
|
169
|
+
}
|
|
170
|
+
memcpy(&r, &b, sizeof(b));
|
|
171
|
+
return r;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
__host__ __device__ static inline float cumo_f16_ldexp(float x, float y)
|
|
175
|
+
{
|
|
176
|
+
if (!(y == y)) return y;
|
|
177
|
+
if (y > 64.0f) y = 64.0f;
|
|
178
|
+
if (y < -64.0f) y = -64.0f;
|
|
179
|
+
return ldexpf(x, (int)y);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
__host__ __device__ static inline float cumo_f16_sinc(float x)
|
|
183
|
+
{
|
|
184
|
+
return (x==0) ? 1.0f : (sinf(x)/x);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
__host__ __device__ static inline float cumo_f16_sign(float x)
|
|
188
|
+
{
|
|
189
|
+
return (x==0) ? 0.0f : ((x>0) ? 1.0f : ((x<0) ? -1.0f : x));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
__host__ __device__ static inline dtype f_seq(dtype x, dtype y, double c)
|
|
193
|
+
{
|
|
194
|
+
return CUMO_F_TO_F16(CUMO_F16_TO_F(x) + CUMO_F16_TO_F(y) * (float)c);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#include "real_accum_kernel.h"
|
|
198
|
+
|
|
199
|
+
__host__ __device__ static inline float cumo_f16_gelu(float x)
|
|
200
|
+
{
|
|
201
|
+
return 0.5f * x * (1.0f + erff(x * (float)CUMO_M_SQRT1_2));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// The approximation GPT-2 and the transformers after it were trained with.
|
|
205
|
+
__host__ __device__ static inline float cumo_f16_gelu_tanh(float x)
|
|
206
|
+
{
|
|
207
|
+
return 0.5f * x * (1.0f + tanhf((float)CUMO_M_SQRT_2_OVER_PI * (x + (float)CUMO_GELU_TANH_CUBIC * x * x * x)));
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// x * sigmoid(x) as one division, cumo having no sigmoid to call.
|
|
211
|
+
__host__ __device__ static inline float cumo_f16_silu(float x)
|
|
212
|
+
{
|
|
213
|
+
return x / (1.0f + expf(-x));
|
|
214
|
+
}
|
|
@@ -32,3 +32,11 @@
|
|
|
32
32
|
#ifndef M_LN10
|
|
33
33
|
#define M_LN10 2.30258509299404568402 /* log_e 10 */
|
|
34
34
|
#endif
|
|
35
|
+
|
|
36
|
+
/* The constants the two gelu forms are written with, spelled once on each side
|
|
37
|
+
so the macro headers cannot drift a digit apart. */
|
|
38
|
+
#ifndef CUMO_M_SQRT1_2
|
|
39
|
+
#define CUMO_M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
|
40
|
+
#define CUMO_M_SQRT_2_OVER_PI 0.79788456080286535588 /* sqrt(2/pi) */
|
|
41
|
+
#define CUMO_GELU_TANH_CUBIC 0.044715 /* fitted, not a closed form */
|
|
42
|
+
#endif
|
|
@@ -36,4 +36,12 @@
|
|
|
36
36
|
#define M_LN10 2.30258509299404568402 /* log_e 10 */
|
|
37
37
|
#endif
|
|
38
38
|
|
|
39
|
+
/* The constants the two gelu forms are written with, spelled once on each side
|
|
40
|
+
so the macro headers cannot drift a digit apart. */
|
|
41
|
+
#ifndef CUMO_M_SQRT1_2
|
|
42
|
+
#define CUMO_M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
|
43
|
+
#define CUMO_M_SQRT_2_OVER_PI 0.79788456080286535588 /* sqrt(2/pi) */
|
|
44
|
+
#define CUMO_GELU_TANH_CUBIC 0.044715 /* fitted, not a closed form */
|
|
45
|
+
#endif
|
|
46
|
+
|
|
39
47
|
#endif // CUMO_FLOAT_DEF_KERNEL_H
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#include "float_def.h"
|
|
2
2
|
#include "half_def.h"
|
|
3
|
+
#include "bf16_def.h"
|
|
3
4
|
|
|
4
5
|
extern double round(double);
|
|
5
6
|
extern double log2(double);
|
|
@@ -19,6 +20,7 @@ extern double pow(double, double);
|
|
|
19
20
|
#define m_from_double(x) (x)
|
|
20
21
|
#define m_from_real(x) (x)
|
|
21
22
|
#define m_from_half(x) m_from_real(cumo_half2float(x))
|
|
23
|
+
#define m_from_bfloat(x) m_from_real(cumo_bfloat2float(x))
|
|
22
24
|
#define m_from_sint(x) (x)
|
|
23
25
|
#define m_from_int32(x) (x)
|
|
24
26
|
#define m_from_int64(x) (x)
|
|
@@ -79,23 +81,6 @@ static inline dtype m_floored_mod(dtype x, dtype y) {
|
|
|
79
81
|
|
|
80
82
|
#define m_sprintf(s,x) sprintf(s,"%g",x)
|
|
81
83
|
|
|
82
|
-
#define cmp_prnan(a,b) \
|
|
83
|
-
((qsort_cast(a)==qsort_cast(b)) ? 0 : \
|
|
84
|
-
(qsort_cast(a) > qsort_cast(b)) ? 1 : -1)
|
|
85
|
-
|
|
86
|
-
#define cmp_ignan(a,b) \
|
|
87
|
-
(m_isnan(qsort_cast(a)) ? (m_isnan(qsort_cast(b)) ? 0 : 1) : \
|
|
88
|
-
(m_isnan(qsort_cast(b)) ? -1 : \
|
|
89
|
-
((qsort_cast(a)==qsort_cast(b)) ? 0 : \
|
|
90
|
-
(qsort_cast(a) > qsort_cast(b)) ? 1 : -1)))
|
|
91
|
-
|
|
92
|
-
#define cmpgt_prnan(a,b) \
|
|
93
|
-
(qsort_cast(a) > qsort_cast(b))
|
|
94
|
-
|
|
95
|
-
#define cmpgt_ignan(a,b) \
|
|
96
|
-
((m_isnan(qsort_cast(a)) && !m_isnan(qsort_cast(b))) || \
|
|
97
|
-
(qsort_cast(a) > qsort_cast(b)))
|
|
98
|
-
|
|
99
84
|
#define m_sqrt(x) sqrt(x)
|
|
100
85
|
#define m_cbrt(x) cbrt(x)
|
|
101
86
|
#define m_log(x) log(x)
|
|
@@ -129,6 +114,9 @@ static inline dtype m_floored_mod(dtype x, dtype y) {
|
|
|
129
114
|
|
|
130
115
|
#define m_erf(x) erf(x)
|
|
131
116
|
#define m_erfc(x) erfc(x)
|
|
117
|
+
#define m_gelu(x) cumo_gelu(x)
|
|
118
|
+
#define m_gelu_tanh(x) cumo_gelu_tanh(x)
|
|
119
|
+
#define m_silu(x) cumo_silu(x)
|
|
132
120
|
#define m_ldexp(x,y) ldexp(x,y)
|
|
133
121
|
#define m_frexp(x,exp) frexp(x,exp)
|
|
134
122
|
|
|
@@ -209,3 +197,24 @@ static inline dtype f_kahan_sum_nan(size_t n, char *p, ssize_t stride)
|
|
|
209
197
|
}
|
|
210
198
|
|
|
211
199
|
#include "real_accum.h"
|
|
200
|
+
|
|
201
|
+
// Typed by the dtype so that a float array reaches erff and tanhf. A helper
|
|
202
|
+
// taking double instead widens every element and runs the fp64 routines, which
|
|
203
|
+
// this card answers an order of magnitude slower than the fp32 ones.
|
|
204
|
+
static inline dtype cumo_gelu(dtype x)
|
|
205
|
+
{
|
|
206
|
+
return (dtype)0.5 * x * ((dtype)1 + erf(x * (dtype)CUMO_M_SQRT1_2));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// The approximation GPT-2 and the transformers after it were trained with.
|
|
210
|
+
static inline dtype cumo_gelu_tanh(dtype x)
|
|
211
|
+
{
|
|
212
|
+
return (dtype)0.5 * x * ((dtype)1 + tanh((dtype)CUMO_M_SQRT_2_OVER_PI *
|
|
213
|
+
(x + (dtype)CUMO_GELU_TANH_CUBIC * x * x * x)));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// x * sigmoid(x) as one division, cumo having no sigmoid to call.
|
|
217
|
+
static inline dtype cumo_silu(dtype x)
|
|
218
|
+
{
|
|
219
|
+
return x / ((dtype)1 + exp(-x));
|
|
220
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
#include "float_def_kernel.h"
|
|
5
5
|
#include "half_def_kernel.h"
|
|
6
|
+
#include "bf16_def_kernel.h"
|
|
6
7
|
|
|
7
8
|
extern double round(double);
|
|
8
9
|
extern double log2(double);
|
|
@@ -22,6 +23,7 @@ extern double pow(double, double);
|
|
|
22
23
|
#define m_from_double(x) (x)
|
|
23
24
|
#define m_from_real(x) (x)
|
|
24
25
|
#define m_from_half(x) m_from_real(cumo_half2float(x))
|
|
26
|
+
#define m_from_bfloat(x) m_from_real(cumo_bfloat2float(x))
|
|
25
27
|
#define m_from_sint(x) (x)
|
|
26
28
|
#define m_from_int32(x) (x)
|
|
27
29
|
#define m_from_int64(x) (x)
|
|
@@ -82,25 +84,6 @@ __host__ __device__ static inline dtype m_floored_mod(dtype x, dtype y) {
|
|
|
82
84
|
|
|
83
85
|
#define m_sprintf(s,x) sprintf(s,"%g",x)
|
|
84
86
|
|
|
85
|
-
/*
|
|
86
|
-
#define cmp_prnan(a,b) \
|
|
87
|
-
((qsort_cast(a)==qsort_cast(b)) ? 0 : \
|
|
88
|
-
(qsort_cast(a) > qsort_cast(b)) ? 1 : -1)
|
|
89
|
-
|
|
90
|
-
#define cmp_ignan(a,b) \
|
|
91
|
-
(m_isnan(qsort_cast(a)) ? (m_isnan(qsort_cast(b)) ? 0 : 1) : \
|
|
92
|
-
(m_isnan(qsort_cast(b)) ? -1 : \
|
|
93
|
-
((qsort_cast(a)==qsort_cast(b)) ? 0 : \
|
|
94
|
-
(qsort_cast(a) > qsort_cast(b)) ? 1 : -1)))
|
|
95
|
-
|
|
96
|
-
#define cmpgt_prnan(a,b) \
|
|
97
|
-
(qsort_cast(a) > qsort_cast(b))
|
|
98
|
-
|
|
99
|
-
#define cmpgt_ignan(a,b) \
|
|
100
|
-
((m_isnan(qsort_cast(a)) && !m_isnan(qsort_cast(b))) || \
|
|
101
|
-
(qsort_cast(a) > qsort_cast(b)))
|
|
102
|
-
*/
|
|
103
|
-
|
|
104
87
|
#define m_sqrt(x) sqrt(x)
|
|
105
88
|
#define m_cbrt(x) cbrt(x)
|
|
106
89
|
#define m_log(x) log(x)
|
|
@@ -134,6 +117,9 @@ __host__ __device__ static inline dtype m_floored_mod(dtype x, dtype y) {
|
|
|
134
117
|
|
|
135
118
|
#define m_erf(x) erf(x)
|
|
136
119
|
#define m_erfc(x) erfc(x)
|
|
120
|
+
#define m_gelu(x) cumo_gelu(x)
|
|
121
|
+
#define m_gelu_tanh(x) cumo_gelu_tanh(x)
|
|
122
|
+
#define m_silu(x) cumo_silu(x)
|
|
137
123
|
#define m_ldexp(x,y) ldexp(x,y)
|
|
138
124
|
#define m_frexp(x,exp) frexp(x,exp)
|
|
139
125
|
|
|
@@ -172,4 +158,25 @@ __host__ __device__ static inline dtype f_seq(dtype x, dtype y, double c)
|
|
|
172
158
|
|
|
173
159
|
#include "real_accum_kernel.h"
|
|
174
160
|
|
|
161
|
+
// Typed by the dtype so that a float array reaches erff and tanhf. A helper
|
|
162
|
+
// taking double instead widens every element and runs the fp64 routines, which
|
|
163
|
+
// this card answers an order of magnitude slower than the fp32 ones.
|
|
164
|
+
__host__ __device__ static inline dtype cumo_gelu(dtype x)
|
|
165
|
+
{
|
|
166
|
+
return (dtype)0.5 * x * ((dtype)1 + erf(x * (dtype)CUMO_M_SQRT1_2));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// The approximation GPT-2 and the transformers after it were trained with.
|
|
170
|
+
__host__ __device__ static inline dtype cumo_gelu_tanh(dtype x)
|
|
171
|
+
{
|
|
172
|
+
return (dtype)0.5 * x * ((dtype)1 + tanh((dtype)CUMO_M_SQRT_2_OVER_PI *
|
|
173
|
+
(x + (dtype)CUMO_GELU_TANH_CUBIC * x * x * x)));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// x * sigmoid(x) as one division, cumo having no sigmoid to call.
|
|
177
|
+
__host__ __device__ static inline dtype cumo_silu(dtype x)
|
|
178
|
+
{
|
|
179
|
+
return x / ((dtype)1 + exp(-x));
|
|
180
|
+
}
|
|
181
|
+
|
|
175
182
|
#endif // CUMO_FLOAT_MACRO_KERNEL_H
|