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_stack.c CHANGED
@@ -125,6 +125,26 @@ ca_stack_setup_with_axis (CAStack *ca, int32_t n_parents, CArray **parents,
125
125
  int32_t i;
126
126
  int8_t a;
127
127
 
128
+ /* ca == NULL asks for the checks only, so that a constructor can run
129
+ them before it allocates. They see the parents as the setup will,
130
+ one Face level down, without changing the caller's list. */
131
+ if ( ca == NULL ) {
132
+ volatile VALUE holder = 0;
133
+ CArray **seen = ALLOCV_N(CArray *, holder, n_parents > 0 ? n_parents : 1);
134
+ for ( i = 0; i < n_parents; i++ ) {
135
+ seen[i] = ca_is_face(parents[i]) ? CAVIEW(parents[i])->parent : parents[i];
136
+ }
137
+ ca_stack_check_uniform(n_parents, seen);
138
+ ca_check_rank_fits(seen[0]->ndim + 1, NULL);
139
+ if ( k_axis < 0 || k_axis > seen[0]->ndim ) {
140
+ rb_raise(rb_eArgError,
141
+ "CAStack k_axis %d out of range [0, %d]",
142
+ (int) k_axis, (int) seen[0]->ndim);
143
+ }
144
+ ALLOCV_END(holder);
145
+ return 0;
146
+ }
147
+
128
148
  /* §8.3 / MEMO_FACE_DOUBLE_LIFT §15.3: pre-strip Face parents one level to
129
149
  storage so a stacked Face lifts to a single-Face chain
130
150
  (CATime[CAStack[entity, ...]]) instead of a Face on top of Face parents.
@@ -141,6 +161,7 @@ ca_stack_setup_with_axis (CAStack *ca, int32_t n_parents, CArray **parents,
141
161
  ca_stack_check_uniform(n_parents, parents);
142
162
  ref = parents[0];
143
163
 
164
+ ca_check_rank_fits(ref->ndim + 1, NULL);
144
165
  if ( k_axis < 0 || k_axis > ref->ndim ) {
145
166
  rb_raise(rb_eArgError,
146
167
  "CAStack k_axis %d out of range [0, %d]",
@@ -190,7 +211,9 @@ ca_stack_setup (CAStack *ca, int32_t n_parents, CArray **parents)
190
211
  CAStack *
191
212
  ca_stack_new_with_axis (int32_t n_parents, CArray **parents, int8_t k_axis)
192
213
  {
193
- CAStack *ca = ALLOC(CAStack);
214
+ CAStack *ca;
215
+ ca_stack_setup_with_axis(NULL, n_parents, parents, k_axis);
216
+ ca = ALLOC(CAStack);
194
217
  ca_stack_setup_with_axis(ca, n_parents, parents, k_axis);
195
218
  return ca;
196
219
  }
@@ -236,12 +259,12 @@ ca_stack_func_clone (void *ap)
236
259
  /* On the mask of a CAStack: let its stand-ins give way to the parents' own
237
260
  masks (see ca_multi_parent_mask_refresh). */
238
261
  static void
239
- ca_stack_mask_refresh (CAStack *ca, int for_write)
262
+ ca_stack_mask_refresh (CAStack *ca)
240
263
  {
241
264
  CAStack *o = (CAStack *) ca->mask_owner;
242
265
  if ( o != NULL ) {
243
266
  ca_multi_parent_mask_refresh((CArray *) ca, o->parents, o->mask_standins,
244
- o->n_parents, for_write);
267
+ o->n_parents);
245
268
  }
246
269
  }
247
270
 
@@ -259,7 +282,7 @@ static void
259
282
  ca_stack_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
260
283
  {
261
284
  CAStack *ca = (CAStack *) ap;
262
- ca_stack_mask_refresh(ca, dir == CA_XFER_PUT);
285
+ ca_stack_mask_refresh(ca);
263
286
  int8_t k_axis = ca->k_axis;
264
287
  ca_size_t k = idx[k_axis];
265
288
  if ( k < 0 || k >= ca->n_parents ) {
@@ -295,7 +318,7 @@ ca_stack_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
295
318
  void *data, int dir)
296
319
  {
297
320
  CAStack *ca = (CAStack *) ap;
298
- ca_stack_mask_refresh(ca, dir == CA_XFER_PUT);
321
+ ca_stack_mask_refresh(ca);
299
322
  int8_t k_axis = ca->k_axis;
300
323
  ca_size_t parent_elements = ca->parents[0]->elements;
301
324
  ca_size_t bytes = ca->bytes;
@@ -422,7 +445,7 @@ ca_stack_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
422
445
  {
423
446
  if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
424
447
  CAStack *ca = (CAStack *) ap;
425
- ca_stack_mask_refresh(ca, dir == CA_XFER_PUT);
448
+ ca_stack_mask_refresh(ca);
426
449
  int8_t k_axis = ca->k_axis;
427
450
  int8_t pndim = ca->ndim - 1;
428
451
  ca_size_t native[CA_RANK_MAX], dstride[CA_RANK_MAX];
@@ -515,6 +538,7 @@ ca_stack_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
515
538
  ca_size_t pidx[CA_RANK_MAX];
516
539
  ca_size_t paddr = 0;
517
540
  for ( a = 0; a < pndim; a++ ) pidx[a] = 0;
541
+ /* empty: the slot returns on an empty region at its entry */
518
542
  while ( 1 ) {
519
543
  ca_size_t voff = k_off;
520
544
  for ( a = 0; a < k_axis; a++ ) voff += pidx[a] * dstride[a];
@@ -593,6 +617,7 @@ ca_stack_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
593
617
  the CAStack-level addr2index dispatch hop in the per-cell fallback. */
594
618
  ca_size_t pidx[CA_RANK_MAX], doff = 0;
595
619
  for ( i = 0; i < ca->ndim; i++ ) odo[i] = 0;
620
+ /* empty: the slot returns on an empty region at its entry */
596
621
  while ( 1 ) {
597
622
  ca_size_t k2 = starts[k_axis] + odo[p];
598
623
  for ( a = 0; a < pndim; a++ ) {
@@ -611,6 +636,7 @@ ca_stack_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
611
636
  s = ca->bytes;
612
637
  for ( i = ca->ndim - 1; i >= 0; i-- ) { dstride[i] = s; s *= counts[i]; }
613
638
  for ( i = 0; i <= p; i++ ) odo[i] = 0;
639
+ /* empty: the slot returns on an empty region at its entry */
614
640
  while ( 1 ) {
615
641
  ca_size_t k2 = starts[k_axis] + odo[p];
616
642
  ca_size_t doff = 0;
@@ -640,6 +666,7 @@ ca_stack_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
640
666
  ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
641
667
  for ( i = 0; i < ca->ndim; i++ ) base += starts[i] * native[i];
642
668
  for ( i = 0; i < ca->ndim; i++ ) idx[i] = 0;
669
+ /* empty: the slot returns on an empty region at its entry */
643
670
  while ( 1 ) {
644
671
  ca_size_t toff = base, vidx[CA_RANK_MAX];
645
672
  for ( i = 0; i < ca->ndim; i++ ) toff += idx[i] * strides[i];
@@ -749,6 +776,7 @@ ca_stack_xfer_parents (CAStack *ca, char *d, int dir, int into_buffers)
749
776
  }
750
777
  else if ( dir == CA_XFER_GET ) {
751
778
  /* dir-hoisted GET inner loop, incremental voff. */
779
+ /* empty: the function returns on an empty view at its entry */
752
780
  while ( 1 ) {
753
781
  memcpy(d + voff, buf + paddr_bytes, bytes);
754
782
  paddr_bytes += bytes;
@@ -764,6 +792,7 @@ ca_stack_xfer_parents (CAStack *ca, char *d, int dir, int into_buffers)
764
792
  }
765
793
  else {
766
794
  /* dir-hoisted PUT inner loop, incremental voff. */
795
+ /* empty: the function returns on an empty view at its entry */
767
796
  while ( 1 ) {
768
797
  memcpy(buf + paddr_bytes, d + voff, bytes);
769
798
  paddr_bytes += bytes;
@@ -795,7 +824,7 @@ ca_stack_xfer_parents (CAStack *ca, char *d, int dir, int into_buffers)
795
824
  static void
796
825
  ca_stack_func_xfer_all (void *ap, void *data, int dir)
797
826
  {
798
- ca_stack_mask_refresh((CAStack *) ap, dir == CA_XFER_PUT);
827
+ ca_stack_mask_refresh((CAStack *) ap);
799
828
  ca_stack_xfer_parents((CAStack *) ap, (char *) data, dir, 0);
800
829
  }
801
830
 
@@ -807,9 +836,9 @@ static void
807
836
  ca_stack_func_allocate (void *ap)
808
837
  {
809
838
  CAStack *ca = (CAStack *) ap;
810
- ca_stack_mask_refresh(ca, 0);
839
+ ca_stack_mask_refresh(ca);
811
840
  ca_attach_all(ca->parents, ca->n_parents);
812
- ca->ptr = xmalloc(ca_length(ca));
841
+ ca->ptr = ca_alloc_cells((CArray *) ca);
813
842
  }
814
843
 
815
844
  static VALUE
@@ -823,23 +852,18 @@ static void
823
852
  ca_stack_func_attach (void *ap)
824
853
  {
825
854
  CAStack *ca = (CAStack *) ap;
826
- ca_stack_mask_refresh(ca, 0);
827
- int32_t k;
828
- int tag = 0;
855
+ ca_stack_mask_refresh(ca);
829
856
  ca_attach_all(ca->parents, ca->n_parents);
830
- rb_protect(ca_stack_attach_owned, (VALUE) ca, &tag);
831
- if ( tag ) {
832
- for ( k = 0; k < ca->n_parents; k++ ) {
833
- ca_detach(ca->parents[k]);
834
- }
835
- rb_jump_tag(tag);
836
- }
857
+ ca_fill_or_detach(ca->n_parents, ca->parents, ca_stack_attach_owned, (VALUE) ca);
837
858
  }
838
859
 
860
+ static void ca_stack_mask_refuse_sync (CAStack *ca);
861
+
839
862
  static void
840
863
  ca_stack_func_sync (void *ap)
841
864
  {
842
865
  CAStack *ca = (CAStack *) ap;
866
+ ca_stack_mask_refuse_sync(ca);
843
867
  ca_stack_xfer_parents(ca, ca->ptr, CA_XFER_PUT, 1);
844
868
  ca_sync_all(ca->parents, ca->n_parents);
845
869
  ca_stack_mask_settle(ca);
@@ -865,7 +889,7 @@ static void
865
889
  ca_stack_func_fill_data (void *ap, void *ptr)
866
890
  {
867
891
  CAStack *ca = (CAStack *) ap;
868
- ca_stack_mask_refresh(ca, 1);
892
+ ca_stack_mask_refresh(ca);
869
893
  int32_t k;
870
894
  for ( k = 0; k < ca->n_parents; k++ ) {
871
895
  ca_fill(ca->parents[k], ptr);
@@ -968,54 +992,172 @@ ca_stack_func_fold_stride (void *ap, ca_fold_t *f, void **next_parent)
968
992
  /* operation table */
969
993
  /* ------------------------------------------------------------------- */
970
994
 
971
- /* The table's write slots: after a write, refuse a true that reached the
972
- stand-in of a value array or a mask array (ca_multi_parent_mask_check).
973
- Only the mask of a CAStack has stand-ins to check. */
995
+ /* The table's write slots: after a write that may have put a true into a
996
+ stand-in, the true goes on to the parent's mask, or is refused for a
997
+ value array or a mask array (ca_mask_standin_settle). Only the mask of
998
+ a CAStack has stand-ins. */
999
+ /* A write to the mask of a CAStack, run once against blank masks first
1000
+ (ca_multi_parent_mask_refuse_first), so that a write refused for a value
1001
+ array or mask array part changes no other part. */
1002
+ enum { CA_STACK_PUT_INDEX, CA_STACK_PUT_ADDRS, CA_STACK_PUT_STRIDE, CA_STACK_PUT_ALL,
1003
+ CA_STACK_PUT_FILL, CA_STACK_PUT_SYNC, CA_STACK_PUT_FILL_ADDRS,
1004
+ CA_STACK_PUT_FILL_STRIDE };
1005
+
1006
+ typedef struct {
1007
+ int slot;
1008
+ void *ap;
1009
+ ca_size_t *idx;
1010
+ ca_size_t n;
1011
+ ca_size_t *addrs;
1012
+ ca_size_t *starts;
1013
+ ca_size_t *counts;
1014
+ ca_size_t *strides;
1015
+ void *data;
1016
+ ca_size_t base;
1017
+ int8_t ndim;
1018
+ ca_size_t *steps;
1019
+ } ca_stack_put_t;
1020
+
1021
+ static VALUE
1022
+ ca_stack_put_body (VALUE arg)
1023
+ {
1024
+ ca_stack_put_t *a = (ca_stack_put_t *) arg;
1025
+ switch ( a->slot ) {
1026
+ case CA_STACK_PUT_INDEX:
1027
+ ca_stack_func_xfer_index(a->ap, a->idx, a->data, CA_XFER_PUT); break;
1028
+ case CA_STACK_PUT_ADDRS:
1029
+ ca_stack_func_xfer_addrs(a->ap, a->n, a->addrs, a->data, CA_XFER_PUT); break;
1030
+ case CA_STACK_PUT_STRIDE:
1031
+ ca_stack_func_xfer_stride(a->ap, a->starts, a->counts, a->strides, a->data,
1032
+ CA_XFER_PUT); break;
1033
+ case CA_STACK_PUT_ALL:
1034
+ ca_stack_func_xfer_all(a->ap, a->data, CA_XFER_PUT); break;
1035
+ case CA_STACK_PUT_FILL:
1036
+ ca_stack_func_fill_data(a->ap, a->data); break;
1037
+ case CA_STACK_PUT_FILL_ADDRS:
1038
+ ca_fill_addrs_default(a->ap, a->n, a->addrs, a->data); break;
1039
+ case CA_STACK_PUT_FILL_STRIDE:
1040
+ ca_fill_stride_default(a->ap, a->base, a->ndim, a->counts, a->steps,
1041
+ a->data); break;
1042
+ case CA_STACK_PUT_SYNC:
1043
+ ca_stack_xfer_parents((CAStack *) a->ap, ((CArray *) a->ap)->ptr, CA_XFER_PUT, 1);
1044
+ break;
1045
+ }
1046
+ return Qnil;
1047
+ }
1048
+
974
1049
  static void
975
- ca_stack_mask_check (CAStack *ca)
1050
+ ca_stack_mask_refuse_first (ca_stack_put_t *a)
976
1051
  {
977
- CAStack *o = (CAStack *) ca->mask_owner;
1052
+ CAStack *o = (CAStack *) ((CAStack *) a->ap)->mask_owner;
978
1053
  if ( o != NULL ) {
979
- ca_multi_parent_mask_check((CArray *) ca, o->parents, o->mask_standins,
980
- o->n_parents);
1054
+ ca_multi_parent_mask_refuse_first((CArray *) a->ap, o->parents,
1055
+ o->mask_standins, o->n_parents,
1056
+ ca_stack_put_body, (VALUE) a);
1057
+ }
1058
+ }
1059
+
1060
+ static void
1061
+ ca_stack_mask_refuse_sync (CAStack *ca)
1062
+ {
1063
+ ca_stack_put_t a = { CA_STACK_PUT_SYNC, ca, NULL, 0, NULL, NULL, NULL, NULL, NULL };
1064
+ ca_stack_mask_refuse_first(&a);
1065
+ }
1066
+
1067
+ /* After a write of n cells of `data` to the mask of a CAStack: a true
1068
+ that went into a stand-in goes on to its parent's mask. */
1069
+ static void
1070
+ ca_stack_mask_settle_after (CAStack *ca, const void *data, ca_size_t n)
1071
+ {
1072
+ if ( ca->mask_owner != NULL && ca_mask_any_true(data, n) ) {
1073
+ ca_stack_mask_settle(ca);
981
1074
  }
982
1075
  }
983
1076
 
984
1077
  static void
985
1078
  ca_stack_put_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
986
1079
  {
1080
+ if ( dir == CA_XFER_PUT ) {
1081
+ ca_stack_put_t a = { CA_STACK_PUT_INDEX, ap, idx, 0, NULL, NULL, NULL, NULL, data };
1082
+ ca_stack_mask_refuse_first(&a);
1083
+ }
987
1084
  ca_stack_func_xfer_index(ap, idx, data, dir);
988
- if ( dir == CA_XFER_PUT ) ca_stack_mask_check((CAStack *) ap);
1085
+ if ( dir == CA_XFER_PUT ) ca_stack_mask_settle_after((CAStack *) ap, data, 1);
989
1086
  }
990
1087
 
991
1088
  static void
992
1089
  ca_stack_put_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data,
993
1090
  int dir)
994
1091
  {
1092
+ if ( dir == CA_XFER_PUT ) {
1093
+ ca_stack_put_t a = { CA_STACK_PUT_ADDRS, ap, NULL, n, addrs, NULL, NULL, NULL, data };
1094
+ ca_stack_mask_refuse_first(&a);
1095
+ }
995
1096
  ca_stack_func_xfer_addrs(ap, n, addrs, data, dir);
996
- if ( dir == CA_XFER_PUT ) ca_stack_mask_check((CAStack *) ap);
1097
+ if ( dir == CA_XFER_PUT ) ca_stack_mask_settle_after((CAStack *) ap, data, n);
997
1098
  }
998
1099
 
999
1100
  static void
1000
1101
  ca_stack_put_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
1001
1102
  ca_size_t *strides, void *data, int dir)
1002
1103
  {
1104
+ if ( dir == CA_XFER_PUT ) {
1105
+ ca_stack_put_t a = { CA_STACK_PUT_STRIDE, ap, NULL, 0, NULL, starts, counts, strides, data };
1106
+ ca_stack_mask_refuse_first(&a);
1107
+ }
1003
1108
  ca_stack_func_xfer_stride(ap, starts, counts, strides, data, dir);
1004
- if ( dir == CA_XFER_PUT ) ca_stack_mask_check((CAStack *) ap);
1109
+ if ( dir == CA_XFER_PUT ) {
1110
+ ca_stack_mask_settle_after((CAStack *) ap, data,
1111
+ ca_shape_elements(((CArray *) ap)->ndim, counts, 1));
1112
+ }
1005
1113
  }
1006
1114
 
1007
1115
  static void
1008
1116
  ca_stack_put_xfer_all (void *ap, void *data, int dir)
1009
1117
  {
1118
+ if ( dir == CA_XFER_PUT ) {
1119
+ ca_stack_put_t a = { CA_STACK_PUT_ALL, ap, NULL, 0, NULL, NULL, NULL, NULL, data };
1120
+ ca_stack_mask_refuse_first(&a);
1121
+ }
1010
1122
  ca_stack_func_xfer_all(ap, data, dir);
1011
- if ( dir == CA_XFER_PUT ) ca_stack_mask_check((CAStack *) ap);
1123
+ if ( dir == CA_XFER_PUT ) {
1124
+ ca_stack_mask_settle_after((CAStack *) ap, data, ((CArray *) ap)->elements);
1125
+ }
1012
1126
  }
1013
1127
 
1014
1128
  static void
1015
1129
  ca_stack_put_fill_data (void *ap, void *ptr)
1016
1130
  {
1131
+ {
1132
+ ca_stack_put_t a = { CA_STACK_PUT_FILL, ap, NULL, 0, NULL, NULL, NULL, NULL, ptr };
1133
+ ca_stack_mask_refuse_first(&a);
1134
+ }
1017
1135
  ca_stack_func_fill_data(ap, ptr);
1018
- ca_stack_mask_check((CAStack *) ap);
1136
+ ca_stack_mask_settle_after((CAStack *) ap, ptr, 1);
1137
+ }
1138
+
1139
+ /* A fill of part of the mask goes cell by cell through xfer_index; run
1140
+ the whole of it against blank masks first, so that a cell refused late
1141
+ does not leave the cells before it written. */
1142
+ static void
1143
+ ca_stack_put_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
1144
+ {
1145
+ ca_stack_put_t a = { CA_STACK_PUT_FILL_ADDRS, ap, NULL, n, addrs, NULL, NULL,
1146
+ NULL, ptr };
1147
+ ca_stack_mask_refuse_first(&a);
1148
+ ca_fill_addrs_default(ap, n, addrs, ptr);
1149
+ ca_stack_mask_settle_after((CAStack *) ap, ptr, 1);
1150
+ }
1151
+
1152
+ static void
1153
+ ca_stack_put_fill_stride (void *ap, ca_size_t base, int8_t ndim,
1154
+ ca_size_t *counts, ca_size_t *steps, void *ptr)
1155
+ {
1156
+ ca_stack_put_t a = { CA_STACK_PUT_FILL_STRIDE, ap, NULL, 0, NULL, NULL, counts,
1157
+ NULL, ptr, base, ndim, steps };
1158
+ ca_stack_mask_refuse_first(&a);
1159
+ ca_fill_stride_default(ap, base, ndim, counts, steps, ptr);
1160
+ ca_stack_mask_settle_after((CAStack *) ap, ptr, 1);
1019
1161
  }
1020
1162
 
1021
1163
  ca_operation_function_t ca_stack_func = {
@@ -1149,8 +1291,8 @@ rb_ca_stack_initialize (int argc, VALUE *argv, VALUE self)
1149
1291
  VALUE first = rb_ary_entry(list, 0);
1150
1292
  rb_check_carray_object(first);
1151
1293
  TypedData_Get_Struct(first, CArray, &carray_data_type, ref);
1152
- k_axis = (int8_t) rb_ca_normalize_axis_for_ndim(
1153
- NUM2LONG(axis_val), (int) ref->ndim + 1, "CAStack.new");
1294
+ k_axis = (int8_t) ca_normalize_axis_arg(
1295
+ axis_val, (int) ref->ndim + 1, "CAStack.new");
1154
1296
  }
1155
1297
  TypedData_Get_Struct(self, CAStack, &castack_data_type, ca);
1156
1298
  ca_check_uninitialized(ca);
@@ -1247,6 +1389,9 @@ Init_ca_obj_stack (void)
1247
1389
  rb_cCAStack = rb_define_class("CAStack", rb_cCAView);
1248
1390
  rb_cCAStackMask = rb_define_class("CAStackMask", rb_cCAStack);
1249
1391
 
1392
+ ca_stack_func.fill_addrs = ca_stack_put_fill_addrs;
1393
+ ca_stack_func.fill_stride = ca_stack_put_fill_stride;
1394
+
1250
1395
  CA_OBJ_STACK = ca_install_obj_type(rb_cCAStack,
1251
1396
  &castack_data_type,
1252
1397
  rb_cCAStackMask,