carray 3.0.2 → 3.0.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.
Files changed (247) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +568 -0
  3. data/README.md +6 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +220 -0
  7. data/ext/ca_axis_group.c +201 -123
  8. data/ext/ca_binop_dispatch.c +46 -52
  9. data/ext/ca_binop_dispatch.h +1 -1
  10. data/ext/ca_categorical_iterator.c +249 -183
  11. data/ext/ca_compare.c +7 -12
  12. data/ext/ca_for_buffer.h +21 -68
  13. data/ext/ca_group_iter.c +38 -23
  14. data/ext/ca_kernel_iterator.c +1765 -2076
  15. data/ext/ca_kernel_iterator.h +584 -566
  16. data/ext/ca_monop_dispatch.c +86 -63
  17. data/ext/ca_monop_dispatch.h +5 -0
  18. data/ext/ca_obj_array.c +223 -56
  19. data/ext/ca_obj_bincmp.c +172 -138
  20. data/ext/ca_obj_binop.c +116 -230
  21. data/ext/ca_obj_bitarray.c +40 -26
  22. data/ext/ca_obj_bitfield.c +100 -68
  23. data/ext/ca_obj_block.c +19 -9
  24. data/ext/ca_obj_byte_swap.c +45 -46
  25. data/ext/ca_obj_const_string.c +269 -44
  26. data/ext/ca_obj_face.c +612 -89
  27. data/ext/ca_obj_face.h +111 -47
  28. data/ext/ca_obj_fake.c +36 -79
  29. data/ext/ca_obj_farray.c +7 -3
  30. data/ext/ca_obj_field.c +33 -8
  31. data/ext/ca_obj_fixlen_string.c +23 -24
  32. data/ext/ca_obj_grid.c +541 -210
  33. data/ext/ca_obj_meld.c +331 -111
  34. data/ext/ca_obj_moncmp.c +80 -65
  35. data/ext/ca_obj_monop.c +177 -149
  36. data/ext/ca_obj_object.c +664 -248
  37. data/ext/ca_obj_record.c +63 -23
  38. data/ext/ca_obj_reduce.c +18 -16
  39. data/ext/ca_obj_refer.c +140 -58
  40. data/ext/ca_obj_remap.c +85 -24
  41. data/ext/ca_obj_repeat.c +24 -9
  42. data/ext/ca_obj_roll.c +121 -16
  43. data/ext/ca_obj_select.c +61 -58
  44. data/ext/ca_obj_select_axis.c +73 -107
  45. data/ext/ca_obj_shift.c +32 -102
  46. data/ext/ca_obj_stack.c +372 -122
  47. data/ext/ca_obj_stride.c +348 -140
  48. data/ext/ca_obj_string.c +88 -22
  49. data/ext/ca_obj_tile.c +38 -21
  50. data/ext/ca_obj_time.c +45 -31
  51. data/ext/ca_obj_timedelta.c +43 -29
  52. data/ext/ca_obj_transpose.c +17 -6
  53. data/ext/ca_obj_triop.c +125 -141
  54. data/ext/ca_obj_window.c +330 -44
  55. data/ext/ca_op_ipower.c +24 -11
  56. data/ext/ca_op_powi.h +57 -30
  57. data/ext/ca_pow5_table.h +656 -0
  58. data/ext/ca_sort_kernels.h +70 -0
  59. data/ext/ca_sweep_engine.c +104 -81
  60. data/ext/ca_sweep_engine.h +7 -20
  61. data/ext/ca_triop_dispatch.c +4 -1
  62. data/ext/ca_triop_dispatch.h +5 -2
  63. data/ext/caframe_csv_reader.c +542 -0
  64. data/ext/carray.h +241 -92
  65. data/ext/carray_access.c +608 -276
  66. data/ext/carray_address_basis.c +494 -97
  67. data/ext/carray_attribute.c +129 -4
  68. data/ext/carray_bincount.c +39 -7
  69. data/ext/carray_broadcast.c +56 -19
  70. data/ext/carray_build_flags.h +1 -1
  71. data/ext/carray_call_cfunc.c +108 -28
  72. data/ext/carray_cast.c +1576 -223
  73. data/ext/carray_cast_func.rb +77 -24
  74. data/ext/carray_class.c +4 -3
  75. data/ext/carray_conversion.c +208 -75
  76. data/ext/carray_copy.c +82 -24
  77. data/ext/carray_core.c +646 -162
  78. data/ext/carray_count.c +171 -88
  79. data/ext/carray_element.c +94 -60
  80. data/ext/carray_factorize.c +670 -324
  81. data/ext/carray_generate.c +260 -83
  82. data/ext/carray_histogram.c +209 -106
  83. data/ext/carray_hold.c +14 -16
  84. data/ext/carray_index_classifier.c +422 -243
  85. data/ext/carray_internal.h +692 -3
  86. data/ext/carray_kernels_bincmp.c +7 -0
  87. data/ext/carray_kernels_binop.c +487 -120
  88. data/ext/carray_kernels_init.c +653 -50
  89. data/ext/carray_kernels_moncmp.c +15 -8
  90. data/ext/carray_kernels_monop.c +99 -43
  91. data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
  92. data/ext/carray_kernels_reduce_boolean.c +112 -36
  93. data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
  94. data/ext/carray_kernels_reduce_extreme.c +3032 -2892
  95. data/ext/carray_kernels_reduce_variance.c +439 -500
  96. data/ext/carray_kernels_scan.c +1097 -488
  97. data/ext/carray_kernels_search.c +3787 -2176
  98. data/ext/carray_kernels_sort.c +1200 -920
  99. data/ext/carray_kernels_triop.c +479 -7
  100. data/ext/carray_key_windows.c +216 -0
  101. data/ext/carray_lazy.c +967 -153
  102. data/ext/carray_loop.c +81 -65
  103. data/ext/carray_mask.c +910 -324
  104. data/ext/carray_math_kernel.h +1 -0
  105. data/ext/carray_median_percentile.c +299 -100
  106. data/ext/carray_memory_view.c +872 -758
  107. data/ext/carray_operator.c +1171 -364
  108. data/ext/carray_order.c +505 -133
  109. data/ext/carray_partition.c +112 -65
  110. data/ext/carray_random.c +327 -239
  111. data/ext/carray_round.c +273 -0
  112. data/ext/carray_scatter.c +346 -78
  113. data/ext/carray_segment.c +257 -0
  114. data/ext/carray_slab.c +249 -86
  115. data/ext/carray_sort.c +224 -227
  116. data/ext/carray_sort_kernel.c +8 -1
  117. data/ext/carray_struct.c +118 -39
  118. data/ext/carray_test.c +193 -69
  119. data/ext/carray_time_text.c +1182 -0
  120. data/ext/carray_undef.c +4 -0
  121. data/ext/carray_utils.c +579 -113
  122. data/ext/extconf.rb +27 -2
  123. data/ext/mk_call_cfunc.rb +19 -4
  124. data/ext/mk_pow5_table.rb +35 -0
  125. data/ext/mkkernel.rb +1202 -1014
  126. data/ext/ruby_carray.c +17 -5
  127. data/ext/version.h +4 -4
  128. data/ext/version.rb +4 -2
  129. data/lib/carray/attribute.rb +160 -17
  130. data/lib/carray/autoload_carray.rb +23 -27
  131. data/lib/carray/autoload_method_extension.rb +20 -5
  132. data/lib/carray/axis_group.rb +360 -63
  133. data/lib/carray/basics.rb +162 -28
  134. data/lib/carray/bincount_nd.rb +18 -2
  135. data/lib/carray/block_iterator.rb +231 -58
  136. data/lib/carray/boolean_reduce.rb +34 -42
  137. data/lib/carray/categorical.rb +242 -52
  138. data/lib/carray/categorical_iterator.rb +437 -827
  139. data/lib/carray/complex.rb +41 -34
  140. data/lib/carray/conditional.rb +150 -14
  141. data/lib/carray/const_string.rb +59 -4
  142. data/lib/carray/construct.rb +15 -11
  143. data/lib/carray/data_type_extension.rb +1 -0
  144. data/lib/carray/distance_limit.rb +77 -0
  145. data/lib/carray/fixlen_string.rb +7 -1
  146. data/lib/carray/frame/column_verbs.rb +70 -0
  147. data/lib/carray/frame/concat.rb +157 -6
  148. data/lib/carray/frame/convert.rb +82 -7
  149. data/lib/carray/frame/csv_parser.rb +688 -87
  150. data/lib/carray/frame/describe.rb +80 -0
  151. data/lib/carray/frame/frame.rb +369 -45
  152. data/lib/carray/frame/group.rb +631 -90
  153. data/lib/carray/frame/io.rb +506 -79
  154. data/lib/carray/frame/join.rb +411 -62
  155. data/lib/carray/frame/records.rb +116 -19
  156. data/lib/carray/frame/reshape.rb +455 -0
  157. data/lib/carray/frame/sort.rb +30 -18
  158. data/lib/carray/frame/verbs.rb +868 -61
  159. data/lib/carray/frame/windows.rb +117 -0
  160. data/lib/carray/frame.rb +4 -0
  161. data/lib/carray/fuse_source.rb +118 -2
  162. data/lib/carray/fusion.rb +257 -42
  163. data/lib/carray/histogram.rb +6 -1
  164. data/lib/carray/inspect.rb +54 -13
  165. data/lib/carray/iterator.rb +99 -9
  166. data/lib/carray/key_windows.rb +620 -0
  167. data/lib/carray/lazy.rb +216 -193
  168. data/lib/carray/mask_gap_fill.rb +112 -92
  169. data/lib/carray/math.rb +32 -19
  170. data/lib/carray/meld_reduce.rb +52 -21
  171. data/lib/carray/methods/align_addr.rb +8 -4
  172. data/lib/carray/methods/bin.rb +26 -18
  173. data/lib/carray/methods/bincount.rb +18 -2
  174. data/lib/carray/methods/bit_string.rb +15 -4
  175. data/lib/carray/methods/choose.rb +16 -3
  176. data/lib/carray/methods/composition.rb +18 -10
  177. data/lib/carray/methods/factorize.rb +2 -2
  178. data/lib/carray/methods/gather_nd.rb +25 -5
  179. data/lib/carray/methods/insert_block.rb +9 -14
  180. data/lib/carray/methods/is_between.rb +59 -0
  181. data/lib/carray/methods/is_in.rb +140 -10
  182. data/lib/carray/methods/join.rb +2 -7
  183. data/lib/carray/methods/lag.rb +49 -0
  184. data/lib/carray/methods/locate_addr.rb +182 -45
  185. data/lib/carray/methods/mode.rb +18 -1
  186. data/lib/carray/methods/nunique.rb +11 -6
  187. data/lib/carray/methods/repeat.rb +1 -20
  188. data/lib/carray/methods/resize.rb +21 -23
  189. data/lib/carray/methods/snap.rb +34 -12
  190. data/lib/carray/methods/unique.rb +11 -2
  191. data/lib/carray/methods/value_counts.rb +4 -11
  192. data/lib/carray/record_order.rb +208 -0
  193. data/lib/carray/rng.rb +3 -0
  194. data/lib/carray/runtime.rb +65 -17
  195. data/lib/carray/segment_iterator.rb +1221 -0
  196. data/lib/carray/serialize.rb +214 -30
  197. data/lib/carray/slab_iterator.rb +101 -27
  198. data/lib/carray/stack.rb +10 -4
  199. data/lib/carray/string.rb +105 -5
  200. data/lib/carray/string_operation_extension.rb +12 -4
  201. data/lib/carray/struct.rb +137 -58
  202. data/lib/carray/struct_builder.rb +124 -17
  203. data/lib/carray/time.rb +1222 -186
  204. data/lib/carray/window_iterator.rb +242 -81
  205. data/lib/carray.rb +9 -2
  206. data/yard-stubs/ca_obj_array.rb +4 -4
  207. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  208. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  209. data/yard-stubs/ca_obj_fake.rb +1 -1
  210. data/yard-stubs/ca_obj_field.rb +5 -1
  211. data/yard-stubs/ca_obj_grid.rb +21 -10
  212. data/yard-stubs/ca_obj_refer.rb +5 -4
  213. data/yard-stubs/ca_obj_roll.rb +2 -3
  214. data/yard-stubs/ca_obj_shift.rb +5 -1
  215. data/yard-stubs/ca_obj_stride.rb +10 -7
  216. data/yard-stubs/ca_obj_tile.rb +1 -1
  217. data/yard-stubs/ca_obj_transpose.rb +1 -1
  218. data/yard-stubs/ca_obj_window.rb +9 -5
  219. data/yard-stubs/carray_access.rb +11 -5
  220. data/yard-stubs/carray_attribute.rb +0 -5
  221. data/yard-stubs/carray_broadcast.rb +1 -1
  222. data/yard-stubs/carray_cast.rb +88 -43
  223. data/yard-stubs/carray_conversion.rb +15 -2
  224. data/yard-stubs/carray_copy.rb +12 -5
  225. data/yard-stubs/carray_core.rb +3 -3
  226. data/yard-stubs/carray_count.rb +9 -0
  227. data/yard-stubs/carray_element.rb +10 -4
  228. data/yard-stubs/carray_generate.rb +21 -1
  229. data/yard-stubs/carray_lazy.rb +5 -1
  230. data/yard-stubs/carray_loop.rb +4 -1
  231. data/yard-stubs/carray_mask.rb +60 -12
  232. data/yard-stubs/carray_math.rb +52 -14
  233. data/yard-stubs/carray_median_percentile.rb +15 -8
  234. data/yard-stubs/carray_memory_view.rb +40 -23
  235. data/yard-stubs/carray_order.rb +61 -29
  236. data/yard-stubs/carray_random.rb +13 -4
  237. data/yard-stubs/carray_scatter.rb +21 -9
  238. data/yard-stubs/carray_segment.rb +72 -0
  239. data/yard-stubs/carray_slab.rb +10 -2
  240. data/yard-stubs/carray_sort.rb +49 -8
  241. data/yard-stubs/carray_test.rb +15 -3
  242. data/yard-stubs/carray_utils.rb +0 -26
  243. metadata +19 -5
  244. data/ext/ca_for_each_element.h +0 -239
  245. data/ext/carray_kernels_map.c +0 -3467
  246. data/lib/carray/arrow_tensor.rb +0 -401
  247. data/lib/carray/table.rb +0 -108
data/ext/ca_obj_string.c CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  Surface data_type is CA_OBJECT (== storage): unlike the NonNumeric Faces
13
13
  (CATime etc.) there is no CA_FIXLEN gate. Per-cell fetch returns
14
- the stored String VALUE directly (no storage_to_scalar decode). Numeric
14
+ the stored String VALUE directly (no storage_to_element decode). Numeric
15
15
  dispatch lands on the :object kernels, so String-meaningful ops (+, sort
16
16
  via <=>) work and nonsensical ones raise at the Ruby method call.
17
17
 
@@ -20,6 +20,7 @@
20
20
  --------------------------------------------------------------------------- */
21
21
 
22
22
  #include "carray.h"
23
+ #include "carray_internal.h"
23
24
  #include "ca_obj_face.h"
24
25
 
25
26
  typedef struct {
@@ -75,7 +76,7 @@ const rb_data_type_t castring_data_type = {
75
76
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
76
77
  };
77
78
 
78
- static int8_t CA_OBJ_STRING;
79
+ int8_t CA_OBJ_STRING; /* non-static: read by the store path in carray_access.c */
79
80
  static VALUE rb_cCAString;
80
81
 
81
82
  /* ------------------------------------------------------------------- */
@@ -88,6 +89,12 @@ ca_string_setup (CAString *ca, CArray *parent)
88
89
  "CAString requires object storage (parent.data_type != CA_OBJECT)");
89
90
  }
90
91
 
92
+ /* ca == NULL asks for the checks above only, so that a constructor can
93
+ run them before it allocates. */
94
+ if ( ca == NULL ) {
95
+ return 0;
96
+ }
97
+
91
98
  ca->obj_type = CA_OBJ_STRING;
92
99
  ca->data_type = CA_OBJECT;
93
100
  /* ORDERABLE + COMPARABLE, and both hold by construction: a storage cell
@@ -112,9 +119,6 @@ ca_string_setup (CAString *ca, CArray *parent)
112
119
  ca->attach = 0;
113
120
  ca->nosync = 0;
114
121
 
115
- if ( ca_has_mask(parent) ) {
116
- ca_create_mask((CArray *) ca);
117
- }
118
122
 
119
123
  if ( ca_is_scalar(parent) ) {
120
124
  ca_set_flag(ca, CA_FLAG_SCALAR);
@@ -130,8 +134,11 @@ ca_string_setup (CAString *ca, CArray *parent)
130
134
  CAString *
131
135
  ca_string_new (CArray *parent)
132
136
  {
133
- CAString *ca = (CAString *) ca_array_alloc(CA_OBJ_STRING, parent->ndim);
137
+ CAString *ca;
138
+ ca_string_setup(NULL, parent);
139
+ ca = (CAString *) ca_array_alloc(CA_OBJ_STRING, parent->ndim);
134
140
  ca_string_setup(ca, parent);
141
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
135
142
  return ca;
136
143
  }
137
144
 
@@ -169,18 +176,6 @@ ca_string_func_allocate (void *ap)
169
176
  ca->ptr = ca->parent->ptr;
170
177
  }
171
178
 
172
- static void
173
- ca_string_func_create_mask (void *ap)
174
- {
175
- CAString *ca = (CAString *) ap;
176
- ca_update_mask(ca->parent);
177
- if ( ! ca->parent->mask ) {
178
- ca_create_mask(ca->parent);
179
- }
180
- ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
181
- CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
182
- }
183
-
184
179
  ca_operation_function_t ca_string_func = {
185
180
  -1, /* CA_OBJ_STRING — filled by ca_install_obj_type */
186
181
  CA_VIEW_ARRAY,
@@ -191,7 +186,7 @@ ca_operation_function_t ca_string_func = {
191
186
  ca_face_sync,
192
187
  ca_face_detach,
193
188
  ca_face_fill_data,
194
- ca_string_func_create_mask,
189
+ ca_view_func_create_mask,
195
190
  ca_face_xfer_index,
196
191
  ca_face_xfer_addrs,
197
192
  NULL, /* fold_stride: identity Face is not foldable */
@@ -203,6 +198,69 @@ ca_operation_function_t ca_string_func = {
203
198
 
204
199
  /* ------------------------------------------------------------------- */
205
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. */
220
+ static void
221
+ ca_string_check_cells (VALUE parent_val, CArray *parent)
222
+ {
223
+ ca_size_t i;
224
+ char where[64];
225
+ if ( ca_is_entity(parent) && parent->ptr ) {
226
+ VALUE *p = (VALUE *) parent->ptr;
227
+ boolean8_t *m = ( parent->mask && parent->mask->ptr )
228
+ ? (boolean8_t *) parent->mask->ptr : NULL;
229
+ for (i = 0; i < parent->elements; i++) {
230
+ if ( m && m[i] ) continue;
231
+ if ( ! RB_TYPE_P(p[i], T_STRING) ) {
232
+ snprintf(where, sizeof(where), "cell %" PRId64, (int64_t) i);
233
+ ca_string_refuse_cell(p[i], where);
234
+ }
235
+ }
236
+ }
237
+ else {
238
+ volatile VALUE list =
239
+ rb_funcall(rb_funcall(parent_val, rb_intern("flatten"), 0),
240
+ rb_intern("to_a"), 0);
241
+ long n = RARRAY_LEN(list), j;
242
+ for (j = 0; j < n; j++) {
243
+ VALUE v = rb_ary_entry(list, j);
244
+ if ( v == CA_UNDEF ) continue;
245
+ if ( ! RB_TYPE_P(v, T_STRING) ) {
246
+ snprintf(where, sizeof(where), "cell %ld", j);
247
+ ca_string_refuse_cell(v, where);
248
+ }
249
+ }
250
+ }
251
+ }
252
+
253
+ /* The write hook: a value stored into a CAString is a String. */
254
+ static VALUE
255
+ ca_string_element_to_storage (VALUE self, VALUE v)
256
+ {
257
+ (void) self;
258
+ if ( ! RB_TYPE_P(v, T_STRING) ) {
259
+ ca_string_refuse_cell(v, "a value stored into a CAString");
260
+ }
261
+ return v;
262
+ }
263
+
206
264
  /* CAString.wrap(object_array) — zero-copy Face wrap of a CA_OBJECT array */
207
265
  VALUE
208
266
  rb_ca_string_wrap (VALUE parent_val)
@@ -214,6 +272,8 @@ rb_ca_string_wrap (VALUE parent_val)
214
272
  rb_check_carray_object(parent_val);
215
273
  TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
216
274
 
275
+ ca_string_setup(NULL, parent);
276
+ ca_string_check_cells(parent_val, parent);
217
277
  ca = ca_string_new(parent);
218
278
  obj = ca_wrap_struct(ca);
219
279
  rb_ca_set_parent(obj, parent_val);
@@ -239,11 +299,13 @@ rb_ca_string_initialize_copy (VALUE self, VALUE other)
239
299
  {
240
300
  CAString *ca, *cs;
241
301
  TypedData_Get_Struct(self, CAString, &castring_data_type, ca);
302
+ ca_check_uninitialized(ca);
242
303
  TypedData_Get_Struct(other, CAString, &castring_data_type, cs);
243
304
  if ( ca_func[CA_OBJ_STRING].pool_init ) {
244
305
  ca_array_pool_alloc(ca, CA_OBJ_STRING, cs->parent->ndim);
245
306
  }
246
307
  ca_string_setup(ca, cs->parent);
308
+ ca_view_inherit_mask((VALUE) ca);
247
309
  return self;
248
310
  }
249
311
 
@@ -268,7 +330,11 @@ Init_ca_obj_string (void)
268
330
  rb_ca_string_initialize_copy, 1);
269
331
  rb_define_singleton_method(rb_cCAString, "wrap", rb_ca_string_wrap_method, 1);
270
332
 
271
- /* VALUE storage is per-process, so the Face cannot be carried across
272
- multi-parent constructions (CAStack / Marshal / MemoryView). */
273
- ca_face_register_state_portable(CA_OBJ_STRING, 0);
333
+ ca_face_register_element_to_storage(CA_OBJ_STRING,
334
+ ca_string_element_to_storage);
335
+
336
+ /* A cell is the String itself, so the Face is the same over any parent:
337
+ CAStack / CAMeld / concatenate can carry it (unlike CAConstString, whose
338
+ cells point into one parent's buffer). */
339
+ ca_face_register_state_portable(CA_OBJ_STRING, 1);
274
340
  }
data/ext/ca_obj_tile.c CHANGED
@@ -16,6 +16,7 @@
16
16
  ---------------------------------------------------------------------------- */
17
17
 
18
18
  #include "carray.h"
19
+ #include "carray_internal.h"
19
20
  #include "ca_composite_dispatch.h"
20
21
  #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
21
22
 
@@ -75,17 +76,24 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
75
76
  ndim = parent->ndim;
76
77
  bytes = parent->bytes;
77
78
 
78
- elements = 1;
79
- for (i = 0; i < ndim; i++) {
80
- if ( reps[i] <= 0 ) {
81
- rb_raise(rb_eIndexError,
82
- "invalid reps for %d-th dimension (must be positive)", i);
83
- }
84
- if ( parent->dim[i] <= 0 ) {
85
- rb_raise(rb_eIndexError,
86
- "invalid parent dim for %d-th dimension", i);
79
+ {
80
+ ca_size_t tiled[CA_RANK_MAX];
81
+ for (i = 0; i < ndim; i++) {
82
+ if ( reps[i] <= 0 ) {
83
+ rb_raise(rb_eIndexError,
84
+ "invalid reps for %d-th dimension (must be positive)", i);
85
+ }
86
+ if ( __builtin_mul_overflow(parent->dim[i], reps[i], &tiled[i]) ) {
87
+ rb_raise(rb_eArgError, "too large byte length");
88
+ }
87
89
  }
88
- elements *= parent->dim[i] * reps[i];
90
+ elements = ca_shape_elements(ndim, tiled, bytes);
91
+ }
92
+
93
+ /* ca == NULL asks for the checks above only, so that a constructor can
94
+ run them before it allocates. */
95
+ if ( ca == NULL ) {
96
+ return 0;
89
97
  }
90
98
 
91
99
  ca->obj_type = CA_OBJ_TILE;
@@ -108,9 +116,6 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
108
116
  ca->dim[i] = parent->dim[i] * reps[i];
109
117
  }
110
118
 
111
- if ( ca_has_mask(parent) ) {
112
- ca_create_mask(ca);
113
- }
114
119
 
115
120
  return 0;
116
121
  }
@@ -118,8 +123,11 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
118
123
  CATile *
119
124
  ca_tile_new (CArray *parent, ca_size_t *reps)
120
125
  {
121
- CATile *ca = ALLOC(CATile);
126
+ CATile *ca;
127
+ ca_tile_setup(NULL, parent, reps);
128
+ ca = ALLOC(CATile);
122
129
  ca_tile_setup(ca, parent, reps);
130
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
123
131
  return ca;
124
132
  }
125
133
 
@@ -196,6 +204,7 @@ static void
196
204
  ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
197
205
  ca_size_t *strides, void *data, int dir)
198
206
  {
207
+ if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
199
208
  CATile *ca = (CATile *) ap;
200
209
  CArray *parent = ca->parent;
201
210
  int8_t ndim = ca->ndim;
@@ -233,6 +242,7 @@ ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
233
242
  ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
234
243
  for (k = 0; k < ndim; k++) base += starts[k] * tnative[k];
235
244
  for (k = 0; k < ndim; k++) idx[k] = 0;
245
+ /* empty: the slot returns on an empty region at its entry */
236
246
  while (1) {
237
247
  ca_size_t toff = base, tidx[CA_RANK_MAX];
238
248
  for (k = 0; k < ndim; k++) toff += idx[k] * strides[k];
@@ -247,6 +257,7 @@ ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
247
257
  }
248
258
 
249
259
  for (k = 0; k < ndim; k++) o[k] = 0;
260
+ /* empty: the slot returns on an empty region at its entry */
250
261
  while (1) {
251
262
  ca_size_t pbase = 0, doff = 0, i;
252
263
  for (k = 0; k < inner; k++) {
@@ -392,7 +403,7 @@ ca_tile_func_allocate (void *ap)
392
403
  {
393
404
  CATile *ca = (CATile *) ap;
394
405
  ca_attach(ca->parent);
395
- ca->ptr = xmalloc(ca_length(ca));
406
+ ca->ptr = ca_alloc_cells((CArray *) ca);
396
407
  }
397
408
 
398
409
  static void
@@ -400,7 +411,7 @@ ca_tile_func_attach (void *ap)
400
411
  {
401
412
  CATile *ca = (CATile *) ap;
402
413
  ca_attach(ca->parent);
403
- ca->ptr = xmalloc(ca_length(ca));
414
+ ca->ptr = ca_alloc_cells((CArray *) ca);
404
415
  ca_tile_attach_into(ca, ca->ptr);
405
416
  }
406
417
 
@@ -445,10 +456,13 @@ ca_tile_func_xfer_all (void *ap, void *data, int dir)
445
456
  parent->ptr = parent_scratch;
446
457
  if ( dir == CA_XFER_GET ) ca_tile_attach_into(ca, (char *) data);
447
458
  else ca_tile_sync_from(ca, (char *) data);
459
+ /* Put parent->ptr back before the PUT: the PUT can raise (a lazy
460
+ backing's sync failing), and the scratch is gone once this
461
+ frame is. */
462
+ parent->ptr = parent_ptr_saved;
448
463
  if ( dir == CA_XFER_PUT ) {
449
464
  ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
450
465
  }
451
- parent->ptr = parent_ptr_saved;
452
466
  ALLOCV_END(holder);
453
467
  }
454
468
  }
@@ -466,10 +480,7 @@ static void
466
480
  ca_tile_func_create_mask (void *ap)
467
481
  {
468
482
  CATile *ca = (CATile *) ap;
469
- ca_update_mask(ca->parent);
470
- if ( ! ca->parent->mask ) {
471
- ca_create_mask(ca->parent);
472
- }
483
+ ca_create_mask(ca->parent);
473
484
  ca->mask = (CArray *) ca_tile_new(ca->parent->mask, ca->reps);
474
485
  }
475
486
 
@@ -571,11 +582,14 @@ rb_ca_tile_initialize_copy (VALUE self, VALUE other)
571
582
  {
572
583
  CATile *ca, *cs;
573
584
  TypedData_Get_Struct(self, CATile, &catile_data_type, ca);
585
+ ca_check_uninitialized(ca);
574
586
  TypedData_Get_Struct(other, CATile, &catile_data_type, cs);
575
587
  ca_tile_setup(ca, cs->parent, cs->reps);
588
+ ca_view_inherit_mask((VALUE) ca);
576
589
  return self;
577
590
  }
578
591
 
592
+ #ifdef CARRAY_DEV_BUILD
579
593
  /* Debug-only accessor returning the tile descriptor as a Hash.
580
594
  Naming: leading underscore signals internal use. */
581
595
  static VALUE
@@ -597,6 +611,7 @@ rb_ca_tile_descriptor (VALUE self)
597
611
  rb_hash_aset(hash, ID2SYM(rb_intern("ndim")), INT2NUM(ca->ndim));
598
612
  return hash;
599
613
  }
614
+ #endif
600
615
 
601
616
  void
602
617
  Init_ca_obj_tile (void)
@@ -616,7 +631,9 @@ Init_ca_obj_tile (void)
616
631
  rb_define_method(rb_cCATile, "initialize_copy",
617
632
  rb_ca_tile_initialize_copy, 1);
618
633
 
634
+ #ifdef CARRAY_DEV_BUILD
619
635
  /* Debug-only descriptor accessor. */
620
636
  rb_define_method(rb_cCATile, "_tile_descriptor",
621
637
  rb_ca_tile_descriptor, 0);
638
+ #endif
622
639
  }
data/ext/ca_obj_time.c CHANGED
@@ -14,6 +14,7 @@
14
14
  --------------------------------------------------------------------------- */
15
15
 
16
16
  #include "carray.h"
17
+ #include "carray_internal.h"
17
18
  #include "ca_obj_face.h"
18
19
 
19
20
  /* unit enum (base epoch is 1970-01-01) */
@@ -36,7 +37,7 @@ enum {
36
37
  typedef struct {
37
38
  /* === CAView prefix === */
38
39
  int16_t obj_type;
39
- int8_t data_type; /* fixed to CA_INT64 */
40
+ int8_t data_type; /* surface: CA_FIXLEN (storage is the int64 parent) */
40
41
  int8_t ndim;
41
42
  int32_t flags; /* CA_FLAG_IS_FACE set */
42
43
  ca_size_t bytes; /* fixed to sizeof(int64_t) */
@@ -153,6 +154,21 @@ rb_ca_time_element_initialize (VALUE self, VALUE value, VALUE unit)
153
154
  return self;
154
155
  }
155
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
+
156
172
  static VALUE
157
173
  rb_ca_time_element_value (VALUE self)
158
174
  {
@@ -182,6 +198,12 @@ ca_time_setup (CATime *ca, CArray *parent, int8_t unit, int64_t count)
182
198
  "CATime requires int64 storage (parent.data_type != CA_INT64)");
183
199
  }
184
200
 
201
+ /* ca == NULL asks for the checks above only, so that a constructor can
202
+ run them before it allocates. */
203
+ if ( ca == NULL ) {
204
+ return 0;
205
+ }
206
+
185
207
  ca->obj_type = CA_OBJ_TIME;
186
208
  /* The surface data_type is CA_FIXLEN, not CA_INT64: this routes
187
209
  mkkernel dispatch onto the ca_*_not_implement stubs so numeric
@@ -209,9 +231,6 @@ ca_time_setup (CATime *ca, CArray *parent, int8_t unit, int64_t count)
209
231
  ca->unit = unit;
210
232
  ca->count = count;
211
233
 
212
- if ( ca_has_mask(parent) ) {
213
- ca_create_mask((CArray *) ca);
214
- }
215
234
 
216
235
  if ( ca_is_scalar(parent) ) {
217
236
  ca_set_flag(ca, CA_FLAG_SCALAR);
@@ -227,8 +246,11 @@ ca_time_setup (CATime *ca, CArray *parent, int8_t unit, int64_t count)
227
246
  CATime *
228
247
  ca_time_new (CArray *parent, int8_t unit, int64_t count)
229
248
  {
230
- CATime *ca = (CATime *) ca_array_alloc(CA_OBJ_TIME, parent->ndim);
249
+ CATime *ca;
250
+ ca_time_setup(NULL, parent, unit, count);
251
+ ca = (CATime *) ca_array_alloc(CA_OBJ_TIME, parent->ndim);
231
252
  ca_time_setup(ca, parent, unit, count);
253
+ ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
232
254
  return ca;
233
255
  }
234
256
 
@@ -266,18 +288,6 @@ ca_time_func_allocate (void *ap)
266
288
  ca->ptr = ca->parent->ptr;
267
289
  }
268
290
 
269
- static void
270
- ca_time_func_create_mask (void *ap)
271
- {
272
- CATime *ca = (CATime *) ap;
273
- ca_update_mask(ca->parent);
274
- if ( ! ca->parent->mask ) {
275
- ca_create_mask(ca->parent);
276
- }
277
- ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
278
- CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
279
- }
280
-
281
291
  ca_operation_function_t ca_time_func = {
282
292
  -1, /* CA_OBJ_TIME — filled by ca_install_obj_type */
283
293
  CA_VIEW_ARRAY,
@@ -288,7 +298,7 @@ ca_operation_function_t ca_time_func = {
288
298
  ca_face_sync,
289
299
  ca_face_detach,
290
300
  ca_face_fill_data,
291
- ca_time_func_create_mask,
301
+ ca_view_func_create_mask,
292
302
  ca_face_xfer_index,
293
303
  ca_face_xfer_addrs,
294
304
  NULL, /* fold_stride: identity Face is not foldable */
@@ -401,7 +411,7 @@ rb_ca_time_wrap (VALUE parent_val, int8_t unit, int64_t count)
401
411
  return obj;
402
412
  }
403
413
 
404
- /* __wrap__(raw, unit_spec) — primitive; unit_spec is Symbol / String /
414
+ /* wrap_storage(raw, unit_spec) — primitive; unit_spec is Symbol / String /
405
415
  Resolution / nil (normalized here). */
406
416
  static VALUE
407
417
  rb_ca_time_wrap_method (VALUE klass, VALUE raw, VALUE unit_spec)
@@ -422,16 +432,16 @@ rb_ca_time_unit (VALUE self)
422
432
  return ca_time_resolution(ca->count, ca->unit);
423
433
  }
424
434
 
425
- /* storage_to_scalar implemented in C to avoid per-cell Ruby method dispatch
426
- on the fetch hot path. CAREFUL: there must be no Ruby `storage_to_scalar`
435
+ /* storage_to_element implemented in C to avoid per-cell Ruby method dispatch
436
+ on the fetch hot path. CAREFUL: there must be no Ruby `storage_to_element`
427
437
  def in lib/carray/time.rb — require order would let a Ruby version
428
- shadow this C method (the Ruby `scalar_to_storage` write hook is a
438
+ shadow this C method (the Ruby `element_to_storage` write hook is a
429
439
  distinct method and does not collide).
430
440
  Since the Face surface is CA_FIXLEN, fetch delivers an 8-byte raw
431
441
  String. Decode it as the parent int64 (= storage), then construct
432
442
  CATime::Element(epoch, unit). */
433
443
  static VALUE
434
- rb_ca_time_storage_to_scalar (VALUE self, VALUE raw)
444
+ rb_ca_time_storage_to_element (VALUE self, VALUE raw)
435
445
  {
436
446
  CATime *ca;
437
447
  CATimeElement *s;
@@ -443,7 +453,7 @@ rb_ca_time_storage_to_scalar (VALUE self, VALUE raw)
443
453
  if ( TYPE(raw) == T_STRING ) {
444
454
  if ( RSTRING_LEN(raw) != (long) sizeof(int64_t) ) {
445
455
  rb_raise(rb_eArgError,
446
- "CATime#storage_to_scalar: expected %lu bytes, got %ld",
456
+ "CATime#storage_to_element: expected %lu bytes, got %ld",
447
457
  (unsigned long) sizeof(int64_t), RSTRING_LEN(raw));
448
458
  }
449
459
  memcpy(&epoch, RSTRING_PTR(raw), sizeof(int64_t));
@@ -476,11 +486,13 @@ rb_ca_time_initialize_copy (VALUE self, VALUE other)
476
486
  {
477
487
  CATime *ca, *cs;
478
488
  TypedData_Get_Struct(self, CATime, &catime_data_type, ca);
489
+ ca_check_uninitialized(ca);
479
490
  TypedData_Get_Struct(other, CATime, &catime_data_type, cs);
480
491
  if ( ca_func[CA_OBJ_TIME].pool_init ) {
481
492
  ca_array_pool_alloc(ca, CA_OBJ_TIME, cs->parent->ndim);
482
493
  }
483
494
  ca_time_setup(ca, cs->parent, cs->unit, cs->count);
495
+ ca_view_inherit_mask((VALUE) ca);
484
496
  return self;
485
497
  }
486
498
 
@@ -514,15 +526,15 @@ Init_ca_obj_time (void)
514
526
  rb_define_method(rb_cCATime, "initialize_copy",
515
527
  rb_ca_time_initialize_copy, 1);
516
528
 
517
- rb_define_singleton_method(rb_cCATime, "__wrap__",
518
- 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);
519
531
  rb_define_method(rb_cCATime, "unit", rb_ca_time_unit, 0);
520
- rb_define_method(rb_cCATime, "storage_to_scalar",
521
- rb_ca_time_storage_to_scalar, 1);
522
- /* Registers the C-level fast path so CA_FACE_STORAGE_TO_SCALAR_IF_FACE can
532
+ rb_define_method(rb_cCATime, "storage_to_element",
533
+ rb_ca_time_storage_to_element, 1);
534
+ /* Registers the C-level fast path so CA_FACE_STORAGE_TO_ELEMENT_IF_FACE can
523
535
  skip rb_funcall on the hot path. */
524
- ca_face_register_storage_to_scalar(CA_OBJ_TIME,
525
- rb_ca_time_storage_to_scalar);
536
+ ca_face_register_storage_to_element(CA_OBJ_TIME,
537
+ rb_ca_time_storage_to_element);
526
538
  ca_face_register_state_compatible(CA_OBJ_TIME,
527
539
  ca_time_state_compatible);
528
540
  /* unit is pure metadata (= no per-parent buffer), so the Face wrap can
@@ -541,6 +553,8 @@ Init_ca_obj_time (void)
541
553
  rb_ca_time_element_s_allocate);
542
554
  rb_define_method(rb_cCATimeElement, "initialize",
543
555
  rb_ca_time_element_initialize, 2);
556
+ rb_define_method(rb_cCATimeElement, "initialize_copy",
557
+ rb_ca_time_element_initialize_copy, 1);
544
558
  rb_define_method(rb_cCATimeElement, "value",
545
559
  rb_ca_time_element_value, 0);
546
560
  rb_define_method(rb_cCATimeElement, "unit",