cumo 0.1.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 +7 -0
- data/.gitignore +27 -0
- data/.travis.yml +5 -0
- data/3rd_party/mkmf-cu/.gitignore +36 -0
- data/3rd_party/mkmf-cu/Gemfile +3 -0
- data/3rd_party/mkmf-cu/LICENSE +21 -0
- data/3rd_party/mkmf-cu/README.md +36 -0
- data/3rd_party/mkmf-cu/Rakefile +11 -0
- data/3rd_party/mkmf-cu/bin/mkmf-cu-nvcc +4 -0
- data/3rd_party/mkmf-cu/lib/mkmf-cu.rb +32 -0
- data/3rd_party/mkmf-cu/lib/mkmf-cu/cli.rb +80 -0
- data/3rd_party/mkmf-cu/lib/mkmf-cu/nvcc.rb +157 -0
- data/3rd_party/mkmf-cu/mkmf-cu.gemspec +16 -0
- data/3rd_party/mkmf-cu/test/test_mkmf-cu.rb +67 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +82 -0
- data/README.md +252 -0
- data/Rakefile +43 -0
- data/bench/broadcast_fp32.rb +138 -0
- data/bench/cumo_bench.rb +193 -0
- data/bench/numo_bench.rb +138 -0
- data/bench/reduction_fp32.rb +117 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/cumo.gemspec +32 -0
- data/ext/cumo/cuda/cublas.c +278 -0
- data/ext/cumo/cuda/driver.c +421 -0
- data/ext/cumo/cuda/memory_pool.cpp +185 -0
- data/ext/cumo/cuda/memory_pool_impl.cpp +308 -0
- data/ext/cumo/cuda/memory_pool_impl.hpp +370 -0
- data/ext/cumo/cuda/memory_pool_impl_test.cpp +554 -0
- data/ext/cumo/cuda/nvrtc.c +207 -0
- data/ext/cumo/cuda/runtime.c +167 -0
- data/ext/cumo/cumo.c +148 -0
- data/ext/cumo/depend.erb +58 -0
- data/ext/cumo/extconf.rb +179 -0
- data/ext/cumo/include/cumo.h +25 -0
- data/ext/cumo/include/cumo/compat.h +23 -0
- data/ext/cumo/include/cumo/cuda/cublas.h +153 -0
- data/ext/cumo/include/cumo/cuda/cumo_thrust.hpp +187 -0
- data/ext/cumo/include/cumo/cuda/cumo_thrust_complex.hpp +79 -0
- data/ext/cumo/include/cumo/cuda/driver.h +22 -0
- data/ext/cumo/include/cumo/cuda/memory_pool.h +28 -0
- data/ext/cumo/include/cumo/cuda/nvrtc.h +22 -0
- data/ext/cumo/include/cumo/cuda/runtime.h +40 -0
- data/ext/cumo/include/cumo/indexer.h +238 -0
- data/ext/cumo/include/cumo/intern.h +142 -0
- data/ext/cumo/include/cumo/intern_fwd.h +38 -0
- data/ext/cumo/include/cumo/intern_kernel.h +6 -0
- data/ext/cumo/include/cumo/narray.h +429 -0
- data/ext/cumo/include/cumo/narray_kernel.h +149 -0
- data/ext/cumo/include/cumo/ndloop.h +95 -0
- data/ext/cumo/include/cumo/reduce_kernel.h +126 -0
- data/ext/cumo/include/cumo/template.h +158 -0
- data/ext/cumo/include/cumo/template_kernel.h +77 -0
- data/ext/cumo/include/cumo/types/bit.h +40 -0
- data/ext/cumo/include/cumo/types/bit_kernel.h +34 -0
- data/ext/cumo/include/cumo/types/complex.h +402 -0
- data/ext/cumo/include/cumo/types/complex_kernel.h +414 -0
- data/ext/cumo/include/cumo/types/complex_macro.h +382 -0
- data/ext/cumo/include/cumo/types/complex_macro_kernel.h +186 -0
- data/ext/cumo/include/cumo/types/dcomplex.h +46 -0
- data/ext/cumo/include/cumo/types/dcomplex_kernel.h +13 -0
- data/ext/cumo/include/cumo/types/dfloat.h +47 -0
- data/ext/cumo/include/cumo/types/dfloat_kernel.h +14 -0
- data/ext/cumo/include/cumo/types/float_def.h +34 -0
- data/ext/cumo/include/cumo/types/float_def_kernel.h +39 -0
- data/ext/cumo/include/cumo/types/float_macro.h +191 -0
- data/ext/cumo/include/cumo/types/float_macro_kernel.h +158 -0
- data/ext/cumo/include/cumo/types/int16.h +24 -0
- data/ext/cumo/include/cumo/types/int16_kernel.h +23 -0
- data/ext/cumo/include/cumo/types/int32.h +24 -0
- data/ext/cumo/include/cumo/types/int32_kernel.h +19 -0
- data/ext/cumo/include/cumo/types/int64.h +24 -0
- data/ext/cumo/include/cumo/types/int64_kernel.h +19 -0
- data/ext/cumo/include/cumo/types/int8.h +24 -0
- data/ext/cumo/include/cumo/types/int8_kernel.h +19 -0
- data/ext/cumo/include/cumo/types/int_macro.h +67 -0
- data/ext/cumo/include/cumo/types/int_macro_kernel.h +48 -0
- data/ext/cumo/include/cumo/types/real_accum.h +486 -0
- data/ext/cumo/include/cumo/types/real_accum_kernel.h +101 -0
- data/ext/cumo/include/cumo/types/robj_macro.h +80 -0
- data/ext/cumo/include/cumo/types/robj_macro_kernel.h +0 -0
- data/ext/cumo/include/cumo/types/robject.h +27 -0
- data/ext/cumo/include/cumo/types/robject_kernel.h +7 -0
- data/ext/cumo/include/cumo/types/scomplex.h +46 -0
- data/ext/cumo/include/cumo/types/scomplex_kernel.h +13 -0
- data/ext/cumo/include/cumo/types/sfloat.h +48 -0
- data/ext/cumo/include/cumo/types/sfloat_kernel.h +14 -0
- data/ext/cumo/include/cumo/types/uint16.h +25 -0
- data/ext/cumo/include/cumo/types/uint16_kernel.h +20 -0
- data/ext/cumo/include/cumo/types/uint32.h +25 -0
- data/ext/cumo/include/cumo/types/uint32_kernel.h +20 -0
- data/ext/cumo/include/cumo/types/uint64.h +25 -0
- data/ext/cumo/include/cumo/types/uint64_kernel.h +20 -0
- data/ext/cumo/include/cumo/types/uint8.h +25 -0
- data/ext/cumo/include/cumo/types/uint8_kernel.h +20 -0
- data/ext/cumo/include/cumo/types/uint_macro.h +58 -0
- data/ext/cumo/include/cumo/types/uint_macro_kernel.h +38 -0
- data/ext/cumo/include/cumo/types/xint_macro.h +169 -0
- data/ext/cumo/include/cumo/types/xint_macro_kernel.h +88 -0
- data/ext/cumo/narray/SFMT-params.h +97 -0
- data/ext/cumo/narray/SFMT-params19937.h +46 -0
- data/ext/cumo/narray/SFMT.c +620 -0
- data/ext/cumo/narray/SFMT.h +167 -0
- data/ext/cumo/narray/array.c +638 -0
- data/ext/cumo/narray/data.c +961 -0
- data/ext/cumo/narray/gen/cogen.rb +56 -0
- data/ext/cumo/narray/gen/cogen_kernel.rb +58 -0
- data/ext/cumo/narray/gen/def/bit.rb +37 -0
- data/ext/cumo/narray/gen/def/dcomplex.rb +39 -0
- data/ext/cumo/narray/gen/def/dfloat.rb +37 -0
- data/ext/cumo/narray/gen/def/int16.rb +36 -0
- data/ext/cumo/narray/gen/def/int32.rb +36 -0
- data/ext/cumo/narray/gen/def/int64.rb +36 -0
- data/ext/cumo/narray/gen/def/int8.rb +36 -0
- data/ext/cumo/narray/gen/def/robject.rb +37 -0
- data/ext/cumo/narray/gen/def/scomplex.rb +39 -0
- data/ext/cumo/narray/gen/def/sfloat.rb +37 -0
- data/ext/cumo/narray/gen/def/uint16.rb +36 -0
- data/ext/cumo/narray/gen/def/uint32.rb +36 -0
- data/ext/cumo/narray/gen/def/uint64.rb +36 -0
- data/ext/cumo/narray/gen/def/uint8.rb +36 -0
- data/ext/cumo/narray/gen/erbpp2.rb +346 -0
- data/ext/cumo/narray/gen/narray_def.rb +268 -0
- data/ext/cumo/narray/gen/spec.rb +425 -0
- data/ext/cumo/narray/gen/tmpl/accum.c +86 -0
- data/ext/cumo/narray/gen/tmpl/accum_binary.c +121 -0
- data/ext/cumo/narray/gen/tmpl/accum_binary_kernel.cu +61 -0
- data/ext/cumo/narray/gen/tmpl/accum_index.c +119 -0
- data/ext/cumo/narray/gen/tmpl/accum_index_kernel.cu +66 -0
- data/ext/cumo/narray/gen/tmpl/accum_kernel.cu +12 -0
- data/ext/cumo/narray/gen/tmpl/alloc_func.c +107 -0
- data/ext/cumo/narray/gen/tmpl/allocate.c +37 -0
- data/ext/cumo/narray/gen/tmpl/aref.c +66 -0
- data/ext/cumo/narray/gen/tmpl/aref_cpu.c +50 -0
- data/ext/cumo/narray/gen/tmpl/aset.c +56 -0
- data/ext/cumo/narray/gen/tmpl/binary.c +162 -0
- data/ext/cumo/narray/gen/tmpl/binary2.c +70 -0
- data/ext/cumo/narray/gen/tmpl/binary2_kernel.cu +15 -0
- data/ext/cumo/narray/gen/tmpl/binary_kernel.cu +31 -0
- data/ext/cumo/narray/gen/tmpl/binary_s.c +45 -0
- data/ext/cumo/narray/gen/tmpl/binary_s_kernel.cu +15 -0
- data/ext/cumo/narray/gen/tmpl/bincount.c +181 -0
- data/ext/cumo/narray/gen/tmpl/cast.c +44 -0
- data/ext/cumo/narray/gen/tmpl/cast_array.c +13 -0
- data/ext/cumo/narray/gen/tmpl/class.c +9 -0
- data/ext/cumo/narray/gen/tmpl/class_kernel.cu +6 -0
- data/ext/cumo/narray/gen/tmpl/clip.c +121 -0
- data/ext/cumo/narray/gen/tmpl/coerce_cast.c +10 -0
- data/ext/cumo/narray/gen/tmpl/complex_accum_kernel.cu +129 -0
- data/ext/cumo/narray/gen/tmpl/cond_binary.c +68 -0
- data/ext/cumo/narray/gen/tmpl/cond_binary_kernel.cu +18 -0
- data/ext/cumo/narray/gen/tmpl/cond_unary.c +46 -0
- data/ext/cumo/narray/gen/tmpl/cum.c +50 -0
- data/ext/cumo/narray/gen/tmpl/each.c +47 -0
- data/ext/cumo/narray/gen/tmpl/each_with_index.c +70 -0
- data/ext/cumo/narray/gen/tmpl/ewcomp.c +79 -0
- data/ext/cumo/narray/gen/tmpl/ewcomp_kernel.cu +19 -0
- data/ext/cumo/narray/gen/tmpl/extract.c +22 -0
- data/ext/cumo/narray/gen/tmpl/extract_cpu.c +26 -0
- data/ext/cumo/narray/gen/tmpl/extract_data.c +53 -0
- data/ext/cumo/narray/gen/tmpl/eye.c +105 -0
- data/ext/cumo/narray/gen/tmpl/eye_kernel.cu +19 -0
- data/ext/cumo/narray/gen/tmpl/fill.c +52 -0
- data/ext/cumo/narray/gen/tmpl/fill_kernel.cu +29 -0
- data/ext/cumo/narray/gen/tmpl/float_accum_kernel.cu +106 -0
- data/ext/cumo/narray/gen/tmpl/format.c +62 -0
- data/ext/cumo/narray/gen/tmpl/format_to_a.c +49 -0
- data/ext/cumo/narray/gen/tmpl/frexp.c +38 -0
- data/ext/cumo/narray/gen/tmpl/gemm.c +203 -0
- data/ext/cumo/narray/gen/tmpl/init_class.c +20 -0
- data/ext/cumo/narray/gen/tmpl/init_module.c +12 -0
- data/ext/cumo/narray/gen/tmpl/inspect.c +21 -0
- data/ext/cumo/narray/gen/tmpl/lib.c +50 -0
- data/ext/cumo/narray/gen/tmpl/lib_kernel.cu +24 -0
- data/ext/cumo/narray/gen/tmpl/logseq.c +102 -0
- data/ext/cumo/narray/gen/tmpl/logseq_kernel.cu +31 -0
- data/ext/cumo/narray/gen/tmpl/map_with_index.c +98 -0
- data/ext/cumo/narray/gen/tmpl/median.c +66 -0
- data/ext/cumo/narray/gen/tmpl/minmax.c +47 -0
- data/ext/cumo/narray/gen/tmpl/module.c +9 -0
- data/ext/cumo/narray/gen/tmpl/module_kernel.cu +1 -0
- data/ext/cumo/narray/gen/tmpl/new_dim0.c +15 -0
- data/ext/cumo/narray/gen/tmpl/new_dim0_kernel.cu +8 -0
- data/ext/cumo/narray/gen/tmpl/poly.c +50 -0
- data/ext/cumo/narray/gen/tmpl/pow.c +97 -0
- data/ext/cumo/narray/gen/tmpl/pow_kernel.cu +29 -0
- data/ext/cumo/narray/gen/tmpl/powint.c +17 -0
- data/ext/cumo/narray/gen/tmpl/qsort.c +212 -0
- data/ext/cumo/narray/gen/tmpl/rand.c +168 -0
- data/ext/cumo/narray/gen/tmpl/rand_norm.c +121 -0
- data/ext/cumo/narray/gen/tmpl/real_accum_kernel.cu +75 -0
- data/ext/cumo/narray/gen/tmpl/seq.c +112 -0
- data/ext/cumo/narray/gen/tmpl/seq_kernel.cu +43 -0
- data/ext/cumo/narray/gen/tmpl/set2.c +57 -0
- data/ext/cumo/narray/gen/tmpl/sort.c +48 -0
- data/ext/cumo/narray/gen/tmpl/sort_index.c +111 -0
- data/ext/cumo/narray/gen/tmpl/store.c +41 -0
- data/ext/cumo/narray/gen/tmpl/store_array.c +187 -0
- data/ext/cumo/narray/gen/tmpl/store_array_kernel.cu +58 -0
- data/ext/cumo/narray/gen/tmpl/store_bit.c +86 -0
- data/ext/cumo/narray/gen/tmpl/store_bit_kernel.cu +66 -0
- data/ext/cumo/narray/gen/tmpl/store_from.c +81 -0
- data/ext/cumo/narray/gen/tmpl/store_from_kernel.cu +58 -0
- data/ext/cumo/narray/gen/tmpl/store_kernel.cu +3 -0
- data/ext/cumo/narray/gen/tmpl/store_numeric.c +9 -0
- data/ext/cumo/narray/gen/tmpl/to_a.c +43 -0
- data/ext/cumo/narray/gen/tmpl/unary.c +132 -0
- data/ext/cumo/narray/gen/tmpl/unary2.c +60 -0
- data/ext/cumo/narray/gen/tmpl/unary_kernel.cu +72 -0
- data/ext/cumo/narray/gen/tmpl/unary_ret2.c +34 -0
- data/ext/cumo/narray/gen/tmpl/unary_s.c +86 -0
- data/ext/cumo/narray/gen/tmpl/unary_s_kernel.cu +58 -0
- data/ext/cumo/narray/gen/tmpl_bit/allocate.c +24 -0
- data/ext/cumo/narray/gen/tmpl_bit/aref.c +54 -0
- data/ext/cumo/narray/gen/tmpl_bit/aref_cpu.c +57 -0
- data/ext/cumo/narray/gen/tmpl_bit/aset.c +56 -0
- data/ext/cumo/narray/gen/tmpl_bit/binary.c +98 -0
- data/ext/cumo/narray/gen/tmpl_bit/bit_count.c +64 -0
- data/ext/cumo/narray/gen/tmpl_bit/bit_count_cpu.c +88 -0
- data/ext/cumo/narray/gen/tmpl_bit/bit_count_kernel.cu +76 -0
- data/ext/cumo/narray/gen/tmpl_bit/bit_reduce.c +133 -0
- data/ext/cumo/narray/gen/tmpl_bit/each.c +48 -0
- data/ext/cumo/narray/gen/tmpl_bit/each_with_index.c +70 -0
- data/ext/cumo/narray/gen/tmpl_bit/extract.c +30 -0
- data/ext/cumo/narray/gen/tmpl_bit/extract_cpu.c +29 -0
- data/ext/cumo/narray/gen/tmpl_bit/fill.c +69 -0
- data/ext/cumo/narray/gen/tmpl_bit/format.c +64 -0
- data/ext/cumo/narray/gen/tmpl_bit/format_to_a.c +51 -0
- data/ext/cumo/narray/gen/tmpl_bit/inspect.c +21 -0
- data/ext/cumo/narray/gen/tmpl_bit/mask.c +136 -0
- data/ext/cumo/narray/gen/tmpl_bit/none_p.c +14 -0
- data/ext/cumo/narray/gen/tmpl_bit/store_array.c +108 -0
- data/ext/cumo/narray/gen/tmpl_bit/store_bit.c +70 -0
- data/ext/cumo/narray/gen/tmpl_bit/store_from.c +60 -0
- data/ext/cumo/narray/gen/tmpl_bit/to_a.c +47 -0
- data/ext/cumo/narray/gen/tmpl_bit/unary.c +81 -0
- data/ext/cumo/narray/gen/tmpl_bit/where.c +90 -0
- data/ext/cumo/narray/gen/tmpl_bit/where2.c +95 -0
- data/ext/cumo/narray/index.c +880 -0
- data/ext/cumo/narray/kwargs.c +153 -0
- data/ext/cumo/narray/math.c +142 -0
- data/ext/cumo/narray/narray.c +1948 -0
- data/ext/cumo/narray/ndloop.c +2105 -0
- data/ext/cumo/narray/rand.c +45 -0
- data/ext/cumo/narray/step.c +474 -0
- data/ext/cumo/narray/struct.c +886 -0
- data/lib/cumo.rb +3 -0
- data/lib/cumo/cuda.rb +11 -0
- data/lib/cumo/cuda/compile_error.rb +36 -0
- data/lib/cumo/cuda/compiler.rb +161 -0
- data/lib/cumo/cuda/device.rb +47 -0
- data/lib/cumo/cuda/link_state.rb +31 -0
- data/lib/cumo/cuda/module.rb +40 -0
- data/lib/cumo/cuda/nvrtc_program.rb +27 -0
- data/lib/cumo/linalg.rb +12 -0
- data/lib/cumo/narray.rb +2 -0
- data/lib/cumo/narray/extra.rb +1278 -0
- data/lib/erbpp.rb +294 -0
- data/lib/erbpp/line_number.rb +137 -0
- data/lib/erbpp/narray_def.rb +381 -0
- data/numo-narray-version +1 -0
- data/run.gdb +7 -0
- metadata +353 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**********************************************************************
|
|
2
|
+
|
|
3
|
+
Function to extract Keyword argument for ruby-2.1.x
|
|
4
|
+
Copied from class.c in ruby-2.4.2
|
|
5
|
+
|
|
6
|
+
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
|
7
|
+
|
|
8
|
+
**********************************************************************/
|
|
9
|
+
#include <ruby.h>
|
|
10
|
+
#define rb_hash_tbl_raw(hash) rb_hash_tbl(hash)
|
|
11
|
+
|
|
12
|
+
/* from internal.h */
|
|
13
|
+
struct RBasicRaw {
|
|
14
|
+
VALUE flags;
|
|
15
|
+
VALUE klass;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
#define RBASIC_SET_CLASS(obj, cls) do { \
|
|
19
|
+
VALUE _obj_ = (obj); \
|
|
20
|
+
RB_OBJ_WRITE(_obj_, &((struct RBasicRaw *)(_obj_))->klass, cls); \
|
|
21
|
+
} while (0)
|
|
22
|
+
|
|
23
|
+
/* from class.c */
|
|
24
|
+
VALUE
|
|
25
|
+
rb_keyword_error_new(const char *error, VALUE keys)
|
|
26
|
+
{
|
|
27
|
+
const char *msg = "";
|
|
28
|
+
VALUE error_message;
|
|
29
|
+
|
|
30
|
+
if (RARRAY_LEN(keys) == 1) {
|
|
31
|
+
keys = RARRAY_AREF(keys, 0);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
keys = rb_ary_join(keys, rb_usascii_str_new2(", "));
|
|
35
|
+
msg = "s";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
error_message = rb_sprintf("%s keyword%s: %"PRIsVALUE, error, msg, keys);
|
|
39
|
+
|
|
40
|
+
return rb_exc_new_str(rb_eArgError, error_message);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
NORETURN(static void rb_keyword_error(const char *error, VALUE keys));
|
|
44
|
+
static void
|
|
45
|
+
rb_keyword_error(const char *error, VALUE keys)
|
|
46
|
+
{
|
|
47
|
+
rb_exc_raise(rb_keyword_error_new(error, keys));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
NORETURN(static void unknown_keyword_error(VALUE hash, const ID *table, int keywords));
|
|
51
|
+
static void
|
|
52
|
+
unknown_keyword_error(VALUE hash, const ID *table, int keywords)
|
|
53
|
+
{
|
|
54
|
+
st_table *tbl = rb_hash_tbl_raw(hash);
|
|
55
|
+
VALUE keys;
|
|
56
|
+
int i;
|
|
57
|
+
for (i = 0; i < keywords; i++) {
|
|
58
|
+
st_data_t key = ID2SYM(table[i]);
|
|
59
|
+
st_delete(tbl, &key, NULL);
|
|
60
|
+
}
|
|
61
|
+
keys = rb_funcallv(hash, rb_intern("keys"), 0, 0);
|
|
62
|
+
if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
|
|
63
|
+
rb_keyword_error("unknown", keys);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static int
|
|
67
|
+
separate_symbol(st_data_t key, st_data_t value, st_data_t arg)
|
|
68
|
+
{
|
|
69
|
+
VALUE *kwdhash = (VALUE *)arg;
|
|
70
|
+
|
|
71
|
+
if (!SYMBOL_P(key)) kwdhash++;
|
|
72
|
+
if (!*kwdhash) *kwdhash = rb_hash_new();
|
|
73
|
+
rb_hash_aset(*kwdhash, (VALUE)key, (VALUE)value);
|
|
74
|
+
return ST_CONTINUE;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
VALUE
|
|
78
|
+
rb_extract_keywords(VALUE *orighash)
|
|
79
|
+
{
|
|
80
|
+
VALUE parthash[2] = {0, 0};
|
|
81
|
+
VALUE hash = *orighash;
|
|
82
|
+
|
|
83
|
+
if (RHASH_EMPTY_P(hash)) {
|
|
84
|
+
*orighash = 0;
|
|
85
|
+
return hash;
|
|
86
|
+
}
|
|
87
|
+
st_foreach(rb_hash_tbl_raw(hash), separate_symbol, (st_data_t)&parthash);
|
|
88
|
+
*orighash = parthash[1];
|
|
89
|
+
if (parthash[1] && RBASIC_CLASS(hash) != rb_cHash) {
|
|
90
|
+
RBASIC_SET_CLASS(parthash[1], RBASIC_CLASS(hash));
|
|
91
|
+
}
|
|
92
|
+
return parthash[0];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
int
|
|
96
|
+
rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
|
|
97
|
+
{
|
|
98
|
+
int i = 0, j;
|
|
99
|
+
int rest = 0;
|
|
100
|
+
VALUE missing = Qnil;
|
|
101
|
+
st_data_t key;
|
|
102
|
+
|
|
103
|
+
#define extract_kwarg(keyword, val) \
|
|
104
|
+
(key = (st_data_t)(keyword), values ? \
|
|
105
|
+
st_delete(rb_hash_tbl_raw(keyword_hash), &key, (val)) : \
|
|
106
|
+
st_lookup(rb_hash_tbl_raw(keyword_hash), key, (val)))
|
|
107
|
+
|
|
108
|
+
if (NIL_P(keyword_hash)) keyword_hash = 0;
|
|
109
|
+
|
|
110
|
+
if (optional < 0) {
|
|
111
|
+
rest = 1;
|
|
112
|
+
optional = -1-optional;
|
|
113
|
+
}
|
|
114
|
+
if (values) {
|
|
115
|
+
for (j = 0; j < required + optional; j++) {
|
|
116
|
+
values[j] = Qundef;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (required) {
|
|
120
|
+
for (; i < required; i++) {
|
|
121
|
+
VALUE keyword = ID2SYM(table[i]);
|
|
122
|
+
if (keyword_hash) {
|
|
123
|
+
st_data_t val;
|
|
124
|
+
if (extract_kwarg(keyword, &val)) {
|
|
125
|
+
if (values) values[i] = (VALUE)val;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
|
|
130
|
+
rb_ary_push(missing, keyword);
|
|
131
|
+
}
|
|
132
|
+
if (!NIL_P(missing)) {
|
|
133
|
+
rb_keyword_error("missing", missing);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
j = i;
|
|
137
|
+
if (optional && keyword_hash) {
|
|
138
|
+
for (i = 0; i < optional; i++) {
|
|
139
|
+
st_data_t val;
|
|
140
|
+
if (extract_kwarg(ID2SYM(table[required+i]), &val)) {
|
|
141
|
+
if (values) values[required+i] = (VALUE)val;
|
|
142
|
+
j++;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (!rest && keyword_hash) {
|
|
147
|
+
if (RHASH_SIZE(keyword_hash) > (unsigned int)(values ? 0 : j)) {
|
|
148
|
+
unknown_keyword_error(keyword_hash, table, required+optional);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return j;
|
|
152
|
+
#undef extract_kwarg
|
|
153
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "cumo/narray.h"
|
|
3
|
+
|
|
4
|
+
VALUE cumo_mNMath;
|
|
5
|
+
extern VALUE cumo_mDFloatMath, cumo_mDComplexMath;
|
|
6
|
+
extern VALUE cumo_mSFloatMath, cumo_mSComplexMath;
|
|
7
|
+
static ID id_send;
|
|
8
|
+
static ID id_UPCAST;
|
|
9
|
+
static ID id_DISPATCH;
|
|
10
|
+
static ID id_extract;
|
|
11
|
+
|
|
12
|
+
static VALUE
|
|
13
|
+
nary_type_s_upcast(VALUE type1, VALUE type2)
|
|
14
|
+
{
|
|
15
|
+
VALUE upcast_hash;
|
|
16
|
+
VALUE result_type;
|
|
17
|
+
|
|
18
|
+
if (type1==type2) return type1;
|
|
19
|
+
upcast_hash = rb_const_get(type1, id_UPCAST);
|
|
20
|
+
result_type = rb_hash_aref(upcast_hash, type2);
|
|
21
|
+
if (NIL_P(result_type)) {
|
|
22
|
+
if (TYPE(type2)==T_CLASS) {
|
|
23
|
+
if ( RTEST(rb_class_inherited_p(type2,cNArray)) ) {
|
|
24
|
+
upcast_hash = rb_const_get(type2, id_UPCAST);
|
|
25
|
+
result_type = rb_hash_aref(upcast_hash, type1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return result_type;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
static VALUE nary_math_cast2(VALUE type1, VALUE type2)
|
|
34
|
+
{
|
|
35
|
+
if ( RTEST(rb_class_inherited_p( type1, cNArray )) ){
|
|
36
|
+
return nary_type_s_upcast( type1, type2 );
|
|
37
|
+
}
|
|
38
|
+
if ( RTEST(rb_class_inherited_p( type2, cNArray )) ){
|
|
39
|
+
return nary_type_s_upcast( type2, type1 );
|
|
40
|
+
}
|
|
41
|
+
if ( RTEST(rb_class_inherited_p( type1, rb_cNumeric )) &&
|
|
42
|
+
RTEST(rb_class_inherited_p( type2, rb_cNumeric )) ){
|
|
43
|
+
if ( RTEST(rb_class_inherited_p( type1, rb_cComplex)) ||
|
|
44
|
+
RTEST(rb_class_inherited_p( type2, rb_cComplex )) ){
|
|
45
|
+
return rb_cComplex;
|
|
46
|
+
}
|
|
47
|
+
return rb_cFloat;
|
|
48
|
+
}
|
|
49
|
+
return type2;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
VALUE na_ary_composition_dtype(VALUE);
|
|
54
|
+
|
|
55
|
+
static VALUE nary_mathcast(int argc, VALUE *argv)
|
|
56
|
+
{
|
|
57
|
+
VALUE type, type2;
|
|
58
|
+
int i;
|
|
59
|
+
|
|
60
|
+
type = na_ary_composition_dtype(argv[0]);
|
|
61
|
+
for (i=1; i<argc; i++) {
|
|
62
|
+
type2 = na_ary_composition_dtype(argv[i]);
|
|
63
|
+
type = nary_math_cast2(type, type2);
|
|
64
|
+
if (NIL_P(type)) {
|
|
65
|
+
rb_raise(rb_eTypeError,"includes unknown DataType for upcast");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return type;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
Dispatches method to Math module of upcasted type,
|
|
74
|
+
eg, Cumo::DFloat::Math.
|
|
75
|
+
@overload method_missing(name,x,...)
|
|
76
|
+
@param [Symbol] name method name.
|
|
77
|
+
@param [NArray,Numeric] x input array.
|
|
78
|
+
@return [NArray] result.
|
|
79
|
+
*/
|
|
80
|
+
static VALUE nary_math_method_missing(int argc, VALUE *argv, VALUE mod)
|
|
81
|
+
{
|
|
82
|
+
VALUE type, ans, typemod, hash;
|
|
83
|
+
if (argc>1) {
|
|
84
|
+
type = nary_mathcast(argc-1,argv+1);
|
|
85
|
+
|
|
86
|
+
hash = rb_const_get(mod, id_DISPATCH);
|
|
87
|
+
typemod = rb_hash_aref( hash, type );
|
|
88
|
+
if (NIL_P(typemod)) {
|
|
89
|
+
rb_raise(rb_eTypeError,"%s is unknown for Cumo::NMath",
|
|
90
|
+
rb_class2name(type));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
ans = rb_funcall2(typemod,id_send,argc,argv);
|
|
94
|
+
|
|
95
|
+
if (!RTEST(rb_class_inherited_p(type,cNArray)) &&
|
|
96
|
+
IsNArray(ans) ) {
|
|
97
|
+
ans = rb_funcall(ans,id_extract,0);
|
|
98
|
+
}
|
|
99
|
+
return ans;
|
|
100
|
+
}
|
|
101
|
+
rb_raise(rb_eArgError,"argument or method missing");
|
|
102
|
+
return Qnil;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
void
|
|
107
|
+
Init_cumo_nary_math()
|
|
108
|
+
{
|
|
109
|
+
VALUE hCast;
|
|
110
|
+
|
|
111
|
+
cumo_mNMath = rb_define_module_under(mCumo, "NMath");
|
|
112
|
+
rb_define_singleton_method(cumo_mNMath, "method_missing", nary_math_method_missing, -1);
|
|
113
|
+
|
|
114
|
+
hCast = rb_hash_new();
|
|
115
|
+
rb_define_const(cumo_mNMath, "DISPATCH", hCast);
|
|
116
|
+
rb_hash_aset(hCast, cumo_cInt64, cumo_mDFloatMath);
|
|
117
|
+
rb_hash_aset(hCast, cumo_cInt32, cumo_mDFloatMath);
|
|
118
|
+
rb_hash_aset(hCast, cumo_cInt16, cumo_mDFloatMath);
|
|
119
|
+
rb_hash_aset(hCast, cumo_cInt8, cumo_mDFloatMath);
|
|
120
|
+
rb_hash_aset(hCast, cumo_cUInt64, cumo_mDFloatMath);
|
|
121
|
+
rb_hash_aset(hCast, cumo_cUInt32, cumo_mDFloatMath);
|
|
122
|
+
rb_hash_aset(hCast, cumo_cUInt16, cumo_mDFloatMath);
|
|
123
|
+
rb_hash_aset(hCast, cumo_cUInt8, cumo_mDFloatMath);
|
|
124
|
+
rb_hash_aset(hCast, cumo_cDFloat, cumo_mDFloatMath);
|
|
125
|
+
rb_hash_aset(hCast, cumo_cDFloat, cumo_mDFloatMath);
|
|
126
|
+
rb_hash_aset(hCast, cumo_cDComplex, cumo_mDComplexMath);
|
|
127
|
+
rb_hash_aset(hCast, cumo_cSFloat, cumo_mSFloatMath);
|
|
128
|
+
rb_hash_aset(hCast, cumo_cSComplex, cumo_mSComplexMath);
|
|
129
|
+
#ifdef RUBY_INTEGER_UNIFICATION
|
|
130
|
+
rb_hash_aset(hCast, rb_cInteger, rb_mMath);
|
|
131
|
+
#else
|
|
132
|
+
rb_hash_aset(hCast, rb_cFixnum, rb_mMath);
|
|
133
|
+
rb_hash_aset(hCast, rb_cBignum, rb_mMath);
|
|
134
|
+
#endif
|
|
135
|
+
rb_hash_aset(hCast, rb_cFloat, rb_mMath);
|
|
136
|
+
rb_hash_aset(hCast, rb_cComplex, cumo_mDComplexMath);
|
|
137
|
+
|
|
138
|
+
id_send = rb_intern("send");
|
|
139
|
+
id_UPCAST = rb_intern("UPCAST");
|
|
140
|
+
id_DISPATCH = rb_intern("DISPATCH");
|
|
141
|
+
id_extract = rb_intern("extract");
|
|
142
|
+
}
|
|
@@ -0,0 +1,1948 @@
|
|
|
1
|
+
#define CUMO_NARRAY_C
|
|
2
|
+
#include <ruby.h>
|
|
3
|
+
#include <assert.h>
|
|
4
|
+
#include "cumo.h"
|
|
5
|
+
#include "cumo/narray.h"
|
|
6
|
+
#include "cumo/cuda/memory_pool.h"
|
|
7
|
+
#include "cumo/cuda/runtime.h"
|
|
8
|
+
|
|
9
|
+
/* global variables within this module */
|
|
10
|
+
VALUE cumo_cNArray;
|
|
11
|
+
VALUE rb_mCumo;
|
|
12
|
+
VALUE nary_eCastError;
|
|
13
|
+
VALUE nary_eShapeError;
|
|
14
|
+
VALUE nary_eOperationError;
|
|
15
|
+
VALUE nary_eDimensionError;
|
|
16
|
+
VALUE nary_eValueError;
|
|
17
|
+
|
|
18
|
+
static ID id_contiguous_stride;
|
|
19
|
+
static ID id_allocate;
|
|
20
|
+
static ID id_element_byte_size;
|
|
21
|
+
static ID id_fill;
|
|
22
|
+
static ID id_seq;
|
|
23
|
+
static ID id_logseq;
|
|
24
|
+
static ID id_eye;
|
|
25
|
+
static ID id_UPCAST;
|
|
26
|
+
static ID id_cast;
|
|
27
|
+
static ID id_dup;
|
|
28
|
+
static ID id_to_host;
|
|
29
|
+
static ID id_bracket;
|
|
30
|
+
static ID id_shift_left;
|
|
31
|
+
static ID id_eq;
|
|
32
|
+
static ID id_count_false;
|
|
33
|
+
static ID id_count_false_cpu;
|
|
34
|
+
static ID id_axis;
|
|
35
|
+
static ID id_nan;
|
|
36
|
+
static ID id_keepdims;
|
|
37
|
+
|
|
38
|
+
VALUE sym_reduce;
|
|
39
|
+
VALUE sym_option;
|
|
40
|
+
VALUE sym_loop_opt;
|
|
41
|
+
VALUE sym_init;
|
|
42
|
+
|
|
43
|
+
VALUE na_cStep;
|
|
44
|
+
#ifndef HAVE_RB_CCOMPLEX
|
|
45
|
+
VALUE rb_cComplex;
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
int cumo_na_inspect_rows=20;
|
|
49
|
+
int cumo_na_inspect_cols=80;
|
|
50
|
+
|
|
51
|
+
const rb_data_type_t na_data_type = {
|
|
52
|
+
"Cumo::NArray",
|
|
53
|
+
{0, 0, 0,}, 0, 0, 0,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
static void
|
|
57
|
+
nary_debug_info_nadata(VALUE self)
|
|
58
|
+
{
|
|
59
|
+
narray_data_t *na;
|
|
60
|
+
GetNArrayData(self,na);
|
|
61
|
+
|
|
62
|
+
printf(" ptr = 0x%"SZF"x\n", (size_t)(na->ptr));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
static VALUE
|
|
67
|
+
nary_debug_info_naview(VALUE self)
|
|
68
|
+
{
|
|
69
|
+
int i;
|
|
70
|
+
narray_view_t *na;
|
|
71
|
+
size_t *idx;
|
|
72
|
+
size_t j;
|
|
73
|
+
GetNArrayView(self,na);
|
|
74
|
+
|
|
75
|
+
printf(" data = 0x%"SZF"x\n", (size_t)na->data);
|
|
76
|
+
printf(" offset = %"SZF"d\n", (size_t)na->offset);
|
|
77
|
+
printf(" stridx = 0x%"SZF"x\n", (size_t)na->stridx);
|
|
78
|
+
|
|
79
|
+
if (na->stridx) {
|
|
80
|
+
printf(" stridx = [");
|
|
81
|
+
for (i=0; i<na->base.ndim; i++) {
|
|
82
|
+
if (SDX_IS_INDEX(na->stridx[i])) {
|
|
83
|
+
|
|
84
|
+
idx = SDX_GET_INDEX(na->stridx[i]);
|
|
85
|
+
printf(" index[%d]=[", i);
|
|
86
|
+
for (j=0; j<na->base.shape[i]; j++) {
|
|
87
|
+
printf(" %"SZF"d", idx[j]);
|
|
88
|
+
}
|
|
89
|
+
printf(" ] ");
|
|
90
|
+
|
|
91
|
+
} else {
|
|
92
|
+
printf(" %"SZF"d", SDX_GET_STRIDE(na->stridx[i]));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
printf(" ]\n");
|
|
96
|
+
}
|
|
97
|
+
return Qnil;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
VALUE
|
|
102
|
+
nary_debug_info(VALUE self)
|
|
103
|
+
{
|
|
104
|
+
int i;
|
|
105
|
+
narray_t *na;
|
|
106
|
+
GetNArray(self,na);
|
|
107
|
+
|
|
108
|
+
printf("%s:\n",rb_class2name(CLASS_OF(self)));
|
|
109
|
+
printf(" id = 0x%"PRI_VALUE_PREFIX"x\n", self);
|
|
110
|
+
printf(" type = %d\n", na->type);
|
|
111
|
+
printf(" flag = [%d,%d]\n", na->flag[0], na->flag[1]);
|
|
112
|
+
printf(" size = %"SZF"d\n", na->size);
|
|
113
|
+
printf(" ndim = %d\n", na->ndim);
|
|
114
|
+
printf(" shape = 0x%"SZF"x\n", (size_t)na->shape);
|
|
115
|
+
if (na->shape) {
|
|
116
|
+
printf(" shape = [");
|
|
117
|
+
for (i=0;i<na->ndim;i++)
|
|
118
|
+
printf(" %"SZF"d", na->shape[i]);
|
|
119
|
+
printf(" ]\n");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
switch(na->type) {
|
|
123
|
+
case NARRAY_DATA_T:
|
|
124
|
+
case NARRAY_FILEMAP_T:
|
|
125
|
+
nary_debug_info_nadata(self);
|
|
126
|
+
break;
|
|
127
|
+
case NARRAY_VIEW_T:
|
|
128
|
+
nary_debug_info_naview(self);
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
return Qnil;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
static size_t
|
|
136
|
+
na_view_memsize(const void* ptr)
|
|
137
|
+
{
|
|
138
|
+
int i;
|
|
139
|
+
size_t size = sizeof(narray_view_t);
|
|
140
|
+
const narray_view_t *na = ptr;
|
|
141
|
+
|
|
142
|
+
assert(na->base.type == NARRAY_VIEW_T);
|
|
143
|
+
|
|
144
|
+
if (na->stridx != NULL) {
|
|
145
|
+
for (i=0; i<na->base.ndim; i++) {
|
|
146
|
+
if (SDX_IS_INDEX(na->stridx[i])) {
|
|
147
|
+
size += sizeof(size_t) * na->base.shape[i];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
size += sizeof(stridx_t) * na->base.ndim;
|
|
151
|
+
}
|
|
152
|
+
if (na->base.size > 0) {
|
|
153
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
|
154
|
+
size += sizeof(size_t) * na->base.ndim;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return size;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static void
|
|
161
|
+
na_view_free(void* ptr)
|
|
162
|
+
{
|
|
163
|
+
int i;
|
|
164
|
+
narray_view_t *na = (narray_view_t*)ptr;
|
|
165
|
+
|
|
166
|
+
assert(na->base.type == NARRAY_VIEW_T);
|
|
167
|
+
|
|
168
|
+
if (na->stridx != NULL) {
|
|
169
|
+
for (i=0; i<na->base.ndim; i++) {
|
|
170
|
+
if (SDX_IS_INDEX(na->stridx[i])) {
|
|
171
|
+
void *p = SDX_GET_INDEX(na->stridx[i]);
|
|
172
|
+
if (cumo_cuda_runtime_is_device_memory(p)) {
|
|
173
|
+
cumo_cuda_runtime_free(p);
|
|
174
|
+
} else {
|
|
175
|
+
xfree(p);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
xfree(na->stridx);
|
|
180
|
+
na->stridx = NULL;
|
|
181
|
+
}
|
|
182
|
+
if (na->base.size > 0) {
|
|
183
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
|
184
|
+
xfree(na->base.shape);
|
|
185
|
+
na->base.shape = NULL;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
xfree(na);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static void
|
|
192
|
+
na_view_gc_mark(void* na)
|
|
193
|
+
{
|
|
194
|
+
if (((narray_t*)na)->type == NARRAY_VIEW_T) {
|
|
195
|
+
rb_gc_mark(((narray_view_t*)na)->data);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const rb_data_type_t na_data_type_view = {
|
|
200
|
+
"Cumo::NArrayView",
|
|
201
|
+
{na_view_gc_mark, na_view_free, na_view_memsize,},
|
|
202
|
+
&na_data_type, 0, 0,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
VALUE
|
|
206
|
+
na_s_allocate_view(VALUE klass)
|
|
207
|
+
{
|
|
208
|
+
narray_view_t *na = ALLOC(narray_view_t);
|
|
209
|
+
|
|
210
|
+
na->base.ndim = 0;
|
|
211
|
+
na->base.type = NARRAY_VIEW_T;
|
|
212
|
+
na->base.flag[0] = NA_FL0_INIT;
|
|
213
|
+
na->base.flag[1] = NA_FL1_INIT;
|
|
214
|
+
na->base.size = 0;
|
|
215
|
+
na->base.shape = NULL;
|
|
216
|
+
na->base.reduce = INT2FIX(0);
|
|
217
|
+
na->data = Qnil;
|
|
218
|
+
na->offset = 0;
|
|
219
|
+
na->stridx = NULL;
|
|
220
|
+
return TypedData_Wrap_Struct(klass, &na_data_type_view, (void*)na);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
//static const size_t zero=0;
|
|
225
|
+
|
|
226
|
+
void
|
|
227
|
+
na_array_to_internal_shape(VALUE self, VALUE ary, size_t *shape)
|
|
228
|
+
{
|
|
229
|
+
size_t i, n, c, s;
|
|
230
|
+
ssize_t x;
|
|
231
|
+
VALUE v;
|
|
232
|
+
int flag = 0;
|
|
233
|
+
|
|
234
|
+
n = RARRAY_LEN(ary);
|
|
235
|
+
|
|
236
|
+
if (RTEST(self)) {
|
|
237
|
+
flag = TEST_COLUMN_MAJOR(self);
|
|
238
|
+
}
|
|
239
|
+
if (flag) {
|
|
240
|
+
c = n-1;
|
|
241
|
+
s = -1;
|
|
242
|
+
} else {
|
|
243
|
+
c = 0;
|
|
244
|
+
s = 1;
|
|
245
|
+
}
|
|
246
|
+
for (i=0; i<n; i++) {
|
|
247
|
+
v = RARRAY_AREF(ary,i);
|
|
248
|
+
x = NUM2SSIZET(v);
|
|
249
|
+
if (x < 0) {
|
|
250
|
+
rb_raise(rb_eArgError,"size must be non-negative");
|
|
251
|
+
}
|
|
252
|
+
shape[c] = x;
|
|
253
|
+
c += s;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
void
|
|
260
|
+
na_alloc_shape(narray_t *na, int ndim)
|
|
261
|
+
{
|
|
262
|
+
na->ndim = ndim;
|
|
263
|
+
na->size = 0;
|
|
264
|
+
switch(ndim) {
|
|
265
|
+
case 0:
|
|
266
|
+
case 1:
|
|
267
|
+
na->shape = &(na->size);
|
|
268
|
+
break;
|
|
269
|
+
default:
|
|
270
|
+
if (ndim < 0) {
|
|
271
|
+
rb_raise(nary_eDimensionError,"ndim=%d is negative", ndim);
|
|
272
|
+
}
|
|
273
|
+
if (ndim > NA_MAX_DIMENSION) {
|
|
274
|
+
rb_raise(nary_eDimensionError,"ndim=%d is too many", ndim);
|
|
275
|
+
}
|
|
276
|
+
na->shape = ALLOC_N(size_t, ndim);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
void
|
|
281
|
+
na_setup_shape(narray_t *na, int ndim, size_t *shape)
|
|
282
|
+
{
|
|
283
|
+
int i;
|
|
284
|
+
size_t size;
|
|
285
|
+
|
|
286
|
+
na_alloc_shape(na, ndim);
|
|
287
|
+
|
|
288
|
+
if (ndim==0) {
|
|
289
|
+
na->size = 1;
|
|
290
|
+
}
|
|
291
|
+
else if (ndim==1) {
|
|
292
|
+
na->size = shape[0];
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
for (i=0, size=1; i<ndim; i++) {
|
|
296
|
+
na->shape[i] = shape[i];
|
|
297
|
+
size *= shape[i];
|
|
298
|
+
}
|
|
299
|
+
na->size = size;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
static void
|
|
304
|
+
na_setup(VALUE self, int ndim, size_t *shape)
|
|
305
|
+
{
|
|
306
|
+
narray_t *na;
|
|
307
|
+
GetNArray(self,na);
|
|
308
|
+
na_setup_shape(na, ndim, shape);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
/*
|
|
313
|
+
@overload initialize(shape)
|
|
314
|
+
@overload initialize(size0, size1, ...)
|
|
315
|
+
@param [Array] shape (array of sizes along each dimension)
|
|
316
|
+
@param [Integer] sizeN (size along Nth-dimension)
|
|
317
|
+
@return [Cumo::NArray] unallocated narray.
|
|
318
|
+
|
|
319
|
+
Constructs an instance of NArray class using the given
|
|
320
|
+
and <i>shape</i> or <i>sizes</i>.
|
|
321
|
+
Note that NArray itself is an abstract super class and
|
|
322
|
+
not suitable to create instances.
|
|
323
|
+
Use Typed Subclasses of NArray (DFloat, Int32, etc) to create instances.
|
|
324
|
+
This method does not allocate memory for array data.
|
|
325
|
+
Memory is allocated on write method such as #fill, #store, #seq, etc.
|
|
326
|
+
|
|
327
|
+
@example
|
|
328
|
+
i = Cumo::Int64.new([2,4,3])
|
|
329
|
+
#=> Cumo::Int64#shape=[2,4,3](empty)
|
|
330
|
+
|
|
331
|
+
f = Cumo::DFloat.new(3,4)
|
|
332
|
+
#=> Cumo::DFloat#shape=[3,4](empty)
|
|
333
|
+
|
|
334
|
+
f.fill(2)
|
|
335
|
+
#=> Cumo::DFloat#shape=[3,4]
|
|
336
|
+
# [[2, 2, 2, 2],
|
|
337
|
+
# [2, 2, 2, 2],
|
|
338
|
+
# [2, 2, 2, 2]]
|
|
339
|
+
|
|
340
|
+
x = Cumo::NArray.new(5)
|
|
341
|
+
#=> in `new': allocator undefined for Cumo::NArray (TypeError)
|
|
342
|
+
# from t.rb:9:in `<main>'
|
|
343
|
+
|
|
344
|
+
*/
|
|
345
|
+
static VALUE
|
|
346
|
+
na_initialize(VALUE self, VALUE args)
|
|
347
|
+
{
|
|
348
|
+
VALUE v;
|
|
349
|
+
size_t *shape=NULL;
|
|
350
|
+
int ndim;
|
|
351
|
+
|
|
352
|
+
if (RARRAY_LEN(args) == 1) {
|
|
353
|
+
v = RARRAY_AREF(args,0);
|
|
354
|
+
if (TYPE(v) != T_ARRAY) {
|
|
355
|
+
v = args;
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
v = args;
|
|
359
|
+
}
|
|
360
|
+
ndim = RARRAY_LEN(v);
|
|
361
|
+
if (ndim > NA_MAX_DIMENSION) {
|
|
362
|
+
rb_raise(rb_eArgError,"ndim=%d exceeds maximum dimension",ndim);
|
|
363
|
+
}
|
|
364
|
+
shape = ALLOCA_N(size_t, ndim);
|
|
365
|
+
// setup size_t shape[] from VALUE shape argument
|
|
366
|
+
na_array_to_internal_shape(self, v, shape);
|
|
367
|
+
na_setup(self, ndim, shape);
|
|
368
|
+
|
|
369
|
+
return self;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
VALUE
|
|
374
|
+
nary_new(VALUE klass, int ndim, size_t *shape)
|
|
375
|
+
{
|
|
376
|
+
volatile VALUE obj;
|
|
377
|
+
|
|
378
|
+
obj = rb_funcall(klass, id_allocate, 0);
|
|
379
|
+
na_setup(obj, ndim, shape);
|
|
380
|
+
return obj;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
VALUE
|
|
385
|
+
nary_view_new(VALUE klass, int ndim, size_t *shape)
|
|
386
|
+
{
|
|
387
|
+
volatile VALUE obj;
|
|
388
|
+
|
|
389
|
+
obj = na_s_allocate_view(klass);
|
|
390
|
+
na_setup(obj, ndim, shape);
|
|
391
|
+
return obj;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
/*
|
|
396
|
+
Replaces the contents of self with the contents of other narray.
|
|
397
|
+
Used in dup and clone method.
|
|
398
|
+
@overload initialize_copy(other)
|
|
399
|
+
@param [Cumo::NArray] other
|
|
400
|
+
@return [Cumo::NArray] self
|
|
401
|
+
*/
|
|
402
|
+
static VALUE
|
|
403
|
+
na_initialize_copy(VALUE self, VALUE orig)
|
|
404
|
+
{
|
|
405
|
+
narray_t *na;
|
|
406
|
+
GetNArray(orig,na);
|
|
407
|
+
|
|
408
|
+
na_setup(self,NA_NDIM(na),NA_SHAPE(na));
|
|
409
|
+
na_store(self,orig);
|
|
410
|
+
na_copy_flags(orig,self);
|
|
411
|
+
return self;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
/*
|
|
416
|
+
* call-seq:
|
|
417
|
+
* zeros(shape) => narray
|
|
418
|
+
* zeros(size1,size2,...) => narray
|
|
419
|
+
*
|
|
420
|
+
* Returns a zero-filled narray with <i>shape</i>.
|
|
421
|
+
* This singleton method is valid not for NArray class itself
|
|
422
|
+
* but for typed NArray subclasses, e.g., DFloat, Int64.
|
|
423
|
+
* @example
|
|
424
|
+
* a = Cumo::DFloat.zeros(3,5)
|
|
425
|
+
* => Cumo::DFloat#shape=[3,5]
|
|
426
|
+
* [[0, 0, 0, 0, 0],
|
|
427
|
+
* [0, 0, 0, 0, 0],
|
|
428
|
+
* [0, 0, 0, 0, 0]]
|
|
429
|
+
*/
|
|
430
|
+
static VALUE
|
|
431
|
+
na_s_zeros(int argc, VALUE *argv, VALUE klass)
|
|
432
|
+
{
|
|
433
|
+
VALUE obj;
|
|
434
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
|
435
|
+
return rb_funcall(obj, id_fill, 1, INT2FIX(0));
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
/*
|
|
440
|
+
* call-seq:
|
|
441
|
+
* ones(shape) => narray
|
|
442
|
+
* ones(size1,size2,...) => narray
|
|
443
|
+
*
|
|
444
|
+
* Returns a one-filled narray with <i>shape</i>.
|
|
445
|
+
* This singleton method is valid not for NArray class itself
|
|
446
|
+
* but for typed NArray subclasses, e.g., DFloat, Int64.
|
|
447
|
+
* @example
|
|
448
|
+
* a = Cumo::DFloat.ones(3,5)
|
|
449
|
+
* => Cumo::DFloat#shape=[3,5]
|
|
450
|
+
* [[1, 1, 1, 1, 1],
|
|
451
|
+
* [1, 1, 1, 1, 1],
|
|
452
|
+
* [1, 1, 1, 1, 1]]
|
|
453
|
+
*/
|
|
454
|
+
static VALUE
|
|
455
|
+
na_s_ones(int argc, VALUE *argv, VALUE klass)
|
|
456
|
+
{
|
|
457
|
+
VALUE obj;
|
|
458
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
|
459
|
+
return rb_funcall(obj, id_fill, 1, INT2FIX(1));
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
/*
|
|
464
|
+
Returns an array of N linearly spaced points between x1 and x2.
|
|
465
|
+
This singleton method is valid not for NArray class itself
|
|
466
|
+
but for typed NArray subclasses, e.g., DFloat, Int64.
|
|
467
|
+
|
|
468
|
+
@overload linspace(x1, x2, [n])
|
|
469
|
+
@param [Numeric] x1 The start value
|
|
470
|
+
@param [Numeric] x2 The end value
|
|
471
|
+
@param [Integer] n The number of elements. (default is 100).
|
|
472
|
+
@return [Cumo::NArray] result array.
|
|
473
|
+
|
|
474
|
+
@example
|
|
475
|
+
a = Cumo::DFloat.linspace(-5,5,7)
|
|
476
|
+
=> Cumo::DFloat#shape=[7]
|
|
477
|
+
[-5, -3.33333, -1.66667, 0, 1.66667, 3.33333, 5]
|
|
478
|
+
*/
|
|
479
|
+
static VALUE
|
|
480
|
+
na_s_linspace(int argc, VALUE *argv, VALUE klass)
|
|
481
|
+
{
|
|
482
|
+
VALUE obj, vx1, vx2, vstep, vsize;
|
|
483
|
+
double n;
|
|
484
|
+
int narg;
|
|
485
|
+
|
|
486
|
+
narg = rb_scan_args(argc,argv,"21",&vx1,&vx2,&vsize);
|
|
487
|
+
if (narg==3) {
|
|
488
|
+
n = NUM2DBL(vsize);
|
|
489
|
+
} else {
|
|
490
|
+
n = 100;
|
|
491
|
+
vsize = INT2FIX(100);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
obj = rb_funcall(vx2, '-', 1, vx1);
|
|
495
|
+
vstep = rb_funcall(obj, '/', 1, DBL2NUM(n-1));
|
|
496
|
+
|
|
497
|
+
obj = rb_class_new_instance(1, &vsize, klass);
|
|
498
|
+
return rb_funcall(obj, id_seq, 2, vx1, vstep);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/*
|
|
502
|
+
Returns an array of N logarithmically spaced points between 10^a and 10^b.
|
|
503
|
+
This singleton method is valid not for NArray having +logseq+ method,
|
|
504
|
+
i.e., DFloat, SFloat, DComplex, and SComplex.
|
|
505
|
+
|
|
506
|
+
@overload logspace(a, b, [n, base])
|
|
507
|
+
@param [Numeric] a The start value
|
|
508
|
+
@param [Numeric] b The end value
|
|
509
|
+
@param [Integer] n The number of elements. (default is 50)
|
|
510
|
+
@param [Numeric] base The base of log space. (default is 10)
|
|
511
|
+
@return [Cumo::NArray] result array.
|
|
512
|
+
|
|
513
|
+
@example
|
|
514
|
+
Cumo::DFloat.logspace(4,0,5,2)
|
|
515
|
+
=> Cumo::DFloat#shape=[5]
|
|
516
|
+
[16, 8, 4, 2, 1]
|
|
517
|
+
Cumo::DComplex.logspace(0,1i*Math::PI,5,Math::E)
|
|
518
|
+
=> Cumo::DComplex#shape=[5]
|
|
519
|
+
[1+4.44659e-323i, 0.707107+0.707107i, 6.12323e-17+1i, -0.707107+0.707107i, ...]
|
|
520
|
+
*/
|
|
521
|
+
static VALUE
|
|
522
|
+
na_s_logspace(int argc, VALUE *argv, VALUE klass)
|
|
523
|
+
{
|
|
524
|
+
VALUE obj, vx1, vx2, vstep, vsize, vbase;
|
|
525
|
+
double n;
|
|
526
|
+
|
|
527
|
+
rb_scan_args(argc,argv,"22",&vx1,&vx2,&vsize,&vbase);
|
|
528
|
+
if (vsize == Qnil) {
|
|
529
|
+
vsize = INT2FIX(50);
|
|
530
|
+
n = 50;
|
|
531
|
+
} else {
|
|
532
|
+
n = NUM2DBL(vsize);
|
|
533
|
+
}
|
|
534
|
+
if (vbase == Qnil) {
|
|
535
|
+
vbase = DBL2NUM(10);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
obj = rb_funcall(vx2, '-', 1, vx1);
|
|
539
|
+
vstep = rb_funcall(obj, '/', 1, DBL2NUM(n-1));
|
|
540
|
+
|
|
541
|
+
obj = rb_class_new_instance(1, &vsize, klass);
|
|
542
|
+
return rb_funcall(obj, id_logseq, 3, vx1, vstep, vbase);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
/*
|
|
547
|
+
Returns a NArray with shape=(n,n) whose diagonal elements are 1, otherwise 0.
|
|
548
|
+
@overload eye(n)
|
|
549
|
+
@param [Integer] n Size of NArray. Creates 2-D NArray with shape=(n,n)
|
|
550
|
+
@return [Cumo::NArray] created NArray.
|
|
551
|
+
@example
|
|
552
|
+
a = Cumo::DFloat.eye(3)
|
|
553
|
+
=> Cumo::DFloat#shape=[3,3]
|
|
554
|
+
[[1, 0, 0],
|
|
555
|
+
[0, 1, 0],
|
|
556
|
+
[0, 0, 1]]
|
|
557
|
+
*/
|
|
558
|
+
static VALUE
|
|
559
|
+
na_s_eye(int argc, VALUE *argv, VALUE klass)
|
|
560
|
+
{
|
|
561
|
+
VALUE obj;
|
|
562
|
+
VALUE tmp[2];
|
|
563
|
+
|
|
564
|
+
if (argc==0) {
|
|
565
|
+
rb_raise(rb_eArgError,"No argument");
|
|
566
|
+
}
|
|
567
|
+
else if (argc==1) {
|
|
568
|
+
tmp[0] = tmp[1] = argv[0];
|
|
569
|
+
argv = tmp;
|
|
570
|
+
argc = 2;
|
|
571
|
+
}
|
|
572
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
|
573
|
+
return rb_funcall(obj, id_eye, 0);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
#define READ 1
|
|
579
|
+
#define WRITE 2
|
|
580
|
+
|
|
581
|
+
static char *
|
|
582
|
+
na_get_pointer_for_rw(VALUE self, int flag)
|
|
583
|
+
{
|
|
584
|
+
char *ptr;
|
|
585
|
+
VALUE obj;
|
|
586
|
+
narray_t *na;
|
|
587
|
+
|
|
588
|
+
if ((flag & WRITE) && OBJ_FROZEN(self)) {
|
|
589
|
+
rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
GetNArray(self,na);
|
|
593
|
+
|
|
594
|
+
switch(NA_TYPE(na)) {
|
|
595
|
+
case NARRAY_DATA_T:
|
|
596
|
+
ptr = NA_DATA_PTR(na);
|
|
597
|
+
if (NA_SIZE(na) > 0 && ptr == NULL) {
|
|
598
|
+
if (flag & READ) {
|
|
599
|
+
rb_raise(rb_eRuntimeError,"cannot read unallocated NArray");
|
|
600
|
+
}
|
|
601
|
+
if (flag & WRITE) {
|
|
602
|
+
rb_funcall(self, id_allocate, 0);
|
|
603
|
+
ptr = NA_DATA_PTR(na);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return ptr;
|
|
607
|
+
case NARRAY_VIEW_T:
|
|
608
|
+
obj = NA_VIEW_DATA(na);
|
|
609
|
+
if ((flag & WRITE) && OBJ_FROZEN(obj)) {
|
|
610
|
+
rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
|
|
611
|
+
}
|
|
612
|
+
GetNArray(obj,na);
|
|
613
|
+
switch(NA_TYPE(na)) {
|
|
614
|
+
case NARRAY_DATA_T:
|
|
615
|
+
ptr = NA_DATA_PTR(na);
|
|
616
|
+
if (flag & (READ|WRITE)) {
|
|
617
|
+
if (NA_SIZE(na) > 0 && ptr == NULL) {
|
|
618
|
+
rb_raise(rb_eRuntimeError,"cannot read/write unallocated NArray");
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
return ptr;
|
|
622
|
+
default:
|
|
623
|
+
rb_raise(rb_eRuntimeError,"invalid NA_TYPE of view: %d",NA_TYPE(na));
|
|
624
|
+
}
|
|
625
|
+
default:
|
|
626
|
+
rb_raise(rb_eRuntimeError,"invalid NA_TYPE: %d",NA_TYPE(na));
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
return NULL;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
char *
|
|
633
|
+
na_get_pointer_for_read(VALUE self)
|
|
634
|
+
{
|
|
635
|
+
return na_get_pointer_for_rw(self, READ);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
char *
|
|
639
|
+
na_get_pointer_for_write(VALUE self)
|
|
640
|
+
{
|
|
641
|
+
return na_get_pointer_for_rw(self, WRITE);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
char *
|
|
645
|
+
na_get_pointer_for_read_write(VALUE self)
|
|
646
|
+
{
|
|
647
|
+
return na_get_pointer_for_rw(self, READ|WRITE);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
char *
|
|
651
|
+
na_get_pointer(VALUE self)
|
|
652
|
+
{
|
|
653
|
+
return na_get_pointer_for_rw(self, 0);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
void
|
|
658
|
+
na_release_lock(VALUE self)
|
|
659
|
+
{
|
|
660
|
+
narray_t *na;
|
|
661
|
+
|
|
662
|
+
UNSET_LOCK(self);
|
|
663
|
+
GetNArray(self,na);
|
|
664
|
+
|
|
665
|
+
switch(NA_TYPE(na)) {
|
|
666
|
+
case NARRAY_VIEW_T:
|
|
667
|
+
na_release_lock(NA_VIEW_DATA(na));
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
/* method: size() -- returns the total number of typeents */
|
|
674
|
+
static VALUE
|
|
675
|
+
na_size(VALUE self)
|
|
676
|
+
{
|
|
677
|
+
narray_t *na;
|
|
678
|
+
GetNArray(self,na);
|
|
679
|
+
return SIZET2NUM(na->size);
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
/* method: size() -- returns the total number of typeents */
|
|
684
|
+
static VALUE
|
|
685
|
+
na_ndim(VALUE self)
|
|
686
|
+
{
|
|
687
|
+
narray_t *na;
|
|
688
|
+
GetNArray(self,na);
|
|
689
|
+
return INT2NUM(na->ndim);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
/*
|
|
694
|
+
Returns true if self.size == 0.
|
|
695
|
+
@overload empty?
|
|
696
|
+
*/
|
|
697
|
+
static VALUE
|
|
698
|
+
na_empty_p(VALUE self)
|
|
699
|
+
{
|
|
700
|
+
narray_t *na;
|
|
701
|
+
GetNArray(self,na);
|
|
702
|
+
if (NA_SIZE(na)==0) {
|
|
703
|
+
return Qtrue;
|
|
704
|
+
}
|
|
705
|
+
return Qfalse;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
/* method: shape() -- returns shape, array of the size of dimensions */
|
|
710
|
+
static VALUE
|
|
711
|
+
na_shape(VALUE self)
|
|
712
|
+
{
|
|
713
|
+
volatile VALUE v;
|
|
714
|
+
narray_t *na;
|
|
715
|
+
size_t i, n, c, s;
|
|
716
|
+
|
|
717
|
+
GetNArray(self,na);
|
|
718
|
+
n = NA_NDIM(na);
|
|
719
|
+
if (TEST_COLUMN_MAJOR(self)) {
|
|
720
|
+
c = n-1;
|
|
721
|
+
s = -1;
|
|
722
|
+
} else {
|
|
723
|
+
c = 0;
|
|
724
|
+
s = 1;
|
|
725
|
+
}
|
|
726
|
+
v = rb_ary_new2(n);
|
|
727
|
+
for (i=0; i<n; i++) {
|
|
728
|
+
rb_ary_push(v, SIZET2NUM(na->shape[c]));
|
|
729
|
+
c += s;
|
|
730
|
+
}
|
|
731
|
+
return v;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
|
|
735
|
+
unsigned int
|
|
736
|
+
nary_element_stride(VALUE v)
|
|
737
|
+
{
|
|
738
|
+
narray_type_info_t *info;
|
|
739
|
+
narray_t *na;
|
|
740
|
+
|
|
741
|
+
GetNArray(v,na);
|
|
742
|
+
if (na->type == NARRAY_VIEW_T) {
|
|
743
|
+
v = NA_VIEW_DATA(na);
|
|
744
|
+
GetNArray(v,na);
|
|
745
|
+
}
|
|
746
|
+
assert(na->type == NARRAY_DATA_T);
|
|
747
|
+
|
|
748
|
+
info = (narray_type_info_t *)(RTYPEDDATA_TYPE(v)->data);
|
|
749
|
+
return info->element_stride;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
size_t
|
|
753
|
+
na_dtype_elmsz(VALUE klass)
|
|
754
|
+
{
|
|
755
|
+
return NUM2SIZET(rb_const_get(klass, id_contiguous_stride));
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
size_t
|
|
759
|
+
na_get_offset(VALUE self)
|
|
760
|
+
{
|
|
761
|
+
narray_t *na;
|
|
762
|
+
GetNArray(self,na);
|
|
763
|
+
|
|
764
|
+
switch(na->type) {
|
|
765
|
+
case NARRAY_DATA_T:
|
|
766
|
+
case NARRAY_FILEMAP_T:
|
|
767
|
+
return 0;
|
|
768
|
+
case NARRAY_VIEW_T:
|
|
769
|
+
return NA_VIEW_OFFSET(na);
|
|
770
|
+
}
|
|
771
|
+
return 0;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
void
|
|
776
|
+
na_index_arg_to_internal_order(int argc, VALUE *argv, VALUE self)
|
|
777
|
+
{
|
|
778
|
+
int i,j;
|
|
779
|
+
VALUE tmp;
|
|
780
|
+
|
|
781
|
+
if (TEST_COLUMN_MAJOR(self)) {
|
|
782
|
+
for (i=0,j=argc-1; i<argc/2; i++,j--) {
|
|
783
|
+
tmp = argv[i];
|
|
784
|
+
argv[i] = argv[j];
|
|
785
|
+
argv[j] = tmp;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
void
|
|
791
|
+
na_copy_flags(VALUE src, VALUE dst)
|
|
792
|
+
{
|
|
793
|
+
narray_t *na1, *na2;
|
|
794
|
+
|
|
795
|
+
GetNArray(src,na1);
|
|
796
|
+
GetNArray(dst,na2);
|
|
797
|
+
|
|
798
|
+
na2->flag[0] = na1->flag[0];
|
|
799
|
+
//na2->flag[1] = NA_FL1_INIT;
|
|
800
|
+
|
|
801
|
+
RBASIC(dst)->flags |= (RBASIC(src)->flags) &
|
|
802
|
+
(FL_USER1|FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6|FL_USER7);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
|
|
806
|
+
// fix name, ex, allow_stride_for_flatten_view
|
|
807
|
+
VALUE
|
|
808
|
+
na_check_ladder(VALUE self, int start_dim)
|
|
809
|
+
{
|
|
810
|
+
int i;
|
|
811
|
+
ssize_t st0, st1;
|
|
812
|
+
narray_t *na;
|
|
813
|
+
GetNArray(self,na);
|
|
814
|
+
|
|
815
|
+
if (start_dim < -na->ndim || start_dim >= na->ndim) {
|
|
816
|
+
rb_bug("start_dim (%d) out of range",start_dim);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
switch(na->type) {
|
|
820
|
+
case NARRAY_DATA_T:
|
|
821
|
+
case NARRAY_FILEMAP_T:
|
|
822
|
+
return Qtrue;
|
|
823
|
+
case NARRAY_VIEW_T:
|
|
824
|
+
// negative dim -> position from last dim
|
|
825
|
+
if (start_dim < 0) {
|
|
826
|
+
start_dim += NA_NDIM(na);
|
|
827
|
+
}
|
|
828
|
+
// not ladder if it has index
|
|
829
|
+
for (i=start_dim; i<NA_NDIM(na); i++) {
|
|
830
|
+
if (NA_IS_INDEX_AT(na,i))
|
|
831
|
+
return Qfalse;
|
|
832
|
+
}
|
|
833
|
+
// check stride
|
|
834
|
+
st0 = NA_STRIDE_AT(na,start_dim);
|
|
835
|
+
for (i=start_dim+1; i<NA_NDIM(na); i++) {
|
|
836
|
+
st1 = NA_STRIDE_AT(na,i);
|
|
837
|
+
if (st0 != (ssize_t)(st1 * NA_SHAPE(na)[i])) {
|
|
838
|
+
return Qfalse;
|
|
839
|
+
}
|
|
840
|
+
st0 = st1;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return Qtrue;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
VALUE
|
|
847
|
+
na_check_contiguous(VALUE self)
|
|
848
|
+
{
|
|
849
|
+
ssize_t elmsz;
|
|
850
|
+
narray_t *na;
|
|
851
|
+
GetNArray(self,na);
|
|
852
|
+
|
|
853
|
+
switch(na->type) {
|
|
854
|
+
case NARRAY_DATA_T:
|
|
855
|
+
case NARRAY_FILEMAP_T:
|
|
856
|
+
return Qtrue;
|
|
857
|
+
case NARRAY_VIEW_T:
|
|
858
|
+
if (NA_VIEW_STRIDX(na)==0) {
|
|
859
|
+
return Qtrue;
|
|
860
|
+
}
|
|
861
|
+
if (na_check_ladder(self,0)==Qtrue) {
|
|
862
|
+
elmsz = nary_element_stride(self);
|
|
863
|
+
if (elmsz == NA_STRIDE_AT(na,NA_NDIM(na)-1)) {
|
|
864
|
+
return Qtrue;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
return Qfalse;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
//----------------------------------------------------------------------
|
|
872
|
+
|
|
873
|
+
/*
|
|
874
|
+
* call-seq:
|
|
875
|
+
* narray.view => narray
|
|
876
|
+
*
|
|
877
|
+
* Return view of NArray
|
|
878
|
+
*/
|
|
879
|
+
VALUE
|
|
880
|
+
na_make_view(VALUE self)
|
|
881
|
+
{
|
|
882
|
+
int i, nd;
|
|
883
|
+
size_t j;
|
|
884
|
+
size_t *idx1, *idx2;
|
|
885
|
+
ssize_t stride;
|
|
886
|
+
narray_t *na;
|
|
887
|
+
narray_view_t *na1, *na2;
|
|
888
|
+
volatile VALUE view;
|
|
889
|
+
|
|
890
|
+
GetNArray(self,na);
|
|
891
|
+
nd = na->ndim;
|
|
892
|
+
|
|
893
|
+
view = na_s_allocate_view(CLASS_OF(self));
|
|
894
|
+
|
|
895
|
+
na_copy_flags(self, view);
|
|
896
|
+
GetNArrayView(view, na2);
|
|
897
|
+
|
|
898
|
+
na_setup_shape((narray_t*)na2, nd, na->shape);
|
|
899
|
+
na2->stridx = ALLOC_N(stridx_t,nd);
|
|
900
|
+
|
|
901
|
+
switch(na->type) {
|
|
902
|
+
case NARRAY_DATA_T:
|
|
903
|
+
case NARRAY_FILEMAP_T:
|
|
904
|
+
stride = nary_element_stride(self);
|
|
905
|
+
for (i=nd; i--;) {
|
|
906
|
+
SDX_SET_STRIDE(na2->stridx[i],stride);
|
|
907
|
+
stride *= na->shape[i];
|
|
908
|
+
}
|
|
909
|
+
na2->offset = 0;
|
|
910
|
+
na2->data = self;
|
|
911
|
+
break;
|
|
912
|
+
case NARRAY_VIEW_T:
|
|
913
|
+
GetNArrayView(self, na1);
|
|
914
|
+
for (i=0; i<nd; i++) {
|
|
915
|
+
if (SDX_IS_INDEX(na1->stridx[i])) {
|
|
916
|
+
idx1 = SDX_GET_INDEX(na1->stridx[i]);
|
|
917
|
+
idx2 = ALLOC_N(size_t,na1->base.shape[i]);
|
|
918
|
+
for (j=0; j<na1->base.shape[i]; j++) {
|
|
919
|
+
idx2[j] = idx1[j];
|
|
920
|
+
}
|
|
921
|
+
SDX_SET_INDEX(na2->stridx[i],idx2);
|
|
922
|
+
} else {
|
|
923
|
+
na2->stridx[i] = na1->stridx[i];
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
na2->offset = na1->offset;
|
|
927
|
+
na2->data = na1->data;
|
|
928
|
+
break;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
return view;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
|
|
935
|
+
//----------------------------------------------------------------------
|
|
936
|
+
|
|
937
|
+
/*
|
|
938
|
+
* call-seq:
|
|
939
|
+
* narray.expand_dims(dim) => narray view
|
|
940
|
+
*
|
|
941
|
+
* Expand the shape of an array. Insert a new axis with size=1
|
|
942
|
+
* at a given dimension.
|
|
943
|
+
* @param [Integer] dim dimension at which new axis is inserted.
|
|
944
|
+
* @return [Cumo::NArray] result narray view.
|
|
945
|
+
*/
|
|
946
|
+
static VALUE
|
|
947
|
+
na_expand_dims(VALUE self, VALUE vdim)
|
|
948
|
+
{
|
|
949
|
+
int i, j, nd, dim;
|
|
950
|
+
size_t *shape, *na_shape;
|
|
951
|
+
stridx_t *stridx, *na_stridx;
|
|
952
|
+
narray_t *na;
|
|
953
|
+
narray_view_t *na2;
|
|
954
|
+
VALUE view;
|
|
955
|
+
|
|
956
|
+
GetNArray(self,na);
|
|
957
|
+
nd = na->ndim;
|
|
958
|
+
|
|
959
|
+
dim = NUM2INT(vdim);
|
|
960
|
+
if (dim < -nd-1 || dim > nd) {
|
|
961
|
+
rb_raise(nary_eDimensionError,"invalid axis (%d for %dD NArray)",
|
|
962
|
+
dim,nd);
|
|
963
|
+
}
|
|
964
|
+
if (dim < 0) {
|
|
965
|
+
dim += nd+1;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
view = na_make_view(self);
|
|
969
|
+
GetNArrayView(view, na2);
|
|
970
|
+
|
|
971
|
+
shape = ALLOC_N(size_t,nd+1);
|
|
972
|
+
stridx = ALLOC_N(stridx_t,nd+1);
|
|
973
|
+
na_shape = na2->base.shape;
|
|
974
|
+
na_stridx = na2->stridx;
|
|
975
|
+
|
|
976
|
+
for (i=j=0; i<=nd; i++) {
|
|
977
|
+
if (i==dim) {
|
|
978
|
+
shape[i] = 1;
|
|
979
|
+
SDX_SET_STRIDE(stridx[i],0);
|
|
980
|
+
} else {
|
|
981
|
+
shape[i] = na_shape[j];
|
|
982
|
+
stridx[i] = na_stridx[j];
|
|
983
|
+
j++;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
na2->stridx = stridx;
|
|
988
|
+
xfree(na_stridx);
|
|
989
|
+
na2->base.shape = shape;
|
|
990
|
+
if (na_shape != &(na2->base.size)) {
|
|
991
|
+
xfree(na_shape);
|
|
992
|
+
}
|
|
993
|
+
na2->base.ndim++;
|
|
994
|
+
return view;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
//----------------------------------------------------------------------
|
|
998
|
+
|
|
999
|
+
/*
|
|
1000
|
+
* call-seq:
|
|
1001
|
+
* narray.reverse([dim0,dim1,..]) => narray
|
|
1002
|
+
*
|
|
1003
|
+
* Return reversed view along specified dimeinsion
|
|
1004
|
+
*/
|
|
1005
|
+
static VALUE
|
|
1006
|
+
nary_reverse(int argc, VALUE *argv, VALUE self)
|
|
1007
|
+
{
|
|
1008
|
+
int i, nd;
|
|
1009
|
+
size_t j, n;
|
|
1010
|
+
size_t offset;
|
|
1011
|
+
size_t *idx1, *idx2;
|
|
1012
|
+
ssize_t stride;
|
|
1013
|
+
ssize_t sign;
|
|
1014
|
+
narray_t *na;
|
|
1015
|
+
narray_view_t *na1, *na2;
|
|
1016
|
+
VALUE view;
|
|
1017
|
+
VALUE reduce;
|
|
1018
|
+
|
|
1019
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self, 0, 0);
|
|
1020
|
+
|
|
1021
|
+
GetNArray(self,na);
|
|
1022
|
+
nd = na->ndim;
|
|
1023
|
+
|
|
1024
|
+
view = na_s_allocate_view(CLASS_OF(self));
|
|
1025
|
+
|
|
1026
|
+
na_copy_flags(self, view);
|
|
1027
|
+
GetNArrayView(view, na2);
|
|
1028
|
+
|
|
1029
|
+
na_setup_shape((narray_t*)na2, nd, na->shape);
|
|
1030
|
+
na2->stridx = ALLOC_N(stridx_t,nd);
|
|
1031
|
+
|
|
1032
|
+
switch(na->type) {
|
|
1033
|
+
case NARRAY_DATA_T:
|
|
1034
|
+
case NARRAY_FILEMAP_T:
|
|
1035
|
+
stride = nary_element_stride(self);
|
|
1036
|
+
offset = 0;
|
|
1037
|
+
for (i=nd; i--;) {
|
|
1038
|
+
if (na_test_reduce(reduce,i)) {
|
|
1039
|
+
offset += (na->shape[i]-1)*stride;
|
|
1040
|
+
sign = -1;
|
|
1041
|
+
} else {
|
|
1042
|
+
sign = 1;
|
|
1043
|
+
}
|
|
1044
|
+
SDX_SET_STRIDE(na2->stridx[i],stride*sign);
|
|
1045
|
+
stride *= na->shape[i];
|
|
1046
|
+
}
|
|
1047
|
+
na2->offset = offset;
|
|
1048
|
+
na2->data = self;
|
|
1049
|
+
break;
|
|
1050
|
+
case NARRAY_VIEW_T:
|
|
1051
|
+
GetNArrayView(self, na1);
|
|
1052
|
+
offset = na1->offset;
|
|
1053
|
+
for (i=0; i<nd; i++) {
|
|
1054
|
+
n = na1->base.shape[i];
|
|
1055
|
+
if (SDX_IS_INDEX(na1->stridx[i])) {
|
|
1056
|
+
idx1 = SDX_GET_INDEX(na1->stridx[i]);
|
|
1057
|
+
idx2 = ALLOC_N(size_t,n);
|
|
1058
|
+
if (na_test_reduce(reduce,i)) {
|
|
1059
|
+
for (j=0; j<n; j++) {
|
|
1060
|
+
idx2[n-1-j] = idx1[j];
|
|
1061
|
+
}
|
|
1062
|
+
} else {
|
|
1063
|
+
for (j=0; j<n; j++) {
|
|
1064
|
+
idx2[j] = idx1[j];
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
SDX_SET_INDEX(na2->stridx[i],idx2);
|
|
1068
|
+
} else {
|
|
1069
|
+
stride = SDX_GET_STRIDE(na1->stridx[i]);
|
|
1070
|
+
if (na_test_reduce(reduce,i)) {
|
|
1071
|
+
offset += (n-1)*stride;
|
|
1072
|
+
SDX_SET_STRIDE(na2->stridx[i],-stride);
|
|
1073
|
+
} else {
|
|
1074
|
+
na2->stridx[i] = na1->stridx[i];
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
na2->offset = offset;
|
|
1079
|
+
na2->data = na1->data;
|
|
1080
|
+
break;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
return view;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
//----------------------------------------------------------------------
|
|
1087
|
+
|
|
1088
|
+
VALUE
|
|
1089
|
+
cumo_na_upcast(VALUE type1, VALUE type2)
|
|
1090
|
+
{
|
|
1091
|
+
VALUE upcast_hash;
|
|
1092
|
+
VALUE result_type;
|
|
1093
|
+
|
|
1094
|
+
if (type1==type2) {
|
|
1095
|
+
return type1;
|
|
1096
|
+
}
|
|
1097
|
+
upcast_hash = rb_const_get(type1, id_UPCAST);
|
|
1098
|
+
result_type = rb_hash_aref(upcast_hash, type2);
|
|
1099
|
+
if (NIL_P(result_type)) {
|
|
1100
|
+
if (TYPE(type2)==T_CLASS) {
|
|
1101
|
+
if (RTEST(rb_class_inherited_p(type2,cNArray))) {
|
|
1102
|
+
upcast_hash = rb_const_get(type2, id_UPCAST);
|
|
1103
|
+
result_type = rb_hash_aref(upcast_hash, type1);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return result_type;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
/*
|
|
1111
|
+
Returns an array containing other and self,
|
|
1112
|
+
both are converted to upcasted type of NArray.
|
|
1113
|
+
Note that NArray has distinct UPCAST mechanism.
|
|
1114
|
+
Coerce is used for operation between non-NArray and NArray.
|
|
1115
|
+
@overload coerce(other)
|
|
1116
|
+
@param [Object] other numeric object.
|
|
1117
|
+
@return [Array] NArray-casted [other,self]
|
|
1118
|
+
*/
|
|
1119
|
+
static VALUE
|
|
1120
|
+
nary_coerce(VALUE x, VALUE y)
|
|
1121
|
+
{
|
|
1122
|
+
VALUE type;
|
|
1123
|
+
|
|
1124
|
+
type = cumo_na_upcast(CLASS_OF(x), CLASS_OF(y));
|
|
1125
|
+
y = rb_funcall(type,id_cast,1,y);
|
|
1126
|
+
return rb_assoc_new(y , x);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
|
|
1130
|
+
/*
|
|
1131
|
+
Returns total byte size of NArray.
|
|
1132
|
+
@return [Integer] byte size.
|
|
1133
|
+
*/
|
|
1134
|
+
static VALUE
|
|
1135
|
+
nary_byte_size(VALUE self)
|
|
1136
|
+
{
|
|
1137
|
+
VALUE velmsz;
|
|
1138
|
+
narray_t *na;
|
|
1139
|
+
|
|
1140
|
+
GetNArray(self,na);
|
|
1141
|
+
velmsz = rb_const_get(CLASS_OF(self), id_element_byte_size);
|
|
1142
|
+
if (FIXNUM_P(velmsz)) {
|
|
1143
|
+
return SIZET2NUM(NUM2SIZET(velmsz) * na->size);
|
|
1144
|
+
}
|
|
1145
|
+
return SIZET2NUM(ceil(NUM2DBL(velmsz) * na->size));
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/*
|
|
1149
|
+
Returns byte size of one element of NArray.
|
|
1150
|
+
@return [Numeric] byte size.
|
|
1151
|
+
*/
|
|
1152
|
+
static VALUE
|
|
1153
|
+
nary_s_byte_size(VALUE type)
|
|
1154
|
+
{
|
|
1155
|
+
return rb_const_get(type, id_element_byte_size);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
/*
|
|
1160
|
+
Returns a new 1-D array initialized from binary raw data in a string.
|
|
1161
|
+
@overload from_binary(string,[shape])
|
|
1162
|
+
@param [String] string Binary raw data.
|
|
1163
|
+
@param [Array] shape array of integers representing array shape.
|
|
1164
|
+
@return [Cumo::NArray] NArray containing binary data.
|
|
1165
|
+
*/
|
|
1166
|
+
static VALUE
|
|
1167
|
+
nary_s_from_binary(int argc, VALUE *argv, VALUE type)
|
|
1168
|
+
{
|
|
1169
|
+
size_t len, str_len, byte_size;
|
|
1170
|
+
size_t *shape;
|
|
1171
|
+
char *ptr;
|
|
1172
|
+
int i, nd, narg;
|
|
1173
|
+
VALUE vstr, vshape, vna;
|
|
1174
|
+
VALUE velmsz;
|
|
1175
|
+
|
|
1176
|
+
narg = rb_scan_args(argc,argv,"11",&vstr,&vshape);
|
|
1177
|
+
Check_Type(vstr,T_STRING);
|
|
1178
|
+
str_len = RSTRING_LEN(vstr);
|
|
1179
|
+
velmsz = rb_const_get(type, id_element_byte_size);
|
|
1180
|
+
if (narg==2) {
|
|
1181
|
+
switch(TYPE(vshape)) {
|
|
1182
|
+
case T_FIXNUM:
|
|
1183
|
+
nd = 1;
|
|
1184
|
+
len = NUM2SIZET(vshape);
|
|
1185
|
+
shape = &len;
|
|
1186
|
+
break;
|
|
1187
|
+
case T_ARRAY:
|
|
1188
|
+
nd = RARRAY_LEN(vshape);
|
|
1189
|
+
if (nd == 0 || nd > NA_MAX_DIMENSION) {
|
|
1190
|
+
rb_raise(nary_eDimensionError,"too long or empty shape (%d)", nd);
|
|
1191
|
+
}
|
|
1192
|
+
shape = ALLOCA_N(size_t,nd);
|
|
1193
|
+
len = 1;
|
|
1194
|
+
for (i=0; i<nd; ++i) {
|
|
1195
|
+
len *= shape[i] = NUM2SIZET(RARRAY_AREF(vshape,i));
|
|
1196
|
+
}
|
|
1197
|
+
break;
|
|
1198
|
+
default:
|
|
1199
|
+
rb_raise(rb_eArgError,"second argument must be size or shape");
|
|
1200
|
+
}
|
|
1201
|
+
if (FIXNUM_P(velmsz)) {
|
|
1202
|
+
byte_size = len * NUM2SIZET(velmsz);
|
|
1203
|
+
} else {
|
|
1204
|
+
byte_size = ceil(len * NUM2DBL(velmsz));
|
|
1205
|
+
}
|
|
1206
|
+
if (byte_size > str_len) {
|
|
1207
|
+
rb_raise(rb_eArgError, "specified size is too large");
|
|
1208
|
+
}
|
|
1209
|
+
} else {
|
|
1210
|
+
nd = 1;
|
|
1211
|
+
if (FIXNUM_P(velmsz)) {
|
|
1212
|
+
len = str_len / NUM2SIZET(velmsz);
|
|
1213
|
+
byte_size = len * NUM2SIZET(velmsz);
|
|
1214
|
+
} else {
|
|
1215
|
+
len = floor(str_len / NUM2DBL(velmsz));
|
|
1216
|
+
byte_size = str_len;
|
|
1217
|
+
}
|
|
1218
|
+
if (len == 0) {
|
|
1219
|
+
rb_raise(rb_eArgError, "string is empty or too short");
|
|
1220
|
+
}
|
|
1221
|
+
shape = ALLOCA_N(size_t,nd);
|
|
1222
|
+
shape[0] = len;
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
vna = nary_new(type, nd, shape);
|
|
1226
|
+
ptr = na_get_pointer_for_write(vna);
|
|
1227
|
+
|
|
1228
|
+
memcpy(ptr, RSTRING_PTR(vstr), byte_size);
|
|
1229
|
+
|
|
1230
|
+
return vna;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
/*
|
|
1234
|
+
Returns a new 1-D array initialized from binary raw data in a string.
|
|
1235
|
+
@overload store_binary(string,[offset])
|
|
1236
|
+
@param [String] string Binary raw data.
|
|
1237
|
+
@param [Integer] (optional) offset Byte offset in string.
|
|
1238
|
+
@return [Integer] stored length.
|
|
1239
|
+
*/
|
|
1240
|
+
static VALUE
|
|
1241
|
+
nary_store_binary(int argc, VALUE *argv, VALUE self)
|
|
1242
|
+
{
|
|
1243
|
+
size_t size, str_len, byte_size, offset;
|
|
1244
|
+
char *ptr;
|
|
1245
|
+
int narg;
|
|
1246
|
+
VALUE vstr, voffset;
|
|
1247
|
+
VALUE velmsz;
|
|
1248
|
+
narray_t *na;
|
|
1249
|
+
|
|
1250
|
+
narg = rb_scan_args(argc,argv,"11",&vstr,&voffset);
|
|
1251
|
+
str_len = RSTRING_LEN(vstr);
|
|
1252
|
+
if (narg==2) {
|
|
1253
|
+
offset = NUM2SIZET(voffset);
|
|
1254
|
+
if (str_len < offset) {
|
|
1255
|
+
rb_raise(rb_eArgError, "offset is larger than string length");
|
|
1256
|
+
}
|
|
1257
|
+
str_len -= offset;
|
|
1258
|
+
} else {
|
|
1259
|
+
offset = 0;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
GetNArray(self,na);
|
|
1263
|
+
size = NA_SIZE(na);
|
|
1264
|
+
velmsz = rb_const_get(CLASS_OF(self), id_element_byte_size);
|
|
1265
|
+
if (FIXNUM_P(velmsz)) {
|
|
1266
|
+
byte_size = size * NUM2SIZET(velmsz);
|
|
1267
|
+
} else {
|
|
1268
|
+
byte_size = ceil(size * NUM2DBL(velmsz));
|
|
1269
|
+
}
|
|
1270
|
+
if (byte_size > str_len) {
|
|
1271
|
+
rb_raise(rb_eArgError, "string is too short to store");
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
ptr = na_get_pointer_for_write(self);
|
|
1275
|
+
memcpy(ptr, RSTRING_PTR(vstr)+offset, byte_size);
|
|
1276
|
+
|
|
1277
|
+
return SIZET2NUM(byte_size);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
/*
|
|
1281
|
+
Returns string containing the raw data bytes in NArray.
|
|
1282
|
+
@overload to_binary()
|
|
1283
|
+
@return [String] String object containing binary raw data.
|
|
1284
|
+
*/
|
|
1285
|
+
static VALUE
|
|
1286
|
+
nary_to_binary(VALUE self)
|
|
1287
|
+
{
|
|
1288
|
+
size_t len, offset=0;
|
|
1289
|
+
char *ptr;
|
|
1290
|
+
VALUE str;
|
|
1291
|
+
narray_t *na;
|
|
1292
|
+
|
|
1293
|
+
SHOW_SYNCHRONIZE_WARNING_ONCE("nary_to_binary", "any");
|
|
1294
|
+
cumo_cuda_runtime_check_status(cudaDeviceSynchronize());
|
|
1295
|
+
|
|
1296
|
+
GetNArray(self,na);
|
|
1297
|
+
if (na->type == NARRAY_VIEW_T) {
|
|
1298
|
+
if (na_check_contiguous(self)==Qtrue) {
|
|
1299
|
+
offset = NA_VIEW_OFFSET(na);
|
|
1300
|
+
} else {
|
|
1301
|
+
self = rb_funcall(self,id_dup,0);
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
len = NUM2SIZET(nary_byte_size(self));
|
|
1305
|
+
ptr = na_get_pointer_for_read(self);
|
|
1306
|
+
str = rb_usascii_str_new(ptr+offset,len);
|
|
1307
|
+
RB_GC_GUARD(self);
|
|
1308
|
+
return str;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
/*
|
|
1312
|
+
Dump marshal data.
|
|
1313
|
+
@overload marshal_dump()
|
|
1314
|
+
@return [Array] Array containing marshal data.
|
|
1315
|
+
*/
|
|
1316
|
+
static VALUE
|
|
1317
|
+
nary_marshal_dump(VALUE self)
|
|
1318
|
+
{
|
|
1319
|
+
VALUE a;
|
|
1320
|
+
|
|
1321
|
+
SHOW_SYNCHRONIZE_WARNING_ONCE("nary_marshal_dump", "any");
|
|
1322
|
+
cumo_cuda_runtime_check_status(cudaDeviceSynchronize());
|
|
1323
|
+
|
|
1324
|
+
a = rb_ary_new();
|
|
1325
|
+
rb_ary_push(a, INT2FIX(1)); // version
|
|
1326
|
+
rb_ary_push(a, na_shape(self));
|
|
1327
|
+
rb_ary_push(a, INT2FIX(NA_FLAG0(self)));
|
|
1328
|
+
if (CLASS_OF(self) == cumo_cRObject) {
|
|
1329
|
+
narray_t *na;
|
|
1330
|
+
VALUE *ptr;
|
|
1331
|
+
size_t offset=0;
|
|
1332
|
+
GetNArray(self,na);
|
|
1333
|
+
if (na->type == NARRAY_VIEW_T) {
|
|
1334
|
+
if (na_check_contiguous(self)==Qtrue) {
|
|
1335
|
+
offset = NA_VIEW_OFFSET(na);
|
|
1336
|
+
} else {
|
|
1337
|
+
self = rb_funcall(self,id_dup,0);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
ptr = (VALUE*)na_get_pointer_for_read(self);
|
|
1341
|
+
rb_ary_push(a, rb_ary_new4(NA_SIZE(na), ptr+offset));
|
|
1342
|
+
} else {
|
|
1343
|
+
rb_ary_push(a, nary_to_binary(self));
|
|
1344
|
+
}
|
|
1345
|
+
RB_GC_GUARD(self);
|
|
1346
|
+
return a;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
static VALUE na_inplace( VALUE self );
|
|
1350
|
+
/*
|
|
1351
|
+
Load marshal data.
|
|
1352
|
+
@overload marshal_load(data)
|
|
1353
|
+
@params [Array] Array containing marshal data.
|
|
1354
|
+
@return [nil]
|
|
1355
|
+
*/
|
|
1356
|
+
static VALUE
|
|
1357
|
+
nary_marshal_load(VALUE self, VALUE a)
|
|
1358
|
+
{
|
|
1359
|
+
VALUE v;
|
|
1360
|
+
|
|
1361
|
+
if (TYPE(a) != T_ARRAY) {
|
|
1362
|
+
rb_raise(rb_eArgError,"marshal argument should be array");
|
|
1363
|
+
}
|
|
1364
|
+
if (RARRAY_LEN(a) != 4) {
|
|
1365
|
+
rb_raise(rb_eArgError,"marshal array size should be 4");
|
|
1366
|
+
}
|
|
1367
|
+
if (RARRAY_AREF(a,0) != INT2FIX(1)) {
|
|
1368
|
+
rb_raise(rb_eArgError,"NArray marshal version %d is not supported "
|
|
1369
|
+
"(only version 1)", NUM2INT(RARRAY_AREF(a,0)));
|
|
1370
|
+
}
|
|
1371
|
+
na_initialize(self,RARRAY_AREF(a,1));
|
|
1372
|
+
NA_FL0_SET(self,FIX2INT(RARRAY_AREF(a,2)));
|
|
1373
|
+
v = RARRAY_AREF(a,3);
|
|
1374
|
+
if (CLASS_OF(self) == cumo_cRObject) {
|
|
1375
|
+
narray_t *na;
|
|
1376
|
+
char *ptr;
|
|
1377
|
+
if (TYPE(v) != T_ARRAY) {
|
|
1378
|
+
rb_raise(rb_eArgError,"RObject content should be array");
|
|
1379
|
+
}
|
|
1380
|
+
GetNArray(self,na);
|
|
1381
|
+
if (RARRAY_LEN(v) != (long)NA_SIZE(na)) {
|
|
1382
|
+
rb_raise(rb_eArgError,"RObject content size mismatch");
|
|
1383
|
+
}
|
|
1384
|
+
ptr = na_get_pointer_for_write(self);
|
|
1385
|
+
memcpy(ptr, RARRAY_PTR(v), NA_SIZE(na)*sizeof(VALUE));
|
|
1386
|
+
} else {
|
|
1387
|
+
nary_store_binary(1,&v,self);
|
|
1388
|
+
if (TEST_BYTE_SWAPPED(self)) {
|
|
1389
|
+
rb_funcall(na_inplace(self),id_to_host,0);
|
|
1390
|
+
REVERSE_ENDIAN(self); // correct behavior??
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
RB_GC_GUARD(a);
|
|
1394
|
+
return self;
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
/*
|
|
1399
|
+
Cast self to another NArray datatype.
|
|
1400
|
+
@overload cast_to(datatype)
|
|
1401
|
+
@param [Class] datatype NArray datatype.
|
|
1402
|
+
@return [Cumo::NArray]
|
|
1403
|
+
*/
|
|
1404
|
+
static VALUE
|
|
1405
|
+
nary_cast_to(VALUE obj, VALUE type)
|
|
1406
|
+
{
|
|
1407
|
+
return rb_funcall(type, id_cast, 1, obj);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
// reduce is dimension indicies to reduce in reduction kernel (in bits), e.g., for an array of shape:
|
|
1413
|
+
// [2,3,4], 111b for sum(), 010b for sum(axis: 1), 110b for sum(axis: [1,2])
|
|
1414
|
+
bool
|
|
1415
|
+
na_test_reduce(VALUE reduce, int dim)
|
|
1416
|
+
{
|
|
1417
|
+
size_t m;
|
|
1418
|
+
|
|
1419
|
+
if (!RTEST(reduce))
|
|
1420
|
+
return 0;
|
|
1421
|
+
if (FIXNUM_P(reduce)) {
|
|
1422
|
+
m = FIX2LONG(reduce);
|
|
1423
|
+
if (m==0) return 1;
|
|
1424
|
+
return (m & (1u<<dim)) ? 1 : 0;
|
|
1425
|
+
} else {
|
|
1426
|
+
return (rb_funcall(reduce,id_bracket,1,INT2FIX(dim))==INT2FIX(1)) ?
|
|
1427
|
+
1 : 0 ;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
static VALUE
|
|
1433
|
+
na_get_reduce_flag_from_narray(int naryc, VALUE *naryv, int *max_arg)
|
|
1434
|
+
{
|
|
1435
|
+
int ndim, ndim0;
|
|
1436
|
+
int rowmaj;
|
|
1437
|
+
int i;
|
|
1438
|
+
size_t j;
|
|
1439
|
+
narray_t *na;
|
|
1440
|
+
VALUE reduce;
|
|
1441
|
+
|
|
1442
|
+
if (naryc<1) {
|
|
1443
|
+
rb_raise(rb_eRuntimeError,"must be positive: naryc=%d", naryc);
|
|
1444
|
+
}
|
|
1445
|
+
GetNArray(naryv[0],na);
|
|
1446
|
+
if (na->size==0) {
|
|
1447
|
+
rb_raise(nary_eShapeError,"cannot reduce empty NArray");
|
|
1448
|
+
}
|
|
1449
|
+
reduce = na->reduce;
|
|
1450
|
+
ndim = ndim0 = na->ndim;
|
|
1451
|
+
if (max_arg) *max_arg = 0;
|
|
1452
|
+
rowmaj = TEST_COLUMN_MAJOR(naryv[0]);
|
|
1453
|
+
for (i=0; i<naryc; i++) {
|
|
1454
|
+
GetNArray(naryv[i],na);
|
|
1455
|
+
if (na->size==0) {
|
|
1456
|
+
rb_raise(nary_eShapeError,"cannot reduce empty NArray");
|
|
1457
|
+
}
|
|
1458
|
+
if (TEST_COLUMN_MAJOR(naryv[i]) != rowmaj) {
|
|
1459
|
+
rb_raise(nary_eDimensionError,"dimension order is different");
|
|
1460
|
+
}
|
|
1461
|
+
if (na->ndim > ndim) { // maximum dimension
|
|
1462
|
+
ndim = na->ndim;
|
|
1463
|
+
if (max_arg) *max_arg = i;
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
if (ndim != ndim0) {
|
|
1467
|
+
j = NUM2SIZET(reduce) << (ndim-ndim0);
|
|
1468
|
+
reduce = SIZET2NUM(j);
|
|
1469
|
+
}
|
|
1470
|
+
return reduce;
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
|
|
1474
|
+
static VALUE
|
|
1475
|
+
na_get_reduce_flag_from_axes(VALUE na_obj, VALUE axes)
|
|
1476
|
+
{
|
|
1477
|
+
int i, r;
|
|
1478
|
+
int ndim, rowmaj;
|
|
1479
|
+
long narg;
|
|
1480
|
+
size_t j;
|
|
1481
|
+
size_t len;
|
|
1482
|
+
ssize_t beg, step;
|
|
1483
|
+
VALUE v;
|
|
1484
|
+
size_t m;
|
|
1485
|
+
VALUE reduce;
|
|
1486
|
+
narray_t *na;
|
|
1487
|
+
|
|
1488
|
+
GetNArray(na_obj,na);
|
|
1489
|
+
ndim = na->ndim;
|
|
1490
|
+
rowmaj = TEST_COLUMN_MAJOR(na_obj);
|
|
1491
|
+
|
|
1492
|
+
m = 0;
|
|
1493
|
+
reduce = Qnil;
|
|
1494
|
+
narg = RARRAY_LEN(axes);
|
|
1495
|
+
for (i=0; i<narg; i++) {
|
|
1496
|
+
v = RARRAY_AREF(axes,i);
|
|
1497
|
+
//printf("argv[%d]=",i);rb_p(v);
|
|
1498
|
+
if (TYPE(v)==T_FIXNUM) {
|
|
1499
|
+
beg = FIX2INT(v);
|
|
1500
|
+
if (beg<0) beg+=ndim;
|
|
1501
|
+
if (beg>=ndim || beg<0) {
|
|
1502
|
+
rb_raise(nary_eDimensionError,"dimension is out of range");
|
|
1503
|
+
}
|
|
1504
|
+
len = 1;
|
|
1505
|
+
step = 0;
|
|
1506
|
+
//printf("beg=%d step=%d len=%d\n",beg,step,len);
|
|
1507
|
+
} else if (rb_obj_is_kind_of(v,rb_cRange) ||
|
|
1508
|
+
rb_obj_is_kind_of(v,na_cStep)) {
|
|
1509
|
+
nary_step_array_index( v, ndim, &len, &beg, &step );
|
|
1510
|
+
} else {
|
|
1511
|
+
rb_raise(nary_eDimensionError, "invalid dimension argument %s",
|
|
1512
|
+
rb_obj_classname(v));
|
|
1513
|
+
}
|
|
1514
|
+
for (j=0; j<len; j++) {
|
|
1515
|
+
r = beg + step*j;
|
|
1516
|
+
if (rowmaj) {
|
|
1517
|
+
r = ndim-1-r;
|
|
1518
|
+
}
|
|
1519
|
+
if (reduce==Qnil) {
|
|
1520
|
+
if ( r < (ssize_t)sizeof(size_t) ) {
|
|
1521
|
+
m |= ((size_t)1) << r;
|
|
1522
|
+
continue;
|
|
1523
|
+
} else {
|
|
1524
|
+
reduce = SIZET2NUM(m);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
v = rb_funcall( INT2FIX(1), id_shift_left, 1, INT2FIX(r) );
|
|
1528
|
+
reduce = rb_funcall( reduce, '|', 1, v );
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
if (NIL_P(reduce)) reduce = SIZET2NUM(m);
|
|
1532
|
+
return reduce;
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
VALUE
|
|
1537
|
+
nary_reduce_options(VALUE axes, VALUE *opts, int naryc, VALUE *naryv,
|
|
1538
|
+
ndfunc_t *ndf)
|
|
1539
|
+
{
|
|
1540
|
+
int max_arg;
|
|
1541
|
+
VALUE reduce;
|
|
1542
|
+
|
|
1543
|
+
// option: axis
|
|
1544
|
+
if (opts[0] != Qundef && RTEST(opts[0])) {
|
|
1545
|
+
if (!NIL_P(axes)) {
|
|
1546
|
+
rb_raise(rb_eArgError,
|
|
1547
|
+
"cannot specify axis-arguments and axis-keyword simultaneously");
|
|
1548
|
+
}
|
|
1549
|
+
if (TYPE(opts[0]) == T_ARRAY) {
|
|
1550
|
+
axes = opts[0];
|
|
1551
|
+
} else {
|
|
1552
|
+
axes = rb_ary_new3(1,opts[0]);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
if (ndf) {
|
|
1556
|
+
// option: keepdims
|
|
1557
|
+
if (opts[1] != Qundef) {
|
|
1558
|
+
if (RTEST(opts[1]))
|
|
1559
|
+
ndf->flag |= NDF_KEEP_DIM;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
reduce = na_get_reduce_flag_from_narray(naryc, naryv, &max_arg);
|
|
1564
|
+
|
|
1565
|
+
if (NIL_P(axes)) return reduce;
|
|
1566
|
+
|
|
1567
|
+
return na_get_reduce_flag_from_axes(naryv[max_arg], axes);
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
|
|
1571
|
+
VALUE
|
|
1572
|
+
nary_reduce_dimension(int argc, VALUE *argv, int naryc, VALUE *naryv,
|
|
1573
|
+
ndfunc_t *ndf, na_iter_func_t iter_nan)
|
|
1574
|
+
{
|
|
1575
|
+
long narg;
|
|
1576
|
+
VALUE axes;
|
|
1577
|
+
VALUE kw_hash = Qnil;
|
|
1578
|
+
ID kw_table[3] = {id_axis,id_keepdims,id_nan};
|
|
1579
|
+
VALUE opts[3] = {Qundef,Qundef,Qundef};
|
|
1580
|
+
|
|
1581
|
+
narg = rb_scan_args(argc, argv, "*:", &axes, &kw_hash);
|
|
1582
|
+
rb_get_kwargs(kw_hash, kw_table, 0, 3, opts);
|
|
1583
|
+
|
|
1584
|
+
if (ndf) {
|
|
1585
|
+
// option: nan
|
|
1586
|
+
if (iter_nan && opts[2] != Qundef) {
|
|
1587
|
+
if (RTEST(opts[2]))
|
|
1588
|
+
ndf->func = iter_nan; // replace to nan-aware iterator function
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
return na_reduce_options((narg)?axes:Qnil, opts, naryc, naryv, ndf);
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
/*
|
|
1596
|
+
Return true if column major.
|
|
1597
|
+
*/
|
|
1598
|
+
static VALUE na_column_major_p( VALUE self )
|
|
1599
|
+
{
|
|
1600
|
+
if (TEST_COLUMN_MAJOR(self))
|
|
1601
|
+
return Qtrue;
|
|
1602
|
+
else
|
|
1603
|
+
return Qfalse;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
/*
|
|
1607
|
+
Return true if row major.
|
|
1608
|
+
*/
|
|
1609
|
+
static VALUE na_row_major_p( VALUE self )
|
|
1610
|
+
{
|
|
1611
|
+
if (TEST_ROW_MAJOR(self))
|
|
1612
|
+
return Qtrue;
|
|
1613
|
+
else
|
|
1614
|
+
return Qfalse;
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
|
|
1618
|
+
/*
|
|
1619
|
+
Return true if byte swapped.
|
|
1620
|
+
*/
|
|
1621
|
+
static VALUE na_byte_swapped_p( VALUE self )
|
|
1622
|
+
{
|
|
1623
|
+
if (TEST_BYTE_SWAPPED(self))
|
|
1624
|
+
return Qtrue;
|
|
1625
|
+
return Qfalse;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
/*
|
|
1629
|
+
Return true if not byte swapped.
|
|
1630
|
+
*/
|
|
1631
|
+
static VALUE na_host_order_p( VALUE self )
|
|
1632
|
+
{
|
|
1633
|
+
if (TEST_BYTE_SWAPPED(self))
|
|
1634
|
+
return Qfalse;
|
|
1635
|
+
return Qtrue;
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
|
|
1639
|
+
/*
|
|
1640
|
+
Returns view of narray with inplace flagged.
|
|
1641
|
+
@return [Cumo::NArray] view of narray with inplace flag.
|
|
1642
|
+
*/
|
|
1643
|
+
static VALUE na_inplace( VALUE self )
|
|
1644
|
+
{
|
|
1645
|
+
VALUE view = self;
|
|
1646
|
+
view = na_make_view(self);
|
|
1647
|
+
SET_INPLACE(view);
|
|
1648
|
+
return view;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/*
|
|
1652
|
+
Set inplace flag to self.
|
|
1653
|
+
@return [Cumo::NArray] self
|
|
1654
|
+
*/
|
|
1655
|
+
static VALUE na_inplace_bang( VALUE self )
|
|
1656
|
+
{
|
|
1657
|
+
SET_INPLACE(self);
|
|
1658
|
+
return self;
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
/*
|
|
1662
|
+
Return true if inplace flagged.
|
|
1663
|
+
*/
|
|
1664
|
+
static VALUE na_inplace_p( VALUE self )
|
|
1665
|
+
{
|
|
1666
|
+
if (TEST_INPLACE(self))
|
|
1667
|
+
return Qtrue;
|
|
1668
|
+
else
|
|
1669
|
+
return Qfalse;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
/*
|
|
1673
|
+
Unset inplace flag to self.
|
|
1674
|
+
@return [Cumo::NArray] self
|
|
1675
|
+
*/
|
|
1676
|
+
static VALUE na_out_of_place_bang( VALUE self )
|
|
1677
|
+
{
|
|
1678
|
+
UNSET_INPLACE(self);
|
|
1679
|
+
return self;
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
int na_debug_flag=0;
|
|
1683
|
+
|
|
1684
|
+
static VALUE na_debug_set(VALUE mod, VALUE flag)
|
|
1685
|
+
{
|
|
1686
|
+
na_debug_flag = RTEST(flag);
|
|
1687
|
+
return Qnil;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
static double na_profile_value=0;
|
|
1691
|
+
|
|
1692
|
+
static VALUE na_profile(VALUE mod)
|
|
1693
|
+
{
|
|
1694
|
+
return rb_float_new(na_profile_value);
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
static VALUE na_profile_set(VALUE mod, VALUE val)
|
|
1698
|
+
{
|
|
1699
|
+
na_profile_value = NUM2DBL(val);
|
|
1700
|
+
return val;
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
/*
|
|
1705
|
+
Returns the number of rows used for NArray#inspect
|
|
1706
|
+
@overload inspect_rows
|
|
1707
|
+
@return [Integer or nil] the number of rows.
|
|
1708
|
+
*/
|
|
1709
|
+
static VALUE na_inspect_rows(VALUE mod)
|
|
1710
|
+
{
|
|
1711
|
+
if (cumo_na_inspect_rows > 0) {
|
|
1712
|
+
return INT2NUM(cumo_na_inspect_rows);
|
|
1713
|
+
} else {
|
|
1714
|
+
return Qnil;
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
/*
|
|
1719
|
+
Set the number of rows used for NArray#inspect
|
|
1720
|
+
@overload inspect_rows=(rows)
|
|
1721
|
+
@param [Integer or nil] rows the number of rows
|
|
1722
|
+
@return [nil]
|
|
1723
|
+
*/
|
|
1724
|
+
static VALUE na_inspect_rows_set(VALUE mod, VALUE num)
|
|
1725
|
+
{
|
|
1726
|
+
if (RTEST(num)) {
|
|
1727
|
+
cumo_na_inspect_rows = NUM2INT(num);
|
|
1728
|
+
} else {
|
|
1729
|
+
cumo_na_inspect_rows = 0;
|
|
1730
|
+
}
|
|
1731
|
+
return Qnil;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
/*
|
|
1735
|
+
Returns the number of cols used for NArray#inspect
|
|
1736
|
+
@overload inspect_cols
|
|
1737
|
+
@return [Integer or nil] the number of cols.
|
|
1738
|
+
*/
|
|
1739
|
+
static VALUE na_inspect_cols(VALUE mod)
|
|
1740
|
+
{
|
|
1741
|
+
if (cumo_na_inspect_cols > 0) {
|
|
1742
|
+
return INT2NUM(cumo_na_inspect_cols);
|
|
1743
|
+
} else {
|
|
1744
|
+
return Qnil;
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1748
|
+
/*
|
|
1749
|
+
Set the number of cols used for NArray#inspect
|
|
1750
|
+
@overload inspect_cols=(cols)
|
|
1751
|
+
@param [Integer or nil] cols the number of cols
|
|
1752
|
+
@return [nil]
|
|
1753
|
+
*/
|
|
1754
|
+
static VALUE na_inspect_cols_set(VALUE mod, VALUE num)
|
|
1755
|
+
{
|
|
1756
|
+
if (RTEST(num)) {
|
|
1757
|
+
cumo_na_inspect_cols = NUM2INT(num);
|
|
1758
|
+
} else {
|
|
1759
|
+
cumo_na_inspect_cols = 0;
|
|
1760
|
+
}
|
|
1761
|
+
return Qnil;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
|
|
1765
|
+
/*
|
|
1766
|
+
Equality of self and other in view of numerical array.
|
|
1767
|
+
i.e., both arrays have same shape and corresponding elements are equal.
|
|
1768
|
+
@overload == other
|
|
1769
|
+
@param [Object] other
|
|
1770
|
+
@return [Boolean] true if self and other is equal.
|
|
1771
|
+
*/
|
|
1772
|
+
static VALUE
|
|
1773
|
+
na_equal(VALUE self, volatile VALUE other)
|
|
1774
|
+
{
|
|
1775
|
+
volatile VALUE vbool;
|
|
1776
|
+
narray_t *na1, *na2;
|
|
1777
|
+
int i;
|
|
1778
|
+
|
|
1779
|
+
GetNArray(self,na1);
|
|
1780
|
+
|
|
1781
|
+
if (!rb_obj_is_kind_of(other,cNArray)) {
|
|
1782
|
+
other = rb_funcall(CLASS_OF(self), id_cast, 1, other);
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
GetNArray(other,na2);
|
|
1786
|
+
if (na1->ndim != na2->ndim) {
|
|
1787
|
+
return Qfalse;
|
|
1788
|
+
}
|
|
1789
|
+
for (i=0; i<na1->ndim; i++) {
|
|
1790
|
+
if (na1->shape[i] != na2->shape[i]) {
|
|
1791
|
+
return Qfalse;
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
vbool = rb_funcall(self, id_eq, 1, other);
|
|
1795
|
+
return (rb_funcall(vbool, id_count_false_cpu, 0)==INT2FIX(0)) ? Qtrue : Qfalse;
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
/*
|
|
1799
|
+
Free data memory explicitly without waiting GC.
|
|
1800
|
+
|
|
1801
|
+
@return [Boolean] true if free
|
|
1802
|
+
*/
|
|
1803
|
+
VALUE
|
|
1804
|
+
cumo_na_free_data(VALUE self)
|
|
1805
|
+
{
|
|
1806
|
+
narray_t *na;
|
|
1807
|
+
GetNArray(self, na);
|
|
1808
|
+
|
|
1809
|
+
if (na->type == NARRAY_DATA_T) {
|
|
1810
|
+
void *ptr = NA_DATA_PTR(na);
|
|
1811
|
+
if (ptr != NULL) {
|
|
1812
|
+
if (cumo_cuda_runtime_is_device_memory(ptr)) {
|
|
1813
|
+
cumo_cuda_runtime_free(ptr);
|
|
1814
|
+
} else {
|
|
1815
|
+
xfree(ptr);
|
|
1816
|
+
}
|
|
1817
|
+
NA_DATA_PTR(na) = NULL;
|
|
1818
|
+
return Qtrue;
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
return Qfalse;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
/* initialization of NArray Class */
|
|
1826
|
+
void
|
|
1827
|
+
Init_cumo_narray()
|
|
1828
|
+
{
|
|
1829
|
+
mCumo = rb_define_module("Cumo");
|
|
1830
|
+
|
|
1831
|
+
/*
|
|
1832
|
+
Document-class: Cumo::NArray
|
|
1833
|
+
|
|
1834
|
+
Cumo::NArray is the abstract super class for
|
|
1835
|
+
Numerical N-dimensional Array in the Ruby/Cumo module.
|
|
1836
|
+
Use Typed Subclasses of NArray (Cumo::DFloat, Int32, etc)
|
|
1837
|
+
to create data array instances.
|
|
1838
|
+
*/
|
|
1839
|
+
cNArray = rb_define_class_under(mCumo, "NArray", rb_cObject);
|
|
1840
|
+
|
|
1841
|
+
#ifndef HAVE_RB_CCOMPLEX
|
|
1842
|
+
rb_require("complex");
|
|
1843
|
+
rb_cComplex = rb_const_get(rb_cObject, rb_intern("Complex"));
|
|
1844
|
+
#endif
|
|
1845
|
+
|
|
1846
|
+
rb_define_const(cNArray, "VERSION", rb_str_new2(CUMO_VERSION));
|
|
1847
|
+
|
|
1848
|
+
nary_eCastError = rb_define_class_under(cNArray, "CastError", rb_eStandardError);
|
|
1849
|
+
nary_eShapeError = rb_define_class_under(cNArray, "ShapeError", rb_eStandardError);
|
|
1850
|
+
nary_eOperationError = rb_define_class_under(cNArray, "OperationError", rb_eStandardError);
|
|
1851
|
+
nary_eDimensionError = rb_define_class_under(cNArray, "DimensionError", rb_eStandardError);
|
|
1852
|
+
nary_eValueError = rb_define_class_under(cNArray, "ValueError", rb_eStandardError);
|
|
1853
|
+
|
|
1854
|
+
rb_define_singleton_method(cNArray, "debug=", na_debug_set, 1);
|
|
1855
|
+
rb_define_singleton_method(cNArray, "profile", na_profile, 0);
|
|
1856
|
+
rb_define_singleton_method(cNArray, "profile=", na_profile_set, 1);
|
|
1857
|
+
|
|
1858
|
+
rb_define_singleton_method(cNArray, "inspect_rows", na_inspect_rows, 0);
|
|
1859
|
+
rb_define_singleton_method(cNArray, "inspect_rows=", na_inspect_rows_set, 1);
|
|
1860
|
+
rb_define_singleton_method(cNArray, "inspect_cols", na_inspect_cols, 0);
|
|
1861
|
+
rb_define_singleton_method(cNArray, "inspect_cols=", na_inspect_cols_set, 1);
|
|
1862
|
+
|
|
1863
|
+
/* Ruby allocation framework */
|
|
1864
|
+
rb_undef_alloc_func(cNArray);
|
|
1865
|
+
rb_define_method(cNArray, "initialize", na_initialize, -2);
|
|
1866
|
+
rb_define_method(cNArray, "initialize_copy", na_initialize_copy, 1);
|
|
1867
|
+
|
|
1868
|
+
rb_define_method(cNArray, "free", cumo_na_free_data, 0);
|
|
1869
|
+
|
|
1870
|
+
rb_define_singleton_method(cNArray, "zeros", na_s_zeros, -1);
|
|
1871
|
+
rb_define_singleton_method(cNArray, "ones", na_s_ones, -1);
|
|
1872
|
+
rb_define_singleton_method(cNArray, "linspace", na_s_linspace, -1);
|
|
1873
|
+
rb_define_singleton_method(cNArray, "logspace", na_s_logspace, -1);
|
|
1874
|
+
rb_define_singleton_method(cNArray, "eye", na_s_eye, -1);
|
|
1875
|
+
|
|
1876
|
+
rb_define_method(cNArray, "size", na_size, 0);
|
|
1877
|
+
rb_define_alias (cNArray, "length","size");
|
|
1878
|
+
rb_define_alias (cNArray, "total","size");
|
|
1879
|
+
rb_define_method(cNArray, "shape", na_shape, 0);
|
|
1880
|
+
rb_define_method(cNArray, "ndim", na_ndim,0);
|
|
1881
|
+
rb_define_alias (cNArray, "rank","ndim");
|
|
1882
|
+
rb_define_method(cNArray, "empty?", na_empty_p, 0);
|
|
1883
|
+
|
|
1884
|
+
rb_define_method(cNArray, "debug_info", nary_debug_info, 0);
|
|
1885
|
+
|
|
1886
|
+
rb_define_method(cNArray, "contiguous?", na_check_contiguous, 0);
|
|
1887
|
+
|
|
1888
|
+
rb_define_method(cNArray, "view", na_make_view, 0);
|
|
1889
|
+
rb_define_method(cNArray, "expand_dims", na_expand_dims, 1);
|
|
1890
|
+
rb_define_method(cNArray, "reverse", nary_reverse, -1);
|
|
1891
|
+
|
|
1892
|
+
rb_define_singleton_method(cNArray, "upcast", cumo_na_upcast, 1);
|
|
1893
|
+
rb_define_singleton_method(cNArray, "byte_size", nary_s_byte_size, 0);
|
|
1894
|
+
|
|
1895
|
+
rb_define_singleton_method(cNArray, "from_binary", nary_s_from_binary, -1);
|
|
1896
|
+
rb_define_alias (rb_singleton_class(cNArray), "from_string", "from_binary");
|
|
1897
|
+
rb_define_method(cNArray, "store_binary", nary_store_binary, -1);
|
|
1898
|
+
rb_define_method(cNArray, "to_binary", nary_to_binary, 0);
|
|
1899
|
+
rb_define_alias (cNArray, "to_string", "to_binary");
|
|
1900
|
+
rb_define_method(cNArray, "marshal_dump", nary_marshal_dump, 0);
|
|
1901
|
+
rb_define_method(cNArray, "marshal_load", nary_marshal_load, 1);
|
|
1902
|
+
|
|
1903
|
+
rb_define_method(cNArray, "byte_size", nary_byte_size, 0);
|
|
1904
|
+
|
|
1905
|
+
rb_define_method(cNArray, "cast_to", nary_cast_to, 1);
|
|
1906
|
+
|
|
1907
|
+
rb_define_method(cNArray, "coerce", nary_coerce, 1);
|
|
1908
|
+
|
|
1909
|
+
rb_define_method(cNArray, "column_major?", na_column_major_p, 0);
|
|
1910
|
+
rb_define_method(cNArray, "row_major?", na_row_major_p, 0);
|
|
1911
|
+
rb_define_method(cNArray, "byte_swapped?", na_byte_swapped_p, 0);
|
|
1912
|
+
rb_define_method(cNArray, "host_order?", na_host_order_p, 0);
|
|
1913
|
+
|
|
1914
|
+
rb_define_method(cNArray, "inplace", na_inplace, 0);
|
|
1915
|
+
rb_define_method(cNArray, "inplace?", na_inplace_p, 0);
|
|
1916
|
+
rb_define_method(cNArray, "inplace!", na_inplace_bang, 0);
|
|
1917
|
+
rb_define_method(cNArray, "out_of_place!", na_out_of_place_bang, 0);
|
|
1918
|
+
rb_define_alias (cNArray, "not_inplace!", "out_of_place!");
|
|
1919
|
+
|
|
1920
|
+
rb_define_method(cNArray, "==", na_equal, 1);
|
|
1921
|
+
|
|
1922
|
+
id_allocate = rb_intern("allocate");
|
|
1923
|
+
id_contiguous_stride = rb_intern(CONTIGUOUS_STRIDE);
|
|
1924
|
+
//id_element_bit_size = rb_intern(ELEMENT_BIT_SIZE);
|
|
1925
|
+
id_element_byte_size = rb_intern(ELEMENT_BYTE_SIZE);
|
|
1926
|
+
|
|
1927
|
+
id_fill = rb_intern("fill");
|
|
1928
|
+
id_seq = rb_intern("seq");
|
|
1929
|
+
id_logseq = rb_intern("logseq");
|
|
1930
|
+
id_eye = rb_intern("eye");
|
|
1931
|
+
id_UPCAST = rb_intern("UPCAST");
|
|
1932
|
+
id_cast = rb_intern("cast");
|
|
1933
|
+
id_dup = rb_intern("dup");
|
|
1934
|
+
id_to_host = rb_intern("to_host");
|
|
1935
|
+
id_bracket = rb_intern("[]");
|
|
1936
|
+
id_shift_left = rb_intern("<<");
|
|
1937
|
+
id_eq = rb_intern("eq");
|
|
1938
|
+
id_count_false = rb_intern("count_false");
|
|
1939
|
+
id_count_false_cpu = rb_intern("count_false_cpu");
|
|
1940
|
+
id_axis = rb_intern("axis");
|
|
1941
|
+
id_nan = rb_intern("nan");
|
|
1942
|
+
id_keepdims = rb_intern("keepdims");
|
|
1943
|
+
|
|
1944
|
+
sym_reduce = ID2SYM(rb_intern("reduce"));
|
|
1945
|
+
sym_option = ID2SYM(rb_intern("option"));
|
|
1946
|
+
sym_loop_opt = ID2SYM(rb_intern("loop_opt"));
|
|
1947
|
+
sym_init = ID2SYM(rb_intern("init"));
|
|
1948
|
+
}
|