cumo 0.6.0 → 0.7.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/CHANGELOG.md +44 -2
- data/README.md +133 -0
- data/bench/cumo_sync_probe.rb +71 -8
- data/ext/cumo/cuda/cublas.c +0 -40
- data/ext/cumo/cuda/cudnn.c +48 -0
- data/ext/cumo/cuda/cudnn_impl.cpp +91 -62
- data/ext/cumo/cuda/runtime.c +3 -4
- data/ext/cumo/cumo.c +34 -0
- data/ext/cumo/extconf.rb +2 -0
- data/ext/cumo/include/cumo/cuda/cudnn.h +21 -2
- data/ext/cumo/include/cumo/cuda/cumo_thrust.hpp +1 -0
- data/ext/cumo/include/cumo/cuda/runtime.h +28 -0
- data/ext/cumo/include/cumo/intern.h +4 -1
- data/ext/cumo/include/cumo/narray.h +59 -3
- data/ext/cumo/include/cumo/template.h +35 -10
- data/ext/cumo/include/cumo/template_kernel.h +96 -0
- data/ext/cumo/include/cumo/types/bit.h +3 -0
- data/ext/cumo/include/cumo/types/bit_kernel.h +3 -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/float_macro.h +2 -0
- data/ext/cumo/include/cumo/types/float_macro_kernel.h +2 -0
- data/ext/cumo/include/cumo/types/half_def.h +129 -0
- data/ext/cumo/include/cumo/types/half_def_kernel.h +28 -0
- data/ext/cumo/include/cumo/types/half_macro.h +188 -0
- data/ext/cumo/include/cumo/types/half_macro_kernel.h +198 -0
- data/ext/cumo/include/cumo/types/hfloat.h +22 -0
- data/ext/cumo/include/cumo/types/hfloat_kernel.h +16 -0
- data/ext/cumo/include/cumo/types/real_accum.h +2 -0
- data/ext/cumo/include/cumo/types/real_accum_kernel.h +2 -0
- data/ext/cumo/include/cumo/types/robj_macro.h +3 -0
- data/ext/cumo/include/cumo/types/xint_macro.h +3 -0
- 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 +49 -174
- data/ext/cumo/narray/gen/def/bit.rb +2 -0
- data/ext/cumo/narray/gen/def/dcomplex.rb +2 -0
- data/ext/cumo/narray/gen/def/dfloat.rb +8 -0
- data/ext/cumo/narray/gen/def/hfloat.rb +47 -0
- data/ext/cumo/narray/gen/def/int16.rb +2 -0
- data/ext/cumo/narray/gen/def/int32.rb +2 -0
- data/ext/cumo/narray/gen/def/int64.rb +2 -0
- data/ext/cumo/narray/gen/def/int8.rb +2 -0
- data/ext/cumo/narray/gen/def/robject.rb +2 -0
- data/ext/cumo/narray/gen/def/scomplex.rb +2 -0
- data/ext/cumo/narray/gen/def/sfloat.rb +8 -0
- data/ext/cumo/narray/gen/def/uint16.rb +3 -1
- data/ext/cumo/narray/gen/def/uint32.rb +3 -1
- data/ext/cumo/narray/gen/def/uint64.rb +2 -0
- data/ext/cumo/narray/gen/def/uint8.rb +3 -1
- data/ext/cumo/narray/gen/erbpp2.rb +6 -0
- data/ext/cumo/narray/gen/spec.rb +1 -0
- data/ext/cumo/narray/gen/tmpl/accum.c +1 -1
- data/ext/cumo/narray/gen/tmpl/accum_arg.c +1 -1
- data/ext/cumo/narray/gen/tmpl/accum_arg_kernel.cu +5 -5
- data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +14 -1
- data/ext/cumo/narray/gen/tmpl/accum_index.c +1 -1
- data/ext/cumo/narray/gen/tmpl/accum_index_kernel.cu +5 -5
- data/ext/cumo/narray/gen/tmpl/alloc_func.c +4 -7
- data/ext/cumo/narray/gen/tmpl/allocate.c +1 -2
- data/ext/cumo/narray/gen/tmpl/aref_cpu.c +1 -1
- data/ext/cumo/narray/gen/tmpl/batch_norm.c +11 -23
- data/ext/cumo/narray/gen/tmpl/batch_norm_backward.c +12 -24
- data/ext/cumo/narray/gen/tmpl/binary_kernel.cu +69 -2
- data/ext/cumo/narray/gen/tmpl/clip.c +3 -3
- data/ext/cumo/narray/gen/tmpl/cond_unary.c +1 -1
- data/ext/cumo/narray/gen/tmpl/conv.c +11 -17
- data/ext/cumo/narray/gen/tmpl/conv_grad_w.c +11 -17
- data/ext/cumo/narray/gen/tmpl/conv_transpose.c +11 -17
- data/ext/cumo/narray/gen/tmpl/cum.c +24 -1
- data/ext/cumo/narray/gen/tmpl/cum_kernel.cu +29 -4
- data/ext/cumo/narray/gen/tmpl/each.c +2 -3
- data/ext/cumo/narray/gen/tmpl/each_with_index.c +5 -21
- data/ext/cumo/narray/gen/tmpl/extract_cpu.c +1 -1
- data/ext/cumo/narray/gen/tmpl/extract_data.c +1 -1
- data/ext/cumo/narray/gen/tmpl/fill.c +1 -1
- data/ext/cumo/narray/gen/tmpl/fixed_batch_norm.c +9 -21
- data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +42 -37
- data/ext/cumo/narray/gen/tmpl/format.c +1 -1
- data/ext/cumo/narray/gen/tmpl/format_to_a.c +1 -1
- data/ext/cumo/narray/gen/tmpl/gemm.c +78 -27
- data/ext/cumo/narray/gen/tmpl/init_class.c +0 -7
- data/ext/cumo/narray/gen/tmpl/init_upcast.c +6 -0
- data/ext/cumo/narray/gen/tmpl/inspect.c +1 -1
- data/ext/cumo/narray/gen/tmpl/lib.c +11 -1
- data/ext/cumo/narray/gen/tmpl/map_with_index.c +7 -14
- data/ext/cumo/narray/gen/tmpl/median.c +9 -47
- data/ext/cumo/narray/gen/tmpl/minmax.c +1 -1
- data/ext/cumo/narray/gen/tmpl/poly.c +1 -1
- data/ext/cumo/narray/gen/tmpl/pooling_backward.c +2 -14
- data/ext/cumo/narray/gen/tmpl/pooling_forward.c +2 -14
- data/ext/cumo/narray/gen/tmpl/qsort.c +0 -1
- data/ext/cumo/narray/gen/tmpl/rand.c +20 -2
- data/ext/cumo/narray/gen/tmpl/rand_kernel.cu +13 -0
- data/ext/cumo/narray/gen/tmpl/rand_norm.c +4 -4
- data/ext/cumo/narray/gen/tmpl/rand_norm_kernel.cu +7 -5
- data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +83 -97
- data/ext/cumo/narray/gen/tmpl/sort.c +1 -1
- data/ext/cumo/narray/gen/tmpl/sort_index.c +6 -3
- data/ext/cumo/narray/gen/tmpl/store_array.c +21 -22
- data/ext/cumo/narray/gen/tmpl/store_bit.c +1 -1
- data/ext/cumo/narray/gen/tmpl/store_from.c +1 -1
- data/ext/cumo/narray/gen/tmpl/store_from_kernel.cu +37 -2
- data/ext/cumo/narray/gen/tmpl/to_a.c +1 -1
- data/ext/cumo/narray/gen/tmpl/unary.c +20 -3
- data/ext/cumo/narray/gen/tmpl/unary2.c +1 -1
- data/ext/cumo/narray/gen/tmpl/unary_s.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/allocate.c +2 -3
- data/ext/cumo/narray/gen/tmpl_bit/aref_cpu.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/bit_count_cpu.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/each.c +2 -2
- data/ext/cumo/narray/gen/tmpl_bit/each_with_index.c +5 -20
- data/ext/cumo/narray/gen/tmpl_bit/extract_cpu.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/format.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/format_to_a.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/inspect.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/mask.c +38 -17
- data/ext/cumo/narray/gen/tmpl_bit/mask_kernel.cu +4 -4
- data/ext/cumo/narray/gen/tmpl_bit/store_array.c +10 -11
- data/ext/cumo/narray/gen/tmpl_bit/store_from.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/to_a.c +1 -1
- data/ext/cumo/narray/gen/tmpl_bit/where.c +66 -13
- data/ext/cumo/narray/gen/tmpl_bit/where2.c +57 -20
- data/ext/cumo/narray/gen/tmpl_bit/where_kernel.cu +6 -6
- data/ext/cumo/narray/index.c +63 -18
- data/ext/cumo/narray/index_kernel.cu +15 -0
- data/ext/cumo/narray/math.c +2 -0
- data/ext/cumo/narray/narray.c +289 -183
- data/ext/cumo/narray/ndloop.c +91 -26
- data/ext/cumo/narray/sort_kernel.cu +39 -18
- data/ext/cumo/narray/struct.c +14 -17
- data/lib/cumo/cuda/cudnn.rb +1 -1
- data/lib/cumo/narray/extra.rb +11 -2
- data/test/bit_test.rb +147 -0
- data/test/cudnn_test.rb +132 -46
- data/test/extra_test.rb +1 -1
- data/test/hfloat_test.rb +717 -0
- data/test/math_test.rb +4 -1
- data/test/narray_alt_coverage_test.rb +7 -0
- data/test/narray_test.rb +1018 -11
- data/test/test_helper.rb +73 -0
- metadata +11 -1
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#ifdef CUDNN_FOUND
|
|
2
2
|
|
|
3
|
-
<%
|
|
4
|
-
cudnn_dtype =
|
|
5
|
-
case type_name
|
|
6
|
-
when 'sfloat'
|
|
7
|
-
'CUDNN_DATA_FLOAT'
|
|
8
|
-
when 'dfloat'
|
|
9
|
-
'CUDNN_DATA_DOUBLE'
|
|
10
|
-
else
|
|
11
|
-
# CUDNN_DATA_HALF
|
|
12
|
-
raise 'not supported'
|
|
13
|
-
end
|
|
14
|
-
%>
|
|
15
3
|
|
|
16
4
|
// gx, ggamma, gbeta = x.batch_norm_backward(gamma, gy, mean:, inv_std:, eps:, axis:)
|
|
17
5
|
static VALUE
|
|
@@ -20,8 +8,8 @@ static VALUE
|
|
|
20
8
|
cudnnDataType_t cudnn_dtype = <%= cudnn_dtype %>;
|
|
21
9
|
cudnnStatus_t status = 0;
|
|
22
10
|
cudnnHandle_t handle = 0;
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
<%=cudnn_scalar_t%> coef_one = 1;
|
|
12
|
+
<%=cudnn_scalar_t%> coef_zero = 0;
|
|
25
13
|
|
|
26
14
|
VALUE x=self, gamma, gy, mean, inv_std, eps, axis, gx, ggamma, gbeta;
|
|
27
15
|
VALUE kw_hash = Qnil;
|
|
@@ -107,10 +95,10 @@ static VALUE
|
|
|
107
95
|
}
|
|
108
96
|
|
|
109
97
|
CUMO_CHECK_NARRAY_TYPE(x, cT);
|
|
110
|
-
|
|
98
|
+
cumo_cuda_cudnn_check_param_type(gamma, <%=cudnn_param_class%>, "gamma");
|
|
111
99
|
CUMO_CHECK_NARRAY_TYPE(gy, cT);
|
|
112
|
-
if (mean != Qnil)
|
|
113
|
-
if (inv_std != Qnil)
|
|
100
|
+
if (mean != Qnil) cumo_cuda_cudnn_check_param_type(mean, <%=cudnn_param_class%>, "mean");
|
|
101
|
+
if (inv_std != Qnil) cumo_cuda_cudnn_check_param_type(inv_std, <%=cudnn_param_class%>, "inv_std");
|
|
114
102
|
|
|
115
103
|
x_cont = cumo_na_as_contiguous_array(x);
|
|
116
104
|
gamma_cont = cumo_na_as_contiguous_array(gamma);
|
|
@@ -133,15 +121,15 @@ static VALUE
|
|
|
133
121
|
}
|
|
134
122
|
gx_ptr = cumo_na_get_offset_pointer_for_write(gx);
|
|
135
123
|
if (ggamma == Qnil) {
|
|
136
|
-
ggamma = cumo_na_new(
|
|
124
|
+
ggamma = cumo_na_new(<%=cudnn_param_class%>, gamma_ndim, gamma_shape);
|
|
137
125
|
} else {
|
|
138
|
-
cumo_cuda_cudnn_check_output(ggamma,
|
|
126
|
+
cumo_cuda_cudnn_check_output(ggamma, <%=cudnn_param_class%>, gamma_ndim, gamma_shape);
|
|
139
127
|
}
|
|
140
128
|
ggamma_ptr = cumo_na_get_offset_pointer_for_write(ggamma);
|
|
141
129
|
if (gbeta == Qnil) {
|
|
142
|
-
gbeta = cumo_na_new(
|
|
130
|
+
gbeta = cumo_na_new(<%=cudnn_param_class%>, gamma_ndim, gamma_shape);
|
|
143
131
|
} else {
|
|
144
|
-
cumo_cuda_cudnn_check_output(gbeta,
|
|
132
|
+
cumo_cuda_cudnn_check_output(gbeta, <%=cudnn_param_class%>, gamma_ndim, gamma_shape);
|
|
145
133
|
}
|
|
146
134
|
gbeta_ptr = cumo_na_get_offset_pointer_for_write(gbeta);
|
|
147
135
|
|
|
@@ -151,9 +139,9 @@ static VALUE
|
|
|
151
139
|
mode = cumo_cuda_cudnn_GetBatchNormMode(axis_ndim, int_axis);
|
|
152
140
|
status = cumo_cuda_cudnn_CreateBNTensorDescriptor(&bn_desc, x_desc, mode);
|
|
153
141
|
if (status != CUDNN_STATUS_SUCCESS) goto BATCH_NORM_BACKWARD_ERROR;
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
142
|
+
// cuDNN derives the parameter descriptor as float for a half x and as x's
|
|
143
|
+
// own type otherwise, and the checks above hold every parameter to exactly
|
|
144
|
+
// that class, so none of them needs a cast.
|
|
157
145
|
|
|
158
146
|
handle = cumo_cuda_cudnn_handle();
|
|
159
147
|
|
|
@@ -48,6 +48,64 @@ __global__ void <%="cumo_#{c_iter}_kernel_dim#{idim}"%>(cumo_na_iarray_t a1, cum
|
|
|
48
48
|
//<% end %>
|
|
49
49
|
<% end %>
|
|
50
50
|
|
|
51
|
+
// One operand of a 2-d elementwise op can be a transposed view, which leaves
|
|
52
|
+
// either its read or the write strided whichever way the loop walks. Stage that
|
|
53
|
+
// operand through a shared memory tile so all three arrays are touched in rows.
|
|
54
|
+
// t_side says which operand is the transposed one.
|
|
55
|
+
__global__ void <%="cumo_#{c_iter}_transpose_kernel"%>(char *p1, char *p2, char *p3, int* divzero, int t_side, uint64_t rows, uint64_t cols)
|
|
56
|
+
{
|
|
57
|
+
CUMO_TRANSPOSE_TILE_DECL(dtype, tile);
|
|
58
|
+
char *tp = (t_side == 1) ? p1 : p2;
|
|
59
|
+
char *sp = (t_side == 1) ? p2 : p1;
|
|
60
|
+
|
|
61
|
+
CUMO_TRANSPOSE_TILE_LOOP(tile, rows, cols,
|
|
62
|
+
*(dtype*)(tp + cumo_tile_src * sizeof(dtype)),
|
|
63
|
+
dtype o = *(dtype*)(sp + cumo_tile_dst * sizeof(dtype));
|
|
64
|
+
dtype lhs = (t_side == 1) ? cumo_tile_val : o;
|
|
65
|
+
dtype rhs = (t_side == 1) ? o : cumo_tile_val;
|
|
66
|
+
cumo_check_intdivzero(rhs);
|
|
67
|
+
*(dtype*)(p3 + cumo_tile_dst * sizeof(dtype)) = m_<%=name%>(lhs, rhs);
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Launches the tiled kernel and answers 1 when it did. It takes over when one
|
|
72
|
+
// operand is a transposed plain array and the other two are row-major ones, and
|
|
73
|
+
// only once both sides reach a tile: a shorter one leaves most of each warp idle
|
|
74
|
+
// while the plain loop already reads or writes it in one go.
|
|
75
|
+
static int
|
|
76
|
+
<%="cumo_#{c_iter}_launch_transpose"%>(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_iarray_t* a3, cumo_na_indexer_t* indexer, int* divzero)
|
|
77
|
+
{
|
|
78
|
+
ssize_t esz = (ssize_t)sizeof(dtype);
|
|
79
|
+
uint64_t rows, cols;
|
|
80
|
+
ssize_t row, col;
|
|
81
|
+
int rows_a1, rows_a2, t_side;
|
|
82
|
+
|
|
83
|
+
if (!CUMO_TRANSPOSE_TILE_FITS(indexer)) {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
rows = indexer->shape[0];
|
|
87
|
+
cols = indexer->shape[1];
|
|
88
|
+
row = esz * (ssize_t)cols;
|
|
89
|
+
col = esz * (ssize_t)rows;
|
|
90
|
+
if (a3->step[0] != row || a3->step[1] != esz) {
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
rows_a1 = (a1->step[0] == row && a1->step[1] == esz);
|
|
94
|
+
rows_a2 = (a2->step[0] == row && a2->step[1] == esz);
|
|
95
|
+
if (!rows_a2 && rows_a1 && a2->step[0] == esz && a2->step[1] == col) {
|
|
96
|
+
t_side = 2;
|
|
97
|
+
} else if (!rows_a1 && rows_a2 && a1->step[0] == esz && a1->step[1] == col) {
|
|
98
|
+
t_side = 1;
|
|
99
|
+
} else {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
CUMO_TRANSPOSE_LAUNCH(<%="cumo_#{c_iter}_transpose_kernel"%>, rows, cols,
|
|
104
|
+
a1->ptr, a2->ptr, a3->ptr, divzero, t_side);
|
|
105
|
+
cumo_cuda_runtime_check_kernel_launch();
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
51
109
|
//<% if has_scalar %>
|
|
52
110
|
static void <%="cumo_#{c_iter}_kernel_dispatch"%>(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_iarray_t* a3, cumo_na_indexer_t* indexer, int* divzero, dtype sv, int use_scalar)
|
|
53
111
|
{
|
|
@@ -69,6 +127,10 @@ static void <%="cumo_#{c_iter}_kernel_dispatch"%>(cumo_na_iarray_t* a1, cumo_na_
|
|
|
69
127
|
void <%="cumo_#{c_iter}_kernel_launch"%>(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_iarray_t* a3, cumo_na_indexer_t* indexer, int* divzero)
|
|
70
128
|
{
|
|
71
129
|
dtype sv;
|
|
130
|
+
|
|
131
|
+
if (<%="cumo_#{c_iter}_launch_transpose"%>(a1,a2,a3,indexer,divzero)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
72
134
|
memset(&sv, 0, sizeof(dtype));
|
|
73
135
|
<%="cumo_#{c_iter}_kernel_dispatch"%>(a1,a2,a3,indexer,divzero,sv,0);
|
|
74
136
|
}
|
|
@@ -82,8 +144,13 @@ void <%="cumo_#{c_iter}_s_kernel_launch"%>(cumo_na_iarray_t* a1, dtype sv, cumo_
|
|
|
82
144
|
//<% else %>
|
|
83
145
|
void <%="cumo_#{c_iter}_kernel_launch"%>(cumo_na_iarray_t* a1, cumo_na_iarray_t* a2, cumo_na_iarray_t* a3, cumo_na_indexer_t* indexer, int* divzero)
|
|
84
146
|
{
|
|
85
|
-
size_t grid_dim
|
|
86
|
-
|
|
147
|
+
size_t grid_dim, block_dim;
|
|
148
|
+
|
|
149
|
+
if (<%="cumo_#{c_iter}_launch_transpose"%>(a1,a2,a3,indexer,divzero)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
grid_dim = cumo_get_grid_dim(indexer->total_size);
|
|
153
|
+
block_dim = cumo_get_block_dim(indexer->total_size);
|
|
87
154
|
switch (indexer->ndim) {
|
|
88
155
|
<% (0..opt_indexer_ndim).each do |idim| %>
|
|
89
156
|
case <%=idim%>:
|
|
@@ -24,7 +24,7 @@ static void
|
|
|
24
24
|
CUMO_INIT_PTR(lp, 3, p4, s4);
|
|
25
25
|
|
|
26
26
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
27
|
-
|
|
27
|
+
cumo_cuda_runtime_device_synchronize();
|
|
28
28
|
for (i=n; i--;) {
|
|
29
29
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
30
30
|
CUMO_GET_DATA_STRIDE(p2,s2,dtype,min);
|
|
@@ -69,7 +69,7 @@ static void
|
|
|
69
69
|
CUMO_INIT_PTR(lp, 2, p3, s3);
|
|
70
70
|
|
|
71
71
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>_min", "<%=type_name%>");
|
|
72
|
-
|
|
72
|
+
cumo_cuda_runtime_device_synchronize();
|
|
73
73
|
for (i=n; i--;) {
|
|
74
74
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
75
75
|
CUMO_GET_DATA_STRIDE(p2,s2,dtype,min);
|
|
@@ -105,7 +105,7 @@ static void
|
|
|
105
105
|
CUMO_INIT_PTR(lp, 2, p3, s3);
|
|
106
106
|
|
|
107
107
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>_max", "<%=type_name%>");
|
|
108
|
-
|
|
108
|
+
cumo_cuda_runtime_device_synchronize();
|
|
109
109
|
for (i=n; i--;) {
|
|
110
110
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
111
111
|
CUMO_GET_DATA_STRIDE(p2,s2,dtype,max);
|
|
@@ -20,7 +20,7 @@ static void
|
|
|
20
20
|
CUMO_INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
21
21
|
CUMO_INIT_PTR_BIT(lp, 1, a2, p2, s2);
|
|
22
22
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
23
|
-
|
|
23
|
+
cumo_cuda_runtime_device_synchronize();
|
|
24
24
|
if (idx1) {
|
|
25
25
|
for (i=0; i<n; i++) {
|
|
26
26
|
CUMO_GET_DATA_INDEX(p1,idx1,dtype,x);
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#ifdef CUDNN_FOUND
|
|
2
2
|
|
|
3
|
-
<%
|
|
4
|
-
cudnn_dtype =
|
|
5
|
-
case type_name
|
|
6
|
-
when 'sfloat'
|
|
7
|
-
'CUDNN_DATA_FLOAT'
|
|
8
|
-
when 'dfloat'
|
|
9
|
-
'CUDNN_DATA_DOUBLE'
|
|
10
|
-
else
|
|
11
|
-
# CUDNN_DATA_HALF
|
|
12
|
-
raise 'not supported'
|
|
13
|
-
end
|
|
14
|
-
%>
|
|
15
3
|
|
|
16
4
|
// cover_all=true is not supported with CUDNN
|
|
17
5
|
// dilation > 1 is not supported yet
|
|
@@ -22,8 +10,8 @@ static VALUE
|
|
|
22
10
|
cudnnDataType_t cudnn_dtype = <%= cudnn_dtype %>;
|
|
23
11
|
cudnnStatus_t status = 0;
|
|
24
12
|
cudnnHandle_t handle = 0;
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
<%=cudnn_scalar_t%> alpha = 1;
|
|
14
|
+
<%=cudnn_scalar_t%> beta = 0;
|
|
27
15
|
|
|
28
16
|
VALUE x=self, w, b, stride, pad, y;
|
|
29
17
|
VALUE kw_hash = Qnil;
|
|
@@ -45,7 +33,7 @@ static VALUE
|
|
|
45
33
|
|
|
46
34
|
cudnnConvolutionFwdAlgoPerf_t perf_result;
|
|
47
35
|
cudnnConvolutionFwdAlgo_t algo;
|
|
48
|
-
size_t max_workspace_size =
|
|
36
|
+
size_t max_workspace_size = cumo_cuda_cudnn_max_workspace_size();
|
|
49
37
|
size_t workspace_size;
|
|
50
38
|
char* workspace = 0;
|
|
51
39
|
|
|
@@ -113,7 +101,7 @@ static VALUE
|
|
|
113
101
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_ERROR;
|
|
114
102
|
status = cumo_cuda_cudnn_CreateFilterDescriptor(&w_desc, w_cont, cudnn_dtype);
|
|
115
103
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_ERROR;
|
|
116
|
-
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad,
|
|
104
|
+
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad, <%=cudnn_compute_dtype%>, <%=cudnn_math_type%>);
|
|
117
105
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_ERROR;
|
|
118
106
|
|
|
119
107
|
handle = cumo_cuda_cudnn_handle();
|
|
@@ -135,10 +123,16 @@ static VALUE
|
|
|
135
123
|
ndim,
|
|
136
124
|
cudnn_dtype);
|
|
137
125
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_ERROR;
|
|
126
|
+
// The descriptor asked for a math type; use the one the search settled on.
|
|
127
|
+
status = cudnnSetConvolutionMathType(conv_desc, perf_result.mathType);
|
|
128
|
+
if (status != CUDNN_STATUS_SUCCESS) goto CONV_ERROR;
|
|
129
|
+
|
|
138
130
|
algo = perf_result.algo;
|
|
139
131
|
workspace_size = perf_result.memory;
|
|
140
132
|
|
|
141
|
-
|
|
133
|
+
// The search may look at algorithms needing up to max_workspace_size,
|
|
134
|
+
// but only the one it picked has to be paid for.
|
|
135
|
+
if (workspace_size > 0) workspace = cumo_cuda_runtime_malloc(workspace_size);
|
|
142
136
|
status = cudnnConvolutionForward(
|
|
143
137
|
handle,
|
|
144
138
|
(void*)&alpha,
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#ifdef CUDNN_FOUND
|
|
2
2
|
|
|
3
|
-
<%
|
|
4
|
-
cudnn_dtype =
|
|
5
|
-
case type_name
|
|
6
|
-
when 'sfloat'
|
|
7
|
-
'CUDNN_DATA_FLOAT'
|
|
8
|
-
when 'dfloat'
|
|
9
|
-
'CUDNN_DATA_DOUBLE'
|
|
10
|
-
else
|
|
11
|
-
# CUDNN_DATA_HALF
|
|
12
|
-
raise 'not supported'
|
|
13
|
-
end
|
|
14
|
-
%>
|
|
15
3
|
|
|
16
4
|
static void
|
|
17
5
|
cumo_cuda_cudnn_get_sizet_ary(size_t *sizet_ary, VALUE ary, size_t ndim)
|
|
@@ -31,8 +19,8 @@ static VALUE
|
|
|
31
19
|
cudnnDataType_t cudnn_dtype = <%= cudnn_dtype %>;
|
|
32
20
|
cudnnStatus_t status = 0;
|
|
33
21
|
cudnnHandle_t handle = 0;
|
|
34
|
-
|
|
35
|
-
|
|
22
|
+
<%=cudnn_scalar_t%> one = 1;
|
|
23
|
+
<%=cudnn_scalar_t%> zero = 0;
|
|
36
24
|
|
|
37
25
|
VALUE x=self, gy, w_shape, stride, pad, gw;
|
|
38
26
|
VALUE kw_hash = Qnil;
|
|
@@ -51,7 +39,7 @@ static VALUE
|
|
|
51
39
|
|
|
52
40
|
cudnnConvolutionBwdFilterAlgoPerf_t perf_result;
|
|
53
41
|
cudnnConvolutionBwdFilterAlgo_t algo;
|
|
54
|
-
size_t max_workspace_size =
|
|
42
|
+
size_t max_workspace_size = cumo_cuda_cudnn_max_workspace_size();
|
|
55
43
|
size_t workspace_size;
|
|
56
44
|
char* workspace = 0;
|
|
57
45
|
|
|
@@ -124,7 +112,7 @@ static VALUE
|
|
|
124
112
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_GRAD_W_ERROR;
|
|
125
113
|
status = cumo_cuda_cudnn_CreateFilterDescriptor(&gw_desc, gw, cudnn_dtype);
|
|
126
114
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_GRAD_W_ERROR;
|
|
127
|
-
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad,
|
|
115
|
+
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad, <%=cudnn_compute_dtype%>, <%=cudnn_math_type%>);
|
|
128
116
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_GRAD_W_ERROR;
|
|
129
117
|
|
|
130
118
|
handle = cumo_cuda_cudnn_handle();
|
|
@@ -146,10 +134,16 @@ static VALUE
|
|
|
146
134
|
ndim,
|
|
147
135
|
cudnn_dtype);
|
|
148
136
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_GRAD_W_ERROR;
|
|
137
|
+
// The descriptor asked for a math type; use the one the search settled on.
|
|
138
|
+
status = cudnnSetConvolutionMathType(conv_desc, perf_result.mathType);
|
|
139
|
+
if (status != CUDNN_STATUS_SUCCESS) goto CONV_GRAD_W_ERROR;
|
|
140
|
+
|
|
149
141
|
algo = perf_result.algo;
|
|
150
142
|
workspace_size = perf_result.memory;
|
|
151
143
|
|
|
152
|
-
|
|
144
|
+
// The search may look at algorithms needing up to max_workspace_size,
|
|
145
|
+
// but only the one it picked has to be paid for.
|
|
146
|
+
if (workspace_size > 0) workspace = cumo_cuda_runtime_malloc(workspace_size);
|
|
153
147
|
status = cudnnConvolutionBackwardFilter(
|
|
154
148
|
handle,
|
|
155
149
|
(void*)&one,
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#ifdef CUDNN_FOUND
|
|
2
2
|
|
|
3
|
-
<%
|
|
4
|
-
cudnn_dtype =
|
|
5
|
-
case type_name
|
|
6
|
-
when 'sfloat'
|
|
7
|
-
'CUDNN_DATA_FLOAT'
|
|
8
|
-
when 'dfloat'
|
|
9
|
-
'CUDNN_DATA_DOUBLE'
|
|
10
|
-
else
|
|
11
|
-
# CUDNN_DATA_HALF
|
|
12
|
-
raise 'not supported'
|
|
13
|
-
end
|
|
14
|
-
%>
|
|
15
3
|
|
|
16
4
|
// VALUE is Ruby Array
|
|
17
5
|
static void
|
|
@@ -47,8 +35,8 @@ static VALUE
|
|
|
47
35
|
cudnnDataType_t cudnn_dtype = <%= cudnn_dtype %>;
|
|
48
36
|
cudnnStatus_t status = 0;
|
|
49
37
|
cudnnHandle_t handle = 0;
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
<%=cudnn_scalar_t%> alpha = 1;
|
|
39
|
+
<%=cudnn_scalar_t%> beta = 0;
|
|
52
40
|
|
|
53
41
|
VALUE x=self, w, b, stride, pad, out_size, y;
|
|
54
42
|
VALUE kw_hash = Qnil;
|
|
@@ -70,7 +58,7 @@ static VALUE
|
|
|
70
58
|
|
|
71
59
|
cudnnConvolutionBwdDataAlgoPerf_t perf_result;
|
|
72
60
|
cudnnConvolutionBwdDataAlgo_t algo;
|
|
73
|
-
size_t max_workspace_size =
|
|
61
|
+
size_t max_workspace_size = cumo_cuda_cudnn_max_workspace_size();
|
|
74
62
|
size_t workspace_size;
|
|
75
63
|
char* workspace = 0;
|
|
76
64
|
|
|
@@ -140,7 +128,7 @@ static VALUE
|
|
|
140
128
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_TRANSPOSE_ERROR;
|
|
141
129
|
status = cumo_cuda_cudnn_CreateFilterDescriptor(&w_desc, w_cont, cudnn_dtype);
|
|
142
130
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_TRANSPOSE_ERROR;
|
|
143
|
-
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad,
|
|
131
|
+
status = cumo_cuda_cudnn_CreateConvolutionDescriptor(&conv_desc, ndim, int_stride, int_pad, <%=cudnn_compute_dtype%>, <%=cudnn_math_type%>);
|
|
144
132
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_TRANSPOSE_ERROR;
|
|
145
133
|
|
|
146
134
|
handle = cumo_cuda_cudnn_handle();
|
|
@@ -162,10 +150,16 @@ static VALUE
|
|
|
162
150
|
ndim,
|
|
163
151
|
cudnn_dtype);
|
|
164
152
|
if (status != CUDNN_STATUS_SUCCESS) goto CONV_TRANSPOSE_ERROR;
|
|
153
|
+
// The descriptor asked for a math type; use the one the search settled on.
|
|
154
|
+
status = cudnnSetConvolutionMathType(conv_desc, perf_result.mathType);
|
|
155
|
+
if (status != CUDNN_STATUS_SUCCESS) goto CONV_TRANSPOSE_ERROR;
|
|
156
|
+
|
|
165
157
|
algo = perf_result.algo;
|
|
166
158
|
workspace_size = perf_result.memory;
|
|
167
159
|
|
|
168
|
-
|
|
160
|
+
// The search may look at algorithms needing up to max_workspace_size,
|
|
161
|
+
// but only the one it picked has to be paid for.
|
|
162
|
+
if (workspace_size > 0) workspace = cumo_cuda_runtime_malloc(workspace_size);
|
|
169
163
|
status = cudnnConvolutionBackwardData(
|
|
170
164
|
handle,
|
|
171
165
|
(void*)&alpha,
|
|
@@ -26,8 +26,30 @@ static void
|
|
|
26
26
|
<% end %>
|
|
27
27
|
|
|
28
28
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%><%=j%>", "<%=type_name%>");
|
|
29
|
-
|
|
29
|
+
cumo_cuda_runtime_device_synchronize();
|
|
30
30
|
|
|
31
|
+
<% if is_half && name == 'cumsum' %>
|
|
32
|
+
// The scan this stands in for carries float, and a running sum of halves
|
|
33
|
+
// stops moving once it passes 2048, so the accumulator is float here too.
|
|
34
|
+
{
|
|
35
|
+
float acc, fy;
|
|
36
|
+
|
|
37
|
+
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
38
|
+
acc = cumo_half2float(x);
|
|
39
|
+
CUMO_SET_DATA_STRIDE(p2,s2,dtype,x);
|
|
40
|
+
for (i--; i--;) {
|
|
41
|
+
CUMO_GET_DATA_STRIDE(p1,s1,dtype,y);
|
|
42
|
+
fy = cumo_half2float(y);
|
|
43
|
+
<% if j == '_nan' %>
|
|
44
|
+
if (acc != acc) { acc = fy; } else if (fy == fy) { acc += fy; }
|
|
45
|
+
<% else %>
|
|
46
|
+
acc += fy;
|
|
47
|
+
<% end %>
|
|
48
|
+
x = cumo_float2half(acc);
|
|
49
|
+
CUMO_SET_DATA_STRIDE(p2,s2,dtype,x);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
<% else %>
|
|
31
53
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
32
54
|
CUMO_SET_DATA_STRIDE(p2,s2,dtype,x);
|
|
33
55
|
//printf("i=%lu x=%f\n",i,x);
|
|
@@ -37,6 +59,7 @@ static void
|
|
|
37
59
|
CUMO_SET_DATA_STRIDE(p2,s2,dtype,x);
|
|
38
60
|
//printf("i=%lu x=%f\n",i,x);
|
|
39
61
|
}
|
|
62
|
+
<% end %>
|
|
40
63
|
}
|
|
41
64
|
<% end %>
|
|
42
65
|
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
<% unless type_name == 'robject' %>
|
|
2
|
+
<% widen = is_half && name == 'cumsum' %>
|
|
3
|
+
<% cum_t = widen ? 'float' : 'dtype' %>
|
|
4
|
+
<% if widen %>
|
|
5
|
+
|
|
6
|
+
// A running sum of halves stops moving once it passes 2048, so the scan carries
|
|
7
|
+
// float and each element is rounded as it is written.
|
|
8
|
+
struct <%="cumo_thrust_#{name}_widen"%>
|
|
9
|
+
{
|
|
10
|
+
__host__ __device__ float operator()(dtype x) const { return cumo_half2float(x); }
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
struct <%="cumo_thrust_#{name}_narrow"%>
|
|
14
|
+
{
|
|
15
|
+
__host__ __device__ dtype operator()(float x) const { return cumo_float2half(x); }
|
|
16
|
+
};
|
|
17
|
+
<% end %>
|
|
2
18
|
<% (is_float ? ["","_nan"] : [""]).each do |j| %>
|
|
3
19
|
|
|
4
20
|
#if defined(__cplusplus)
|
|
@@ -14,12 +30,13 @@
|
|
|
14
30
|
// last ulp, the same way sum already does.
|
|
15
31
|
struct <%="cumo_thrust_#{name}#{j}"%>
|
|
16
32
|
{
|
|
17
|
-
using first_argument_type =
|
|
18
|
-
using second_argument_type =
|
|
19
|
-
using result_type =
|
|
20
|
-
__host__ __device__
|
|
33
|
+
using first_argument_type = <%=cum_t%>;
|
|
34
|
+
using second_argument_type = <%=cum_t%>;
|
|
35
|
+
using result_type = <%=cum_t%>;
|
|
36
|
+
__host__ __device__ <%=cum_t%> operator()(<%=cum_t%> x, <%=cum_t%> y) const { m_<%=name%><%=j%>(x,y); return x; }
|
|
21
37
|
};
|
|
22
38
|
|
|
39
|
+
|
|
23
40
|
// Nothing may reach the C caller: it has no handler, so an escaping exception
|
|
24
41
|
// is std::terminate. The status goes back instead and the caller raises.
|
|
25
42
|
template<typename Iterator1, typename Iterator2>
|
|
@@ -27,7 +44,15 @@ static cudaError_t <%="cumo_#{type_name}_#{name}#{j}_scan"%>(Iterator1 first, It
|
|
|
27
44
|
{
|
|
28
45
|
cumo_thrust_pool_allocator alloc;
|
|
29
46
|
try {
|
|
47
|
+
<% if widen %>
|
|
48
|
+
thrust::inclusive_scan(thrust::cuda::par(alloc),
|
|
49
|
+
thrust::make_transform_iterator(first, <%="cumo_thrust_#{name}_widen"%>()),
|
|
50
|
+
thrust::make_transform_iterator(last, <%="cumo_thrust_#{name}_widen"%>()),
|
|
51
|
+
thrust::make_transform_output_iterator(result, <%="cumo_thrust_#{name}_narrow"%>()),
|
|
52
|
+
<%="cumo_thrust_#{name}#{j}"%>());
|
|
53
|
+
<% else %>
|
|
30
54
|
thrust::inclusive_scan(thrust::cuda::par(alloc), first, last, result, <%="cumo_thrust_#{name}#{j}"%>());
|
|
55
|
+
<% end %>
|
|
31
56
|
} catch (const thrust::system_error& e) {
|
|
32
57
|
return (cudaError_t)e.code().value();
|
|
33
58
|
} catch (const std::bad_alloc&) {
|
|
@@ -10,18 +10,17 @@ static void
|
|
|
10
10
|
CUMO_INIT_COUNTER(lp, i);
|
|
11
11
|
CUMO_INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
12
12
|
|
|
13
|
-
CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
14
13
|
|
|
15
14
|
if (idx1) {
|
|
16
15
|
for (; i--;) {
|
|
17
|
-
|
|
16
|
+
if (cumo_cuda_runtime_sync_if_busy()) { CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>"); }
|
|
18
17
|
CUMO_GET_DATA_INDEX(p1,idx1,dtype,x);
|
|
19
18
|
y = m_data_to_num(x);
|
|
20
19
|
rb_yield(y);
|
|
21
20
|
}
|
|
22
21
|
} else {
|
|
23
22
|
for (; i--;) {
|
|
24
|
-
|
|
23
|
+
if (cumo_cuda_runtime_sync_if_busy()) { CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>"); }
|
|
25
24
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
26
25
|
y = m_data_to_num(x);
|
|
27
26
|
rb_yield(y);
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
static inline void
|
|
2
|
-
yield_each_with_index(dtype x, size_t *c, VALUE *a, int nd, int md)
|
|
3
|
-
{
|
|
4
|
-
int j;
|
|
5
|
-
|
|
6
|
-
a[0] = m_data_to_num(x);
|
|
7
|
-
for (j=0; j<=nd; j++) {
|
|
8
|
-
a[j+1] = SIZET2NUM(c[j]);
|
|
9
|
-
}
|
|
10
|
-
rb_yield(rb_ary_new4(md,a));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
1
|
static void
|
|
15
2
|
<%=c_iter%>(cumo_na_loop_t *const lp)
|
|
16
3
|
{
|
|
@@ -23,29 +10,26 @@ static void
|
|
|
23
10
|
int nd, md;
|
|
24
11
|
|
|
25
12
|
c = (size_t*)(lp->opt_ptr);
|
|
26
|
-
|
|
27
|
-
if (nd > 0) {nd--;}
|
|
28
|
-
md = nd + 2;
|
|
13
|
+
cumo_na_with_index_dims(lp->ndim, &nd, &md);
|
|
29
14
|
a = ALLOCA_N(VALUE,md);
|
|
30
15
|
|
|
31
16
|
CUMO_INIT_COUNTER(lp, i);
|
|
32
17
|
CUMO_INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
33
18
|
c[nd] = 0;
|
|
34
19
|
|
|
35
|
-
CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
36
20
|
|
|
37
21
|
if (idx1) {
|
|
38
22
|
for (; i--;) {
|
|
39
|
-
|
|
23
|
+
if (cumo_cuda_runtime_sync_if_busy()) { CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>"); }
|
|
40
24
|
CUMO_GET_DATA_INDEX(p1,idx1,dtype,x);
|
|
41
|
-
|
|
25
|
+
cumo_na_yield_with_index(m_data_to_num(x),c,a,nd,md);
|
|
42
26
|
c[nd]++;
|
|
43
27
|
}
|
|
44
28
|
} else {
|
|
45
29
|
for (; i--;) {
|
|
46
|
-
|
|
30
|
+
if (cumo_cuda_runtime_sync_if_busy()) { CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>"); }
|
|
47
31
|
CUMO_GET_DATA_STRIDE(p1,s1,dtype,x);
|
|
48
|
-
|
|
32
|
+
cumo_na_yield_with_index(m_data_to_num(x),c,a,nd,md);
|
|
49
33
|
c[nd]++;
|
|
50
34
|
}
|
|
51
35
|
}
|
|
@@ -17,7 +17,7 @@ static VALUE
|
|
|
17
17
|
if (na->ndim==0) {
|
|
18
18
|
ptr = cumo_na_get_pointer_for_read(self) + cumo_na_get_offset(self);
|
|
19
19
|
CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
20
|
-
|
|
20
|
+
cumo_cuda_runtime_device_synchronize();
|
|
21
21
|
v = m_extract(ptr);
|
|
22
22
|
cumo_na_release_lock(self);
|
|
23
23
|
return v;
|
|
@@ -12,7 +12,7 @@ static dtype
|
|
|
12
12
|
VALUE r, klass;
|
|
13
13
|
|
|
14
14
|
CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
15
|
-
|
|
15
|
+
cumo_cuda_runtime_device_synchronize();
|
|
16
16
|
|
|
17
17
|
if (CumoIsNArray(obj)) {
|
|
18
18
|
CumoGetNArray(obj,na);
|
|
@@ -19,7 +19,7 @@ static void
|
|
|
19
19
|
CUMO_SHOW_SYNCHRONIZE_FIXME_WARNING_ONCE("<%=name%>", "<%=type_name%>");
|
|
20
20
|
// The index array is filled by a kernel; wait for it before reading it
|
|
21
21
|
// from here.
|
|
22
|
-
|
|
22
|
+
cumo_cuda_runtime_device_synchronize();
|
|
23
23
|
if (idx1) {
|
|
24
24
|
for (; i--;) {
|
|
25
25
|
CUMO_SET_DATA_INDEX(p1,idx1,dtype,y);
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
#ifdef CUDNN_FOUND
|
|
2
2
|
|
|
3
|
-
<%
|
|
4
|
-
cudnn_dtype =
|
|
5
|
-
case type_name
|
|
6
|
-
when 'sfloat'
|
|
7
|
-
'CUDNN_DATA_FLOAT'
|
|
8
|
-
when 'dfloat'
|
|
9
|
-
'CUDNN_DATA_DOUBLE'
|
|
10
|
-
else
|
|
11
|
-
# CUDNN_DATA_HALF
|
|
12
|
-
raise 'not supported'
|
|
13
|
-
end
|
|
14
|
-
%>
|
|
15
3
|
|
|
16
4
|
// y = x.fixed_batch_norm(gamma, beta, mean, var, eps:, axis:)
|
|
17
5
|
static VALUE
|
|
@@ -20,8 +8,8 @@ static VALUE
|
|
|
20
8
|
cudnnDataType_t cudnn_dtype = <%= cudnn_dtype %>;
|
|
21
9
|
cudnnStatus_t status = 0;
|
|
22
10
|
cudnnHandle_t handle = 0;
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
<%=cudnn_scalar_t%> coef_one = 1;
|
|
12
|
+
<%=cudnn_scalar_t%> coef_zero = 0;
|
|
25
13
|
|
|
26
14
|
VALUE x=self, gamma, beta, mean, var, eps, axis, y;
|
|
27
15
|
VALUE kw_hash = Qnil;
|
|
@@ -85,10 +73,10 @@ static VALUE
|
|
|
85
73
|
}
|
|
86
74
|
|
|
87
75
|
CUMO_CHECK_NARRAY_TYPE(x, cT);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
cumo_cuda_cudnn_check_param_type(gamma, <%=cudnn_param_class%>, "gamma");
|
|
77
|
+
cumo_cuda_cudnn_check_param_type(beta, <%=cudnn_param_class%>, "beta");
|
|
78
|
+
cumo_cuda_cudnn_check_param_type(mean, <%=cudnn_param_class%>, "mean");
|
|
79
|
+
cumo_cuda_cudnn_check_param_type(var, <%=cudnn_param_class%>, "var");
|
|
92
80
|
|
|
93
81
|
x_cont = cumo_na_as_contiguous_array(x);
|
|
94
82
|
gamma_cont = cumo_na_as_contiguous_array(gamma);
|
|
@@ -115,9 +103,9 @@ static VALUE
|
|
|
115
103
|
mode = cumo_cuda_cudnn_GetBatchNormMode(axis_ndim, int_axis);
|
|
116
104
|
status = cumo_cuda_cudnn_CreateBNTensorDescriptor(&bn_desc, x_desc, mode);
|
|
117
105
|
if (status != CUDNN_STATUS_SUCCESS) goto FIXED_BATCH_NORM_ERROR;
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
106
|
+
// cuDNN derives the parameter descriptor as float for a half x and as x's
|
|
107
|
+
// own type otherwise, and the checks above hold every parameter to exactly
|
|
108
|
+
// that class, so none of them needs a cast.
|
|
121
109
|
|
|
122
110
|
handle = cumo_cuda_cudnn_handle();
|
|
123
111
|
|