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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +590 -152
  3. data/CHANGELOG.md +63 -0
  4. data/README.md +245 -0
  5. data/bench/cumo_probe.rb +1 -1
  6. data/cumo.gemspec +7 -1
  7. data/ext/cumo/cuda/cudnn.c +18 -0
  8. data/ext/cumo/cuda/cudnn_impl.cpp +60 -14
  9. data/ext/cumo/cuda/driver.c +11 -9
  10. data/ext/cumo/cuda/memory_pool_impl.cpp +32 -22
  11. data/ext/cumo/cuda/memory_pool_impl.hpp +3 -1
  12. data/ext/cumo/cuda/memory_pool_impl_test.cpp +19 -25
  13. data/ext/cumo/cuda/runtime.c +56 -0
  14. data/ext/cumo/cumo.c +4 -0
  15. data/ext/cumo/extconf.rb +2 -0
  16. data/ext/cumo/include/cumo/bit_reduce_kernel.h +6 -6
  17. data/ext/cumo/include/cumo/check.h +11 -3
  18. data/ext/cumo/include/cumo/cuda/cudnn.h +43 -6
  19. data/ext/cumo/include/cumo/cuda/runtime.h +2 -0
  20. data/ext/cumo/include/cumo/indexer.h +16 -0
  21. data/ext/cumo/include/cumo/intern.h +11 -0
  22. data/ext/cumo/include/cumo/narray.h +1 -0
  23. data/ext/cumo/include/cumo/reduce_kernel.h +283 -54
  24. data/ext/cumo/include/cumo/row_kernel.h +202 -0
  25. data/ext/cumo/include/cumo/row_method.h +149 -0
  26. data/ext/cumo/include/cumo/template_kernel.h +26 -0
  27. data/ext/cumo/include/cumo/types/bf16_def.h +82 -0
  28. data/ext/cumo/include/cumo/types/bf16_def_kernel.h +28 -0
  29. data/ext/cumo/include/cumo/types/bf16_macro.h +14 -0
  30. data/ext/cumo/include/cumo/types/bf16_macro_kernel.h +19 -0
  31. data/ext/cumo/include/cumo/types/bfloat.h +22 -0
  32. data/ext/cumo/include/cumo/types/bfloat_kernel.h +16 -0
  33. data/ext/cumo/include/cumo/types/bit.h +2 -0
  34. data/ext/cumo/include/cumo/types/bit_kernel.h +2 -0
  35. data/ext/cumo/include/cumo/types/complex_macro.h +2 -0
  36. data/ext/cumo/include/cumo/types/complex_macro_kernel.h +2 -0
  37. data/ext/cumo/include/cumo/types/f16_macro.h +191 -0
  38. data/ext/cumo/include/cumo/types/f16_macro_kernel.h +214 -0
  39. data/ext/cumo/include/cumo/types/float_def.h +8 -0
  40. data/ext/cumo/include/cumo/types/float_def_kernel.h +8 -0
  41. data/ext/cumo/include/cumo/types/float_macro.h +26 -17
  42. data/ext/cumo/include/cumo/types/float_macro_kernel.h +26 -19
  43. data/ext/cumo/include/cumo/types/half_macro.h +6 -180
  44. data/ext/cumo/include/cumo/types/half_macro_kernel.h +6 -185
  45. data/ext/cumo/include/cumo/types/robj_macro.h +2 -0
  46. data/ext/cumo/include/cumo/types/xint_macro.h +2 -6
  47. data/ext/cumo/include/cumo/types/xint_macro_kernel.h +2 -0
  48. data/ext/cumo/include/cumo.h +2 -2
  49. data/ext/cumo/narray/data.c +15 -6
  50. data/ext/cumo/narray/data_kernel.cu +110 -0
  51. data/ext/cumo/narray/gen/def/bfloat.rb +57 -0
  52. data/ext/cumo/narray/gen/def/bit.rb +12 -1
  53. data/ext/cumo/narray/gen/def/dcomplex.rb +12 -1
  54. data/ext/cumo/narray/gen/def/dfloat.rb +11 -1
  55. data/ext/cumo/narray/gen/def/hfloat.rb +11 -1
  56. data/ext/cumo/narray/gen/def/int16.rb +12 -1
  57. data/ext/cumo/narray/gen/def/int32.rb +12 -1
  58. data/ext/cumo/narray/gen/def/int64.rb +12 -1
  59. data/ext/cumo/narray/gen/def/int8.rb +12 -1
  60. data/ext/cumo/narray/gen/def/robject.rb +12 -1
  61. data/ext/cumo/narray/gen/def/scomplex.rb +12 -1
  62. data/ext/cumo/narray/gen/def/sfloat.rb +11 -1
  63. data/ext/cumo/narray/gen/def/uint16.rb +12 -1
  64. data/ext/cumo/narray/gen/def/uint32.rb +12 -1
  65. data/ext/cumo/narray/gen/def/uint64.rb +12 -1
  66. data/ext/cumo/narray/gen/def/uint8.rb +12 -1
  67. data/ext/cumo/narray/gen/narray_def.rb +35 -6
  68. data/ext/cumo/narray/gen/spec.rb +14 -14
  69. data/ext/cumo/narray/gen/tmpl/accum_arg.c +1 -1
  70. data/ext/cumo/narray/gen/tmpl/accum_binary.c +63 -5
  71. data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +29 -13
  72. data/ext/cumo/narray/gen/tmpl/accum_index.c +1 -1
  73. data/ext/cumo/narray/gen/tmpl/batch_norm.c +4 -4
  74. data/ext/cumo/narray/gen/tmpl/batch_norm_backward.c +5 -5
  75. data/ext/cumo/narray/gen/tmpl/binary.c +3 -9
  76. data/ext/cumo/narray/gen/tmpl/complex_accum_kernel.cu +15 -5
  77. data/ext/cumo/narray/gen/tmpl/conv.c +90 -123
  78. data/ext/cumo/narray/gen/tmpl/conv_grad_w.c +91 -83
  79. data/ext/cumo/narray/gen/tmpl/conv_transpose.c +90 -123
  80. data/ext/cumo/narray/gen/tmpl/cum.c +8 -7
  81. data/ext/cumo/narray/gen/tmpl/cum_kernel.cu +7 -6
  82. data/ext/cumo/narray/gen/tmpl/fixed_batch_norm.c +4 -4
  83. data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +22 -10
  84. data/ext/cumo/narray/gen/tmpl/gemm.c +11 -41
  85. data/ext/cumo/narray/gen/tmpl/layer_norm.c +38 -0
  86. data/ext/cumo/narray/gen/tmpl/layer_norm_kernel.cu +54 -0
  87. data/ext/cumo/narray/gen/tmpl/lib.c +1 -0
  88. data/ext/cumo/narray/gen/tmpl/lib_kernel.cu +1 -0
  89. data/ext/cumo/narray/gen/tmpl/median.c +1 -1
  90. data/ext/cumo/narray/gen/tmpl/poly.c +0 -3
  91. data/ext/cumo/narray/gen/tmpl/poly_kernel.cu +1 -1
  92. data/ext/cumo/narray/gen/tmpl/pooling_backward.c +3 -2
  93. data/ext/cumo/narray/gen/tmpl/pooling_forward.c +3 -2
  94. data/ext/cumo/narray/gen/tmpl/quantize_symmetric.c +74 -0
  95. data/ext/cumo/narray/gen/tmpl/quantize_symmetric_kernel.cu +67 -0
  96. data/ext/cumo/narray/gen/tmpl/rand.c +9 -9
  97. data/ext/cumo/narray/gen/tmpl/rand_kernel.cu +9 -9
  98. data/ext/cumo/narray/gen/tmpl/rand_norm.c +4 -4
  99. data/ext/cumo/narray/gen/tmpl/rand_norm_kernel.cu +7 -7
  100. data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +6 -6
  101. data/ext/cumo/narray/gen/tmpl/rms_norm.c +38 -0
  102. data/ext/cumo/narray/gen/tmpl/rms_norm_kernel.cu +57 -0
  103. data/ext/cumo/narray/gen/tmpl/softmax.c +21 -0
  104. data/ext/cumo/narray/gen/tmpl/softmax_kernel.cu +157 -0
  105. data/ext/cumo/narray/gen/tmpl/sort.c +9 -32
  106. data/ext/cumo/narray/gen/tmpl/sort_index.c +16 -95
  107. data/ext/cumo/narray/gen/tmpl/store_array.c +12 -9
  108. data/ext/cumo/narray/gen/tmpl/store_from.c +1 -16
  109. data/ext/cumo/narray/gen/tmpl_bit/mask.c +11 -11
  110. data/ext/cumo/narray/gen/tmpl_bit/store_array.c +5 -9
  111. data/ext/cumo/narray/gen/tmpl_bit/where.c +50 -11
  112. data/ext/cumo/narray/gen/tmpl_bit/where2.c +11 -12
  113. data/ext/cumo/narray/gen/tmpl_bit/where_kernel.cu +1 -2
  114. data/ext/cumo/narray/index.c +35 -25
  115. data/ext/cumo/narray/index_kernel.cu +27 -0
  116. data/ext/cumo/narray/math.c +40 -8
  117. data/ext/cumo/narray/narray.c +85 -15
  118. data/ext/cumo/narray/ndloop.c +210 -5
  119. data/ext/cumo/narray/sort_kernel.cu +61 -41
  120. data/ext/cumo/narray/struct.c +3 -0
  121. data/lib/cumo/cuda/cudnn.rb +1 -1
  122. data/lib/cumo/narray/extra.rb +2 -2
  123. data/test/bfloat_test.rb +238 -0
  124. data/test/bit_test.rb +52 -14
  125. data/test/cuda/memory_pool_test.rb +8 -7
  126. data/test/cuda/runtime_test.rb +25 -0
  127. data/test/cudnn_test.rb +108 -24
  128. data/test/extra_test.rb +1 -1
  129. data/test/fused_test.rb +587 -0
  130. data/test/math_test.rb +182 -2
  131. data/test/narray_alt_coverage_test.rb +1 -0
  132. data/test/narray_test.rb +344 -22
  133. data/test/test_helper.rb +1 -0
  134. metadata +32 -5
  135. data/ext/cumo/narray/gen/tmpl/qsort.c +0 -205
@@ -1,188 +1,14 @@
1
1
  #include "float_def.h"
2
+ #include "bf16_def.h"
2
3
  #include "half_def.h"
3
4
 
4
5
  #define CUMO_HALF_EPSILON 9.765625e-04f
5
6
 
6
- #define m_zero cumo_float2half(0.0f)
7
- #define m_one cumo_float2half(1.0f)
7
+ #define CUMO_F16_TO_F(x) cumo_half2float(x)
8
+ #define CUMO_F_TO_F16(x) cumo_float2half(x)
9
+ #define CUMO_D_TO_F16(x) cumo_double2half(x)
8
10
 
9
- #define m_num_to_data(x) cumo_na_ruby_num_to_half(x)
10
- #define m_data_to_num(x) rb_float_new(cumo_half2float(x))
11
-
12
- #define m_from_double(x) cumo_double2half((double)(x))
13
- #define m_from_real(x) cumo_double2half((double)(x))
14
- #define m_from_sint(x) cumo_double2half((double)(x))
15
- #define m_from_int32(x) cumo_double2half((double)(x))
16
- #define m_from_int64(x) cumo_double2half((double)(x))
17
- #define m_from_uint32(x) cumo_double2half((double)(x))
18
- #define m_from_uint64(x) cumo_double2half((double)(x))
19
11
  #define m_from_half(x) (x)
12
+ #define m_from_bfloat(x) cumo_float2half(cumo_bfloat2float(x))
20
13
 
21
- #define m_add(x,y) cumo_float2half(cumo_half2float(x)+cumo_half2float(y))
22
- #define m_sub(x,y) cumo_float2half(cumo_half2float(x)-cumo_half2float(y))
23
- #define m_mul(x,y) cumo_float2half(cumo_half2float(x)*cumo_half2float(y))
24
- #define m_div(x,y) cumo_float2half(cumo_half2float(x)/cumo_half2float(y))
25
- #define m_div_check(x,y) (cumo_half2float(y)==0)
26
-
27
- static inline float cumo_half_floored_mod(float x, float y)
28
- {
29
- float r = fmodf(x,y);
30
- if (r != 0 && ((r < 0) != (y < 0))) {
31
- r += y;
32
- }
33
- return r;
34
- }
35
-
36
- #define m_mod(x,y) cumo_float2half(cumo_half_floored_mod(cumo_half2float(x),cumo_half2float(y)))
37
- #define m_divmod(x,y,a,b) \
38
- {float cumo_h_x = cumo_half2float(x), cumo_h_y = cumo_half2float(y); \
39
- float cumo_h_b = fmodf(cumo_h_x,cumo_h_y); \
40
- float cumo_h_a = roundf((cumo_h_x-cumo_h_b)/cumo_h_y); \
41
- if (cumo_h_b != 0 && ((cumo_h_b < 0) != (cumo_h_y < 0))) { \
42
- cumo_h_b += cumo_h_y; cumo_h_a -= 1; \
43
- } \
44
- a = cumo_float2half(cumo_h_a); b = cumo_float2half(cumo_h_b);}
45
- #define m_pow(x,y) cumo_float2half(powf(cumo_half2float(x),cumo_half2float(y)))
46
- #define m_pow_int(x,y) cumo_float2half(cumo_half_pow_int(cumo_half2float(x),(int)(y)))
47
-
48
- #define m_abs(x) cumo_float2half(fabsf(cumo_half2float(x)))
49
- #define m_minus(x) cumo_float2half(-cumo_half2float(x))
50
- #define m_reciprocal(x) cumo_float2half(1.0f/cumo_half2float(x))
51
- #define m_square(x) cumo_float2half(cumo_half2float(x)*cumo_half2float(x))
52
- #define m_floor(x) cumo_float2half(floorf(cumo_half2float(x)))
53
- #define m_round(x) cumo_float2half(roundf(cumo_half2float(x)))
54
- #define m_ceil(x) cumo_float2half(ceilf(cumo_half2float(x)))
55
- #define m_trunc(x) cumo_float2half(truncf(cumo_half2float(x)))
56
- #define m_rint(x) cumo_float2half(rintf(cumo_half2float(x)))
57
- #define m_sign(x) cumo_float2half(cumo_half_sign(cumo_half2float(x)))
58
- #define m_copysign(x,y) cumo_float2half(copysignf(cumo_half2float(x),cumo_half2float(y)))
59
- #define m_signbit(x) signbit(cumo_half2float(x))
60
- #define m_modf(x,y,z) {float cumo_h_i; float cumo_h_f = modff(cumo_half2float(x),&cumo_h_i); y = cumo_float2half(cumo_h_f); z = cumo_float2half(cumo_h_i);}
61
-
62
- #define m_eq(x,y) (cumo_half2float(x)==cumo_half2float(y))
63
- #define m_ne(x,y) (cumo_half2float(x)!=cumo_half2float(y))
64
- #define m_gt(x,y) (cumo_half2float(x)>cumo_half2float(y))
65
- #define m_ge(x,y) (cumo_half2float(x)>=cumo_half2float(y))
66
- #define m_lt(x,y) (cumo_half2float(x)<cumo_half2float(y))
67
- #define m_le(x,y) (cumo_half2float(x)<=cumo_half2float(y))
68
-
69
- #define m_isnan(x) isnan(cumo_half2float(x))
70
- #define m_isinf(x) isinf(cumo_half2float(x))
71
- #define m_isposinf(x) (isinf(cumo_half2float(x)) && signbit(cumo_half2float(x))==0)
72
- #define m_isneginf(x) (isinf(cumo_half2float(x)) && signbit(cumo_half2float(x)))
73
- #define m_isfinite(x) isfinite(cumo_half2float(x))
74
-
75
- #define not_nan(x) (cumo_half2float(x)==cumo_half2float(x))
76
-
77
- #define m_mulsum_init INT2FIX(0)
78
-
79
- #define m_sprintf(s,x) sprintf(s,"%g",cumo_half2float(x))
80
-
81
- #define cmp_prnan(a,b) \
82
- ((cumo_half2float(qsort_cast(a))==cumo_half2float(qsort_cast(b))) ? 0 : \
83
- (cumo_half2float(qsort_cast(a)) > cumo_half2float(qsort_cast(b))) ? 1 : -1)
84
-
85
- #define cmp_ignan(a,b) \
86
- (m_isnan(qsort_cast(a)) ? (m_isnan(qsort_cast(b)) ? 0 : 1) : \
87
- (m_isnan(qsort_cast(b)) ? -1 : \
88
- ((cumo_half2float(qsort_cast(a))==cumo_half2float(qsort_cast(b))) ? 0 : \
89
- (cumo_half2float(qsort_cast(a)) > cumo_half2float(qsort_cast(b))) ? 1 : -1)))
90
-
91
- #define cmpgt_prnan(a,b) \
92
- (cumo_half2float(qsort_cast(a)) > cumo_half2float(qsort_cast(b)))
93
-
94
- #define cmpgt_ignan(a,b) \
95
- ((m_isnan(qsort_cast(a)) && !m_isnan(qsort_cast(b))) || \
96
- (cumo_half2float(qsort_cast(a)) > cumo_half2float(qsort_cast(b))))
97
-
98
- #define m_sqrt(x) cumo_float2half(sqrtf(cumo_half2float(x)))
99
- #define m_cbrt(x) cumo_float2half(cbrtf(cumo_half2float(x)))
100
- #define m_log(x) cumo_float2half(logf(cumo_half2float(x)))
101
- #define m_log2(x) cumo_float2half(log2f(cumo_half2float(x)))
102
- #define m_log10(x) cumo_float2half(log10f(cumo_half2float(x)))
103
- #define m_exp(x) cumo_float2half(expf(cumo_half2float(x)))
104
- #define m_exp2(x) cumo_float2half(exp2f(cumo_half2float(x)))
105
- #ifdef HAVE_EXP10
106
- #define m_exp10(x) cumo_float2half(exp10f(cumo_half2float(x)))
107
- #else
108
- #define m_exp10(x) cumo_float2half(powf(10.0f,cumo_half2float(x)))
109
- #endif
110
- #define m_expm1(x) cumo_float2half(expm1f(cumo_half2float(x)))
111
- #define m_log1p(x) cumo_float2half(log1pf(cumo_half2float(x)))
112
-
113
- #define m_sin(x) cumo_float2half(sinf(cumo_half2float(x)))
114
- #define m_cos(x) cumo_float2half(cosf(cumo_half2float(x)))
115
- #define m_tan(x) cumo_float2half(tanf(cumo_half2float(x)))
116
- #define m_asin(x) cumo_float2half(asinf(cumo_half2float(x)))
117
- #define m_acos(x) cumo_float2half(acosf(cumo_half2float(x)))
118
- #define m_atan(x) cumo_float2half(atanf(cumo_half2float(x)))
119
- #define m_sinh(x) cumo_float2half(sinhf(cumo_half2float(x)))
120
- #define m_cosh(x) cumo_float2half(coshf(cumo_half2float(x)))
121
- #define m_tanh(x) cumo_float2half(tanhf(cumo_half2float(x)))
122
- #define m_asinh(x) cumo_float2half(asinhf(cumo_half2float(x)))
123
- #define m_acosh(x) cumo_float2half(acoshf(cumo_half2float(x)))
124
- #define m_atanh(x) cumo_float2half(atanhf(cumo_half2float(x)))
125
- #define m_atan2(x,y) cumo_float2half(atan2f(cumo_half2float(x),cumo_half2float(y)))
126
- #define m_hypot(x,y) cumo_float2half(hypotf(cumo_half2float(x),cumo_half2float(y)))
127
- #define m_sinc(x) cumo_float2half(cumo_half_sinc(cumo_half2float(x)))
128
-
129
- #define m_erf(x) cumo_float2half(erff(cumo_half2float(x)))
130
- #define m_erfc(x) cumo_float2half(erfcf(cumo_half2float(x)))
131
- #define m_ldexp(x,y) cumo_float2half(cumo_half_ldexp(cumo_half2float(x),cumo_half2float(y)))
132
- #define m_frexp(x,exp) cumo_float2half(frexpf(cumo_half2float(x),exp))
133
-
134
-
135
- static inline float cumo_half_pow_positive_int(float x, unsigned int p)
136
- {
137
- float r = 1.0f;
138
- switch (p) {
139
- case 0: return 1.0f;
140
- case 1: return x;
141
- case 2: return x*x;
142
- case 3: return x*x*x;
143
- case 4: x = x*x; return x*x;
144
- }
145
- if (p > 64) return powf(x, (float)p);
146
- while (p) {
147
- if (p & 1) r *= x;
148
- x *= x;
149
- p >>= 1;
150
- }
151
- return r;
152
- }
153
-
154
- static inline float cumo_half_pow_int(float x, int p)
155
- {
156
- if (p < 0) return 1.0f / cumo_half_pow_positive_int(x, -(unsigned int)p);
157
- return cumo_half_pow_positive_int(x, (unsigned int)p);
158
- }
159
-
160
- static inline float cumo_half_ldexp(float x, float y)
161
- {
162
- if (!(y == y)) return y;
163
- if (y > 64.0f) y = 64.0f;
164
- if (y < -64.0f) y = -64.0f;
165
- return ldexpf(x, (int)y);
166
- }
167
-
168
- static inline float cumo_half_sinc(float x)
169
- {
170
- return (x==0) ? 1.0f : (sinf(x)/x);
171
- }
172
-
173
- static inline float cumo_half_sign(float x)
174
- {
175
- return (x==0) ? 0.0f : ((x>0) ? 1.0f : ((x<0) ? -1.0f : x));
176
- }
177
-
178
- static inline cumo_half cumo_na_ruby_num_to_half(VALUE x)
179
- {
180
- return cumo_double2half(NIL_P(x) ? nan("") : NUM2DBL(x));
181
- }
182
-
183
- static inline cumo_half f_seq(cumo_half x, cumo_half y, double c)
184
- {
185
- return cumo_float2half(cumo_half2float(x) + cumo_half2float(y) * (float)c);
186
- }
187
-
188
- #include "real_accum.h"
14
+ #include "f16_macro.h"
@@ -2,197 +2,18 @@
2
2
  #define CUMO_HALF_MACRO_KERNEL_H
3
3
 
4
4
  #include "float_def_kernel.h"
5
+ #include "bf16_def_kernel.h"
5
6
  #include "half_def_kernel.h"
6
- #include <string.h>
7
7
 
8
8
  #define CUMO_HALF_EPSILON 9.765625e-04f
9
9
 
10
- #define m_zero cumo_float2half(0.0f)
11
- #define m_one cumo_float2half(1.0f)
10
+ #define CUMO_F16_TO_F(x) cumo_half2float(x)
11
+ #define CUMO_F_TO_F16(x) cumo_float2half(x)
12
+ #define CUMO_D_TO_F16(x) cumo_double2half(x)
12
13
 
13
- #define m_from_double(x) cumo_double2half((double)(x))
14
- #define m_from_real(x) cumo_double2half((double)(x))
15
- #define m_from_sint(x) cumo_double2half((double)(x))
16
- #define m_from_int32(x) cumo_double2half((double)(x))
17
- #define m_from_int64(x) cumo_double2half((double)(x))
18
- #define m_from_uint32(x) cumo_double2half((double)(x))
19
- #define m_from_uint64(x) cumo_double2half((double)(x))
20
14
  #define m_from_half(x) (x)
15
+ #define m_from_bfloat(x) cumo_float2half(cumo_bfloat2float(x))
21
16
 
22
- // Overloaded rather than substituted, so that a scan or a reduction can apply
23
- // the same rule to its own wider accumulator.
24
- __host__ __device__ static inline float cumo_half_add(float x, float y) { return x + y; }
25
- __host__ __device__ static inline float cumo_half_sub(float x, float y) { return x - y; }
26
- __host__ __device__ static inline float cumo_half_mul(float x, float y) { return x * y; }
27
- __host__ __device__ static inline float cumo_half_div(float x, float y) { return x / y; }
28
- __host__ __device__ static inline bool cumo_half_not_nan(float x) { return x == x; }
29
- __host__ __device__ static inline cumo_half cumo_half_add(cumo_half x, cumo_half y) { return cumo_float2half(cumo_half2float(x) + cumo_half2float(y)); }
30
- __host__ __device__ static inline cumo_half cumo_half_sub(cumo_half x, cumo_half y) { return cumo_float2half(cumo_half2float(x) - cumo_half2float(y)); }
31
- __host__ __device__ static inline cumo_half cumo_half_mul(cumo_half x, cumo_half y) { return cumo_float2half(cumo_half2float(x) * cumo_half2float(y)); }
32
- __host__ __device__ static inline cumo_half cumo_half_div(cumo_half x, cumo_half y) { return cumo_float2half(cumo_half2float(x) / cumo_half2float(y)); }
33
- __host__ __device__ static inline bool cumo_half_not_nan(cumo_half x) { return cumo_half2float(x) == cumo_half2float(x); }
34
-
35
- #define m_add(x,y) cumo_half_add(x,y)
36
- #define m_sub(x,y) cumo_half_sub(x,y)
37
- #define m_mul(x,y) cumo_half_mul(x,y)
38
- #define m_div(x,y) cumo_half_div(x,y)
39
- #define m_div_check(x,y) (cumo_half2float(y)==0)
40
-
41
- __host__ __device__ static inline float cumo_half_floored_mod(float x, float y)
42
- {
43
- float r = fmodf(x,y);
44
- if (r != 0 && ((r < 0) != (y < 0))) {
45
- r += y;
46
- }
47
- return r;
48
- }
49
-
50
- #define m_mod(x,y) cumo_float2half(cumo_half_floored_mod(cumo_half2float(x),cumo_half2float(y)))
51
- #define m_divmod(x,y,a,b) \
52
- {float cumo_h_x = cumo_half2float(x), cumo_h_y = cumo_half2float(y); \
53
- float cumo_h_b = fmodf(cumo_h_x,cumo_h_y); \
54
- float cumo_h_a = roundf((cumo_h_x-cumo_h_b)/cumo_h_y); \
55
- if (cumo_h_b != 0 && ((cumo_h_b < 0) != (cumo_h_y < 0))) { \
56
- cumo_h_b += cumo_h_y; cumo_h_a -= 1; \
57
- } \
58
- a = cumo_float2half(cumo_h_a); b = cumo_float2half(cumo_h_b);}
59
- #define m_pow(x,y) cumo_float2half(powf(cumo_half2float(x),cumo_half2float(y)))
60
- #define m_pow_int(x,y) cumo_float2half(cumo_half_pow_int(cumo_half2float(x),(int)(y)))
61
-
62
- #define m_abs(x) cumo_float2half(fabsf(cumo_half2float(x)))
63
- #define m_minus(x) cumo_float2half(-cumo_half2float(x))
64
- #define m_reciprocal(x) cumo_float2half(1.0f/cumo_half2float(x))
65
- #define m_square(x) cumo_float2half(cumo_half2float(x)*cumo_half2float(x))
66
- #define m_floor(x) cumo_float2half(floorf(cumo_half2float(x)))
67
- #define m_round(x) cumo_float2half(roundf(cumo_half2float(x)))
68
- #define m_ceil(x) cumo_float2half(ceilf(cumo_half2float(x)))
69
- #define m_trunc(x) cumo_float2half(truncf(cumo_half2float(x)))
70
- #define m_rint(x) cumo_float2half(rintf(cumo_half2float(x)))
71
- #define m_sign(x) cumo_float2half(cumo_half_sign(cumo_half2float(x)))
72
- #define m_copysign(x,y) cumo_float2half(copysignf(cumo_half2float(x),cumo_half2float(y)))
73
- #define m_signbit(x) signbit(cumo_half2float(x))
74
- #define m_modf(x,y,z) {float cumo_h_i; float cumo_h_f = modff(cumo_half2float(x),&cumo_h_i); y = cumo_float2half(cumo_h_f); z = cumo_float2half(cumo_h_i);}
75
-
76
- #define m_eq(x,y) (cumo_half2float(x)==cumo_half2float(y))
77
- #define m_ne(x,y) (cumo_half2float(x)!=cumo_half2float(y))
78
- #define m_gt(x,y) (cumo_half2float(x)>cumo_half2float(y))
79
- #define m_ge(x,y) (cumo_half2float(x)>=cumo_half2float(y))
80
- #define m_lt(x,y) (cumo_half2float(x)<cumo_half2float(y))
81
- #define m_le(x,y) (cumo_half2float(x)<=cumo_half2float(y))
82
-
83
- #define m_isnan(x) isnan(cumo_half2float(x))
84
- #define m_isinf(x) isinf(cumo_half2float(x))
85
- #define m_isposinf(x) (isinf(cumo_half2float(x)) && signbit(cumo_half2float(x))==0)
86
- #define m_isneginf(x) (isinf(cumo_half2float(x)) && signbit(cumo_half2float(x)))
87
- #define m_isfinite(x) isfinite(cumo_half2float(x))
88
-
89
- #define not_nan(x) cumo_half_not_nan(x)
90
-
91
- #define m_mulsum_init m_zero
92
-
93
- #define m_sprintf(s,x) sprintf(s,"%g",cumo_half2float(x))
94
-
95
- #define m_sqrt(x) cumo_float2half(sqrtf(cumo_half2float(x)))
96
- #define m_cbrt(x) cumo_float2half(cbrtf(cumo_half2float(x)))
97
- #define m_log(x) cumo_float2half(logf(cumo_half2float(x)))
98
- #define m_log2(x) cumo_float2half(log2f(cumo_half2float(x)))
99
- #define m_log10(x) cumo_float2half(log10f(cumo_half2float(x)))
100
- #define m_exp(x) cumo_float2half(expf(cumo_half2float(x)))
101
- #define m_exp2(x) cumo_float2half(exp2f(cumo_half2float(x)))
102
- #ifdef HAVE_EXP10
103
- #define m_exp10(x) cumo_float2half(exp10f(cumo_half2float(x)))
104
- #else
105
- #define m_exp10(x) cumo_float2half(powf(10.0f,cumo_half2float(x)))
106
- #endif
107
- #define m_expm1(x) cumo_float2half(expm1f(cumo_half2float(x)))
108
- #define m_log1p(x) cumo_float2half(log1pf(cumo_half2float(x)))
109
-
110
- #define m_sin(x) cumo_float2half(sinf(cumo_half2float(x)))
111
- #define m_cos(x) cumo_float2half(cosf(cumo_half2float(x)))
112
- #define m_tan(x) cumo_float2half(tanf(cumo_half2float(x)))
113
- #define m_asin(x) cumo_float2half(asinf(cumo_half2float(x)))
114
- #define m_acos(x) cumo_float2half(acosf(cumo_half2float(x)))
115
- #define m_atan(x) cumo_float2half(atanf(cumo_half2float(x)))
116
- #define m_sinh(x) cumo_float2half(sinhf(cumo_half2float(x)))
117
- #define m_cosh(x) cumo_float2half(coshf(cumo_half2float(x)))
118
- #define m_tanh(x) cumo_float2half(tanhf(cumo_half2float(x)))
119
- #define m_asinh(x) cumo_float2half(asinhf(cumo_half2float(x)))
120
- #define m_acosh(x) cumo_float2half(acoshf(cumo_half2float(x)))
121
- #define m_atanh(x) cumo_float2half(atanhf(cumo_half2float(x)))
122
- #define m_atan2(x,y) cumo_float2half(atan2f(cumo_half2float(x),cumo_half2float(y)))
123
- #define m_hypot(x,y) cumo_float2half(hypotf(cumo_half2float(x),cumo_half2float(y)))
124
- #define m_sinc(x) cumo_float2half(cumo_half_sinc(cumo_half2float(x)))
125
-
126
- #define m_erf(x) cumo_float2half(erff(cumo_half2float(x)))
127
- #define m_erfc(x) cumo_float2half(erfcf(cumo_half2float(x)))
128
- #define m_ldexp(x,y) cumo_float2half(cumo_half_ldexp(cumo_half2float(x),cumo_half2float(y)))
129
- #define m_frexp(x,exp) cumo_float2half(frexpf(cumo_half2float(x),exp))
130
-
131
-
132
- __host__ __device__ static inline float cumo_half_pow_positive_int(float x, unsigned int p)
133
- {
134
- float r = 1.0f;
135
- switch (p) {
136
- case 0: return 1.0f;
137
- case 1: return x;
138
- case 2: return x*x;
139
- case 3: return x*x*x;
140
- case 4: x = x*x; return x*x;
141
- }
142
- if (p > 64) return powf(x, (float)p);
143
- while (p) {
144
- if (p & 1) r *= x;
145
- x *= x;
146
- p >>= 1;
147
- }
148
- return r;
149
- }
150
-
151
- __host__ __device__ static inline float cumo_half_pow_int(float x, int p)
152
- {
153
- if (p < 0) return 1.0f / cumo_half_pow_positive_int(x, -(unsigned int)p);
154
- return cumo_half_pow_positive_int(x, (unsigned int)p);
155
- }
156
-
157
- // The bit-pattern intrinsics are device-only before CUDA 12, so the bits are
158
- // taken the way a host caller can take them too.
159
- __host__ __device__ static inline cumo_half cumo_half_step_down(cumo_half h)
160
- {
161
- unsigned short b;
162
- cumo_half r;
163
- memcpy(&b, &h, sizeof(b));
164
- if (b == 0x0000u) {
165
- b = 0x8001u;
166
- } else {
167
- b = (unsigned short)((b & 0x8000u) ? (b + 1) : (b - 1));
168
- }
169
- memcpy(&r, &b, sizeof(b));
170
- return r;
171
- }
172
-
173
- __host__ __device__ static inline float cumo_half_ldexp(float x, float y)
174
- {
175
- if (!(y == y)) return y;
176
- if (y > 64.0f) y = 64.0f;
177
- if (y < -64.0f) y = -64.0f;
178
- return ldexpf(x, (int)y);
179
- }
180
-
181
- __host__ __device__ static inline float cumo_half_sinc(float x)
182
- {
183
- return (x==0) ? 1.0f : (sinf(x)/x);
184
- }
185
-
186
- __host__ __device__ static inline float cumo_half_sign(float x)
187
- {
188
- return (x==0) ? 0.0f : ((x>0) ? 1.0f : ((x<0) ? -1.0f : x));
189
- }
190
-
191
- __host__ __device__ static inline cumo_half f_seq(cumo_half x, cumo_half y, double c)
192
- {
193
- return cumo_float2half(cumo_half2float(x) + cumo_half2float(y) * (float)c);
194
- }
195
-
196
- #include "real_accum_kernel.h"
17
+ #include "f16_macro_kernel.h"
197
18
 
198
19
  #endif // CUMO_HALF_MACRO_KERNEL_H
@@ -1,4 +1,5 @@
1
1
  #include "half_def.h"
2
+ #include "bf16_def.h"
2
3
 
3
4
  #define m_zero INT2FIX(0)
4
5
  #define m_one INT2FIX(1)
@@ -9,6 +10,7 @@
9
10
  #define m_from_double(x) rb_float_new(x)
10
11
  #define m_from_real(x) rb_float_new(x)
11
12
  #define m_from_half(x) m_from_real(cumo_half2float(x))
13
+ #define m_from_bfloat(x) m_from_real(cumo_bfloat2float(x))
12
14
  #define m_from_sint(x) INT2FIX(x)
13
15
  #define m_from_int32(x) INT322NUM(x)
14
16
  #define m_from_int64(x) INT642NUM(x)
@@ -1,4 +1,5 @@
1
1
  #include "half_def.h"
2
+ #include "bf16_def.h"
2
3
 
3
4
  #define m_zero 0
4
5
  #define m_one 1
@@ -9,6 +10,7 @@
9
10
  #define m_from_double(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
10
11
  #define m_from_real(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
11
12
  #define m_from_half(x) m_from_real(cumo_half2float(x))
13
+ #define m_from_bfloat(x) m_from_real(cumo_bfloat2float(x))
12
14
  #define m_from_sint(x) (x)
13
15
  #define m_from_int32(x) (x)
14
16
  #define m_from_int64(x) (x)
@@ -49,12 +51,6 @@
49
51
  #define m_cumsum(x,y) {x += y;}
50
52
  #define m_cumprod(x,y) {x *= y;}
51
53
 
52
- #define cmp(a,b) \
53
- ((qsort_cast(a)==qsort_cast(b)) ? 0 : \
54
- (qsort_cast(a) > qsort_cast(b)) ? 1 : -1)
55
- #define cmpgt(a,b) \
56
- (qsort_cast(a) > qsort_cast(b))
57
-
58
54
  static inline dtype f_min(size_t n, char *p, ssize_t stride)
59
55
  {
60
56
  dtype x,y;
@@ -1,6 +1,7 @@
1
1
  #ifndef CUMO_XINT_MACRO_KERNEL_H
2
2
  #define CUMO_XINT_MACRO_KERNEL_H
3
3
  #include "half_def_kernel.h"
4
+ #include "bf16_def_kernel.h"
4
5
 
5
6
  #define m_zero 0
6
7
  #define m_one 1
@@ -8,6 +9,7 @@
8
9
  #define m_from_double(x) (x)
9
10
  #define m_from_real(x) (x)
10
11
  #define m_from_half(x) m_from_real(cumo_half2float(x))
12
+ #define m_from_bfloat(x) m_from_real(cumo_bfloat2float(x))
11
13
  #define m_from_sint(x) (x)
12
14
  #define m_from_int32(x) (x)
13
15
  #define m_from_int64(x) (x)
@@ -10,8 +10,8 @@ extern "C" {
10
10
  #endif
11
11
  #endif
12
12
 
13
- #define CUMO_VERSION "0.7.0"
14
- #define CUMO_VERSION_CODE 700
13
+ #define CUMO_VERSION "0.9.0"
14
+ #define CUMO_VERSION_CODE 900
15
15
 
16
16
  bool cumo_compatible_mode_enabled_p();
17
17
  bool cumo_show_warning_enabled_p();
@@ -55,6 +55,7 @@ static ID cumo_id_swap_byte;
55
55
 
56
56
  void cumo_iter_copy_bytes_kernel_launch(char *p1, char *p2, ssize_t s1, ssize_t s2, size_t *idx1, size_t *idx2, size_t n, int elmsz);
57
57
  void cumo_iter_copy_bytes_indexer_kernel_launch(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz);
58
+ void cumo_iter_copy_bytes_stridx_kernel_launch(cumo_na_iarray_stridx_t* a1, cumo_na_iarray_stridx_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz);
58
59
  void cumo_iter_swap_byte_indexer_kernel_launch(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz);
59
60
  #define m_memcpy(src,dst) memcpy(dst,src,e)
60
61
 
@@ -86,11 +87,19 @@ iter_copy_bytes(cumo_na_loop_t *const lp)
86
87
  static void
87
88
  iter_copy_bytes_indexer(cumo_na_loop_t *const lp)
88
89
  {
89
- cumo_na_iarray_t a1 = cumo_na_make_iarray(&lp->args[0]);
90
- cumo_na_iarray_t a2 = cumo_na_make_iarray(&lp->args[1]);
91
90
  cumo_na_indexer_t indexer = cumo_na_make_indexer(&lp->args[0]);
92
91
 
93
- cumo_iter_copy_bytes_indexer_kernel_launch(&a1, &a2, &indexer, (ssize_t)lp->args[0].elmsz);
92
+ if (cumo_na_loop_has_index(lp)) {
93
+ cumo_na_iarray_stridx_t b1 = cumo_na_make_iarray_stridx(&lp->args[0]);
94
+ cumo_na_iarray_stridx_t b2 = cumo_na_make_iarray_stridx(&lp->args[1]);
95
+
96
+ cumo_iter_copy_bytes_stridx_kernel_launch(&b1, &b2, &indexer, (ssize_t)lp->args[0].elmsz);
97
+ } else {
98
+ cumo_na_iarray_t a1 = cumo_na_make_iarray(&lp->args[0]);
99
+ cumo_na_iarray_t a2 = cumo_na_make_iarray(&lp->args[1]);
100
+
101
+ cumo_iter_copy_bytes_indexer_kernel_launch(&a1, &a2, &indexer, (ssize_t)lp->args[0].elmsz);
102
+ }
94
103
  }
95
104
 
96
105
  VALUE
@@ -99,7 +108,7 @@ cumo_na_copy(VALUE self)
99
108
  VALUE v;
100
109
  cumo_ndfunc_arg_in_t ain[1] = {{Qnil,0}};
101
110
  cumo_ndfunc_arg_out_t aout[1] = {{INT2FIX(0),0}};
102
- cumo_ndfunc_t ndf = { iter_copy_bytes, CUMO_FULL_LOOP, 1, 1, ain, aout };
111
+ cumo_ndfunc_t ndf = { iter_copy_bytes, CUMO_FULL_LOOP_NIP, 1, 1, ain, aout };
103
112
 
104
113
  // The loops below move whole bytes, which is one element of every class but
105
114
  // Cumo::Bit, whose element is one bit. Its own copy is the one that can
@@ -114,7 +123,7 @@ cumo_na_copy(VALUE self)
114
123
  // synchronization per step when an operand carries an index array.
115
124
  if (!rb_obj_is_kind_of(self, cumo_cRObject)) {
116
125
  ndf.func = iter_copy_bytes_indexer;
117
- ndf.flag = CUMO_STRIDE_LOOP|CUMO_NDF_INDEXER_LOOP;
126
+ ndf.flag = CUMO_FULL_LOOP_NIP|CUMO_NDF_INDEXER_LOOP;
118
127
  }
119
128
 
120
129
  v = cumo_na_ndloop(&ndf, 1, self);
@@ -502,7 +511,7 @@ cumo_na_reshape_bang(int argc, VALUE *argv, VALUE self)
502
511
 
503
512
  @overload reshape(size0,size1,...)
504
513
  @param sizeN [Integer] new shape
505
- @return [Cumo::NArray] return self.
514
+ @return [Cumo::NArray] a copy carrying the new shape.
506
515
  @example
507
516
  */
508
517
  static VALUE
@@ -1,5 +1,6 @@
1
1
  #include "cumo/narray_kernel.h"
2
2
  #include "cumo/indexer.h"
3
+ #include "cumo/template_kernel.h"
3
4
 
4
5
  #if defined(__cplusplus)
5
6
  extern "C" {
@@ -239,8 +240,117 @@ __global__ void cumo_iter_copy_bytes_indexer_kernel_dim(cumo_na_iarray_t a1, cum
239
240
  }
240
241
  }
241
242
 
243
+ #define CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(NDIM) \
244
+ __global__ void cumo_iter_copy_bytes_stridx_kernel_dim##NDIM( \
245
+ cumo_na_iarray_stridx_t a1, cumo_na_iarray_stridx_t a2, cumo_na_indexer_t indexer, ssize_t elmsz) { \
246
+ for (uint64_t i = blockIdx.x * blockDim.x + threadIdx.x; i < indexer.total_size; i += blockDim.x * gridDim.x) { \
247
+ cumo_na_indexer_set_dim##NDIM(&indexer, i); \
248
+ char* p1 = cumo_na_iarray_stridx_at_dim##NDIM(&a1, &indexer); \
249
+ char* p2 = cumo_na_iarray_stridx_at_dim##NDIM(&a2, &indexer); \
250
+ memcpy(p2, p1, elmsz); \
251
+ } \
252
+ }
253
+
254
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(0)
255
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(1)
256
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(2)
257
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(3)
258
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(4)
259
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(5)
260
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(6)
261
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(7)
262
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL(8)
263
+ CUMO_ITER_COPY_BYTES_STRIDX_KERNEL()
264
+
265
+ #undef CUMO_ITER_COPY_BYTES_STRIDX_KERNEL
266
+
267
+ void cumo_iter_copy_bytes_stridx_kernel_launch(cumo_na_iarray_stridx_t* a1, cumo_na_iarray_stridx_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz)
268
+ {
269
+ size_t grid_dim = cumo_get_grid_dim(indexer->total_size);
270
+ size_t block_dim = cumo_get_block_dim(indexer->total_size);
271
+ switch (indexer->ndim) {
272
+ #define CUMO_ITER_COPY_BYTES_STRIDX_CASE(NDIM) \
273
+ case NDIM: \
274
+ cumo_iter_copy_bytes_stridx_kernel_dim##NDIM<<<grid_dim, block_dim>>>(*a1, *a2, *indexer, elmsz); \
275
+ break;
276
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(0)
277
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(1)
278
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(2)
279
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(3)
280
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(4)
281
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(5)
282
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(6)
283
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(7)
284
+ CUMO_ITER_COPY_BYTES_STRIDX_CASE(8)
285
+ #undef CUMO_ITER_COPY_BYTES_STRIDX_CASE
286
+ default:
287
+ cumo_iter_copy_bytes_stridx_kernel_dim<<<grid_dim, block_dim>>>(*a1, *a2, *indexer, elmsz);
288
+ break;
289
+ }
290
+ cumo_cuda_runtime_check_kernel_launch();
291
+ }
292
+
293
+ // A copy of a transposed view has one side strided whichever way it is walked,
294
+ // so it stages a square tile in shared memory the way the typed store does. The
295
+ // element size is only known here at run time, so there is one kernel per size
296
+ // a tile can carry.
297
+ struct cumo_copy_bytes_elm16 { uint64_t lo, hi; };
298
+
299
+ #define CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(SZ, TYPE) \
300
+ __global__ void cumo_iter_copy_bytes_transpose_kernel_##SZ( \
301
+ char *dst, char *src, uint64_t rows, uint64_t cols) { \
302
+ CUMO_TRANSPOSE_TILE_DECL(TYPE, tile); \
303
+ CUMO_TRANSPOSE_TILE_LOOP(tile, rows, cols, \
304
+ *(TYPE*)(src + cumo_tile_src * sizeof(TYPE)), \
305
+ *(TYPE*)(dst + cumo_tile_dst * sizeof(TYPE)) = cumo_tile_val; \
306
+ ); \
307
+ }
308
+
309
+ CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(1, uint8_t)
310
+ CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(2, uint16_t)
311
+ CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(4, uint32_t)
312
+ CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(8, uint64_t)
313
+ CUMO_ITER_COPY_BYTES_TRANSPOSE_KERNEL(16, cumo_copy_bytes_elm16)
314
+
315
+ // True when the source runs along its columns and the destination along its
316
+ // rows. a1 is the source here and a2 the destination, the other way round from
317
+ // the typed store.
318
+ static int
319
+ cumo_iter_copy_bytes_is_transpose(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz)
320
+ {
321
+ return (elmsz == 1 || elmsz == 2 || elmsz == 4 || elmsz == 8 || elmsz == 16) &&
322
+ CUMO_TRANSPOSE_TILE_FITS(indexer) &&
323
+ a2->step[1] == elmsz &&
324
+ a2->step[0] == elmsz * (ssize_t)indexer->shape[1] &&
325
+ a1->step[0] == elmsz &&
326
+ a1->step[1] == elmsz * (ssize_t)indexer->shape[0];
327
+ }
328
+
242
329
  void cumo_iter_copy_bytes_indexer_kernel_launch(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_indexer_t* indexer, ssize_t elmsz)
243
330
  {
331
+ if (cumo_iter_copy_bytes_is_transpose(a1, a2, indexer, elmsz)) {
332
+ uint64_t rows = indexer->shape[0];
333
+ uint64_t cols = indexer->shape[1];
334
+ switch (elmsz) {
335
+ case 1:
336
+ CUMO_TRANSPOSE_LAUNCH(cumo_iter_copy_bytes_transpose_kernel_1, rows, cols, a2->ptr, a1->ptr);
337
+ break;
338
+ case 2:
339
+ CUMO_TRANSPOSE_LAUNCH(cumo_iter_copy_bytes_transpose_kernel_2, rows, cols, a2->ptr, a1->ptr);
340
+ break;
341
+ case 4:
342
+ CUMO_TRANSPOSE_LAUNCH(cumo_iter_copy_bytes_transpose_kernel_4, rows, cols, a2->ptr, a1->ptr);
343
+ break;
344
+ case 8:
345
+ CUMO_TRANSPOSE_LAUNCH(cumo_iter_copy_bytes_transpose_kernel_8, rows, cols, a2->ptr, a1->ptr);
346
+ break;
347
+ default:
348
+ CUMO_TRANSPOSE_LAUNCH(cumo_iter_copy_bytes_transpose_kernel_16, rows, cols, a2->ptr, a1->ptr);
349
+ break;
350
+ }
351
+ cumo_cuda_runtime_check_kernel_launch();
352
+ return;
353
+ }
244
354
  size_t grid_dim = cumo_get_grid_dim(indexer->total_size);
245
355
  size_t block_dim = cumo_get_block_dim(indexer->total_size);
246
356
  switch (indexer->ndim) {