carray 3.0.3 → 3.0.5

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.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +469 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_descriptor.h +27 -24
  7. data/ext/ca_axis_dispatch.c +14 -26
  8. data/ext/ca_axis_group.c +27 -27
  9. data/ext/ca_binop_dispatch.c +1 -29
  10. data/ext/ca_binop_dispatch.h +0 -1
  11. data/ext/ca_categorical_iterator.c +231 -153
  12. data/ext/ca_compare.c +9 -20
  13. data/ext/ca_composite_dispatch.c +9 -9
  14. data/ext/ca_group_iter.c +16 -17
  15. data/ext/ca_kernel_iterator.c +1240 -2000
  16. data/ext/ca_kernel_iterator.h +502 -519
  17. data/ext/ca_monop_dispatch.c +82 -59
  18. data/ext/ca_monop_dispatch.h +1 -0
  19. data/ext/ca_obj_array.c +152 -45
  20. data/ext/ca_obj_bincmp.c +25 -21
  21. data/ext/ca_obj_binop.c +16 -26
  22. data/ext/ca_obj_bitarray.c +8 -3
  23. data/ext/ca_obj_bitfield.c +63 -49
  24. data/ext/ca_obj_block.c +18 -9
  25. data/ext/ca_obj_byte_swap.c +7 -7
  26. data/ext/ca_obj_const_string.c +188 -22
  27. data/ext/ca_obj_face.c +280 -58
  28. data/ext/ca_obj_face.h +19 -0
  29. data/ext/ca_obj_fake.c +15 -29
  30. data/ext/ca_obj_farray.c +6 -3
  31. data/ext/ca_obj_field.c +30 -8
  32. data/ext/ca_obj_fixlen_string.c +2 -3
  33. data/ext/ca_obj_grid.c +455 -134
  34. data/ext/ca_obj_meld.c +172 -34
  35. data/ext/ca_obj_moncmp.c +23 -8
  36. data/ext/ca_obj_monop.c +113 -67
  37. data/ext/ca_obj_object.c +210 -52
  38. data/ext/ca_obj_record.c +15 -7
  39. data/ext/ca_obj_reduce.c +17 -8
  40. data/ext/ca_obj_refer.c +42 -35
  41. data/ext/ca_obj_remap.c +30 -9
  42. data/ext/ca_obj_repeat.c +9 -10
  43. data/ext/ca_obj_roll.c +31 -10
  44. data/ext/ca_obj_select.c +48 -14
  45. data/ext/ca_obj_select_axis.c +15 -47
  46. data/ext/ca_obj_shift.c +41 -7
  47. data/ext/ca_obj_stack.c +180 -34
  48. data/ext/ca_obj_stride.c +190 -134
  49. data/ext/ca_obj_string.c +80 -4
  50. data/ext/ca_obj_tile.c +32 -11
  51. data/ext/ca_obj_time.c +22 -6
  52. data/ext/ca_obj_timedelta.c +22 -6
  53. data/ext/ca_obj_transpose.c +13 -7
  54. data/ext/ca_obj_triop.c +26 -32
  55. data/ext/ca_obj_window.c +267 -74
  56. data/ext/ca_op_ipower.c +4 -4
  57. data/ext/ca_sort_kernels.h +6 -3
  58. data/ext/ca_sweep_engine.c +2 -2
  59. data/ext/caframe_csv_reader.c +80 -1
  60. data/ext/carray.h +214 -75
  61. data/ext/carray_access.c +200 -99
  62. data/ext/carray_address_basis.c +343 -87
  63. data/ext/carray_attribute.c +113 -6
  64. data/ext/carray_bincount.c +10 -8
  65. data/ext/carray_broadcast.c +13 -8
  66. data/ext/carray_build_flags.h +3 -0
  67. data/ext/carray_call_cfunc.c +108 -0
  68. data/ext/carray_cast.c +375 -96
  69. data/ext/carray_cast_func.rb +90 -20
  70. data/ext/carray_class.c +4 -3
  71. data/ext/carray_config.h +28 -0
  72. data/ext/carray_conversion.c +18 -9
  73. data/ext/carray_copy.c +51 -14
  74. data/ext/carray_core.c +150 -55
  75. data/ext/carray_count.c +56 -20
  76. data/ext/carray_element.c +81 -33
  77. data/ext/carray_factorize.c +138 -84
  78. data/ext/carray_generate.c +199 -52
  79. data/ext/carray_histogram.c +63 -18
  80. data/ext/carray_hold.c +12 -15
  81. data/ext/carray_index_classifier.c +388 -176
  82. data/ext/carray_internal.h +348 -29
  83. data/ext/carray_kernels_bincmp.c +4453 -0
  84. data/ext/carray_kernels_binop.c +11368 -0
  85. data/ext/carray_kernels_init.c +1734 -0
  86. data/ext/carray_kernels_moncmp.c +2104 -0
  87. data/ext/carray_kernels_monop.c +18369 -0
  88. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  89. data/ext/carray_kernels_reduce_boolean.c +406 -0
  90. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  91. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  92. data/ext/carray_kernels_reduce_variance.c +3849 -0
  93. data/ext/carray_kernels_scan.c +4302 -0
  94. data/ext/carray_kernels_search.c +33829 -0
  95. data/ext/carray_kernels_sort.c +10897 -0
  96. data/ext/carray_kernels_triop.c +1864 -0
  97. data/ext/carray_key_windows.c +220 -0
  98. data/ext/carray_lazy.c +170 -111
  99. data/ext/carray_mask.c +337 -94
  100. data/ext/carray_median_percentile.c +82 -28
  101. data/ext/carray_memory_view.c +669 -561
  102. data/ext/carray_operator.c +129 -52
  103. data/ext/carray_order.c +604 -77
  104. data/ext/carray_partition.c +28 -27
  105. data/ext/carray_random.c +85 -31
  106. data/ext/carray_round.c +273 -0
  107. data/ext/carray_scatter.c +87 -45
  108. data/ext/carray_segment.c +3 -3
  109. data/ext/carray_slab.c +123 -37
  110. data/ext/carray_sort.c +259 -51
  111. data/ext/carray_sort_kernel.c +5 -7
  112. data/ext/carray_struct.c +54 -61
  113. data/ext/carray_test.c +26 -5
  114. data/ext/carray_time_text.c +4 -2
  115. data/ext/carray_undef.c +4 -0
  116. data/ext/carray_utils.c +309 -66
  117. data/ext/mk_call_cfunc.rb +19 -2
  118. data/ext/mkkernel.rb +403 -350
  119. data/ext/ruby_carray.c +10 -4
  120. data/ext/version.h +4 -4
  121. data/lib/carray/attribute.rb +139 -22
  122. data/lib/carray/autoload_carray.rb +8 -31
  123. data/lib/carray/autoload_method_extension.rb +14 -5
  124. data/lib/carray/axis_group.rb +255 -106
  125. data/lib/carray/basics.rb +105 -17
  126. data/lib/carray/bincount_nd.rb +12 -2
  127. data/lib/carray/block_iterator.rb +126 -23
  128. data/lib/carray/boolean_reduce.rb +17 -17
  129. data/lib/carray/categorical.rb +195 -59
  130. data/lib/carray/categorical_iterator.rb +132 -29
  131. data/lib/carray/complex.rb +5 -5
  132. data/lib/carray/conditional.rb +67 -18
  133. data/lib/carray/const_string.rb +24 -5
  134. data/lib/carray/construct.rb +15 -11
  135. data/lib/carray/data_type_extension.rb +9 -1
  136. data/lib/carray/distance_limit.rb +77 -0
  137. data/lib/carray/fixlen_string.rb +48 -3
  138. data/lib/carray/frame/column_verbs.rb +71 -0
  139. data/lib/carray/frame/concat.rb +17 -3
  140. data/lib/carray/frame/convert.rb +69 -0
  141. data/lib/carray/frame/csv_parser.rb +111 -17
  142. data/lib/carray/frame/describe.rb +3 -2
  143. data/lib/carray/frame/frame.rb +252 -28
  144. data/lib/carray/frame/group.rb +603 -101
  145. data/lib/carray/frame/io.rb +117 -28
  146. data/lib/carray/frame/join.rb +312 -51
  147. data/lib/carray/frame/records.rb +83 -7
  148. data/lib/carray/frame/reshape.rb +42 -35
  149. data/lib/carray/frame/sort.rb +7 -19
  150. data/lib/carray/frame/verbs.rb +188 -48
  151. data/lib/carray/frame/windows.rb +117 -0
  152. data/lib/carray/frame.rb +2 -0
  153. data/lib/carray/fuse_source.rb +42 -6
  154. data/lib/carray/fusion.rb +40 -16
  155. data/lib/carray/histogram.rb +6 -1
  156. data/lib/carray/inspect.rb +31 -8
  157. data/lib/carray/iterator.rb +85 -7
  158. data/lib/carray/key_windows.rb +620 -0
  159. data/lib/carray/lazy.rb +217 -183
  160. data/lib/carray/mask_gap_fill.rb +63 -57
  161. data/lib/carray/meld_reduce.rb +12 -14
  162. data/lib/carray/methods/bin.rb +26 -18
  163. data/lib/carray/methods/bincount.rb +16 -0
  164. data/lib/carray/methods/bit_string.rb +1 -1
  165. data/lib/carray/methods/choose.rb +16 -3
  166. data/lib/carray/methods/composition.rb +3 -1
  167. data/lib/carray/methods/gather_nd.rb +14 -5
  168. data/lib/carray/methods/insert_block.rb +2 -2
  169. data/lib/carray/methods/is_between.rb +59 -0
  170. data/lib/carray/methods/is_in.rb +61 -37
  171. data/lib/carray/methods/join.rb +1 -6
  172. data/lib/carray/methods/lag.rb +49 -0
  173. data/lib/carray/methods/locate_addr.rb +47 -51
  174. data/lib/carray/methods/mode.rb +1 -1
  175. data/lib/carray/methods/nunique.rb +11 -6
  176. data/lib/carray/methods/resize.rb +3 -3
  177. data/lib/carray/methods/value_counts.rb +4 -11
  178. data/lib/carray/record_order.rb +3 -3
  179. data/lib/carray/rng.rb +3 -0
  180. data/lib/carray/runtime.rb +53 -8
  181. data/lib/carray/segment_iterator.rb +323 -88
  182. data/lib/carray/serialize.rb +45 -14
  183. data/lib/carray/slab_iterator.rb +50 -0
  184. data/lib/carray/stack.rb +15 -12
  185. data/lib/carray/string.rb +113 -5
  186. data/lib/carray/string_operation_extension.rb +21 -6
  187. data/lib/carray/struct.rb +9 -21
  188. data/lib/carray/struct_builder.rb +24 -11
  189. data/lib/carray/time.rb +819 -158
  190. data/lib/carray/window_iterator.rb +122 -16
  191. data/lib/carray.rb +7 -0
  192. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  193. data/yard-stubs/ca_obj_field.rb +4 -0
  194. data/yard-stubs/ca_obj_grid.rb +21 -10
  195. data/yard-stubs/ca_obj_refer.rb +2 -1
  196. data/yard-stubs/ca_obj_roll.rb +2 -2
  197. data/yard-stubs/ca_obj_shift.rb +5 -1
  198. data/yard-stubs/ca_obj_tile.rb +1 -1
  199. data/yard-stubs/ca_obj_transpose.rb +5 -4
  200. data/yard-stubs/ca_obj_window.rb +8 -3
  201. data/yard-stubs/carray_access.rb +6 -1
  202. data/yard-stubs/carray_attribute.rb +3 -6
  203. data/yard-stubs/carray_cast.rb +12 -0
  204. data/yard-stubs/carray_conversion.rb +7 -2
  205. data/yard-stubs/carray_copy.rb +4 -2
  206. data/yard-stubs/carray_count.rb +4 -4
  207. data/yard-stubs/carray_element.rb +17 -10
  208. data/yard-stubs/carray_generate.rb +21 -1
  209. data/yard-stubs/carray_mask.rb +32 -3
  210. data/yard-stubs/carray_math.rb +41 -5
  211. data/yard-stubs/carray_median_percentile.rb +5 -2
  212. data/yard-stubs/carray_memory_view.rb +40 -23
  213. data/yard-stubs/carray_order.rb +129 -22
  214. data/yard-stubs/carray_random.rb +13 -4
  215. data/yard-stubs/carray_scatter.rb +17 -10
  216. data/yard-stubs/carray_slab.rb +9 -2
  217. data/yard-stubs/carray_sort.rb +6 -5
  218. data/yard-stubs/carray_test.rb +5 -3
  219. metadata +25 -3
  220. data/lib/carray/arrow_tensor.rb +0 -401
  221. data/lib/carray/table.rb +0 -108
data/ext/ca_obj_string.c CHANGED
@@ -76,7 +76,7 @@ const rb_data_type_t castring_data_type = {
76
76
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
77
77
  };
78
78
 
79
- static int8_t CA_OBJ_STRING;
79
+ int8_t CA_OBJ_STRING; /* non-static: read by the store path in carray_access.c */
80
80
  static VALUE rb_cCAString;
81
81
 
82
82
  /* ------------------------------------------------------------------- */
@@ -119,9 +119,6 @@ ca_string_setup (CAString *ca, CArray *parent)
119
119
  ca->attach = 0;
120
120
  ca->nosync = 0;
121
121
 
122
- if ( ca_has_mask(parent) ) {
123
- ca_create_mask((CArray *) ca);
124
- }
125
122
 
126
123
  if ( ca_is_scalar(parent) ) {
127
124
  ca_set_flag(ca, CA_FLAG_SCALAR);
@@ -141,6 +138,7 @@ ca_string_new (CArray *parent)
141
138
  ca_string_setup(NULL, parent);
142
139
  ca = (CAString *) ca_array_alloc(CA_OBJ_STRING, parent->ndim);
143
140
  ca_string_setup(ca, parent);
141
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
144
142
  return ca;
145
143
  }
146
144
 
@@ -200,6 +198,78 @@ ca_operation_function_t ca_string_func = {
200
198
 
201
199
  /* ------------------------------------------------------------------- */
202
200
 
201
+ /* A CAString cell is a String; UNDEF (a masked cell) is no value. Refuse
202
+ anything else, naming what it is, so a cell of a CAString always answers
203
+ the String operations. */
204
+ NORETURN(static void ca_string_refuse_cell (VALUE v, const char *where));
205
+
206
+ static void
207
+ ca_string_refuse_cell (VALUE v, const char *where)
208
+ {
209
+ if ( NIL_P(v) ) {
210
+ rb_raise(rb_eTypeError,
211
+ "%s is nil, not a String (a CAString holds Strings; "
212
+ "UNDEF masks a cell)", where);
213
+ }
214
+ rb_raise(rb_eTypeError,
215
+ "%s is of class %s, not a String (a CAString holds Strings; "
216
+ "UNDEF masks a cell)", where, rb_obj_classname(v));
217
+ }
218
+
219
+ /* Every cell of `parent` that is not masked is a String. Under a masked
220
+ cell of an entity that can be written, a value that is not a String (the
221
+ 0 an object array starts with) becomes an empty String, so that the cell
222
+ is still a String once it is unmasked. */
223
+ static void
224
+ ca_string_check_cells (VALUE parent_val, CArray *parent)
225
+ {
226
+ ca_size_t i;
227
+ char where[64];
228
+ if ( ca_is_entity(parent) && parent->ptr ) {
229
+ VALUE *p = (VALUE *) parent->ptr;
230
+ boolean8_t *m = ( parent->mask && parent->mask->ptr )
231
+ ? (boolean8_t *) parent->mask->ptr : NULL;
232
+ int writable = ! ca_is_readonly(parent);
233
+ for (i = 0; i < parent->elements; i++) {
234
+ if ( m && m[i] ) {
235
+ if ( writable && ! RB_TYPE_P(p[i], T_STRING) ) {
236
+ p[i] = rb_utf8_str_new("", 0);
237
+ }
238
+ continue;
239
+ }
240
+ if ( ! RB_TYPE_P(p[i], T_STRING) ) {
241
+ snprintf(where, sizeof(where), "cell %" PRId64, (int64_t) i);
242
+ ca_string_refuse_cell(p[i], where);
243
+ }
244
+ }
245
+ }
246
+ else {
247
+ volatile VALUE list =
248
+ rb_funcall(rb_funcall(parent_val, rb_intern("flatten"), 0),
249
+ rb_intern("to_a"), 0);
250
+ long n = RARRAY_LEN(list), j;
251
+ for (j = 0; j < n; j++) {
252
+ VALUE v = rb_ary_entry(list, j);
253
+ if ( v == CA_UNDEF ) continue;
254
+ if ( ! RB_TYPE_P(v, T_STRING) ) {
255
+ snprintf(where, sizeof(where), "cell %ld", j);
256
+ ca_string_refuse_cell(v, where);
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ /* The write hook: a value stored into a CAString is a String. */
263
+ static VALUE
264
+ ca_string_element_to_storage (VALUE self, VALUE v)
265
+ {
266
+ (void) self;
267
+ if ( ! RB_TYPE_P(v, T_STRING) ) {
268
+ ca_string_refuse_cell(v, "a value stored into a CAString");
269
+ }
270
+ return v;
271
+ }
272
+
203
273
  /* CAString.wrap(object_array) — zero-copy Face wrap of a CA_OBJECT array */
204
274
  VALUE
205
275
  rb_ca_string_wrap (VALUE parent_val)
@@ -211,6 +281,8 @@ rb_ca_string_wrap (VALUE parent_val)
211
281
  rb_check_carray_object(parent_val);
212
282
  TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
213
283
 
284
+ ca_string_setup(NULL, parent);
285
+ ca_string_check_cells(parent_val, parent);
214
286
  ca = ca_string_new(parent);
215
287
  obj = ca_wrap_struct(ca);
216
288
  rb_ca_set_parent(obj, parent_val);
@@ -242,6 +314,7 @@ rb_ca_string_initialize_copy (VALUE self, VALUE other)
242
314
  ca_array_pool_alloc(ca, CA_OBJ_STRING, cs->parent->ndim);
243
315
  }
244
316
  ca_string_setup(ca, cs->parent);
317
+ ca_view_inherit_mask((VALUE) ca);
245
318
  return self;
246
319
  }
247
320
 
@@ -266,6 +339,9 @@ Init_ca_obj_string (void)
266
339
  rb_ca_string_initialize_copy, 1);
267
340
  rb_define_singleton_method(rb_cCAString, "wrap", rb_ca_string_wrap_method, 1);
268
341
 
342
+ ca_face_register_element_to_storage(CA_OBJ_STRING,
343
+ ca_string_element_to_storage);
344
+
269
345
  /* A cell is the String itself, so the Face is the same over any parent:
270
346
  CAStack / CAMeld / concatenate can carry it (unlike CAConstString, whose
271
347
  cells point into one parent's buffer). */
data/ext/ca_obj_tile.c CHANGED
@@ -108,6 +108,8 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
108
108
  ca->parent = parent;
109
109
  ca->attach = 0;
110
110
  ca->nosync = 0;
111
+ ca->reps = NULL; /* set before either allocation can raise */
112
+ ca->dim = NULL;
111
113
  ca->reps = ALLOC_N(ca_size_t, ndim);
112
114
  ca->dim = ALLOC_N(ca_size_t, ndim);
113
115
 
@@ -116,21 +118,37 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
116
118
  ca->dim[i] = parent->dim[i] * reps[i];
117
119
  }
118
120
 
119
- if ( ca_has_mask(parent) ) {
120
- ca_create_mask(ca);
121
- }
122
121
 
123
122
  return 0;
124
123
  }
125
124
 
125
+ typedef struct {
126
+ CATile *ca;
127
+ CArray *parent;
128
+ ca_size_t *reps;
129
+ } ca_tile_new_arg;
130
+
131
+ static VALUE
132
+ ca_tile_new_setup (VALUE varg)
133
+ {
134
+ ca_tile_new_arg *a = (ca_tile_new_arg *) varg;
135
+ ca_tile_setup(a->ca, a->parent, a->reps);
136
+ return Qnil;
137
+ }
138
+
139
+ /* The setup allocates reps and dim after the struct: when either fails,
140
+ the struct goes too. */
126
141
  CATile *
127
142
  ca_tile_new (CArray *parent, ca_size_t *reps)
128
143
  {
129
- CATile *ca;
144
+ ca_tile_new_arg a;
130
145
  ca_tile_setup(NULL, parent, reps);
131
- ca = ALLOC(CATile);
132
- ca_tile_setup(ca, parent, reps);
133
- return ca;
146
+ a.ca = ALLOC(CATile);
147
+ a.parent = parent;
148
+ a.reps = reps;
149
+ ca_fill_or_free((CArray *) a.ca, ca_tile_new_setup, (VALUE) &a);
150
+ ca_fill_or_free((CArray *) a.ca, ca_view_inherit_mask, (VALUE) a.ca);
151
+ return a.ca;
134
152
  }
135
153
 
136
154
  static void
@@ -244,6 +262,7 @@ ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
244
262
  ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
245
263
  for (k = 0; k < ndim; k++) base += starts[k] * tnative[k];
246
264
  for (k = 0; k < ndim; k++) idx[k] = 0;
265
+ /* empty: the slot returns on an empty region at its entry */
247
266
  while (1) {
248
267
  ca_size_t toff = base, tidx[CA_RANK_MAX];
249
268
  for (k = 0; k < ndim; k++) toff += idx[k] * strides[k];
@@ -258,6 +277,7 @@ ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
258
277
  }
259
278
 
260
279
  for (k = 0; k < ndim; k++) o[k] = 0;
280
+ /* empty: the slot returns on an empty region at its entry */
261
281
  while (1) {
262
282
  ca_size_t pbase = 0, doff = 0, i;
263
283
  for (k = 0; k < inner; k++) {
@@ -403,7 +423,7 @@ ca_tile_func_allocate (void *ap)
403
423
  {
404
424
  CATile *ca = (CATile *) ap;
405
425
  ca_attach(ca->parent);
406
- ca->ptr = xmalloc(ca_length(ca));
426
+ ca->ptr = ca_alloc_cells((CArray *) ca);
407
427
  }
408
428
 
409
429
  static void
@@ -411,7 +431,7 @@ ca_tile_func_attach (void *ap)
411
431
  {
412
432
  CATile *ca = (CATile *) ap;
413
433
  ca_attach(ca->parent);
414
- ca->ptr = xmalloc(ca_length(ca));
434
+ ca->ptr = ca_alloc_cells((CArray *) ca);
415
435
  ca_tile_attach_into(ca, ca->ptr);
416
436
  }
417
437
 
@@ -548,7 +568,7 @@ rb_ca_tile (int argc, VALUE *argv, VALUE self)
548
568
  len, ca->ndim);
549
569
  }
550
570
  for ( i = 0; i < ca->ndim; i++ ) {
551
- reps[i] = NUM2SIZE(rb_ary_entry(ary, i));
571
+ reps[i] = ca_integer_arg(rb_ary_entry(ary, i), "a repeat count", NULL);
552
572
  }
553
573
  }
554
574
  else {
@@ -559,7 +579,7 @@ rb_ca_tile (int argc, VALUE *argv, VALUE self)
559
579
  ca->ndim, argc);
560
580
  }
561
581
  for ( i = 0; i < ca->ndim; i++ ) {
562
- reps[i] = NUM2SIZE(argv[i]);
582
+ reps[i] = ca_integer_arg(argv[i], "a repeat count", NULL);
563
583
  }
564
584
  }
565
585
 
@@ -585,6 +605,7 @@ rb_ca_tile_initialize_copy (VALUE self, VALUE other)
585
605
  ca_check_uninitialized(ca);
586
606
  TypedData_Get_Struct(other, CATile, &catile_data_type, cs);
587
607
  ca_tile_setup(ca, cs->parent, cs->reps);
608
+ ca_view_inherit_mask((VALUE) ca);
588
609
  return self;
589
610
  }
590
611
 
data/ext/ca_obj_time.c CHANGED
@@ -154,6 +154,21 @@ rb_ca_time_element_initialize (VALUE self, VALUE value, VALUE unit)
154
154
  return self;
155
155
  }
156
156
 
157
+ /* dup / clone copy the value and the unit (the allocator leaves both 0). */
158
+ static VALUE
159
+ rb_ca_time_element_initialize_copy (VALUE self, VALUE orig)
160
+ {
161
+ CATimeElement *s, *o;
162
+ if ( self == orig ) {
163
+ return self;
164
+ }
165
+ rb_check_frozen(self);
166
+ TypedData_Get_Struct(self, CATimeElement, &catime_element_data_type, s);
167
+ TypedData_Get_Struct(orig, CATimeElement, &catime_element_data_type, o);
168
+ *s = *o;
169
+ return self;
170
+ }
171
+
157
172
  static VALUE
158
173
  rb_ca_time_element_value (VALUE self)
159
174
  {
@@ -216,9 +231,6 @@ ca_time_setup (CATime *ca, CArray *parent, int8_t unit, int64_t count)
216
231
  ca->unit = unit;
217
232
  ca->count = count;
218
233
 
219
- if ( ca_has_mask(parent) ) {
220
- ca_create_mask((CArray *) ca);
221
- }
222
234
 
223
235
  if ( ca_is_scalar(parent) ) {
224
236
  ca_set_flag(ca, CA_FLAG_SCALAR);
@@ -238,6 +250,7 @@ ca_time_new (CArray *parent, int8_t unit, int64_t count)
238
250
  ca_time_setup(NULL, parent, unit, count);
239
251
  ca = (CATime *) ca_array_alloc(CA_OBJ_TIME, parent->ndim);
240
252
  ca_time_setup(ca, parent, unit, count);
253
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
241
254
  return ca;
242
255
  }
243
256
 
@@ -398,7 +411,7 @@ rb_ca_time_wrap (VALUE parent_val, int8_t unit, int64_t count)
398
411
  return obj;
399
412
  }
400
413
 
401
- /* __wrap__(raw, unit_spec) — primitive; unit_spec is Symbol / String /
414
+ /* wrap_storage(raw, unit_spec) — primitive; unit_spec is Symbol / String /
402
415
  Resolution / nil (normalized here). */
403
416
  static VALUE
404
417
  rb_ca_time_wrap_method (VALUE klass, VALUE raw, VALUE unit_spec)
@@ -479,6 +492,7 @@ rb_ca_time_initialize_copy (VALUE self, VALUE other)
479
492
  ca_array_pool_alloc(ca, CA_OBJ_TIME, cs->parent->ndim);
480
493
  }
481
494
  ca_time_setup(ca, cs->parent, cs->unit, cs->count);
495
+ ca_view_inherit_mask((VALUE) ca);
482
496
  return self;
483
497
  }
484
498
 
@@ -512,8 +526,8 @@ Init_ca_obj_time (void)
512
526
  rb_define_method(rb_cCATime, "initialize_copy",
513
527
  rb_ca_time_initialize_copy, 1);
514
528
 
515
- rb_define_singleton_method(rb_cCATime, "__wrap__",
516
- rb_ca_time_wrap_method, 2);
529
+ rb_define_private_method(rb_singleton_class(rb_cCATime), "wrap_storage",
530
+ rb_ca_time_wrap_method, 2);
517
531
  rb_define_method(rb_cCATime, "unit", rb_ca_time_unit, 0);
518
532
  rb_define_method(rb_cCATime, "storage_to_element",
519
533
  rb_ca_time_storage_to_element, 1);
@@ -539,6 +553,8 @@ Init_ca_obj_time (void)
539
553
  rb_ca_time_element_s_allocate);
540
554
  rb_define_method(rb_cCATimeElement, "initialize",
541
555
  rb_ca_time_element_initialize, 2);
556
+ rb_define_method(rb_cCATimeElement, "initialize_copy",
557
+ rb_ca_time_element_initialize_copy, 1);
542
558
  rb_define_method(rb_cCATimeElement, "value",
543
559
  rb_ca_time_element_value, 0);
544
560
  rb_define_method(rb_cCATimeElement, "unit",
@@ -133,6 +133,21 @@ rb_ca_timedelta_element_initialize (VALUE self, VALUE value, VALUE unit)
133
133
  return self;
134
134
  }
135
135
 
136
+ /* dup / clone copy the value and the unit (the allocator leaves both 0). */
137
+ static VALUE
138
+ rb_ca_timedelta_element_initialize_copy (VALUE self, VALUE orig)
139
+ {
140
+ CATimedeltaElement *s, *o;
141
+ if ( self == orig ) {
142
+ return self;
143
+ }
144
+ rb_check_frozen(self);
145
+ TypedData_Get_Struct(self, CATimedeltaElement, &catimedelta_element_data_type, s);
146
+ TypedData_Get_Struct(orig, CATimedeltaElement, &catimedelta_element_data_type, o);
147
+ *s = *o;
148
+ return self;
149
+ }
150
+
136
151
  static VALUE
137
152
  rb_ca_timedelta_element_value (VALUE self)
138
153
  {
@@ -197,9 +212,6 @@ ca_timedelta_setup (CATimedelta *ca, CArray *parent, int8_t unit, int64_t count)
197
212
  ca->unit = unit;
198
213
  ca->count = count;
199
214
 
200
- if ( ca_has_mask(parent) ) {
201
- ca_create_mask((CArray *) ca);
202
- }
203
215
 
204
216
  if ( ca_is_scalar(parent) ) {
205
217
  ca_set_flag(ca, CA_FLAG_SCALAR);
@@ -219,6 +231,7 @@ ca_timedelta_new (CArray *parent, int8_t unit, int64_t count)
219
231
  ca_timedelta_setup(NULL, parent, unit, count);
220
232
  ca = (CATimedelta *) ca_array_alloc(CA_OBJ_TIMEDELTA, parent->ndim);
221
233
  ca_timedelta_setup(ca, parent, unit, count);
234
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
222
235
  return ca;
223
236
  }
224
237
 
@@ -293,7 +306,7 @@ rb_ca_timedelta_wrap (VALUE parent_val, int8_t unit, int64_t count)
293
306
  return obj;
294
307
  }
295
308
 
296
- /* __wrap__(raw, unit_spec) — primitive; unit_spec is Symbol / String /
309
+ /* wrap_storage(raw, unit_spec) — primitive; unit_spec is Symbol / String /
297
310
  Resolution / nil (normalized here). */
298
311
  static VALUE
299
312
  rb_ca_timedelta_wrap_method (VALUE klass, VALUE raw, VALUE unit_spec)
@@ -333,6 +346,7 @@ rb_ca_timedelta_initialize_copy (VALUE self, VALUE other)
333
346
  ca_array_pool_alloc(ca, CA_OBJ_TIMEDELTA, cs->parent->ndim);
334
347
  }
335
348
  ca_timedelta_setup(ca, cs->parent, cs->unit, cs->count);
349
+ ca_view_inherit_mask((VALUE) ca);
336
350
  return self;
337
351
  }
338
352
 
@@ -403,8 +417,8 @@ Init_ca_obj_timedelta (void)
403
417
  rb_define_method(rb_cCATimedelta, "initialize_copy",
404
418
  rb_ca_timedelta_initialize_copy, 1);
405
419
 
406
- rb_define_singleton_method(rb_cCATimedelta, "__wrap__",
407
- rb_ca_timedelta_wrap_method, 2);
420
+ rb_define_private_method(rb_singleton_class(rb_cCATimedelta), "wrap_storage",
421
+ rb_ca_timedelta_wrap_method, 2);
408
422
  rb_define_method(rb_cCATimedelta, "unit", rb_ca_timedelta_unit, 0);
409
423
  rb_define_method(rb_cCATimedelta, "storage_to_element",
410
424
  rb_ca_timedelta_storage_to_element, 1);
@@ -428,6 +442,8 @@ Init_ca_obj_timedelta (void)
428
442
  rb_ca_timedelta_element_s_allocate);
429
443
  rb_define_method(rb_cCATimedeltaElement, "initialize",
430
444
  rb_ca_timedelta_element_initialize, 2);
445
+ rb_define_method(rb_cCATimedeltaElement, "initialize_copy",
446
+ rb_ca_timedelta_element_initialize_copy, 1);
431
447
  rb_define_method(rb_cCATimedeltaElement, "value",
432
448
  rb_ca_timedelta_element_value, 0);
433
449
  rb_define_method(rb_cCATimedeltaElement, "unit",
@@ -7,6 +7,7 @@
7
7
  ---------------------------------------------------------------------------- */
8
8
 
9
9
  #include "carray.h"
10
+ #include "carray_internal.h" /* ca_view_inherit_mask */
10
11
  #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
11
12
 
12
13
  extern ca_operation_function_t ca_stride_func;
@@ -41,8 +42,8 @@ ca_trans_setup (CAStride *ca, CArray *parent, ca_size_t *imap)
41
42
  "specified %i-th dimension number out of range", i);
42
43
  }
43
44
  if (map[idim] != -1) {
44
- rb_raise(rb_eArgError,
45
- "specified %i-th dimension number is duplicated", i);
45
+ rb_raise(rb_eArgError, "%s: axis %" PRId64 " is given twice",
46
+ ca_calling_method_name(), (int64_t) idim);
46
47
  }
47
48
  map[idim] = i;
48
49
  newdim[i] = dim0[idim];
@@ -64,9 +65,9 @@ ca_trans_setup (CAStride *ca, CArray *parent, ca_size_t *imap)
64
65
  return 0;
65
66
  }
66
67
 
67
- ca_stride_setup(ca, CA_OBJ_TRANSPOSE, parent,
68
- parent->data_type, parent->bytes,
69
- ndim, newdim, strides, 0);
68
+ ca_stride_setup_view(ca, CA_OBJ_TRANSPOSE, parent,
69
+ parent->data_type, parent->bytes,
70
+ ndim, newdim, strides, 0);
70
71
  return 0;
71
72
  }
72
73
 
@@ -77,6 +78,7 @@ ca_trans_new (CArray *parent, ca_size_t *imap)
77
78
  ca_trans_setup(NULL, parent, imap);
78
79
  ca = (CAStride *) ca_array_alloc(CA_OBJ_TRANSPOSE, parent->ndim);
79
80
  ca_trans_setup(ca, parent, imap);
81
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
80
82
  return ca;
81
83
  }
82
84
 
@@ -118,10 +120,14 @@ rb_ca_trans (int argc, VALUE *argv, VALUE self)
118
120
  for (i = 0; i < ca->ndim; i++) imap[i] = ca->ndim - i - 1;
119
121
  }
120
122
  else if (argc == ca->ndim) {
121
- for (i = 0; i < ca->ndim; i++) imap[i] = NUM2SIZE(argv[i]);
123
+ /* Each axis read as every axis argument is: negative from the end. */
124
+ for (i = 0; i < ca->ndim; i++) {
125
+ imap[i] = ca_normalize_axis_arg(argv[i], ca->ndim, NULL);
126
+ }
122
127
  }
123
128
  else {
124
- rb_raise(rb_eArgError, "# of arguments should be equal to ndim");
129
+ rb_raise(rb_eArgError, "%s: %d axes given for ndim %d",
130
+ ca_calling_method_name(), argc, (int) ca->ndim);
125
131
  }
126
132
 
127
133
  obj = rb_ca_trans_new(self, imap);
data/ext/ca_obj_triop.c CHANGED
@@ -163,6 +163,7 @@ ca_triop_setup (CATriOp *ca, CArray *op1, CArray *op2, CArray *op3,
163
163
  CATriOp *
164
164
  ca_triop_new (CArray *op1, CArray *op2, CArray *op3, uint16_t op_id)
165
165
  {
166
+ /* check: the setup checks nothing */
166
167
  CATriOp *ca = (CATriOp *) ca_array_alloc(CA_OBJ_TRIOP, op1->ndim);
167
168
  ca_triop_setup(ca, op1, op2, op3, op_id);
168
169
  return ca;
@@ -210,7 +211,7 @@ ca_triop_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
210
211
  ca_size_t s;
211
212
 
212
213
  if ( dir != CA_XFER_GET ) {
213
- rb_raise(rb_eRuntimeError, "CATriOp is read-only (xfer_index PUT)");
214
+ ca_refuse_read_only();
214
215
  }
215
216
 
216
217
  s = ca->bytes;
@@ -296,7 +297,7 @@ ca_triop_eval (CATriOp *to, const ca_lazy_req_t *req, void *data)
296
297
  "CATriOp: kernel not implemented (op_id=%u data_type=%d)",
297
298
  (unsigned) to->op_id, (int) to->data_type);
298
299
  }
299
- if ( to->data_type == CA_OBJECT ) {
300
+ if ( ca_op_raises_on_cell(CA_OP_KIND_TRIOP, to->op_id, to->data_type) ) {
300
301
  CArray *ops[3];
301
302
  ops[0] = to->parent;
302
303
  ops[1] = to->op2;
@@ -322,7 +323,7 @@ ca_triop_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
322
323
  if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
323
324
  ca_lazy_req_t req;
324
325
  if ( dir != CA_XFER_GET ) {
325
- rb_raise(rb_eRuntimeError, "CATriOp is read-only (xfer_stride PUT)");
326
+ ca_refuse_read_only();
326
327
  }
327
328
  ca_lazy_req_region(&req, ap, starts, counts, strides);
328
329
  ca_triop_eval((CATriOp *) ap, &req, data);
@@ -335,7 +336,7 @@ ca_triop_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
335
336
  {
336
337
  ca_lazy_req_t req;
337
338
  if ( dir != CA_XFER_GET ) {
338
- rb_raise(rb_eRuntimeError, "CATriOp is read-only (xfer_addrs PUT)");
339
+ ca_refuse_read_only();
339
340
  }
340
341
  ca_lazy_req_addrs(&req, n, addrs);
341
342
  ca_triop_eval((CATriOp *) ap, &req, data);
@@ -358,15 +359,7 @@ static void
358
359
  ca_triop_func_allocate (void *ap)
359
360
  {
360
361
  CATriOp *ca = (CATriOp *) ap;
361
- ca->ptr = xmalloc(ca_length(ca));
362
- /* CA_OBJECT cells are VALUEs and this buffer is about to be marked as
363
- soon as the view is, so it must not be handed to the GC as raw
364
- xmalloc garbage. */
365
- if ( ca->data_type == CA_OBJECT ) {
366
- VALUE *p = (VALUE *) ca->ptr;
367
- ca_size_t i;
368
- for ( i = 0; i < ca->elements; i++ ) *p++ = Qnil;
369
- }
362
+ ca->ptr = ca_alloc_cells((CArray *) ca);
370
363
  }
371
364
 
372
365
  static void
@@ -381,19 +374,11 @@ ca_triop_func_attach (void *ap)
381
374
  int8_t k;
382
375
  ca_size_t s;
383
376
 
384
- ca->ptr = xmalloc(ca_length(ca));
377
+ ca->ptr = ca_alloc_cells((CArray *) ca);
385
378
 
386
379
  s = ca->bytes;
387
380
  for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
388
381
  for ( k = 0; k < ca->ndim; k++ ) starts[k] = 0;
389
- /* CA_OBJECT cells are VALUEs and this buffer is about to be marked as
390
- soon as the view is, so it must not be handed to the GC as raw
391
- xmalloc garbage. */
392
- if ( ca->data_type == CA_OBJECT ) {
393
- VALUE *p = (VALUE *) ca->ptr;
394
- ca_size_t i;
395
- for ( i = 0; i < ca->elements; i++ ) *p++ = Qnil;
396
- }
397
382
  ca_triop_func_xfer_stride(ca, starts, ca->dim, native, ca->ptr, CA_XFER_GET);
398
383
  }
399
384
 
@@ -416,7 +401,7 @@ static void
416
401
  ca_triop_func_fill_data (void *ap, void *ptr)
417
402
  {
418
403
  (void) ap; (void) ptr;
419
- rb_raise(rb_eRuntimeError, "CATriOp is read-only (fill_data)");
404
+ ca_refuse_read_only();
420
405
  }
421
406
 
422
407
  /* Build out.mask on each read (CAMaskOfOperands): the three operands'
@@ -557,6 +542,9 @@ rb_ca_triop_build (VALUE cary1, VALUE cary2, VALUE cary3, uint16_t op_id)
557
542
  r3 = ca_lazy_settle_scalar(r3, r3_scalar);
558
543
  }
559
544
 
545
+ ca_refuse_without_common_type(r1, r2);
546
+ ca_refuse_without_common_type(r1, r3);
547
+ ca_refuse_without_common_type(r2, r3);
560
548
  TypedData_Get_Struct(r1, CArray, &carray_data_type, op1);
561
549
  TypedData_Get_Struct(r2, CArray, &carray_data_type, op2);
562
550
  TypedData_Get_Struct(r3, CArray, &carray_data_type, op3);
@@ -575,8 +563,7 @@ rb_ca_triop_build (VALUE cary1, VALUE cary2, VALUE cary3, uint16_t op_id)
575
563
 
576
564
  /* No kernel for that data_type: raise as the eager triop does. */
577
565
  if ( ca_triop_kernel_lookup_vvv(op_id, dt1) == ca_triop_not_implement ) {
578
- rb_raise(rb_eCADataTypeError,
579
- "invalid data_type for triop (not implemented)");
566
+ ca_op_refuse_unimplemented(cary1, dt1, rb_eCADataTypeError);
580
567
  }
581
568
  r1 = insert_cast(r1, dt1, &op1);
582
569
  r2 = insert_cast(r2, dt2, &op2);
@@ -589,10 +576,11 @@ rb_ca_triop_build (VALUE cary1, VALUE cary2, VALUE cary3, uint16_t op_id)
589
576
  CArray *anchor = NULL;
590
577
  volatile VALUE r_anchor = Qnil;
591
578
  int8_t anchor_ndim;
592
- /* Pick the largest-ndim non-scalar operand as anchor. */
593
- if ( op1->elements > 1 ) { anchor = op1; r_anchor = r1; }
594
- else if ( op2->elements > 1 ) { anchor = op2; r_anchor = r2; }
595
- else if ( op3->elements > 1 ) { anchor = op3; r_anchor = r3; }
579
+ /* The first operand that is not a scalar is the anchor. An array of
580
+ no cells is one (its shape is the walk's), not a scalar. */
581
+ if ( ! ca_is_scalar(op1) ) { anchor = op1; r_anchor = r1; }
582
+ else if ( ! ca_is_scalar(op2) ) { anchor = op2; r_anchor = r2; }
583
+ else if ( ! ca_is_scalar(op3) ) { anchor = op3; r_anchor = r3; }
596
584
  if ( anchor && anchor != op1 ) {
597
585
  /* op1 is a CScalar but the walk shape is determined by another
598
586
  operand. Lift op1 up to anchor's shape via
@@ -642,6 +630,7 @@ static VALUE
642
630
  rb_ca_triop_s_build (VALUE klass, VALUE cary1, VALUE cary2, VALUE cary3,
643
631
  VALUE op_id_val)
644
632
  {
633
+ /* fits: an operation number from the library's own table */
645
634
  uint16_t op_id = (uint16_t) NUM2UINT(op_id_val);
646
635
  (void) klass;
647
636
  return rb_ca_triop_build(cary1, cary2, cary3, op_id);
@@ -653,9 +642,10 @@ rb_ca_triop_s_build (VALUE klass, VALUE cary1, VALUE cary2, VALUE cary3,
653
642
  static VALUE
654
643
  rb_ca_triop_trapping (VALUE self)
655
644
  {
656
- CArray *ca;
657
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
658
- return ( ca->data_type == CA_OBJECT ) ? Qtrue : Qfalse;
645
+ CATriOp *to;
646
+ TypedData_Get_Struct(self, CATriOp, &catriop_data_type, to);
647
+ return ca_op_raises_on_cell(CA_OP_KIND_TRIOP, to->op_id, to->data_type)
648
+ ? Qtrue : Qfalse;
659
649
  }
660
650
 
661
651
  static VALUE
@@ -679,6 +669,7 @@ rb_ca_triop_op3 (VALUE self)
679
669
  }
680
670
 
681
671
  /* Test instrumentation. */
672
+ #ifdef CARRAY_DEV_BUILD
682
673
  static VALUE
683
674
  rb_ca_triop_s_reset_scratch_counter (VALUE klass)
684
675
  {
@@ -708,6 +699,7 @@ rb_ca_triop_s_materialise_count (VALUE klass)
708
699
  (void) klass;
709
700
  return SIZE2NUM(ca_triop_materialise_call_count);
710
701
  }
702
+ #endif /* CARRAY_DEV_BUILD */
711
703
 
712
704
  static VALUE
713
705
  rb_ca_triop_s_allocate (VALUE klass)
@@ -767,6 +759,7 @@ Init_ca_obj_triop (void)
767
759
  rb_ca_triop_op3, 0);
768
760
 
769
761
  /* Test instrumentation. */
762
+ #ifdef CARRAY_DEV_BUILD
770
763
  rb_define_singleton_method(rb_cCATriOp, "__reset_scratch_counter__",
771
764
  rb_ca_triop_s_reset_scratch_counter, 0);
772
765
  rb_define_singleton_method(rb_cCATriOp, "__scratch_count__",
@@ -775,4 +768,5 @@ Init_ca_obj_triop (void)
775
768
  rb_ca_triop_s_reset_materialise_counter, 0);
776
769
  rb_define_singleton_method(rb_cCATriOp, "__materialise_count__",
777
770
  rb_ca_triop_s_materialise_count, 0);
771
+ #endif
778
772
  }