cumo 0.14.1 → 0.15.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 +21 -0
- data/README.md +24 -0
- data/Rakefile +3 -1
- data/ext/cumo/cuda/cub.cu +26 -0
- data/ext/cumo/extconf.rb +1 -1
- data/ext/cumo/{narray/sort_kernel.cu → include/cumo/sort_kernel.h} +15 -15
- data/ext/cumo/include/cumo/template_kernel.h +2 -0
- data/ext/cumo/narray/data.c +3 -0
- data/ext/cumo/narray/gen/cogen_kernel.rb +19 -10
- data/ext/cumo/narray/gen/kernel_parts.rb +5 -3
- data/ext/cumo/narray/gen/spec.rb +4 -0
- data/ext/cumo/narray/gen/tmpl/accum_arg_kernel.cu +2 -2
- data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +1 -1
- data/ext/cumo/narray/gen/tmpl/accum_index_kernel.cu +2 -2
- data/ext/cumo/narray/gen/tmpl/complex_accum_kernel.cu +17 -3
- data/ext/cumo/narray/gen/tmpl/cum_kernel.cu +2 -0
- data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +15 -3
- data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +19 -1
- data/ext/cumo/narray/gen/tmpl/sort_kernel.cu +19 -0
- data/ext/cumo/narray/index.c +98 -82
- data/ext/cumo/narray/narray.c +9 -0
- data/ext/cumo/narray/ndloop.c +4 -0
- data/ext/cumo/narray/step.c +0 -2
- data/lib/cumo/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d6fcb0462dc2821749f43c243267e8eef32c5362d2a647769c3f93ccc048ddd0
|
|
4
|
+
data.tar.gz: 131ec1045f331591fb3f1c522824ea1e14c56fad40091bccacde73bb7f64a649
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfbb78f6f9ea625ae2848210722aa58106e6efd80af31d38e239585def253b7fb0e00426d18804e4177040492469d3498eaf61dca0cb7880ee482bd1c9669d0e
|
|
7
|
+
data.tar.gz: 80c944b3b2a544c593a221c9600c2a8cc441b273e37dc77f3ca1bbb738e381e1fcc0db42cbc66265f6d75832ee0ca396b008ffec7ff666549db313d386b82e81
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# 0.15.0 (2026/11/02)
|
|
2
|
+
|
|
3
|
+
Breaking changes:
|
|
4
|
+
|
|
5
|
+
* A subscript of an empty array is read as it is for any other array, where every subscript of an empty array raised `Cumo::NArray::ShapeError`. `a[true, 1]` of a 0 x 3 array answers an empty view, and a subscript that names an element raises as it does for any array, so `a[0]` raises `IndexError`. An empty range now selects nothing when it starts where an element could be inserted, as with `Array#[]`, so `b[2...2, true]` of a 2 x 3 array answers a 0 x 3 view where it raised `RangeError`. The README lists where this differs from Numo (PR #641)
|
|
6
|
+
* `Cumo::RObject` no longer has `store_binary`, `to_string`, `hton` or `Cumo::RObject.from_string`, and `set` with a String raises `NoMethodError` for it. They read or wrote the object references of an RObject as raw bytes, so the next garbage collection could crash, and `to_string` gave out heap addresses. Calling the methods of `Cumo::NArray` on an RObject through `bind_call` raises `TypeError` (PR #638)
|
|
7
|
+
|
|
8
|
+
Fixes:
|
|
9
|
+
|
|
10
|
+
* Fix `require "cumo"` under `ruby -w` warning "method redefined; discarding old %". Cumo no longer defines `Range#%` again, which Ruby has had since 2.6 and which works the same (PR #643)
|
|
11
|
+
* Fix a crash, possible since 0.7.0, when storing an Array whose NArray row of another type is followed by a row that raises, such as one with the wrong number of dimensions. The garbage collector could free the cast copy of the row before the store let go of it (PR #642)
|
|
12
|
+
* Fix a range with a negative step and an excluded or missing end selecting the wrong elements: `(4...1).step(-1)` selected 5 elements of a 5-element array where it should select 3, and `(3..).step(-1)` none. Fix a stepped range that selects nothing returning elements, as `(1..0).step(2)` returned one and `(3...3).step(-1)` two (PR #641)
|
|
13
|
+
* Fix `to_a` and `format_to_a` aborting when Cumo is compiled with `RUBY_DEBUG` against a Ruby whose headers check the index of `RARRAY_AREF`, as Ruby master does since ruby/ruby@61261bf5c4 (PR #640)
|
|
14
|
+
|
|
15
|
+
Changes:
|
|
16
|
+
|
|
17
|
+
* CI builds against CUDA 13.4.3 on Ubuntu 26.04 where it built against 13.4.1 on Ubuntu 24.04, and the CUDA 12.9.2 job builds for sm_121 where it built for sm_120 (PR #639)
|
|
18
|
+
* The first `sort`, `median` or `sort_index` of a type loads the sort kernels of that type alone, where the first of a process loaded those of all twelve types. On SFloat the first `sort` is about 5.7 times faster, `median` about 9 times and `sort_index` about 3 times (PR #636)
|
|
19
|
+
* The first `cumsum` or `cumprod` of a process no longer loads every sort kernel, which makes the first SFloat `cumsum` about 2.1 times faster and keeps the peak RSS 57 MB lower (PR #635)
|
|
20
|
+
* `sum`, `mean`, `max`, `min` and the `dot` of two vectors have a kernel module of their own, so the first of them on a type no longer loads every reduction of the type. The first SFloat `sum` or vector `dot` of a process is about 8.6 times faster (PR #634)
|
|
21
|
+
|
|
1
22
|
# 0.14.1 (2026/10/22)
|
|
2
23
|
|
|
3
24
|
Fixes:
|
data/README.md
CHANGED
|
@@ -198,6 +198,30 @@ Cumo::DFloat.new(1, 3).seq.transpose.contiguous? #=> true
|
|
|
198
198
|
Code that runs against both libraries should not read `contiguous?` and expect the same answer.
|
|
199
199
|
Where it wants a contiguous array it can ask for one, since `dup` answers one in either library.
|
|
200
200
|
|
|
201
|
+
#### Subscripts That Select Nothing
|
|
202
|
+
|
|
203
|
+
Numo raises `ShapeError` for every subscript of an empty array.
|
|
204
|
+
Cumo returns the empty view numpy does, and raises only for a subscript that names an element.
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
a = Cumo::DFloat.new(0, 3)
|
|
208
|
+
a[true, 1].shape #=> [0], where Numo raises ShapeError
|
|
209
|
+
a[0] # raises IndexError, where Numo raises ShapeError
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
A range that selects nothing only has to start where an element could be inserted, as with `Array#[]`.
|
|
213
|
+
Numo raises `RangeError` when such a range starts at either end of an axis.
|
|
214
|
+
|
|
215
|
+
```ruby
|
|
216
|
+
b = Cumo::DFloat.new(2, 3).seq
|
|
217
|
+
b[2...2, true].shape #=> [0, 3], where Numo raises RangeError
|
|
218
|
+
b[3...3, true] # raises RangeError in both
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
A stepped range that selects nothing also selects nothing in Cumo.
|
|
222
|
+
Numo returns one element for `(1..0).step(2)` and two for `(3...3).step(-1)`.
|
|
223
|
+
`compatible_mode` does not change any of this.
|
|
224
|
+
|
|
201
225
|
### Keeping Scalars On The Device
|
|
202
226
|
|
|
203
227
|
The 0-dimensional return is what lets an iterative loop stay on the GPU.
|
data/Rakefile
CHANGED
|
@@ -39,7 +39,9 @@ Rake::TestTask.new(:test) do |t|
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
require "rake/extensiontask"
|
|
42
|
-
Rake::ExtensionTask.new("cumo")
|
|
42
|
+
ext = Rake::ExtensionTask.new("cumo")
|
|
43
|
+
# The Makefile lists an object for each kernel part, so a new part needs extconf.rb to run again.
|
|
44
|
+
file "#{ext.tmp_dir}/#{ext.platform}/#{ext.name}/#{RUBY_VERSION}/Makefile" => "ext/cumo/narray/gen/kernel_parts.rb"
|
|
43
45
|
|
|
44
46
|
desc 'Build the C++ memory pool test harness without running it (running it needs a GPU)'
|
|
45
47
|
task :build_ctest do
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#include <cub/util_device.cuh>
|
|
2
|
+
#include "cumo/template_kernel.h"
|
|
3
|
+
|
|
4
|
+
namespace {
|
|
5
|
+
|
|
6
|
+
__global__ void cumo_cub_ptx_version_probe() {}
|
|
7
|
+
|
|
8
|
+
} // namespace
|
|
9
|
+
|
|
10
|
+
// CUB learns each device's PTX version once, from the attributes of an empty
|
|
11
|
+
// kernel. Each translation unit has its own empty kernel, but the link keeps
|
|
12
|
+
// one copy of the code that asks. The query loads the module that copy came
|
|
13
|
+
// from, which can be a large one the caller never runs. This module has one
|
|
14
|
+
// kernel built with the same flags, so it gives the same version at little cost.
|
|
15
|
+
extern "C" void
|
|
16
|
+
cumo_cuda_cub_prime_ptx_version(void)
|
|
17
|
+
{
|
|
18
|
+
cub::GetPerDeviceAttributeCache<cub::PtxVersionCacheTag>()(
|
|
19
|
+
[](int& ptx_version) {
|
|
20
|
+
cudaFuncAttributes attrs = {};
|
|
21
|
+
cudaError_t status = cudaFuncGetAttributes(&attrs, (const void*)cumo_cub_ptx_version_probe);
|
|
22
|
+
ptx_version = attrs.ptxVersion * 10;
|
|
23
|
+
return status;
|
|
24
|
+
},
|
|
25
|
+
cub::CurrentDevice());
|
|
26
|
+
}
|
data/ext/cumo/extconf.rb
CHANGED
|
@@ -55,7 +55,6 @@ narray/ndloop
|
|
|
55
55
|
narray/ndloop_kernel
|
|
56
56
|
narray/data
|
|
57
57
|
narray/data_kernel
|
|
58
|
-
narray/sort_kernel
|
|
59
58
|
narray/math
|
|
60
59
|
narray/SFMT
|
|
61
60
|
narray/struct
|
|
@@ -70,6 +69,7 @@ cuda/cudnn
|
|
|
70
69
|
cuda/cudnn_impl
|
|
71
70
|
cuda/cusolver
|
|
72
71
|
cuda/cufft
|
|
72
|
+
cuda/cub
|
|
73
73
|
)
|
|
74
74
|
%w[bit int8 int16 int32 int64 uint8 uint16 uint32 uint64 hfloat bfloat sfloat dfloat scomplex dcomplex robject].each do |type_name|
|
|
75
75
|
srcs << "narray/types/#{type_name}"
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#ifndef CUMO_SORT_KERNEL_H
|
|
2
|
+
#define CUMO_SORT_KERNEL_H
|
|
3
|
+
|
|
1
4
|
#include "cumo/narray_kernel.h"
|
|
2
5
|
#include "cumo/indexer.h"
|
|
3
6
|
#include "cumo/template_kernel.h"
|
|
@@ -146,6 +149,7 @@ cudaError_t sort_pairs(const Key* kin, Key* kout, const Value* vin, Value* vout,
|
|
|
146
149
|
int64_t total, int64_t n_rows, int64_t row_len) {
|
|
147
150
|
size_t bytes = 0;
|
|
148
151
|
cudaError_t st = cudaSuccess;
|
|
152
|
+
cumo_cuda_cub_prime_ptx_version();
|
|
149
153
|
if (n_rows == 1) {
|
|
150
154
|
st = cub::DeviceRadixSort::SortPairs(nullptr, bytes, kin, kout, vin, vout, total, 0, sizeof(Key) * 8, cumo_cuda_stream());
|
|
151
155
|
if (st != cudaSuccess) { return st; }
|
|
@@ -168,6 +172,7 @@ template <typename Key>
|
|
|
168
172
|
cudaError_t sort_keys(const Key* kin, Key* kout, int64_t total, int64_t n_rows, int64_t row_len) {
|
|
169
173
|
size_t bytes = 0;
|
|
170
174
|
cudaError_t st = cudaSuccess;
|
|
175
|
+
cumo_cuda_cub_prime_ptx_version();
|
|
171
176
|
if (n_rows == 1) {
|
|
172
177
|
st = cub::DeviceRadixSort::SortKeys(nullptr, bytes, kin, kout, total, 0, sizeof(Key) * 8, cumo_cuda_stream());
|
|
173
178
|
if (st != cudaSuccess) { return st; }
|
|
@@ -329,6 +334,12 @@ __global__ void iota_kernel(I* out, int64_t n) {
|
|
|
329
334
|
}
|
|
330
335
|
}
|
|
331
336
|
|
|
337
|
+
// The positions go to CUB as this rather than as a bare integer, so that
|
|
338
|
+
// SortPairs is a function of this file alone. With a bare integer it is the
|
|
339
|
+
// same function for every type whose key has the same width, and the link
|
|
340
|
+
// keeps one, so SFloat would launch the kernels of the UInt32 module.
|
|
341
|
+
template <typename I> struct position { I value; };
|
|
342
|
+
|
|
332
343
|
// perm[i] is the position the i-th smallest element sat at, and the index
|
|
333
344
|
// array holds the number to answer for that position.
|
|
334
345
|
template <int NDIM, typename I>
|
|
@@ -373,13 +384,13 @@ void sort_index_rows(cumo_na_iarray_t* a, cumo_na_indexer_t* indexer, cumo_na_ia
|
|
|
373
384
|
key_t* kout = (key_t*)cumo_cuda_runtime_malloc(sizeof(key_t) * total);
|
|
374
385
|
float_key_kernel<T><<<grid_dim, block_dim, 0, cumo_cuda_stream()>>>(data, kin, total);
|
|
375
386
|
cumo_check_launch_holding(kin, kout, pin, pout, gathered);
|
|
376
|
-
cumo_check_status_holding(sort_pairs(kin, kout, pin, pout, total, n_rows, row_len),
|
|
387
|
+
cumo_check_status_holding(sort_pairs(kin, kout, (const position<I>*)pin, (position<I>*)pout, total, n_rows, row_len),
|
|
377
388
|
kin, kout, pin, pout, gathered);
|
|
378
389
|
cumo_cuda_runtime_free((char*)kout);
|
|
379
390
|
cumo_cuda_runtime_free((char*)kin);
|
|
380
391
|
} else {
|
|
381
392
|
T* kout = (T*)cumo_cuda_runtime_malloc(sizeof(T) * total);
|
|
382
|
-
cumo_check_status_holding(sort_pairs(data, kout, pin, pout, total, n_rows, row_len),
|
|
393
|
+
cumo_check_status_holding(sort_pairs(data, kout, (const position<I>*)pin, (position<I>*)pout, total, n_rows, row_len),
|
|
383
394
|
kout, pin, pout, gathered);
|
|
384
395
|
cumo_cuda_runtime_free((char*)kout);
|
|
385
396
|
}
|
|
@@ -396,7 +407,7 @@ void sort_index_rows(cumo_na_iarray_t* a, cumo_na_indexer_t* indexer, cumo_na_ia
|
|
|
396
407
|
|
|
397
408
|
} // namespace
|
|
398
409
|
|
|
399
|
-
// float_key is only defined for the
|
|
410
|
+
// float_key is only defined for the float types, so the integer entry
|
|
400
411
|
// points must not instantiate it; the bool picks the branch at compile time.
|
|
401
412
|
#define CUMO_DEF_SORT(name, type, is_float) \
|
|
402
413
|
extern "C" void cumo_##name##_sort_kernel_launch( \
|
|
@@ -420,15 +431,4 @@ void sort_index_rows(cumo_na_iarray_t* a, cumo_na_indexer_t* indexer, cumo_na_ia
|
|
|
420
431
|
} \
|
|
421
432
|
}
|
|
422
433
|
|
|
423
|
-
|
|
424
|
-
CUMO_DEF_SORT(int16, int16_t, false)
|
|
425
|
-
CUMO_DEF_SORT(int32, int32_t, false)
|
|
426
|
-
CUMO_DEF_SORT(int64, int64_t, false)
|
|
427
|
-
CUMO_DEF_SORT(uint8, u_int8_t, false)
|
|
428
|
-
CUMO_DEF_SORT(uint16, u_int16_t, false)
|
|
429
|
-
CUMO_DEF_SORT(uint32, u_int32_t, false)
|
|
430
|
-
CUMO_DEF_SORT(uint64, u_int64_t, false)
|
|
431
|
-
CUMO_DEF_SORT(hfloat, cumo_half, true)
|
|
432
|
-
CUMO_DEF_SORT(bfloat, cumo_bfloat, true)
|
|
433
|
-
CUMO_DEF_SORT(sfloat, float, true)
|
|
434
|
-
CUMO_DEF_SORT(dfloat, double, true)
|
|
434
|
+
#endif /* ifndef CUMO_SORT_KERNEL_H */
|
|
@@ -186,6 +186,8 @@ void cumo_cuda_runtime_check_kernel_launch(void);
|
|
|
186
186
|
// The stream every launch and copy goes to. It is 0 until Stream#with says
|
|
187
187
|
// otherwise, and thread local, so one thread's choice is not another's.
|
|
188
188
|
struct CUstream_st* cumo_cuda_stream(void);
|
|
189
|
+
// Call before any CUB or Thrust algorithm. Defined in cuda/cub.cu, which says why.
|
|
190
|
+
void cumo_cuda_cub_prime_ptx_version(void);
|
|
189
191
|
|
|
190
192
|
// The forms to call while scratch is held, which free what they are given
|
|
191
193
|
// before they raise. Pass every buffer that is still outstanding, including the
|
data/ext/cumo/narray/data.c
CHANGED
|
@@ -158,6 +158,9 @@ cumo_na_swap_byte(VALUE self)
|
|
|
158
158
|
CUMO_STRIDE_LOOP|CUMO_NDF_INDEXER_LOOP|CUMO_NDF_ACCEPT_BYTESWAP,
|
|
159
159
|
1, 1, ain, aout };
|
|
160
160
|
|
|
161
|
+
if (rb_obj_is_kind_of(self, cumo_cRObject)) {
|
|
162
|
+
rb_raise(rb_eTypeError, "cannot swap bytes of %s", rb_obj_classname(self));
|
|
163
|
+
}
|
|
161
164
|
// Cumo::Bit's element is one bit, so swapping the bytes of an element
|
|
162
165
|
// changes nothing, and a loop stepping by the element stride would walk
|
|
163
166
|
// one byte per bit, eight times past the end of the packed buffer. Only
|
|
@@ -41,14 +41,14 @@ erb_dir.unshift("tmpl_bit") if (type_name == "bit")
|
|
|
41
41
|
erb_dir.map! { |d| File.join(thisdir, d) }
|
|
42
42
|
|
|
43
43
|
TEMPLATE_KERNEL_PARTS = {
|
|
44
|
-
"accum" => %w[reduce reduce_nan],
|
|
45
|
-
"accum_index" => %w[reduce reduce_nan],
|
|
46
|
-
"accum_arg" => %w[reduce reduce_nan],
|
|
47
|
-
"accum_binary" => %w[reduce reduce_nan reduce_from],
|
|
48
|
-
"cum" => %w[
|
|
49
|
-
"layer_norm" => %w[
|
|
50
|
-
"rms_norm" => %w[
|
|
51
|
-
"softmax" => %w[
|
|
44
|
+
"accum" => %w[reduce reduce_rare reduce_nan],
|
|
45
|
+
"accum_index" => %w[reduce reduce_rare reduce_nan],
|
|
46
|
+
"accum_arg" => %w[reduce reduce_rare reduce_nan],
|
|
47
|
+
"accum_binary" => %w[reduce reduce_rare reduce_nan reduce_from],
|
|
48
|
+
"cum" => %w[reduce_rare],
|
|
49
|
+
"layer_norm" => %w[reduce_rare],
|
|
50
|
+
"rms_norm" => %w[reduce_rare],
|
|
51
|
+
"softmax" => %w[reduce_rare],
|
|
52
52
|
"bit_count" => %w[reduce],
|
|
53
53
|
"bit_reduce" => %w[reduce],
|
|
54
54
|
"bit_stat" => %w[reduce],
|
|
@@ -59,10 +59,14 @@ TEMPLATE_KERNEL_PARTS = {
|
|
|
59
59
|
"poly" => %w[misc],
|
|
60
60
|
"quantize_symmetric" => %w[misc],
|
|
61
61
|
"unary_ret2" => %w[misc],
|
|
62
|
+
"sort" => %w[sort],
|
|
62
63
|
}.freeze
|
|
63
64
|
|
|
64
65
|
MATH_TEMPLATES = %w[unary_s binary_s ternary_s frexp].freeze
|
|
65
66
|
COMMON_MATH = %w[sqrt log log2 log10 exp exp2 sin cos tan tanh erf gelu gelu_tanh silu sigmoid softplus].freeze
|
|
67
|
+
# mulsum is here for dot of two vectors.
|
|
68
|
+
COMMON_REDUCE = %w[sum mean max min mulsum].freeze
|
|
69
|
+
RARE_REDUCE = %w[prod ptp minmax var stddev rms abs_sum abs_max abs_min kahan_sum min_index max_index argmin argmax].freeze
|
|
66
70
|
|
|
67
71
|
abort "unknown kernel part: #{$kernel_part}" unless KERNEL_PARTS.include?($kernel_part)
|
|
68
72
|
undeclared_math = COMMON_MATH - File.read(File.join(thisdir, "spec.rb")).scan(/^\s*math "(\w+)"/).flatten
|
|
@@ -83,8 +87,13 @@ class ErbPP
|
|
|
83
87
|
@children.select { |c| c.kernel_parts.include?($kernel_part) }
|
|
84
88
|
end
|
|
85
89
|
|
|
86
|
-
def kernel_part?(nan: false, from: nil)
|
|
87
|
-
$kernel_part ==
|
|
90
|
+
def kernel_part?(op = nil, nan: false, from: nil)
|
|
91
|
+
return $kernel_part == "reduce_from" if from
|
|
92
|
+
return $kernel_part == "reduce_nan" if nan
|
|
93
|
+
return $kernel_part == "reduce" if COMMON_REDUCE.include?(op)
|
|
94
|
+
return $kernel_part == "reduce_rare" if RARE_REDUCE.include?(op)
|
|
95
|
+
|
|
96
|
+
raise ArgumentError, "#{op.inspect} is in neither COMMON_REDUCE nor RARE_REDUCE"
|
|
88
97
|
end
|
|
89
98
|
|
|
90
99
|
def indexer_dims(narrow = false)
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
KERNEL_PARTS = %w[main reduce reduce_nan reduce_from math math_rare compare cast misc].freeze
|
|
3
|
+
KERNEL_PARTS = %w[main reduce reduce_nan reduce_from reduce_rare math math_rare compare cast misc sort].freeze
|
|
4
4
|
MATH_TYPES = %w[hfloat bfloat sfloat dfloat scomplex dcomplex].freeze
|
|
5
|
+
SORT_TYPES = %w[int8 int16 int32 int64 uint8 uint16 uint32 uint64 hfloat bfloat sfloat dfloat].freeze
|
|
5
6
|
|
|
6
7
|
def kernel_parts_of(type_name)
|
|
7
|
-
return
|
|
8
|
+
return %w[main reduce reduce_nan reduce_from] if type_name == "robject"
|
|
8
9
|
|
|
9
10
|
KERNEL_PARTS.reject do |part|
|
|
10
11
|
(%w[math math_rare].include?(part) && !MATH_TYPES.include?(type_name)) ||
|
|
11
|
-
(%w[compare misc].include?(part) && type_name == "bit")
|
|
12
|
+
(%w[compare misc reduce_rare].include?(part) && type_name == "bit") ||
|
|
13
|
+
(part == "sort" && !SORT_TYPES.include?(type_name))
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
|
data/ext/cumo/narray/gen/spec.rb
CHANGED
|
@@ -100,8 +100,12 @@ end
|
|
|
100
100
|
|
|
101
101
|
if is_object
|
|
102
102
|
undef_singleton_method "from_binary"
|
|
103
|
+
undef_singleton_method "from_string"
|
|
104
|
+
undef_method "store_binary"
|
|
103
105
|
undef_method "to_binary"
|
|
106
|
+
undef_method "to_string"
|
|
104
107
|
undef_method "swap_byte"
|
|
108
|
+
undef_method "hton"
|
|
105
109
|
undef_method "to_network"
|
|
106
110
|
undef_method "to_vacs"
|
|
107
111
|
undef_method "to_host"
|
|
@@ -119,7 +119,7 @@ extern "C" {
|
|
|
119
119
|
#endif
|
|
120
120
|
#endif
|
|
121
121
|
|
|
122
|
-
<% if kernel_part? %>
|
|
122
|
+
<% if kernel_part?("argmin") %>
|
|
123
123
|
void cumo_<%=type_name%>_argmin_int<%=i%>_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
124
124
|
{
|
|
125
125
|
cumo_reduce_arg_split<dtype, idx_t, cumo_<%=type_name%>_argmin_int<%=i%>_impl>(*arg, cumo_<%=type_name%>_argmin_int<%=i%>_impl{});
|
|
@@ -133,7 +133,7 @@ void cumo_<%=type_name%>_argmin_nan_int<%=i%>_kernel_launch(cumo_na_reduction_ar
|
|
|
133
133
|
}
|
|
134
134
|
<% end %>
|
|
135
135
|
|
|
136
|
-
<% if kernel_part? %>
|
|
136
|
+
<% if kernel_part?("argmax") %>
|
|
137
137
|
void cumo_<%=type_name%>_argmax_int<%=i%>_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
138
138
|
{
|
|
139
139
|
cumo_reduce_arg_split<dtype, idx_t, cumo_<%=type_name%>_argmax_int<%=i%>_impl>(*arg, cumo_<%=type_name%>_argmax_int<%=i%>_impl{});
|
|
@@ -63,7 +63,7 @@ extern "C" {
|
|
|
63
63
|
//<% (is_float ? ["","_nan"] : [""]).each do |nan| %>
|
|
64
64
|
//<% ([nil] + from_types).each do |from| %>
|
|
65
65
|
//<% sfx = from ? "_from_#{from[:id]}" : "" %>
|
|
66
|
-
//<% if kernel_part?(nan: nan == "_nan", from: from) %>
|
|
66
|
+
//<% if kernel_part?(name, nan: nan == "_nan", from: from) %>
|
|
67
67
|
void <%="cumo_#{type_name}_#{name}#{nan}#{sfx}_kernel_launch"%>(cumo_na_reduction_arg_t* arg, cumo_na_iarray_t* in2)
|
|
68
68
|
{
|
|
69
69
|
cumo_reduce_zip_split<dtype, <%= from ? from[:ctype] : "dtype" %>, dtype, <%="cumo_#{type_name}_#{name}#{nan}#{sfx}_impl"%>>(*arg, *in2, <%="cumo_#{type_name}_#{name}#{nan}#{sfx}_impl"%>{});
|
|
@@ -119,7 +119,7 @@ extern "C" {
|
|
|
119
119
|
#endif
|
|
120
120
|
#endif
|
|
121
121
|
|
|
122
|
-
<% if kernel_part? %>
|
|
122
|
+
<% if kernel_part?("min_index") %>
|
|
123
123
|
void cumo_<%=type_name%>_min_index_int<%=i%>_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
124
124
|
{
|
|
125
125
|
cumo_reduce_split<dtype, idx_t, cumo_<%=type_name%>_min_index_int<%=i%>_impl>(*arg, cumo_<%=type_name%>_min_index_int<%=i%>_impl{});
|
|
@@ -133,7 +133,7 @@ void cumo_<%=type_name%>_min_index_nan_int<%=i%>_kernel_launch(cumo_na_reduction
|
|
|
133
133
|
}
|
|
134
134
|
<% end %>
|
|
135
135
|
|
|
136
|
-
<% if kernel_part? %>
|
|
136
|
+
<% if kernel_part?("max_index") %>
|
|
137
137
|
void cumo_<%=type_name%>_max_index_int<%=i%>_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
138
138
|
{
|
|
139
139
|
cumo_reduce_split<dtype, idx_t, cumo_<%=type_name%>_max_index_int<%=i%>_impl>(*arg, cumo_<%=type_name%>_max_index_int<%=i%>_impl{});
|
|
@@ -215,33 +215,43 @@ extern "C" {
|
|
|
215
215
|
#endif
|
|
216
216
|
#endif
|
|
217
217
|
|
|
218
|
-
<% if kernel_part? %>
|
|
218
|
+
<% if kernel_part?("sum") %>
|
|
219
219
|
void cumo_<%=type_name%>_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
220
220
|
{
|
|
221
221
|
cumo_reduce_split<dtype, <%=dtype%>, cumo_<%=type_name%>_sum_impl>(*arg, cumo_<%=type_name%>_sum_impl{});
|
|
222
222
|
}
|
|
223
|
+
<% end %>
|
|
223
224
|
|
|
225
|
+
<% if kernel_part?("prod") %>
|
|
224
226
|
void cumo_<%=type_name%>_prod_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
225
227
|
{
|
|
226
228
|
cumo_reduce_split<dtype, <%=dtype%>, cumo_<%=type_name%>_prod_impl>(*arg, cumo_<%=type_name%>_prod_impl{});
|
|
227
229
|
}
|
|
230
|
+
<% end %>
|
|
228
231
|
|
|
232
|
+
<% if kernel_part?("mean") %>
|
|
229
233
|
void cumo_<%=type_name%>_mean_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
230
234
|
{
|
|
231
235
|
rtype n = (rtype)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
232
236
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_mean_impl>(*arg, cumo_<%=type_name%>_mean_impl{n});
|
|
233
237
|
}
|
|
238
|
+
<% end %>
|
|
234
239
|
|
|
240
|
+
<% if kernel_part?("var") %>
|
|
235
241
|
void cumo_<%=type_name%>_var_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
236
242
|
{
|
|
237
243
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_var_impl>(*arg, cumo_<%=type_name%>_var_impl{});
|
|
238
244
|
}
|
|
245
|
+
<% end %>
|
|
239
246
|
|
|
247
|
+
<% if kernel_part?("stddev") %>
|
|
240
248
|
void cumo_<%=type_name%>_stddev_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
241
249
|
{
|
|
242
250
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_stddev_impl>(*arg, cumo_<%=type_name%>_stddev_impl{});
|
|
243
251
|
}
|
|
252
|
+
<% end %>
|
|
244
253
|
|
|
254
|
+
<% if kernel_part?("rms") %>
|
|
245
255
|
void cumo_<%=type_name%>_rms_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
246
256
|
{
|
|
247
257
|
rtype n = (rtype)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
@@ -280,25 +290,29 @@ void cumo_<%=type_name%>_rms_nan_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
|
280
290
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_rms_nan_impl>(*arg, cumo_<%=type_name%>_rms_nan_impl{});
|
|
281
291
|
}
|
|
282
292
|
<% end %>
|
|
283
|
-
<% if kernel_part? %>
|
|
293
|
+
<% if kernel_part?("abs_sum") %>
|
|
284
294
|
void cumo_<%=type_name%>_abs_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
285
295
|
{
|
|
286
296
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_abs_sum_impl>(*arg, cumo_<%=type_name%>_abs_sum_impl{});
|
|
287
297
|
}
|
|
298
|
+
<% end %>
|
|
288
299
|
|
|
300
|
+
<% if kernel_part?("abs_max") %>
|
|
289
301
|
void cumo_<%=type_name%>_abs_max_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
290
302
|
{
|
|
291
303
|
using impl = cumo_<%=type_name%>_abs_extremum_of<cumo_<%=type_name%>_abs_extremum_rules::Max>;
|
|
292
304
|
cumo_reduce_split<dtype, rtype, impl>(*arg, impl{});
|
|
293
305
|
}
|
|
306
|
+
<% end %>
|
|
294
307
|
|
|
308
|
+
<% if kernel_part?("abs_min") %>
|
|
295
309
|
void cumo_<%=type_name%>_abs_min_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
296
310
|
{
|
|
297
311
|
using impl = cumo_<%=type_name%>_abs_extremum_of<cumo_<%=type_name%>_abs_extremum_rules::Min>;
|
|
298
312
|
cumo_reduce_split<dtype, rtype, impl>(*arg, impl{});
|
|
299
313
|
}
|
|
300
314
|
<% end %>
|
|
301
|
-
<% if is_double_precision && kernel_part? %>
|
|
315
|
+
<% if is_double_precision && kernel_part?("kahan_sum") %>
|
|
302
316
|
|
|
303
317
|
void cumo_<%=type_name%>_kahan_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
304
318
|
{
|
|
@@ -162,6 +162,7 @@ struct <%="cumo_thrust_#{name}#{j}"%>
|
|
|
162
162
|
template<typename Iterator1, typename Iterator2>
|
|
163
163
|
static cudaError_t <%="cumo_#{type_name}_#{name}#{j}_scan_by_key"%>(Iterator1 first, Iterator1 last, Iterator2 result, uint64_t row_len)
|
|
164
164
|
{
|
|
165
|
+
cumo_cuda_cub_prime_ptx_version();
|
|
165
166
|
cumo_thrust_pool_allocator alloc;
|
|
166
167
|
<%="cumo_thrust_#{name}_row"%> row = {row_len};
|
|
167
168
|
auto keys = thrust::make_transform_iterator(thrust::make_counting_iterator<uint64_t>(0), row);
|
|
@@ -190,6 +191,7 @@ static cudaError_t <%="cumo_#{type_name}_#{name}#{j}_scan_by_key"%>(Iterator1 fi
|
|
|
190
191
|
template<typename Iterator1, typename Iterator2>
|
|
191
192
|
static cudaError_t <%="cumo_#{type_name}_#{name}#{j}_scan"%>(Iterator1 first, Iterator1 last, Iterator2 result)
|
|
192
193
|
{
|
|
194
|
+
cumo_cuda_cub_prime_ptx_version();
|
|
193
195
|
cumo_thrust_pool_allocator alloc;
|
|
194
196
|
try {
|
|
195
197
|
<% if widen %>
|
|
@@ -181,23 +181,29 @@ extern "C" {
|
|
|
181
181
|
#endif
|
|
182
182
|
#endif
|
|
183
183
|
|
|
184
|
-
<% if kernel_part? %>
|
|
184
|
+
<% if kernel_part?("mean") %>
|
|
185
185
|
void cumo_<%=type_name%>_mean_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
186
186
|
{
|
|
187
187
|
<%=acc%> n = (<%=acc%>)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
188
188
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_mean_impl>(*arg, cumo_<%=type_name%>_mean_impl{n});
|
|
189
189
|
}
|
|
190
|
+
<% end %>
|
|
190
191
|
|
|
192
|
+
<% if kernel_part?("var") %>
|
|
191
193
|
void cumo_<%=type_name%>_var_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
192
194
|
{
|
|
193
195
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_var_impl>(*arg, cumo_<%=type_name%>_var_impl{});
|
|
194
196
|
}
|
|
197
|
+
<% end %>
|
|
195
198
|
|
|
199
|
+
<% if kernel_part?("stddev") %>
|
|
196
200
|
void cumo_<%=type_name%>_stddev_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
197
201
|
{
|
|
198
202
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_stddev_impl>(*arg, cumo_<%=type_name%>_stddev_impl{});
|
|
199
203
|
}
|
|
204
|
+
<% end %>
|
|
200
205
|
|
|
206
|
+
<% if kernel_part?("rms") %>
|
|
201
207
|
void cumo_<%=type_name%>_rms_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
202
208
|
{
|
|
203
209
|
<%=acc%> n = (<%=acc%>)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
@@ -226,25 +232,31 @@ void cumo_<%=type_name%>_rms_nan_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
|
226
232
|
cumo_reduce_split<dtype, rtype, cumo_<%=type_name%>_rms_nan_impl>(*arg, cumo_<%=type_name%>_rms_nan_impl{});
|
|
227
233
|
}
|
|
228
234
|
<% end %>
|
|
229
|
-
<% if %w[sfloat dfloat].include?(type_name)
|
|
235
|
+
<% if %w[sfloat dfloat].include?(type_name) %>
|
|
236
|
+
<% if kernel_part?("abs_sum") %>
|
|
230
237
|
void cumo_<%=type_name%>_abs_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
231
238
|
{
|
|
232
239
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_abs_sum_impl>(*arg, cumo_<%=type_name%>_abs_sum_impl{});
|
|
233
240
|
}
|
|
241
|
+
<% end %>
|
|
234
242
|
|
|
243
|
+
<% if kernel_part?("abs_max") %>
|
|
235
244
|
void cumo_<%=type_name%>_abs_max_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
236
245
|
{
|
|
237
246
|
using impl = cumo_<%=type_name%>_abs_extremum_of<cumo_<%=type_name%>_extremum_rules::Max>;
|
|
238
247
|
cumo_reduce_split<dtype, dtype, impl>(*arg, impl{});
|
|
239
248
|
}
|
|
249
|
+
<% end %>
|
|
240
250
|
|
|
251
|
+
<% if kernel_part?("abs_min") %>
|
|
241
252
|
void cumo_<%=type_name%>_abs_min_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
242
253
|
{
|
|
243
254
|
using impl = cumo_<%=type_name%>_abs_extremum_of<cumo_<%=type_name%>_extremum_rules::Min>;
|
|
244
255
|
cumo_reduce_split<dtype, dtype, impl>(*arg, impl{});
|
|
245
256
|
}
|
|
246
257
|
<% end %>
|
|
247
|
-
<%
|
|
258
|
+
<% end %>
|
|
259
|
+
<% if is_double_precision && kernel_part?("kahan_sum") %>
|
|
248
260
|
|
|
249
261
|
void cumo_<%=type_name%>_kahan_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
250
262
|
{
|
|
@@ -198,54 +198,72 @@ extern "C" {
|
|
|
198
198
|
#endif
|
|
199
199
|
#endif
|
|
200
200
|
|
|
201
|
-
<% if kernel_part? %>
|
|
201
|
+
<% if kernel_part?("sum") %>
|
|
202
202
|
void cumo_<%=type_name%>_sum_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
203
203
|
{
|
|
204
204
|
cumo_reduce_split<dtype, <%=dtype%>, cumo_<%=type_name%>_sum_impl>(*arg, cumo_<%=type_name%>_sum_impl{});
|
|
205
205
|
}
|
|
206
|
+
<% end %>
|
|
206
207
|
|
|
208
|
+
<% if kernel_part?("prod") %>
|
|
207
209
|
void cumo_<%=type_name%>_prod_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
208
210
|
{
|
|
209
211
|
cumo_reduce_split<dtype, <%=dtype%>, cumo_<%=type_name%>_prod_impl>(*arg, cumo_<%=type_name%>_prod_impl{});
|
|
210
212
|
}
|
|
213
|
+
<% end %>
|
|
211
214
|
|
|
215
|
+
<% if kernel_part?("min") %>
|
|
212
216
|
void cumo_<%=type_name%>_min_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
213
217
|
{
|
|
214
218
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_min_impl>(*arg, cumo_<%=type_name%>_min_impl{});
|
|
215
219
|
}
|
|
220
|
+
<% end %>
|
|
216
221
|
|
|
222
|
+
<% if kernel_part?("max") %>
|
|
217
223
|
void cumo_<%=type_name%>_max_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
218
224
|
{
|
|
219
225
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_max_impl>(*arg, cumo_<%=type_name%>_max_impl{});
|
|
220
226
|
}
|
|
227
|
+
<% end %>
|
|
221
228
|
|
|
229
|
+
<% if kernel_part?("ptp") %>
|
|
222
230
|
void cumo_<%=type_name%>_ptp_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
223
231
|
{
|
|
224
232
|
cumo_reduce_split<dtype, dtype, cumo_<%=type_name%>_ptp_impl>(*arg, cumo_<%=type_name%>_ptp_impl{});
|
|
225
233
|
}
|
|
234
|
+
<% end %>
|
|
226
235
|
|
|
236
|
+
<% if kernel_part?("minmax") %>
|
|
227
237
|
void cumo_<%=type_name%>_minmax_kernel_launch(cumo_na_reduction_arg_t* arg, cumo_na_iarray_t* out2)
|
|
228
238
|
{
|
|
229
239
|
cumo_reduce_pair_split<dtype, dtype, cumo_<%=type_name%>_minmax_impl>(*arg, *out2, cumo_<%=type_name%>_minmax_impl{});
|
|
230
240
|
}
|
|
241
|
+
<% end %>
|
|
231
242
|
<% unless is_float %>
|
|
232
243
|
|
|
244
|
+
<% if kernel_part?("mean") %>
|
|
233
245
|
void cumo_<%=type_name%>_mean_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
234
246
|
{
|
|
235
247
|
double n = (double)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
236
248
|
cumo_reduce_split<dtype, double, cumo_<%=type_name%>_mean_impl>(*arg, cumo_<%=type_name%>_mean_impl{n});
|
|
237
249
|
}
|
|
250
|
+
<% end %>
|
|
238
251
|
|
|
252
|
+
<% if kernel_part?("var") %>
|
|
239
253
|
void cumo_<%=type_name%>_var_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
240
254
|
{
|
|
241
255
|
cumo_reduce_split<dtype, double, cumo_<%=type_name%>_var_impl>(*arg, cumo_<%=type_name%>_var_impl{});
|
|
242
256
|
}
|
|
257
|
+
<% end %>
|
|
243
258
|
|
|
259
|
+
<% if kernel_part?("stddev") %>
|
|
244
260
|
void cumo_<%=type_name%>_stddev_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
245
261
|
{
|
|
246
262
|
cumo_reduce_split<dtype, double, cumo_<%=type_name%>_stddev_impl>(*arg, cumo_<%=type_name%>_stddev_impl{});
|
|
247
263
|
}
|
|
264
|
+
<% end %>
|
|
248
265
|
|
|
266
|
+
<% if kernel_part?("rms") %>
|
|
249
267
|
void cumo_<%=type_name%>_rms_kernel_launch(cumo_na_reduction_arg_t* arg)
|
|
250
268
|
{
|
|
251
269
|
double n = (double)(arg->in_indexer.total_size / arg->out_indexer.total_size);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#if defined(__cplusplus)
|
|
2
|
+
#if 0
|
|
3
|
+
{ /* satisfy cc-mode */
|
|
4
|
+
#endif
|
|
5
|
+
} /* extern "C" { */
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include "cumo/sort_kernel.h"
|
|
9
|
+
|
|
10
|
+
// sort_index and median sort with the same kernels, so their entry points are
|
|
11
|
+
// made here too.
|
|
12
|
+
CUMO_DEF_SORT(<%=type_name%>, dtype, <%=is_float%>)
|
|
13
|
+
|
|
14
|
+
#if defined(__cplusplus)
|
|
15
|
+
extern "C" {
|
|
16
|
+
#if 0
|
|
17
|
+
} /* satisfy cc-mode */
|
|
18
|
+
#endif
|
|
19
|
+
#endif
|
data/ext/cumo/narray/index.c
CHANGED
|
@@ -68,7 +68,7 @@ static void
|
|
|
68
68
|
cumo_na_index_set_step(cumo_na_index_arg_t *q, int i, size_t n, size_t beg, ssize_t step)
|
|
69
69
|
{
|
|
70
70
|
q->n = n;
|
|
71
|
-
q->beg = beg;
|
|
71
|
+
q->beg = n == 0 ? 0 : beg;
|
|
72
72
|
q->step = step;
|
|
73
73
|
q->idx = NULL;
|
|
74
74
|
q->reduce = 0;
|
|
@@ -178,6 +178,11 @@ cumo_na_parse_array(VALUE ary, int orig_dim, ssize_t size, cumo_na_index_arg_t *
|
|
|
178
178
|
cudaError_t status;
|
|
179
179
|
int n = RARRAY_LEN(ary);
|
|
180
180
|
|
|
181
|
+
if (n == 0) {
|
|
182
|
+
cumo_na_index_set_step(q, orig_dim, 0, 0, 1);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
|
|
181
186
|
// A step names the one element a one-element subscript does, without a
|
|
182
187
|
// device allocation, a kernel to fill it, or the synchronize a loop pays
|
|
183
188
|
// to read that one entry back. at() is left out: it gathers through an
|
|
@@ -250,10 +255,16 @@ cumo_na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, cumo_na_index_ar
|
|
|
250
255
|
if (CUMO_NA_SIZE(na) != (size_t)size) {
|
|
251
256
|
rb_raise(rb_eIndexError, "Bit-NArray size mismatch");
|
|
252
257
|
}
|
|
253
|
-
|
|
254
|
-
|
|
258
|
+
if (size > 0) {
|
|
259
|
+
a = rb_funcall(a, cumo_id_where, 0);
|
|
260
|
+
CumoGetNArray(a,na);
|
|
261
|
+
}
|
|
255
262
|
}
|
|
256
263
|
n = CUMO_NA_SIZE(na);
|
|
264
|
+
if (n == 0) {
|
|
265
|
+
cumo_na_index_set_step(q, orig_dim, 0, 0, 1);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
257
268
|
idx = cumo_na_new(cIndex,1,&n);
|
|
258
269
|
cumo_na_store(idx,a);
|
|
259
270
|
|
|
@@ -301,6 +312,28 @@ cumo_na_parse_narray_index(VALUE a, int orig_dim, ssize_t size, cumo_na_index_ar
|
|
|
301
312
|
q->orig_dim = orig_dim;
|
|
302
313
|
}
|
|
303
314
|
|
|
315
|
+
static ssize_t
|
|
316
|
+
cumo_na_range_count(ssize_t beg, ssize_t end, int excl, ssize_t step, ssize_t size)
|
|
317
|
+
{
|
|
318
|
+
ssize_t last;
|
|
319
|
+
|
|
320
|
+
if (step > 0) {
|
|
321
|
+
if (excl ? end <= beg : end < beg) {
|
|
322
|
+
return (beg < 0 || beg > size || end < -1 || end > size) ? -1 : 0;
|
|
323
|
+
}
|
|
324
|
+
last = excl ? end - 1 : end;
|
|
325
|
+
} else {
|
|
326
|
+
if (excl ? end >= beg : end > beg) {
|
|
327
|
+
return (beg < -1 || beg >= size || end < -1 || end > size) ? -1 : 0;
|
|
328
|
+
}
|
|
329
|
+
last = excl ? end + 1 : end;
|
|
330
|
+
}
|
|
331
|
+
if (beg < 0 || beg >= size || last < 0 || last >= size) {
|
|
332
|
+
return -1;
|
|
333
|
+
}
|
|
334
|
+
return (last - beg) / step + 1;
|
|
335
|
+
}
|
|
336
|
+
|
|
304
337
|
static void
|
|
305
338
|
cumo_na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, cumo_na_index_arg_t *q)
|
|
306
339
|
{
|
|
@@ -309,8 +342,8 @@ cumo_na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, cumo_
|
|
|
309
342
|
// caught that: a truncated count came out negative up to 2**32 and was
|
|
310
343
|
// rounded to an empty view, and past that it came out positive and wrong.
|
|
311
344
|
ssize_t n;
|
|
312
|
-
ssize_t beg, end
|
|
313
|
-
|
|
345
|
+
ssize_t beg, end;
|
|
346
|
+
int excl;
|
|
314
347
|
|
|
315
348
|
#ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
|
|
316
349
|
rb_arithmetic_sequence_components_t x;
|
|
@@ -323,61 +356,34 @@ cumo_na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, cumo_
|
|
|
323
356
|
rb_raise(rb_eArgError, "step must not be zero");
|
|
324
357
|
}
|
|
325
358
|
|
|
326
|
-
beg =
|
|
327
|
-
if (beg < 0) {
|
|
328
|
-
beg += size;
|
|
329
|
-
}
|
|
359
|
+
beg = NUM2SSIZET(x.begin);
|
|
330
360
|
if (T_NIL == TYPE(x.end)) { // endless range
|
|
331
|
-
end = size - 1;
|
|
332
|
-
|
|
333
|
-
dot = edot;
|
|
334
|
-
}
|
|
335
|
-
if (beg < 0 || beg >= size) {
|
|
336
|
-
rb_raise(rb_eRangeError,
|
|
337
|
-
"%"SZF"d%s is out of range for size=%"SZF"d",
|
|
338
|
-
beg_orig, dot, size);
|
|
339
|
-
}
|
|
361
|
+
end = step > 0 ? size - 1 : 0;
|
|
362
|
+
excl = 0;
|
|
340
363
|
} else {
|
|
341
|
-
end =
|
|
364
|
+
end = NUM2SSIZET(x.end);
|
|
342
365
|
if (end < 0) {
|
|
343
366
|
end += size;
|
|
344
367
|
}
|
|
345
|
-
|
|
346
|
-
end--;
|
|
347
|
-
dot = edot;
|
|
348
|
-
}
|
|
349
|
-
if (beg < 0 || beg >= size || end < 0 || end >= size) {
|
|
350
|
-
rb_raise(rb_eRangeError,
|
|
351
|
-
"%"SZF"d%s%"SZF"d is out of range for size=%"SZF"d",
|
|
352
|
-
beg_orig, dot, end_orig, size);
|
|
353
|
-
}
|
|
368
|
+
excl = RTEST(x.exclude_end);
|
|
354
369
|
}
|
|
355
370
|
#else
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
beg = beg_orig = NUM2SSIZET(rb_funcall(range,cumo_id_beg,0));
|
|
359
|
-
if (beg < 0) {
|
|
360
|
-
beg += size;
|
|
361
|
-
}
|
|
362
|
-
end = end_orig = NUM2SSIZET(rb_funcall(range,cumo_id_end,0));
|
|
371
|
+
beg = NUM2SSIZET(rb_funcall(range,cumo_id_beg,0));
|
|
372
|
+
end = NUM2SSIZET(rb_funcall(range,cumo_id_end,0));
|
|
363
373
|
if (end < 0) {
|
|
364
374
|
end += size;
|
|
365
375
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
376
|
+
excl = RTEST(rb_funcall(range,cumo_id_exclude_end,0));
|
|
377
|
+
#endif
|
|
378
|
+
if (beg < 0) {
|
|
379
|
+
beg += size;
|
|
370
380
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
381
|
+
n = cumo_na_range_count(beg, end, excl, step, size);
|
|
382
|
+
if (n < 0) {
|
|
383
|
+
rb_raise(rb_eRangeError, "%"PRIsVALUE" is out of range for size=%"SZF"d",
|
|
384
|
+
rb_inspect(range), size);
|
|
375
385
|
}
|
|
376
|
-
#endif
|
|
377
|
-
n = (end-beg)/step+1;
|
|
378
|
-
if (n<0) n=0;
|
|
379
386
|
cumo_na_index_set_step(q,orig_dim,n,beg,step);
|
|
380
|
-
|
|
381
387
|
}
|
|
382
388
|
|
|
383
389
|
void
|
|
@@ -622,6 +628,9 @@ cumo_na_index_aref_nadata(cumo_narray_data_t *na1, cumo_narray_view_t *na2,
|
|
|
622
628
|
j++;
|
|
623
629
|
total *= size;
|
|
624
630
|
}
|
|
631
|
+
if (total == 0) {
|
|
632
|
+
na2->offset = 0;
|
|
633
|
+
}
|
|
625
634
|
cumo_na_set_newaxis_strides(na2, newaxis, n_newaxis, j, elmsz);
|
|
626
635
|
na2->base.size = total;
|
|
627
636
|
}
|
|
@@ -696,10 +705,12 @@ cumo_na_index_aref_naview(cumo_narray_view_t *na1, cumo_narray_view_t *na2,
|
|
|
696
705
|
size_t last;
|
|
697
706
|
stride1 = -stride1;
|
|
698
707
|
last = na1->base.shape[q[i].orig_dim] - 1;
|
|
699
|
-
if (
|
|
700
|
-
|
|
708
|
+
if (na1->base.size > 0) {
|
|
709
|
+
if (na2->offset < last * stride1) {
|
|
710
|
+
rb_raise(rb_eStandardError,"bug: negative offset");
|
|
711
|
+
}
|
|
712
|
+
na2->offset -= last * stride1;
|
|
701
713
|
}
|
|
702
|
-
na2->offset -= last * stride1;
|
|
703
714
|
cumo_na_index_aref_naview_index_stride_last_kernel_launch(index, stride1, last, size);
|
|
704
715
|
} else {
|
|
705
716
|
cumo_na_index_aref_naview_index_stride_kernel_launch(index, stride1, size);
|
|
@@ -727,10 +738,27 @@ cumo_na_index_aref_naview(cumo_narray_view_t *na1, cumo_narray_view_t *na2,
|
|
|
727
738
|
j++;
|
|
728
739
|
total *= size;
|
|
729
740
|
}
|
|
741
|
+
if (total == 0) {
|
|
742
|
+
na2->offset = na1->offset;
|
|
743
|
+
}
|
|
730
744
|
cumo_na_set_newaxis_strides(na2, newaxis, n_newaxis, j, elmsz);
|
|
731
745
|
na2->base.size = total;
|
|
732
746
|
}
|
|
733
747
|
|
|
748
|
+
static size_t
|
|
749
|
+
cumo_na_index_at_size(const cumo_na_index_arg_t *q, int ndim)
|
|
750
|
+
{
|
|
751
|
+
int i;
|
|
752
|
+
size_t size = q[ndim-1].n;
|
|
753
|
+
|
|
754
|
+
for (i=0; i<ndim-1; i++) {
|
|
755
|
+
if (q[i].n != size) {
|
|
756
|
+
rb_raise(cumo_na_eShapeError, "index array sizes mismatch");
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
return size;
|
|
760
|
+
}
|
|
761
|
+
|
|
734
762
|
void cumo_na_index_at_nadata_index_stride_add_kernel_launch(size_t *idx, size_t *idx1, ssize_t s1, uint64_t n);
|
|
735
763
|
void cumo_na_index_at_nadata_index_beg_step_stride_kernel_launch(size_t *idx, size_t beg, ssize_t step, ssize_t s1, uint64_t n);
|
|
736
764
|
void cumo_na_index_at_nadata_index_beg_step_stride_add_kernel_launch(size_t *idx, size_t beg, ssize_t step, ssize_t s1, uint64_t n);
|
|
@@ -740,7 +768,7 @@ cumo_na_index_at_nadata(cumo_narray_data_t *na1, cumo_narray_view_t *na2,
|
|
|
740
768
|
cumo_na_index_arg_t *q, ssize_t elmsz, int ndim, int keep_dim)
|
|
741
769
|
{
|
|
742
770
|
int i;
|
|
743
|
-
size_t size =
|
|
771
|
+
size_t size = na2->base.size;
|
|
744
772
|
ssize_t stride1;
|
|
745
773
|
ssize_t *strides_na1;
|
|
746
774
|
size_t *index;
|
|
@@ -759,15 +787,6 @@ cumo_na_index_at_nadata(cumo_narray_data_t *na1, cumo_narray_view_t *na2,
|
|
|
759
787
|
|
|
760
788
|
for (i=ndim-1; i>=0; i--) {
|
|
761
789
|
stride1 = strides_na1[q[i].orig_dim];
|
|
762
|
-
if (i==ndim-1) {
|
|
763
|
-
if (size == 0) {
|
|
764
|
-
rb_raise(cumo_na_eShapeError, "cannot get element of empty array");
|
|
765
|
-
}
|
|
766
|
-
} else {
|
|
767
|
-
if (size != q[i].n) {
|
|
768
|
-
rb_raise(cumo_na_eShapeError, "index array sizes mismatch");
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
790
|
|
|
772
791
|
if (q[i].idx != NULL) {
|
|
773
792
|
if (i==ndim-1) {
|
|
@@ -787,8 +806,6 @@ cumo_na_index_at_nadata(cumo_narray_data_t *na1, cumo_narray_view_t *na2,
|
|
|
787
806
|
}
|
|
788
807
|
|
|
789
808
|
}
|
|
790
|
-
na2->base.size = size;
|
|
791
|
-
na2->base.shape[0] = size;
|
|
792
809
|
}
|
|
793
810
|
|
|
794
811
|
void cumo_na_index_at_naview_index_index_index_add_kernel_launch(size_t *idx, size_t *idx1, size_t *idx2, uint64_t n);
|
|
@@ -801,7 +818,7 @@ cumo_na_index_at_naview(cumo_narray_view_t *na1, cumo_narray_view_t *na2,
|
|
|
801
818
|
{
|
|
802
819
|
int i;
|
|
803
820
|
size_t *index;
|
|
804
|
-
size_t size =
|
|
821
|
+
size_t size = na2->base.size;
|
|
805
822
|
|
|
806
823
|
if (q[ndim-1].idx != NULL) {
|
|
807
824
|
index = q[ndim-1].idx;
|
|
@@ -813,15 +830,6 @@ cumo_na_index_at_naview(cumo_narray_view_t *na1, cumo_narray_view_t *na2,
|
|
|
813
830
|
|
|
814
831
|
for (i=ndim-1; i>=0; i--) {
|
|
815
832
|
cumo_stridx_t sdx1 = na1->stridx[q[i].orig_dim];
|
|
816
|
-
if (i==ndim-1) {
|
|
817
|
-
if (size == 0) {
|
|
818
|
-
rb_raise(cumo_na_eShapeError, "cannot get element of empty array");
|
|
819
|
-
}
|
|
820
|
-
} else {
|
|
821
|
-
if (size != q[i].n) {
|
|
822
|
-
rb_raise(cumo_na_eShapeError, "index array sizes mismatch");
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
833
|
|
|
826
834
|
if (q[i].idx != NULL && CUMO_SDX_IS_INDEX(sdx1)) {
|
|
827
835
|
// index <- index
|
|
@@ -899,8 +907,6 @@ cumo_na_index_at_naview(cumo_narray_view_t *na1, cumo_narray_view_t *na2,
|
|
|
899
907
|
}
|
|
900
908
|
}
|
|
901
909
|
}
|
|
902
|
-
na2->base.size = size;
|
|
903
|
-
na2->base.shape[0] = size;
|
|
904
910
|
}
|
|
905
911
|
|
|
906
912
|
static int
|
|
@@ -981,6 +987,13 @@ VALUE cumo_na_aref_md_protected(VALUE data_value)
|
|
|
981
987
|
|
|
982
988
|
elmsz = cumo_na_element_stride(self);
|
|
983
989
|
|
|
990
|
+
if (at_mode && ndim > 0) {
|
|
991
|
+
size_t size = cumo_na_index_at_size(q, ndim);
|
|
992
|
+
na2->base.size = size;
|
|
993
|
+
na2->base.shape[0] = size;
|
|
994
|
+
CUMO_SDX_SET_STRIDE(na2->stridx[0], elmsz);
|
|
995
|
+
}
|
|
996
|
+
|
|
984
997
|
switch(na1->type) {
|
|
985
998
|
case CUMO_NARRAY_DATA_T:
|
|
986
999
|
case CUMO_NARRAY_FILEMAP_T:
|
|
@@ -989,7 +1002,9 @@ VALUE cumo_na_aref_md_protected(VALUE data_value)
|
|
|
989
1002
|
na2->base.size = 1;
|
|
990
1003
|
} else {
|
|
991
1004
|
if (at_mode) {
|
|
992
|
-
|
|
1005
|
+
if (na2->base.size > 0) {
|
|
1006
|
+
cumo_na_index_at_nadata((cumo_narray_data_t *)na1,na2,q,elmsz,ndim,keep_dim);
|
|
1007
|
+
}
|
|
993
1008
|
} else {
|
|
994
1009
|
cumo_na_index_aref_nadata((cumo_narray_data_t *)na1,na2,q,elmsz,ndim,keep_dim);
|
|
995
1010
|
}
|
|
@@ -1005,7 +1020,9 @@ VALUE cumo_na_aref_md_protected(VALUE data_value)
|
|
|
1005
1020
|
na2->offset = ((cumo_narray_view_t *)na1)->offset;
|
|
1006
1021
|
na2->data = ((cumo_narray_view_t *)na1)->data;
|
|
1007
1022
|
if (at_mode) {
|
|
1008
|
-
|
|
1023
|
+
if (na2->base.size > 0) {
|
|
1024
|
+
cumo_na_index_at_naview((cumo_narray_view_t *)na1,na2,q,elmsz,ndim,keep_dim);
|
|
1025
|
+
}
|
|
1009
1026
|
} else {
|
|
1010
1027
|
cumo_na_index_aref_naview((cumo_narray_view_t *)na1,na2,q,elmsz,ndim,keep_dim);
|
|
1011
1028
|
}
|
|
@@ -1201,9 +1218,6 @@ cumo_na_get_result_dimension(VALUE self, int argc, VALUE *argv, ssize_t stride,
|
|
|
1201
1218
|
VALUE a;
|
|
1202
1219
|
|
|
1203
1220
|
CumoGetNArray(self,na);
|
|
1204
|
-
if (na->size == 0) {
|
|
1205
|
-
rb_raise(cumo_na_eShapeError, "cannot get element of empty array");
|
|
1206
|
-
}
|
|
1207
1221
|
idx = ALLOCA_N(ssize_t, argc);
|
|
1208
1222
|
for (i=j=0; i<argc; i++) {
|
|
1209
1223
|
a = argv[i];
|
|
@@ -1241,13 +1255,15 @@ cumo_na_get_result_dimension(VALUE self, int argc, VALUE *argv, ssize_t stride,
|
|
|
1241
1255
|
pos = nv->offset;
|
|
1242
1256
|
if (j == na->ndim) {
|
|
1243
1257
|
for (i=j-1; i>=0; i--) {
|
|
1244
|
-
|
|
1258
|
+
idx[i] = cumo_na_range_check(idx[i], na->shape[i], i);
|
|
1259
|
+
}
|
|
1260
|
+
for (i=j-1; i>=0; i--) {
|
|
1245
1261
|
sdx = nv->stridx[i];
|
|
1246
1262
|
if (CUMO_SDX_IS_INDEX(sdx)) {
|
|
1247
1263
|
cumo_na_index_wait_fill(nv);
|
|
1248
|
-
pos += CUMO_SDX_GET_INDEX(sdx)[
|
|
1264
|
+
pos += CUMO_SDX_GET_INDEX(sdx)[idx[i]];
|
|
1249
1265
|
} else {
|
|
1250
|
-
pos += CUMO_SDX_GET_STRIDE(sdx)*
|
|
1266
|
+
pos += CUMO_SDX_GET_STRIDE(sdx)*idx[i];
|
|
1251
1267
|
}
|
|
1252
1268
|
}
|
|
1253
1269
|
*pos_idx = pos;
|
data/ext/cumo/narray/narray.c
CHANGED
|
@@ -1820,6 +1820,9 @@ cumo_na_s_from_binary(int argc, VALUE *argv, VALUE type)
|
|
|
1820
1820
|
VALUE vstr, vshape, vna;
|
|
1821
1821
|
VALUE velmsz;
|
|
1822
1822
|
|
|
1823
|
+
if (RTEST(rb_class_inherited_p(type, cumo_cRObject))) {
|
|
1824
|
+
rb_raise(rb_eTypeError, "cannot restore %s from binary data", rb_class2name(type));
|
|
1825
|
+
}
|
|
1823
1826
|
narg = rb_scan_args(argc,argv,"11",&vstr,&vshape);
|
|
1824
1827
|
Check_Type(vstr,T_STRING);
|
|
1825
1828
|
str_len = RSTRING_LEN(vstr);
|
|
@@ -1931,6 +1934,9 @@ cumo_na_store_binary(int argc, VALUE *argv, VALUE self)
|
|
|
1931
1934
|
VALUE velmsz;
|
|
1932
1935
|
cumo_narray_t *na;
|
|
1933
1936
|
|
|
1937
|
+
if (RTEST(rb_obj_is_kind_of(self, cumo_cRObject))) {
|
|
1938
|
+
rb_raise(rb_eTypeError, "cannot store binary data to %s", rb_obj_classname(self));
|
|
1939
|
+
}
|
|
1934
1940
|
narg = rb_scan_args(argc,argv,"11",&vstr,&voffset);
|
|
1935
1941
|
Check_Type(vstr,T_STRING);
|
|
1936
1942
|
if (narg==2) {
|
|
@@ -2016,6 +2022,9 @@ cumo_na_to_binary(VALUE self)
|
|
|
2016
2022
|
VALUE str;
|
|
2017
2023
|
cumo_narray_t *na;
|
|
2018
2024
|
|
|
2025
|
+
if (RTEST(rb_obj_is_kind_of(self, cumo_cRObject))) {
|
|
2026
|
+
rb_raise(rb_eTypeError, "cannot convert %s into binary data", rb_obj_classname(self));
|
|
2027
|
+
}
|
|
2019
2028
|
CumoGetNArray(self,na);
|
|
2020
2029
|
if (na->type == CUMO_NARRAY_VIEW_T &&
|
|
2021
2030
|
!(cumo_na_view_offset_reaches_bytes(self) && cumo_na_check_contiguous(self)==Qtrue)) {
|
data/ext/cumo/narray/ndloop.c
CHANGED
|
@@ -53,6 +53,7 @@ typedef struct CUMO_NA_MD_LOOP {
|
|
|
53
53
|
// 3 for sum(), 1 for sum(axis: 1), 2 for sum(axis: [1,2])
|
|
54
54
|
int *trans_map;
|
|
55
55
|
size_t sub_narray_len; // elements the sub-narray of the current row reaches with, for loop_store_subnarray
|
|
56
|
+
VALUE sub_narray; // keeps the row's sub-narray, which may be a cast copy, visible to the GC until ndloop_release
|
|
56
57
|
VALUE vargs;
|
|
57
58
|
VALUE reduce; // dimension indicies to reduce in reduction kernel (in bits), e.g., for an array of shape:
|
|
58
59
|
// [2,3,4], 111b for sum(), 010b for sum(axis: 1), 110b for sum(axis: [1,2])
|
|
@@ -893,6 +894,7 @@ ndloop_set_output(cumo_ndfunc_t *nf, cumo_na_md_loop_t *lp, VALUE args)
|
|
|
893
894
|
}
|
|
894
895
|
LARG(lp,j).value = t;
|
|
895
896
|
LARG(lp,j).elmsz = sizeof(VALUE);
|
|
897
|
+
rb_ary_push(results, Qnil);
|
|
896
898
|
} else {
|
|
897
899
|
rb_raise(rb_eRuntimeError,"ndloop_set_output: invalid for type");
|
|
898
900
|
}
|
|
@@ -2546,6 +2548,7 @@ loop_store_subnarray(cumo_ndfunc_t *nf, cumo_na_md_loop_t *lp, int i0, size_t *c
|
|
|
2546
2548
|
if (rb_obj_class(a) != a_type) {
|
|
2547
2549
|
a = rb_funcall(a_type, cumo_id_cast, 1, a);
|
|
2548
2550
|
}
|
|
2551
|
+
lp->sub_narray = a;
|
|
2549
2552
|
CumoGetNArray(a,na);
|
|
2550
2553
|
if (na->ndim != nd-i0+1) {
|
|
2551
2554
|
rb_raise(cumo_na_eShapeError, "mismatched dimension of sub-narray: "
|
|
@@ -2602,6 +2605,7 @@ loop_store_subnarray(cumo_ndfunc_t *nf, cumo_na_md_loop_t *lp, int i0, size_t *c
|
|
|
2602
2605
|
}
|
|
2603
2606
|
}
|
|
2604
2607
|
loop_end:
|
|
2608
|
+
LARG(lp,1).value = Qnil;
|
|
2605
2609
|
LARG(lp,1).ptr = NULL;
|
|
2606
2610
|
LARG(lp,1).shape = saved_shape;
|
|
2607
2611
|
LARG(lp,1).elmsz = saved_elmsz;
|
data/ext/cumo/narray/step.c
CHANGED
|
@@ -271,8 +271,6 @@ cumo_na_step_sequence( VALUE obj, size_t *plen, double *pbeg, double *pstep )
|
|
|
271
271
|
void
|
|
272
272
|
Init_cumo_na_step()
|
|
273
273
|
{
|
|
274
|
-
rb_define_alias(rb_cRange, "%", "step");
|
|
275
|
-
|
|
276
274
|
cumo_id_beg = rb_intern("begin");
|
|
277
275
|
cumo_id_end = rb_intern("end");
|
|
278
276
|
cumo_id_len = rb_intern("length");
|
data/lib/cumo/version.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Cumo
|
|
4
|
-
VERSION = "0.
|
|
4
|
+
VERSION = "0.15.0"
|
|
5
5
|
|
|
6
6
|
spec = Gem.loaded_specs["cumo"] if defined?(Gem)
|
|
7
7
|
REVISION = (spec.metadata["cumo_revision"]&.dup&.freeze if spec && spec.full_gem_path == File.expand_path("../..", __dir__))
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cumo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Naotoshi Seo
|
|
@@ -38,6 +38,7 @@ files:
|
|
|
38
38
|
- Rakefile
|
|
39
39
|
- cumo.gemspec
|
|
40
40
|
- docs/src-tree.md
|
|
41
|
+
- ext/cumo/cuda/cub.cu
|
|
41
42
|
- ext/cumo/cuda/cublas.c
|
|
42
43
|
- ext/cumo/cuda/cudnn.c
|
|
43
44
|
- ext/cumo/cuda/cudnn_impl.cpp
|
|
@@ -78,6 +79,7 @@ files:
|
|
|
78
79
|
- ext/cumo/include/cumo/reduce_kernel.h
|
|
79
80
|
- ext/cumo/include/cumo/row_kernel.h
|
|
80
81
|
- ext/cumo/include/cumo/row_method.h
|
|
82
|
+
- ext/cumo/include/cumo/sort_kernel.h
|
|
81
83
|
- ext/cumo/include/cumo/template.h
|
|
82
84
|
- ext/cumo/include/cumo/template_kernel.h
|
|
83
85
|
- ext/cumo/include/cumo/types/bf16_def.h
|
|
@@ -271,6 +273,7 @@ files:
|
|
|
271
273
|
- ext/cumo/narray/gen/tmpl/softmax_kernel.cu
|
|
272
274
|
- ext/cumo/narray/gen/tmpl/sort.c
|
|
273
275
|
- ext/cumo/narray/gen/tmpl/sort_index.c
|
|
276
|
+
- ext/cumo/narray/gen/tmpl/sort_kernel.cu
|
|
274
277
|
- ext/cumo/narray/gen/tmpl/store.c
|
|
275
278
|
- ext/cumo/narray/gen/tmpl/store_array.c
|
|
276
279
|
- ext/cumo/narray/gen/tmpl/store_array_kernel.cu
|
|
@@ -334,7 +337,6 @@ files:
|
|
|
334
337
|
- ext/cumo/narray/ndloop.c
|
|
335
338
|
- ext/cumo/narray/ndloop_kernel.cu
|
|
336
339
|
- ext/cumo/narray/rand.c
|
|
337
|
-
- ext/cumo/narray/sort_kernel.cu
|
|
338
340
|
- ext/cumo/narray/step.c
|
|
339
341
|
- ext/cumo/narray/struct.c
|
|
340
342
|
- lib/cumo.rb
|
|
@@ -370,7 +372,7 @@ metadata:
|
|
|
370
372
|
changelog_uri: https://github.com/sonots/cumo/blob/master/CHANGELOG.md
|
|
371
373
|
bug_tracker_uri: https://github.com/sonots/cumo/issues
|
|
372
374
|
rubygems_mfa_required: 'true'
|
|
373
|
-
cumo_revision: v0.
|
|
375
|
+
cumo_revision: v0.15.0
|
|
374
376
|
rdoc_options: []
|
|
375
377
|
require_paths:
|
|
376
378
|
- lib
|