carray 3.0.5 → 3.0.6

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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +233 -0
  3. data/README.md +1 -1
  4. data/carray.gemspec +3 -2
  5. data/ext/ca_axis_dispatch.c +6 -0
  6. data/ext/ca_axis_group.c +1 -1
  7. data/ext/ca_categorical_iterator.c +7 -7
  8. data/ext/ca_kernel_iterator.c +116 -231
  9. data/ext/ca_kernel_iterator.h +410 -254
  10. data/ext/ca_obj_bincmp.c +9 -1
  11. data/ext/ca_obj_binop.c +10 -1
  12. data/ext/ca_obj_bitfield.c +2 -0
  13. data/ext/ca_obj_byte_swap.c +2 -0
  14. data/ext/ca_obj_face.c +2 -0
  15. data/ext/ca_obj_fake.c +3 -1
  16. data/ext/ca_obj_grid.c +167 -12
  17. data/ext/ca_obj_meld.c +69 -113
  18. data/ext/ca_obj_moncmp.c +9 -1
  19. data/ext/ca_obj_monop.c +40 -2
  20. data/ext/ca_obj_object.c +54 -20
  21. data/ext/ca_obj_reduce.c +15 -1
  22. data/ext/ca_obj_refer.c +65 -20
  23. data/ext/ca_obj_remap.c +69 -10
  24. data/ext/ca_obj_roll.c +1 -0
  25. data/ext/ca_obj_select.c +4 -1
  26. data/ext/ca_obj_select_axis.c +1 -0
  27. data/ext/ca_obj_shift.c +1 -0
  28. data/ext/ca_obj_stack.c +310 -111
  29. data/ext/ca_obj_stride.c +131 -45
  30. data/ext/ca_obj_string.c +18 -2
  31. data/ext/ca_obj_tile.c +1 -0
  32. data/ext/ca_obj_triop.c +9 -1
  33. data/ext/ca_obj_window.c +1 -0
  34. data/ext/ca_op_ipower.c +8 -8
  35. data/ext/caframe_csv_reader.c +1 -1
  36. data/ext/carray.h +2 -1
  37. data/ext/carray_access.c +27 -64
  38. data/ext/carray_address_basis.c +134 -0
  39. data/ext/carray_attribute.c +8 -0
  40. data/ext/carray_broadcast.c +3 -4
  41. data/ext/carray_build_flags.h +1 -1
  42. data/ext/carray_cast.c +8 -11
  43. data/ext/carray_conversion.c +9 -5
  44. data/ext/carray_core.c +811 -72
  45. data/ext/carray_element.c +13 -9
  46. data/ext/carray_histogram.c +25 -3
  47. data/ext/carray_internal.h +147 -12
  48. data/ext/carray_kernels_bincmp.c +2007 -3
  49. data/ext/carray_kernels_binop.c +25365 -5199
  50. data/ext/carray_kernels_init.c +8 -8
  51. data/ext/carray_kernels_monop.c +10696 -3678
  52. data/ext/carray_kernels_reduce_aggregate.c +4429 -702
  53. data/ext/carray_kernels_reduce_boolean.c +1533 -15
  54. data/ext/carray_kernels_reduce_cumulative.c +1808 -248
  55. data/ext/carray_kernels_reduce_extreme.c +4508 -511
  56. data/ext/carray_kernels_reduce_variance.c +2284 -152
  57. data/ext/carray_kernels_scan.c +240 -240
  58. data/ext/carray_kernels_search.c +4211 -264
  59. data/ext/carray_kernels_sort.c +367 -450
  60. data/ext/carray_lazy.c +47 -0
  61. data/ext/carray_loop.c +1 -1
  62. data/ext/carray_mask.c +130 -139
  63. data/ext/carray_median_percentile.c +4 -4
  64. data/ext/carray_memory_view.c +13 -7
  65. data/ext/carray_operator.c +147 -44
  66. data/ext/carray_order.c +3 -2
  67. data/ext/carray_random.c +4 -1
  68. data/ext/carray_slab.c +97 -21
  69. data/ext/carray_sort.c +1 -1
  70. data/ext/carray_test.c +74 -19
  71. data/ext/carray_time_text.c +2 -2
  72. data/ext/extconf.rb +11 -0
  73. data/ext/mkkernel.rb +346 -94
  74. data/ext/ruby_carray.c +4 -1
  75. data/ext/version.h +4 -4
  76. data/lib/carray/attribute.rb +25 -1
  77. data/lib/carray/autoload_carray.rb +3 -3
  78. data/lib/carray/autoload_method_extension.rb +5 -3
  79. data/lib/carray/axis_group.rb +13 -7
  80. data/lib/carray/basics.rb +1 -1
  81. data/lib/carray/block_iterator.rb +17 -3
  82. data/lib/carray/categorical.rb +6 -8
  83. data/lib/carray/categorical_iterator.rb +2 -2
  84. data/lib/carray/complex.rb +2 -2
  85. data/lib/carray/conditional.rb +3 -2
  86. data/lib/carray/frame/column_verbs.rb +45 -14
  87. data/lib/carray/frame/convert.rb +19 -0
  88. data/lib/carray/frame/csv_parser.rb +32 -32
  89. data/lib/carray/frame/describe.rb +4 -2
  90. data/lib/carray/frame/frame.rb +399 -78
  91. data/lib/carray/frame/group.rb +679 -53
  92. data/lib/carray/frame/io.rb +209 -71
  93. data/lib/carray/frame/join.rb +146 -37
  94. data/lib/carray/frame/records.rb +3 -3
  95. data/lib/carray/frame/reshape.rb +89 -11
  96. data/lib/carray/frame/sort.rb +57 -9
  97. data/lib/carray/frame/verbs.rb +384 -49
  98. data/lib/carray/frame/windows.rb +44 -6
  99. data/lib/carray/inspect.rb +7 -2
  100. data/lib/carray/iterator.rb +32 -0
  101. data/lib/carray/lazy.rb +17 -8
  102. data/lib/carray/mask_gap_fill.rb +37 -17
  103. data/lib/carray/meld_reduce.rb +1 -1
  104. data/lib/carray/methods/choose.rb +3 -2
  105. data/lib/carray/methods/meshgrid.rb +3 -1
  106. data/lib/carray/runtime.rb +47 -8
  107. data/lib/carray/segment_iterator.rb +23 -8
  108. data/lib/carray/serialize.rb +34 -17
  109. data/lib/carray/stack.rb +18 -6
  110. data/lib/carray/time.rb +5 -0
  111. data/lib/carray/window_iterator.rb +16 -4
  112. data/yard-stubs/ca_obj_array.rb +26 -1
  113. data/yard-stubs/carray_cast.rb +8 -5
  114. data/yard-stubs/carray_conversion.rb +8 -2
  115. data/yard-stubs/carray_mask.rb +20 -1
  116. data/yard-stubs/carray_math.rb +31 -16
  117. data/yard-stubs/carray_memory_view.rb +7 -0
  118. data/yard-stubs/carray_test.rb +7 -4
  119. metadata +18 -4
@@ -63,6 +63,13 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
63
63
  positions align between iterators. */
64
64
  int8_t slab_axes[CA_RANK_MAX];
65
65
  slab_axes[0] = (int8_t) axis;
66
+ ca_size_t fiber_n = ca->dim[axis];
67
+ volatile VALUE hbuf = 0, haux = 0;
68
+ sort_index_pair_i8 *buf = ALLOCV_N(sort_index_pair_i8, hbuf, fiber_n);
69
+ sort_index_pair_i8 *aux = NULL;
70
+ if ( do_stable ) {
71
+ aux = ALLOCV_N(sort_index_pair_i8, haux, fiber_n);
72
+ }
66
73
  ca_iter_state st_in, st_out;
67
74
  int rc;
68
75
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -77,14 +84,6 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
77
84
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
78
85
  }
79
86
 
80
- ca_size_t fiber_n = st_in.slab_elements;
81
- volatile VALUE hbuf = 0, haux = 0;
82
- sort_index_pair_i8 *buf = ALLOCV_N(sort_index_pair_i8, hbuf, fiber_n);
83
- sort_index_pair_i8 *aux = NULL;
84
- if ( do_stable ) {
85
- aux = ALLOCV_N(sort_index_pair_i8, haux, fiber_n);
86
- }
87
-
88
87
  char *pi, *po;
89
88
  boolean8_t *mi, *mo;
90
89
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -178,6 +177,13 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
178
177
  positions align between iterators. */
179
178
  int8_t slab_axes[CA_RANK_MAX];
180
179
  slab_axes[0] = (int8_t) axis;
180
+ ca_size_t fiber_n = ca->dim[axis];
181
+ volatile VALUE hbuf = 0, haux = 0;
182
+ sort_index_pair_u8 *buf = ALLOCV_N(sort_index_pair_u8, hbuf, fiber_n);
183
+ sort_index_pair_u8 *aux = NULL;
184
+ if ( do_stable ) {
185
+ aux = ALLOCV_N(sort_index_pair_u8, haux, fiber_n);
186
+ }
181
187
  ca_iter_state st_in, st_out;
182
188
  int rc;
183
189
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -192,14 +198,6 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
192
198
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
193
199
  }
194
200
 
195
- ca_size_t fiber_n = st_in.slab_elements;
196
- volatile VALUE hbuf = 0, haux = 0;
197
- sort_index_pair_u8 *buf = ALLOCV_N(sort_index_pair_u8, hbuf, fiber_n);
198
- sort_index_pair_u8 *aux = NULL;
199
- if ( do_stable ) {
200
- aux = ALLOCV_N(sort_index_pair_u8, haux, fiber_n);
201
- }
202
-
203
201
  char *pi, *po;
204
202
  boolean8_t *mi, *mo;
205
203
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -293,6 +291,13 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
293
291
  positions align between iterators. */
294
292
  int8_t slab_axes[CA_RANK_MAX];
295
293
  slab_axes[0] = (int8_t) axis;
294
+ ca_size_t fiber_n = ca->dim[axis];
295
+ volatile VALUE hbuf = 0, haux = 0;
296
+ sort_index_pair_i16 *buf = ALLOCV_N(sort_index_pair_i16, hbuf, fiber_n);
297
+ sort_index_pair_i16 *aux = NULL;
298
+ if ( do_stable ) {
299
+ aux = ALLOCV_N(sort_index_pair_i16, haux, fiber_n);
300
+ }
296
301
  ca_iter_state st_in, st_out;
297
302
  int rc;
298
303
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -307,14 +312,6 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
307
312
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
308
313
  }
309
314
 
310
- ca_size_t fiber_n = st_in.slab_elements;
311
- volatile VALUE hbuf = 0, haux = 0;
312
- sort_index_pair_i16 *buf = ALLOCV_N(sort_index_pair_i16, hbuf, fiber_n);
313
- sort_index_pair_i16 *aux = NULL;
314
- if ( do_stable ) {
315
- aux = ALLOCV_N(sort_index_pair_i16, haux, fiber_n);
316
- }
317
-
318
315
  char *pi, *po;
319
316
  boolean8_t *mi, *mo;
320
317
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -408,6 +405,13 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
408
405
  positions align between iterators. */
409
406
  int8_t slab_axes[CA_RANK_MAX];
410
407
  slab_axes[0] = (int8_t) axis;
408
+ ca_size_t fiber_n = ca->dim[axis];
409
+ volatile VALUE hbuf = 0, haux = 0;
410
+ sort_index_pair_u16 *buf = ALLOCV_N(sort_index_pair_u16, hbuf, fiber_n);
411
+ sort_index_pair_u16 *aux = NULL;
412
+ if ( do_stable ) {
413
+ aux = ALLOCV_N(sort_index_pair_u16, haux, fiber_n);
414
+ }
411
415
  ca_iter_state st_in, st_out;
412
416
  int rc;
413
417
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -422,14 +426,6 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
422
426
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
423
427
  }
424
428
 
425
- ca_size_t fiber_n = st_in.slab_elements;
426
- volatile VALUE hbuf = 0, haux = 0;
427
- sort_index_pair_u16 *buf = ALLOCV_N(sort_index_pair_u16, hbuf, fiber_n);
428
- sort_index_pair_u16 *aux = NULL;
429
- if ( do_stable ) {
430
- aux = ALLOCV_N(sort_index_pair_u16, haux, fiber_n);
431
- }
432
-
433
429
  char *pi, *po;
434
430
  boolean8_t *mi, *mo;
435
431
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -523,6 +519,13 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
523
519
  positions align between iterators. */
524
520
  int8_t slab_axes[CA_RANK_MAX];
525
521
  slab_axes[0] = (int8_t) axis;
522
+ ca_size_t fiber_n = ca->dim[axis];
523
+ volatile VALUE hbuf = 0, haux = 0;
524
+ sort_index_pair_i32 *buf = ALLOCV_N(sort_index_pair_i32, hbuf, fiber_n);
525
+ sort_index_pair_i32 *aux = NULL;
526
+ if ( do_stable ) {
527
+ aux = ALLOCV_N(sort_index_pair_i32, haux, fiber_n);
528
+ }
526
529
  ca_iter_state st_in, st_out;
527
530
  int rc;
528
531
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -537,14 +540,6 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
537
540
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
538
541
  }
539
542
 
540
- ca_size_t fiber_n = st_in.slab_elements;
541
- volatile VALUE hbuf = 0, haux = 0;
542
- sort_index_pair_i32 *buf = ALLOCV_N(sort_index_pair_i32, hbuf, fiber_n);
543
- sort_index_pair_i32 *aux = NULL;
544
- if ( do_stable ) {
545
- aux = ALLOCV_N(sort_index_pair_i32, haux, fiber_n);
546
- }
547
-
548
543
  char *pi, *po;
549
544
  boolean8_t *mi, *mo;
550
545
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -638,6 +633,13 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
638
633
  positions align between iterators. */
639
634
  int8_t slab_axes[CA_RANK_MAX];
640
635
  slab_axes[0] = (int8_t) axis;
636
+ ca_size_t fiber_n = ca->dim[axis];
637
+ volatile VALUE hbuf = 0, haux = 0;
638
+ sort_index_pair_u32 *buf = ALLOCV_N(sort_index_pair_u32, hbuf, fiber_n);
639
+ sort_index_pair_u32 *aux = NULL;
640
+ if ( do_stable ) {
641
+ aux = ALLOCV_N(sort_index_pair_u32, haux, fiber_n);
642
+ }
641
643
  ca_iter_state st_in, st_out;
642
644
  int rc;
643
645
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -652,14 +654,6 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
652
654
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
653
655
  }
654
656
 
655
- ca_size_t fiber_n = st_in.slab_elements;
656
- volatile VALUE hbuf = 0, haux = 0;
657
- sort_index_pair_u32 *buf = ALLOCV_N(sort_index_pair_u32, hbuf, fiber_n);
658
- sort_index_pair_u32 *aux = NULL;
659
- if ( do_stable ) {
660
- aux = ALLOCV_N(sort_index_pair_u32, haux, fiber_n);
661
- }
662
-
663
657
  char *pi, *po;
664
658
  boolean8_t *mi, *mo;
665
659
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -753,6 +747,13 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
753
747
  positions align between iterators. */
754
748
  int8_t slab_axes[CA_RANK_MAX];
755
749
  slab_axes[0] = (int8_t) axis;
750
+ ca_size_t fiber_n = ca->dim[axis];
751
+ volatile VALUE hbuf = 0, haux = 0;
752
+ sort_index_pair_i64 *buf = ALLOCV_N(sort_index_pair_i64, hbuf, fiber_n);
753
+ sort_index_pair_i64 *aux = NULL;
754
+ if ( do_stable ) {
755
+ aux = ALLOCV_N(sort_index_pair_i64, haux, fiber_n);
756
+ }
756
757
  ca_iter_state st_in, st_out;
757
758
  int rc;
758
759
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -767,14 +768,6 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
767
768
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
768
769
  }
769
770
 
770
- ca_size_t fiber_n = st_in.slab_elements;
771
- volatile VALUE hbuf = 0, haux = 0;
772
- sort_index_pair_i64 *buf = ALLOCV_N(sort_index_pair_i64, hbuf, fiber_n);
773
- sort_index_pair_i64 *aux = NULL;
774
- if ( do_stable ) {
775
- aux = ALLOCV_N(sort_index_pair_i64, haux, fiber_n);
776
- }
777
-
778
771
  char *pi, *po;
779
772
  boolean8_t *mi, *mo;
780
773
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -868,6 +861,13 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
868
861
  positions align between iterators. */
869
862
  int8_t slab_axes[CA_RANK_MAX];
870
863
  slab_axes[0] = (int8_t) axis;
864
+ ca_size_t fiber_n = ca->dim[axis];
865
+ volatile VALUE hbuf = 0, haux = 0;
866
+ sort_index_pair_u64 *buf = ALLOCV_N(sort_index_pair_u64, hbuf, fiber_n);
867
+ sort_index_pair_u64 *aux = NULL;
868
+ if ( do_stable ) {
869
+ aux = ALLOCV_N(sort_index_pair_u64, haux, fiber_n);
870
+ }
871
871
  ca_iter_state st_in, st_out;
872
872
  int rc;
873
873
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -882,14 +882,6 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
882
882
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
883
883
  }
884
884
 
885
- ca_size_t fiber_n = st_in.slab_elements;
886
- volatile VALUE hbuf = 0, haux = 0;
887
- sort_index_pair_u64 *buf = ALLOCV_N(sort_index_pair_u64, hbuf, fiber_n);
888
- sort_index_pair_u64 *aux = NULL;
889
- if ( do_stable ) {
890
- aux = ALLOCV_N(sort_index_pair_u64, haux, fiber_n);
891
- }
892
-
893
885
  char *pi, *po;
894
886
  boolean8_t *mi, *mo;
895
887
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -983,6 +975,10 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
983
975
  positions align between iterators. */
984
976
  int8_t slab_axes[CA_RANK_MAX];
985
977
  slab_axes[0] = (int8_t) axis;
978
+ ca_size_t fiber_n = ca->dim[axis];
979
+ volatile VALUE hbuf = 0, haux = 0;
980
+ sort_index_pair_f32 *buf = ALLOCV_N(sort_index_pair_f32, hbuf, fiber_n);
981
+ sort_index_pair_f32 *aux = ALLOCV_N(sort_index_pair_f32, haux, fiber_n);
986
982
  ca_iter_state st_in, st_out;
987
983
  int rc;
988
984
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -997,14 +993,6 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
997
993
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
998
994
  }
999
995
 
1000
- ca_size_t fiber_n = st_in.slab_elements;
1001
- volatile VALUE hbuf = 0, haux = 0;
1002
- sort_index_pair_f32 *buf = ALLOCV_N(sort_index_pair_f32, hbuf, fiber_n);
1003
- sort_index_pair_f32 *aux = NULL;
1004
- if ( do_stable ) {
1005
- aux = ALLOCV_N(sort_index_pair_f32, haux, fiber_n);
1006
- }
1007
-
1008
996
  char *pi, *po;
1009
997
  boolean8_t *mi, *mo;
1010
998
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1065,7 +1053,7 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1065
1053
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
1066
1054
  pushed to the tail (= NaN-at-end policy, matches sort_copy
1067
1055
  AC8). Only the finite slice is sorted. */
1068
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n);
1056
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f32 *) aux);
1069
1057
  if ( do_stable ) {
1070
1058
  ca_sort_merge_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_pair_f32 *) aux, finite_n);
1071
1059
  } else {
@@ -1102,6 +1090,10 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1102
1090
  positions align between iterators. */
1103
1091
  int8_t slab_axes[CA_RANK_MAX];
1104
1092
  slab_axes[0] = (int8_t) axis;
1093
+ ca_size_t fiber_n = ca->dim[axis];
1094
+ volatile VALUE hbuf = 0, haux = 0;
1095
+ sort_index_pair_f64 *buf = ALLOCV_N(sort_index_pair_f64, hbuf, fiber_n);
1096
+ sort_index_pair_f64 *aux = ALLOCV_N(sort_index_pair_f64, haux, fiber_n);
1105
1097
  ca_iter_state st_in, st_out;
1106
1098
  int rc;
1107
1099
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1116,14 +1108,6 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1116
1108
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1117
1109
  }
1118
1110
 
1119
- ca_size_t fiber_n = st_in.slab_elements;
1120
- volatile VALUE hbuf = 0, haux = 0;
1121
- sort_index_pair_f64 *buf = ALLOCV_N(sort_index_pair_f64, hbuf, fiber_n);
1122
- sort_index_pair_f64 *aux = NULL;
1123
- if ( do_stable ) {
1124
- aux = ALLOCV_N(sort_index_pair_f64, haux, fiber_n);
1125
- }
1126
-
1127
1111
  char *pi, *po;
1128
1112
  boolean8_t *mi, *mo;
1129
1113
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1184,7 +1168,7 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1184
1168
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
1185
1169
  pushed to the tail (= NaN-at-end policy, matches sort_copy
1186
1170
  AC8). Only the finite slice is sorted. */
1187
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n);
1171
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f64 *) aux);
1188
1172
  if ( do_stable ) {
1189
1173
  ca_sort_merge_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_pair_f64 *) aux, finite_n);
1190
1174
  } else {
@@ -1221,6 +1205,13 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1221
1205
  positions align between iterators. */
1222
1206
  int8_t slab_axes[CA_RANK_MAX];
1223
1207
  slab_axes[0] = (int8_t) axis;
1208
+ ca_size_t fiber_n = ca->dim[axis];
1209
+ volatile VALUE hbuf = 0, haux = 0;
1210
+ sort_index_pair_bool *buf = ALLOCV_N(sort_index_pair_bool, hbuf, fiber_n);
1211
+ sort_index_pair_bool *aux = NULL;
1212
+ if ( do_stable ) {
1213
+ aux = ALLOCV_N(sort_index_pair_bool, haux, fiber_n);
1214
+ }
1224
1215
  ca_iter_state st_in, st_out;
1225
1216
  int rc;
1226
1217
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1235,14 +1226,6 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1235
1226
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1236
1227
  }
1237
1228
 
1238
- ca_size_t fiber_n = st_in.slab_elements;
1239
- volatile VALUE hbuf = 0, haux = 0;
1240
- sort_index_pair_bool *buf = ALLOCV_N(sort_index_pair_bool, hbuf, fiber_n);
1241
- sort_index_pair_bool *aux = NULL;
1242
- if ( do_stable ) {
1243
- aux = ALLOCV_N(sort_index_pair_bool, haux, fiber_n);
1244
- }
1245
-
1246
1229
  char *pi, *po;
1247
1230
  boolean8_t *mi, *mo;
1248
1231
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1336,9 +1319,9 @@ sort_index_cmp_object (const void *a, const void *b)
1336
1319
  return 0;
1337
1320
  }
1338
1321
 
1339
- /* The object lane calls Ruby for every cell, so a walk can raise part
1340
- way. Its states live in the caller's frame, and ca_iter_ensure
1341
- finishes them however the body leaves. */
1322
+ /* The walks can raise part way (a Ruby call per cell in the object
1323
+ lane, an allocation in any lane). Their states live in the caller's
1324
+ frame, and ca_iter_ensure finishes them however the body leaves. */
1342
1325
  typedef struct {
1343
1326
  ca_iter_state states[2];
1344
1327
  VALUE self;
@@ -1374,6 +1357,10 @@ sort_index_ki_native_object_body (VALUE arg)
1374
1357
  positions align between iterators. */
1375
1358
  int8_t slab_axes[CA_RANK_MAX];
1376
1359
  slab_axes[0] = (int8_t) axis;
1360
+ ca_size_t fiber_n = ca->dim[axis];
1361
+ volatile VALUE hbuf = 0, haux = 0;
1362
+ sort_index_pair_object *buf = ALLOCV_N(sort_index_pair_object, hbuf, fiber_n);
1363
+ sort_index_pair_object *aux = ALLOCV_N(sort_index_pair_object, haux, fiber_n);
1377
1364
  int rc;
1378
1365
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1379
1366
  slab_axes, 1, 0);
@@ -1387,11 +1374,6 @@ sort_index_ki_native_object_body (VALUE arg)
1387
1374
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1388
1375
  }
1389
1376
 
1390
- ca_size_t fiber_n = st_in.slab_elements;
1391
- volatile VALUE hbuf = 0, haux = 0;
1392
- sort_index_pair_object *buf = ALLOCV_N(sort_index_pair_object, hbuf, fiber_n);
1393
- sort_index_pair_object *aux = ALLOCV_N(sort_index_pair_object, haux, fiber_n);
1394
-
1395
1377
  char *pi, *po;
1396
1378
  boolean8_t *mi, *mo;
1397
1379
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1475,7 +1457,7 @@ sort_index_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, in
1475
1457
  fr.axis = axis;
1476
1458
  fr.do_stable = do_stable;
1477
1459
  fr.masked_last = masked_last;
1478
- return ca_iter_ensure(2, fr.states, sort_index_ki_native_object_body, (VALUE) &fr);
1460
+ return ca_iter_ensure_computing(ca, 2, fr.states, sort_index_ki_native_object_body, (VALUE) &fr);
1479
1461
  }
1480
1462
 
1481
1463
 
@@ -1511,6 +1493,10 @@ sort_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
1511
1493
  positions align between iterators. */
1512
1494
  int8_t slab_axes[CA_RANK_MAX];
1513
1495
  slab_axes[0] = (int8_t) axis;
1496
+ ca_size_t fiber_n = ca->dim[axis];
1497
+ volatile VALUE hbuf = 0, haux = 0;
1498
+ sort_index_pair_fixlen *buf = ALLOCV_N(sort_index_pair_fixlen, hbuf, fiber_n);
1499
+ (void) haux;
1514
1500
  ca_iter_state st_in, st_out;
1515
1501
  int rc;
1516
1502
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1525,11 +1511,6 @@ sort_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
1525
1511
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1526
1512
  }
1527
1513
 
1528
- ca_size_t fiber_n = st_in.slab_elements;
1529
- volatile VALUE hbuf = 0, haux = 0;
1530
- sort_index_pair_fixlen *buf = ALLOCV_N(sort_index_pair_fixlen, hbuf, fiber_n);
1531
- (void) haux;
1532
-
1533
1514
  char *pi, *po;
1534
1515
  boolean8_t *mi, *mo;
1535
1516
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1710,6 +1691,13 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1710
1691
  positions align between iterators. */
1711
1692
  int8_t slab_axes[CA_RANK_MAX];
1712
1693
  slab_axes[0] = (int8_t) axis;
1694
+ ca_size_t fiber_n = ca->dim[axis];
1695
+ volatile VALUE hbuf = 0, haux = 0;
1696
+ sort_addr_pair_i8 *buf = ALLOCV_N(sort_addr_pair_i8, hbuf, fiber_n);
1697
+ sort_addr_pair_i8 *aux = NULL;
1698
+ if ( do_stable ) {
1699
+ aux = ALLOCV_N(sort_addr_pair_i8, haux, fiber_n);
1700
+ }
1713
1701
  ca_iter_state st_in, st_out;
1714
1702
  int rc;
1715
1703
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1724,14 +1712,6 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1724
1712
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1725
1713
  }
1726
1714
 
1727
- ca_size_t fiber_n = st_in.slab_elements;
1728
- volatile VALUE hbuf = 0, haux = 0;
1729
- sort_addr_pair_i8 *buf = ALLOCV_N(sort_addr_pair_i8, hbuf, fiber_n);
1730
- sort_addr_pair_i8 *aux = NULL;
1731
- if ( do_stable ) {
1732
- aux = ALLOCV_N(sort_addr_pair_i8, haux, fiber_n);
1733
- }
1734
-
1735
1715
  /* :view_flat semantics: kernel computes view-flat address
1736
1716
  (= row-major position in ca's shape, 0..elements-1) for
1737
1717
  each cell. Used to feed CARemap.idx directly (= sort
@@ -1857,6 +1837,13 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1857
1837
  positions align between iterators. */
1858
1838
  int8_t slab_axes[CA_RANK_MAX];
1859
1839
  slab_axes[0] = (int8_t) axis;
1840
+ ca_size_t fiber_n = ca->dim[axis];
1841
+ volatile VALUE hbuf = 0, haux = 0;
1842
+ sort_addr_pair_u8 *buf = ALLOCV_N(sort_addr_pair_u8, hbuf, fiber_n);
1843
+ sort_addr_pair_u8 *aux = NULL;
1844
+ if ( do_stable ) {
1845
+ aux = ALLOCV_N(sort_addr_pair_u8, haux, fiber_n);
1846
+ }
1860
1847
  ca_iter_state st_in, st_out;
1861
1848
  int rc;
1862
1849
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1871,14 +1858,6 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1871
1858
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1872
1859
  }
1873
1860
 
1874
- ca_size_t fiber_n = st_in.slab_elements;
1875
- volatile VALUE hbuf = 0, haux = 0;
1876
- sort_addr_pair_u8 *buf = ALLOCV_N(sort_addr_pair_u8, hbuf, fiber_n);
1877
- sort_addr_pair_u8 *aux = NULL;
1878
- if ( do_stable ) {
1879
- aux = ALLOCV_N(sort_addr_pair_u8, haux, fiber_n);
1880
- }
1881
-
1882
1861
  /* :view_flat semantics: kernel computes view-flat address
1883
1862
  (= row-major position in ca's shape, 0..elements-1) for
1884
1863
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2004,6 +1983,13 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2004
1983
  positions align between iterators. */
2005
1984
  int8_t slab_axes[CA_RANK_MAX];
2006
1985
  slab_axes[0] = (int8_t) axis;
1986
+ ca_size_t fiber_n = ca->dim[axis];
1987
+ volatile VALUE hbuf = 0, haux = 0;
1988
+ sort_addr_pair_i16 *buf = ALLOCV_N(sort_addr_pair_i16, hbuf, fiber_n);
1989
+ sort_addr_pair_i16 *aux = NULL;
1990
+ if ( do_stable ) {
1991
+ aux = ALLOCV_N(sort_addr_pair_i16, haux, fiber_n);
1992
+ }
2007
1993
  ca_iter_state st_in, st_out;
2008
1994
  int rc;
2009
1995
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2018,14 +2004,6 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2018
2004
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2019
2005
  }
2020
2006
 
2021
- ca_size_t fiber_n = st_in.slab_elements;
2022
- volatile VALUE hbuf = 0, haux = 0;
2023
- sort_addr_pair_i16 *buf = ALLOCV_N(sort_addr_pair_i16, hbuf, fiber_n);
2024
- sort_addr_pair_i16 *aux = NULL;
2025
- if ( do_stable ) {
2026
- aux = ALLOCV_N(sort_addr_pair_i16, haux, fiber_n);
2027
- }
2028
-
2029
2007
  /* :view_flat semantics: kernel computes view-flat address
2030
2008
  (= row-major position in ca's shape, 0..elements-1) for
2031
2009
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2151,6 +2129,13 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2151
2129
  positions align between iterators. */
2152
2130
  int8_t slab_axes[CA_RANK_MAX];
2153
2131
  slab_axes[0] = (int8_t) axis;
2132
+ ca_size_t fiber_n = ca->dim[axis];
2133
+ volatile VALUE hbuf = 0, haux = 0;
2134
+ sort_addr_pair_u16 *buf = ALLOCV_N(sort_addr_pair_u16, hbuf, fiber_n);
2135
+ sort_addr_pair_u16 *aux = NULL;
2136
+ if ( do_stable ) {
2137
+ aux = ALLOCV_N(sort_addr_pair_u16, haux, fiber_n);
2138
+ }
2154
2139
  ca_iter_state st_in, st_out;
2155
2140
  int rc;
2156
2141
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2165,14 +2150,6 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2165
2150
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2166
2151
  }
2167
2152
 
2168
- ca_size_t fiber_n = st_in.slab_elements;
2169
- volatile VALUE hbuf = 0, haux = 0;
2170
- sort_addr_pair_u16 *buf = ALLOCV_N(sort_addr_pair_u16, hbuf, fiber_n);
2171
- sort_addr_pair_u16 *aux = NULL;
2172
- if ( do_stable ) {
2173
- aux = ALLOCV_N(sort_addr_pair_u16, haux, fiber_n);
2174
- }
2175
-
2176
2153
  /* :view_flat semantics: kernel computes view-flat address
2177
2154
  (= row-major position in ca's shape, 0..elements-1) for
2178
2155
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2298,6 +2275,13 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2298
2275
  positions align between iterators. */
2299
2276
  int8_t slab_axes[CA_RANK_MAX];
2300
2277
  slab_axes[0] = (int8_t) axis;
2278
+ ca_size_t fiber_n = ca->dim[axis];
2279
+ volatile VALUE hbuf = 0, haux = 0;
2280
+ sort_addr_pair_i32 *buf = ALLOCV_N(sort_addr_pair_i32, hbuf, fiber_n);
2281
+ sort_addr_pair_i32 *aux = NULL;
2282
+ if ( do_stable ) {
2283
+ aux = ALLOCV_N(sort_addr_pair_i32, haux, fiber_n);
2284
+ }
2301
2285
  ca_iter_state st_in, st_out;
2302
2286
  int rc;
2303
2287
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2312,14 +2296,6 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2312
2296
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2313
2297
  }
2314
2298
 
2315
- ca_size_t fiber_n = st_in.slab_elements;
2316
- volatile VALUE hbuf = 0, haux = 0;
2317
- sort_addr_pair_i32 *buf = ALLOCV_N(sort_addr_pair_i32, hbuf, fiber_n);
2318
- sort_addr_pair_i32 *aux = NULL;
2319
- if ( do_stable ) {
2320
- aux = ALLOCV_N(sort_addr_pair_i32, haux, fiber_n);
2321
- }
2322
-
2323
2299
  /* :view_flat semantics: kernel computes view-flat address
2324
2300
  (= row-major position in ca's shape, 0..elements-1) for
2325
2301
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2445,6 +2421,13 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2445
2421
  positions align between iterators. */
2446
2422
  int8_t slab_axes[CA_RANK_MAX];
2447
2423
  slab_axes[0] = (int8_t) axis;
2424
+ ca_size_t fiber_n = ca->dim[axis];
2425
+ volatile VALUE hbuf = 0, haux = 0;
2426
+ sort_addr_pair_u32 *buf = ALLOCV_N(sort_addr_pair_u32, hbuf, fiber_n);
2427
+ sort_addr_pair_u32 *aux = NULL;
2428
+ if ( do_stable ) {
2429
+ aux = ALLOCV_N(sort_addr_pair_u32, haux, fiber_n);
2430
+ }
2448
2431
  ca_iter_state st_in, st_out;
2449
2432
  int rc;
2450
2433
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2459,14 +2442,6 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2459
2442
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2460
2443
  }
2461
2444
 
2462
- ca_size_t fiber_n = st_in.slab_elements;
2463
- volatile VALUE hbuf = 0, haux = 0;
2464
- sort_addr_pair_u32 *buf = ALLOCV_N(sort_addr_pair_u32, hbuf, fiber_n);
2465
- sort_addr_pair_u32 *aux = NULL;
2466
- if ( do_stable ) {
2467
- aux = ALLOCV_N(sort_addr_pair_u32, haux, fiber_n);
2468
- }
2469
-
2470
2445
  /* :view_flat semantics: kernel computes view-flat address
2471
2446
  (= row-major position in ca's shape, 0..elements-1) for
2472
2447
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2592,6 +2567,13 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2592
2567
  positions align between iterators. */
2593
2568
  int8_t slab_axes[CA_RANK_MAX];
2594
2569
  slab_axes[0] = (int8_t) axis;
2570
+ ca_size_t fiber_n = ca->dim[axis];
2571
+ volatile VALUE hbuf = 0, haux = 0;
2572
+ sort_addr_pair_i64 *buf = ALLOCV_N(sort_addr_pair_i64, hbuf, fiber_n);
2573
+ sort_addr_pair_i64 *aux = NULL;
2574
+ if ( do_stable ) {
2575
+ aux = ALLOCV_N(sort_addr_pair_i64, haux, fiber_n);
2576
+ }
2595
2577
  ca_iter_state st_in, st_out;
2596
2578
  int rc;
2597
2579
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2606,14 +2588,6 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2606
2588
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2607
2589
  }
2608
2590
 
2609
- ca_size_t fiber_n = st_in.slab_elements;
2610
- volatile VALUE hbuf = 0, haux = 0;
2611
- sort_addr_pair_i64 *buf = ALLOCV_N(sort_addr_pair_i64, hbuf, fiber_n);
2612
- sort_addr_pair_i64 *aux = NULL;
2613
- if ( do_stable ) {
2614
- aux = ALLOCV_N(sort_addr_pair_i64, haux, fiber_n);
2615
- }
2616
-
2617
2591
  /* :view_flat semantics: kernel computes view-flat address
2618
2592
  (= row-major position in ca's shape, 0..elements-1) for
2619
2593
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2739,6 +2713,13 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2739
2713
  positions align between iterators. */
2740
2714
  int8_t slab_axes[CA_RANK_MAX];
2741
2715
  slab_axes[0] = (int8_t) axis;
2716
+ ca_size_t fiber_n = ca->dim[axis];
2717
+ volatile VALUE hbuf = 0, haux = 0;
2718
+ sort_addr_pair_u64 *buf = ALLOCV_N(sort_addr_pair_u64, hbuf, fiber_n);
2719
+ sort_addr_pair_u64 *aux = NULL;
2720
+ if ( do_stable ) {
2721
+ aux = ALLOCV_N(sort_addr_pair_u64, haux, fiber_n);
2722
+ }
2742
2723
  ca_iter_state st_in, st_out;
2743
2724
  int rc;
2744
2725
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2753,14 +2734,6 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2753
2734
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2754
2735
  }
2755
2736
 
2756
- ca_size_t fiber_n = st_in.slab_elements;
2757
- volatile VALUE hbuf = 0, haux = 0;
2758
- sort_addr_pair_u64 *buf = ALLOCV_N(sort_addr_pair_u64, hbuf, fiber_n);
2759
- sort_addr_pair_u64 *aux = NULL;
2760
- if ( do_stable ) {
2761
- aux = ALLOCV_N(sort_addr_pair_u64, haux, fiber_n);
2762
- }
2763
-
2764
2737
  /* :view_flat semantics: kernel computes view-flat address
2765
2738
  (= row-major position in ca's shape, 0..elements-1) for
2766
2739
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2886,6 +2859,10 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2886
2859
  positions align between iterators. */
2887
2860
  int8_t slab_axes[CA_RANK_MAX];
2888
2861
  slab_axes[0] = (int8_t) axis;
2862
+ ca_size_t fiber_n = ca->dim[axis];
2863
+ volatile VALUE hbuf = 0, haux = 0;
2864
+ sort_addr_pair_f32 *buf = ALLOCV_N(sort_addr_pair_f32, hbuf, fiber_n);
2865
+ sort_addr_pair_f32 *aux = ALLOCV_N(sort_addr_pair_f32, haux, fiber_n);
2889
2866
  ca_iter_state st_in, st_out;
2890
2867
  int rc;
2891
2868
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2900,14 +2877,6 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2900
2877
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2901
2878
  }
2902
2879
 
2903
- ca_size_t fiber_n = st_in.slab_elements;
2904
- volatile VALUE hbuf = 0, haux = 0;
2905
- sort_addr_pair_f32 *buf = ALLOCV_N(sort_addr_pair_f32, hbuf, fiber_n);
2906
- sort_addr_pair_f32 *aux = NULL;
2907
- if ( do_stable ) {
2908
- aux = ALLOCV_N(sort_addr_pair_f32, haux, fiber_n);
2909
- }
2910
-
2911
2880
  /* :view_flat semantics: kernel computes view-flat address
2912
2881
  (= row-major position in ca's shape, 0..elements-1) for
2913
2882
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2995,7 +2964,7 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2995
2964
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
2996
2965
  pushed to the tail (= NaN-at-end policy, matches sort_copy
2997
2966
  AC8). Only the finite slice is sorted. */
2998
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n);
2967
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f32 *) aux);
2999
2968
  if ( do_stable ) {
3000
2969
  ca_sort_merge_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_pair_f32 *) aux, finite_n);
3001
2970
  } else {
@@ -3037,6 +3006,10 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3037
3006
  positions align between iterators. */
3038
3007
  int8_t slab_axes[CA_RANK_MAX];
3039
3008
  slab_axes[0] = (int8_t) axis;
3009
+ ca_size_t fiber_n = ca->dim[axis];
3010
+ volatile VALUE hbuf = 0, haux = 0;
3011
+ sort_addr_pair_f64 *buf = ALLOCV_N(sort_addr_pair_f64, hbuf, fiber_n);
3012
+ sort_addr_pair_f64 *aux = ALLOCV_N(sort_addr_pair_f64, haux, fiber_n);
3040
3013
  ca_iter_state st_in, st_out;
3041
3014
  int rc;
3042
3015
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3051,14 +3024,6 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3051
3024
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3052
3025
  }
3053
3026
 
3054
- ca_size_t fiber_n = st_in.slab_elements;
3055
- volatile VALUE hbuf = 0, haux = 0;
3056
- sort_addr_pair_f64 *buf = ALLOCV_N(sort_addr_pair_f64, hbuf, fiber_n);
3057
- sort_addr_pair_f64 *aux = NULL;
3058
- if ( do_stable ) {
3059
- aux = ALLOCV_N(sort_addr_pair_f64, haux, fiber_n);
3060
- }
3061
-
3062
3027
  /* :view_flat semantics: kernel computes view-flat address
3063
3028
  (= row-major position in ca's shape, 0..elements-1) for
3064
3029
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3146,7 +3111,7 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3146
3111
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
3147
3112
  pushed to the tail (= NaN-at-end policy, matches sort_copy
3148
3113
  AC8). Only the finite slice is sorted. */
3149
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n);
3114
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f64 *) aux);
3150
3115
  if ( do_stable ) {
3151
3116
  ca_sort_merge_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_pair_f64 *) aux, finite_n);
3152
3117
  } else {
@@ -3188,6 +3153,13 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3188
3153
  positions align between iterators. */
3189
3154
  int8_t slab_axes[CA_RANK_MAX];
3190
3155
  slab_axes[0] = (int8_t) axis;
3156
+ ca_size_t fiber_n = ca->dim[axis];
3157
+ volatile VALUE hbuf = 0, haux = 0;
3158
+ sort_addr_pair_bool *buf = ALLOCV_N(sort_addr_pair_bool, hbuf, fiber_n);
3159
+ sort_addr_pair_bool *aux = NULL;
3160
+ if ( do_stable ) {
3161
+ aux = ALLOCV_N(sort_addr_pair_bool, haux, fiber_n);
3162
+ }
3191
3163
  ca_iter_state st_in, st_out;
3192
3164
  int rc;
3193
3165
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3202,14 +3174,6 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3202
3174
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3203
3175
  }
3204
3176
 
3205
- ca_size_t fiber_n = st_in.slab_elements;
3206
- volatile VALUE hbuf = 0, haux = 0;
3207
- sort_addr_pair_bool *buf = ALLOCV_N(sort_addr_pair_bool, hbuf, fiber_n);
3208
- sort_addr_pair_bool *aux = NULL;
3209
- if ( do_stable ) {
3210
- aux = ALLOCV_N(sort_addr_pair_bool, haux, fiber_n);
3211
- }
3212
-
3213
3177
  /* :view_flat semantics: kernel computes view-flat address
3214
3178
  (= row-major position in ca's shape, 0..elements-1) for
3215
3179
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3335,9 +3299,9 @@ sort_addr_cmp_object (const void *a, const void *b)
3335
3299
  return 0;
3336
3300
  }
3337
3301
 
3338
- /* The object lane calls Ruby for every cell, so a walk can raise part
3339
- way. Its states live in the caller's frame, and ca_iter_ensure
3340
- finishes them however the body leaves. */
3302
+ /* The walks can raise part way (a Ruby call per cell in the object
3303
+ lane, an allocation in any lane). Their states live in the caller's
3304
+ frame, and ca_iter_ensure finishes them however the body leaves. */
3341
3305
  typedef struct {
3342
3306
  ca_iter_state states[2];
3343
3307
  VALUE self;
@@ -3373,6 +3337,10 @@ sort_addr_ki_native_object_body (VALUE arg)
3373
3337
  positions align between iterators. */
3374
3338
  int8_t slab_axes[CA_RANK_MAX];
3375
3339
  slab_axes[0] = (int8_t) axis;
3340
+ ca_size_t fiber_n = ca->dim[axis];
3341
+ volatile VALUE hbuf = 0, haux = 0;
3342
+ sort_addr_pair_object *buf = ALLOCV_N(sort_addr_pair_object, hbuf, fiber_n);
3343
+ sort_addr_pair_object *aux = ALLOCV_N(sort_addr_pair_object, haux, fiber_n);
3376
3344
  int rc;
3377
3345
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3378
3346
  slab_axes, 1, 0);
@@ -3386,11 +3354,6 @@ sort_addr_ki_native_object_body (VALUE arg)
3386
3354
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3387
3355
  }
3388
3356
 
3389
- ca_size_t fiber_n = st_in.slab_elements;
3390
- volatile VALUE hbuf = 0, haux = 0;
3391
- sort_addr_pair_object *buf = ALLOCV_N(sort_addr_pair_object, hbuf, fiber_n);
3392
- sort_addr_pair_object *aux = ALLOCV_N(sort_addr_pair_object, haux, fiber_n);
3393
-
3394
3357
  /* :view_flat semantics: kernel computes view-flat address
3395
3358
  (= row-major position in ca's shape, 0..elements-1) for
3396
3359
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3506,7 +3469,7 @@ sort_addr_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, int
3506
3469
  fr.axis = axis;
3507
3470
  fr.do_stable = do_stable;
3508
3471
  fr.masked_last = masked_last;
3509
- return ca_iter_ensure(2, fr.states, sort_addr_ki_native_object_body, (VALUE) &fr);
3472
+ return ca_iter_ensure_computing(ca, 2, fr.states, sort_addr_ki_native_object_body, (VALUE) &fr);
3510
3473
  }
3511
3474
 
3512
3475
 
@@ -3542,6 +3505,10 @@ sort_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, int
3542
3505
  positions align between iterators. */
3543
3506
  int8_t slab_axes[CA_RANK_MAX];
3544
3507
  slab_axes[0] = (int8_t) axis;
3508
+ ca_size_t fiber_n = ca->dim[axis];
3509
+ volatile VALUE hbuf = 0, haux = 0;
3510
+ sort_addr_pair_fixlen *buf = ALLOCV_N(sort_addr_pair_fixlen, hbuf, fiber_n);
3511
+ (void) haux;
3545
3512
  ca_iter_state st_in, st_out;
3546
3513
  int rc;
3547
3514
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3556,11 +3523,6 @@ sort_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, int
3556
3523
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3557
3524
  }
3558
3525
 
3559
- ca_size_t fiber_n = st_in.slab_elements;
3560
- volatile VALUE hbuf = 0, haux = 0;
3561
- sort_addr_pair_fixlen *buf = ALLOCV_N(sort_addr_pair_fixlen, hbuf, fiber_n);
3562
- (void) haux;
3563
-
3564
3526
  /* :view_flat semantics: kernel computes view-flat address
3565
3527
  (= row-major position in ca's shape, 0..elements-1) for
3566
3528
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3811,6 +3773,10 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3811
3773
  positions align between iterators. */
3812
3774
  int8_t slab_axes[CA_RANK_MAX];
3813
3775
  slab_axes[0] = (int8_t) axis;
3776
+ ca_size_t fiber_n = ca->dim[axis];
3777
+ volatile VALUE hbuf = 0, haux = 0;
3778
+ partition_index_pair_i8 *buf = ALLOCV_N(partition_index_pair_i8, hbuf, fiber_n);
3779
+ (void) haux;
3814
3780
  ca_iter_state st_in, st_out;
3815
3781
  int rc;
3816
3782
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3825,11 +3791,6 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3825
3791
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3826
3792
  }
3827
3793
 
3828
- ca_size_t fiber_n = st_in.slab_elements;
3829
- volatile VALUE hbuf = 0, haux = 0;
3830
- partition_index_pair_i8 *buf = ALLOCV_N(partition_index_pair_i8, hbuf, fiber_n);
3831
- (void) haux;
3832
-
3833
3794
  char *pi, *po;
3834
3795
  boolean8_t *mi, *mo;
3835
3796
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -3990,6 +3951,10 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3990
3951
  positions align between iterators. */
3991
3952
  int8_t slab_axes[CA_RANK_MAX];
3992
3953
  slab_axes[0] = (int8_t) axis;
3954
+ ca_size_t fiber_n = ca->dim[axis];
3955
+ volatile VALUE hbuf = 0, haux = 0;
3956
+ partition_index_pair_u8 *buf = ALLOCV_N(partition_index_pair_u8, hbuf, fiber_n);
3957
+ (void) haux;
3993
3958
  ca_iter_state st_in, st_out;
3994
3959
  int rc;
3995
3960
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4004,11 +3969,6 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4004
3969
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4005
3970
  }
4006
3971
 
4007
- ca_size_t fiber_n = st_in.slab_elements;
4008
- volatile VALUE hbuf = 0, haux = 0;
4009
- partition_index_pair_u8 *buf = ALLOCV_N(partition_index_pair_u8, hbuf, fiber_n);
4010
- (void) haux;
4011
-
4012
3972
  char *pi, *po;
4013
3973
  boolean8_t *mi, *mo;
4014
3974
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4169,6 +4129,10 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4169
4129
  positions align between iterators. */
4170
4130
  int8_t slab_axes[CA_RANK_MAX];
4171
4131
  slab_axes[0] = (int8_t) axis;
4132
+ ca_size_t fiber_n = ca->dim[axis];
4133
+ volatile VALUE hbuf = 0, haux = 0;
4134
+ partition_index_pair_i16 *buf = ALLOCV_N(partition_index_pair_i16, hbuf, fiber_n);
4135
+ (void) haux;
4172
4136
  ca_iter_state st_in, st_out;
4173
4137
  int rc;
4174
4138
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4183,11 +4147,6 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4183
4147
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4184
4148
  }
4185
4149
 
4186
- ca_size_t fiber_n = st_in.slab_elements;
4187
- volatile VALUE hbuf = 0, haux = 0;
4188
- partition_index_pair_i16 *buf = ALLOCV_N(partition_index_pair_i16, hbuf, fiber_n);
4189
- (void) haux;
4190
-
4191
4150
  char *pi, *po;
4192
4151
  boolean8_t *mi, *mo;
4193
4152
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4348,6 +4307,10 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4348
4307
  positions align between iterators. */
4349
4308
  int8_t slab_axes[CA_RANK_MAX];
4350
4309
  slab_axes[0] = (int8_t) axis;
4310
+ ca_size_t fiber_n = ca->dim[axis];
4311
+ volatile VALUE hbuf = 0, haux = 0;
4312
+ partition_index_pair_u16 *buf = ALLOCV_N(partition_index_pair_u16, hbuf, fiber_n);
4313
+ (void) haux;
4351
4314
  ca_iter_state st_in, st_out;
4352
4315
  int rc;
4353
4316
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4362,11 +4325,6 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4362
4325
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4363
4326
  }
4364
4327
 
4365
- ca_size_t fiber_n = st_in.slab_elements;
4366
- volatile VALUE hbuf = 0, haux = 0;
4367
- partition_index_pair_u16 *buf = ALLOCV_N(partition_index_pair_u16, hbuf, fiber_n);
4368
- (void) haux;
4369
-
4370
4328
  char *pi, *po;
4371
4329
  boolean8_t *mi, *mo;
4372
4330
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4527,6 +4485,10 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4527
4485
  positions align between iterators. */
4528
4486
  int8_t slab_axes[CA_RANK_MAX];
4529
4487
  slab_axes[0] = (int8_t) axis;
4488
+ ca_size_t fiber_n = ca->dim[axis];
4489
+ volatile VALUE hbuf = 0, haux = 0;
4490
+ partition_index_pair_i32 *buf = ALLOCV_N(partition_index_pair_i32, hbuf, fiber_n);
4491
+ (void) haux;
4530
4492
  ca_iter_state st_in, st_out;
4531
4493
  int rc;
4532
4494
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4541,11 +4503,6 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4541
4503
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4542
4504
  }
4543
4505
 
4544
- ca_size_t fiber_n = st_in.slab_elements;
4545
- volatile VALUE hbuf = 0, haux = 0;
4546
- partition_index_pair_i32 *buf = ALLOCV_N(partition_index_pair_i32, hbuf, fiber_n);
4547
- (void) haux;
4548
-
4549
4506
  char *pi, *po;
4550
4507
  boolean8_t *mi, *mo;
4551
4508
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4706,6 +4663,10 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4706
4663
  positions align between iterators. */
4707
4664
  int8_t slab_axes[CA_RANK_MAX];
4708
4665
  slab_axes[0] = (int8_t) axis;
4666
+ ca_size_t fiber_n = ca->dim[axis];
4667
+ volatile VALUE hbuf = 0, haux = 0;
4668
+ partition_index_pair_u32 *buf = ALLOCV_N(partition_index_pair_u32, hbuf, fiber_n);
4669
+ (void) haux;
4709
4670
  ca_iter_state st_in, st_out;
4710
4671
  int rc;
4711
4672
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4720,11 +4681,6 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4720
4681
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4721
4682
  }
4722
4683
 
4723
- ca_size_t fiber_n = st_in.slab_elements;
4724
- volatile VALUE hbuf = 0, haux = 0;
4725
- partition_index_pair_u32 *buf = ALLOCV_N(partition_index_pair_u32, hbuf, fiber_n);
4726
- (void) haux;
4727
-
4728
4684
  char *pi, *po;
4729
4685
  boolean8_t *mi, *mo;
4730
4686
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4885,6 +4841,10 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4885
4841
  positions align between iterators. */
4886
4842
  int8_t slab_axes[CA_RANK_MAX];
4887
4843
  slab_axes[0] = (int8_t) axis;
4844
+ ca_size_t fiber_n = ca->dim[axis];
4845
+ volatile VALUE hbuf = 0, haux = 0;
4846
+ partition_index_pair_i64 *buf = ALLOCV_N(partition_index_pair_i64, hbuf, fiber_n);
4847
+ (void) haux;
4888
4848
  ca_iter_state st_in, st_out;
4889
4849
  int rc;
4890
4850
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4899,11 +4859,6 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4899
4859
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4900
4860
  }
4901
4861
 
4902
- ca_size_t fiber_n = st_in.slab_elements;
4903
- volatile VALUE hbuf = 0, haux = 0;
4904
- partition_index_pair_i64 *buf = ALLOCV_N(partition_index_pair_i64, hbuf, fiber_n);
4905
- (void) haux;
4906
-
4907
4862
  char *pi, *po;
4908
4863
  boolean8_t *mi, *mo;
4909
4864
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5064,6 +5019,10 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5064
5019
  positions align between iterators. */
5065
5020
  int8_t slab_axes[CA_RANK_MAX];
5066
5021
  slab_axes[0] = (int8_t) axis;
5022
+ ca_size_t fiber_n = ca->dim[axis];
5023
+ volatile VALUE hbuf = 0, haux = 0;
5024
+ partition_index_pair_u64 *buf = ALLOCV_N(partition_index_pair_u64, hbuf, fiber_n);
5025
+ (void) haux;
5067
5026
  ca_iter_state st_in, st_out;
5068
5027
  int rc;
5069
5028
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5078,11 +5037,6 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5078
5037
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5079
5038
  }
5080
5039
 
5081
- ca_size_t fiber_n = st_in.slab_elements;
5082
- volatile VALUE hbuf = 0, haux = 0;
5083
- partition_index_pair_u64 *buf = ALLOCV_N(partition_index_pair_u64, hbuf, fiber_n);
5084
- (void) haux;
5085
-
5086
5040
  char *pi, *po;
5087
5041
  boolean8_t *mi, *mo;
5088
5042
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5243,6 +5197,10 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5243
5197
  positions align between iterators. */
5244
5198
  int8_t slab_axes[CA_RANK_MAX];
5245
5199
  slab_axes[0] = (int8_t) axis;
5200
+ ca_size_t fiber_n = ca->dim[axis];
5201
+ volatile VALUE hbuf = 0, haux = 0;
5202
+ partition_index_pair_f32 *buf = ALLOCV_N(partition_index_pair_f32, hbuf, fiber_n);
5203
+ (void) haux;
5246
5204
  ca_iter_state st_in, st_out;
5247
5205
  int rc;
5248
5206
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5257,11 +5215,6 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5257
5215
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5258
5216
  }
5259
5217
 
5260
- ca_size_t fiber_n = st_in.slab_elements;
5261
- volatile VALUE hbuf = 0, haux = 0;
5262
- partition_index_pair_f32 *buf = ALLOCV_N(partition_index_pair_f32, hbuf, fiber_n);
5263
- (void) haux;
5264
-
5265
5218
  char *pi, *po;
5266
5219
  boolean8_t *mi, *mo;
5267
5220
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5422,6 +5375,10 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5422
5375
  positions align between iterators. */
5423
5376
  int8_t slab_axes[CA_RANK_MAX];
5424
5377
  slab_axes[0] = (int8_t) axis;
5378
+ ca_size_t fiber_n = ca->dim[axis];
5379
+ volatile VALUE hbuf = 0, haux = 0;
5380
+ partition_index_pair_f64 *buf = ALLOCV_N(partition_index_pair_f64, hbuf, fiber_n);
5381
+ (void) haux;
5425
5382
  ca_iter_state st_in, st_out;
5426
5383
  int rc;
5427
5384
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5436,11 +5393,6 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5436
5393
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5437
5394
  }
5438
5395
 
5439
- ca_size_t fiber_n = st_in.slab_elements;
5440
- volatile VALUE hbuf = 0, haux = 0;
5441
- partition_index_pair_f64 *buf = ALLOCV_N(partition_index_pair_f64, hbuf, fiber_n);
5442
- (void) haux;
5443
-
5444
5396
  char *pi, *po;
5445
5397
  boolean8_t *mi, *mo;
5446
5398
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5601,6 +5553,10 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5601
5553
  positions align between iterators. */
5602
5554
  int8_t slab_axes[CA_RANK_MAX];
5603
5555
  slab_axes[0] = (int8_t) axis;
5556
+ ca_size_t fiber_n = ca->dim[axis];
5557
+ volatile VALUE hbuf = 0, haux = 0;
5558
+ partition_index_pair_bool *buf = ALLOCV_N(partition_index_pair_bool, hbuf, fiber_n);
5559
+ (void) haux;
5604
5560
  ca_iter_state st_in, st_out;
5605
5561
  int rc;
5606
5562
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5615,11 +5571,6 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5615
5571
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5616
5572
  }
5617
5573
 
5618
- ca_size_t fiber_n = st_in.slab_elements;
5619
- volatile VALUE hbuf = 0, haux = 0;
5620
- partition_index_pair_bool *buf = ALLOCV_N(partition_index_pair_bool, hbuf, fiber_n);
5621
- (void) haux;
5622
-
5623
5574
  char *pi, *po;
5624
5575
  boolean8_t *mi, *mo;
5625
5576
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5767,9 +5718,9 @@ partition_index_quickselect_object (partition_index_pair_object *arr,
5767
5718
  }
5768
5719
  }
5769
5720
 
5770
- /* The object lane calls Ruby for every cell, so a walk can raise part
5771
- way. Its states live in the caller's frame, and ca_iter_ensure
5772
- finishes them however the body leaves. */
5721
+ /* The walks can raise part way (a Ruby call per cell in the object
5722
+ lane, an allocation in any lane). Their states live in the caller's
5723
+ frame, and ca_iter_ensure finishes them however the body leaves. */
5773
5724
  typedef struct {
5774
5725
  ca_iter_state states[2];
5775
5726
  VALUE self;
@@ -5805,6 +5756,10 @@ partition_index_ki_native_object_body (VALUE arg)
5805
5756
  positions align between iterators. */
5806
5757
  int8_t slab_axes[CA_RANK_MAX];
5807
5758
  slab_axes[0] = (int8_t) axis;
5759
+ ca_size_t fiber_n = ca->dim[axis];
5760
+ volatile VALUE hbuf = 0, haux = 0;
5761
+ partition_index_pair_object *buf = ALLOCV_N(partition_index_pair_object, hbuf, fiber_n);
5762
+ (void) haux;
5808
5763
  int rc;
5809
5764
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
5810
5765
  slab_axes, 1, 0);
@@ -5818,11 +5773,6 @@ partition_index_ki_native_object_body (VALUE arg)
5818
5773
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5819
5774
  }
5820
5775
 
5821
- ca_size_t fiber_n = st_in.slab_elements;
5822
- volatile VALUE hbuf = 0, haux = 0;
5823
- partition_index_pair_object *buf = ALLOCV_N(partition_index_pair_object, hbuf, fiber_n);
5824
- (void) haux;
5825
-
5826
5776
  char *pi, *po;
5827
5777
  boolean8_t *mi, *mo;
5828
5778
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5908,7 +5858,7 @@ partition_index_ki_native_object (VALUE self, CArray *ca, int axis, ca_size_t kt
5908
5858
  fr.axis = axis;
5909
5859
  fr.kth = kth;
5910
5860
  fr.masked_last = masked_last;
5911
- return ca_iter_ensure(2, fr.states, partition_index_ki_native_object_body, (VALUE) &fr);
5861
+ return ca_iter_ensure_computing(ca, 2, fr.states, partition_index_ki_native_object_body, (VALUE) &fr);
5912
5862
  }
5913
5863
 
5914
5864
 
@@ -5999,6 +5949,10 @@ partition_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kt
5999
5949
  positions align between iterators. */
6000
5950
  int8_t slab_axes[CA_RANK_MAX];
6001
5951
  slab_axes[0] = (int8_t) axis;
5952
+ ca_size_t fiber_n = ca->dim[axis];
5953
+ volatile VALUE hbuf = 0, haux = 0;
5954
+ partition_index_pair_fixlen *buf = ALLOCV_N(partition_index_pair_fixlen, hbuf, fiber_n);
5955
+ (void) haux;
6002
5956
  ca_iter_state st_in, st_out;
6003
5957
  int rc;
6004
5958
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6013,11 +5967,6 @@ partition_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kt
6013
5967
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6014
5968
  }
6015
5969
 
6016
- ca_size_t fiber_n = st_in.slab_elements;
6017
- volatile VALUE hbuf = 0, haux = 0;
6018
- partition_index_pair_fixlen *buf = ALLOCV_N(partition_index_pair_fixlen, hbuf, fiber_n);
6019
- (void) haux;
6020
-
6021
5970
  char *pi, *po;
6022
5971
  boolean8_t *mi, *mo;
6023
5972
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -6254,6 +6203,10 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6254
6203
  positions align between iterators. */
6255
6204
  int8_t slab_axes[CA_RANK_MAX];
6256
6205
  slab_axes[0] = (int8_t) axis;
6206
+ ca_size_t fiber_n = ca->dim[axis];
6207
+ volatile VALUE hbuf = 0, haux = 0;
6208
+ partition_addr_pair_i8 *buf = ALLOCV_N(partition_addr_pair_i8, hbuf, fiber_n);
6209
+ (void) haux;
6257
6210
  ca_iter_state st_in, st_out;
6258
6211
  int rc;
6259
6212
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6268,11 +6221,6 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6268
6221
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6269
6222
  }
6270
6223
 
6271
- ca_size_t fiber_n = st_in.slab_elements;
6272
- volatile VALUE hbuf = 0, haux = 0;
6273
- partition_addr_pair_i8 *buf = ALLOCV_N(partition_addr_pair_i8, hbuf, fiber_n);
6274
- (void) haux;
6275
-
6276
6224
  /* :view_flat semantics: kernel computes view-flat address
6277
6225
  (= row-major position in ca's shape, 0..elements-1) for
6278
6226
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6465,6 +6413,10 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6465
6413
  positions align between iterators. */
6466
6414
  int8_t slab_axes[CA_RANK_MAX];
6467
6415
  slab_axes[0] = (int8_t) axis;
6416
+ ca_size_t fiber_n = ca->dim[axis];
6417
+ volatile VALUE hbuf = 0, haux = 0;
6418
+ partition_addr_pair_u8 *buf = ALLOCV_N(partition_addr_pair_u8, hbuf, fiber_n);
6419
+ (void) haux;
6468
6420
  ca_iter_state st_in, st_out;
6469
6421
  int rc;
6470
6422
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6479,11 +6431,6 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6479
6431
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6480
6432
  }
6481
6433
 
6482
- ca_size_t fiber_n = st_in.slab_elements;
6483
- volatile VALUE hbuf = 0, haux = 0;
6484
- partition_addr_pair_u8 *buf = ALLOCV_N(partition_addr_pair_u8, hbuf, fiber_n);
6485
- (void) haux;
6486
-
6487
6434
  /* :view_flat semantics: kernel computes view-flat address
6488
6435
  (= row-major position in ca's shape, 0..elements-1) for
6489
6436
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6676,6 +6623,10 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6676
6623
  positions align between iterators. */
6677
6624
  int8_t slab_axes[CA_RANK_MAX];
6678
6625
  slab_axes[0] = (int8_t) axis;
6626
+ ca_size_t fiber_n = ca->dim[axis];
6627
+ volatile VALUE hbuf = 0, haux = 0;
6628
+ partition_addr_pair_i16 *buf = ALLOCV_N(partition_addr_pair_i16, hbuf, fiber_n);
6629
+ (void) haux;
6679
6630
  ca_iter_state st_in, st_out;
6680
6631
  int rc;
6681
6632
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6690,11 +6641,6 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6690
6641
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6691
6642
  }
6692
6643
 
6693
- ca_size_t fiber_n = st_in.slab_elements;
6694
- volatile VALUE hbuf = 0, haux = 0;
6695
- partition_addr_pair_i16 *buf = ALLOCV_N(partition_addr_pair_i16, hbuf, fiber_n);
6696
- (void) haux;
6697
-
6698
6644
  /* :view_flat semantics: kernel computes view-flat address
6699
6645
  (= row-major position in ca's shape, 0..elements-1) for
6700
6646
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6887,6 +6833,10 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6887
6833
  positions align between iterators. */
6888
6834
  int8_t slab_axes[CA_RANK_MAX];
6889
6835
  slab_axes[0] = (int8_t) axis;
6836
+ ca_size_t fiber_n = ca->dim[axis];
6837
+ volatile VALUE hbuf = 0, haux = 0;
6838
+ partition_addr_pair_u16 *buf = ALLOCV_N(partition_addr_pair_u16, hbuf, fiber_n);
6839
+ (void) haux;
6890
6840
  ca_iter_state st_in, st_out;
6891
6841
  int rc;
6892
6842
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6901,11 +6851,6 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6901
6851
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6902
6852
  }
6903
6853
 
6904
- ca_size_t fiber_n = st_in.slab_elements;
6905
- volatile VALUE hbuf = 0, haux = 0;
6906
- partition_addr_pair_u16 *buf = ALLOCV_N(partition_addr_pair_u16, hbuf, fiber_n);
6907
- (void) haux;
6908
-
6909
6854
  /* :view_flat semantics: kernel computes view-flat address
6910
6855
  (= row-major position in ca's shape, 0..elements-1) for
6911
6856
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7098,6 +7043,10 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7098
7043
  positions align between iterators. */
7099
7044
  int8_t slab_axes[CA_RANK_MAX];
7100
7045
  slab_axes[0] = (int8_t) axis;
7046
+ ca_size_t fiber_n = ca->dim[axis];
7047
+ volatile VALUE hbuf = 0, haux = 0;
7048
+ partition_addr_pair_i32 *buf = ALLOCV_N(partition_addr_pair_i32, hbuf, fiber_n);
7049
+ (void) haux;
7101
7050
  ca_iter_state st_in, st_out;
7102
7051
  int rc;
7103
7052
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7112,11 +7061,6 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7112
7061
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7113
7062
  }
7114
7063
 
7115
- ca_size_t fiber_n = st_in.slab_elements;
7116
- volatile VALUE hbuf = 0, haux = 0;
7117
- partition_addr_pair_i32 *buf = ALLOCV_N(partition_addr_pair_i32, hbuf, fiber_n);
7118
- (void) haux;
7119
-
7120
7064
  /* :view_flat semantics: kernel computes view-flat address
7121
7065
  (= row-major position in ca's shape, 0..elements-1) for
7122
7066
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7309,6 +7253,10 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7309
7253
  positions align between iterators. */
7310
7254
  int8_t slab_axes[CA_RANK_MAX];
7311
7255
  slab_axes[0] = (int8_t) axis;
7256
+ ca_size_t fiber_n = ca->dim[axis];
7257
+ volatile VALUE hbuf = 0, haux = 0;
7258
+ partition_addr_pair_u32 *buf = ALLOCV_N(partition_addr_pair_u32, hbuf, fiber_n);
7259
+ (void) haux;
7312
7260
  ca_iter_state st_in, st_out;
7313
7261
  int rc;
7314
7262
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7323,11 +7271,6 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7323
7271
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7324
7272
  }
7325
7273
 
7326
- ca_size_t fiber_n = st_in.slab_elements;
7327
- volatile VALUE hbuf = 0, haux = 0;
7328
- partition_addr_pair_u32 *buf = ALLOCV_N(partition_addr_pair_u32, hbuf, fiber_n);
7329
- (void) haux;
7330
-
7331
7274
  /* :view_flat semantics: kernel computes view-flat address
7332
7275
  (= row-major position in ca's shape, 0..elements-1) for
7333
7276
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7520,6 +7463,10 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7520
7463
  positions align between iterators. */
7521
7464
  int8_t slab_axes[CA_RANK_MAX];
7522
7465
  slab_axes[0] = (int8_t) axis;
7466
+ ca_size_t fiber_n = ca->dim[axis];
7467
+ volatile VALUE hbuf = 0, haux = 0;
7468
+ partition_addr_pair_i64 *buf = ALLOCV_N(partition_addr_pair_i64, hbuf, fiber_n);
7469
+ (void) haux;
7523
7470
  ca_iter_state st_in, st_out;
7524
7471
  int rc;
7525
7472
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7534,11 +7481,6 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7534
7481
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7535
7482
  }
7536
7483
 
7537
- ca_size_t fiber_n = st_in.slab_elements;
7538
- volatile VALUE hbuf = 0, haux = 0;
7539
- partition_addr_pair_i64 *buf = ALLOCV_N(partition_addr_pair_i64, hbuf, fiber_n);
7540
- (void) haux;
7541
-
7542
7484
  /* :view_flat semantics: kernel computes view-flat address
7543
7485
  (= row-major position in ca's shape, 0..elements-1) for
7544
7486
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7731,6 +7673,10 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7731
7673
  positions align between iterators. */
7732
7674
  int8_t slab_axes[CA_RANK_MAX];
7733
7675
  slab_axes[0] = (int8_t) axis;
7676
+ ca_size_t fiber_n = ca->dim[axis];
7677
+ volatile VALUE hbuf = 0, haux = 0;
7678
+ partition_addr_pair_u64 *buf = ALLOCV_N(partition_addr_pair_u64, hbuf, fiber_n);
7679
+ (void) haux;
7734
7680
  ca_iter_state st_in, st_out;
7735
7681
  int rc;
7736
7682
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7745,11 +7691,6 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7745
7691
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7746
7692
  }
7747
7693
 
7748
- ca_size_t fiber_n = st_in.slab_elements;
7749
- volatile VALUE hbuf = 0, haux = 0;
7750
- partition_addr_pair_u64 *buf = ALLOCV_N(partition_addr_pair_u64, hbuf, fiber_n);
7751
- (void) haux;
7752
-
7753
7694
  /* :view_flat semantics: kernel computes view-flat address
7754
7695
  (= row-major position in ca's shape, 0..elements-1) for
7755
7696
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7942,6 +7883,10 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7942
7883
  positions align between iterators. */
7943
7884
  int8_t slab_axes[CA_RANK_MAX];
7944
7885
  slab_axes[0] = (int8_t) axis;
7886
+ ca_size_t fiber_n = ca->dim[axis];
7887
+ volatile VALUE hbuf = 0, haux = 0;
7888
+ partition_addr_pair_f32 *buf = ALLOCV_N(partition_addr_pair_f32, hbuf, fiber_n);
7889
+ (void) haux;
7945
7890
  ca_iter_state st_in, st_out;
7946
7891
  int rc;
7947
7892
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7956,11 +7901,6 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7956
7901
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7957
7902
  }
7958
7903
 
7959
- ca_size_t fiber_n = st_in.slab_elements;
7960
- volatile VALUE hbuf = 0, haux = 0;
7961
- partition_addr_pair_f32 *buf = ALLOCV_N(partition_addr_pair_f32, hbuf, fiber_n);
7962
- (void) haux;
7963
-
7964
7904
  /* :view_flat semantics: kernel computes view-flat address
7965
7905
  (= row-major position in ca's shape, 0..elements-1) for
7966
7906
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8153,6 +8093,10 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8153
8093
  positions align between iterators. */
8154
8094
  int8_t slab_axes[CA_RANK_MAX];
8155
8095
  slab_axes[0] = (int8_t) axis;
8096
+ ca_size_t fiber_n = ca->dim[axis];
8097
+ volatile VALUE hbuf = 0, haux = 0;
8098
+ partition_addr_pair_f64 *buf = ALLOCV_N(partition_addr_pair_f64, hbuf, fiber_n);
8099
+ (void) haux;
8156
8100
  ca_iter_state st_in, st_out;
8157
8101
  int rc;
8158
8102
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8167,11 +8111,6 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8167
8111
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8168
8112
  }
8169
8113
 
8170
- ca_size_t fiber_n = st_in.slab_elements;
8171
- volatile VALUE hbuf = 0, haux = 0;
8172
- partition_addr_pair_f64 *buf = ALLOCV_N(partition_addr_pair_f64, hbuf, fiber_n);
8173
- (void) haux;
8174
-
8175
8114
  /* :view_flat semantics: kernel computes view-flat address
8176
8115
  (= row-major position in ca's shape, 0..elements-1) for
8177
8116
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8364,6 +8303,10 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8364
8303
  positions align between iterators. */
8365
8304
  int8_t slab_axes[CA_RANK_MAX];
8366
8305
  slab_axes[0] = (int8_t) axis;
8306
+ ca_size_t fiber_n = ca->dim[axis];
8307
+ volatile VALUE hbuf = 0, haux = 0;
8308
+ partition_addr_pair_bool *buf = ALLOCV_N(partition_addr_pair_bool, hbuf, fiber_n);
8309
+ (void) haux;
8367
8310
  ca_iter_state st_in, st_out;
8368
8311
  int rc;
8369
8312
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8378,11 +8321,6 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8378
8321
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8379
8322
  }
8380
8323
 
8381
- ca_size_t fiber_n = st_in.slab_elements;
8382
- volatile VALUE hbuf = 0, haux = 0;
8383
- partition_addr_pair_bool *buf = ALLOCV_N(partition_addr_pair_bool, hbuf, fiber_n);
8384
- (void) haux;
8385
-
8386
8324
  /* :view_flat semantics: kernel computes view-flat address
8387
8325
  (= row-major position in ca's shape, 0..elements-1) for
8388
8326
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8562,9 +8500,9 @@ partition_addr_quickselect_object (partition_addr_pair_object *arr,
8562
8500
  }
8563
8501
  }
8564
8502
 
8565
- /* The object lane calls Ruby for every cell, so a walk can raise part
8566
- way. Its states live in the caller's frame, and ca_iter_ensure
8567
- finishes them however the body leaves. */
8503
+ /* The walks can raise part way (a Ruby call per cell in the object
8504
+ lane, an allocation in any lane). Their states live in the caller's
8505
+ frame, and ca_iter_ensure finishes them however the body leaves. */
8568
8506
  typedef struct {
8569
8507
  ca_iter_state states[2];
8570
8508
  VALUE self;
@@ -8600,6 +8538,10 @@ partition_addr_ki_native_object_body (VALUE arg)
8600
8538
  positions align between iterators. */
8601
8539
  int8_t slab_axes[CA_RANK_MAX];
8602
8540
  slab_axes[0] = (int8_t) axis;
8541
+ ca_size_t fiber_n = ca->dim[axis];
8542
+ volatile VALUE hbuf = 0, haux = 0;
8543
+ partition_addr_pair_object *buf = ALLOCV_N(partition_addr_pair_object, hbuf, fiber_n);
8544
+ (void) haux;
8603
8545
  int rc;
8604
8546
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
8605
8547
  slab_axes, 1, 0);
@@ -8613,11 +8555,6 @@ partition_addr_ki_native_object_body (VALUE arg)
8613
8555
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8614
8556
  }
8615
8557
 
8616
- ca_size_t fiber_n = st_in.slab_elements;
8617
- volatile VALUE hbuf = 0, haux = 0;
8618
- partition_addr_pair_object *buf = ALLOCV_N(partition_addr_pair_object, hbuf, fiber_n);
8619
- (void) haux;
8620
-
8621
8558
  /* :view_flat semantics: kernel computes view-flat address
8622
8559
  (= row-major position in ca's shape, 0..elements-1) for
8623
8560
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8735,7 +8672,7 @@ partition_addr_ki_native_object (VALUE self, CArray *ca, int axis, ca_size_t kth
8735
8672
  fr.axis = axis;
8736
8673
  fr.kth = kth;
8737
8674
  fr.masked_last = masked_last;
8738
- return ca_iter_ensure(2, fr.states, partition_addr_ki_native_object_body, (VALUE) &fr);
8675
+ return ca_iter_ensure_computing(ca, 2, fr.states, partition_addr_ki_native_object_body, (VALUE) &fr);
8739
8676
  }
8740
8677
 
8741
8678
 
@@ -8826,6 +8763,10 @@ partition_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kth
8826
8763
  positions align between iterators. */
8827
8764
  int8_t slab_axes[CA_RANK_MAX];
8828
8765
  slab_axes[0] = (int8_t) axis;
8766
+ ca_size_t fiber_n = ca->dim[axis];
8767
+ volatile VALUE hbuf = 0, haux = 0;
8768
+ partition_addr_pair_fixlen *buf = ALLOCV_N(partition_addr_pair_fixlen, hbuf, fiber_n);
8769
+ (void) haux;
8829
8770
  ca_iter_state st_in, st_out;
8830
8771
  int rc;
8831
8772
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8840,11 +8781,6 @@ partition_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kth
8840
8781
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8841
8782
  }
8842
8783
 
8843
- ca_size_t fiber_n = st_in.slab_elements;
8844
- volatile VALUE hbuf = 0, haux = 0;
8845
- partition_addr_pair_fixlen *buf = ALLOCV_N(partition_addr_pair_fixlen, hbuf, fiber_n);
8846
- (void) haux;
8847
-
8848
8784
  /* :view_flat semantics: kernel computes view-flat address
8849
8785
  (= row-major position in ca's shape, 0..elements-1) for
8850
8786
  each cell. Used to feed CARemap.idx directly (= sort
@@ -9028,6 +8964,13 @@ rank_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9028
8964
  next_slab_axes will then be non-NULL). Created up-front
9029
8965
  when input has any mask. */
9030
8966
  if ( ca_has_mask(ca) ) ca_create_mask(co);
8967
+ ca_size_t fiber_n = ca->dim[axis];
8968
+ volatile VALUE hbuf = 0, haux = 0;
8969
+ rank_index_pair_i8 *buf = ALLOCV_N(rank_index_pair_i8, hbuf, fiber_n);
8970
+ rank_index_pair_i8 *aux = NULL;
8971
+ if ( do_stable ) {
8972
+ aux = ALLOCV_N(rank_index_pair_i8, haux, fiber_n);
8973
+ }
9031
8974
  ca_iter_state st_in, st_out;
9032
8975
  int rc;
9033
8976
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9042,14 +8985,6 @@ rank_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9042
8985
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9043
8986
  }
9044
8987
 
9045
- ca_size_t fiber_n = st_in.slab_elements;
9046
- volatile VALUE hbuf = 0, haux = 0;
9047
- rank_index_pair_i8 *buf = ALLOCV_N(rank_index_pair_i8, hbuf, fiber_n);
9048
- rank_index_pair_i8 *aux = NULL;
9049
- if ( do_stable ) {
9050
- aux = ALLOCV_N(rank_index_pair_i8, haux, fiber_n);
9051
- }
9052
-
9053
8988
  char *pi, *po;
9054
8989
  boolean8_t *mi, *mo;
9055
8990
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9159,6 +9094,13 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9159
9094
  next_slab_axes will then be non-NULL). Created up-front
9160
9095
  when input has any mask. */
9161
9096
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9097
+ ca_size_t fiber_n = ca->dim[axis];
9098
+ volatile VALUE hbuf = 0, haux = 0;
9099
+ rank_index_pair_u8 *buf = ALLOCV_N(rank_index_pair_u8, hbuf, fiber_n);
9100
+ rank_index_pair_u8 *aux = NULL;
9101
+ if ( do_stable ) {
9102
+ aux = ALLOCV_N(rank_index_pair_u8, haux, fiber_n);
9103
+ }
9162
9104
  ca_iter_state st_in, st_out;
9163
9105
  int rc;
9164
9106
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9173,14 +9115,6 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9173
9115
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9174
9116
  }
9175
9117
 
9176
- ca_size_t fiber_n = st_in.slab_elements;
9177
- volatile VALUE hbuf = 0, haux = 0;
9178
- rank_index_pair_u8 *buf = ALLOCV_N(rank_index_pair_u8, hbuf, fiber_n);
9179
- rank_index_pair_u8 *aux = NULL;
9180
- if ( do_stable ) {
9181
- aux = ALLOCV_N(rank_index_pair_u8, haux, fiber_n);
9182
- }
9183
-
9184
9118
  char *pi, *po;
9185
9119
  boolean8_t *mi, *mo;
9186
9120
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9290,6 +9224,13 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9290
9224
  next_slab_axes will then be non-NULL). Created up-front
9291
9225
  when input has any mask. */
9292
9226
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9227
+ ca_size_t fiber_n = ca->dim[axis];
9228
+ volatile VALUE hbuf = 0, haux = 0;
9229
+ rank_index_pair_i16 *buf = ALLOCV_N(rank_index_pair_i16, hbuf, fiber_n);
9230
+ rank_index_pair_i16 *aux = NULL;
9231
+ if ( do_stable ) {
9232
+ aux = ALLOCV_N(rank_index_pair_i16, haux, fiber_n);
9233
+ }
9293
9234
  ca_iter_state st_in, st_out;
9294
9235
  int rc;
9295
9236
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9304,14 +9245,6 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9304
9245
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9305
9246
  }
9306
9247
 
9307
- ca_size_t fiber_n = st_in.slab_elements;
9308
- volatile VALUE hbuf = 0, haux = 0;
9309
- rank_index_pair_i16 *buf = ALLOCV_N(rank_index_pair_i16, hbuf, fiber_n);
9310
- rank_index_pair_i16 *aux = NULL;
9311
- if ( do_stable ) {
9312
- aux = ALLOCV_N(rank_index_pair_i16, haux, fiber_n);
9313
- }
9314
-
9315
9248
  char *pi, *po;
9316
9249
  boolean8_t *mi, *mo;
9317
9250
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9421,6 +9354,13 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9421
9354
  next_slab_axes will then be non-NULL). Created up-front
9422
9355
  when input has any mask. */
9423
9356
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9357
+ ca_size_t fiber_n = ca->dim[axis];
9358
+ volatile VALUE hbuf = 0, haux = 0;
9359
+ rank_index_pair_u16 *buf = ALLOCV_N(rank_index_pair_u16, hbuf, fiber_n);
9360
+ rank_index_pair_u16 *aux = NULL;
9361
+ if ( do_stable ) {
9362
+ aux = ALLOCV_N(rank_index_pair_u16, haux, fiber_n);
9363
+ }
9424
9364
  ca_iter_state st_in, st_out;
9425
9365
  int rc;
9426
9366
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9435,14 +9375,6 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9435
9375
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9436
9376
  }
9437
9377
 
9438
- ca_size_t fiber_n = st_in.slab_elements;
9439
- volatile VALUE hbuf = 0, haux = 0;
9440
- rank_index_pair_u16 *buf = ALLOCV_N(rank_index_pair_u16, hbuf, fiber_n);
9441
- rank_index_pair_u16 *aux = NULL;
9442
- if ( do_stable ) {
9443
- aux = ALLOCV_N(rank_index_pair_u16, haux, fiber_n);
9444
- }
9445
-
9446
9378
  char *pi, *po;
9447
9379
  boolean8_t *mi, *mo;
9448
9380
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9552,6 +9484,13 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9552
9484
  next_slab_axes will then be non-NULL). Created up-front
9553
9485
  when input has any mask. */
9554
9486
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9487
+ ca_size_t fiber_n = ca->dim[axis];
9488
+ volatile VALUE hbuf = 0, haux = 0;
9489
+ rank_index_pair_i32 *buf = ALLOCV_N(rank_index_pair_i32, hbuf, fiber_n);
9490
+ rank_index_pair_i32 *aux = NULL;
9491
+ if ( do_stable ) {
9492
+ aux = ALLOCV_N(rank_index_pair_i32, haux, fiber_n);
9493
+ }
9555
9494
  ca_iter_state st_in, st_out;
9556
9495
  int rc;
9557
9496
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9566,14 +9505,6 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9566
9505
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9567
9506
  }
9568
9507
 
9569
- ca_size_t fiber_n = st_in.slab_elements;
9570
- volatile VALUE hbuf = 0, haux = 0;
9571
- rank_index_pair_i32 *buf = ALLOCV_N(rank_index_pair_i32, hbuf, fiber_n);
9572
- rank_index_pair_i32 *aux = NULL;
9573
- if ( do_stable ) {
9574
- aux = ALLOCV_N(rank_index_pair_i32, haux, fiber_n);
9575
- }
9576
-
9577
9508
  char *pi, *po;
9578
9509
  boolean8_t *mi, *mo;
9579
9510
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9683,6 +9614,13 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9683
9614
  next_slab_axes will then be non-NULL). Created up-front
9684
9615
  when input has any mask. */
9685
9616
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9617
+ ca_size_t fiber_n = ca->dim[axis];
9618
+ volatile VALUE hbuf = 0, haux = 0;
9619
+ rank_index_pair_u32 *buf = ALLOCV_N(rank_index_pair_u32, hbuf, fiber_n);
9620
+ rank_index_pair_u32 *aux = NULL;
9621
+ if ( do_stable ) {
9622
+ aux = ALLOCV_N(rank_index_pair_u32, haux, fiber_n);
9623
+ }
9686
9624
  ca_iter_state st_in, st_out;
9687
9625
  int rc;
9688
9626
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9697,14 +9635,6 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9697
9635
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9698
9636
  }
9699
9637
 
9700
- ca_size_t fiber_n = st_in.slab_elements;
9701
- volatile VALUE hbuf = 0, haux = 0;
9702
- rank_index_pair_u32 *buf = ALLOCV_N(rank_index_pair_u32, hbuf, fiber_n);
9703
- rank_index_pair_u32 *aux = NULL;
9704
- if ( do_stable ) {
9705
- aux = ALLOCV_N(rank_index_pair_u32, haux, fiber_n);
9706
- }
9707
-
9708
9638
  char *pi, *po;
9709
9639
  boolean8_t *mi, *mo;
9710
9640
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9814,6 +9744,13 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9814
9744
  next_slab_axes will then be non-NULL). Created up-front
9815
9745
  when input has any mask. */
9816
9746
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9747
+ ca_size_t fiber_n = ca->dim[axis];
9748
+ volatile VALUE hbuf = 0, haux = 0;
9749
+ rank_index_pair_i64 *buf = ALLOCV_N(rank_index_pair_i64, hbuf, fiber_n);
9750
+ rank_index_pair_i64 *aux = NULL;
9751
+ if ( do_stable ) {
9752
+ aux = ALLOCV_N(rank_index_pair_i64, haux, fiber_n);
9753
+ }
9817
9754
  ca_iter_state st_in, st_out;
9818
9755
  int rc;
9819
9756
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9828,14 +9765,6 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9828
9765
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9829
9766
  }
9830
9767
 
9831
- ca_size_t fiber_n = st_in.slab_elements;
9832
- volatile VALUE hbuf = 0, haux = 0;
9833
- rank_index_pair_i64 *buf = ALLOCV_N(rank_index_pair_i64, hbuf, fiber_n);
9834
- rank_index_pair_i64 *aux = NULL;
9835
- if ( do_stable ) {
9836
- aux = ALLOCV_N(rank_index_pair_i64, haux, fiber_n);
9837
- }
9838
-
9839
9768
  char *pi, *po;
9840
9769
  boolean8_t *mi, *mo;
9841
9770
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9945,6 +9874,13 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9945
9874
  next_slab_axes will then be non-NULL). Created up-front
9946
9875
  when input has any mask. */
9947
9876
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9877
+ ca_size_t fiber_n = ca->dim[axis];
9878
+ volatile VALUE hbuf = 0, haux = 0;
9879
+ rank_index_pair_u64 *buf = ALLOCV_N(rank_index_pair_u64, hbuf, fiber_n);
9880
+ rank_index_pair_u64 *aux = NULL;
9881
+ if ( do_stable ) {
9882
+ aux = ALLOCV_N(rank_index_pair_u64, haux, fiber_n);
9883
+ }
9948
9884
  ca_iter_state st_in, st_out;
9949
9885
  int rc;
9950
9886
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9959,14 +9895,6 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9959
9895
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9960
9896
  }
9961
9897
 
9962
- ca_size_t fiber_n = st_in.slab_elements;
9963
- volatile VALUE hbuf = 0, haux = 0;
9964
- rank_index_pair_u64 *buf = ALLOCV_N(rank_index_pair_u64, hbuf, fiber_n);
9965
- rank_index_pair_u64 *aux = NULL;
9966
- if ( do_stable ) {
9967
- aux = ALLOCV_N(rank_index_pair_u64, haux, fiber_n);
9968
- }
9969
-
9970
9898
  char *pi, *po;
9971
9899
  boolean8_t *mi, *mo;
9972
9900
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10076,6 +10004,10 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10076
10004
  next_slab_axes will then be non-NULL). Created up-front
10077
10005
  when input has any mask. */
10078
10006
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10007
+ ca_size_t fiber_n = ca->dim[axis];
10008
+ volatile VALUE hbuf = 0, haux = 0;
10009
+ rank_index_pair_f32 *buf = ALLOCV_N(rank_index_pair_f32, hbuf, fiber_n);
10010
+ rank_index_pair_f32 *aux = ALLOCV_N(rank_index_pair_f32, haux, fiber_n);
10079
10011
  ca_iter_state st_in, st_out;
10080
10012
  int rc;
10081
10013
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10090,14 +10022,6 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10090
10022
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10091
10023
  }
10092
10024
 
10093
- ca_size_t fiber_n = st_in.slab_elements;
10094
- volatile VALUE hbuf = 0, haux = 0;
10095
- rank_index_pair_f32 *buf = ALLOCV_N(rank_index_pair_f32, hbuf, fiber_n);
10096
- rank_index_pair_f32 *aux = NULL;
10097
- if ( do_stable ) {
10098
- aux = ALLOCV_N(rank_index_pair_f32, haux, fiber_n);
10099
- }
10100
-
10101
10025
  char *pi, *po;
10102
10026
  boolean8_t *mi, *mo;
10103
10027
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10124,7 +10048,7 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10124
10048
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
10125
10049
  pushed to the tail (= NaN-at-end policy, matches sort_copy
10126
10050
  AC8). Only the finite slice is sorted. */
10127
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) buf, (ca_size_t) k_unmasked);
10051
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) buf, (ca_size_t) k_unmasked, (ca_pair_f32 *) aux);
10128
10052
  if ( do_stable ) {
10129
10053
  ca_sort_merge_pair_f32((ca_pair_f32 *) buf, (ca_pair_f32 *) aux, finite_n);
10130
10054
  } else {
@@ -10213,6 +10137,10 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10213
10137
  next_slab_axes will then be non-NULL). Created up-front
10214
10138
  when input has any mask. */
10215
10139
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10140
+ ca_size_t fiber_n = ca->dim[axis];
10141
+ volatile VALUE hbuf = 0, haux = 0;
10142
+ rank_index_pair_f64 *buf = ALLOCV_N(rank_index_pair_f64, hbuf, fiber_n);
10143
+ rank_index_pair_f64 *aux = ALLOCV_N(rank_index_pair_f64, haux, fiber_n);
10216
10144
  ca_iter_state st_in, st_out;
10217
10145
  int rc;
10218
10146
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10227,14 +10155,6 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10227
10155
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10228
10156
  }
10229
10157
 
10230
- ca_size_t fiber_n = st_in.slab_elements;
10231
- volatile VALUE hbuf = 0, haux = 0;
10232
- rank_index_pair_f64 *buf = ALLOCV_N(rank_index_pair_f64, hbuf, fiber_n);
10233
- rank_index_pair_f64 *aux = NULL;
10234
- if ( do_stable ) {
10235
- aux = ALLOCV_N(rank_index_pair_f64, haux, fiber_n);
10236
- }
10237
-
10238
10158
  char *pi, *po;
10239
10159
  boolean8_t *mi, *mo;
10240
10160
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10261,7 +10181,7 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10261
10181
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
10262
10182
  pushed to the tail (= NaN-at-end policy, matches sort_copy
10263
10183
  AC8). Only the finite slice is sorted. */
10264
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) buf, (ca_size_t) k_unmasked);
10184
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) buf, (ca_size_t) k_unmasked, (ca_pair_f64 *) aux);
10265
10185
  if ( do_stable ) {
10266
10186
  ca_sort_merge_pair_f64((ca_pair_f64 *) buf, (ca_pair_f64 *) aux, finite_n);
10267
10187
  } else {
@@ -10350,6 +10270,13 @@ rank_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
10350
10270
  next_slab_axes will then be non-NULL). Created up-front
10351
10271
  when input has any mask. */
10352
10272
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10273
+ ca_size_t fiber_n = ca->dim[axis];
10274
+ volatile VALUE hbuf = 0, haux = 0;
10275
+ rank_index_pair_bool *buf = ALLOCV_N(rank_index_pair_bool, hbuf, fiber_n);
10276
+ rank_index_pair_bool *aux = NULL;
10277
+ if ( do_stable ) {
10278
+ aux = ALLOCV_N(rank_index_pair_bool, haux, fiber_n);
10279
+ }
10353
10280
  ca_iter_state st_in, st_out;
10354
10281
  int rc;
10355
10282
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10364,14 +10291,6 @@ rank_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
10364
10291
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10365
10292
  }
10366
10293
 
10367
- ca_size_t fiber_n = st_in.slab_elements;
10368
- volatile VALUE hbuf = 0, haux = 0;
10369
- rank_index_pair_bool *buf = ALLOCV_N(rank_index_pair_bool, hbuf, fiber_n);
10370
- rank_index_pair_bool *aux = NULL;
10371
- if ( do_stable ) {
10372
- aux = ALLOCV_N(rank_index_pair_bool, haux, fiber_n);
10373
- }
10374
-
10375
10294
  char *pi, *po;
10376
10295
  boolean8_t *mi, *mo;
10377
10296
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10476,9 +10395,9 @@ rank_index_cmp_object (const void *a, const void *b)
10476
10395
  return 0;
10477
10396
  }
10478
10397
 
10479
- /* The object lane calls Ruby for every cell, so a walk can raise part
10480
- way. Its states live in the caller's frame, and ca_iter_ensure
10481
- finishes them however the body leaves. */
10398
+ /* The walks can raise part way (a Ruby call per cell in the object
10399
+ lane, an allocation in any lane). Their states live in the caller's
10400
+ frame, and ca_iter_ensure finishes them however the body leaves. */
10482
10401
  typedef struct {
10483
10402
  ca_iter_state states[2];
10484
10403
  VALUE self;
@@ -10519,6 +10438,10 @@ rank_index_ki_native_object_body (VALUE arg)
10519
10438
  next_slab_axes will then be non-NULL). Created up-front
10520
10439
  when input has any mask. */
10521
10440
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10441
+ ca_size_t fiber_n = ca->dim[axis];
10442
+ volatile VALUE hbuf = 0, haux = 0;
10443
+ rank_index_pair_object *buf = ALLOCV_N(rank_index_pair_object, hbuf, fiber_n);
10444
+ rank_index_pair_object *aux = ALLOCV_N(rank_index_pair_object, haux, fiber_n);
10522
10445
  int rc;
10523
10446
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
10524
10447
  slab_axes, 1, 0);
@@ -10532,11 +10455,6 @@ rank_index_ki_native_object_body (VALUE arg)
10532
10455
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10533
10456
  }
10534
10457
 
10535
- ca_size_t fiber_n = st_in.slab_elements;
10536
- volatile VALUE hbuf = 0, haux = 0;
10537
- rank_index_pair_object *buf = ALLOCV_N(rank_index_pair_object, hbuf, fiber_n);
10538
- rank_index_pair_object *aux = ALLOCV_N(rank_index_pair_object, haux, fiber_n);
10539
-
10540
10458
  char *pi, *po;
10541
10459
  boolean8_t *mi, *mo;
10542
10460
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10633,7 +10551,7 @@ rank_index_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, in
10633
10551
  fr.axis = axis;
10634
10552
  fr.do_stable = do_stable;
10635
10553
  fr.dense = dense;
10636
- return ca_iter_ensure(2, fr.states, rank_index_ki_native_object_body, (VALUE) &fr);
10554
+ return ca_iter_ensure_computing(ca, 2, fr.states, rank_index_ki_native_object_body, (VALUE) &fr);
10637
10555
  }
10638
10556
 
10639
10557
 
@@ -10674,6 +10592,10 @@ rank_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
10674
10592
  next_slab_axes will then be non-NULL). Created up-front
10675
10593
  when input has any mask. */
10676
10594
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10595
+ ca_size_t fiber_n = ca->dim[axis];
10596
+ volatile VALUE hbuf = 0, haux = 0;
10597
+ rank_index_pair_fixlen *buf = ALLOCV_N(rank_index_pair_fixlen, hbuf, fiber_n);
10598
+ (void) haux;
10677
10599
  ca_iter_state st_in, st_out;
10678
10600
  int rc;
10679
10601
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10688,11 +10610,6 @@ rank_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
10688
10610
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10689
10611
  }
10690
10612
 
10691
- ca_size_t fiber_n = st_in.slab_elements;
10692
- volatile VALUE hbuf = 0, haux = 0;
10693
- rank_index_pair_fixlen *buf = ALLOCV_N(rank_index_pair_fixlen, hbuf, fiber_n);
10694
- (void) haux;
10695
-
10696
10613
  char *pi, *po;
10697
10614
  boolean8_t *mi, *mo;
10698
10615
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&