carray 3.0.3 → 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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +1 -6
  7. data/ext/ca_axis_group.c +27 -27
  8. data/ext/ca_binop_dispatch.c +1 -29
  9. data/ext/ca_binop_dispatch.h +0 -1
  10. data/ext/ca_categorical_iterator.c +205 -134
  11. data/ext/ca_compare.c +7 -18
  12. data/ext/ca_group_iter.c +16 -17
  13. data/ext/ca_kernel_iterator.c +1234 -1994
  14. data/ext/ca_kernel_iterator.h +391 -437
  15. data/ext/ca_monop_dispatch.c +82 -59
  16. data/ext/ca_monop_dispatch.h +1 -0
  17. data/ext/ca_obj_array.c +96 -39
  18. data/ext/ca_obj_bincmp.c +24 -21
  19. data/ext/ca_obj_binop.c +15 -26
  20. data/ext/ca_obj_bitarray.c +3 -2
  21. data/ext/ca_obj_bitfield.c +5 -6
  22. data/ext/ca_obj_block.c +18 -9
  23. data/ext/ca_obj_byte_swap.c +5 -6
  24. data/ext/ca_obj_const_string.c +173 -19
  25. data/ext/ca_obj_face.c +238 -57
  26. data/ext/ca_obj_face.h +19 -0
  27. data/ext/ca_obj_fake.c +15 -29
  28. data/ext/ca_obj_farray.c +6 -3
  29. data/ext/ca_obj_field.c +17 -5
  30. data/ext/ca_obj_fixlen_string.c +2 -3
  31. data/ext/ca_obj_grid.c +406 -132
  32. data/ext/ca_obj_meld.c +172 -34
  33. data/ext/ca_obj_moncmp.c +23 -8
  34. data/ext/ca_obj_monop.c +67 -57
  35. data/ext/ca_obj_object.c +157 -51
  36. data/ext/ca_obj_record.c +12 -7
  37. data/ext/ca_obj_reduce.c +13 -8
  38. data/ext/ca_obj_refer.c +25 -27
  39. data/ext/ca_obj_remap.c +30 -9
  40. data/ext/ca_obj_repeat.c +9 -10
  41. data/ext/ca_obj_roll.c +6 -5
  42. data/ext/ca_obj_select.c +14 -9
  43. data/ext/ca_obj_select_axis.c +15 -47
  44. data/ext/ca_obj_shift.c +11 -1
  45. data/ext/ca_obj_stack.c +179 -34
  46. data/ext/ca_obj_stride.c +162 -115
  47. data/ext/ca_obj_string.c +71 -4
  48. data/ext/ca_obj_tile.c +6 -5
  49. data/ext/ca_obj_time.c +22 -6
  50. data/ext/ca_obj_timedelta.c +22 -6
  51. data/ext/ca_obj_transpose.c +5 -3
  52. data/ext/ca_obj_triop.c +23 -32
  53. data/ext/ca_obj_window.c +190 -26
  54. data/ext/ca_sweep_engine.c +2 -2
  55. data/ext/caframe_csv_reader.c +80 -1
  56. data/ext/carray.h +181 -75
  57. data/ext/carray_access.c +184 -96
  58. data/ext/carray_address_basis.c +343 -87
  59. data/ext/carray_attribute.c +89 -6
  60. data/ext/carray_bincount.c +10 -8
  61. data/ext/carray_broadcast.c +13 -8
  62. data/ext/carray_build_flags.h +3 -0
  63. data/ext/carray_call_cfunc.c +108 -0
  64. data/ext/carray_cast.c +142 -24
  65. data/ext/carray_cast_func.rb +46 -6
  66. data/ext/carray_class.c +4 -3
  67. data/ext/carray_config.h +28 -0
  68. data/ext/carray_conversion.c +16 -7
  69. data/ext/carray_copy.c +51 -14
  70. data/ext/carray_core.c +147 -55
  71. data/ext/carray_count.c +50 -20
  72. data/ext/carray_element.c +76 -33
  73. data/ext/carray_factorize.c +118 -64
  74. data/ext/carray_generate.c +191 -50
  75. data/ext/carray_histogram.c +62 -17
  76. data/ext/carray_hold.c +12 -15
  77. data/ext/carray_index_classifier.c +388 -176
  78. data/ext/carray_internal.h +336 -29
  79. data/ext/carray_kernels_bincmp.c +4453 -0
  80. data/ext/carray_kernels_binop.c +11368 -0
  81. data/ext/carray_kernels_init.c +1734 -0
  82. data/ext/carray_kernels_moncmp.c +2104 -0
  83. data/ext/carray_kernels_monop.c +18369 -0
  84. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  85. data/ext/carray_kernels_reduce_boolean.c +406 -0
  86. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  87. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  88. data/ext/carray_kernels_reduce_variance.c +3849 -0
  89. data/ext/carray_kernels_scan.c +4302 -0
  90. data/ext/carray_kernels_search.c +33829 -0
  91. data/ext/carray_kernels_sort.c +10906 -0
  92. data/ext/carray_kernels_triop.c +1864 -0
  93. data/ext/carray_key_windows.c +216 -0
  94. data/ext/carray_lazy.c +170 -111
  95. data/ext/carray_mask.c +292 -72
  96. data/ext/carray_median_percentile.c +82 -28
  97. data/ext/carray_memory_view.c +669 -561
  98. data/ext/carray_operator.c +124 -47
  99. data/ext/carray_order.c +384 -76
  100. data/ext/carray_partition.c +28 -27
  101. data/ext/carray_random.c +67 -13
  102. data/ext/carray_round.c +273 -0
  103. data/ext/carray_scatter.c +63 -38
  104. data/ext/carray_segment.c +3 -3
  105. data/ext/carray_slab.c +91 -28
  106. data/ext/carray_sort.c +35 -35
  107. data/ext/carray_struct.c +19 -18
  108. data/ext/carray_test.c +26 -5
  109. data/ext/carray_undef.c +4 -0
  110. data/ext/carray_utils.c +246 -45
  111. data/ext/mk_call_cfunc.rb +19 -2
  112. data/ext/mkkernel.rb +198 -240
  113. data/ext/ruby_carray.c +10 -4
  114. data/ext/version.h +4 -4
  115. data/lib/carray/attribute.rb +126 -22
  116. data/lib/carray/autoload_carray.rb +8 -31
  117. data/lib/carray/autoload_method_extension.rb +14 -5
  118. data/lib/carray/axis_group.rb +255 -106
  119. data/lib/carray/basics.rb +78 -10
  120. data/lib/carray/bincount_nd.rb +12 -2
  121. data/lib/carray/block_iterator.rb +126 -23
  122. data/lib/carray/boolean_reduce.rb +17 -17
  123. data/lib/carray/categorical.rb +165 -43
  124. data/lib/carray/categorical_iterator.rb +130 -27
  125. data/lib/carray/complex.rb +5 -5
  126. data/lib/carray/conditional.rb +67 -18
  127. data/lib/carray/const_string.rb +14 -5
  128. data/lib/carray/construct.rb +15 -11
  129. data/lib/carray/data_type_extension.rb +1 -0
  130. data/lib/carray/distance_limit.rb +77 -0
  131. data/lib/carray/fixlen_string.rb +7 -1
  132. data/lib/carray/frame/column_verbs.rb +70 -0
  133. data/lib/carray/frame/convert.rb +69 -0
  134. data/lib/carray/frame/csv_parser.rb +111 -17
  135. data/lib/carray/frame/describe.rb +3 -2
  136. data/lib/carray/frame/frame.rb +246 -21
  137. data/lib/carray/frame/group.rb +510 -95
  138. data/lib/carray/frame/io.rb +115 -28
  139. data/lib/carray/frame/join.rb +312 -51
  140. data/lib/carray/frame/records.rb +83 -7
  141. data/lib/carray/frame/reshape.rb +42 -35
  142. data/lib/carray/frame/sort.rb +7 -19
  143. data/lib/carray/frame/verbs.rb +188 -48
  144. data/lib/carray/frame/windows.rb +117 -0
  145. data/lib/carray/frame.rb +2 -0
  146. data/lib/carray/fuse_source.rb +11 -4
  147. data/lib/carray/fusion.rb +40 -16
  148. data/lib/carray/histogram.rb +6 -1
  149. data/lib/carray/inspect.rb +31 -8
  150. data/lib/carray/iterator.rb +85 -7
  151. data/lib/carray/key_windows.rb +620 -0
  152. data/lib/carray/lazy.rb +182 -183
  153. data/lib/carray/mask_gap_fill.rb +63 -57
  154. data/lib/carray/meld_reduce.rb +12 -14
  155. data/lib/carray/methods/bin.rb +26 -18
  156. data/lib/carray/methods/bincount.rb +16 -0
  157. data/lib/carray/methods/bit_string.rb +1 -1
  158. data/lib/carray/methods/choose.rb +16 -3
  159. data/lib/carray/methods/composition.rb +3 -1
  160. data/lib/carray/methods/gather_nd.rb +14 -5
  161. data/lib/carray/methods/insert_block.rb +2 -2
  162. data/lib/carray/methods/is_between.rb +59 -0
  163. data/lib/carray/methods/is_in.rb +53 -36
  164. data/lib/carray/methods/join.rb +1 -6
  165. data/lib/carray/methods/lag.rb +49 -0
  166. data/lib/carray/methods/locate_addr.rb +47 -51
  167. data/lib/carray/methods/mode.rb +1 -1
  168. data/lib/carray/methods/nunique.rb +11 -6
  169. data/lib/carray/methods/resize.rb +3 -3
  170. data/lib/carray/methods/value_counts.rb +4 -11
  171. data/lib/carray/record_order.rb +3 -3
  172. data/lib/carray/rng.rb +3 -0
  173. data/lib/carray/runtime.rb +53 -8
  174. data/lib/carray/segment_iterator.rb +313 -82
  175. data/lib/carray/serialize.rb +24 -10
  176. data/lib/carray/slab_iterator.rb +50 -0
  177. data/lib/carray/string.rb +105 -5
  178. data/lib/carray/string_operation_extension.rb +8 -1
  179. data/lib/carray/struct.rb +9 -21
  180. data/lib/carray/struct_builder.rb +19 -8
  181. data/lib/carray/time.rb +726 -104
  182. data/lib/carray/window_iterator.rb +122 -16
  183. data/lib/carray.rb +7 -0
  184. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  185. data/yard-stubs/ca_obj_field.rb +4 -0
  186. data/yard-stubs/ca_obj_grid.rb +21 -10
  187. data/yard-stubs/ca_obj_refer.rb +2 -1
  188. data/yard-stubs/ca_obj_roll.rb +2 -2
  189. data/yard-stubs/ca_obj_shift.rb +5 -1
  190. data/yard-stubs/ca_obj_tile.rb +1 -1
  191. data/yard-stubs/ca_obj_window.rb +8 -3
  192. data/yard-stubs/carray_access.rb +6 -1
  193. data/yard-stubs/carray_attribute.rb +0 -5
  194. data/yard-stubs/carray_cast.rb +10 -0
  195. data/yard-stubs/carray_conversion.rb +2 -1
  196. data/yard-stubs/carray_copy.rb +4 -2
  197. data/yard-stubs/carray_count.rb +4 -4
  198. data/yard-stubs/carray_element.rb +10 -4
  199. data/yard-stubs/carray_generate.rb +21 -1
  200. data/yard-stubs/carray_mask.rb +26 -2
  201. data/yard-stubs/carray_math.rb +27 -1
  202. data/yard-stubs/carray_median_percentile.rb +5 -2
  203. data/yard-stubs/carray_memory_view.rb +40 -23
  204. data/yard-stubs/carray_order.rb +29 -18
  205. data/yard-stubs/carray_random.rb +13 -4
  206. data/yard-stubs/carray_scatter.rb +14 -9
  207. data/yard-stubs/carray_slab.rb +9 -2
  208. data/yard-stubs/carray_sort.rb +6 -5
  209. data/yard-stubs/carray_test.rb +5 -3
  210. metadata +25 -3
  211. data/lib/carray/arrow_tensor.rb +0 -401
  212. data/lib/carray/table.rb +0 -108
data/ext/ca_obj_meld.c CHANGED
@@ -152,6 +152,20 @@ ca_meld_setup (CAMeld *ca, int32_t n_parents, CArray **parents, int8_t meld_axis
152
152
  int32_t i;
153
153
  int8_t a;
154
154
 
155
+ /* ca == NULL asks for the checks only, so that a constructor can run
156
+ them before it allocates. They see the parents as the setup will,
157
+ one Face level down, without changing the caller's list. */
158
+ if ( ca == NULL ) {
159
+ volatile VALUE holder = 0;
160
+ CArray **seen = ALLOCV_N(CArray *, holder, n_parents > 0 ? n_parents : 1);
161
+ for ( i = 0; i < n_parents; i++ ) {
162
+ seen[i] = ca_is_face(parents[i]) ? CAVIEW(parents[i])->parent : parents[i];
163
+ }
164
+ ca_meld_check_uniform(n_parents, seen, meld_axis);
165
+ ALLOCV_END(holder);
166
+ return 0;
167
+ }
168
+
155
169
  /* Pre-strip Face parents one level to storage, as CAStack does, so a
156
170
  melded Face lifts to a single-Face chain (CATime[CAMeld[entity, ...]])
157
171
  rather than a Face sitting on Face parents. One level, not a full walk,
@@ -211,7 +225,9 @@ ca_meld_setup (CAMeld *ca, int32_t n_parents, CArray **parents, int8_t meld_axis
211
225
  CAMeld *
212
226
  ca_meld_new (int32_t n_parents, CArray **parents, int8_t meld_axis)
213
227
  {
214
- CAMeld *ca = ALLOC(CAMeld);
228
+ CAMeld *ca;
229
+ ca_meld_setup(NULL, n_parents, parents, meld_axis);
230
+ ca = ALLOC(CAMeld);
215
231
  ca_meld_setup(ca, n_parents, parents, meld_axis);
216
232
  return ca;
217
233
  }
@@ -285,12 +301,12 @@ ca_meld_tail_elements (const CAMeld *ca)
285
301
  /* On the mask of a CAMeld: let its stand-ins give way to the parents' own
286
302
  masks (see ca_multi_parent_mask_refresh). */
287
303
  static void
288
- ca_meld_mask_refresh (CAMeld *ca, int for_write)
304
+ ca_meld_mask_refresh (CAMeld *ca)
289
305
  {
290
306
  CAMeld *o = (CAMeld *) ca->mask_owner;
291
307
  if ( o != NULL ) {
292
308
  ca_multi_parent_mask_refresh((CArray *) ca, o->parents, o->mask_standins,
293
- o->n_parents, for_write);
309
+ o->n_parents);
294
310
  }
295
311
  }
296
312
 
@@ -308,7 +324,7 @@ static void
308
324
  ca_meld_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
309
325
  {
310
326
  CAMeld *ca = (CAMeld *) ap;
311
- ca_meld_mask_refresh(ca, dir == CA_XFER_PUT);
327
+ ca_meld_mask_refresh(ca);
312
328
  int8_t ma = ca->meld_axis;
313
329
  ca_size_t v = idx[ma];
314
330
  int32_t k;
@@ -343,7 +359,7 @@ ca_meld_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
343
359
  void *data, int dir)
344
360
  {
345
361
  CAMeld *ca = (CAMeld *) ap;
346
- ca_meld_mask_refresh(ca, dir == CA_XFER_PUT);
362
+ ca_meld_mask_refresh(ca);
347
363
  int8_t ma = ca->meld_axis;
348
364
  ca_size_t bytes = ca->bytes;
349
365
  ca_size_t view_div[CA_RANK_MAX]; /* row-major divisor per view axis */
@@ -559,6 +575,7 @@ ca_meld_xfer_stride_ma_internal (CAMeld *ca, ca_size_t *starts,
559
575
  else memcpy(buf, d + voff, chunk_bytes);
560
576
  }
561
577
  else if ( dir == CA_XFER_GET ) {
578
+ /* empty: the slot (ca_meld_func_xfer_stride) returns on an empty region; a parent the request does not reach returns above */
562
579
  while ( 1 ) {
563
580
  memcpy(d + voff, buf + paddr, chunk_bytes);
564
581
  paddr += chunk_bytes;
@@ -572,6 +589,7 @@ ca_meld_xfer_stride_ma_internal (CAMeld *ca, ca_size_t *starts,
572
589
  if ( i < 0 ) break;
573
590
  }
574
591
  } else {
592
+ /* empty: as above */
575
593
  while ( 1 ) {
576
594
  memcpy(buf + paddr, d + voff, chunk_bytes);
577
595
  paddr += chunk_bytes;
@@ -619,6 +637,7 @@ ca_meld_xfer_stride_per_cell (CAMeld *ca, ca_size_t *starts, ca_size_t *counts,
619
637
  for ( i = 0; i < ndim; i++ ) base += starts[i] * native[i];
620
638
  for ( i = 0; i < ndim; i++ ) idx[i] = 0;
621
639
 
640
+ /* empty: the slot (ca_meld_func_xfer_stride) returns on an empty region */
622
641
  while ( 1 ) {
623
642
  ca_size_t toff = base;
624
643
  for ( i = 0; i < ndim; i++ ) toff += idx[i] * strides[i];
@@ -641,7 +660,7 @@ ca_meld_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
641
660
  {
642
661
  if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
643
662
  CAMeld *ca = (CAMeld *) ap;
644
- ca_meld_mask_refresh(ca, dir == CA_XFER_PUT);
663
+ ca_meld_mask_refresh(ca);
645
664
  int8_t ma = ca->meld_axis;
646
665
  ca_size_t native[CA_RANK_MAX];
647
666
  ca_size_t s;
@@ -787,6 +806,7 @@ ca_meld_xfer_all_ma_internal (CAMeld *ca, void *data, int dir,
787
806
  else memcpy(buf, d + voff, chunk_bytes);
788
807
  }
789
808
  else if ( dir == CA_XFER_GET ) {
809
+ /* empty: the slot returns on an empty view; the outer axes are the view's, and a parent empty along the meld axis copies chunks of 0 bytes */
790
810
  while ( 1 ) {
791
811
  memcpy(d + voff, buf + paddr, chunk_bytes);
792
812
  paddr += chunk_bytes;
@@ -801,6 +821,7 @@ ca_meld_xfer_all_ma_internal (CAMeld *ca, void *data, int dir,
801
821
  }
802
822
  }
803
823
  else {
824
+ /* empty: as above */
804
825
  while ( 1 ) {
805
826
  memcpy(buf + paddr, d + voff, chunk_bytes);
806
827
  paddr += chunk_bytes;
@@ -835,7 +856,8 @@ ca_meld_xfer_parents (CAMeld *ca, void *data, int dir, int into_buffers)
835
856
  static void
836
857
  ca_meld_func_xfer_all (void *ap, void *data, int dir)
837
858
  {
838
- ca_meld_mask_refresh((CAMeld *) ap, dir == CA_XFER_PUT);
859
+ if ( ((CArray *) ap)->elements == 0 ) return;
860
+ ca_meld_mask_refresh((CAMeld *) ap);
839
861
  ca_meld_xfer_parents((CAMeld *) ap, data, dir, 0);
840
862
  }
841
863
 
@@ -847,9 +869,9 @@ static void
847
869
  ca_meld_func_allocate (void *ap)
848
870
  {
849
871
  CAMeld *ca = (CAMeld *) ap;
850
- ca_meld_mask_refresh(ca, 0);
872
+ ca_meld_mask_refresh(ca);
851
873
  ca_attach_all(ca->parents, ca->n_parents);
852
- ca->ptr = xmalloc(ca_length(ca));
874
+ ca->ptr = ca_alloc_cells((CArray *) ca);
853
875
  }
854
876
 
855
877
  static VALUE
@@ -863,23 +885,18 @@ static void
863
885
  ca_meld_func_attach (void *ap)
864
886
  {
865
887
  CAMeld *ca = (CAMeld *) ap;
866
- ca_meld_mask_refresh(ca, 0);
867
- int32_t k;
868
- int tag = 0;
888
+ ca_meld_mask_refresh(ca);
869
889
  ca_attach_all(ca->parents, ca->n_parents);
870
- rb_protect(ca_meld_attach_owned, (VALUE) ca, &tag);
871
- if ( tag ) {
872
- for ( k = 0; k < ca->n_parents; k++ ) {
873
- ca_detach(ca->parents[k]);
874
- }
875
- rb_jump_tag(tag);
876
- }
890
+ ca_fill_or_detach(ca->n_parents, ca->parents, ca_meld_attach_owned, (VALUE) ca);
877
891
  }
878
892
 
893
+ static void ca_meld_mask_refuse_sync (CAMeld *ca);
894
+
879
895
  static void
880
896
  ca_meld_func_sync (void *ap)
881
897
  {
882
898
  CAMeld *ca = (CAMeld *) ap;
899
+ ca_meld_mask_refuse_sync(ca);
883
900
  ca_meld_xfer_parents(ca, ca->ptr, CA_XFER_PUT, 1);
884
901
  ca_sync_all(ca->parents, ca->n_parents);
885
902
  ca_meld_mask_settle(ca);
@@ -905,7 +922,7 @@ static void
905
922
  ca_meld_func_fill_data (void *ap, void *ptr)
906
923
  {
907
924
  CAMeld *ca = (CAMeld *) ap;
908
- ca_meld_mask_refresh(ca, 1);
925
+ ca_meld_mask_refresh(ca);
909
926
  int32_t k;
910
927
  for ( k = 0; k < ca->n_parents; k++ ) {
911
928
  ca_fill(ca->parents[k], ptr);
@@ -953,54 +970,172 @@ ca_meld_func_fold_stride (void *ap, ca_fold_t *f, void **next_parent)
953
970
  /* operation table */
954
971
  /* ------------------------------------------------------------------- */
955
972
 
956
- /* The table's write slots: after a write, refuse a true that reached the
957
- stand-in of a value array or a mask array (ca_multi_parent_mask_check).
958
- Only the mask of a CAMeld has stand-ins to check. */
973
+ /* The table's write slots: after a write that may have put a true into a
974
+ stand-in, the true goes on to the parent's mask, or is refused for a
975
+ value array or a mask array (ca_mask_standin_settle). Only the mask of
976
+ a CAMeld has stand-ins. */
977
+ /* A write to the mask of a CAMeld, run once against blank masks first
978
+ (ca_multi_parent_mask_refuse_first), so that a write refused for a value
979
+ array or mask array part changes no other part. */
980
+ enum { CA_MELD_PUT_INDEX, CA_MELD_PUT_ADDRS, CA_MELD_PUT_STRIDE, CA_MELD_PUT_ALL,
981
+ CA_MELD_PUT_FILL, CA_MELD_PUT_SYNC, CA_MELD_PUT_FILL_ADDRS,
982
+ CA_MELD_PUT_FILL_STRIDE };
983
+
984
+ typedef struct {
985
+ int slot;
986
+ void *ap;
987
+ ca_size_t *idx;
988
+ ca_size_t n;
989
+ ca_size_t *addrs;
990
+ ca_size_t *starts;
991
+ ca_size_t *counts;
992
+ ca_size_t *strides;
993
+ void *data;
994
+ ca_size_t base;
995
+ int8_t ndim;
996
+ ca_size_t *steps;
997
+ } ca_meld_put_t;
998
+
999
+ static VALUE
1000
+ ca_meld_put_body (VALUE arg)
1001
+ {
1002
+ ca_meld_put_t *a = (ca_meld_put_t *) arg;
1003
+ switch ( a->slot ) {
1004
+ case CA_MELD_PUT_INDEX:
1005
+ ca_meld_func_xfer_index(a->ap, a->idx, a->data, CA_XFER_PUT); break;
1006
+ case CA_MELD_PUT_ADDRS:
1007
+ ca_meld_func_xfer_addrs(a->ap, a->n, a->addrs, a->data, CA_XFER_PUT); break;
1008
+ case CA_MELD_PUT_STRIDE:
1009
+ ca_meld_func_xfer_stride(a->ap, a->starts, a->counts, a->strides, a->data,
1010
+ CA_XFER_PUT); break;
1011
+ case CA_MELD_PUT_ALL:
1012
+ ca_meld_func_xfer_all(a->ap, a->data, CA_XFER_PUT); break;
1013
+ case CA_MELD_PUT_FILL:
1014
+ ca_meld_func_fill_data(a->ap, a->data); break;
1015
+ case CA_MELD_PUT_FILL_ADDRS:
1016
+ ca_fill_addrs_default(a->ap, a->n, a->addrs, a->data); break;
1017
+ case CA_MELD_PUT_FILL_STRIDE:
1018
+ ca_fill_stride_default(a->ap, a->base, a->ndim, a->counts, a->steps,
1019
+ a->data); break;
1020
+ case CA_MELD_PUT_SYNC:
1021
+ ca_meld_xfer_parents((CAMeld *) a->ap, ((CArray *) a->ap)->ptr, CA_XFER_PUT, 1);
1022
+ break;
1023
+ }
1024
+ return Qnil;
1025
+ }
1026
+
959
1027
  static void
960
- ca_meld_mask_check (CAMeld *ca)
1028
+ ca_meld_mask_refuse_first (ca_meld_put_t *a)
961
1029
  {
962
- CAMeld *o = (CAMeld *) ca->mask_owner;
1030
+ CAMeld *o = (CAMeld *) ((CAMeld *) a->ap)->mask_owner;
963
1031
  if ( o != NULL ) {
964
- ca_multi_parent_mask_check((CArray *) ca, o->parents, o->mask_standins,
965
- o->n_parents);
1032
+ ca_multi_parent_mask_refuse_first((CArray *) a->ap, o->parents,
1033
+ o->mask_standins, o->n_parents,
1034
+ ca_meld_put_body, (VALUE) a);
1035
+ }
1036
+ }
1037
+
1038
+ static void
1039
+ ca_meld_mask_refuse_sync (CAMeld *ca)
1040
+ {
1041
+ ca_meld_put_t a = { CA_MELD_PUT_SYNC, ca, NULL, 0, NULL, NULL, NULL, NULL, NULL };
1042
+ ca_meld_mask_refuse_first(&a);
1043
+ }
1044
+
1045
+ /* After a write of n cells of `data` to the mask of a CAMeld: a true
1046
+ that went into a stand-in goes on to its parent's mask. */
1047
+ static void
1048
+ ca_meld_mask_settle_after (CAMeld *ca, const void *data, ca_size_t n)
1049
+ {
1050
+ if ( ca->mask_owner != NULL && ca_mask_any_true(data, n) ) {
1051
+ ca_meld_mask_settle(ca);
966
1052
  }
967
1053
  }
968
1054
 
969
1055
  static void
970
1056
  ca_meld_put_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
971
1057
  {
1058
+ if ( dir == CA_XFER_PUT ) {
1059
+ ca_meld_put_t a = { CA_MELD_PUT_INDEX, ap, idx, 0, NULL, NULL, NULL, NULL, data };
1060
+ ca_meld_mask_refuse_first(&a);
1061
+ }
972
1062
  ca_meld_func_xfer_index(ap, idx, data, dir);
973
- if ( dir == CA_XFER_PUT ) ca_meld_mask_check((CAMeld *) ap);
1063
+ if ( dir == CA_XFER_PUT ) ca_meld_mask_settle_after((CAMeld *) ap, data, 1);
974
1064
  }
975
1065
 
976
1066
  static void
977
1067
  ca_meld_put_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data,
978
1068
  int dir)
979
1069
  {
1070
+ if ( dir == CA_XFER_PUT ) {
1071
+ ca_meld_put_t a = { CA_MELD_PUT_ADDRS, ap, NULL, n, addrs, NULL, NULL, NULL, data };
1072
+ ca_meld_mask_refuse_first(&a);
1073
+ }
980
1074
  ca_meld_func_xfer_addrs(ap, n, addrs, data, dir);
981
- if ( dir == CA_XFER_PUT ) ca_meld_mask_check((CAMeld *) ap);
1075
+ if ( dir == CA_XFER_PUT ) ca_meld_mask_settle_after((CAMeld *) ap, data, n);
982
1076
  }
983
1077
 
984
1078
  static void
985
1079
  ca_meld_put_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
986
1080
  ca_size_t *strides, void *data, int dir)
987
1081
  {
1082
+ if ( dir == CA_XFER_PUT ) {
1083
+ ca_meld_put_t a = { CA_MELD_PUT_STRIDE, ap, NULL, 0, NULL, starts, counts, strides, data };
1084
+ ca_meld_mask_refuse_first(&a);
1085
+ }
988
1086
  ca_meld_func_xfer_stride(ap, starts, counts, strides, data, dir);
989
- if ( dir == CA_XFER_PUT ) ca_meld_mask_check((CAMeld *) ap);
1087
+ if ( dir == CA_XFER_PUT ) {
1088
+ ca_meld_mask_settle_after((CAMeld *) ap, data,
1089
+ ca_shape_elements(((CArray *) ap)->ndim, counts, 1));
1090
+ }
990
1091
  }
991
1092
 
992
1093
  static void
993
1094
  ca_meld_put_xfer_all (void *ap, void *data, int dir)
994
1095
  {
1096
+ if ( dir == CA_XFER_PUT ) {
1097
+ ca_meld_put_t a = { CA_MELD_PUT_ALL, ap, NULL, 0, NULL, NULL, NULL, NULL, data };
1098
+ ca_meld_mask_refuse_first(&a);
1099
+ }
995
1100
  ca_meld_func_xfer_all(ap, data, dir);
996
- if ( dir == CA_XFER_PUT ) ca_meld_mask_check((CAMeld *) ap);
1101
+ if ( dir == CA_XFER_PUT ) {
1102
+ ca_meld_mask_settle_after((CAMeld *) ap, data, ((CArray *) ap)->elements);
1103
+ }
997
1104
  }
998
1105
 
999
1106
  static void
1000
1107
  ca_meld_put_fill_data (void *ap, void *ptr)
1001
1108
  {
1109
+ {
1110
+ ca_meld_put_t a = { CA_MELD_PUT_FILL, ap, NULL, 0, NULL, NULL, NULL, NULL, ptr };
1111
+ ca_meld_mask_refuse_first(&a);
1112
+ }
1002
1113
  ca_meld_func_fill_data(ap, ptr);
1003
- ca_meld_mask_check((CAMeld *) ap);
1114
+ ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
1115
+ }
1116
+
1117
+ /* A fill of part of the mask goes cell by cell through xfer_index; run
1118
+ the whole of it against blank masks first, so that a cell refused late
1119
+ does not leave the cells before it written. */
1120
+ static void
1121
+ ca_meld_put_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
1122
+ {
1123
+ ca_meld_put_t a = { CA_MELD_PUT_FILL_ADDRS, ap, NULL, n, addrs, NULL, NULL,
1124
+ NULL, ptr };
1125
+ ca_meld_mask_refuse_first(&a);
1126
+ ca_fill_addrs_default(ap, n, addrs, ptr);
1127
+ ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
1128
+ }
1129
+
1130
+ static void
1131
+ ca_meld_put_fill_stride (void *ap, ca_size_t base, int8_t ndim,
1132
+ ca_size_t *counts, ca_size_t *steps, void *ptr)
1133
+ {
1134
+ ca_meld_put_t a = { CA_MELD_PUT_FILL_STRIDE, ap, NULL, 0, NULL, NULL, counts,
1135
+ NULL, ptr, base, ndim, steps };
1136
+ ca_meld_mask_refuse_first(&a);
1137
+ ca_fill_stride_default(ap, base, ndim, counts, steps, ptr);
1138
+ ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
1004
1139
  }
1005
1140
 
1006
1141
  ca_operation_function_t ca_meld_func = {
@@ -1099,8 +1234,8 @@ rb_ca_meld_initialize (int argc, VALUE *argv, VALUE self)
1099
1234
  VALUE first = rb_ary_entry(list, 0);
1100
1235
  rb_check_carray_object(first);
1101
1236
  TypedData_Get_Struct(first, CArray, &carray_data_type, ref);
1102
- meld_axis = (int8_t) rb_ca_normalize_axis_for_ndim(
1103
- NUM2LONG(axis_val), (int) ref->ndim, "CAMeld.new");
1237
+ meld_axis = (int8_t) ca_normalize_axis_arg(
1238
+ axis_val, (int) ref->ndim, "CAMeld.new");
1104
1239
  }
1105
1240
  TypedData_Get_Struct(self, CAMeld, &cameld_data_type, ca);
1106
1241
  ca_check_uninitialized(ca);
@@ -1197,6 +1332,9 @@ Init_ca_obj_meld (void)
1197
1332
  rb_cCAMeld = rb_define_class("CAMeld", rb_cCAView);
1198
1333
  rb_cCAMeldMask = rb_define_class("CAMeldMask", rb_cCAMeld);
1199
1334
 
1335
+ ca_meld_func.fill_addrs = ca_meld_put_fill_addrs;
1336
+ ca_meld_func.fill_stride = ca_meld_put_fill_stride;
1337
+
1200
1338
  CA_OBJ_MELD = ca_install_obj_type(rb_cCAMeld,
1201
1339
  &cameld_data_type,
1202
1340
  rb_cCAMeldMask,
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];
@@ -282,7 +283,7 @@ ca_moncmp_eval (CAMonCmp *mc, const ca_lazy_req_t *req, void *data)
282
283
  "CAMonCmp: kernel not implemented (op_id=%u data_type=%d)",
283
284
  (unsigned) mc->op_id, (int) mc->parent->data_type);
284
285
  }
285
- if ( mc->parent->data_type == CA_OBJECT ) {
286
+ if ( ca_op_raises_on_cell(CA_OP_KIND_MONCMP, mc->op_id, mc->parent->data_type) ) {
286
287
  slab_mask = ca_lazy_req_mask(req, 1, &mc->parent);
287
288
  }
288
289
  fn(slab_n, slab_mask,
@@ -301,7 +302,7 @@ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
301
302
  if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
302
303
  ca_lazy_req_t req;
303
304
  if ( dir != CA_XFER_GET ) {
304
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_stride PUT)");
305
+ ca_refuse_read_only();
305
306
  }
306
307
  ca_lazy_req_region(&req, ap, starts, counts, strides);
307
308
  ca_moncmp_eval((CAMonCmp *) ap, &req, data);
@@ -314,7 +315,7 @@ ca_moncmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
314
315
  {
315
316
  ca_lazy_req_t req;
316
317
  if ( dir != CA_XFER_GET ) {
317
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_addrs PUT)");
318
+ ca_refuse_read_only();
318
319
  }
319
320
  ca_lazy_req_addrs(&req, n, addrs);
320
321
  ca_moncmp_eval((CAMonCmp *) ap, &req, data);
@@ -337,7 +338,7 @@ static void
337
338
  ca_moncmp_func_allocate (void *ap)
338
339
  {
339
340
  CAMonCmp *ca = (CAMonCmp *) ap;
340
- ca->ptr = xmalloc(ca_length(ca));
341
+ ca->ptr = ca_alloc_cells((CArray *) ca);
341
342
  }
342
343
 
343
344
  static void
@@ -353,7 +354,7 @@ ca_moncmp_func_attach (void *ap)
353
354
  int8_t k;
354
355
  ca_size_t s;
355
356
 
356
- ca->ptr = xmalloc(ca_length(ca));
357
+ ca->ptr = ca_alloc_cells((CArray *) ca);
357
358
 
358
359
  s = ca->bytes;
359
360
  for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
@@ -379,7 +380,7 @@ NORETURN(static void ca_moncmp_func_fill_data (void *ap, void *ptr));
379
380
  static void
380
381
  ca_moncmp_func_fill_data (void *ap, void *ptr)
381
382
  {
382
- rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (fill_data)");
383
+ ca_refuse_read_only();
383
384
  }
384
385
 
385
386
  /* The parent's mask cell for cell, read-only as the comparison is. */
@@ -436,6 +437,14 @@ rb_ca_moncmp_new (VALUE p_cary, uint16_t op_id)
436
437
  CAMonCmp *ca;
437
438
  rb_check_carray_object(p_cary);
438
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
+ }
439
448
  ca = ca_moncmp_new(p, op_id);
440
449
  obj = ca_wrap_struct(ca);
441
450
  rb_ca_set_parent(obj, p_cary);
@@ -452,6 +461,7 @@ rb_ca_moncmp_build (VALUE p_cary, uint16_t op_id)
452
461
  static VALUE
453
462
  rb_ca_moncmp_s_build (VALUE klass, VALUE p_cary, VALUE op_id_val)
454
463
  {
464
+ /* fits: an operation number from the library's own table */
455
465
  uint16_t op_id = (uint16_t) NUM2UINT(op_id_val);
456
466
  (void) klass;
457
467
  return rb_ca_moncmp_build(p_cary, op_id);
@@ -465,7 +475,8 @@ rb_ca_moncmp_trapping (VALUE self)
465
475
  {
466
476
  CAMonCmp *mc;
467
477
  TypedData_Get_Struct(self, CAMonCmp, &camoncmp_data_type, mc);
468
- return ( mc->parent->data_type == CA_OBJECT ) ? Qtrue : Qfalse;
478
+ return ca_op_raises_on_cell(CA_OP_KIND_MONCMP, mc->op_id, mc->parent->data_type)
479
+ ? Qtrue : Qfalse;
469
480
  }
470
481
 
471
482
  static VALUE
@@ -476,6 +487,7 @@ rb_ca_moncmp_op_id (VALUE self)
476
487
  return UINT2NUM(mc->op_id);
477
488
  }
478
489
 
490
+ #ifdef CARRAY_DEV_BUILD
479
491
  static VALUE
480
492
  rb_ca_moncmp_s_reset_scratch_counter (VALUE klass)
481
493
  {
@@ -520,6 +532,7 @@ rb_ca_moncmp_s_leaf_inplace_count (VALUE klass)
520
532
  (void) klass;
521
533
  return SIZE2NUM(ca_moncmp_leaf_inplace_count);
522
534
  }
535
+ #endif /* CARRAY_DEV_BUILD */
523
536
 
524
537
  static VALUE
525
538
  rb_ca_moncmp_s_allocate (VALUE klass)
@@ -573,6 +586,7 @@ Init_ca_obj_moncmp (void)
573
586
  rb_define_method(rb_cCAMonCmp, "__op_id__", rb_ca_moncmp_op_id, 0);
574
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
  }