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_moncmp.c CHANGED
@@ -132,6 +132,7 @@ ca_moncmp_setup (CAMonCmp *ca, CArray *parent, uint16_t op_id)
132
132
  CAMonCmp *
133
133
  ca_moncmp_new (CArray *parent, uint16_t op_id)
134
134
  {
135
+ /* check: the setup checks nothing */
135
136
  CAMonCmp *ca = (CAMonCmp *) ca_array_alloc(CA_OBJ_MONCMP, parent->ndim);
136
137
  ca_moncmp_setup(ca, parent, op_id);
137
138
  return ca;
@@ -179,7 +180,7 @@ ca_moncmp_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
179
180
  int8_t k;
180
181
 
181
182
  if ( dir != CA_XFER_GET ) {
182
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_index PUT)");
183
+ ca_refuse_read_only();
183
184
  }
184
185
  for ( k = ca->ndim - 1; k >= 0; k-- ) {
185
186
  starts[k] = idx[k];
@@ -189,24 +190,6 @@ ca_moncmp_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
189
190
  ca_moncmp_func_xfer_stride(ca, starts, counts, strides, data, CA_XFER_GET);
190
191
  }
191
192
 
192
- static void
193
- ca_moncmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
194
- void *data, int dir)
195
- {
196
- CAMonCmp *ca = (CAMonCmp *) ap;
197
- ca_size_t i;
198
- char *out = (char *) data;
199
-
200
- if ( dir != CA_XFER_GET ) {
201
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_addrs PUT)");
202
- }
203
- for ( i = 0; i < n; i++ ) {
204
- ca_size_t idx[CA_RANK_MAX];
205
- ca_addr2index((CArray *)ca, addrs[i], idx);
206
- ca_moncmp_func_xfer_index(ca, idx, out + i, CA_XFER_GET);
207
- }
208
- }
209
-
210
193
  ca_size_t ca_moncmp_scratch_acquire_count = 0;
211
194
  ca_size_t ca_moncmp_materialise_call_count = 0;
212
195
  ca_size_t ca_moncmp_leaf_inplace_count = 0;
@@ -242,55 +225,30 @@ ca_moncmp_try_leaf_inplace (CArray *p,
242
225
  return 1;
243
226
  }
244
227
 
228
+ /* Evaluate the cells a request names into `data` (packed, n cells). */
245
229
  static void
246
- ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
247
- ca_size_t *strides, void *data, int dir)
230
+ ca_moncmp_eval (CAMonCmp *mc, const ca_lazy_req_t *req, void *data)
248
231
  {
249
- CAMonCmp *mc = (CAMonCmp *) ap;
250
- ca_size_t slab_n;
251
- int8_t k;
232
+ ca_size_t slab_n = req->n;
252
233
  void *scratch;
253
234
  ca_size_t operand_bytes;
254
- ca_size_t operand_strides[CA_RANK_MAX];
255
235
  int is_contig;
256
236
 
257
- if ( dir != CA_XFER_GET ) {
258
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_stride PUT)");
259
- }
260
237
  ca_moncmp_materialise_call_count++;
261
238
 
262
- slab_n = 1;
263
- for ( k = 0; k < mc->ndim; k++ ) slab_n *= counts[k];
264
-
265
239
  operand_bytes = mc->parent->bytes;
266
240
 
267
- /* The operand's cell is operand_bytes wide where this view's is one byte
268
- (CA_BOOLEAN), so the caller's strides have to be restated at the
269
- operand's cell size before the pull; strides[k] / bytes is the index
270
- step, which is what the two spaces share.
271
-
272
- is_contig says the caller asked for the row-major slab that xfer_all
273
- and attach send. Only then does the parent's own buffer hold the
274
- wanted cells in the packed order the kernel reads them in, so it is
275
- also the only case the leaf in-place path is good for. */
276
- {
277
- ca_size_t native = mc->bytes;
278
- is_contig = 1;
279
- for ( k = mc->ndim - 1; k >= 0; k-- ) {
280
- operand_strides[k] = strides[k] / mc->bytes * operand_bytes;
281
- if ( strides[k] != native ) {
282
- is_contig = 0;
283
- }
284
- native *= mc->dim[k];
285
- }
286
- }
241
+ /* The leaf in-place path reads the parent's own buffer, which holds the
242
+ wanted cells in the order the kernel reads them only for the row-major
243
+ slab that xfer_all and attach send. */
244
+ is_contig = ca_lazy_req_is_packed(req, mc);
287
245
 
288
246
  /* === 1. pull parent (leaf-opt or scratch) === */
289
247
  int scratch_is_inplace = 0;
290
248
  {
291
249
  char *inplace = NULL;
292
250
  if ( is_contig &&
293
- ca_moncmp_try_leaf_inplace(mc->parent, starts, counts,
251
+ ca_moncmp_try_leaf_inplace(mc->parent, req->starts, req->counts,
294
252
  operand_bytes, &inplace) ) {
295
253
  scratch = inplace;
296
254
  scratch_is_inplace = 1;
@@ -301,8 +259,7 @@ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
301
259
  ? ca_lazy_arena_acquire_object(slab_n)
302
260
  : ca_lazy_arena_acquire(slab_n * operand_bytes);
303
261
  ca_moncmp_scratch_acquire_count++;
304
- ca_xfer_stride(mc->parent, starts, counts, operand_strides, scratch,
305
- CA_XFER_GET);
262
+ ca_lazy_req_pull(mc->parent, req, scratch, CA_XFER_GET);
306
263
  }
307
264
  }
308
265
 
@@ -312,10 +269,12 @@ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
312
269
  * fn(n, m, ptr1, i1, ptr2, i2)
313
270
  * where ptr2 is boolean8_t*
314
271
  *
315
- * Non-trapping: m=NULL (= SIMD fast path). Per-data_type kernel handles
316
- * integer is_nan etc. internally.
272
+ * m=NULL (= SIMD fast path) except for an object parent, whose cells
273
+ * call Ruby: those skip the masked cells, as the eager method does.
274
+ * Per-data_type kernel handles integer is_nan etc. internally.
317
275
  */
318
276
  {
277
+ boolean8_t *slab_mask = NULL;
319
278
  ca_moncmp_func_t fn = ca_moncmp_kernel_lookup(mc->op_id,
320
279
  mc->parent->data_type);
321
280
  if ( fn == NULL ) {
@@ -324,14 +283,44 @@ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
324
283
  "CAMonCmp: kernel not implemented (op_id=%u data_type=%d)",
325
284
  (unsigned) mc->op_id, (int) mc->parent->data_type);
326
285
  }
327
- fn(slab_n, NULL,
286
+ if ( ca_op_raises_on_cell(CA_OP_KIND_MONCMP, mc->op_id, mc->parent->data_type) ) {
287
+ slab_mask = ca_lazy_req_mask(req, 1, &mc->parent);
288
+ }
289
+ fn(slab_n, slab_mask,
328
290
  (char *) scratch, 1,
329
291
  (boolean8_t *) data, 1);
292
+ if ( slab_mask ) ca_lazy_arena_release(slab_mask);
330
293
  }
331
294
 
332
295
  if ( ! scratch_is_inplace ) ca_lazy_arena_release(scratch);
333
296
  }
334
297
 
298
+ static void
299
+ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
300
+ ca_size_t *strides, void *data, int dir)
301
+ {
302
+ if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
303
+ ca_lazy_req_t req;
304
+ if ( dir != CA_XFER_GET ) {
305
+ ca_refuse_read_only();
306
+ }
307
+ ca_lazy_req_region(&req, ap, starts, counts, strides);
308
+ ca_moncmp_eval((CAMonCmp *) ap, &req, data);
309
+ }
310
+
311
+ /* An address list is evaluated in one pass, as a region is. */
312
+ static void
313
+ ca_moncmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
314
+ void *data, int dir)
315
+ {
316
+ ca_lazy_req_t req;
317
+ if ( dir != CA_XFER_GET ) {
318
+ ca_refuse_read_only();
319
+ }
320
+ ca_lazy_req_addrs(&req, n, addrs);
321
+ ca_moncmp_eval((CAMonCmp *) ap, &req, data);
322
+ }
323
+
335
324
  static void
336
325
  ca_moncmp_func_xfer_all (void *ap, void *data, int dir)
337
326
  {
@@ -349,7 +338,7 @@ static void
349
338
  ca_moncmp_func_allocate (void *ap)
350
339
  {
351
340
  CAMonCmp *ca = (CAMonCmp *) ap;
352
- ca->ptr = xmalloc(ca_length(ca));
341
+ ca->ptr = ca_alloc_cells((CArray *) ca);
353
342
  }
354
343
 
355
344
  static void
@@ -365,7 +354,7 @@ ca_moncmp_func_attach (void *ap)
365
354
  int8_t k;
366
355
  ca_size_t s;
367
356
 
368
- ca->ptr = xmalloc(ca_length(ca));
357
+ ca->ptr = ca_alloc_cells((CArray *) ca);
369
358
 
370
359
  s = ca->bytes;
371
360
  for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
@@ -391,20 +380,19 @@ NORETURN(static void ca_moncmp_func_fill_data (void *ap, void *ptr));
391
380
  static void
392
381
  ca_moncmp_func_fill_data (void *ap, void *ptr)
393
382
  {
394
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (fill_data)");
383
+ ca_refuse_read_only();
395
384
  }
396
385
 
386
+ /* The parent's mask cell for cell, read-only as the comparison is. */
397
387
  static void
398
388
  ca_moncmp_func_create_mask (void *ap)
399
389
  {
400
390
  CAMonCmp *mc = (CAMonCmp *) ap;
401
391
  CArray *p = mc->parent;
402
392
  if ( ! ca_has_mask(p) ) return;
403
-
404
- mc->mask = (CArray *) carray_new(CA_BOOLEAN, mc->ndim, mc->dim, 0, NULL);
405
- ca_attach(p->mask);
406
- memcpy(mc->mask->ptr, p->mask->ptr, mc->elements);
407
- ca_detach(p->mask);
393
+ mc->mask = (CArray *) ca_refer_new(p->mask, CA_BOOLEAN,
394
+ mc->ndim, mc->dim, 0, 0);
395
+ ca_set_flag(mc->mask, CA_FLAG_READ_ONLY);
408
396
  }
409
397
 
410
398
  ca_operation_function_t ca_moncmp_func = {
@@ -449,6 +437,14 @@ rb_ca_moncmp_new (VALUE p_cary, uint16_t op_id)
449
437
  CAMonCmp *ca;
450
438
  rb_check_carray_object(p_cary);
451
439
  TypedData_Get_Struct(p_cary, CArray, &carray_data_type, p);
440
+ /* No kernel for the parent's type: refuse as the eager comparison does,
441
+ before anything is allocated. */
442
+ {
443
+ ca_moncmp_func_t fn = ca_moncmp_kernel_lookup(op_id, p->data_type);
444
+ if ( fn == NULL || fn == ca_moncmp_not_implement ) {
445
+ ca_op_refuse_unimplemented(p_cary, p->data_type, rb_eCADataTypeError);
446
+ }
447
+ }
452
448
  ca = ca_moncmp_new(p, op_id);
453
449
  obj = ca_wrap_struct(ca);
454
450
  rb_ca_set_parent(obj, p_cary);
@@ -465,11 +461,24 @@ rb_ca_moncmp_build (VALUE p_cary, uint16_t op_id)
465
461
  static VALUE
466
462
  rb_ca_moncmp_s_build (VALUE klass, VALUE p_cary, VALUE op_id_val)
467
463
  {
464
+ /* fits: an operation number from the library's own table */
468
465
  uint16_t op_id = (uint16_t) NUM2UINT(op_id_val);
469
466
  (void) klass;
470
467
  return rb_ca_moncmp_build(p_cary, op_id);
471
468
  }
472
469
 
470
+ /* Whether this node's kernel skips the cells its operands mask, rather
471
+ than computing them: object cells, which call Ruby. CArray::Fusion
472
+ reads it so a plan carries the same rule. */
473
+ static VALUE
474
+ rb_ca_moncmp_trapping (VALUE self)
475
+ {
476
+ CAMonCmp *mc;
477
+ TypedData_Get_Struct(self, CAMonCmp, &camoncmp_data_type, mc);
478
+ return ca_op_raises_on_cell(CA_OP_KIND_MONCMP, mc->op_id, mc->parent->data_type)
479
+ ? Qtrue : Qfalse;
480
+ }
481
+
473
482
  static VALUE
474
483
  rb_ca_moncmp_op_id (VALUE self)
475
484
  {
@@ -478,6 +487,7 @@ rb_ca_moncmp_op_id (VALUE self)
478
487
  return UINT2NUM(mc->op_id);
479
488
  }
480
489
 
490
+ #ifdef CARRAY_DEV_BUILD
481
491
  static VALUE
482
492
  rb_ca_moncmp_s_reset_scratch_counter (VALUE klass)
483
493
  {
@@ -522,6 +532,7 @@ rb_ca_moncmp_s_leaf_inplace_count (VALUE klass)
522
532
  (void) klass;
523
533
  return SIZE2NUM(ca_moncmp_leaf_inplace_count);
524
534
  }
535
+ #endif /* CARRAY_DEV_BUILD */
525
536
 
526
537
  static VALUE
527
538
  rb_ca_moncmp_s_allocate (VALUE klass)
@@ -535,6 +546,7 @@ rb_ca_moncmp_initialize_copy (VALUE self, VALUE other)
535
546
  {
536
547
  CAMonCmp *ca, *cs;
537
548
  TypedData_Get_Struct(self, CAMonCmp, &camoncmp_data_type, ca);
549
+ ca_check_uninitialized(ca);
538
550
  TypedData_Get_Struct(other, CAMonCmp, &camoncmp_data_type, cs);
539
551
  if ( ca_func[CA_OBJ_MONCMP].pool_init ) {
540
552
  ca_array_pool_alloc(ca, CA_OBJ_MONCMP, cs->parent->ndim);
@@ -572,7 +584,9 @@ Init_ca_obj_moncmp (void)
572
584
  rb_ca_moncmp_s_build, 2);
573
585
 
574
586
  rb_define_method(rb_cCAMonCmp, "__op_id__", rb_ca_moncmp_op_id, 0);
587
+ rb_define_method(rb_cCAMonCmp, "__trapping__", rb_ca_moncmp_trapping, 0);
575
588
 
589
+ #ifdef CARRAY_DEV_BUILD
576
590
  rb_define_singleton_method(rb_cCAMonCmp, "__reset_scratch_counter__",
577
591
  rb_ca_moncmp_s_reset_scratch_counter, 0);
578
592
  rb_define_singleton_method(rb_cCAMonCmp, "__scratch_count__",
@@ -585,4 +599,5 @@ Init_ca_obj_moncmp (void)
585
599
  rb_ca_moncmp_s_reset_leaf_inplace_counter, 0);
586
600
  rb_define_singleton_method(rb_cCAMonCmp, "__leaf_inplace_count__",
587
601
  rb_ca_moncmp_s_leaf_inplace_count, 0);
602
+ #endif
588
603
  }