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
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#ifndef CUMO_HALF_MACRO_KERNEL_H
|
|
2
|
+
#define CUMO_HALF_MACRO_KERNEL_H
|
|
3
|
+
|
|
4
|
+
#include "float_def_kernel.h"
|
|
5
|
+
#include "half_def_kernel.h"
|
|
6
|
+
#include <string.h>
|
|
7
|
+
|
|
8
|
+
#define CUMO_HALF_EPSILON 9.765625e-04f
|
|
9
|
+
|
|
10
|
+
#define m_zero cumo_float2half(0.0f)
|
|
11
|
+
#define m_one cumo_float2half(1.0f)
|
|
12
|
+
|
|
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
|
+
#define m_from_half(x) (x)
|
|
21
|
+
|
|
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"
|
|
197
|
+
|
|
198
|
+
#endif // CUMO_HALF_MACRO_KERNEL_H
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#include "half_def.h"
|
|
2
|
+
|
|
3
|
+
typedef cumo_half dtype;
|
|
4
|
+
typedef cumo_half rtype;
|
|
5
|
+
#define cT cumo_cHFloat
|
|
6
|
+
#define cRT cumo_cHFloat
|
|
7
|
+
#define mTM cumo_mHFloatMath
|
|
8
|
+
|
|
9
|
+
#include "half_macro.h"
|
|
10
|
+
#include "cublas_v2.h"
|
|
11
|
+
#include "cumo/cuda/cublas.h"
|
|
12
|
+
#include "cumo/cuda/cudnn.h"
|
|
13
|
+
|
|
14
|
+
#define m_extract(x) rb_float_new(cumo_half2float(*(cumo_half*)x))
|
|
15
|
+
#define m_nearly_eq(x,y) (fabsf(cumo_half2float(x)-cumo_half2float(y))<=(fabsf(cumo_half2float(x))+fabsf(cumo_half2float(y)))*CUMO_HALF_EPSILON*2)
|
|
16
|
+
|
|
17
|
+
#define M_EPSILON rb_float_new(9.765625e-04)
|
|
18
|
+
#define M_MIN rb_float_new(6.103515625e-05)
|
|
19
|
+
#define M_MAX rb_float_new(65504.0)
|
|
20
|
+
|
|
21
|
+
#define DATA_MIN cumo_float2half(-65504.0f)
|
|
22
|
+
#define DATA_MAX cumo_float2half(65504.0f)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#ifndef CUMO_HFLOAT_KERNEL_H
|
|
2
|
+
#define CUMO_HFLOAT_KERNEL_H
|
|
3
|
+
|
|
4
|
+
#include "half_def_kernel.h"
|
|
5
|
+
|
|
6
|
+
typedef cumo_half dtype;
|
|
7
|
+
typedef cumo_half rtype;
|
|
8
|
+
|
|
9
|
+
#include "half_macro_kernel.h"
|
|
10
|
+
|
|
11
|
+
#define m_nearly_eq(x,y) (fabsf(cumo_half2float(x)-cumo_half2float(y))<=(fabsf(cumo_half2float(x))+fabsf(cumo_half2float(y)))*CUMO_HALF_EPSILON*2)
|
|
12
|
+
|
|
13
|
+
#define DATA_MIN cumo_float2half(-65504.0f)
|
|
14
|
+
#define DATA_MAX cumo_float2half(65504.0f)
|
|
15
|
+
|
|
16
|
+
#endif // CUMO_HFLOAT_KERNEL_H
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
#include "half_def.h"
|
|
2
|
+
|
|
1
3
|
#define m_zero INT2FIX(0)
|
|
2
4
|
#define m_one INT2FIX(1)
|
|
3
5
|
|
|
@@ -6,6 +8,7 @@
|
|
|
6
8
|
|
|
7
9
|
#define m_from_double(x) rb_float_new(x)
|
|
8
10
|
#define m_from_real(x) rb_float_new(x)
|
|
11
|
+
#define m_from_half(x) m_from_real(cumo_half2float(x))
|
|
9
12
|
#define m_from_sint(x) INT2FIX(x)
|
|
10
13
|
#define m_from_int32(x) INT322NUM(x)
|
|
11
14
|
#define m_from_int64(x) INT642NUM(x)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
#include "half_def.h"
|
|
2
|
+
|
|
1
3
|
#define m_zero 0
|
|
2
4
|
#define m_one 1
|
|
3
5
|
|
|
@@ -6,6 +8,7 @@
|
|
|
6
8
|
/* Handle negative values consistently across platforms for unsigned integer types */
|
|
7
9
|
#define m_from_double(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
|
|
8
10
|
#define m_from_real(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
|
|
11
|
+
#define m_from_half(x) m_from_real(cumo_half2float(x))
|
|
9
12
|
#define m_from_sint(x) (x)
|
|
10
13
|
#define m_from_int32(x) (x)
|
|
11
14
|
#define m_from_int64(x) (x)
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
#ifndef CUMO_XINT_MACRO_KERNEL_H
|
|
2
2
|
#define CUMO_XINT_MACRO_KERNEL_H
|
|
3
|
+
#include "half_def_kernel.h"
|
|
3
4
|
|
|
4
5
|
#define m_zero 0
|
|
5
6
|
#define m_one 1
|
|
6
7
|
|
|
7
8
|
#define m_from_double(x) (x)
|
|
8
9
|
#define m_from_real(x) (x)
|
|
10
|
+
#define m_from_half(x) m_from_real(cumo_half2float(x))
|
|
9
11
|
#define m_from_sint(x) (x)
|
|
10
12
|
#define m_from_int32(x) (x)
|
|
11
13
|
#define m_from_int64(x) (x)
|
data/ext/cumo/include/cumo.h
CHANGED
data/ext/cumo/narray/data.c
CHANGED
|
@@ -77,7 +77,7 @@ iter_copy_bytes(cumo_na_loop_t *const lp)
|
|
|
77
77
|
// with nothing ordering that against the host reading it back.
|
|
78
78
|
if (idx1 || idx2) {
|
|
79
79
|
CUMO_SHOW_SYNCHRONIZE_WARNING_ONCE("copy", "any");
|
|
80
|
-
|
|
80
|
+
cumo_cuda_runtime_device_synchronize();
|
|
81
81
|
}
|
|
82
82
|
e = lp->args[0].elmsz;
|
|
83
83
|
LOOP_UNARY_PTR(lp,m_memcpy);
|
|
@@ -256,6 +256,8 @@ cumo_na_swapaxes(VALUE self, VALUE a1, VALUE a2)
|
|
|
256
256
|
cumo_narray_view_t *na;
|
|
257
257
|
volatile VALUE view;
|
|
258
258
|
|
|
259
|
+
// cumo_na_make_view borrows, so index_owned is zero and the swap below
|
|
260
|
+
// has no ownership bits to carry with the strides.
|
|
259
261
|
view = cumo_na_make_view(self);
|
|
260
262
|
CumoGetNArrayView(view,na);
|
|
261
263
|
|
|
@@ -459,6 +461,8 @@ cumo_na_reshape_bang(int argc, VALUE *argv, VALUE self)
|
|
|
459
461
|
if (OBJ_FROZEN(self)) {
|
|
460
462
|
rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
|
|
461
463
|
}
|
|
464
|
+
// A contiguous view has every dimension on a stride, so overwriting them
|
|
465
|
+
// below drops no index array this view owns.
|
|
462
466
|
if (cumo_na_check_contiguous(self)==Qfalse) {
|
|
463
467
|
rb_raise(rb_eStandardError, "cannot change shape of non-contiguous NArray");
|
|
464
468
|
}
|
|
@@ -469,15 +473,15 @@ cumo_na_reshape_bang(int argc, VALUE *argv, VALUE self)
|
|
|
469
473
|
if (na->type == CUMO_NARRAY_VIEW_T) {
|
|
470
474
|
CumoGetNArrayView(self, na2);
|
|
471
475
|
if (na->ndim < argc) {
|
|
472
|
-
stridx =
|
|
476
|
+
stridx = ZALLOC_N(cumo_stridx_t,argc);
|
|
473
477
|
} else {
|
|
474
478
|
stridx = na2->stridx;
|
|
475
479
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
480
|
+
// A contiguous view holds its elements one after another from its
|
|
481
|
+
// offset, so the step between them is the element size whatever the
|
|
482
|
+
// strides say: a length-1 dimension may carry any stride, including a
|
|
483
|
+
// negative one.
|
|
484
|
+
stride = cumo_na_element_stride(self);
|
|
481
485
|
for (i=argc; i--;) {
|
|
482
486
|
CUMO_SDX_SET_STRIDE(stridx[i],stride);
|
|
483
487
|
stride *= shape[i];
|
|
@@ -526,11 +530,11 @@ VALUE
|
|
|
526
530
|
cumo_na_flatten_dim(VALUE self, int sd)
|
|
527
531
|
{
|
|
528
532
|
int i, nd, fd;
|
|
529
|
-
size_t *
|
|
533
|
+
size_t *idx2;
|
|
530
534
|
size_t stride;
|
|
531
535
|
size_t *shape, size;
|
|
532
536
|
cumo_narray_t *na;
|
|
533
|
-
cumo_narray_view_t *na1, *na2;
|
|
537
|
+
cumo_narray_view_t *na1 = NULL, *na2;
|
|
534
538
|
volatile VALUE view;
|
|
535
539
|
|
|
536
540
|
CumoGetNArray(self,na);
|
|
@@ -561,7 +565,7 @@ cumo_na_flatten_dim(VALUE self, int sd)
|
|
|
561
565
|
|
|
562
566
|
// new stride
|
|
563
567
|
cumo_na_setup_shape((cumo_narray_t*)na2, sd+1, shape);
|
|
564
|
-
na2->stridx =
|
|
568
|
+
na2->stridx = ZALLOC_N(cumo_stridx_t,sd+1);
|
|
565
569
|
|
|
566
570
|
switch(na->type) {
|
|
567
571
|
case CUMO_NARRAY_DATA_T:
|
|
@@ -578,25 +582,29 @@ cumo_na_flatten_dim(VALUE self, int sd)
|
|
|
578
582
|
CumoGetNArrayView(self, na1);
|
|
579
583
|
na2->data = na1->data;
|
|
580
584
|
na2->offset = na1->offset;
|
|
585
|
+
// Every caller passes sd == 0 today, so this loop does not run.
|
|
581
586
|
for (i=0; i<sd; i++) {
|
|
587
|
+
na2->stridx[i] = na1->stridx[i];
|
|
582
588
|
if (CUMO_SDX_IS_INDEX(na1->stridx[i])) {
|
|
583
|
-
|
|
584
|
-
idx2 = (size_t*)cumo_cuda_runtime_malloc(sizeof(size_t)*shape[i]);
|
|
585
|
-
cumo_cuda_runtime_check_status(cudaMemcpyAsync(idx2,idx1,sizeof(size_t)*shape[i],cudaMemcpyDeviceToDevice,0));
|
|
586
|
-
CUMO_SDX_SET_INDEX(na2->stridx[i],idx2);
|
|
587
|
-
} else {
|
|
588
|
-
na2->stridx[i] = na1->stridx[i];
|
|
589
|
+
cumo_na_index_borrow(na2, self);
|
|
589
590
|
}
|
|
590
591
|
}
|
|
591
|
-
// flat
|
|
592
|
+
// flat dimension == last dimension that advances. A length-1 dimension
|
|
593
|
+
// is not part of the chain cumo_na_check_ladder() walks, so the stride
|
|
594
|
+
// at nd-1 may be any value.
|
|
592
595
|
if (RTEST(cumo_na_check_ladder(self,sd))) {
|
|
593
|
-
|
|
596
|
+
i = cumo_na_last_dim_with_elements(na, sd);
|
|
597
|
+
if (i < 0) {
|
|
598
|
+
CUMO_SDX_SET_STRIDE(na2->stridx[sd], (ssize_t)cumo_na_element_stride(self));
|
|
599
|
+
} else {
|
|
600
|
+
na2->stridx[sd] = na1->stridx[i];
|
|
601
|
+
}
|
|
594
602
|
} else {
|
|
595
603
|
cumo_na_iarray_stridx_t iarray;
|
|
596
604
|
cumo_na_indexer_t indexer;
|
|
597
605
|
|
|
598
606
|
idx2 = (size_t*)cumo_cuda_runtime_malloc(sizeof(size_t)*((shape[sd]==0) ? 1 : shape[sd]));
|
|
599
|
-
|
|
607
|
+
cumo_na_index_own(na2,sd,idx2);
|
|
600
608
|
fd = nd-sd;
|
|
601
609
|
iarray.ptr = NULL;
|
|
602
610
|
indexer.ndim = fd;
|
|
@@ -609,7 +617,11 @@ cumo_na_flatten_dim(VALUE self, int sd)
|
|
|
609
617
|
}
|
|
610
618
|
break;
|
|
611
619
|
}
|
|
612
|
-
|
|
620
|
+
if (na1 != NULL) {
|
|
621
|
+
cumo_na_index_mark_derived(na2, na1);
|
|
622
|
+
} else {
|
|
623
|
+
cumo_na_index_mark_filled(na2);
|
|
624
|
+
}
|
|
613
625
|
return view;
|
|
614
626
|
}
|
|
615
627
|
|
|
@@ -667,13 +679,13 @@ void cumo_na_diagonal_stride_index_kernel_launch(size_t *idx, ssize_t s0, size_t
|
|
|
667
679
|
static VALUE
|
|
668
680
|
cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
669
681
|
{
|
|
670
|
-
int i, k, nd;
|
|
682
|
+
int i, k, nd, borrow;
|
|
671
683
|
size_t *idx0, *idx1, *diag_idx;
|
|
672
684
|
size_t *shape;
|
|
673
685
|
size_t diag_size;
|
|
674
686
|
ssize_t stride, stride0, stride1;
|
|
675
687
|
cumo_narray_t *na;
|
|
676
|
-
cumo_narray_view_t *na1, *na2;
|
|
688
|
+
cumo_narray_view_t *na1 = NULL, *na2;
|
|
677
689
|
VALUE view;
|
|
678
690
|
VALUE vofs=0, vaxes=0;
|
|
679
691
|
ssize_t kofs;
|
|
@@ -768,7 +780,7 @@ cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
|
768
780
|
|
|
769
781
|
// new stride
|
|
770
782
|
cumo_na_setup_shape((cumo_narray_t*)na2, nd-1, shape);
|
|
771
|
-
na2->stridx =
|
|
783
|
+
na2->stridx = ZALLOC_N(cumo_stridx_t, nd-1);
|
|
772
784
|
|
|
773
785
|
switch(na->type) {
|
|
774
786
|
case CUMO_NARRAY_DATA_T:
|
|
@@ -799,19 +811,19 @@ cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
|
799
811
|
CumoGetNArrayView(self, na1);
|
|
800
812
|
na2->data = na1->data;
|
|
801
813
|
na2->offset = na1->offset;
|
|
814
|
+
borrow = !CUMO_SDX_IS_INDEX(na1->stridx[ax[0]]) && !CUMO_SDX_IS_INDEX(na1->stridx[ax[1]]);
|
|
802
815
|
for (i=k=0; i<nd; i++) {
|
|
803
816
|
if (i != ax[0] && i != ax[1]) {
|
|
804
|
-
if (CUMO_SDX_IS_INDEX(na1->stridx[i])) {
|
|
817
|
+
if (borrow || !CUMO_SDX_IS_INDEX(na1->stridx[i])) {
|
|
818
|
+
na2->stridx[k] = na1->stridx[i];
|
|
819
|
+
if (CUMO_SDX_IS_INDEX(na1->stridx[i])) {
|
|
820
|
+
cumo_na_index_borrow(na2, self);
|
|
821
|
+
}
|
|
822
|
+
} else {
|
|
805
823
|
idx0 = CUMO_SDX_GET_INDEX(na1->stridx[i]);
|
|
806
|
-
// idx1 = ALLOC_N(size_t, na->shape[i]);
|
|
807
|
-
// for (j=0; j<na->shape[i]; j++) {
|
|
808
|
-
// idx1[j] = idx0[j];
|
|
809
|
-
// }
|
|
810
824
|
idx1 = (size_t*)cumo_cuda_runtime_malloc(sizeof(size_t)*na->shape[i]);
|
|
825
|
+
cumo_na_index_own(na2,k,idx1);
|
|
811
826
|
cumo_cuda_runtime_check_status(cudaMemcpyAsync(idx1,idx0,sizeof(size_t)*na->shape[i],cudaMemcpyDeviceToDevice,0));
|
|
812
|
-
CUMO_SDX_SET_INDEX(na2->stridx[k],idx1);
|
|
813
|
-
} else {
|
|
814
|
-
na2->stridx[k] = na1->stridx[i];
|
|
815
827
|
}
|
|
816
828
|
k++;
|
|
817
829
|
}
|
|
@@ -820,6 +832,7 @@ cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
|
820
832
|
idx0 = CUMO_SDX_GET_INDEX(na1->stridx[ax[0]]);
|
|
821
833
|
// diag_idx = ALLOC_N(size_t, diag_size);
|
|
822
834
|
diag_idx = (size_t*)cumo_cuda_runtime_malloc(sizeof(size_t)*diag_size);
|
|
835
|
+
cumo_na_index_own(na2,nd-2,diag_idx);
|
|
823
836
|
if (CUMO_SDX_IS_INDEX(na1->stridx[ax[1]])) {
|
|
824
837
|
idx1 = CUMO_SDX_GET_INDEX(na1->stridx[ax[1]]);
|
|
825
838
|
cumo_na_diagonal_index_index_kernel_launch(diag_idx, idx0, idx1, k0, k1, diag_size);
|
|
@@ -827,15 +840,14 @@ cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
|
827
840
|
stride1 = CUMO_SDX_GET_STRIDE(na1->stridx[ax[1]]);
|
|
828
841
|
cumo_na_diagonal_index_stride_kernel_launch(diag_idx, idx0, stride1, k0, k1, diag_size);
|
|
829
842
|
}
|
|
830
|
-
CUMO_SDX_SET_INDEX(na2->stridx[nd-2],diag_idx);
|
|
831
843
|
} else {
|
|
832
844
|
stride0 = CUMO_SDX_GET_STRIDE(na1->stridx[ax[0]]);
|
|
833
845
|
if (CUMO_SDX_IS_INDEX(na1->stridx[ax[1]])) {
|
|
834
846
|
idx1 = CUMO_SDX_GET_INDEX(na1->stridx[ax[1]]);
|
|
835
847
|
// diag_idx = ALLOC_N(size_t, diag_size);
|
|
836
848
|
diag_idx = (size_t*)cumo_cuda_runtime_malloc(sizeof(size_t)*diag_size);
|
|
849
|
+
cumo_na_index_own(na2,nd-2,diag_idx);
|
|
837
850
|
cumo_na_diagonal_stride_index_kernel_launch(diag_idx, stride0, idx1, k0, k1, diag_size);
|
|
838
|
-
CUMO_SDX_SET_INDEX(na2->stridx[nd-2],diag_idx);
|
|
839
851
|
} else {
|
|
840
852
|
stride1 = CUMO_SDX_GET_STRIDE(na1->stridx[ax[1]]);
|
|
841
853
|
na2->offset += stride0*k0 + stride1*k1;
|
|
@@ -844,153 +856,17 @@ cumo_na_diagonal(int argc, VALUE *argv, VALUE self)
|
|
|
844
856
|
}
|
|
845
857
|
break;
|
|
846
858
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
#if 0
|
|
854
|
-
#ifdef SWAP
|
|
855
|
-
#undef SWAP
|
|
856
|
-
#endif
|
|
857
|
-
#define SWAP(a,b,t) {t=a;a=b;b=t;}
|
|
858
|
-
|
|
859
|
-
static VALUE
|
|
860
|
-
cumo_na_new_dimension_for_dot(VALUE self, int pos, int len, bool transpose)
|
|
861
|
-
{
|
|
862
|
-
int i, k, l, nd;
|
|
863
|
-
size_t j;
|
|
864
|
-
size_t *idx1, *idx2;
|
|
865
|
-
size_t *shape;
|
|
866
|
-
ssize_t stride;
|
|
867
|
-
cumo_narray_t *na;
|
|
868
|
-
cumo_narray_view_t *na1, *na2;
|
|
869
|
-
size_t shape_n;
|
|
870
|
-
cumo_stridx_t stridx_n;
|
|
871
|
-
volatile VALUE view;
|
|
872
|
-
|
|
873
|
-
CumoGetNArray(self,na);
|
|
874
|
-
nd = na->ndim;
|
|
875
|
-
|
|
876
|
-
view = cumo_na_s_allocate_view(rb_obj_class(self));
|
|
877
|
-
|
|
878
|
-
cumo_na_copy_flags(self, view);
|
|
879
|
-
CumoGetNArrayView(view, na2);
|
|
880
|
-
|
|
881
|
-
// new dimension
|
|
882
|
-
if (pos < 0) pos += nd;
|
|
883
|
-
if (pos > nd || pos < 0) {
|
|
884
|
-
rb_raise(rb_eRangeError,"new dimension is out of range");
|
|
885
|
-
}
|
|
886
|
-
nd += len;
|
|
887
|
-
shape = ALLOCA_N(size_t,nd);
|
|
888
|
-
na2->stridx = ALLOC_N(cumo_stridx_t,nd);
|
|
889
|
-
|
|
890
|
-
switch(na->type) {
|
|
891
|
-
case CUMO_NARRAY_DATA_T:
|
|
892
|
-
case CUMO_NARRAY_FILEMAP_T:
|
|
893
|
-
i = k = 0;
|
|
894
|
-
while (i < nd) {
|
|
895
|
-
if (i == pos && len > 0) {
|
|
896
|
-
for (l=0; l<len; l++) {
|
|
897
|
-
shape[i++] = 1;
|
|
898
|
-
}
|
|
899
|
-
} else {
|
|
900
|
-
shape[i++] = na->shape[k++];
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
cumo_na_setup_shape((cumo_narray_t*)na2, nd, shape);
|
|
904
|
-
stride = cumo_na_element_stride(self);
|
|
905
|
-
for (i=nd; i--;) {
|
|
906
|
-
CUMO_SDX_SET_STRIDE(na2->stridx[i], stride);
|
|
907
|
-
stride *= shape[i];
|
|
908
|
-
}
|
|
909
|
-
na2->offset = 0;
|
|
910
|
-
na2->data = self;
|
|
911
|
-
break;
|
|
912
|
-
case CUMO_NARRAY_VIEW_T:
|
|
913
|
-
CumoGetNArrayView(self, na1);
|
|
914
|
-
i = k = 0;
|
|
915
|
-
while (i < nd) {
|
|
916
|
-
if (i == pos && len > 0) {
|
|
917
|
-
if (CUMO_SDX_IS_INDEX(na1->stridx[k])) {
|
|
918
|
-
stride = CUMO_SDX_GET_INDEX(na1->stridx[k])[0];
|
|
919
|
-
} else {
|
|
920
|
-
stride = CUMO_SDX_GET_STRIDE(na1->stridx[k]);
|
|
921
|
-
}
|
|
922
|
-
for (l=0; l<len; l++) {
|
|
923
|
-
shape[i] = 1;
|
|
924
|
-
CUMO_SDX_SET_STRIDE(na2->stridx[i], stride);
|
|
925
|
-
i++;
|
|
926
|
-
}
|
|
927
|
-
} else {
|
|
928
|
-
shape[i] = na1->base.shape[k];
|
|
929
|
-
if (CUMO_SDX_IS_INDEX(na1->stridx[k])) {
|
|
930
|
-
idx1 = CUMO_SDX_GET_INDEX(na1->stridx[k]);
|
|
931
|
-
idx2 = ALLOC_N(size_t,na1->base.shape[k]);
|
|
932
|
-
for (j=0; j<na1->base.shape[k]; j++) {
|
|
933
|
-
idx2[j] = idx1[j];
|
|
934
|
-
}
|
|
935
|
-
CUMO_SDX_SET_INDEX(na2->stridx[i], idx2);
|
|
936
|
-
} else {
|
|
937
|
-
na2->stridx[i] = na1->stridx[k];
|
|
938
|
-
}
|
|
939
|
-
i++; k++;
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
cumo_na_setup_shape((cumo_narray_t*)na2, nd, shape);
|
|
943
|
-
na2->offset = na1->offset;
|
|
944
|
-
na2->data = na1->data;
|
|
945
|
-
break;
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
if (transpose) {
|
|
949
|
-
SWAP(na2->base.shape[nd-1], na2->base.shape[nd-2], shape_n);
|
|
950
|
-
SWAP(na2->stridx[nd-1], na2->stridx[nd-2], stridx_n);
|
|
859
|
+
if (na1 != NULL) {
|
|
860
|
+
cumo_na_index_mark_derived(na2, na1);
|
|
861
|
+
} else {
|
|
862
|
+
cumo_na_index_mark_filled(na2);
|
|
951
863
|
}
|
|
952
|
-
|
|
953
864
|
return view;
|
|
954
865
|
}
|
|
955
866
|
|
|
956
|
-
|
|
957
867
|
//----------------------------------------------------------------------
|
|
958
868
|
|
|
959
|
-
/*
|
|
960
|
-
* call-seq:
|
|
961
|
-
* narray.dot(other) => narray
|
|
962
|
-
*
|
|
963
|
-
* Returns dot product.
|
|
964
|
-
*
|
|
965
|
-
*/
|
|
966
|
-
|
|
967
|
-
static VALUE
|
|
968
|
-
cumo_na_dot(VALUE self, VALUE other)
|
|
969
|
-
{
|
|
970
|
-
volatile VALUE a1=self, a2=other;
|
|
971
|
-
cumo_narray_t *na1, *na2;
|
|
972
869
|
|
|
973
|
-
if (!rb_respond_to(a1, cumo_id_mulsum)) {
|
|
974
|
-
rb_raise(rb_eNoMethodError,"requires mulsum method for dot method");
|
|
975
|
-
}
|
|
976
|
-
CumoGetNArray(a1,na1);
|
|
977
|
-
CumoGetNArray(a2,na2);
|
|
978
|
-
if (na1->ndim==0 || na2->ndim==0) {
|
|
979
|
-
rb_raise(cumo_na_eDimensionError,"zero dimensional narray");
|
|
980
|
-
}
|
|
981
|
-
if (na2->ndim > 1) {
|
|
982
|
-
if (na1->shape[na1->ndim-1] != na2->shape[na2->ndim-2]) {
|
|
983
|
-
rb_raise(cumo_na_eShapeError,"shape mismatch: self.shape[-1](=%"SZF"d) != other.shape[-2](=%"SZF"d)",
|
|
984
|
-
na1->shape[na1->ndim-1], na2->shape[na2->ndim-2]);
|
|
985
|
-
}
|
|
986
|
-
// insert new axis [ ..., last-1-dim, newaxis*other.ndim, last-dim ]
|
|
987
|
-
a1 = cumo_na_new_dimension_for_dot(a1, na1->ndim-1, na2->ndim-1, 0);
|
|
988
|
-
// insert & transpose [ newaxis*self.ndim, ..., last-dim, last-1-dim ]
|
|
989
|
-
a2 = cumo_na_new_dimension_for_dot(a2, 0, na1->ndim-1, 1);
|
|
990
|
-
}
|
|
991
|
-
return rb_funcall(a1,cumo_id_mulsum,2,a2,INT2FIX(-1));
|
|
992
|
-
}
|
|
993
|
-
#endif
|
|
994
870
|
|
|
995
871
|
void
|
|
996
872
|
Init_cumo_na_data(void)
|
|
@@ -1024,7 +900,6 @@ Init_cumo_na_data(void)
|
|
|
1024
900
|
rb_define_method(cNArray, "to_host", cumo_na_to_host, 0);
|
|
1025
901
|
rb_define_method(cNArray, "to_swapped", cumo_na_to_swapped, 0);
|
|
1026
902
|
|
|
1027
|
-
//rb_define_method(cNArray, "dot", cumo_na_dot, 1);
|
|
1028
903
|
|
|
1029
904
|
cumo_id_copy = rb_intern("copy");
|
|
1030
905
|
cumo_id_mulsum = rb_intern("mulsum");
|