carray 3.0.3 → 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +1 -6
  7. data/ext/ca_axis_group.c +27 -27
  8. data/ext/ca_binop_dispatch.c +1 -29
  9. data/ext/ca_binop_dispatch.h +0 -1
  10. data/ext/ca_categorical_iterator.c +205 -134
  11. data/ext/ca_compare.c +7 -18
  12. data/ext/ca_group_iter.c +16 -17
  13. data/ext/ca_kernel_iterator.c +1234 -1994
  14. data/ext/ca_kernel_iterator.h +391 -437
  15. data/ext/ca_monop_dispatch.c +82 -59
  16. data/ext/ca_monop_dispatch.h +1 -0
  17. data/ext/ca_obj_array.c +96 -39
  18. data/ext/ca_obj_bincmp.c +24 -21
  19. data/ext/ca_obj_binop.c +15 -26
  20. data/ext/ca_obj_bitarray.c +3 -2
  21. data/ext/ca_obj_bitfield.c +5 -6
  22. data/ext/ca_obj_block.c +18 -9
  23. data/ext/ca_obj_byte_swap.c +5 -6
  24. data/ext/ca_obj_const_string.c +173 -19
  25. data/ext/ca_obj_face.c +238 -57
  26. data/ext/ca_obj_face.h +19 -0
  27. data/ext/ca_obj_fake.c +15 -29
  28. data/ext/ca_obj_farray.c +6 -3
  29. data/ext/ca_obj_field.c +17 -5
  30. data/ext/ca_obj_fixlen_string.c +2 -3
  31. data/ext/ca_obj_grid.c +406 -132
  32. data/ext/ca_obj_meld.c +172 -34
  33. data/ext/ca_obj_moncmp.c +23 -8
  34. data/ext/ca_obj_monop.c +67 -57
  35. data/ext/ca_obj_object.c +157 -51
  36. data/ext/ca_obj_record.c +12 -7
  37. data/ext/ca_obj_reduce.c +13 -8
  38. data/ext/ca_obj_refer.c +25 -27
  39. data/ext/ca_obj_remap.c +30 -9
  40. data/ext/ca_obj_repeat.c +9 -10
  41. data/ext/ca_obj_roll.c +6 -5
  42. data/ext/ca_obj_select.c +14 -9
  43. data/ext/ca_obj_select_axis.c +15 -47
  44. data/ext/ca_obj_shift.c +11 -1
  45. data/ext/ca_obj_stack.c +179 -34
  46. data/ext/ca_obj_stride.c +162 -115
  47. data/ext/ca_obj_string.c +71 -4
  48. data/ext/ca_obj_tile.c +6 -5
  49. data/ext/ca_obj_time.c +22 -6
  50. data/ext/ca_obj_timedelta.c +22 -6
  51. data/ext/ca_obj_transpose.c +5 -3
  52. data/ext/ca_obj_triop.c +23 -32
  53. data/ext/ca_obj_window.c +190 -26
  54. data/ext/ca_sweep_engine.c +2 -2
  55. data/ext/caframe_csv_reader.c +80 -1
  56. data/ext/carray.h +181 -75
  57. data/ext/carray_access.c +184 -96
  58. data/ext/carray_address_basis.c +343 -87
  59. data/ext/carray_attribute.c +89 -6
  60. data/ext/carray_bincount.c +10 -8
  61. data/ext/carray_broadcast.c +13 -8
  62. data/ext/carray_build_flags.h +3 -0
  63. data/ext/carray_call_cfunc.c +108 -0
  64. data/ext/carray_cast.c +142 -24
  65. data/ext/carray_cast_func.rb +46 -6
  66. data/ext/carray_class.c +4 -3
  67. data/ext/carray_config.h +28 -0
  68. data/ext/carray_conversion.c +16 -7
  69. data/ext/carray_copy.c +51 -14
  70. data/ext/carray_core.c +147 -55
  71. data/ext/carray_count.c +50 -20
  72. data/ext/carray_element.c +76 -33
  73. data/ext/carray_factorize.c +118 -64
  74. data/ext/carray_generate.c +191 -50
  75. data/ext/carray_histogram.c +62 -17
  76. data/ext/carray_hold.c +12 -15
  77. data/ext/carray_index_classifier.c +388 -176
  78. data/ext/carray_internal.h +336 -29
  79. data/ext/carray_kernels_bincmp.c +4453 -0
  80. data/ext/carray_kernels_binop.c +11368 -0
  81. data/ext/carray_kernels_init.c +1734 -0
  82. data/ext/carray_kernels_moncmp.c +2104 -0
  83. data/ext/carray_kernels_monop.c +18369 -0
  84. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  85. data/ext/carray_kernels_reduce_boolean.c +406 -0
  86. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  87. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  88. data/ext/carray_kernels_reduce_variance.c +3849 -0
  89. data/ext/carray_kernels_scan.c +4302 -0
  90. data/ext/carray_kernels_search.c +33829 -0
  91. data/ext/carray_kernels_sort.c +10906 -0
  92. data/ext/carray_kernels_triop.c +1864 -0
  93. data/ext/carray_key_windows.c +216 -0
  94. data/ext/carray_lazy.c +170 -111
  95. data/ext/carray_mask.c +292 -72
  96. data/ext/carray_median_percentile.c +82 -28
  97. data/ext/carray_memory_view.c +669 -561
  98. data/ext/carray_operator.c +124 -47
  99. data/ext/carray_order.c +384 -76
  100. data/ext/carray_partition.c +28 -27
  101. data/ext/carray_random.c +67 -13
  102. data/ext/carray_round.c +273 -0
  103. data/ext/carray_scatter.c +63 -38
  104. data/ext/carray_segment.c +3 -3
  105. data/ext/carray_slab.c +91 -28
  106. data/ext/carray_sort.c +35 -35
  107. data/ext/carray_struct.c +19 -18
  108. data/ext/carray_test.c +26 -5
  109. data/ext/carray_undef.c +4 -0
  110. data/ext/carray_utils.c +246 -45
  111. data/ext/mk_call_cfunc.rb +19 -2
  112. data/ext/mkkernel.rb +198 -240
  113. data/ext/ruby_carray.c +10 -4
  114. data/ext/version.h +4 -4
  115. data/lib/carray/attribute.rb +126 -22
  116. data/lib/carray/autoload_carray.rb +8 -31
  117. data/lib/carray/autoload_method_extension.rb +14 -5
  118. data/lib/carray/axis_group.rb +255 -106
  119. data/lib/carray/basics.rb +78 -10
  120. data/lib/carray/bincount_nd.rb +12 -2
  121. data/lib/carray/block_iterator.rb +126 -23
  122. data/lib/carray/boolean_reduce.rb +17 -17
  123. data/lib/carray/categorical.rb +165 -43
  124. data/lib/carray/categorical_iterator.rb +130 -27
  125. data/lib/carray/complex.rb +5 -5
  126. data/lib/carray/conditional.rb +67 -18
  127. data/lib/carray/const_string.rb +14 -5
  128. data/lib/carray/construct.rb +15 -11
  129. data/lib/carray/data_type_extension.rb +1 -0
  130. data/lib/carray/distance_limit.rb +77 -0
  131. data/lib/carray/fixlen_string.rb +7 -1
  132. data/lib/carray/frame/column_verbs.rb +70 -0
  133. data/lib/carray/frame/convert.rb +69 -0
  134. data/lib/carray/frame/csv_parser.rb +111 -17
  135. data/lib/carray/frame/describe.rb +3 -2
  136. data/lib/carray/frame/frame.rb +246 -21
  137. data/lib/carray/frame/group.rb +510 -95
  138. data/lib/carray/frame/io.rb +115 -28
  139. data/lib/carray/frame/join.rb +312 -51
  140. data/lib/carray/frame/records.rb +83 -7
  141. data/lib/carray/frame/reshape.rb +42 -35
  142. data/lib/carray/frame/sort.rb +7 -19
  143. data/lib/carray/frame/verbs.rb +188 -48
  144. data/lib/carray/frame/windows.rb +117 -0
  145. data/lib/carray/frame.rb +2 -0
  146. data/lib/carray/fuse_source.rb +11 -4
  147. data/lib/carray/fusion.rb +40 -16
  148. data/lib/carray/histogram.rb +6 -1
  149. data/lib/carray/inspect.rb +31 -8
  150. data/lib/carray/iterator.rb +85 -7
  151. data/lib/carray/key_windows.rb +620 -0
  152. data/lib/carray/lazy.rb +182 -183
  153. data/lib/carray/mask_gap_fill.rb +63 -57
  154. data/lib/carray/meld_reduce.rb +12 -14
  155. data/lib/carray/methods/bin.rb +26 -18
  156. data/lib/carray/methods/bincount.rb +16 -0
  157. data/lib/carray/methods/bit_string.rb +1 -1
  158. data/lib/carray/methods/choose.rb +16 -3
  159. data/lib/carray/methods/composition.rb +3 -1
  160. data/lib/carray/methods/gather_nd.rb +14 -5
  161. data/lib/carray/methods/insert_block.rb +2 -2
  162. data/lib/carray/methods/is_between.rb +59 -0
  163. data/lib/carray/methods/is_in.rb +53 -36
  164. data/lib/carray/methods/join.rb +1 -6
  165. data/lib/carray/methods/lag.rb +49 -0
  166. data/lib/carray/methods/locate_addr.rb +47 -51
  167. data/lib/carray/methods/mode.rb +1 -1
  168. data/lib/carray/methods/nunique.rb +11 -6
  169. data/lib/carray/methods/resize.rb +3 -3
  170. data/lib/carray/methods/value_counts.rb +4 -11
  171. data/lib/carray/record_order.rb +3 -3
  172. data/lib/carray/rng.rb +3 -0
  173. data/lib/carray/runtime.rb +53 -8
  174. data/lib/carray/segment_iterator.rb +313 -82
  175. data/lib/carray/serialize.rb +24 -10
  176. data/lib/carray/slab_iterator.rb +50 -0
  177. data/lib/carray/string.rb +105 -5
  178. data/lib/carray/string_operation_extension.rb +8 -1
  179. data/lib/carray/struct.rb +9 -21
  180. data/lib/carray/struct_builder.rb +19 -8
  181. data/lib/carray/time.rb +726 -104
  182. data/lib/carray/window_iterator.rb +122 -16
  183. data/lib/carray.rb +7 -0
  184. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  185. data/yard-stubs/ca_obj_field.rb +4 -0
  186. data/yard-stubs/ca_obj_grid.rb +21 -10
  187. data/yard-stubs/ca_obj_refer.rb +2 -1
  188. data/yard-stubs/ca_obj_roll.rb +2 -2
  189. data/yard-stubs/ca_obj_shift.rb +5 -1
  190. data/yard-stubs/ca_obj_tile.rb +1 -1
  191. data/yard-stubs/ca_obj_window.rb +8 -3
  192. data/yard-stubs/carray_access.rb +6 -1
  193. data/yard-stubs/carray_attribute.rb +0 -5
  194. data/yard-stubs/carray_cast.rb +10 -0
  195. data/yard-stubs/carray_conversion.rb +2 -1
  196. data/yard-stubs/carray_copy.rb +4 -2
  197. data/yard-stubs/carray_count.rb +4 -4
  198. data/yard-stubs/carray_element.rb +10 -4
  199. data/yard-stubs/carray_generate.rb +21 -1
  200. data/yard-stubs/carray_mask.rb +26 -2
  201. data/yard-stubs/carray_math.rb +27 -1
  202. data/yard-stubs/carray_median_percentile.rb +5 -2
  203. data/yard-stubs/carray_memory_view.rb +40 -23
  204. data/yard-stubs/carray_order.rb +29 -18
  205. data/yard-stubs/carray_random.rb +13 -4
  206. data/yard-stubs/carray_scatter.rb +14 -9
  207. data/yard-stubs/carray_slab.rb +9 -2
  208. data/yard-stubs/carray_sort.rb +6 -5
  209. data/yard-stubs/carray_test.rb +5 -3
  210. metadata +25 -3
  211. data/lib/carray/arrow_tensor.rb +0 -401
  212. data/lib/carray/table.rb +0 -108
@@ -0,0 +1,406 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ carray_kernels.c -- GENERATED by ext/mkkernel.rb -- DO NOT EDIT
4
+
5
+ Kernel definitions live in mkkernel.rb (search for `MkKernel.reduce`).
6
+ Regenerate by running:
7
+
8
+ cd ext && ruby mkkernel.rb > carray_kernels.c
9
+
10
+ extconf.rb regenerates automatically when mkkernel.rb is touched.
11
+
12
+ --------------------------------------------------------------------------- */
13
+
14
+ #include "carray.h"
15
+ #include "ca_kernel_iterator.h"
16
+ #include "ca_sort_kernels.h" /* sort kernels: internal, not via the carray.h umbrella */
17
+ #include "carray_internal.h" /* ca_lazy_arena_*, ca_is_lazy_view (streaming reduce) */
18
+ #include "ca_obj_face.h" /* rb_ca_strip_face_value (Face ordering gate) */
19
+ #include <math.h>
20
+ #include <stdint.h>
21
+ #include <stdlib.h> /* qsort, mergesort (HAVE_MERGESORT) -- for :sort kind */
22
+
23
+ /* MEMO_REDUCTION_FASTPATH_ENTITY_ONLY_GUARD Tier 2: CAStack identity is
24
+ probed by operation-table function pointer (obj_type is runtime-
25
+ assigned, so no CA_OBJ_STACK compile-time constant exists). */
26
+ extern ca_operation_function_t ca_stack_func;
27
+ /* The square root of a variance: an ε-negative from rounding becomes 0,
28
+ a NaN stays NaN (fmax(NaN, 0.0) is 0.0). */
29
+ #ifndef CARRAY_SQRT_CLAMP_DEFINED
30
+ #define CARRAY_SQRT_CLAMP_DEFINED
31
+ static inline double ca_sqrt_clamp (double v) { return sqrt(v < 0.0 ? 0.0 : v); }
32
+ #endif
33
+
34
+ /* BOOL2VAL: bool -> Ruby (Qtrue/Qfalse). Used as ruby_scalar wrapper
35
+ for the all/any flat-reduction Ruby surface so `a.all` / `a.any`
36
+ return real true/false, not Integer 0/1. (BOOL2OBJ already exists
37
+ but returns Integer per CArray's boolean-as-int convention.) */
38
+ #ifndef CARRAY_BOOL2VAL_DEFINED
39
+ #define CARRAY_BOOL2VAL_DEFINED
40
+ static inline VALUE BOOL2VAL (boolean8_t x) { return x ? Qtrue : Qfalse; }
41
+ #endif
42
+
43
+ #include "ca_op_powi.h"
44
+ #include "ca_op_cmplx64.h"
45
+
46
+ /* ===== all_ki ============================================ */
47
+
48
+ typedef struct {
49
+ void *chunk;
50
+ CArray *ca;
51
+ } all_ki_stream_bool_t;
52
+
53
+ static VALUE
54
+ all_ki_stream_bool (VALUE arg)
55
+ {
56
+ all_ki_stream_bool_t *__ctx = (all_ki_stream_bool_t *) arg;
57
+ CArray *ca = __ctx->ca;
58
+ ca_size_t __inner = 1;
59
+ int __k;
60
+ for ( __k = 1; __k < ca->ndim; __k++ ) __inner *= ca->dim[__k];
61
+ ca_size_t __target = 4096; /* L1d-friendly element budget (32KB for f64) */
62
+ ca_size_t __rows = (__inner > 0) ? (__target / __inner) : __target;
63
+ if ( __rows < 1 ) __rows = 1; /* at least one row per chunk */
64
+ ca_size_t __chunk_elems = __rows * __inner;
65
+ ca_size_t __outer = ca->dim[0];
66
+ ca_size_t __starts[CA_RANK_MAX] = {0};
67
+ ca_size_t __counts[CA_RANK_MAX];
68
+ ca_size_t __strides[CA_RANK_MAX];
69
+ ca_size_t __s = sizeof(boolean8_t);
70
+ for ( __k = ca->ndim - 1; __k >= 0; __k-- ) {
71
+ __strides[__k] = __s;
72
+ __s *= ca->dim[__k];
73
+ }
74
+ for ( __k = 1; __k < ca->ndim; __k++ ) __counts[__k] = ca->dim[__k];
75
+ ca_size_t __outer_off = 0;
76
+ boolean8_t acc;
77
+ acc = (1);
78
+ boolean8_t *__chunk = (boolean8_t *) ca_lazy_arena_acquire(__chunk_elems * sizeof(boolean8_t));
79
+ __ctx->chunk = __chunk;
80
+ while ( __outer_off < __outer ) {
81
+ ca_size_t __r = (__outer - __outer_off < __rows) ? (__outer - __outer_off) : __rows;
82
+ ca_size_t __n = __r * __inner;
83
+ __starts[0] = __outer_off;
84
+ __counts[0] = __r;
85
+ ca_xfer_stride(ca, __starts, __counts, __strides, __chunk, CA_XFER_GET);
86
+ ca_size_t __i;
87
+ for ( __i = 0; __i < __n; __i++ ) {
88
+ boolean8_t v = __chunk[__i];
89
+ acc &= v;
90
+ }
91
+ __outer_off += __r;
92
+ }
93
+ return BOOL2VAL((boolean8_t) (acc));
94
+ }
95
+
96
+ static VALUE
97
+ all_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int keep_axis)
98
+ {
99
+ if ( naxes == ca->ndim && ca->ndim >= 1 && !keep_axis &&
100
+ ca->elements > 0 &&
101
+ ca_is_lazy_view(ca) && ! ca_has_mask(ca) &&
102
+ ca_fast_paths_enabled() ) {
103
+ all_ki_stream_bool_t __ctx;
104
+ __ctx.chunk = NULL;
105
+ __ctx.ca = ca;
106
+ return ca_lazy_arena_protect(all_ki_stream_bool, ca_lazy_arena_release_held,
107
+ (VALUE) &__ctx);
108
+ }
109
+ VALUE vout = rb_ca_new_reduced(self, slab_axes, naxes, CA_BOOLEAN, keep_axis);
110
+ CArray *co;
111
+ GetCArray(vout, co);
112
+ boolean8_t *op = (boolean8_t *) co->ptr;
113
+ ca_iter_state st;
114
+ int rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES,
115
+ slab_axes, naxes, 0);
116
+ if ( rc != CA_ITER_OK ) {
117
+ rb_raise(rb_eRuntimeError,
118
+ "%s: kernel_iterator init failed rc=%d", ca_calling_method_name(), rc);
119
+ }
120
+ char *p;
121
+ boolean8_t *m;
122
+ ca_size_t out_i = 0;
123
+ while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
124
+ boolean8_t acc;
125
+ CA_SLAB_REDUCE_T(boolean8_t, st, p, m, acc, 1, acc &= v);
126
+ op[out_i++] = (boolean8_t) (acc);
127
+ }
128
+ ca_iter_state_finish(&st);
129
+ if ( naxes == ca->ndim && !keep_axis ) return BOOL2VAL(op[0]);
130
+ return vout;
131
+ }
132
+
133
+ VALUE
134
+ rb_ca_all_ki (int argc, VALUE *argv, VALUE self)
135
+ {
136
+ CArray *src;
137
+ GetCArray(self, src);
138
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
139
+ volatile VALUE raxis = Qnil, rkeep_axis = Qnil;
140
+ rb_scan_options(ropt, "axis,keep_axis", &raxis, &rkeep_axis);
141
+ int keep_axis = RTEST(rkeep_axis);
142
+ int8_t slab_axes[CA_RANK_MAX];
143
+ int8_t naxes = rb_ca_parse_reduce_axes_kw(raxis, src, slab_axes);
144
+ if ( ca_is_lazy_view(src) && ! ( naxes == src->ndim && src->ndim >= 1 && ! keep_axis && ! ca_has_mask(src) ) ) {
145
+ volatile VALUE evaluated = ca_lazy_evaluated(self);
146
+ if ( ! NIL_P(evaluated) ) {
147
+ self = evaluated;
148
+ GetCArray(self, src);
149
+ }
150
+ }
151
+ if ( argc > 0 ) {
152
+ rb_raise(rb_eArgError, "%s: positional axis arguments are no longer accepted (got %d); use the axis: keyword, e.g. a.%s(axis: 0) or a.%s(axis: [0, 1])", ca_calling_method_name(), argc, ca_calling_method_name(), ca_calling_method_name());
153
+ }
154
+ switch ( src->data_type ) {
155
+ case CA_BOOLEAN: CA_RETURN_KEEPING(self, all_ki_native_bool(self, src, slab_axes, naxes, keep_axis));
156
+ default:
157
+ ca_face_refuse_numeric(self, ca_calling_method_name(), rb_eCADataTypeError);
158
+ rb_raise(rb_eCADataTypeError, "%s: source data_type :%s not supported (expected one of: boolean)", ca_calling_method_name(), ca_type_name[src->data_type]);
159
+ }
160
+ return Qnil; /* unreachable */
161
+ }
162
+
163
+ /* ===== any_ki ============================================ */
164
+
165
+ typedef struct {
166
+ void *chunk;
167
+ CArray *ca;
168
+ } any_ki_stream_bool_t;
169
+
170
+ static VALUE
171
+ any_ki_stream_bool (VALUE arg)
172
+ {
173
+ any_ki_stream_bool_t *__ctx = (any_ki_stream_bool_t *) arg;
174
+ CArray *ca = __ctx->ca;
175
+ ca_size_t __inner = 1;
176
+ int __k;
177
+ for ( __k = 1; __k < ca->ndim; __k++ ) __inner *= ca->dim[__k];
178
+ ca_size_t __target = 4096; /* L1d-friendly element budget (32KB for f64) */
179
+ ca_size_t __rows = (__inner > 0) ? (__target / __inner) : __target;
180
+ if ( __rows < 1 ) __rows = 1; /* at least one row per chunk */
181
+ ca_size_t __chunk_elems = __rows * __inner;
182
+ ca_size_t __outer = ca->dim[0];
183
+ ca_size_t __starts[CA_RANK_MAX] = {0};
184
+ ca_size_t __counts[CA_RANK_MAX];
185
+ ca_size_t __strides[CA_RANK_MAX];
186
+ ca_size_t __s = sizeof(boolean8_t);
187
+ for ( __k = ca->ndim - 1; __k >= 0; __k-- ) {
188
+ __strides[__k] = __s;
189
+ __s *= ca->dim[__k];
190
+ }
191
+ for ( __k = 1; __k < ca->ndim; __k++ ) __counts[__k] = ca->dim[__k];
192
+ ca_size_t __outer_off = 0;
193
+ boolean8_t acc;
194
+ acc = (0);
195
+ boolean8_t *__chunk = (boolean8_t *) ca_lazy_arena_acquire(__chunk_elems * sizeof(boolean8_t));
196
+ __ctx->chunk = __chunk;
197
+ while ( __outer_off < __outer ) {
198
+ ca_size_t __r = (__outer - __outer_off < __rows) ? (__outer - __outer_off) : __rows;
199
+ ca_size_t __n = __r * __inner;
200
+ __starts[0] = __outer_off;
201
+ __counts[0] = __r;
202
+ ca_xfer_stride(ca, __starts, __counts, __strides, __chunk, CA_XFER_GET);
203
+ ca_size_t __i;
204
+ for ( __i = 0; __i < __n; __i++ ) {
205
+ boolean8_t v = __chunk[__i];
206
+ acc |= v;
207
+ }
208
+ __outer_off += __r;
209
+ }
210
+ return BOOL2VAL((boolean8_t) (acc));
211
+ }
212
+
213
+ static VALUE
214
+ any_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int keep_axis)
215
+ {
216
+ if ( naxes == ca->ndim && ca->ndim >= 1 && !keep_axis &&
217
+ ca->elements > 0 &&
218
+ ca_is_lazy_view(ca) && ! ca_has_mask(ca) &&
219
+ ca_fast_paths_enabled() ) {
220
+ any_ki_stream_bool_t __ctx;
221
+ __ctx.chunk = NULL;
222
+ __ctx.ca = ca;
223
+ return ca_lazy_arena_protect(any_ki_stream_bool, ca_lazy_arena_release_held,
224
+ (VALUE) &__ctx);
225
+ }
226
+ VALUE vout = rb_ca_new_reduced(self, slab_axes, naxes, CA_BOOLEAN, keep_axis);
227
+ CArray *co;
228
+ GetCArray(vout, co);
229
+ boolean8_t *op = (boolean8_t *) co->ptr;
230
+ ca_iter_state st;
231
+ int rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES,
232
+ slab_axes, naxes, 0);
233
+ if ( rc != CA_ITER_OK ) {
234
+ rb_raise(rb_eRuntimeError,
235
+ "%s: kernel_iterator init failed rc=%d", ca_calling_method_name(), rc);
236
+ }
237
+ char *p;
238
+ boolean8_t *m;
239
+ ca_size_t out_i = 0;
240
+ while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
241
+ boolean8_t acc;
242
+ CA_SLAB_REDUCE_T(boolean8_t, st, p, m, acc, 0, acc |= v);
243
+ op[out_i++] = (boolean8_t) (acc);
244
+ }
245
+ ca_iter_state_finish(&st);
246
+ if ( naxes == ca->ndim && !keep_axis ) return BOOL2VAL(op[0]);
247
+ return vout;
248
+ }
249
+
250
+ VALUE
251
+ rb_ca_any_ki (int argc, VALUE *argv, VALUE self)
252
+ {
253
+ CArray *src;
254
+ GetCArray(self, src);
255
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
256
+ volatile VALUE raxis = Qnil, rkeep_axis = Qnil;
257
+ rb_scan_options(ropt, "axis,keep_axis", &raxis, &rkeep_axis);
258
+ int keep_axis = RTEST(rkeep_axis);
259
+ int8_t slab_axes[CA_RANK_MAX];
260
+ int8_t naxes = rb_ca_parse_reduce_axes_kw(raxis, src, slab_axes);
261
+ if ( ca_is_lazy_view(src) && ! ( naxes == src->ndim && src->ndim >= 1 && ! keep_axis && ! ca_has_mask(src) ) ) {
262
+ volatile VALUE evaluated = ca_lazy_evaluated(self);
263
+ if ( ! NIL_P(evaluated) ) {
264
+ self = evaluated;
265
+ GetCArray(self, src);
266
+ }
267
+ }
268
+ if ( argc > 0 ) {
269
+ rb_raise(rb_eArgError, "%s: positional axis arguments are no longer accepted (got %d); use the axis: keyword, e.g. a.%s(axis: 0) or a.%s(axis: [0, 1])", ca_calling_method_name(), argc, ca_calling_method_name(), ca_calling_method_name());
270
+ }
271
+ switch ( src->data_type ) {
272
+ case CA_BOOLEAN: CA_RETURN_KEEPING(self, any_ki_native_bool(self, src, slab_axes, naxes, keep_axis));
273
+ default:
274
+ ca_face_refuse_numeric(self, ca_calling_method_name(), rb_eCADataTypeError);
275
+ rb_raise(rb_eCADataTypeError, "%s: source data_type :%s not supported (expected one of: boolean)", ca_calling_method_name(), ca_type_name[src->data_type]);
276
+ }
277
+ return Qnil; /* unreachable */
278
+ }
279
+
280
+ /* ===== none_ki ============================================ */
281
+
282
+ typedef struct {
283
+ void *chunk;
284
+ CArray *ca;
285
+ } none_ki_stream_bool_t;
286
+
287
+ static VALUE
288
+ none_ki_stream_bool (VALUE arg)
289
+ {
290
+ none_ki_stream_bool_t *__ctx = (none_ki_stream_bool_t *) arg;
291
+ CArray *ca = __ctx->ca;
292
+ ca_size_t __inner = 1;
293
+ int __k;
294
+ for ( __k = 1; __k < ca->ndim; __k++ ) __inner *= ca->dim[__k];
295
+ ca_size_t __target = 4096; /* L1d-friendly element budget (32KB for f64) */
296
+ ca_size_t __rows = (__inner > 0) ? (__target / __inner) : __target;
297
+ if ( __rows < 1 ) __rows = 1; /* at least one row per chunk */
298
+ ca_size_t __chunk_elems = __rows * __inner;
299
+ ca_size_t __outer = ca->dim[0];
300
+ ca_size_t __starts[CA_RANK_MAX] = {0};
301
+ ca_size_t __counts[CA_RANK_MAX];
302
+ ca_size_t __strides[CA_RANK_MAX];
303
+ ca_size_t __s = sizeof(boolean8_t);
304
+ for ( __k = ca->ndim - 1; __k >= 0; __k-- ) {
305
+ __strides[__k] = __s;
306
+ __s *= ca->dim[__k];
307
+ }
308
+ for ( __k = 1; __k < ca->ndim; __k++ ) __counts[__k] = ca->dim[__k];
309
+ ca_size_t __outer_off = 0;
310
+ boolean8_t acc;
311
+ acc = (1);
312
+ boolean8_t *__chunk = (boolean8_t *) ca_lazy_arena_acquire(__chunk_elems * sizeof(boolean8_t));
313
+ __ctx->chunk = __chunk;
314
+ while ( __outer_off < __outer ) {
315
+ ca_size_t __r = (__outer - __outer_off < __rows) ? (__outer - __outer_off) : __rows;
316
+ ca_size_t __n = __r * __inner;
317
+ __starts[0] = __outer_off;
318
+ __counts[0] = __r;
319
+ ca_xfer_stride(ca, __starts, __counts, __strides, __chunk, CA_XFER_GET);
320
+ ca_size_t __i;
321
+ for ( __i = 0; __i < __n; __i++ ) {
322
+ boolean8_t v = __chunk[__i];
323
+ acc &= !v;
324
+ }
325
+ __outer_off += __r;
326
+ }
327
+ return BOOL2VAL((boolean8_t) (acc));
328
+ }
329
+
330
+ static VALUE
331
+ none_ki_native_bool (VALUE self, CArray *ca, int8_t *slab_axes, int8_t naxes, int keep_axis)
332
+ {
333
+ if ( naxes == ca->ndim && ca->ndim >= 1 && !keep_axis &&
334
+ ca->elements > 0 &&
335
+ ca_is_lazy_view(ca) && ! ca_has_mask(ca) &&
336
+ ca_fast_paths_enabled() ) {
337
+ none_ki_stream_bool_t __ctx;
338
+ __ctx.chunk = NULL;
339
+ __ctx.ca = ca;
340
+ return ca_lazy_arena_protect(none_ki_stream_bool, ca_lazy_arena_release_held,
341
+ (VALUE) &__ctx);
342
+ }
343
+ VALUE vout = rb_ca_new_reduced(self, slab_axes, naxes, CA_BOOLEAN, keep_axis);
344
+ CArray *co;
345
+ GetCArray(vout, co);
346
+ boolean8_t *op = (boolean8_t *) co->ptr;
347
+ ca_iter_state st;
348
+ int rc = ca_iter_state_init_l2(&st, ca, CA_SLAB_AXES,
349
+ slab_axes, naxes, 0);
350
+ if ( rc != CA_ITER_OK ) {
351
+ rb_raise(rb_eRuntimeError,
352
+ "%s: kernel_iterator init failed rc=%d", ca_calling_method_name(), rc);
353
+ }
354
+ char *p;
355
+ boolean8_t *m;
356
+ ca_size_t out_i = 0;
357
+ while ( ca_iter_state_next_slab_axes(&st, &p, &m) ) {
358
+ boolean8_t acc;
359
+ CA_SLAB_REDUCE_T(boolean8_t, st, p, m, acc, 1, acc &= !v);
360
+ op[out_i++] = (boolean8_t) (acc);
361
+ }
362
+ ca_iter_state_finish(&st);
363
+ if ( naxes == ca->ndim && !keep_axis ) return BOOL2VAL(op[0]);
364
+ return vout;
365
+ }
366
+
367
+ VALUE
368
+ rb_ca_none_ki (int argc, VALUE *argv, VALUE self)
369
+ {
370
+ CArray *src;
371
+ GetCArray(self, src);
372
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
373
+ volatile VALUE raxis = Qnil, rkeep_axis = Qnil;
374
+ rb_scan_options(ropt, "axis,keep_axis", &raxis, &rkeep_axis);
375
+ int keep_axis = RTEST(rkeep_axis);
376
+ int8_t slab_axes[CA_RANK_MAX];
377
+ int8_t naxes = rb_ca_parse_reduce_axes_kw(raxis, src, slab_axes);
378
+ if ( ca_is_lazy_view(src) && ! ( naxes == src->ndim && src->ndim >= 1 && ! keep_axis && ! ca_has_mask(src) ) ) {
379
+ volatile VALUE evaluated = ca_lazy_evaluated(self);
380
+ if ( ! NIL_P(evaluated) ) {
381
+ self = evaluated;
382
+ GetCArray(self, src);
383
+ }
384
+ }
385
+ if ( argc > 0 ) {
386
+ rb_raise(rb_eArgError, "%s: positional axis arguments are no longer accepted (got %d); use the axis: keyword, e.g. a.%s(axis: 0) or a.%s(axis: [0, 1])", ca_calling_method_name(), argc, ca_calling_method_name(), ca_calling_method_name());
387
+ }
388
+ switch ( src->data_type ) {
389
+ case CA_BOOLEAN: CA_RETURN_KEEPING(self, none_ki_native_bool(self, src, slab_axes, naxes, keep_axis));
390
+ default:
391
+ ca_face_refuse_numeric(self, ca_calling_method_name(), rb_eCADataTypeError);
392
+ rb_raise(rb_eCADataTypeError, "%s: source data_type :%s not supported (expected one of: boolean)", ca_calling_method_name(), ca_type_name[src->data_type]);
393
+ }
394
+ return Qnil; /* unreachable */
395
+ }
396
+
397
+ void
398
+ Init_carray_kernels_reduce_boolean (void)
399
+ {
400
+ /* Phase E rewire: legacy 'all' now dispatches via all_ki */
401
+ rb_define_method(rb_cCArray, "all", rb_ca_all_ki, -1);
402
+ /* Phase E rewire: legacy 'any' now dispatches via any_ki */
403
+ rb_define_method(rb_cCArray, "any", rb_ca_any_ki, -1);
404
+ /* Phase E rewire: legacy 'none' now dispatches via none_ki */
405
+ rb_define_method(rb_cCArray, "none", rb_ca_none_ki, -1);
406
+ }