cumo 0.5.3 → 0.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ea033fff4a77a42e911f54418e264dd3467372c41ffebcfb693e45b3f5f6faf
4
- data.tar.gz: 7cdc86588d27d4819aaba0b994ed178f9d028cc4441c557c1b403a9570b56b0e
3
+ metadata.gz: 0aea399ff1a36438f62f47a0a1c0350366971c34000343eb20376e8d3d448297
4
+ data.tar.gz: 8f8f8fab9df42cf544131dc38ac2a9ff9c2eda218a3be11eb2a887c26e86fac1
5
5
  SHA512:
6
- metadata.gz: f2ed5c87fcee89596b0ed404169fe82ad514da4cdcb23b3e8b200415d2fe1092d450c88e8a7f109c7ff786b58ffe2a52b12485eb7d0e2844e28fcc18d2303c0c
7
- data.tar.gz: 215bbcab440ff133bd13aa9e4f133cddb8da783003dccddfd8546e072adf49a6d68d93ecd9f97221aca4f09348eaf5b5657437f614d94e0c0fc15dbcf924ded9
6
+ metadata.gz: d57caea8974f8d7c8be8d62c0c5d52004bb414092e178459d29a5e5d3566999ce03899a5cdd82d5b3cdc0d4b690f4c1e9991cdeb40ec8a7eec5f6bd33157ec7b
7
+ data.tar.gz: 7cb0cd15e20c826806209ed91279694f41cc17f54aade1043ed3defd62fc9a9bdccadc0bc9345d1f802302399b915adc7fac1c2059bded270991644babce6d1a
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "English"
3
4
  require "mkmf"
4
5
  require "open3"
5
6
  require_relative "nvcc"
@@ -28,8 +29,10 @@ module MakeMakefileCuda
28
29
  # private
29
30
 
30
31
  def run_command!(*args)
31
- puts colorize(:green, args.join(' '))
32
- exit system(*args)
32
+ command = args.join(' ')
33
+ puts colorize(:green, command)
34
+ system(command)
35
+ exit($CHILD_STATUS.exitstatus)
33
36
  end
34
37
 
35
38
  # TODO(sonots): Make it possible to configure "nvcc" and additional arguments
@@ -114,7 +114,7 @@ module MakeMakefileCuda
114
114
  if opt_h["--mkmf-cu-ext"][0] == "c"
115
115
  " --compiler-bindir " + ENV.fetch("NVCC_CCBIN", RbConfig::CONFIG["CC"])
116
116
  elsif opt_h["--mkmf-cu-ext"][0] == "cxx"
117
- " --compiler-bindir " + ENV.fetch("NVCC_CCBIN", RbConfig::CONFIG["CXX"])
117
+ " --compiler-bindir " + ENV.fetch("NVCC_CCBIN", RbConfig::CONFIG["CXX"]).split.first
118
118
  end
119
119
  end
120
120
 
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ # 0.5.4 (2026/05/30)
2
+
3
+ Fixes:
4
+
5
+ * Backport: Fix to use rb_funcallv_kw in Ruby 2.7 and later
6
+ * Backport: define id_pow as "**" for all types except Bit
7
+ * Backport: define id_minus as "-@" for RObject
8
+ * Backport: duplicated id_eq and id_ne for RObject
9
+ * Backport: follow the change of INIT_PTR_BIT_IDX
10
+ * Backport: add test for empty bit array
11
+ * Backport: fix NArray::Bit#count_true/false: empty array should return zero
12
+ * Fix backport error
13
+ * Backport: minor fixes
14
+ * Backport: fix RObject#sum,prod
15
+ * Backport: NArray#from_binary: allow zero dimension
16
+ * Backport: Added test cases
17
+ * Backport: fix NArray#store: drop automatic 'to_a' conversion
18
+ * Backport: Numo::NArray.cast tries to convert to Array when it has to_a method
19
+ * Backport: use rb_respond_to()
20
+ * Backport: improve discrimination between int32/64
21
+ * Backport: missing declaration of id_ge
22
+ * Backport: support casting any object that responds to 'to_a'
23
+ * Backport: fix the range of int32 as -2**31 .. 2**31-1
24
+ * Backport: if int32_max is Bignum, it should be protected from GC
25
+ * fix: handle compiler flags included in RbConfig::CONFIG properly (#157)
26
+ * Backport: Added more percentile tests
27
+ * Backport: Use File.write in cogen to ensure file is closed
28
+ * Backport: Added percentile method
29
+ * Backport: Use INT2FIX to define m_data_to_num for 8 or 16-bit Int.
30
+ * Backport: raise error if compiler does not support 8 or 4-byte integer
31
+
1
32
  # 0.5.3 (2026/04/26)
2
33
 
3
34
  Fixes:
@@ -99,6 +99,8 @@ extern "C" {
99
99
  # ifndef PRIu64
100
100
  # define PRIu64 "llu"
101
101
  # endif
102
+ #else
103
+ # error ---->> numo/narray requires 8-byte integer. <<----
102
104
  #endif
103
105
 
104
106
  #if SIZEOF_LONG==4
@@ -139,6 +141,8 @@ extern "C" {
139
141
  # ifndef PRIu32
140
142
  # define PRIu32 "u"
141
143
  # endif
144
+ #else
145
+ # error ---->> numo/narray requires 4-byte integer. <<----
142
146
  #endif
143
147
 
144
148
  #if SIZEOF_LONG > 4
@@ -4,8 +4,11 @@ typedef int16_t rtype;
4
4
  #define cRT cT
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2INT(x))
7
- #define m_data_to_num(x) INT2NUM((int)(x))
8
- #define m_extract(x) INT2NUM((int)*(dtype*)(x))
7
+ #if SIZEOF_INT > 2
8
+ #define m_data_to_num(x) INT2FIX(x)
9
+ #else
10
+ #define m_data_to_num(x) INT2NUM(x)
11
+ #endif
9
12
  #define m_sprintf(s,x) sprintf(s,"%d",(int)(x))
10
13
 
11
14
  #ifndef INT16_MIN
@@ -5,7 +5,6 @@ typedef int32_t rtype;
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2INT32(x))
7
7
  #define m_data_to_num(x) INT322NUM((int32_t)(x))
8
- #define m_extract(x) INT322NUM((int32_t)*(dtype*)(x))
9
8
  #define m_sprintf(s,x) sprintf(s,"%"PRId32,(int32_t)(x))
10
9
 
11
10
  #ifndef INT32_MIN
@@ -5,7 +5,6 @@ typedef int64_t rtype;
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2INT64(x))
7
7
  #define m_data_to_num(x) INT642NUM((int64_t)(x))
8
- #define m_extract(x) INT642NUM((int64_t)*(dtype*)(x))
9
8
  #define m_sprintf(s,x) sprintf(s,"%"PRId64,(int64_t)(x))
10
9
 
11
10
  #ifndef INT64_MIN
@@ -4,8 +4,7 @@ typedef int8_t rtype;
4
4
  #define cRT cT
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2INT(x))
7
- #define m_data_to_num(x) INT2NUM((int)(x))
8
- #define m_extract(x) INT2NUM((int)*(dtype*)(x))
7
+ #define m_data_to_num(x) INT2FIX(x)
9
8
  #define m_sprintf(s,x) sprintf(s,"%d",(int)(x))
10
9
 
11
10
  #ifndef INT8_MIN
@@ -4,8 +4,11 @@ typedef u_int16_t rtype;
4
4
  #define cRT cT
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2UINT(x))
7
- #define m_data_to_num(x) UINT2NUM((unsigned int)(x))
8
- #define m_extract(x) UINT2NUM((unsigned int)*(dtype*)(x))
7
+ #if SIZEOF_INT > 2
8
+ #define m_data_to_num(x) INT2FIX(x)
9
+ #else
10
+ #define m_data_to_num(x) UINT2NUM(x)
11
+ #endif
9
12
  #define m_sprintf(s,x) sprintf(s,"%u",(unsigned int)(x))
10
13
 
11
14
  #ifndef UINT16_MIN
@@ -5,7 +5,6 @@ typedef u_int32_t rtype;
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2UINT32(x))
7
7
  #define m_data_to_num(x) UINT322NUM((u_int32_t)(x))
8
- #define m_extract(x) UINT322NUM((u_int32_t)*(dtype*)(x))
9
8
  #define m_sprintf(s,x) sprintf(s,"%"PRIu32,(u_int32_t)(x))
10
9
 
11
10
  #ifndef UINT32_MIN
@@ -5,7 +5,6 @@ typedef u_int64_t rtype;
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2UINT64(x))
7
7
  #define m_data_to_num(x) UINT642NUM((u_int64_t)(x))
8
- #define m_extract(x) UINT642NUM((u_int64_t)*(dtype*)(x))
9
8
  #define m_sprintf(s,x) sprintf(s,"%"PRIu64,(u_int64_t)(x))
10
9
 
11
10
  #ifndef UINT64_MIN
@@ -4,8 +4,7 @@ typedef u_int8_t rtype;
4
4
  #define cRT cT
5
5
 
6
6
  #define m_num_to_data(x) ((dtype)NUM2UINT(x))
7
- #define m_data_to_num(x) UINT2NUM((unsigned int)(x))
8
- #define m_extract(x) UINT2NUM((unsigned int)*(dtype*)(x))
7
+ #define m_data_to_num(x) INT2FIX(x)
9
8
  #define m_sprintf(s,x) sprintf(s,"%u",(unsigned int)(x))
10
9
 
11
10
  #ifndef UINT8_MIN
@@ -1,6 +1,8 @@
1
1
  #define m_zero 0
2
2
  #define m_one 1
3
3
 
4
+ #define m_extract(x) m_data_to_num(*(dtype*)(x))
5
+
4
6
  /* Handle negative values consistently across platforms for unsigned integer types */
5
7
  #define m_from_double(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
6
8
  #define m_from_real(x) ((x) < 0 ? (dtype)((long long)(x)) : (dtype)(x))
@@ -10,7 +10,7 @@ extern "C" {
10
10
  #endif
11
11
  #endif
12
12
 
13
- #define CUMO_VERSION "0.5.3"
13
+ #define CUMO_VERSION "0.5.4"
14
14
  #define CUMO_VERSION_CODE 51
15
15
 
16
16
  bool cumo_compatible_mode_enabled_p();
@@ -25,16 +25,16 @@ static ID cumo_id_step;
25
25
  static ID cumo_id_abs;
26
26
  static ID cumo_id_cast;
27
27
  static ID cumo_id_le;
28
+ #if SIZEOF_LONG <= 4
29
+ static ID cumo_id_ge;
30
+ #endif
28
31
  static ID cumo_id_Complex;
29
-
32
+ static VALUE cumo_int32_max = Qnil;
33
+ static VALUE cumo_int32_min = Qnil;
30
34
 
31
35
  static VALUE
32
36
  cumo_na_object_type(int type, VALUE v)
33
37
  {
34
- static VALUE int32_max = Qnil;
35
- if (NIL_P(int32_max))
36
- int32_max = ULONG2NUM(2147483647);
37
-
38
38
  switch(TYPE(v)) {
39
39
 
40
40
  case T_TRUE:
@@ -43,15 +43,15 @@ static VALUE
43
43
  return CUMO_NA_BIT;
44
44
  return type;
45
45
 
46
- #if SIZEOF_LONG == 4
46
+ #if SIZEOF_LONG <= 4
47
47
  case T_FIXNUM:
48
48
  if (type<CUMO_NA_INT32)
49
49
  return CUMO_NA_INT32;
50
50
  return type;
51
51
  case T_BIGNUM:
52
52
  if (type<CUMO_NA_INT64) {
53
- v = rb_funcall(v,cumo_id_abs,0);
54
- if (RTEST(rb_funcall(v,cumo_id_le,1,int32_max))) {
53
+ if (RTEST(rb_funcall(v,cumo_id_le,1,int32_max)) &&
54
+ RTEST(rb_funcall(v,cumo_id_ge,1,int32_min))) {
55
55
  if (type<CUMO_NA_INT32)
56
56
  return CUMO_NA_INT32;
57
57
  } else {
@@ -59,13 +59,12 @@ static VALUE
59
59
  }
60
60
  }
61
61
  return type;
62
-
63
- #elif SIZEOF_LONG == 8
62
+ #else
64
63
  case T_FIXNUM:
65
64
  if (type<CUMO_NA_INT64) {
66
65
  long x = NUM2LONG(v);
67
66
  if (x<0) x=-x;
68
- if (x<=2147483647) {
67
+ if (x<=2147483647L && x>=-2147483648L) {
69
68
  if (type<CUMO_NA_INT32)
70
69
  return CUMO_NA_INT32;
71
70
  } else {
@@ -77,19 +76,6 @@ static VALUE
77
76
  if (type<CUMO_NA_INT64)
78
77
  return CUMO_NA_INT64;
79
78
  return type;
80
- #else
81
- case T_FIXNUM:
82
- case T_BIGNUM:
83
- if (type<CUMO_NA_INT64) {
84
- v = rb_funcall(v,cumo_id_abs,0);
85
- if (RTEST(rb_funcall(v,cumo_id_le,1,int32_max))) {
86
- if (type<CUMO_NA_INT32)
87
- return CUMO_NA_INT32;
88
- } else {
89
- return CUMO_NA_INT64;
90
- }
91
- }
92
- return type;
93
79
  #endif
94
80
 
95
81
  case T_FLOAT:
@@ -642,5 +628,13 @@ Init_cumo_na_array(void)
642
628
  cumo_id_cast = rb_intern("cast");
643
629
  cumo_id_abs = rb_intern("abs");
644
630
  cumo_id_le = rb_intern("<=");
631
+ #if SIZEOF_LONG <= 4
632
+ cumo_id_ge = rb_intern(">=");
633
+ #endif
645
634
  cumo_id_Complex = rb_intern("Complex");
635
+
636
+ rb_global_variable(&cumo_int32_max);
637
+ cumo_int32_max = INT2NUM(2147483647);
638
+ rb_global_variable(&cumo_int32_min);
639
+ cumo_int32_min = INT2NUM(-2147483648);
646
640
  }
@@ -5,9 +5,7 @@
5
5
  #include "cumo/narray.h"
6
6
  #include "cumo/template.h"
7
7
 
8
- static VALUE cumo_sym_mulsum;
9
8
  static ID cumo_id_mulsum;
10
- static ID cumo_id_respond_to_p;
11
9
  static ID cumo_id_store;
12
10
  static ID cumo_id_swap_byte;
13
11
 
@@ -932,12 +930,10 @@ cumo_na_new_dimension_for_dot(VALUE self, int pos, int len, bool transpose)
932
930
  static VALUE
933
931
  cumo_na_dot(VALUE self, VALUE other)
934
932
  {
935
- VALUE test;
936
933
  volatile VALUE a1=self, a2=other;
937
934
  cumo_narray_t *na1, *na2;
938
935
 
939
- test = rb_funcall(a1, cumo_id_respond_to_p, 1, cumo_sym_mulsum);
940
- if (!RTEST(test)) {
936
+ if (!rb_respond_to(a1, cumo_id_mulsum)) {
941
937
  rb_raise(rb_eNoMethodError,"requires mulsum method for dot method");
942
938
  }
943
939
  CumoGetNArray(a1,na1);
@@ -994,8 +990,6 @@ Init_cumo_na_data(void)
994
990
  //rb_define_method(cNArray, "dot", cumo_na_dot, 1);
995
991
 
996
992
  cumo_id_mulsum = rb_intern("mulsum");
997
- cumo_sym_mulsum = ID2SYM(cumo_id_mulsum);
998
- cumo_id_respond_to_p = rb_intern("respond_to?");
999
993
  cumo_id_store = rb_intern("store");
1000
994
  cumo_id_swap_byte = rb_intern("swap_byte");
1001
995
  }
@@ -54,7 +54,7 @@ code = DefLib.new do
54
54
  end.result
55
55
 
56
56
  if $output
57
- open($output, "w").write(code)
57
+ File.write($output, code)
58
58
  else
59
59
  $stdout.write(code)
60
60
  end
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  def_id "cast"
4
- def_id "eq"
5
- def_id "ne"
6
- def_id "pow"
7
4
  def_id "mulsum"
5
+ def_id "to_a"
8
6
  if is_complex
9
7
  def_id "real"
10
8
  def_id "imag"
@@ -34,7 +32,6 @@ if is_object
34
32
  def_id "bit_xor"
35
33
  def_id "bit_not"
36
34
  def_id "abs"
37
- def_id "minus"
38
35
  def_id "reciprocal"
39
36
  def_id "square"
40
37
  def_id "floor"
@@ -44,6 +41,7 @@ if is_object
44
41
  def_id "nan?"
45
42
  def_id "infinite?"
46
43
  def_id "finite?"
44
+ def_id "-@", "minus"
47
45
  def_id "==", "eq"
48
46
  def_id "!=", "ne"
49
47
  def_id ">" , "gt"
@@ -51,6 +49,9 @@ if is_object
51
49
  def_id "<" , "lt"
52
50
  def_id "<=", "le"
53
51
  def_id "<=>", "ufo"
52
+ else
53
+ def_id "eq"
54
+ def_id "ne"
54
55
  end
55
56
  if (is_float || is_complex) && !is_object
56
57
  def_id "gemm"
@@ -203,7 +204,12 @@ if !is_complex
203
204
  binary2 "divmod"
204
205
  end
205
206
 
206
- pow
207
+
208
+ if !is_bit
209
+ pow
210
+ def_id "**","pow"
211
+ def_alias "pow","**"
212
+ end
207
213
 
208
214
  unary "minus", "-@"
209
215
  unary "reciprocal"
@@ -297,7 +303,7 @@ if is_float
297
303
  cond_unary "isfinite"
298
304
  end
299
305
 
300
- if is_int
306
+ if is_int && !is_object
301
307
  if is_unsigned
302
308
  accum "sum", "u_int64_t", "cumo_cUInt64"
303
309
  accum "prod", "u_int64_t", "cumo_cUInt64"
@@ -115,7 +115,11 @@ static VALUE
115
115
  return <%=c_func%>_self(argc, argv, self);
116
116
  } else {
117
117
  v = rb_funcall(klass, cumo_id_cast, 1, self);
118
+ //<% if Gem::Version.create(RUBY_VERSION) < Gem::Version.create('2.7.0') %>
118
119
  return rb_funcall2(v, rb_intern("<%=name%>"), argc, argv);
120
+ //<% else %>
121
+ return rb_funcallv_kw(v, rb_intern("<%=name%>"), argc, argv, RB_PASS_CALLED_KEYWORDS);
122
+ //<% end %>
119
123
  }
120
124
  //<% end %>
121
125
  }
@@ -35,6 +35,13 @@ static VALUE
35
35
  }
36
36
  return v;
37
37
  }
38
+ if (rb_respond_to(obj,cumo_id_to_a)) {
39
+ obj = rb_funcall(obj,cumo_id_to_a,0);
40
+ if (TYPE(obj)!=T_ARRAY) {
41
+ rb_raise(rb_eTypeError, "`to_a' did not return Array");
42
+ }
43
+ return <%=find_tmpl("cast_array").c_func%>(obj);
44
+ }
38
45
  <% if is_object %>
39
46
  return robject_new_dim0(obj);
40
47
  <% else %>
@@ -25,6 +25,12 @@ static void
25
25
  CUMO_STORE_BIT_STEP(a3, p3, s3, idx3, x);
26
26
  }
27
27
  } else {
28
+ a1 += p1/CUMO_NB;
29
+ p1 %= CUMO_NB;
30
+ a2 += p2/CUMO_NB;
31
+ p2 %= CUMO_NB;
32
+ a3 += p3/CUMO_NB;
33
+ p3 %= CUMO_NB;
28
34
  o1 = p1-p3;
29
35
  o2 = p2-p3;
30
36
  l1 = CUMO_NB+o1;
@@ -78,10 +78,16 @@ static VALUE
78
78
  <%=c_func(-1)%>(int argc, VALUE *argv, VALUE self)
79
79
  {
80
80
  VALUE v, reduce;
81
+ cumo_narray_t *na;
82
+
81
83
  cumo_ndfunc_arg_in_t ain[3] = {{cT,0},{cumo_sym_reduce,0},{cumo_sym_init,0}};
82
84
  cumo_ndfunc_arg_out_t aout[1] = {{cumo_cInt64,0}};
83
85
  cumo_ndfunc_t ndf = { <%=c_iter%>, CUMO_FULL_LOOP_NIP, 3, 1, ain, aout };
84
86
 
87
+ CumoGetNArray(self,na);
88
+ if (CUMO_NA_SIZE(na)==0) {
89
+ return INT2FIX(0);
90
+ }
85
91
  reduce = cumo_na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
86
92
  v = cumo_na_ndloop(&ndf, 3, self, reduce, INT2FIX(0));
87
93
  return rb_funcall(v,rb_intern("extract_cpu"),0);
@@ -118,7 +118,7 @@ static VALUE
118
118
 
119
119
  CumoGetNArray(self,na);
120
120
  if (CUMO_NA_SIZE(na)==0) {
121
- return INT2FIX(0);
121
+ return Qfalse;
122
122
  }
123
123
  reduce = cumo_na_reduce_dimension(argc, argv, 1, &self, &ndf, 0);
124
124
  v = cumo_na_ndloop(&ndf, 3, self, reduce, INT2FIX(<%=init_bit%>));
@@ -1,8 +1,9 @@
1
+ #include <stdio.h>
1
2
  static void
2
3
  <%=c_iter%>(cumo_na_loop_t *const lp)
3
4
  {
4
5
  size_t n;
5
- size_t p1, p3;
6
+ ssize_t p1, p3;
6
7
  ssize_t s1, s3;
7
8
  size_t *idx1, *idx3;
8
9
  int o1, l1, r1, len;
@@ -22,6 +23,10 @@ static void
22
23
  CUMO_STORE_BIT_STEP(a3, p3, s3, idx3, x);
23
24
  }
24
25
  } else {
26
+ a1 += p1/CUMO_NB;
27
+ p1 %= CUMO_NB;
28
+ a3 += p3/CUMO_NB;
29
+ p3 %= CUMO_NB;
25
30
  o1 = p1-p3;
26
31
  l1 = CUMO_NB+o1;
27
32
  r1 = CUMO_NB-o1;
@@ -30,7 +35,7 @@ static void
30
35
  if ((int)n<len) len=n;
31
36
  if (o1>=0) x = *a1>>o1;
32
37
  else x = *a1<<-o1;
33
- if (p1+len>CUMO_NB) x |= *(a1+1)<<r1;
38
+ if (p1+len>(ssize_t)CUMO_NB) x |= *(a1+1)<<r1;
34
39
  a1++;
35
40
  *a3 = (x & (CUMO_SLB(len)<<p3)) | (*a3 & ~(CUMO_SLB(len)<<p3));
36
41
  a3++;
@@ -24,6 +24,10 @@ static void
24
24
  CUMO_STORE_BIT_STEP(a3, p3, s3, idx3, y);
25
25
  }
26
26
  } else {
27
+ a1 += p1/CUMO_NB;
28
+ p1 %= CUMO_NB;
29
+ a3 += p3/CUMO_NB;
30
+ p3 %= CUMO_NB;
27
31
  o1 = p1-p3;
28
32
  l1 = CUMO_NB+o1;
29
33
  r1 = CUMO_NB-o1;
@@ -1346,8 +1346,8 @@ cumo_na_s_from_binary(int argc, VALUE *argv, VALUE type)
1346
1346
  break;
1347
1347
  case T_ARRAY:
1348
1348
  nd = RARRAY_LEN(vshape);
1349
- if (nd == 0 || nd > CUMO_NA_MAX_DIMENSION) {
1350
- rb_raise(cumo_na_eDimensionError,"too long or empty shape (%d)", nd);
1349
+ if (nd > CUMO_NA_MAX_DIMENSION) {
1350
+ rb_raise(cumo_na_eDimensionError,"shape exceeds max dimension");
1351
1351
  }
1352
1352
  shape = ALLOCA_N(size_t,nd);
1353
1353
  len = 1;
@@ -164,7 +164,7 @@ print_ndloop(cumo_na_md_loop_t *lp) {
164
164
  for (i=0; i<lp->user.ndim; i++) {
165
165
  printf(" &user.args[%d].iter[%d] = 0x%"SZF"x\n", j,i, (size_t)&lp->user.args[j].iter[i]);
166
166
  printf(" user.args[%d].iter[%d].pos = %"SZF"u\n", j,i, lp->user.args[j].iter[i].pos);
167
- printf(" user.args[%d].iter[%d].step = %"SZF"u\n", j,i, lp->user.args[j].iter[i].step);
167
+ printf(" user.args[%d].iter[%d].step = %"SZF"d\n", j,i, lp->user.args[j].iter[i].step);
168
168
  printf(" user.args[%d].iter[%d].idx = 0x%"SZF"x (cuda:%d)\n", j,i, (size_t)lp->user.args[j].iter[i].idx, cumo_cuda_runtime_is_device_memory(lp->user.args[j].iter[i].idx));
169
169
  // printf(" user.args[%d].iter[%d].idx = 0x%"SZF"x\n", j,i, (size_t)lp->user.args[j].iter[i].idx);
170
170
  }
@@ -175,7 +175,7 @@ print_ndloop(cumo_na_md_loop_t *lp) {
175
175
  for (i=0; i<=nd; i++) {
176
176
  printf(" &xargs[%d].iter[%d] = 0x%"SZF"x\n", j,i, (size_t)&LITER(lp,i,j));
177
177
  printf(" xargs[%d].iter[%d].pos = %"SZF"u\n", j,i, LITER(lp,i,j).pos);
178
- printf(" xargs[%d].iter[%d].step = %"SZF"u\n", j,i, LITER(lp,i,j).step);
178
+ printf(" xargs[%d].iter[%d].step = %"SZF"d\n", j,i, LITER(lp,i,j).step);
179
179
  printf(" xargs[%d].iter[%d].idx = 0x%"SZF"x (cuda:%d)\n", j,i, (size_t)LITER(lp,i,j).idx, cumo_cuda_runtime_is_device_memory(LITER(lp,i,j).idx));
180
180
  // printf(" xargs[%d].iter[%d].idx = 0x%"SZF"x\n", j,i, (size_t)LITER(lp,i,j).idx);
181
181
  }
@@ -108,7 +108,19 @@ module Cumo
108
108
 
109
109
  # Convert the argument to an narray if not an narray.
110
110
  def self.cast(a)
111
- a.kind_of?(NArray) ? a : NArray.array_type(a).cast(a)
111
+ case a
112
+ when NArray
113
+ a
114
+ when Array,Numeric
115
+ NArray.array_type(a).cast(a)
116
+ else
117
+ if a.respond_to?(:to_a)
118
+ a = a.to_a
119
+ NArray.array_type(a).cast(a)
120
+ else
121
+ raise TypeError,"invalid type for NArray"
122
+ end
123
+ end
112
124
  end
113
125
 
114
126
  def self.asarray(a)
@@ -1186,6 +1198,35 @@ module Cumo
1186
1198
  end
1187
1199
  end
1188
1200
 
1201
+ # Percentile
1202
+ #
1203
+ # @param q [Numo::NArray]
1204
+ # @param axis [Integer] applied axis
1205
+ # @return [Numo::NArray] return percentile
1206
+ def percentile(q, axis: nil)
1207
+ raise ArgumentError, "q is out of range" if q < 0 || q > 100
1208
+
1209
+ x = self
1210
+ unless axis
1211
+ axis = 0
1212
+ x = x.flatten
1213
+ end
1214
+
1215
+ sorted = x.sort(axis: axis)
1216
+ x = q / 100.0 * (sorted.shape[axis] - 1)
1217
+ r = x % 1
1218
+ i = x.floor
1219
+ refs = [true] * sorted.ndim
1220
+ refs[axis] = i
1221
+ if i == sorted.shape[axis] - 1
1222
+ sorted[*refs]
1223
+ else
1224
+ refs_upper = refs.dup
1225
+ refs_upper[axis] = i + 1
1226
+ sorted[*refs] + r * (sorted[*refs_upper] - sorted[*refs])
1227
+ end
1228
+ end
1229
+
1189
1230
  # Kronecker product of two arrays.
1190
1231
  #
1191
1232
  # kron(a,b)[k_0, k_1, ...] = a[i_0, i_1, ...] * b[j_0, j_1, ...]
data/test/bit_test.rb CHANGED
@@ -139,6 +139,37 @@ class BitTest < Test::Unit::TestCase
139
139
  end
140
140
  end
141
141
 
142
+ procs = [
143
+ [proc{|tp,a| tp[*a] },""],
144
+ ]
145
+ procs.each do |init, ref|
146
+
147
+ test "#{dtype},[]#{ref}" do
148
+ src = []
149
+ n = src.size
150
+ a = init.call(dtype, src)
151
+
152
+ assert { a == src }
153
+ assert { (a & 0) == [0] * n }
154
+ assert { (a & 1) == src }
155
+ assert { (a | 0) == src }
156
+ assert { (a | 1) == [1] * n }
157
+ assert { (a ^ 0) == src.map {|x| x ^ 0 } }
158
+ assert { (a ^ 1) == src.map {|x| x ^ 1 } }
159
+ assert { ~a == src.map {|x| 1 - x } }
160
+
161
+ assert { a.count_true == 0 }
162
+ assert { a.count_false == 0 }
163
+ assert { a.where == [] }
164
+ assert { a.where2 == [[], []] }
165
+ assert { a.mask(Cumo::DFloat[]) == [] }
166
+ assert { !a.all? }
167
+ assert { !a.any? }
168
+ assert { a.none? }
169
+ end
170
+
171
+ end
172
+
142
173
  test "store to view" do
143
174
  n = 14
144
175
  x = Cumo::Bit.zeros(n + 2, n + 2, 3)
@@ -154,4 +185,10 @@ class BitTest < Test::Unit::TestCase
154
185
  assert { (~y[1..-2, 1..-2, 0]).where.size == 0 }
155
186
  assert { y[true, true, 1].where.size == 0 }
156
187
  end
188
+
189
+ test "assign nil" do
190
+ x = Cumo::RObject.cast([1, 2, 3])
191
+ x[Cumo::Bit.cast([0, 1, 0])] = nil
192
+ assert { x.to_a == [1, nil, 3] }
193
+ end
157
194
  end
data/test/narray_test.rb CHANGED
@@ -351,6 +351,18 @@ class NArrayTest < Test::Unit::TestCase
351
351
  assert { (a.eq 3) == [[0, 0, 1], [0, 0, 0]] }
352
352
  assert { a.sort == src }
353
353
  assert { a.sort_index == [[0, 1, 2], [3, 4, 5]] }
354
+ assert { a.percentile(0) == 1.0 }
355
+ assert { a.percentile(50) == 4.0 }
356
+ assert { a.percentile(90) == 9.0 }
357
+ assert { a.percentile(100) == 11.0 }
358
+ assert { a.percentile(0, axis: 0) == [1, 2, 3] }
359
+ assert { a.percentile(50, axis: 0) == [3, 4.5, 7] }
360
+ assert { a.percentile(90, axis: 0) == [4.6, 6.5, 10.2] }
361
+ assert { a.percentile(100, axis: 0) == [5, 7, 11] }
362
+ assert { a.percentile(0, axis: 1) == [1, 5] }
363
+ assert { a.percentile(50, axis: 1) == [2, 7] }
364
+ assert { a.percentile(90, axis: 1) == [2.8, 10.2] }
365
+ assert { a.percentile(100, axis: 1) == [3, 11] }
354
366
  end
355
367
  assert { a.dup.fill(12) == [[12] * 3] * 2 }
356
368
  assert { (a + 1) == [[2, 3, 4], [6, 8, 12]] }
@@ -796,6 +808,11 @@ class NArrayTest < Test::Unit::TestCase
796
808
  end
797
809
  end
798
810
 
811
+ test "cast any object that responds to to_a" do
812
+ object = Struct.new(:to_a).new([1, 2, 3])
813
+ assert { Cumo::NArray.cast(object) == [1, 2, 3] }
814
+ end
815
+
799
816
  test "Cumo::DFloat.cast(Cumo::RObject[1, nil, 3])" do
800
817
  assert_equal(Cumo::DFloat[1, Float::NAN, 3].format_to_a,
801
818
  Cumo::DFloat.cast(Cumo::RObject[1, nil, 3]).format_to_a)
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.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Naotoshi Seo
@@ -331,7 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
331
331
  - !ruby/object:Gem::Version
332
332
  version: '0'
333
333
  requirements: []
334
- rubygems_version: 4.0.6
334
+ rubygems_version: 4.0.10
335
335
  specification_version: 4
336
336
  summary: Cumo is CUDA aware numerical library whose interface is highly compatible
337
337
  with Ruby Numo