carray 3.0.0 → 3.0.2

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +845 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +33 -33
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_dispatch.c +33 -4
  8. data/ext/ca_axis_group.c +256 -114
  9. data/ext/ca_binop_dispatch.c +5 -6
  10. data/ext/ca_binop_dispatch.h +0 -7
  11. data/ext/ca_categorical_iterator.c +121 -67
  12. data/ext/ca_for_each_element.h +6 -8
  13. data/ext/ca_group_iter.c +1 -1
  14. data/ext/ca_kernel_iterator.c +386 -74
  15. data/ext/ca_kernel_iterator.h +145 -45
  16. data/ext/ca_obj_array.c +62 -20
  17. data/ext/ca_obj_bincmp.c +57 -27
  18. data/ext/ca_obj_binop.c +86 -30
  19. data/ext/ca_obj_block.c +4 -4
  20. data/ext/ca_obj_const_string.c +88 -27
  21. data/ext/ca_obj_face.c +104 -0
  22. data/ext/ca_obj_face.h +48 -1
  23. data/ext/ca_obj_fake.c +11 -0
  24. data/ext/ca_obj_fixlen_string.c +21 -6
  25. data/ext/ca_obj_grid.c +11 -3
  26. data/ext/ca_obj_meld.c +125 -22
  27. data/ext/ca_obj_moncmp.c +33 -14
  28. data/ext/ca_obj_monop.c +19 -7
  29. data/ext/ca_obj_object.c +107 -4
  30. data/ext/ca_obj_record.c +3 -1
  31. data/ext/ca_obj_refer.c +30 -6
  32. data/ext/ca_obj_roll.c +13 -5
  33. data/ext/ca_obj_select.c +49 -34
  34. data/ext/ca_obj_select_axis.c +16 -6
  35. data/ext/ca_obj_shift.c +3 -3
  36. data/ext/ca_obj_stack.c +3 -8
  37. data/ext/ca_obj_stride.c +178 -24
  38. data/ext/ca_obj_string.c +11 -5
  39. data/ext/ca_obj_tile.c +13 -5
  40. data/ext/ca_obj_time.c +3 -1
  41. data/ext/ca_obj_timedelta.c +3 -1
  42. data/ext/ca_obj_transpose.c +1 -1
  43. data/ext/ca_obj_triop.c +62 -23
  44. data/ext/ca_obj_window.c +94 -19
  45. data/ext/ca_op_cmplx64.h +123 -0
  46. data/ext/ca_op_ipower.c +1 -5
  47. data/ext/ca_rng_normal.h +42 -0
  48. data/ext/ca_rng_xoshiro256pp.h +105 -0
  49. data/ext/ca_sort_kernels.h +5 -5
  50. data/ext/ca_sweep_engine.c +362 -155
  51. data/ext/ca_sweep_engine.h +39 -9
  52. data/ext/ca_transform_common.c +7 -0
  53. data/ext/carray.h +148 -132
  54. data/ext/carray_access.c +83 -49
  55. data/ext/carray_address_basis.c +590 -0
  56. data/ext/carray_bincount.c +8 -8
  57. data/ext/carray_broadcast.c +102 -9
  58. data/ext/carray_build_flags.h +3 -0
  59. data/ext/carray_call_cfunc.c +2010 -335
  60. data/ext/carray_call_cfunc.h +153 -0
  61. data/ext/carray_cast.c +184 -72
  62. data/ext/carray_conversion.c +22 -22
  63. data/ext/carray_copy.c +67 -32
  64. data/ext/carray_core.c +140 -13
  65. data/ext/carray_count.c +10 -11
  66. data/ext/carray_element.c +7 -7
  67. data/ext/carray_factorize.c +72 -51
  68. data/ext/carray_hold.c +1 -1
  69. data/ext/carray_index_classifier.c +7 -21
  70. data/ext/carray_internal.h +36 -3
  71. data/ext/carray_kernels_bincmp.c +1 -0
  72. data/ext/carray_kernels_binop.c +320 -298
  73. data/ext/carray_kernels_init.c +1095 -0
  74. data/ext/carray_kernels_map.c +1 -0
  75. data/ext/carray_kernels_moncmp.c +1 -0
  76. data/ext/carray_kernels_monop.c +412 -411
  77. data/ext/carray_kernels_reduce_aggregate.c +256 -87
  78. data/ext/carray_kernels_reduce_boolean.c +1 -0
  79. data/ext/carray_kernels_reduce_cumulative.c +324 -54
  80. data/ext/carray_kernels_reduce_extreme.c +605 -58
  81. data/ext/carray_kernels_reduce_variance.c +1 -0
  82. data/ext/carray_kernels_scan.c +5 -4
  83. data/ext/carray_kernels_search.c +187 -106
  84. data/ext/carray_kernels_sort.c +1 -0
  85. data/ext/carray_kernels_triop.c +1 -0
  86. data/ext/carray_lazy.c +175 -5
  87. data/ext/carray_loop.c +7 -1
  88. data/ext/carray_mask.c +29 -13
  89. data/ext/carray_median_percentile.c +56 -1
  90. data/ext/carray_memory_view.c +46 -21
  91. data/ext/carray_operator.c +50 -53
  92. data/ext/carray_order.c +1 -1
  93. data/ext/carray_partition.c +4 -4
  94. data/ext/carray_random.c +391 -47
  95. data/ext/carray_scatter.c +1 -1
  96. data/ext/carray_slab.c +13 -0
  97. data/ext/carray_sort.c +22 -24
  98. data/ext/carray_sort_kernel.c +10 -10
  99. data/ext/carray_test.c +1 -1
  100. data/ext/extconf.rb +18 -0
  101. data/ext/mk_call_cfunc.rb +323 -145
  102. data/ext/mkkernel.rb +651 -129
  103. data/ext/ruby_carray.c +28 -17
  104. data/ext/version.h +4 -4
  105. data/lib/carray/autoload_carray.rb +24 -3
  106. data/lib/carray/autoload_method_extension.rb +14 -1
  107. data/lib/carray/axis_group.rb +84 -7
  108. data/lib/carray/basics.rb +63 -59
  109. data/lib/carray/bincount_nd.rb +12 -12
  110. data/lib/carray/block_iterator.rb +111 -25
  111. data/lib/carray/categorical.rb +154 -37
  112. data/lib/carray/categorical_iterator.rb +300 -151
  113. data/lib/carray/conditional.rb +14 -14
  114. data/lib/carray/const_string.rb +131 -27
  115. data/lib/carray/construct.rb +61 -0
  116. data/lib/carray/core_extensions.rb +62 -5
  117. data/lib/carray/data_type_extension.rb +21 -1
  118. data/lib/carray/data_type_limits.rb +91 -0
  119. data/lib/carray/fixlen_string.rb +1 -1
  120. data/lib/carray/frame/concat.rb +3 -3
  121. data/lib/carray/frame/convert.rb +1 -1
  122. data/lib/carray/frame/csv_parser.rb +11 -4
  123. data/lib/carray/frame/frame.rb +85 -21
  124. data/lib/carray/frame/group.rb +36 -3
  125. data/lib/carray/frame/io.rb +224 -15
  126. data/lib/carray/frame/records.rb +18 -4
  127. data/lib/carray/frame/sort.rb +1 -1
  128. data/lib/carray/frame/verbs.rb +32 -12
  129. data/lib/carray/fuse_source.rb +123 -0
  130. data/lib/carray/fusion.rb +218 -0
  131. data/lib/carray/histogram.rb +16 -16
  132. data/lib/carray/inspect.rb +43 -16
  133. data/lib/carray/iterator.rb +147 -3
  134. data/lib/carray/lazy.rb +88 -73
  135. data/lib/carray/mask_gap_fill.rb +3 -1
  136. data/lib/carray/meld_reduce.rb +2 -2
  137. data/lib/carray/methods/align_addr.rb +1 -1
  138. data/lib/carray/methods/composition.rb +1 -1
  139. data/lib/carray/methods/discovery_along.rb +74 -0
  140. data/lib/carray/methods/factorize.rb +50 -0
  141. data/lib/carray/methods/is_in.rb +25 -14
  142. data/lib/carray/methods/locate_addr.rb +81 -3
  143. data/lib/carray/methods/mask_duplicates.rb +36 -2
  144. data/lib/carray/methods/meshgrid.rb +4 -5
  145. data/lib/carray/methods/mode.rb +2 -2
  146. data/lib/carray/methods/nunique.rb +23 -2
  147. data/lib/carray/methods/repeat.rb +110 -0
  148. data/lib/carray/methods/snap.rb +7 -2
  149. data/lib/carray/methods/unique.rb +44 -4
  150. data/lib/carray/methods/value_counts.rb +2 -2
  151. data/lib/carray/rng.rb +86 -0
  152. data/lib/carray/runtime.rb +0 -19
  153. data/lib/carray/slab_iterator.rb +77 -19
  154. data/lib/carray/string_operation_extension.rb +10 -6
  155. data/lib/carray/time.rb +906 -491
  156. data/lib/carray/window_iterator.rb +421 -27
  157. data/lib/carray.rb +7 -5
  158. data/yard-stubs/ca_obj_array.rb +385 -0
  159. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  160. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  161. data/yard-stubs/ca_obj_block.rb +68 -0
  162. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  163. data/yard-stubs/ca_obj_fake.rb +31 -0
  164. data/yard-stubs/ca_obj_farray.rb +32 -0
  165. data/yard-stubs/ca_obj_field.rb +45 -0
  166. data/yard-stubs/ca_obj_grid.rb +35 -0
  167. data/yard-stubs/ca_obj_refer.rb +72 -0
  168. data/yard-stubs/ca_obj_roll.rb +45 -0
  169. data/yard-stubs/ca_obj_shift.rb +43 -0
  170. data/yard-stubs/ca_obj_stride.rb +181 -0
  171. data/yard-stubs/ca_obj_tile.rb +29 -0
  172. data/yard-stubs/ca_obj_transpose.rb +40 -0
  173. data/yard-stubs/ca_obj_window.rb +57 -0
  174. data/yard-stubs/carray_access.rb +131 -0
  175. data/yard-stubs/carray_attribute.rb +246 -0
  176. data/yard-stubs/carray_broadcast.rb +37 -0
  177. data/yard-stubs/carray_cast.rb +489 -0
  178. data/yard-stubs/carray_class.rb +65 -0
  179. data/yard-stubs/carray_conversion.rb +76 -0
  180. data/yard-stubs/carray_copy.rb +79 -0
  181. data/yard-stubs/carray_core.rb +34 -0
  182. data/yard-stubs/carray_count.rb +84 -0
  183. data/yard-stubs/carray_element.rb +108 -0
  184. data/yard-stubs/carray_generate.rb +66 -0
  185. data/yard-stubs/carray_lazy.rb +228 -0
  186. data/yard-stubs/carray_loop.rb +140 -0
  187. data/yard-stubs/carray_mask.rb +259 -0
  188. data/yard-stubs/carray_math.rb +1615 -0
  189. data/yard-stubs/carray_mathfunc.rb +45 -0
  190. data/yard-stubs/carray_median_percentile.rb +103 -0
  191. data/yard-stubs/carray_memory_view.rb +163 -0
  192. data/yard-stubs/carray_order.rb +252 -0
  193. data/yard-stubs/carray_random.rb +89 -0
  194. data/yard-stubs/carray_scatter.rb +106 -0
  195. data/yard-stubs/carray_slab.rb +59 -0
  196. data/yard-stubs/carray_sort.rb +165 -0
  197. data/yard-stubs/carray_test.rb +85 -0
  198. data/yard-stubs/carray_undef.rb +64 -0
  199. data/yard-stubs/carray_utils.rb +97 -0
  200. data/yard-stubs/ruby_carray.rb +193 -0
  201. metadata +67 -10
  202. data/ext/ca_obj_unbound_repeat.c +0 -496
@@ -34,6 +34,7 @@ static inline VALUE BOOL2VAL (boolean8_t x) { return x ? Qtrue : Qfalse; }
34
34
  #endif
35
35
 
36
36
  #include "ca_op_powi.h"
37
+ #include "ca_op_cmplx64.h"
37
38
 
38
39
  /* ===== count_ki ============================================ */
39
40
 
@@ -134,6 +135,7 @@ count_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
134
135
  (void) v;
135
136
  }
136
137
  }
138
+
137
139
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
138
140
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
139
141
  }
@@ -213,6 +215,7 @@ count_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
213
215
  (void) v;
214
216
  }
215
217
  }
218
+
216
219
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
217
220
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
218
221
  }
@@ -338,6 +341,7 @@ count_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
338
341
  (void) v;
339
342
  }
340
343
  }
344
+
341
345
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
342
346
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
343
347
  }
@@ -368,8 +372,8 @@ count_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
368
372
  write stride 1 (= contig output tail) both preserved -> SIMD
369
373
  tile reduce + write maintained.
370
374
 
371
- Performance characteristic (deliver-via-view, per the CLAUDE.md
372
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
375
+ Performance characteristic (deliver-via-view -- the surface
376
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
373
377
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
374
378
  = 2.38x slow. Root cause is the multi-parent data layout
375
379
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -498,6 +502,7 @@ count_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
498
502
  (void) v;
499
503
  }
500
504
  }
505
+
501
506
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
502
507
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
503
508
  }
@@ -639,6 +644,7 @@ count_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
639
644
  (void) v;
640
645
  }
641
646
  }
647
+
642
648
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
643
649
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
644
650
  }
@@ -718,6 +724,7 @@ count_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
718
724
  (void) v;
719
725
  }
720
726
  }
727
+
721
728
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
722
729
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
723
730
  }
@@ -843,6 +850,7 @@ count_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
843
850
  (void) v;
844
851
  }
845
852
  }
853
+
846
854
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
847
855
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
848
856
  }
@@ -873,8 +881,8 @@ count_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
873
881
  write stride 1 (= contig output tail) both preserved -> SIMD
874
882
  tile reduce + write maintained.
875
883
 
876
- Performance characteristic (deliver-via-view, per the CLAUDE.md
877
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
884
+ Performance characteristic (deliver-via-view -- the surface
885
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
878
886
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
879
887
  = 2.38x slow. Root cause is the multi-parent data layout
880
888
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -1003,6 +1011,7 @@ count_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int
1003
1011
  (void) v;
1004
1012
  }
1005
1013
  }
1014
+
1006
1015
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1007
1016
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1008
1017
  }
@@ -1144,6 +1153,7 @@ count_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1144
1153
  (void) v;
1145
1154
  }
1146
1155
  }
1156
+
1147
1157
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1148
1158
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1149
1159
  }
@@ -1223,6 +1233,7 @@ count_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1223
1233
  (void) v;
1224
1234
  }
1225
1235
  }
1236
+
1226
1237
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1227
1238
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1228
1239
  }
@@ -1348,6 +1359,7 @@ count_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1348
1359
  (void) v;
1349
1360
  }
1350
1361
  }
1362
+
1351
1363
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1352
1364
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1353
1365
  }
@@ -1378,8 +1390,8 @@ count_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1378
1390
  write stride 1 (= contig output tail) both preserved -> SIMD
1379
1391
  tile reduce + write maintained.
1380
1392
 
1381
- Performance characteristic (deliver-via-view, per the CLAUDE.md
1382
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
1393
+ Performance characteristic (deliver-via-view -- the surface
1394
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
1383
1395
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
1384
1396
  = 2.38x slow. Root cause is the multi-parent data layout
1385
1397
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -1508,6 +1520,7 @@ count_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1508
1520
  (void) v;
1509
1521
  }
1510
1522
  }
1523
+
1511
1524
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1512
1525
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1513
1526
  }
@@ -1649,6 +1662,7 @@ count_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1649
1662
  (void) v;
1650
1663
  }
1651
1664
  }
1665
+
1652
1666
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1653
1667
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1654
1668
  }
@@ -1728,6 +1742,7 @@ count_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1728
1742
  (void) v;
1729
1743
  }
1730
1744
  }
1745
+
1731
1746
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1732
1747
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1733
1748
  }
@@ -1853,6 +1868,7 @@ count_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1853
1868
  (void) v;
1854
1869
  }
1855
1870
  }
1871
+
1856
1872
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
1857
1873
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
1858
1874
  }
@@ -1883,8 +1899,8 @@ count_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
1883
1899
  write stride 1 (= contig output tail) both preserved -> SIMD
1884
1900
  tile reduce + write maintained.
1885
1901
 
1886
- Performance characteristic (deliver-via-view, per the CLAUDE.md
1887
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
1902
+ Performance characteristic (deliver-via-view -- the surface
1903
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
1888
1904
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
1889
1905
  = 2.38x slow. Root cause is the multi-parent data layout
1890
1906
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -2013,6 +2029,7 @@ count_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2013
2029
  (void) v;
2014
2030
  }
2015
2031
  }
2032
+
2016
2033
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2017
2034
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2018
2035
  }
@@ -2154,6 +2171,7 @@ count_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2154
2171
  (void) v;
2155
2172
  }
2156
2173
  }
2174
+
2157
2175
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2158
2176
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2159
2177
  }
@@ -2233,6 +2251,7 @@ count_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2233
2251
  (void) v;
2234
2252
  }
2235
2253
  }
2254
+
2236
2255
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2237
2256
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2238
2257
  }
@@ -2358,6 +2377,7 @@ count_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2358
2377
  (void) v;
2359
2378
  }
2360
2379
  }
2380
+
2361
2381
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2362
2382
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2363
2383
  }
@@ -2388,8 +2408,8 @@ count_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2388
2408
  write stride 1 (= contig output tail) both preserved -> SIMD
2389
2409
  tile reduce + write maintained.
2390
2410
 
2391
- Performance characteristic (deliver-via-view, per the CLAUDE.md
2392
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
2411
+ Performance characteristic (deliver-via-view -- the surface
2412
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
2393
2413
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
2394
2414
  = 2.38x slow. Root cause is the multi-parent data layout
2395
2415
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -2518,6 +2538,7 @@ count_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2518
2538
  (void) v;
2519
2539
  }
2520
2540
  }
2541
+
2521
2542
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2522
2543
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2523
2544
  }
@@ -2659,6 +2680,7 @@ count_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2659
2680
  (void) v;
2660
2681
  }
2661
2682
  }
2683
+
2662
2684
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2663
2685
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2664
2686
  }
@@ -2738,6 +2760,7 @@ count_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2738
2760
  (void) v;
2739
2761
  }
2740
2762
  }
2763
+
2741
2764
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2742
2765
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2743
2766
  }
@@ -2863,6 +2886,7 @@ count_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2863
2886
  (void) v;
2864
2887
  }
2865
2888
  }
2889
+
2866
2890
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
2867
2891
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
2868
2892
  }
@@ -2893,8 +2917,8 @@ count_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
2893
2917
  write stride 1 (= contig output tail) both preserved -> SIMD
2894
2918
  tile reduce + write maintained.
2895
2919
 
2896
- Performance characteristic (deliver-via-view, per the CLAUDE.md
2897
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
2920
+ Performance characteristic (deliver-via-view -- the surface
2921
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
2898
2922
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
2899
2923
  = 2.38x slow. Root cause is the multi-parent data layout
2900
2924
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -3023,6 +3047,7 @@ count_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3023
3047
  (void) v;
3024
3048
  }
3025
3049
  }
3050
+
3026
3051
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3027
3052
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3028
3053
  }
@@ -3164,6 +3189,7 @@ count_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3164
3189
  (void) v;
3165
3190
  }
3166
3191
  }
3192
+
3167
3193
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3168
3194
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3169
3195
  }
@@ -3243,6 +3269,7 @@ count_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3243
3269
  (void) v;
3244
3270
  }
3245
3271
  }
3272
+
3246
3273
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3247
3274
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3248
3275
  }
@@ -3368,6 +3395,7 @@ count_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3368
3395
  (void) v;
3369
3396
  }
3370
3397
  }
3398
+
3371
3399
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3372
3400
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3373
3401
  }
@@ -3398,8 +3426,8 @@ count_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3398
3426
  write stride 1 (= contig output tail) both preserved -> SIMD
3399
3427
  tile reduce + write maintained.
3400
3428
 
3401
- Performance characteristic (deliver-via-view, per the CLAUDE.md
3402
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
3429
+ Performance characteristic (deliver-via-view -- the surface
3430
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
3403
3431
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
3404
3432
  = 2.38x slow. Root cause is the multi-parent data layout
3405
3433
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -3528,6 +3556,7 @@ count_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3528
3556
  (void) v;
3529
3557
  }
3530
3558
  }
3559
+
3531
3560
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3532
3561
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3533
3562
  }
@@ -3669,6 +3698,7 @@ count_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3669
3698
  (void) v;
3670
3699
  }
3671
3700
  }
3701
+
3672
3702
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3673
3703
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3674
3704
  }
@@ -3748,6 +3778,7 @@ count_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3748
3778
  (void) v;
3749
3779
  }
3750
3780
  }
3781
+
3751
3782
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3752
3783
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3753
3784
  }
@@ -3873,6 +3904,7 @@ count_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3873
3904
  (void) v;
3874
3905
  }
3875
3906
  }
3907
+
3876
3908
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
3877
3909
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
3878
3910
  }
@@ -3903,8 +3935,8 @@ count_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
3903
3935
  write stride 1 (= contig output tail) both preserved -> SIMD
3904
3936
  tile reduce + write maintained.
3905
3937
 
3906
- Performance characteristic (deliver-via-view, per the CLAUDE.md
3907
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
3938
+ Performance characteristic (deliver-via-view -- the surface
3939
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
3908
3940
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
3909
3941
  = 2.38x slow. Root cause is the multi-parent data layout
3910
3942
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -4033,6 +4065,7 @@ count_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4033
4065
  (void) v;
4034
4066
  }
4035
4067
  }
4068
+
4036
4069
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4037
4070
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4038
4071
  }
@@ -4174,6 +4207,7 @@ count_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4174
4207
  (void) v;
4175
4208
  }
4176
4209
  }
4210
+
4177
4211
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4178
4212
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4179
4213
  }
@@ -4253,6 +4287,7 @@ count_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4253
4287
  (void) v;
4254
4288
  }
4255
4289
  }
4290
+
4256
4291
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4257
4292
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4258
4293
  }
@@ -4378,6 +4413,7 @@ count_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4378
4413
  (void) v;
4379
4414
  }
4380
4415
  }
4416
+
4381
4417
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4382
4418
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4383
4419
  }
@@ -4408,8 +4444,8 @@ count_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4408
4444
  write stride 1 (= contig output tail) both preserved -> SIMD
4409
4445
  tile reduce + write maintained.
4410
4446
 
4411
- Performance characteristic (deliver-via-view, per the CLAUDE.md
4412
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
4447
+ Performance characteristic (deliver-via-view -- the surface
4448
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
4413
4449
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
4414
4450
  = 2.38x slow. Root cause is the multi-parent data layout
4415
4451
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -4538,6 +4574,7 @@ count_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4538
4574
  (void) v;
4539
4575
  }
4540
4576
  }
4577
+
4541
4578
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4542
4579
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4543
4580
  }
@@ -4679,6 +4716,7 @@ count_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4679
4716
  (void) v;
4680
4717
  }
4681
4718
  }
4719
+
4682
4720
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4683
4721
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4684
4722
  }
@@ -4758,6 +4796,7 @@ count_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4758
4796
  (void) v;
4759
4797
  }
4760
4798
  }
4799
+
4761
4800
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4762
4801
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4763
4802
  }
@@ -4883,6 +4922,7 @@ count_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4883
4922
  (void) v;
4884
4923
  }
4885
4924
  }
4925
+
4886
4926
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
4887
4927
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
4888
4928
  }
@@ -4913,8 +4953,8 @@ count_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
4913
4953
  write stride 1 (= contig output tail) both preserved -> SIMD
4914
4954
  tile reduce + write maintained.
4915
4955
 
4916
- Performance characteristic (deliver-via-view, per the CLAUDE.md
4917
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
4956
+ Performance characteristic (deliver-via-view -- the surface
4957
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
4918
4958
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
4919
4959
  = 2.38x slow. Root cause is the multi-parent data layout
4920
4960
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -5043,6 +5083,7 @@ count_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, in
5043
5083
  (void) v;
5044
5084
  }
5045
5085
  }
5086
+
5046
5087
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5047
5088
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
5048
5089
  }
@@ -5232,6 +5273,7 @@ accumulate_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5232
5273
  (void) v;
5233
5274
  }
5234
5275
  }
5276
+
5235
5277
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5236
5278
  op[__li_o * __li_INNER + __li_tile + __j] = (int8_t) (__li_buf_acc[__j]);
5237
5279
  }
@@ -5311,6 +5353,7 @@ accumulate_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5311
5353
  (void) v;
5312
5354
  }
5313
5355
  }
5356
+
5314
5357
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5315
5358
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int8_t) (__li_buf_acc[__j]);
5316
5359
  }
@@ -5436,6 +5479,7 @@ accumulate_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5436
5479
  (void) v;
5437
5480
  }
5438
5481
  }
5482
+
5439
5483
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5440
5484
  __li_op_k[__li_tile + __j] = (int8_t) (__li_buf_acc[__j]);
5441
5485
  }
@@ -5466,8 +5510,8 @@ accumulate_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5466
5510
  write stride 1 (= contig output tail) both preserved -> SIMD
5467
5511
  tile reduce + write maintained.
5468
5512
 
5469
- Performance characteristic (deliver-via-view, per the CLAUDE.md
5470
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
5513
+ Performance characteristic (deliver-via-view -- the surface
5514
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
5471
5515
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
5472
5516
  = 2.38x slow. Root cause is the multi-parent data layout
5473
5517
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -5596,6 +5640,7 @@ accumulate_ki_native_i8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5596
5640
  (void) v;
5597
5641
  }
5598
5642
  }
5643
+
5599
5644
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5600
5645
  __li_op_k[__li_tile + __j] = (int8_t) (__li_buf_acc[__j]);
5601
5646
  }
@@ -5751,6 +5796,7 @@ accumulate_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5751
5796
  (void) v;
5752
5797
  }
5753
5798
  }
5799
+
5754
5800
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5755
5801
  op[__li_o * __li_INNER + __li_tile + __j] = (uint8_t) (__li_buf_acc[__j]);
5756
5802
  }
@@ -5830,6 +5876,7 @@ accumulate_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5830
5876
  (void) v;
5831
5877
  }
5832
5878
  }
5879
+
5833
5880
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5834
5881
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (uint8_t) (__li_buf_acc[__j]);
5835
5882
  }
@@ -5955,6 +6002,7 @@ accumulate_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5955
6002
  (void) v;
5956
6003
  }
5957
6004
  }
6005
+
5958
6006
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
5959
6007
  __li_op_k[__li_tile + __j] = (uint8_t) (__li_buf_acc[__j]);
5960
6008
  }
@@ -5985,8 +6033,8 @@ accumulate_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
5985
6033
  write stride 1 (= contig output tail) both preserved -> SIMD
5986
6034
  tile reduce + write maintained.
5987
6035
 
5988
- Performance characteristic (deliver-via-view, per the CLAUDE.md
5989
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
6036
+ Performance characteristic (deliver-via-view -- the surface
6037
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
5990
6038
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
5991
6039
  = 2.38x slow. Root cause is the multi-parent data layout
5992
6040
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -6115,6 +6163,7 @@ accumulate_ki_native_u8 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes
6115
6163
  (void) v;
6116
6164
  }
6117
6165
  }
6166
+
6118
6167
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6119
6168
  __li_op_k[__li_tile + __j] = (uint8_t) (__li_buf_acc[__j]);
6120
6169
  }
@@ -6270,6 +6319,7 @@ accumulate_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6270
6319
  (void) v;
6271
6320
  }
6272
6321
  }
6322
+
6273
6323
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6274
6324
  op[__li_o * __li_INNER + __li_tile + __j] = (int16_t) (__li_buf_acc[__j]);
6275
6325
  }
@@ -6349,6 +6399,7 @@ accumulate_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6349
6399
  (void) v;
6350
6400
  }
6351
6401
  }
6402
+
6352
6403
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6353
6404
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int16_t) (__li_buf_acc[__j]);
6354
6405
  }
@@ -6474,6 +6525,7 @@ accumulate_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6474
6525
  (void) v;
6475
6526
  }
6476
6527
  }
6528
+
6477
6529
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6478
6530
  __li_op_k[__li_tile + __j] = (int16_t) (__li_buf_acc[__j]);
6479
6531
  }
@@ -6504,8 +6556,8 @@ accumulate_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6504
6556
  write stride 1 (= contig output tail) both preserved -> SIMD
6505
6557
  tile reduce + write maintained.
6506
6558
 
6507
- Performance characteristic (deliver-via-view, per the CLAUDE.md
6508
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
6559
+ Performance characteristic (deliver-via-view -- the surface
6560
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
6509
6561
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
6510
6562
  = 2.38x slow. Root cause is the multi-parent data layout
6511
6563
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -6634,6 +6686,7 @@ accumulate_ki_native_i16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6634
6686
  (void) v;
6635
6687
  }
6636
6688
  }
6689
+
6637
6690
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6638
6691
  __li_op_k[__li_tile + __j] = (int16_t) (__li_buf_acc[__j]);
6639
6692
  }
@@ -6789,6 +6842,7 @@ accumulate_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6789
6842
  (void) v;
6790
6843
  }
6791
6844
  }
6845
+
6792
6846
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6793
6847
  op[__li_o * __li_INNER + __li_tile + __j] = (uint16_t) (__li_buf_acc[__j]);
6794
6848
  }
@@ -6868,6 +6922,7 @@ accumulate_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6868
6922
  (void) v;
6869
6923
  }
6870
6924
  }
6925
+
6871
6926
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6872
6927
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (uint16_t) (__li_buf_acc[__j]);
6873
6928
  }
@@ -6993,6 +7048,7 @@ accumulate_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
6993
7048
  (void) v;
6994
7049
  }
6995
7050
  }
7051
+
6996
7052
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
6997
7053
  __li_op_k[__li_tile + __j] = (uint16_t) (__li_buf_acc[__j]);
6998
7054
  }
@@ -7023,8 +7079,8 @@ accumulate_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7023
7079
  write stride 1 (= contig output tail) both preserved -> SIMD
7024
7080
  tile reduce + write maintained.
7025
7081
 
7026
- Performance characteristic (deliver-via-view, per the CLAUDE.md
7027
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
7082
+ Performance characteristic (deliver-via-view -- the surface
7083
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
7028
7084
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
7029
7085
  = 2.38x slow. Root cause is the multi-parent data layout
7030
7086
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -7153,6 +7209,7 @@ accumulate_ki_native_u16 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7153
7209
  (void) v;
7154
7210
  }
7155
7211
  }
7212
+
7156
7213
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7157
7214
  __li_op_k[__li_tile + __j] = (uint16_t) (__li_buf_acc[__j]);
7158
7215
  }
@@ -7308,6 +7365,7 @@ accumulate_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7308
7365
  (void) v;
7309
7366
  }
7310
7367
  }
7368
+
7311
7369
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7312
7370
  op[__li_o * __li_INNER + __li_tile + __j] = (int32_t) (__li_buf_acc[__j]);
7313
7371
  }
@@ -7387,6 +7445,7 @@ accumulate_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7387
7445
  (void) v;
7388
7446
  }
7389
7447
  }
7448
+
7390
7449
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7391
7450
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int32_t) (__li_buf_acc[__j]);
7392
7451
  }
@@ -7512,6 +7571,7 @@ accumulate_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7512
7571
  (void) v;
7513
7572
  }
7514
7573
  }
7574
+
7515
7575
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7516
7576
  __li_op_k[__li_tile + __j] = (int32_t) (__li_buf_acc[__j]);
7517
7577
  }
@@ -7542,8 +7602,8 @@ accumulate_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7542
7602
  write stride 1 (= contig output tail) both preserved -> SIMD
7543
7603
  tile reduce + write maintained.
7544
7604
 
7545
- Performance characteristic (deliver-via-view, per the CLAUDE.md
7546
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
7605
+ Performance characteristic (deliver-via-view -- the surface
7606
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
7547
7607
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
7548
7608
  = 2.38x slow. Root cause is the multi-parent data layout
7549
7609
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -7672,6 +7732,7 @@ accumulate_ki_native_i32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7672
7732
  (void) v;
7673
7733
  }
7674
7734
  }
7735
+
7675
7736
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7676
7737
  __li_op_k[__li_tile + __j] = (int32_t) (__li_buf_acc[__j]);
7677
7738
  }
@@ -7827,6 +7888,7 @@ accumulate_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7827
7888
  (void) v;
7828
7889
  }
7829
7890
  }
7891
+
7830
7892
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7831
7893
  op[__li_o * __li_INNER + __li_tile + __j] = (uint32_t) (__li_buf_acc[__j]);
7832
7894
  }
@@ -7906,6 +7968,7 @@ accumulate_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
7906
7968
  (void) v;
7907
7969
  }
7908
7970
  }
7971
+
7909
7972
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
7910
7973
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (uint32_t) (__li_buf_acc[__j]);
7911
7974
  }
@@ -8031,6 +8094,7 @@ accumulate_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8031
8094
  (void) v;
8032
8095
  }
8033
8096
  }
8097
+
8034
8098
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8035
8099
  __li_op_k[__li_tile + __j] = (uint32_t) (__li_buf_acc[__j]);
8036
8100
  }
@@ -8061,8 +8125,8 @@ accumulate_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8061
8125
  write stride 1 (= contig output tail) both preserved -> SIMD
8062
8126
  tile reduce + write maintained.
8063
8127
 
8064
- Performance characteristic (deliver-via-view, per the CLAUDE.md
8065
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
8128
+ Performance characteristic (deliver-via-view -- the surface
8129
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
8066
8130
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
8067
8131
  = 2.38x slow. Root cause is the multi-parent data layout
8068
8132
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -8191,6 +8255,7 @@ accumulate_ki_native_u32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8191
8255
  (void) v;
8192
8256
  }
8193
8257
  }
8258
+
8194
8259
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8195
8260
  __li_op_k[__li_tile + __j] = (uint32_t) (__li_buf_acc[__j]);
8196
8261
  }
@@ -8346,6 +8411,7 @@ accumulate_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8346
8411
  (void) v;
8347
8412
  }
8348
8413
  }
8414
+
8349
8415
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8350
8416
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
8351
8417
  }
@@ -8425,6 +8491,7 @@ accumulate_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8425
8491
  (void) v;
8426
8492
  }
8427
8493
  }
8494
+
8428
8495
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8429
8496
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
8430
8497
  }
@@ -8550,6 +8617,7 @@ accumulate_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8550
8617
  (void) v;
8551
8618
  }
8552
8619
  }
8620
+
8553
8621
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8554
8622
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
8555
8623
  }
@@ -8580,8 +8648,8 @@ accumulate_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8580
8648
  write stride 1 (= contig output tail) both preserved -> SIMD
8581
8649
  tile reduce + write maintained.
8582
8650
 
8583
- Performance characteristic (deliver-via-view, per the CLAUDE.md
8584
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
8651
+ Performance characteristic (deliver-via-view -- the surface
8652
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
8585
8653
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
8586
8654
  = 2.38x slow. Root cause is the multi-parent data layout
8587
8655
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -8710,6 +8778,7 @@ accumulate_ki_native_i64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8710
8778
  (void) v;
8711
8779
  }
8712
8780
  }
8781
+
8713
8782
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8714
8783
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
8715
8784
  }
@@ -8865,6 +8934,7 @@ accumulate_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8865
8934
  (void) v;
8866
8935
  }
8867
8936
  }
8937
+
8868
8938
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8869
8939
  op[__li_o * __li_INNER + __li_tile + __j] = (uint64_t) (__li_buf_acc[__j]);
8870
8940
  }
@@ -8944,6 +9014,7 @@ accumulate_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
8944
9014
  (void) v;
8945
9015
  }
8946
9016
  }
9017
+
8947
9018
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
8948
9019
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (uint64_t) (__li_buf_acc[__j]);
8949
9020
  }
@@ -9069,6 +9140,7 @@ accumulate_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9069
9140
  (void) v;
9070
9141
  }
9071
9142
  }
9143
+
9072
9144
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9073
9145
  __li_op_k[__li_tile + __j] = (uint64_t) (__li_buf_acc[__j]);
9074
9146
  }
@@ -9099,8 +9171,8 @@ accumulate_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9099
9171
  write stride 1 (= contig output tail) both preserved -> SIMD
9100
9172
  tile reduce + write maintained.
9101
9173
 
9102
- Performance characteristic (deliver-via-view, per the CLAUDE.md
9103
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
9174
+ Performance characteristic (deliver-via-view -- the surface
9175
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
9104
9176
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
9105
9177
  = 2.38x slow. Root cause is the multi-parent data layout
9106
9178
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -9229,6 +9301,7 @@ accumulate_ki_native_u64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9229
9301
  (void) v;
9230
9302
  }
9231
9303
  }
9304
+
9232
9305
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9233
9306
  __li_op_k[__li_tile + __j] = (uint64_t) (__li_buf_acc[__j]);
9234
9307
  }
@@ -9384,6 +9457,7 @@ accumulate_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9384
9457
  (void) v;
9385
9458
  }
9386
9459
  }
9460
+
9387
9461
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9388
9462
  op[__li_o * __li_INNER + __li_tile + __j] = (float) (__li_buf_acc[__j]);
9389
9463
  }
@@ -9463,6 +9537,7 @@ accumulate_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9463
9537
  (void) v;
9464
9538
  }
9465
9539
  }
9540
+
9466
9541
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9467
9542
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (float) (__li_buf_acc[__j]);
9468
9543
  }
@@ -9588,6 +9663,7 @@ accumulate_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9588
9663
  (void) v;
9589
9664
  }
9590
9665
  }
9666
+
9591
9667
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9592
9668
  __li_op_k[__li_tile + __j] = (float) (__li_buf_acc[__j]);
9593
9669
  }
@@ -9618,8 +9694,8 @@ accumulate_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9618
9694
  write stride 1 (= contig output tail) both preserved -> SIMD
9619
9695
  tile reduce + write maintained.
9620
9696
 
9621
- Performance characteristic (deliver-via-view, per the CLAUDE.md
9622
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
9697
+ Performance characteristic (deliver-via-view -- the surface
9698
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
9623
9699
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
9624
9700
  = 2.38x slow. Root cause is the multi-parent data layout
9625
9701
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -9748,6 +9824,7 @@ accumulate_ki_native_f32 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9748
9824
  (void) v;
9749
9825
  }
9750
9826
  }
9827
+
9751
9828
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9752
9829
  __li_op_k[__li_tile + __j] = (float) (__li_buf_acc[__j]);
9753
9830
  }
@@ -9903,6 +9980,7 @@ accumulate_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9903
9980
  (void) v;
9904
9981
  }
9905
9982
  }
9983
+
9906
9984
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9907
9985
  op[__li_o * __li_INNER + __li_tile + __j] = (double) (__li_buf_acc[__j]);
9908
9986
  }
@@ -9982,6 +10060,7 @@ accumulate_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
9982
10060
  (void) v;
9983
10061
  }
9984
10062
  }
10063
+
9985
10064
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
9986
10065
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (double) (__li_buf_acc[__j]);
9987
10066
  }
@@ -10107,6 +10186,7 @@ accumulate_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
10107
10186
  (void) v;
10108
10187
  }
10109
10188
  }
10189
+
10110
10190
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10111
10191
  __li_op_k[__li_tile + __j] = (double) (__li_buf_acc[__j]);
10112
10192
  }
@@ -10137,8 +10217,8 @@ accumulate_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
10137
10217
  write stride 1 (= contig output tail) both preserved -> SIMD
10138
10218
  tile reduce + write maintained.
10139
10219
 
10140
- Performance characteristic (deliver-via-view, per the CLAUDE.md
10141
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
10220
+ Performance characteristic (deliver-via-view -- the surface
10221
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
10142
10222
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
10143
10223
  = 2.38x slow. Root cause is the multi-parent data layout
10144
10224
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -10267,6 +10347,7 @@ accumulate_ki_native_f64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxe
10267
10347
  (void) v;
10268
10348
  }
10269
10349
  }
10350
+
10270
10351
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10271
10352
  __li_op_k[__li_tile + __j] = (double) (__li_buf_acc[__j]);
10272
10353
  }
@@ -10422,6 +10503,7 @@ accumulate_ki_native_cmplx64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10422
10503
  (void) v;
10423
10504
  }
10424
10505
  }
10506
+
10425
10507
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10426
10508
  op[__li_o * __li_INNER + __li_tile + __j] = (cmplx64_t) (__li_buf_acc[__j]);
10427
10509
  }
@@ -10501,6 +10583,7 @@ accumulate_ki_native_cmplx64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10501
10583
  (void) v;
10502
10584
  }
10503
10585
  }
10586
+
10504
10587
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10505
10588
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (cmplx64_t) (__li_buf_acc[__j]);
10506
10589
  }
@@ -10626,6 +10709,7 @@ accumulate_ki_native_cmplx64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10626
10709
  (void) v;
10627
10710
  }
10628
10711
  }
10712
+
10629
10713
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10630
10714
  __li_op_k[__li_tile + __j] = (cmplx64_t) (__li_buf_acc[__j]);
10631
10715
  }
@@ -10656,8 +10740,8 @@ accumulate_ki_native_cmplx64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10656
10740
  write stride 1 (= contig output tail) both preserved -> SIMD
10657
10741
  tile reduce + write maintained.
10658
10742
 
10659
- Performance characteristic (deliver-via-view, per the CLAUDE.md
10660
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
10743
+ Performance characteristic (deliver-via-view -- the surface
10744
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
10661
10745
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
10662
10746
  = 2.38x slow. Root cause is the multi-parent data layout
10663
10747
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -10786,6 +10870,7 @@ accumulate_ki_native_cmplx64 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10786
10870
  (void) v;
10787
10871
  }
10788
10872
  }
10873
+
10789
10874
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10790
10875
  __li_op_k[__li_tile + __j] = (cmplx64_t) (__li_buf_acc[__j]);
10791
10876
  }
@@ -10941,6 +11026,7 @@ accumulate_ki_native_cmplx128 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
10941
11026
  (void) v;
10942
11027
  }
10943
11028
  }
11029
+
10944
11030
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
10945
11031
  op[__li_o * __li_INNER + __li_tile + __j] = (cmplx128_t) (__li_buf_acc[__j]);
10946
11032
  }
@@ -11020,6 +11106,7 @@ accumulate_ki_native_cmplx128 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
11020
11106
  (void) v;
11021
11107
  }
11022
11108
  }
11109
+
11023
11110
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11024
11111
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (cmplx128_t) (__li_buf_acc[__j]);
11025
11112
  }
@@ -11145,6 +11232,7 @@ accumulate_ki_native_cmplx128 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
11145
11232
  (void) v;
11146
11233
  }
11147
11234
  }
11235
+
11148
11236
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11149
11237
  __li_op_k[__li_tile + __j] = (cmplx128_t) (__li_buf_acc[__j]);
11150
11238
  }
@@ -11175,8 +11263,8 @@ accumulate_ki_native_cmplx128 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
11175
11263
  write stride 1 (= contig output tail) both preserved -> SIMD
11176
11264
  tile reduce + write maintained.
11177
11265
 
11178
- Performance characteristic (deliver-via-view, per the CLAUDE.md
11179
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
11266
+ Performance characteristic (deliver-via-view -- the surface
11267
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
11180
11268
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
11181
11269
  = 2.38x slow. Root cause is the multi-parent data layout
11182
11270
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -11305,6 +11393,7 @@ accumulate_ki_native_cmplx128 (VALUE self, CArray *ca, int8_t *slab_axes, int8_t
11305
11393
  (void) v;
11306
11394
  }
11307
11395
  }
11396
+
11308
11397
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11309
11398
  __li_op_k[__li_tile + __j] = (cmplx128_t) (__li_buf_acc[__j]);
11310
11399
  }
@@ -11460,6 +11549,7 @@ accumulate_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
11460
11549
  (void) v;
11461
11550
  }
11462
11551
  }
11552
+
11463
11553
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11464
11554
  op[__li_o * __li_INNER + __li_tile + __j] = (boolean8_t) (__li_buf_acc[__j]);
11465
11555
  }
@@ -11539,6 +11629,7 @@ accumulate_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
11539
11629
  (void) v;
11540
11630
  }
11541
11631
  }
11632
+
11542
11633
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11543
11634
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (boolean8_t) (__li_buf_acc[__j]);
11544
11635
  }
@@ -11664,6 +11755,7 @@ accumulate_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
11664
11755
  (void) v;
11665
11756
  }
11666
11757
  }
11758
+
11667
11759
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11668
11760
  __li_op_k[__li_tile + __j] = (boolean8_t) (__li_buf_acc[__j]);
11669
11761
  }
@@ -11694,8 +11786,8 @@ accumulate_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
11694
11786
  write stride 1 (= contig output tail) both preserved -> SIMD
11695
11787
  tile reduce + write maintained.
11696
11788
 
11697
- Performance characteristic (deliver-via-view, per the CLAUDE.md
11698
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
11789
+ Performance characteristic (deliver-via-view -- the surface
11790
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
11699
11791
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
11700
11792
  = 2.38x slow. Root cause is the multi-parent data layout
11701
11793
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -11824,6 +11916,7 @@ accumulate_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
11824
11916
  (void) v;
11825
11917
  }
11826
11918
  }
11919
+
11827
11920
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11828
11921
  __li_op_k[__li_tile + __j] = (boolean8_t) (__li_buf_acc[__j]);
11829
11922
  }
@@ -11908,7 +12001,7 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
11908
12001
  ca_size_t masked_cnt = 0; /* unused on streaming (no mask) */
11909
12002
  (void) masked_cnt;
11910
12003
  ca_lazy_arena_enter();
11911
- VALUE *__chunk = (VALUE *) ca_lazy_arena_acquire(__chunk_elems * sizeof(VALUE));
12004
+ VALUE *__chunk = (VALUE *) ca_lazy_arena_acquire_object(__chunk_elems);
11912
12005
  while ( __outer_off < __outer ) {
11913
12006
  ca_size_t __r = (__outer - __outer_off < __rows) ? (__outer - __outer_off) : __rows;
11914
12007
  ca_size_t __n = __r * __inner;
@@ -11977,6 +12070,7 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
11977
12070
  (void) v;
11978
12071
  }
11979
12072
  }
12073
+
11980
12074
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
11981
12075
  op[__li_o * __li_INNER + __li_tile + __j] = (VALUE) (__li_buf_acc[__j]);
11982
12076
  }
@@ -12056,6 +12150,7 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
12056
12150
  (void) v;
12057
12151
  }
12058
12152
  }
12153
+
12059
12154
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12060
12155
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (VALUE) (__li_buf_acc[__j]);
12061
12156
  }
@@ -12181,6 +12276,7 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
12181
12276
  (void) v;
12182
12277
  }
12183
12278
  }
12279
+
12184
12280
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12185
12281
  __li_op_k[__li_tile + __j] = (VALUE) (__li_buf_acc[__j]);
12186
12282
  }
@@ -12211,8 +12307,8 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
12211
12307
  write stride 1 (= contig output tail) both preserved -> SIMD
12212
12308
  tile reduce + write maintained.
12213
12309
 
12214
- Performance characteristic (deliver-via-view, per the CLAUDE.md
12215
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
12310
+ Performance characteristic (deliver-via-view -- the surface
12311
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
12216
12312
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
12217
12313
  = 2.38x slow. Root cause is the multi-parent data layout
12218
12314
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -12341,6 +12437,7 @@ accumulate_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t n
12341
12437
  (void) v;
12342
12438
  }
12343
12439
  }
12440
+
12344
12441
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12345
12442
  __li_op_k[__li_tile + __j] = (VALUE) (__li_buf_acc[__j]);
12346
12443
  }
@@ -12594,6 +12691,7 @@ count_true_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
12594
12691
  (void) v;
12595
12692
  }
12596
12693
  }
12694
+
12597
12695
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12598
12696
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
12599
12697
  }
@@ -12673,6 +12771,7 @@ count_true_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
12673
12771
  (void) v;
12674
12772
  }
12675
12773
  }
12774
+
12676
12775
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12677
12776
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
12678
12777
  }
@@ -12798,6 +12897,7 @@ count_true_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
12798
12897
  (void) v;
12799
12898
  }
12800
12899
  }
12900
+
12801
12901
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12802
12902
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
12803
12903
  }
@@ -12828,8 +12928,8 @@ count_true_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
12828
12928
  write stride 1 (= contig output tail) both preserved -> SIMD
12829
12929
  tile reduce + write maintained.
12830
12930
 
12831
- Performance characteristic (deliver-via-view, per the CLAUDE.md
12832
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
12931
+ Performance characteristic (deliver-via-view -- the surface
12932
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
12833
12933
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
12834
12934
  = 2.38x slow. Root cause is the multi-parent data layout
12835
12935
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -12958,6 +13058,7 @@ count_true_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t nax
12958
13058
  (void) v;
12959
13059
  }
12960
13060
  }
13061
+
12961
13062
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
12962
13063
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
12963
13064
  }
@@ -13161,6 +13262,7 @@ count_false_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t na
13161
13262
  (void) v;
13162
13263
  }
13163
13264
  }
13265
+
13164
13266
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
13165
13267
  op[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
13166
13268
  }
@@ -13240,6 +13342,7 @@ count_false_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t na
13240
13342
  (void) v;
13241
13343
  }
13242
13344
  }
13345
+
13243
13346
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
13244
13347
  __li_op_k[__li_o * __li_INNER + __li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
13245
13348
  }
@@ -13365,6 +13468,7 @@ count_false_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t na
13365
13468
  (void) v;
13366
13469
  }
13367
13470
  }
13471
+
13368
13472
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
13369
13473
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
13370
13474
  }
@@ -13395,8 +13499,8 @@ count_false_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t na
13395
13499
  write stride 1 (= contig output tail) both preserved -> SIMD
13396
13500
  tile reduce + write maintained.
13397
13501
 
13398
- Performance characteristic (deliver-via-view, per the CLAUDE.md
13399
- "deliver the materials" principle): bench (b2 pattern, M=200, K=5, eff_INNER
13502
+ Performance characteristic (deliver-via-view -- the surface
13503
+ prioritises delivering the cells over avoiding a copy): bench (b2 pattern, M=200, K=5, eff_INNER
13400
13504
  =360, INNER_pre_K=16) yields 3674 us vs eager-entity 1545 us
13401
13505
  = 2.38x slow. Root cause is the multi-parent data layout
13402
13506
  (= 5 separate 9 MB regions instead of one contig 46 MB),
@@ -13525,6 +13629,7 @@ count_false_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t na
13525
13629
  (void) v;
13526
13630
  }
13527
13631
  }
13632
+
13528
13633
  for ( ca_size_t __j = 0; __j < __li_tile_len; __j++ ) {
13529
13634
  __li_op_k[__li_tile + __j] = (int64_t) (__li_buf_acc[__j]);
13530
13635
  }
@@ -14487,6 +14592,160 @@ ca_size_t out_i = 0;
14487
14592
  return vout;
14488
14593
  }
14489
14594
 
14595
+ static VALUE
14596
+ count_equal_ki_native_object (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int keep_axis, VALUE value_arg, ca_size_t min_count)
14597
+ {
14598
+ /* P.4.5.3b/c streaming chunked reduce: full reduction over lazy unmasked. */
14599
+ /* P.4.5.3c (N-D): outer-axis chunking, 1-D is the natural sub-case. */
14600
+ if ( naxes == ca->ndim && ca->ndim >= 1 && !keep_axis &&
14601
+ ca_is_lazy_view(ca) && ! ca_has_mask(ca) ) {
14602
+ ca_size_t __inner = 1;
14603
+ int __k;
14604
+ for ( __k = 1; __k < ca->ndim; __k++ ) __inner *= ca->dim[__k];
14605
+ ca_size_t __target = 4096; /* L1d-friendly element budget (32KB for f64) */
14606
+ ca_size_t __rows = (__inner > 0) ? (__target / __inner) : __target;
14607
+ if ( __rows < 1 ) __rows = 1; /* at least one row per chunk */
14608
+ ca_size_t __chunk_elems = __rows * __inner;
14609
+ ca_size_t __outer = ca->dim[0];
14610
+ ca_size_t __starts[CA_RANK_MAX] = {0};
14611
+ ca_size_t __counts[CA_RANK_MAX];
14612
+ ca_size_t __strides[CA_RANK_MAX];
14613
+ ca_size_t __s = sizeof(VALUE);
14614
+ for ( __k = ca->ndim - 1; __k >= 0; __k-- ) {
14615
+ __strides[__k] = __s;
14616
+ __s *= ca->dim[__k];
14617
+ }
14618
+ for ( __k = 1; __k < ca->ndim; __k++ ) __counts[__k] = ca->dim[__k];
14619
+ ca_size_t __outer_off = 0;
14620
+ int64_t acc;
14621
+ acc = (0);
14622
+ ca_size_t masked_cnt = 0; /* unused on streaming (no mask) */
14623
+ (void) masked_cnt;
14624
+ ca_lazy_arena_enter();
14625
+ VALUE *__chunk = (VALUE *) ca_lazy_arena_acquire_object(__chunk_elems);
14626
+ while ( __outer_off < __outer ) {
14627
+ ca_size_t __r = (__outer - __outer_off < __rows) ? (__outer - __outer_off) : __rows;
14628
+ ca_size_t __n = __r * __inner;
14629
+ __starts[0] = __outer_off;
14630
+ __counts[0] = __r;
14631
+ ca_xfer_stride(ca, __starts, __counts, __strides, __chunk, CA_XFER_GET);
14632
+ ca_size_t __i;
14633
+ for ( __i = 0; __i < __n; __i++ ) {
14634
+ VALUE v = __chunk[__i];
14635
+ if (RTEST(rb_equal(v, value_arg))) acc += 1;
14636
+ }
14637
+ __outer_off += __r;
14638
+ }
14639
+ ca_lazy_arena_release(__chunk);
14640
+ ca_lazy_arena_exit();
14641
+ return LL2NUM((int64_t) (acc));
14642
+ }
14643
+ VALUE vout = rb_ca_new_reduced(self, slab_axes, naxes, CA_INT64, keep_axis);
14644
+ CArray *co;
14645
+ GetCArray(vout, co);
14646
+ int64_t *op = (int64_t *) co->ptr;
14647
+ ca_iter_state st;
14648
+ int rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES,
14649
+ slab_axes, naxes, 0);
14650
+ if ( rc != CA_ITER_OK ) {
14651
+ rb_raise(rb_eRuntimeError,
14652
+ "count_equal_ki: kernel_iterator init failed rc=%d", rc);
14653
+ }
14654
+ char *p;
14655
+ boolean8_t *m;
14656
+ ca_size_t out_i = 0;
14657
+ boolean8_t *op_mask = NULL; /* lazily allocated on first UNDEF */
14658
+ while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
14659
+ int64_t acc;
14660
+ ca_size_t masked_cnt = 0;
14661
+ CA_SLAB_REDUCE_T_EX(VALUE, st, p, m, acc, 0, if (RTEST(rb_equal(v, value_arg))) acc += 1, masked_cnt);
14662
+ if ( (min_count < 0 ? 0 : st.slab_elements - masked_cnt < min_count) ) {
14663
+ if ( ! op_mask ) {
14664
+ ca_create_mask(co);
14665
+ op_mask = (boolean8_t *) co->mask->ptr;
14666
+ }
14667
+ op_mask[out_i] = 1;
14668
+ op[out_i++] = (int64_t) 0; /* sentinel; mask bit is what counts */
14669
+ } else {
14670
+ op[out_i++] = (int64_t) (acc);
14671
+ }
14672
+ }
14673
+ ca_iter_state_finish(&st);
14674
+ if ( naxes == ca->ndim && !keep_axis ) {
14675
+ if ( op_mask && op_mask[0] ) return CA_UNDEF;
14676
+ return LL2NUM(op[0]);
14677
+ }
14678
+ return vout;
14679
+ }
14680
+
14681
+ static VALUE
14682
+ count_equal_ki_native_fixlen (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int keep_axis, const char *value_arg, ca_size_t min_count)
14683
+ {
14684
+ ca_size_t K = ca->bytes; /* uniform fixlen byte width */
14685
+ VALUE vout = rb_ca_new_reduced(self, slab_axes, naxes, CA_INT64, keep_axis);
14686
+ CArray *co;
14687
+ GetCArray(vout, co);
14688
+ char *op = (char *) co->ptr;
14689
+ ca_iter_state st;
14690
+ int rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES, slab_axes, naxes, 0);
14691
+ if ( rc != CA_ITER_OK ) {
14692
+ rb_raise(rb_eRuntimeError, "count_equal_ki: kernel_iterator init failed rc=%d", rc);
14693
+ }
14694
+ char *p;
14695
+ boolean8_t *m;
14696
+ ca_size_t out_i = 0;
14697
+ boolean8_t *op_mask = NULL; /* lazily allocated on first UNDEF */
14698
+ while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
14699
+ int64_t cnt = 0;
14700
+ ca_size_t masked_cnt = 0;
14701
+ int8_t sndim = st.slab_ndim;
14702
+ ca_size_t sidx[CA_RANK_MAX] = { 0 };
14703
+ ca_size_t total = st.slab_elements;
14704
+ for ( ca_size_t idx = 0; idx < total; idx++ ) {
14705
+ ca_size_t doff = 0, moff = 0;
14706
+ for ( int8_t sk = 0; sk < sndim; sk++ ) {
14707
+ doff += sidx[sk] * st.slab_strides[sk];
14708
+ moff += sidx[sk] * st.slab_mask_strides[sk];
14709
+ }
14710
+ if ( m != NULL && m[moff] ) {
14711
+ masked_cnt++;
14712
+ }
14713
+ else {
14714
+ const char *q = (const char *) p + doff;
14715
+ if ( memcmp(q, value_arg, (size_t) K) == 0 ) {
14716
+ cnt++;
14717
+ }
14718
+ }
14719
+ /* row-major odometer (innermost slab axis fastest) so idx
14720
+ matches CA_SLAB_REDUCE_T's flat slab index. */
14721
+ for ( int8_t sk = (int8_t)(sndim - 1); sk >= 0; sk-- ) {
14722
+ if ( ++sidx[sk] < st.slab_dims[sk] ) break;
14723
+ sidx[sk] = 0;
14724
+ }
14725
+ }
14726
+ if ( min_count < 0 ? 0
14727
+ : st.slab_elements - masked_cnt < min_count ) {
14728
+ if ( ! op_mask ) {
14729
+ ca_create_mask(co);
14730
+ op_mask = (boolean8_t *) co->mask->ptr;
14731
+ }
14732
+ op_mask[out_i] = 1;
14733
+ ((int64_t *) op)[out_i] = 0; /* sentinel; mask bit is what counts */
14734
+ out_i++;
14735
+ }
14736
+ else {
14737
+ ((int64_t *) op)[out_i] = cnt;
14738
+ out_i++;
14739
+ }
14740
+ }
14741
+ ca_iter_state_finish(&st);
14742
+ if ( naxes == ca->ndim && !keep_axis ) {
14743
+ if ( op_mask && op_mask[0] ) return CA_UNDEF;
14744
+ return LL2NUM(((int64_t *) op)[0]);
14745
+ }
14746
+ return vout;
14747
+ }
14748
+
14490
14749
  VALUE
14491
14750
  rb_ca_count_equal_ki (int argc, VALUE *argv, VALUE self)
14492
14751
  {
@@ -14567,8 +14826,19 @@ rb_ca_count_equal_ki (int argc, VALUE *argv, VALUE self)
14567
14826
  result = count_equal_ki_native_f64(self, src, slab_axes, naxes, keep_axis, value_arg, min_count);
14568
14827
  break;
14569
14828
  }
14829
+ case CA_OBJECT: {
14830
+ VALUE value_arg = (VALUE) (VALUE)(rval);
14831
+ result = count_equal_ki_native_object(self, src, slab_axes, naxes, keep_axis, value_arg, min_count);
14832
+ break;
14833
+ }
14834
+ case CA_FIXLEN: {
14835
+ char *value_arg = ALLOCA_N(char, src->bytes);
14836
+ rb_ca_obj2ptr(self, rval, value_arg);
14837
+ result = count_equal_ki_native_fixlen(self, src, slab_axes, naxes, keep_axis, value_arg, min_count);
14838
+ break;
14839
+ }
14570
14840
  default:
14571
- rb_raise(rb_eCADataTypeError, "count_equal_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64)", ca_type_name[src->data_type]);
14841
+ rb_raise(rb_eCADataTypeError, "count_equal_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, object, fixlen)", ca_type_name[src->data_type]);
14572
14842
  }
14573
14843
  if ( ! NIL_P(rfval) ) {
14574
14844
  if ( result == CA_UNDEF ) {