carray 2.0.0 → 3.0.0

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 (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -0,0 +1,3692 @@
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
+ /* BOOL2VAL: bool -> Ruby (Qtrue/Qfalse). Used as ruby_scalar wrapper
28
+ for the all/any flat-reduction Ruby surface so `a.all` / `a.any`
29
+ return real true/false, not Integer 0/1. (BOOL2OBJ already exists
30
+ but returns Integer per CArray's boolean-as-int convention.) */
31
+ #ifndef CARRAY_BOOL2VAL_DEFINED
32
+ #define CARRAY_BOOL2VAL_DEFINED
33
+ static inline VALUE BOOL2VAL (boolean8_t x) { return x ? Qtrue : Qfalse; }
34
+ #endif
35
+
36
+ #include "ca_op_powi.h"
37
+
38
+ /* ===== cumsum_ki ============================================ */
39
+
40
+ static VALUE
41
+ cumsum_ki_native_i8 (VALUE self, CArray *ca, int axis)
42
+ {
43
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
44
+ INT2NUM(sizeof(double)));
45
+ CArray *co;
46
+ GetCArray(vout, co);
47
+
48
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
49
+ iteration is one "fiber" along that axis with acc reset to
50
+ INIT inside the macro. */
51
+ int8_t slab_axes[CA_RANK_MAX];
52
+ slab_axes[0] = (int8_t) axis;
53
+ ca_iter_state st_in, st_out;
54
+ int rc;
55
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
56
+ slab_axes, 1, 0);
57
+ if ( rc != CA_ITER_OK ) {
58
+ rb_raise(rb_eRuntimeError,
59
+ "cumsum_ki: input init failed rc=%d", rc);
60
+ }
61
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
62
+ slab_axes, 1, CA_KERNEL_WRITE);
63
+ if ( rc != CA_ITER_OK ) {
64
+ ca_iter_state_finish(&st_in);
65
+ rb_raise(rb_eRuntimeError,
66
+ "cumsum_ki: output init failed rc=%d", rc);
67
+ }
68
+
69
+ char *pi, *po;
70
+ boolean8_t *mi, *mo;
71
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
72
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
73
+ CA_SLAB_SCAN_T(int8_t, double, st_in, pi, mi,
74
+ st_out, po, 0, acc += v; r = acc);
75
+ ca_iter_state_sync_slab(&st_out);
76
+ }
77
+ ca_iter_state_finish(&st_in);
78
+ ca_iter_state_finish(&st_out);
79
+ return vout;
80
+ }
81
+
82
+ static VALUE
83
+ cumsum_ki_native_u8 (VALUE self, CArray *ca, int axis)
84
+ {
85
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
86
+ INT2NUM(sizeof(double)));
87
+ CArray *co;
88
+ GetCArray(vout, co);
89
+
90
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
91
+ iteration is one "fiber" along that axis with acc reset to
92
+ INIT inside the macro. */
93
+ int8_t slab_axes[CA_RANK_MAX];
94
+ slab_axes[0] = (int8_t) axis;
95
+ ca_iter_state st_in, st_out;
96
+ int rc;
97
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
98
+ slab_axes, 1, 0);
99
+ if ( rc != CA_ITER_OK ) {
100
+ rb_raise(rb_eRuntimeError,
101
+ "cumsum_ki: input init failed rc=%d", rc);
102
+ }
103
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
104
+ slab_axes, 1, CA_KERNEL_WRITE);
105
+ if ( rc != CA_ITER_OK ) {
106
+ ca_iter_state_finish(&st_in);
107
+ rb_raise(rb_eRuntimeError,
108
+ "cumsum_ki: output init failed rc=%d", rc);
109
+ }
110
+
111
+ char *pi, *po;
112
+ boolean8_t *mi, *mo;
113
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
114
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
115
+ CA_SLAB_SCAN_T(uint8_t, double, st_in, pi, mi,
116
+ st_out, po, 0, acc += v; r = acc);
117
+ ca_iter_state_sync_slab(&st_out);
118
+ }
119
+ ca_iter_state_finish(&st_in);
120
+ ca_iter_state_finish(&st_out);
121
+ return vout;
122
+ }
123
+
124
+ static VALUE
125
+ cumsum_ki_native_i16 (VALUE self, CArray *ca, int axis)
126
+ {
127
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
128
+ INT2NUM(sizeof(double)));
129
+ CArray *co;
130
+ GetCArray(vout, co);
131
+
132
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
133
+ iteration is one "fiber" along that axis with acc reset to
134
+ INIT inside the macro. */
135
+ int8_t slab_axes[CA_RANK_MAX];
136
+ slab_axes[0] = (int8_t) axis;
137
+ ca_iter_state st_in, st_out;
138
+ int rc;
139
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
140
+ slab_axes, 1, 0);
141
+ if ( rc != CA_ITER_OK ) {
142
+ rb_raise(rb_eRuntimeError,
143
+ "cumsum_ki: input init failed rc=%d", rc);
144
+ }
145
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
146
+ slab_axes, 1, CA_KERNEL_WRITE);
147
+ if ( rc != CA_ITER_OK ) {
148
+ ca_iter_state_finish(&st_in);
149
+ rb_raise(rb_eRuntimeError,
150
+ "cumsum_ki: output init failed rc=%d", rc);
151
+ }
152
+
153
+ char *pi, *po;
154
+ boolean8_t *mi, *mo;
155
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
156
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
157
+ CA_SLAB_SCAN_T(int16_t, double, st_in, pi, mi,
158
+ st_out, po, 0, acc += v; r = acc);
159
+ ca_iter_state_sync_slab(&st_out);
160
+ }
161
+ ca_iter_state_finish(&st_in);
162
+ ca_iter_state_finish(&st_out);
163
+ return vout;
164
+ }
165
+
166
+ static VALUE
167
+ cumsum_ki_native_u16 (VALUE self, CArray *ca, int axis)
168
+ {
169
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
170
+ INT2NUM(sizeof(double)));
171
+ CArray *co;
172
+ GetCArray(vout, co);
173
+
174
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
175
+ iteration is one "fiber" along that axis with acc reset to
176
+ INIT inside the macro. */
177
+ int8_t slab_axes[CA_RANK_MAX];
178
+ slab_axes[0] = (int8_t) axis;
179
+ ca_iter_state st_in, st_out;
180
+ int rc;
181
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
182
+ slab_axes, 1, 0);
183
+ if ( rc != CA_ITER_OK ) {
184
+ rb_raise(rb_eRuntimeError,
185
+ "cumsum_ki: input init failed rc=%d", rc);
186
+ }
187
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
188
+ slab_axes, 1, CA_KERNEL_WRITE);
189
+ if ( rc != CA_ITER_OK ) {
190
+ ca_iter_state_finish(&st_in);
191
+ rb_raise(rb_eRuntimeError,
192
+ "cumsum_ki: output init failed rc=%d", rc);
193
+ }
194
+
195
+ char *pi, *po;
196
+ boolean8_t *mi, *mo;
197
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
198
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
199
+ CA_SLAB_SCAN_T(uint16_t, double, st_in, pi, mi,
200
+ st_out, po, 0, acc += v; r = acc);
201
+ ca_iter_state_sync_slab(&st_out);
202
+ }
203
+ ca_iter_state_finish(&st_in);
204
+ ca_iter_state_finish(&st_out);
205
+ return vout;
206
+ }
207
+
208
+ static VALUE
209
+ cumsum_ki_native_i32 (VALUE self, CArray *ca, int axis)
210
+ {
211
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
212
+ INT2NUM(sizeof(double)));
213
+ CArray *co;
214
+ GetCArray(vout, co);
215
+
216
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
217
+ iteration is one "fiber" along that axis with acc reset to
218
+ INIT inside the macro. */
219
+ int8_t slab_axes[CA_RANK_MAX];
220
+ slab_axes[0] = (int8_t) axis;
221
+ ca_iter_state st_in, st_out;
222
+ int rc;
223
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
224
+ slab_axes, 1, 0);
225
+ if ( rc != CA_ITER_OK ) {
226
+ rb_raise(rb_eRuntimeError,
227
+ "cumsum_ki: input init failed rc=%d", rc);
228
+ }
229
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
230
+ slab_axes, 1, CA_KERNEL_WRITE);
231
+ if ( rc != CA_ITER_OK ) {
232
+ ca_iter_state_finish(&st_in);
233
+ rb_raise(rb_eRuntimeError,
234
+ "cumsum_ki: output init failed rc=%d", rc);
235
+ }
236
+
237
+ char *pi, *po;
238
+ boolean8_t *mi, *mo;
239
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
240
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
241
+ CA_SLAB_SCAN_T(int32_t, double, st_in, pi, mi,
242
+ st_out, po, 0, acc += v; r = acc);
243
+ ca_iter_state_sync_slab(&st_out);
244
+ }
245
+ ca_iter_state_finish(&st_in);
246
+ ca_iter_state_finish(&st_out);
247
+ return vout;
248
+ }
249
+
250
+ static VALUE
251
+ cumsum_ki_native_u32 (VALUE self, CArray *ca, int axis)
252
+ {
253
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
254
+ INT2NUM(sizeof(double)));
255
+ CArray *co;
256
+ GetCArray(vout, co);
257
+
258
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
259
+ iteration is one "fiber" along that axis with acc reset to
260
+ INIT inside the macro. */
261
+ int8_t slab_axes[CA_RANK_MAX];
262
+ slab_axes[0] = (int8_t) axis;
263
+ ca_iter_state st_in, st_out;
264
+ int rc;
265
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
266
+ slab_axes, 1, 0);
267
+ if ( rc != CA_ITER_OK ) {
268
+ rb_raise(rb_eRuntimeError,
269
+ "cumsum_ki: input init failed rc=%d", rc);
270
+ }
271
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
272
+ slab_axes, 1, CA_KERNEL_WRITE);
273
+ if ( rc != CA_ITER_OK ) {
274
+ ca_iter_state_finish(&st_in);
275
+ rb_raise(rb_eRuntimeError,
276
+ "cumsum_ki: output init failed rc=%d", rc);
277
+ }
278
+
279
+ char *pi, *po;
280
+ boolean8_t *mi, *mo;
281
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
282
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
283
+ CA_SLAB_SCAN_T(uint32_t, double, st_in, pi, mi,
284
+ st_out, po, 0, acc += v; r = acc);
285
+ ca_iter_state_sync_slab(&st_out);
286
+ }
287
+ ca_iter_state_finish(&st_in);
288
+ ca_iter_state_finish(&st_out);
289
+ return vout;
290
+ }
291
+
292
+ static VALUE
293
+ cumsum_ki_native_i64 (VALUE self, CArray *ca, int axis)
294
+ {
295
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
296
+ INT2NUM(sizeof(double)));
297
+ CArray *co;
298
+ GetCArray(vout, co);
299
+
300
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
301
+ iteration is one "fiber" along that axis with acc reset to
302
+ INIT inside the macro. */
303
+ int8_t slab_axes[CA_RANK_MAX];
304
+ slab_axes[0] = (int8_t) axis;
305
+ ca_iter_state st_in, st_out;
306
+ int rc;
307
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
308
+ slab_axes, 1, 0);
309
+ if ( rc != CA_ITER_OK ) {
310
+ rb_raise(rb_eRuntimeError,
311
+ "cumsum_ki: input init failed rc=%d", rc);
312
+ }
313
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
314
+ slab_axes, 1, CA_KERNEL_WRITE);
315
+ if ( rc != CA_ITER_OK ) {
316
+ ca_iter_state_finish(&st_in);
317
+ rb_raise(rb_eRuntimeError,
318
+ "cumsum_ki: output init failed rc=%d", rc);
319
+ }
320
+
321
+ char *pi, *po;
322
+ boolean8_t *mi, *mo;
323
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
324
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
325
+ CA_SLAB_SCAN_T(int64_t, double, st_in, pi, mi,
326
+ st_out, po, 0, acc += v; r = acc);
327
+ ca_iter_state_sync_slab(&st_out);
328
+ }
329
+ ca_iter_state_finish(&st_in);
330
+ ca_iter_state_finish(&st_out);
331
+ return vout;
332
+ }
333
+
334
+ static VALUE
335
+ cumsum_ki_native_u64 (VALUE self, CArray *ca, int axis)
336
+ {
337
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
338
+ INT2NUM(sizeof(double)));
339
+ CArray *co;
340
+ GetCArray(vout, co);
341
+
342
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
343
+ iteration is one "fiber" along that axis with acc reset to
344
+ INIT inside the macro. */
345
+ int8_t slab_axes[CA_RANK_MAX];
346
+ slab_axes[0] = (int8_t) axis;
347
+ ca_iter_state st_in, st_out;
348
+ int rc;
349
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
350
+ slab_axes, 1, 0);
351
+ if ( rc != CA_ITER_OK ) {
352
+ rb_raise(rb_eRuntimeError,
353
+ "cumsum_ki: input init failed rc=%d", rc);
354
+ }
355
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
356
+ slab_axes, 1, CA_KERNEL_WRITE);
357
+ if ( rc != CA_ITER_OK ) {
358
+ ca_iter_state_finish(&st_in);
359
+ rb_raise(rb_eRuntimeError,
360
+ "cumsum_ki: output init failed rc=%d", rc);
361
+ }
362
+
363
+ char *pi, *po;
364
+ boolean8_t *mi, *mo;
365
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
366
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
367
+ CA_SLAB_SCAN_T(uint64_t, double, st_in, pi, mi,
368
+ st_out, po, 0, acc += v; r = acc);
369
+ ca_iter_state_sync_slab(&st_out);
370
+ }
371
+ ca_iter_state_finish(&st_in);
372
+ ca_iter_state_finish(&st_out);
373
+ return vout;
374
+ }
375
+
376
+ static VALUE
377
+ cumsum_ki_native_f32 (VALUE self, CArray *ca, int axis)
378
+ {
379
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
380
+ INT2NUM(sizeof(double)));
381
+ CArray *co;
382
+ GetCArray(vout, co);
383
+
384
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
385
+ iteration is one "fiber" along that axis with acc reset to
386
+ INIT inside the macro. */
387
+ int8_t slab_axes[CA_RANK_MAX];
388
+ slab_axes[0] = (int8_t) axis;
389
+ ca_iter_state st_in, st_out;
390
+ int rc;
391
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
392
+ slab_axes, 1, 0);
393
+ if ( rc != CA_ITER_OK ) {
394
+ rb_raise(rb_eRuntimeError,
395
+ "cumsum_ki: input init failed rc=%d", rc);
396
+ }
397
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
398
+ slab_axes, 1, CA_KERNEL_WRITE);
399
+ if ( rc != CA_ITER_OK ) {
400
+ ca_iter_state_finish(&st_in);
401
+ rb_raise(rb_eRuntimeError,
402
+ "cumsum_ki: output init failed rc=%d", rc);
403
+ }
404
+
405
+ char *pi, *po;
406
+ boolean8_t *mi, *mo;
407
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
408
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
409
+ CA_SLAB_SCAN_T(float, double, st_in, pi, mi,
410
+ st_out, po, 0, acc += v; r = acc);
411
+ ca_iter_state_sync_slab(&st_out);
412
+ }
413
+ ca_iter_state_finish(&st_in);
414
+ ca_iter_state_finish(&st_out);
415
+ return vout;
416
+ }
417
+
418
+ static VALUE
419
+ cumsum_ki_native_f64 (VALUE self, CArray *ca, int axis)
420
+ {
421
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
422
+ INT2NUM(sizeof(double)));
423
+ CArray *co;
424
+ GetCArray(vout, co);
425
+
426
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
427
+ iteration is one "fiber" along that axis with acc reset to
428
+ INIT inside the macro. */
429
+ int8_t slab_axes[CA_RANK_MAX];
430
+ slab_axes[0] = (int8_t) axis;
431
+ ca_iter_state st_in, st_out;
432
+ int rc;
433
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
434
+ slab_axes, 1, 0);
435
+ if ( rc != CA_ITER_OK ) {
436
+ rb_raise(rb_eRuntimeError,
437
+ "cumsum_ki: input init failed rc=%d", rc);
438
+ }
439
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
440
+ slab_axes, 1, CA_KERNEL_WRITE);
441
+ if ( rc != CA_ITER_OK ) {
442
+ ca_iter_state_finish(&st_in);
443
+ rb_raise(rb_eRuntimeError,
444
+ "cumsum_ki: output init failed rc=%d", rc);
445
+ }
446
+
447
+ char *pi, *po;
448
+ boolean8_t *mi, *mo;
449
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
450
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
451
+ CA_SLAB_SCAN_T(double, double, st_in, pi, mi,
452
+ st_out, po, 0, acc += v; r = acc);
453
+ ca_iter_state_sync_slab(&st_out);
454
+ }
455
+ ca_iter_state_finish(&st_in);
456
+ ca_iter_state_finish(&st_out);
457
+ return vout;
458
+ }
459
+
460
+ static VALUE
461
+ cumsum_ki_native_cmplx64 (VALUE self, CArray *ca, int axis)
462
+ {
463
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_CMPLX128),
464
+ INT2NUM(sizeof(cmplx128_t)));
465
+ CArray *co;
466
+ GetCArray(vout, co);
467
+
468
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
469
+ iteration is one "fiber" along that axis with acc reset to
470
+ INIT inside the macro. */
471
+ int8_t slab_axes[CA_RANK_MAX];
472
+ slab_axes[0] = (int8_t) axis;
473
+ ca_iter_state st_in, st_out;
474
+ int rc;
475
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
476
+ slab_axes, 1, 0);
477
+ if ( rc != CA_ITER_OK ) {
478
+ rb_raise(rb_eRuntimeError,
479
+ "cumsum_ki: input init failed rc=%d", rc);
480
+ }
481
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
482
+ slab_axes, 1, CA_KERNEL_WRITE);
483
+ if ( rc != CA_ITER_OK ) {
484
+ ca_iter_state_finish(&st_in);
485
+ rb_raise(rb_eRuntimeError,
486
+ "cumsum_ki: output init failed rc=%d", rc);
487
+ }
488
+
489
+ char *pi, *po;
490
+ boolean8_t *mi, *mo;
491
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
492
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
493
+ CA_SLAB_SCAN_T(cmplx64_t, cmplx128_t, st_in, pi, mi,
494
+ st_out, po, 0, acc += v; r = acc);
495
+ ca_iter_state_sync_slab(&st_out);
496
+ }
497
+ ca_iter_state_finish(&st_in);
498
+ ca_iter_state_finish(&st_out);
499
+ return vout;
500
+ }
501
+
502
+ static VALUE
503
+ cumsum_ki_native_cmplx128 (VALUE self, CArray *ca, int axis)
504
+ {
505
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_CMPLX128),
506
+ INT2NUM(sizeof(cmplx128_t)));
507
+ CArray *co;
508
+ GetCArray(vout, co);
509
+
510
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
511
+ iteration is one "fiber" along that axis with acc reset to
512
+ INIT inside the macro. */
513
+ int8_t slab_axes[CA_RANK_MAX];
514
+ slab_axes[0] = (int8_t) axis;
515
+ ca_iter_state st_in, st_out;
516
+ int rc;
517
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
518
+ slab_axes, 1, 0);
519
+ if ( rc != CA_ITER_OK ) {
520
+ rb_raise(rb_eRuntimeError,
521
+ "cumsum_ki: input init failed rc=%d", rc);
522
+ }
523
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
524
+ slab_axes, 1, CA_KERNEL_WRITE);
525
+ if ( rc != CA_ITER_OK ) {
526
+ ca_iter_state_finish(&st_in);
527
+ rb_raise(rb_eRuntimeError,
528
+ "cumsum_ki: output init failed rc=%d", rc);
529
+ }
530
+
531
+ char *pi, *po;
532
+ boolean8_t *mi, *mo;
533
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
534
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
535
+ CA_SLAB_SCAN_T(cmplx128_t, cmplx128_t, st_in, pi, mi,
536
+ st_out, po, 0, acc += v; r = acc);
537
+ ca_iter_state_sync_slab(&st_out);
538
+ }
539
+ ca_iter_state_finish(&st_in);
540
+ ca_iter_state_finish(&st_out);
541
+ return vout;
542
+ }
543
+
544
+ static VALUE
545
+ cumsum_ki_native_bool (VALUE self, CArray *ca, int axis)
546
+ {
547
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
548
+ INT2NUM(sizeof(uint64_t)));
549
+ CArray *co;
550
+ GetCArray(vout, co);
551
+
552
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
553
+ iteration is one "fiber" along that axis with acc reset to
554
+ INIT inside the macro. */
555
+ int8_t slab_axes[CA_RANK_MAX];
556
+ slab_axes[0] = (int8_t) axis;
557
+ ca_iter_state st_in, st_out;
558
+ int rc;
559
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
560
+ slab_axes, 1, 0);
561
+ if ( rc != CA_ITER_OK ) {
562
+ rb_raise(rb_eRuntimeError,
563
+ "cumsum_ki: input init failed rc=%d", rc);
564
+ }
565
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
566
+ slab_axes, 1, CA_KERNEL_WRITE);
567
+ if ( rc != CA_ITER_OK ) {
568
+ ca_iter_state_finish(&st_in);
569
+ rb_raise(rb_eRuntimeError,
570
+ "cumsum_ki: output init failed rc=%d", rc);
571
+ }
572
+
573
+ char *pi, *po;
574
+ boolean8_t *mi, *mo;
575
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
576
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
577
+ CA_SLAB_SCAN_T(boolean8_t, uint64_t, st_in, pi, mi,
578
+ st_out, po, 0, acc += v; r = acc);
579
+ ca_iter_state_sync_slab(&st_out);
580
+ }
581
+ ca_iter_state_finish(&st_in);
582
+ ca_iter_state_finish(&st_out);
583
+ return vout;
584
+ }
585
+
586
+ static VALUE
587
+ cumsum_ki_native_object (VALUE self, CArray *ca, int axis)
588
+ {
589
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_OBJECT),
590
+ INT2NUM(sizeof(VALUE)));
591
+ CArray *co;
592
+ GetCArray(vout, co);
593
+
594
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
595
+ iteration is one "fiber" along that axis with acc reset to
596
+ INIT inside the macro. */
597
+ int8_t slab_axes[CA_RANK_MAX];
598
+ slab_axes[0] = (int8_t) axis;
599
+ ca_iter_state st_in, st_out;
600
+ int rc;
601
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
602
+ slab_axes, 1, 0);
603
+ if ( rc != CA_ITER_OK ) {
604
+ rb_raise(rb_eRuntimeError,
605
+ "cumsum_ki: input init failed rc=%d", rc);
606
+ }
607
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
608
+ slab_axes, 1, CA_KERNEL_WRITE);
609
+ if ( rc != CA_ITER_OK ) {
610
+ ca_iter_state_finish(&st_in);
611
+ rb_raise(rb_eRuntimeError,
612
+ "cumsum_ki: output init failed rc=%d", rc);
613
+ }
614
+
615
+ char *pi, *po;
616
+ boolean8_t *mi, *mo;
617
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
618
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
619
+ CA_SLAB_SCAN_T(VALUE, VALUE, st_in, pi, mi,
620
+ st_out, po, INT2FIX(0), acc = rb_funcall(acc, rb_intern("+"), 1, v); r = acc);
621
+ ca_iter_state_sync_slab(&st_out);
622
+ }
623
+ ca_iter_state_finish(&st_in);
624
+ ca_iter_state_finish(&st_out);
625
+ return vout;
626
+ }
627
+
628
+ static VALUE
629
+ rb_ca_cumsum_ki (int argc, VALUE *argv, VALUE self)
630
+ {
631
+ CArray *src;
632
+ GetCArray(self, src);
633
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
634
+ volatile VALUE raxis = Qnil;
635
+ rb_scan_options(ropt, "axis", &raxis);
636
+ if ( argc > 0 ) {
637
+ rb_raise(rb_eArgError, "cumsum_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.cumsum(axis: 0)", argc);
638
+ }
639
+ if ( NIL_P(raxis) ) {
640
+ volatile VALUE vflat = rb_funcall(self, rb_intern("flatten"), 0);
641
+ CArray *fsrc;
642
+ GetCArray(vflat, fsrc);
643
+ switch ( fsrc->data_type ) {
644
+ case CA_INT8: return cumsum_ki_native_i8(vflat, fsrc, 0);
645
+ case CA_UINT8: return cumsum_ki_native_u8(vflat, fsrc, 0);
646
+ case CA_INT16: return cumsum_ki_native_i16(vflat, fsrc, 0);
647
+ case CA_UINT16: return cumsum_ki_native_u16(vflat, fsrc, 0);
648
+ case CA_INT32: return cumsum_ki_native_i32(vflat, fsrc, 0);
649
+ case CA_UINT32: return cumsum_ki_native_u32(vflat, fsrc, 0);
650
+ case CA_INT64: return cumsum_ki_native_i64(vflat, fsrc, 0);
651
+ case CA_UINT64: return cumsum_ki_native_u64(vflat, fsrc, 0);
652
+ case CA_FLOAT32: return cumsum_ki_native_f32(vflat, fsrc, 0);
653
+ case CA_FLOAT64: return cumsum_ki_native_f64(vflat, fsrc, 0);
654
+ case CA_CMPLX64: return cumsum_ki_native_cmplx64(vflat, fsrc, 0);
655
+ case CA_CMPLX128: return cumsum_ki_native_cmplx128(vflat, fsrc, 0);
656
+ case CA_BOOLEAN: return cumsum_ki_native_bool(vflat, fsrc, 0);
657
+ case CA_OBJECT: return cumsum_ki_native_object(vflat, fsrc, 0);
658
+ default:
659
+ rb_raise(rb_eCADataTypeError, "cumsum_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, cmplx64, cmplx128, bool, object)", ca_type_name[fsrc->data_type]);
660
+ }
661
+ }
662
+ if ( TYPE(raxis) == T_ARRAY ) {
663
+ rb_raise(rb_eArgError, "cumsum_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.cumsum(axis: 0).cumsum(axis: 1)");
664
+ }
665
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
666
+ rb_raise(rb_eTypeError, "cumsum_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
667
+ }
668
+ int axis = NUM2INT(raxis);
669
+ if ( axis < 0 ) axis += src->ndim;
670
+ if ( axis < 0 || axis >= src->ndim ) {
671
+ rb_raise(rb_eArgError, "cumsum_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
672
+ }
673
+ switch ( src->data_type ) {
674
+ case CA_INT8: return cumsum_ki_native_i8(self, src, axis);
675
+ case CA_UINT8: return cumsum_ki_native_u8(self, src, axis);
676
+ case CA_INT16: return cumsum_ki_native_i16(self, src, axis);
677
+ case CA_UINT16: return cumsum_ki_native_u16(self, src, axis);
678
+ case CA_INT32: return cumsum_ki_native_i32(self, src, axis);
679
+ case CA_UINT32: return cumsum_ki_native_u32(self, src, axis);
680
+ case CA_INT64: return cumsum_ki_native_i64(self, src, axis);
681
+ case CA_UINT64: return cumsum_ki_native_u64(self, src, axis);
682
+ case CA_FLOAT32: return cumsum_ki_native_f32(self, src, axis);
683
+ case CA_FLOAT64: return cumsum_ki_native_f64(self, src, axis);
684
+ case CA_CMPLX64: return cumsum_ki_native_cmplx64(self, src, axis);
685
+ case CA_CMPLX128: return cumsum_ki_native_cmplx128(self, src, axis);
686
+ case CA_BOOLEAN: return cumsum_ki_native_bool(self, src, axis);
687
+ case CA_OBJECT: return cumsum_ki_native_object(self, src, axis);
688
+ default:
689
+ rb_raise(rb_eCADataTypeError, "cumsum_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, cmplx64, cmplx128, bool, object)", ca_type_name[src->data_type]);
690
+ }
691
+ return Qnil; /* unreachable */
692
+ }
693
+
694
+ /* ===== cumprod_ki ============================================ */
695
+
696
+ static VALUE
697
+ cumprod_ki_native_i8 (VALUE self, CArray *ca, int axis)
698
+ {
699
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
700
+ INT2NUM(sizeof(double)));
701
+ CArray *co;
702
+ GetCArray(vout, co);
703
+
704
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
705
+ iteration is one "fiber" along that axis with acc reset to
706
+ INIT inside the macro. */
707
+ int8_t slab_axes[CA_RANK_MAX];
708
+ slab_axes[0] = (int8_t) axis;
709
+ ca_iter_state st_in, st_out;
710
+ int rc;
711
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
712
+ slab_axes, 1, 0);
713
+ if ( rc != CA_ITER_OK ) {
714
+ rb_raise(rb_eRuntimeError,
715
+ "cumprod_ki: input init failed rc=%d", rc);
716
+ }
717
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
718
+ slab_axes, 1, CA_KERNEL_WRITE);
719
+ if ( rc != CA_ITER_OK ) {
720
+ ca_iter_state_finish(&st_in);
721
+ rb_raise(rb_eRuntimeError,
722
+ "cumprod_ki: output init failed rc=%d", rc);
723
+ }
724
+
725
+ char *pi, *po;
726
+ boolean8_t *mi, *mo;
727
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
728
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
729
+ CA_SLAB_SCAN_T(int8_t, double, st_in, pi, mi,
730
+ st_out, po, 1, acc *= v; r = acc);
731
+ ca_iter_state_sync_slab(&st_out);
732
+ }
733
+ ca_iter_state_finish(&st_in);
734
+ ca_iter_state_finish(&st_out);
735
+ return vout;
736
+ }
737
+
738
+ static VALUE
739
+ cumprod_ki_native_u8 (VALUE self, CArray *ca, int axis)
740
+ {
741
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
742
+ INT2NUM(sizeof(double)));
743
+ CArray *co;
744
+ GetCArray(vout, co);
745
+
746
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
747
+ iteration is one "fiber" along that axis with acc reset to
748
+ INIT inside the macro. */
749
+ int8_t slab_axes[CA_RANK_MAX];
750
+ slab_axes[0] = (int8_t) axis;
751
+ ca_iter_state st_in, st_out;
752
+ int rc;
753
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
754
+ slab_axes, 1, 0);
755
+ if ( rc != CA_ITER_OK ) {
756
+ rb_raise(rb_eRuntimeError,
757
+ "cumprod_ki: input init failed rc=%d", rc);
758
+ }
759
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
760
+ slab_axes, 1, CA_KERNEL_WRITE);
761
+ if ( rc != CA_ITER_OK ) {
762
+ ca_iter_state_finish(&st_in);
763
+ rb_raise(rb_eRuntimeError,
764
+ "cumprod_ki: output init failed rc=%d", rc);
765
+ }
766
+
767
+ char *pi, *po;
768
+ boolean8_t *mi, *mo;
769
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
770
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
771
+ CA_SLAB_SCAN_T(uint8_t, double, st_in, pi, mi,
772
+ st_out, po, 1, acc *= v; r = acc);
773
+ ca_iter_state_sync_slab(&st_out);
774
+ }
775
+ ca_iter_state_finish(&st_in);
776
+ ca_iter_state_finish(&st_out);
777
+ return vout;
778
+ }
779
+
780
+ static VALUE
781
+ cumprod_ki_native_i16 (VALUE self, CArray *ca, int axis)
782
+ {
783
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
784
+ INT2NUM(sizeof(double)));
785
+ CArray *co;
786
+ GetCArray(vout, co);
787
+
788
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
789
+ iteration is one "fiber" along that axis with acc reset to
790
+ INIT inside the macro. */
791
+ int8_t slab_axes[CA_RANK_MAX];
792
+ slab_axes[0] = (int8_t) axis;
793
+ ca_iter_state st_in, st_out;
794
+ int rc;
795
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
796
+ slab_axes, 1, 0);
797
+ if ( rc != CA_ITER_OK ) {
798
+ rb_raise(rb_eRuntimeError,
799
+ "cumprod_ki: input init failed rc=%d", rc);
800
+ }
801
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
802
+ slab_axes, 1, CA_KERNEL_WRITE);
803
+ if ( rc != CA_ITER_OK ) {
804
+ ca_iter_state_finish(&st_in);
805
+ rb_raise(rb_eRuntimeError,
806
+ "cumprod_ki: output init failed rc=%d", rc);
807
+ }
808
+
809
+ char *pi, *po;
810
+ boolean8_t *mi, *mo;
811
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
812
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
813
+ CA_SLAB_SCAN_T(int16_t, double, st_in, pi, mi,
814
+ st_out, po, 1, acc *= v; r = acc);
815
+ ca_iter_state_sync_slab(&st_out);
816
+ }
817
+ ca_iter_state_finish(&st_in);
818
+ ca_iter_state_finish(&st_out);
819
+ return vout;
820
+ }
821
+
822
+ static VALUE
823
+ cumprod_ki_native_u16 (VALUE self, CArray *ca, int axis)
824
+ {
825
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
826
+ INT2NUM(sizeof(double)));
827
+ CArray *co;
828
+ GetCArray(vout, co);
829
+
830
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
831
+ iteration is one "fiber" along that axis with acc reset to
832
+ INIT inside the macro. */
833
+ int8_t slab_axes[CA_RANK_MAX];
834
+ slab_axes[0] = (int8_t) axis;
835
+ ca_iter_state st_in, st_out;
836
+ int rc;
837
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
838
+ slab_axes, 1, 0);
839
+ if ( rc != CA_ITER_OK ) {
840
+ rb_raise(rb_eRuntimeError,
841
+ "cumprod_ki: input init failed rc=%d", rc);
842
+ }
843
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
844
+ slab_axes, 1, CA_KERNEL_WRITE);
845
+ if ( rc != CA_ITER_OK ) {
846
+ ca_iter_state_finish(&st_in);
847
+ rb_raise(rb_eRuntimeError,
848
+ "cumprod_ki: output init failed rc=%d", rc);
849
+ }
850
+
851
+ char *pi, *po;
852
+ boolean8_t *mi, *mo;
853
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
854
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
855
+ CA_SLAB_SCAN_T(uint16_t, double, st_in, pi, mi,
856
+ st_out, po, 1, acc *= v; r = acc);
857
+ ca_iter_state_sync_slab(&st_out);
858
+ }
859
+ ca_iter_state_finish(&st_in);
860
+ ca_iter_state_finish(&st_out);
861
+ return vout;
862
+ }
863
+
864
+ static VALUE
865
+ cumprod_ki_native_i32 (VALUE self, CArray *ca, int axis)
866
+ {
867
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
868
+ INT2NUM(sizeof(double)));
869
+ CArray *co;
870
+ GetCArray(vout, co);
871
+
872
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
873
+ iteration is one "fiber" along that axis with acc reset to
874
+ INIT inside the macro. */
875
+ int8_t slab_axes[CA_RANK_MAX];
876
+ slab_axes[0] = (int8_t) axis;
877
+ ca_iter_state st_in, st_out;
878
+ int rc;
879
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
880
+ slab_axes, 1, 0);
881
+ if ( rc != CA_ITER_OK ) {
882
+ rb_raise(rb_eRuntimeError,
883
+ "cumprod_ki: input init failed rc=%d", rc);
884
+ }
885
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
886
+ slab_axes, 1, CA_KERNEL_WRITE);
887
+ if ( rc != CA_ITER_OK ) {
888
+ ca_iter_state_finish(&st_in);
889
+ rb_raise(rb_eRuntimeError,
890
+ "cumprod_ki: output init failed rc=%d", rc);
891
+ }
892
+
893
+ char *pi, *po;
894
+ boolean8_t *mi, *mo;
895
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
896
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
897
+ CA_SLAB_SCAN_T(int32_t, double, st_in, pi, mi,
898
+ st_out, po, 1, acc *= v; r = acc);
899
+ ca_iter_state_sync_slab(&st_out);
900
+ }
901
+ ca_iter_state_finish(&st_in);
902
+ ca_iter_state_finish(&st_out);
903
+ return vout;
904
+ }
905
+
906
+ static VALUE
907
+ cumprod_ki_native_u32 (VALUE self, CArray *ca, int axis)
908
+ {
909
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
910
+ INT2NUM(sizeof(double)));
911
+ CArray *co;
912
+ GetCArray(vout, co);
913
+
914
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
915
+ iteration is one "fiber" along that axis with acc reset to
916
+ INIT inside the macro. */
917
+ int8_t slab_axes[CA_RANK_MAX];
918
+ slab_axes[0] = (int8_t) axis;
919
+ ca_iter_state st_in, st_out;
920
+ int rc;
921
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
922
+ slab_axes, 1, 0);
923
+ if ( rc != CA_ITER_OK ) {
924
+ rb_raise(rb_eRuntimeError,
925
+ "cumprod_ki: input init failed rc=%d", rc);
926
+ }
927
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
928
+ slab_axes, 1, CA_KERNEL_WRITE);
929
+ if ( rc != CA_ITER_OK ) {
930
+ ca_iter_state_finish(&st_in);
931
+ rb_raise(rb_eRuntimeError,
932
+ "cumprod_ki: output init failed rc=%d", rc);
933
+ }
934
+
935
+ char *pi, *po;
936
+ boolean8_t *mi, *mo;
937
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
938
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
939
+ CA_SLAB_SCAN_T(uint32_t, double, st_in, pi, mi,
940
+ st_out, po, 1, acc *= v; r = acc);
941
+ ca_iter_state_sync_slab(&st_out);
942
+ }
943
+ ca_iter_state_finish(&st_in);
944
+ ca_iter_state_finish(&st_out);
945
+ return vout;
946
+ }
947
+
948
+ static VALUE
949
+ cumprod_ki_native_i64 (VALUE self, CArray *ca, int axis)
950
+ {
951
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
952
+ INT2NUM(sizeof(double)));
953
+ CArray *co;
954
+ GetCArray(vout, co);
955
+
956
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
957
+ iteration is one "fiber" along that axis with acc reset to
958
+ INIT inside the macro. */
959
+ int8_t slab_axes[CA_RANK_MAX];
960
+ slab_axes[0] = (int8_t) axis;
961
+ ca_iter_state st_in, st_out;
962
+ int rc;
963
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
964
+ slab_axes, 1, 0);
965
+ if ( rc != CA_ITER_OK ) {
966
+ rb_raise(rb_eRuntimeError,
967
+ "cumprod_ki: input init failed rc=%d", rc);
968
+ }
969
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
970
+ slab_axes, 1, CA_KERNEL_WRITE);
971
+ if ( rc != CA_ITER_OK ) {
972
+ ca_iter_state_finish(&st_in);
973
+ rb_raise(rb_eRuntimeError,
974
+ "cumprod_ki: output init failed rc=%d", rc);
975
+ }
976
+
977
+ char *pi, *po;
978
+ boolean8_t *mi, *mo;
979
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
980
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
981
+ CA_SLAB_SCAN_T(int64_t, double, st_in, pi, mi,
982
+ st_out, po, 1, acc *= v; r = acc);
983
+ ca_iter_state_sync_slab(&st_out);
984
+ }
985
+ ca_iter_state_finish(&st_in);
986
+ ca_iter_state_finish(&st_out);
987
+ return vout;
988
+ }
989
+
990
+ static VALUE
991
+ cumprod_ki_native_u64 (VALUE self, CArray *ca, int axis)
992
+ {
993
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
994
+ INT2NUM(sizeof(double)));
995
+ CArray *co;
996
+ GetCArray(vout, co);
997
+
998
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
999
+ iteration is one "fiber" along that axis with acc reset to
1000
+ INIT inside the macro. */
1001
+ int8_t slab_axes[CA_RANK_MAX];
1002
+ slab_axes[0] = (int8_t) axis;
1003
+ ca_iter_state st_in, st_out;
1004
+ int rc;
1005
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1006
+ slab_axes, 1, 0);
1007
+ if ( rc != CA_ITER_OK ) {
1008
+ rb_raise(rb_eRuntimeError,
1009
+ "cumprod_ki: input init failed rc=%d", rc);
1010
+ }
1011
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1012
+ slab_axes, 1, CA_KERNEL_WRITE);
1013
+ if ( rc != CA_ITER_OK ) {
1014
+ ca_iter_state_finish(&st_in);
1015
+ rb_raise(rb_eRuntimeError,
1016
+ "cumprod_ki: output init failed rc=%d", rc);
1017
+ }
1018
+
1019
+ char *pi, *po;
1020
+ boolean8_t *mi, *mo;
1021
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1022
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1023
+ CA_SLAB_SCAN_T(uint64_t, double, st_in, pi, mi,
1024
+ st_out, po, 1, acc *= v; r = acc);
1025
+ ca_iter_state_sync_slab(&st_out);
1026
+ }
1027
+ ca_iter_state_finish(&st_in);
1028
+ ca_iter_state_finish(&st_out);
1029
+ return vout;
1030
+ }
1031
+
1032
+ static VALUE
1033
+ cumprod_ki_native_f32 (VALUE self, CArray *ca, int axis)
1034
+ {
1035
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
1036
+ INT2NUM(sizeof(double)));
1037
+ CArray *co;
1038
+ GetCArray(vout, co);
1039
+
1040
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1041
+ iteration is one "fiber" along that axis with acc reset to
1042
+ INIT inside the macro. */
1043
+ int8_t slab_axes[CA_RANK_MAX];
1044
+ slab_axes[0] = (int8_t) axis;
1045
+ ca_iter_state st_in, st_out;
1046
+ int rc;
1047
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1048
+ slab_axes, 1, 0);
1049
+ if ( rc != CA_ITER_OK ) {
1050
+ rb_raise(rb_eRuntimeError,
1051
+ "cumprod_ki: input init failed rc=%d", rc);
1052
+ }
1053
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1054
+ slab_axes, 1, CA_KERNEL_WRITE);
1055
+ if ( rc != CA_ITER_OK ) {
1056
+ ca_iter_state_finish(&st_in);
1057
+ rb_raise(rb_eRuntimeError,
1058
+ "cumprod_ki: output init failed rc=%d", rc);
1059
+ }
1060
+
1061
+ char *pi, *po;
1062
+ boolean8_t *mi, *mo;
1063
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1064
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1065
+ CA_SLAB_SCAN_T(float, double, st_in, pi, mi,
1066
+ st_out, po, 1, acc *= v; r = acc);
1067
+ ca_iter_state_sync_slab(&st_out);
1068
+ }
1069
+ ca_iter_state_finish(&st_in);
1070
+ ca_iter_state_finish(&st_out);
1071
+ return vout;
1072
+ }
1073
+
1074
+ static VALUE
1075
+ cumprod_ki_native_f64 (VALUE self, CArray *ca, int axis)
1076
+ {
1077
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
1078
+ INT2NUM(sizeof(double)));
1079
+ CArray *co;
1080
+ GetCArray(vout, co);
1081
+
1082
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1083
+ iteration is one "fiber" along that axis with acc reset to
1084
+ INIT inside the macro. */
1085
+ int8_t slab_axes[CA_RANK_MAX];
1086
+ slab_axes[0] = (int8_t) axis;
1087
+ ca_iter_state st_in, st_out;
1088
+ int rc;
1089
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1090
+ slab_axes, 1, 0);
1091
+ if ( rc != CA_ITER_OK ) {
1092
+ rb_raise(rb_eRuntimeError,
1093
+ "cumprod_ki: input init failed rc=%d", rc);
1094
+ }
1095
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1096
+ slab_axes, 1, CA_KERNEL_WRITE);
1097
+ if ( rc != CA_ITER_OK ) {
1098
+ ca_iter_state_finish(&st_in);
1099
+ rb_raise(rb_eRuntimeError,
1100
+ "cumprod_ki: output init failed rc=%d", rc);
1101
+ }
1102
+
1103
+ char *pi, *po;
1104
+ boolean8_t *mi, *mo;
1105
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1106
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1107
+ CA_SLAB_SCAN_T(double, double, st_in, pi, mi,
1108
+ st_out, po, 1, acc *= v; r = acc);
1109
+ ca_iter_state_sync_slab(&st_out);
1110
+ }
1111
+ ca_iter_state_finish(&st_in);
1112
+ ca_iter_state_finish(&st_out);
1113
+ return vout;
1114
+ }
1115
+
1116
+ static VALUE
1117
+ cumprod_ki_native_cmplx64 (VALUE self, CArray *ca, int axis)
1118
+ {
1119
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_CMPLX128),
1120
+ INT2NUM(sizeof(cmplx128_t)));
1121
+ CArray *co;
1122
+ GetCArray(vout, co);
1123
+
1124
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1125
+ iteration is one "fiber" along that axis with acc reset to
1126
+ INIT inside the macro. */
1127
+ int8_t slab_axes[CA_RANK_MAX];
1128
+ slab_axes[0] = (int8_t) axis;
1129
+ ca_iter_state st_in, st_out;
1130
+ int rc;
1131
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1132
+ slab_axes, 1, 0);
1133
+ if ( rc != CA_ITER_OK ) {
1134
+ rb_raise(rb_eRuntimeError,
1135
+ "cumprod_ki: input init failed rc=%d", rc);
1136
+ }
1137
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1138
+ slab_axes, 1, CA_KERNEL_WRITE);
1139
+ if ( rc != CA_ITER_OK ) {
1140
+ ca_iter_state_finish(&st_in);
1141
+ rb_raise(rb_eRuntimeError,
1142
+ "cumprod_ki: output init failed rc=%d", rc);
1143
+ }
1144
+
1145
+ char *pi, *po;
1146
+ boolean8_t *mi, *mo;
1147
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1148
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1149
+ CA_SLAB_SCAN_T(cmplx64_t, cmplx128_t, st_in, pi, mi,
1150
+ st_out, po, 1, acc *= v; r = acc);
1151
+ ca_iter_state_sync_slab(&st_out);
1152
+ }
1153
+ ca_iter_state_finish(&st_in);
1154
+ ca_iter_state_finish(&st_out);
1155
+ return vout;
1156
+ }
1157
+
1158
+ static VALUE
1159
+ cumprod_ki_native_cmplx128 (VALUE self, CArray *ca, int axis)
1160
+ {
1161
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_CMPLX128),
1162
+ INT2NUM(sizeof(cmplx128_t)));
1163
+ CArray *co;
1164
+ GetCArray(vout, co);
1165
+
1166
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1167
+ iteration is one "fiber" along that axis with acc reset to
1168
+ INIT inside the macro. */
1169
+ int8_t slab_axes[CA_RANK_MAX];
1170
+ slab_axes[0] = (int8_t) axis;
1171
+ ca_iter_state st_in, st_out;
1172
+ int rc;
1173
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1174
+ slab_axes, 1, 0);
1175
+ if ( rc != CA_ITER_OK ) {
1176
+ rb_raise(rb_eRuntimeError,
1177
+ "cumprod_ki: input init failed rc=%d", rc);
1178
+ }
1179
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1180
+ slab_axes, 1, CA_KERNEL_WRITE);
1181
+ if ( rc != CA_ITER_OK ) {
1182
+ ca_iter_state_finish(&st_in);
1183
+ rb_raise(rb_eRuntimeError,
1184
+ "cumprod_ki: output init failed rc=%d", rc);
1185
+ }
1186
+
1187
+ char *pi, *po;
1188
+ boolean8_t *mi, *mo;
1189
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1190
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1191
+ CA_SLAB_SCAN_T(cmplx128_t, cmplx128_t, st_in, pi, mi,
1192
+ st_out, po, 1, acc *= v; r = acc);
1193
+ ca_iter_state_sync_slab(&st_out);
1194
+ }
1195
+ ca_iter_state_finish(&st_in);
1196
+ ca_iter_state_finish(&st_out);
1197
+ return vout;
1198
+ }
1199
+
1200
+ static VALUE
1201
+ cumprod_ki_native_bool (VALUE self, CArray *ca, int axis)
1202
+ {
1203
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
1204
+ INT2NUM(sizeof(uint64_t)));
1205
+ CArray *co;
1206
+ GetCArray(vout, co);
1207
+
1208
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1209
+ iteration is one "fiber" along that axis with acc reset to
1210
+ INIT inside the macro. */
1211
+ int8_t slab_axes[CA_RANK_MAX];
1212
+ slab_axes[0] = (int8_t) axis;
1213
+ ca_iter_state st_in, st_out;
1214
+ int rc;
1215
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1216
+ slab_axes, 1, 0);
1217
+ if ( rc != CA_ITER_OK ) {
1218
+ rb_raise(rb_eRuntimeError,
1219
+ "cumprod_ki: input init failed rc=%d", rc);
1220
+ }
1221
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1222
+ slab_axes, 1, CA_KERNEL_WRITE);
1223
+ if ( rc != CA_ITER_OK ) {
1224
+ ca_iter_state_finish(&st_in);
1225
+ rb_raise(rb_eRuntimeError,
1226
+ "cumprod_ki: output init failed rc=%d", rc);
1227
+ }
1228
+
1229
+ char *pi, *po;
1230
+ boolean8_t *mi, *mo;
1231
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1232
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1233
+ CA_SLAB_SCAN_T(boolean8_t, uint64_t, st_in, pi, mi,
1234
+ st_out, po, 1, acc *= v; r = acc);
1235
+ ca_iter_state_sync_slab(&st_out);
1236
+ }
1237
+ ca_iter_state_finish(&st_in);
1238
+ ca_iter_state_finish(&st_out);
1239
+ return vout;
1240
+ }
1241
+
1242
+ static VALUE
1243
+ cumprod_ki_native_object (VALUE self, CArray *ca, int axis)
1244
+ {
1245
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_OBJECT),
1246
+ INT2NUM(sizeof(VALUE)));
1247
+ CArray *co;
1248
+ GetCArray(vout, co);
1249
+
1250
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1251
+ iteration is one "fiber" along that axis with acc reset to
1252
+ INIT inside the macro. */
1253
+ int8_t slab_axes[CA_RANK_MAX];
1254
+ slab_axes[0] = (int8_t) axis;
1255
+ ca_iter_state st_in, st_out;
1256
+ int rc;
1257
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1258
+ slab_axes, 1, 0);
1259
+ if ( rc != CA_ITER_OK ) {
1260
+ rb_raise(rb_eRuntimeError,
1261
+ "cumprod_ki: input init failed rc=%d", rc);
1262
+ }
1263
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1264
+ slab_axes, 1, CA_KERNEL_WRITE);
1265
+ if ( rc != CA_ITER_OK ) {
1266
+ ca_iter_state_finish(&st_in);
1267
+ rb_raise(rb_eRuntimeError,
1268
+ "cumprod_ki: output init failed rc=%d", rc);
1269
+ }
1270
+
1271
+ char *pi, *po;
1272
+ boolean8_t *mi, *mo;
1273
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1274
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1275
+ CA_SLAB_SCAN_T(VALUE, VALUE, st_in, pi, mi,
1276
+ st_out, po, INT2FIX(1), acc = rb_funcall(acc, rb_intern("*"), 1, v); r = acc);
1277
+ ca_iter_state_sync_slab(&st_out);
1278
+ }
1279
+ ca_iter_state_finish(&st_in);
1280
+ ca_iter_state_finish(&st_out);
1281
+ return vout;
1282
+ }
1283
+
1284
+ static VALUE
1285
+ rb_ca_cumprod_ki (int argc, VALUE *argv, VALUE self)
1286
+ {
1287
+ CArray *src;
1288
+ GetCArray(self, src);
1289
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
1290
+ volatile VALUE raxis = Qnil;
1291
+ rb_scan_options(ropt, "axis", &raxis);
1292
+ if ( argc > 0 ) {
1293
+ rb_raise(rb_eArgError, "cumprod_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.cumprod(axis: 0)", argc);
1294
+ }
1295
+ if ( NIL_P(raxis) ) {
1296
+ volatile VALUE vflat = rb_funcall(self, rb_intern("flatten"), 0);
1297
+ CArray *fsrc;
1298
+ GetCArray(vflat, fsrc);
1299
+ switch ( fsrc->data_type ) {
1300
+ case CA_INT8: return cumprod_ki_native_i8(vflat, fsrc, 0);
1301
+ case CA_UINT8: return cumprod_ki_native_u8(vflat, fsrc, 0);
1302
+ case CA_INT16: return cumprod_ki_native_i16(vflat, fsrc, 0);
1303
+ case CA_UINT16: return cumprod_ki_native_u16(vflat, fsrc, 0);
1304
+ case CA_INT32: return cumprod_ki_native_i32(vflat, fsrc, 0);
1305
+ case CA_UINT32: return cumprod_ki_native_u32(vflat, fsrc, 0);
1306
+ case CA_INT64: return cumprod_ki_native_i64(vflat, fsrc, 0);
1307
+ case CA_UINT64: return cumprod_ki_native_u64(vflat, fsrc, 0);
1308
+ case CA_FLOAT32: return cumprod_ki_native_f32(vflat, fsrc, 0);
1309
+ case CA_FLOAT64: return cumprod_ki_native_f64(vflat, fsrc, 0);
1310
+ case CA_CMPLX64: return cumprod_ki_native_cmplx64(vflat, fsrc, 0);
1311
+ case CA_CMPLX128: return cumprod_ki_native_cmplx128(vflat, fsrc, 0);
1312
+ case CA_BOOLEAN: return cumprod_ki_native_bool(vflat, fsrc, 0);
1313
+ case CA_OBJECT: return cumprod_ki_native_object(vflat, fsrc, 0);
1314
+ default:
1315
+ rb_raise(rb_eCADataTypeError, "cumprod_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, cmplx64, cmplx128, bool, object)", ca_type_name[fsrc->data_type]);
1316
+ }
1317
+ }
1318
+ if ( TYPE(raxis) == T_ARRAY ) {
1319
+ rb_raise(rb_eArgError, "cumprod_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.cumprod(axis: 0).cumprod(axis: 1)");
1320
+ }
1321
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
1322
+ rb_raise(rb_eTypeError, "cumprod_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
1323
+ }
1324
+ int axis = NUM2INT(raxis);
1325
+ if ( axis < 0 ) axis += src->ndim;
1326
+ if ( axis < 0 || axis >= src->ndim ) {
1327
+ rb_raise(rb_eArgError, "cumprod_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
1328
+ }
1329
+ switch ( src->data_type ) {
1330
+ case CA_INT8: return cumprod_ki_native_i8(self, src, axis);
1331
+ case CA_UINT8: return cumprod_ki_native_u8(self, src, axis);
1332
+ case CA_INT16: return cumprod_ki_native_i16(self, src, axis);
1333
+ case CA_UINT16: return cumprod_ki_native_u16(self, src, axis);
1334
+ case CA_INT32: return cumprod_ki_native_i32(self, src, axis);
1335
+ case CA_UINT32: return cumprod_ki_native_u32(self, src, axis);
1336
+ case CA_INT64: return cumprod_ki_native_i64(self, src, axis);
1337
+ case CA_UINT64: return cumprod_ki_native_u64(self, src, axis);
1338
+ case CA_FLOAT32: return cumprod_ki_native_f32(self, src, axis);
1339
+ case CA_FLOAT64: return cumprod_ki_native_f64(self, src, axis);
1340
+ case CA_CMPLX64: return cumprod_ki_native_cmplx64(self, src, axis);
1341
+ case CA_CMPLX128: return cumprod_ki_native_cmplx128(self, src, axis);
1342
+ case CA_BOOLEAN: return cumprod_ki_native_bool(self, src, axis);
1343
+ case CA_OBJECT: return cumprod_ki_native_object(self, src, axis);
1344
+ default:
1345
+ rb_raise(rb_eCADataTypeError, "cumprod_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, cmplx64, cmplx128, bool, object)", ca_type_name[src->data_type]);
1346
+ }
1347
+ return Qnil; /* unreachable */
1348
+ }
1349
+
1350
+ /* ===== cummax_ki ============================================ */
1351
+
1352
+ static VALUE
1353
+ cummax_ki_native_i8 (VALUE self, CArray *ca, int axis)
1354
+ {
1355
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT8),
1356
+ INT2NUM(sizeof(int8_t)));
1357
+ CArray *co;
1358
+ GetCArray(vout, co);
1359
+
1360
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1361
+ iteration is one "fiber" along that axis with acc reset to
1362
+ INIT inside the macro. */
1363
+ int8_t slab_axes[CA_RANK_MAX];
1364
+ slab_axes[0] = (int8_t) axis;
1365
+ ca_iter_state st_in, st_out;
1366
+ int rc;
1367
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1368
+ slab_axes, 1, 0);
1369
+ if ( rc != CA_ITER_OK ) {
1370
+ rb_raise(rb_eRuntimeError,
1371
+ "cummax_ki: input init failed rc=%d", rc);
1372
+ }
1373
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1374
+ slab_axes, 1, CA_KERNEL_WRITE);
1375
+ if ( rc != CA_ITER_OK ) {
1376
+ ca_iter_state_finish(&st_in);
1377
+ rb_raise(rb_eRuntimeError,
1378
+ "cummax_ki: output init failed rc=%d", rc);
1379
+ }
1380
+
1381
+ boolean8_t *op_mask = NULL;
1382
+ char *co_root = (char *) co->ptr;
1383
+ if ( ca_has_mask(ca) ) {
1384
+ ca_create_mask(co);
1385
+ op_mask = (boolean8_t *) co->mask->ptr;
1386
+ }
1387
+
1388
+ char *pi, *po;
1389
+ boolean8_t *mi, *mo;
1390
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1391
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1392
+ boolean8_t *mo_fiber = op_mask
1393
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1394
+ : NULL;
1395
+ CA_SLAB_SCAN_T_GATED(int8_t, int8_t, st_in, pi, mi,
1396
+ st_out, po, mo_fiber, INT8_MIN, if (v > acc) acc = v; r = acc);
1397
+ ca_iter_state_sync_slab(&st_out);
1398
+ }
1399
+ ca_iter_state_finish(&st_in);
1400
+ ca_iter_state_finish(&st_out);
1401
+ return vout;
1402
+ }
1403
+
1404
+ static VALUE
1405
+ cummax_ki_native_u8 (VALUE self, CArray *ca, int axis)
1406
+ {
1407
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT8),
1408
+ INT2NUM(sizeof(uint8_t)));
1409
+ CArray *co;
1410
+ GetCArray(vout, co);
1411
+
1412
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1413
+ iteration is one "fiber" along that axis with acc reset to
1414
+ INIT inside the macro. */
1415
+ int8_t slab_axes[CA_RANK_MAX];
1416
+ slab_axes[0] = (int8_t) axis;
1417
+ ca_iter_state st_in, st_out;
1418
+ int rc;
1419
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1420
+ slab_axes, 1, 0);
1421
+ if ( rc != CA_ITER_OK ) {
1422
+ rb_raise(rb_eRuntimeError,
1423
+ "cummax_ki: input init failed rc=%d", rc);
1424
+ }
1425
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1426
+ slab_axes, 1, CA_KERNEL_WRITE);
1427
+ if ( rc != CA_ITER_OK ) {
1428
+ ca_iter_state_finish(&st_in);
1429
+ rb_raise(rb_eRuntimeError,
1430
+ "cummax_ki: output init failed rc=%d", rc);
1431
+ }
1432
+
1433
+ boolean8_t *op_mask = NULL;
1434
+ char *co_root = (char *) co->ptr;
1435
+ if ( ca_has_mask(ca) ) {
1436
+ ca_create_mask(co);
1437
+ op_mask = (boolean8_t *) co->mask->ptr;
1438
+ }
1439
+
1440
+ char *pi, *po;
1441
+ boolean8_t *mi, *mo;
1442
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1443
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1444
+ boolean8_t *mo_fiber = op_mask
1445
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1446
+ : NULL;
1447
+ CA_SLAB_SCAN_T_GATED(uint8_t, uint8_t, st_in, pi, mi,
1448
+ st_out, po, mo_fiber, 0, if (v > acc) acc = v; r = acc);
1449
+ ca_iter_state_sync_slab(&st_out);
1450
+ }
1451
+ ca_iter_state_finish(&st_in);
1452
+ ca_iter_state_finish(&st_out);
1453
+ return vout;
1454
+ }
1455
+
1456
+ static VALUE
1457
+ cummax_ki_native_i16 (VALUE self, CArray *ca, int axis)
1458
+ {
1459
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT16),
1460
+ INT2NUM(sizeof(int16_t)));
1461
+ CArray *co;
1462
+ GetCArray(vout, co);
1463
+
1464
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1465
+ iteration is one "fiber" along that axis with acc reset to
1466
+ INIT inside the macro. */
1467
+ int8_t slab_axes[CA_RANK_MAX];
1468
+ slab_axes[0] = (int8_t) axis;
1469
+ ca_iter_state st_in, st_out;
1470
+ int rc;
1471
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1472
+ slab_axes, 1, 0);
1473
+ if ( rc != CA_ITER_OK ) {
1474
+ rb_raise(rb_eRuntimeError,
1475
+ "cummax_ki: input init failed rc=%d", rc);
1476
+ }
1477
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1478
+ slab_axes, 1, CA_KERNEL_WRITE);
1479
+ if ( rc != CA_ITER_OK ) {
1480
+ ca_iter_state_finish(&st_in);
1481
+ rb_raise(rb_eRuntimeError,
1482
+ "cummax_ki: output init failed rc=%d", rc);
1483
+ }
1484
+
1485
+ boolean8_t *op_mask = NULL;
1486
+ char *co_root = (char *) co->ptr;
1487
+ if ( ca_has_mask(ca) ) {
1488
+ ca_create_mask(co);
1489
+ op_mask = (boolean8_t *) co->mask->ptr;
1490
+ }
1491
+
1492
+ char *pi, *po;
1493
+ boolean8_t *mi, *mo;
1494
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1495
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1496
+ boolean8_t *mo_fiber = op_mask
1497
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1498
+ : NULL;
1499
+ CA_SLAB_SCAN_T_GATED(int16_t, int16_t, st_in, pi, mi,
1500
+ st_out, po, mo_fiber, INT16_MIN, if (v > acc) acc = v; r = acc);
1501
+ ca_iter_state_sync_slab(&st_out);
1502
+ }
1503
+ ca_iter_state_finish(&st_in);
1504
+ ca_iter_state_finish(&st_out);
1505
+ return vout;
1506
+ }
1507
+
1508
+ static VALUE
1509
+ cummax_ki_native_u16 (VALUE self, CArray *ca, int axis)
1510
+ {
1511
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT16),
1512
+ INT2NUM(sizeof(uint16_t)));
1513
+ CArray *co;
1514
+ GetCArray(vout, co);
1515
+
1516
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1517
+ iteration is one "fiber" along that axis with acc reset to
1518
+ INIT inside the macro. */
1519
+ int8_t slab_axes[CA_RANK_MAX];
1520
+ slab_axes[0] = (int8_t) axis;
1521
+ ca_iter_state st_in, st_out;
1522
+ int rc;
1523
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1524
+ slab_axes, 1, 0);
1525
+ if ( rc != CA_ITER_OK ) {
1526
+ rb_raise(rb_eRuntimeError,
1527
+ "cummax_ki: input init failed rc=%d", rc);
1528
+ }
1529
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1530
+ slab_axes, 1, CA_KERNEL_WRITE);
1531
+ if ( rc != CA_ITER_OK ) {
1532
+ ca_iter_state_finish(&st_in);
1533
+ rb_raise(rb_eRuntimeError,
1534
+ "cummax_ki: output init failed rc=%d", rc);
1535
+ }
1536
+
1537
+ boolean8_t *op_mask = NULL;
1538
+ char *co_root = (char *) co->ptr;
1539
+ if ( ca_has_mask(ca) ) {
1540
+ ca_create_mask(co);
1541
+ op_mask = (boolean8_t *) co->mask->ptr;
1542
+ }
1543
+
1544
+ char *pi, *po;
1545
+ boolean8_t *mi, *mo;
1546
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1547
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1548
+ boolean8_t *mo_fiber = op_mask
1549
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1550
+ : NULL;
1551
+ CA_SLAB_SCAN_T_GATED(uint16_t, uint16_t, st_in, pi, mi,
1552
+ st_out, po, mo_fiber, 0, if (v > acc) acc = v; r = acc);
1553
+ ca_iter_state_sync_slab(&st_out);
1554
+ }
1555
+ ca_iter_state_finish(&st_in);
1556
+ ca_iter_state_finish(&st_out);
1557
+ return vout;
1558
+ }
1559
+
1560
+ static VALUE
1561
+ cummax_ki_native_i32 (VALUE self, CArray *ca, int axis)
1562
+ {
1563
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT32),
1564
+ INT2NUM(sizeof(int32_t)));
1565
+ CArray *co;
1566
+ GetCArray(vout, co);
1567
+
1568
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1569
+ iteration is one "fiber" along that axis with acc reset to
1570
+ INIT inside the macro. */
1571
+ int8_t slab_axes[CA_RANK_MAX];
1572
+ slab_axes[0] = (int8_t) axis;
1573
+ ca_iter_state st_in, st_out;
1574
+ int rc;
1575
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1576
+ slab_axes, 1, 0);
1577
+ if ( rc != CA_ITER_OK ) {
1578
+ rb_raise(rb_eRuntimeError,
1579
+ "cummax_ki: input init failed rc=%d", rc);
1580
+ }
1581
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1582
+ slab_axes, 1, CA_KERNEL_WRITE);
1583
+ if ( rc != CA_ITER_OK ) {
1584
+ ca_iter_state_finish(&st_in);
1585
+ rb_raise(rb_eRuntimeError,
1586
+ "cummax_ki: output init failed rc=%d", rc);
1587
+ }
1588
+
1589
+ boolean8_t *op_mask = NULL;
1590
+ char *co_root = (char *) co->ptr;
1591
+ if ( ca_has_mask(ca) ) {
1592
+ ca_create_mask(co);
1593
+ op_mask = (boolean8_t *) co->mask->ptr;
1594
+ }
1595
+
1596
+ char *pi, *po;
1597
+ boolean8_t *mi, *mo;
1598
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1599
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1600
+ boolean8_t *mo_fiber = op_mask
1601
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1602
+ : NULL;
1603
+ CA_SLAB_SCAN_T_GATED(int32_t, int32_t, st_in, pi, mi,
1604
+ st_out, po, mo_fiber, INT32_MIN, if (v > acc) acc = v; r = acc);
1605
+ ca_iter_state_sync_slab(&st_out);
1606
+ }
1607
+ ca_iter_state_finish(&st_in);
1608
+ ca_iter_state_finish(&st_out);
1609
+ return vout;
1610
+ }
1611
+
1612
+ static VALUE
1613
+ cummax_ki_native_u32 (VALUE self, CArray *ca, int axis)
1614
+ {
1615
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT32),
1616
+ INT2NUM(sizeof(uint32_t)));
1617
+ CArray *co;
1618
+ GetCArray(vout, co);
1619
+
1620
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1621
+ iteration is one "fiber" along that axis with acc reset to
1622
+ INIT inside the macro. */
1623
+ int8_t slab_axes[CA_RANK_MAX];
1624
+ slab_axes[0] = (int8_t) axis;
1625
+ ca_iter_state st_in, st_out;
1626
+ int rc;
1627
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1628
+ slab_axes, 1, 0);
1629
+ if ( rc != CA_ITER_OK ) {
1630
+ rb_raise(rb_eRuntimeError,
1631
+ "cummax_ki: input init failed rc=%d", rc);
1632
+ }
1633
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1634
+ slab_axes, 1, CA_KERNEL_WRITE);
1635
+ if ( rc != CA_ITER_OK ) {
1636
+ ca_iter_state_finish(&st_in);
1637
+ rb_raise(rb_eRuntimeError,
1638
+ "cummax_ki: output init failed rc=%d", rc);
1639
+ }
1640
+
1641
+ boolean8_t *op_mask = NULL;
1642
+ char *co_root = (char *) co->ptr;
1643
+ if ( ca_has_mask(ca) ) {
1644
+ ca_create_mask(co);
1645
+ op_mask = (boolean8_t *) co->mask->ptr;
1646
+ }
1647
+
1648
+ char *pi, *po;
1649
+ boolean8_t *mi, *mo;
1650
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1651
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1652
+ boolean8_t *mo_fiber = op_mask
1653
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1654
+ : NULL;
1655
+ CA_SLAB_SCAN_T_GATED(uint32_t, uint32_t, st_in, pi, mi,
1656
+ st_out, po, mo_fiber, 0, if (v > acc) acc = v; r = acc);
1657
+ ca_iter_state_sync_slab(&st_out);
1658
+ }
1659
+ ca_iter_state_finish(&st_in);
1660
+ ca_iter_state_finish(&st_out);
1661
+ return vout;
1662
+ }
1663
+
1664
+ static VALUE
1665
+ cummax_ki_native_i64 (VALUE self, CArray *ca, int axis)
1666
+ {
1667
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
1668
+ INT2NUM(sizeof(int64_t)));
1669
+ CArray *co;
1670
+ GetCArray(vout, co);
1671
+
1672
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1673
+ iteration is one "fiber" along that axis with acc reset to
1674
+ INIT inside the macro. */
1675
+ int8_t slab_axes[CA_RANK_MAX];
1676
+ slab_axes[0] = (int8_t) axis;
1677
+ ca_iter_state st_in, st_out;
1678
+ int rc;
1679
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1680
+ slab_axes, 1, 0);
1681
+ if ( rc != CA_ITER_OK ) {
1682
+ rb_raise(rb_eRuntimeError,
1683
+ "cummax_ki: input init failed rc=%d", rc);
1684
+ }
1685
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1686
+ slab_axes, 1, CA_KERNEL_WRITE);
1687
+ if ( rc != CA_ITER_OK ) {
1688
+ ca_iter_state_finish(&st_in);
1689
+ rb_raise(rb_eRuntimeError,
1690
+ "cummax_ki: output init failed rc=%d", rc);
1691
+ }
1692
+
1693
+ boolean8_t *op_mask = NULL;
1694
+ char *co_root = (char *) co->ptr;
1695
+ if ( ca_has_mask(ca) ) {
1696
+ ca_create_mask(co);
1697
+ op_mask = (boolean8_t *) co->mask->ptr;
1698
+ }
1699
+
1700
+ char *pi, *po;
1701
+ boolean8_t *mi, *mo;
1702
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1703
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1704
+ boolean8_t *mo_fiber = op_mask
1705
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1706
+ : NULL;
1707
+ CA_SLAB_SCAN_T_GATED(int64_t, int64_t, st_in, pi, mi,
1708
+ st_out, po, mo_fiber, INT64_MIN, if (v > acc) acc = v; r = acc);
1709
+ ca_iter_state_sync_slab(&st_out);
1710
+ }
1711
+ ca_iter_state_finish(&st_in);
1712
+ ca_iter_state_finish(&st_out);
1713
+ return vout;
1714
+ }
1715
+
1716
+ static VALUE
1717
+ cummax_ki_native_u64 (VALUE self, CArray *ca, int axis)
1718
+ {
1719
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
1720
+ INT2NUM(sizeof(uint64_t)));
1721
+ CArray *co;
1722
+ GetCArray(vout, co);
1723
+
1724
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1725
+ iteration is one "fiber" along that axis with acc reset to
1726
+ INIT inside the macro. */
1727
+ int8_t slab_axes[CA_RANK_MAX];
1728
+ slab_axes[0] = (int8_t) axis;
1729
+ ca_iter_state st_in, st_out;
1730
+ int rc;
1731
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1732
+ slab_axes, 1, 0);
1733
+ if ( rc != CA_ITER_OK ) {
1734
+ rb_raise(rb_eRuntimeError,
1735
+ "cummax_ki: input init failed rc=%d", rc);
1736
+ }
1737
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1738
+ slab_axes, 1, CA_KERNEL_WRITE);
1739
+ if ( rc != CA_ITER_OK ) {
1740
+ ca_iter_state_finish(&st_in);
1741
+ rb_raise(rb_eRuntimeError,
1742
+ "cummax_ki: output init failed rc=%d", rc);
1743
+ }
1744
+
1745
+ boolean8_t *op_mask = NULL;
1746
+ char *co_root = (char *) co->ptr;
1747
+ if ( ca_has_mask(ca) ) {
1748
+ ca_create_mask(co);
1749
+ op_mask = (boolean8_t *) co->mask->ptr;
1750
+ }
1751
+
1752
+ char *pi, *po;
1753
+ boolean8_t *mi, *mo;
1754
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1755
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1756
+ boolean8_t *mo_fiber = op_mask
1757
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1758
+ : NULL;
1759
+ CA_SLAB_SCAN_T_GATED(uint64_t, uint64_t, st_in, pi, mi,
1760
+ st_out, po, mo_fiber, 0, if (v > acc) acc = v; r = acc);
1761
+ ca_iter_state_sync_slab(&st_out);
1762
+ }
1763
+ ca_iter_state_finish(&st_in);
1764
+ ca_iter_state_finish(&st_out);
1765
+ return vout;
1766
+ }
1767
+
1768
+ static VALUE
1769
+ cummax_ki_native_f32 (VALUE self, CArray *ca, int axis)
1770
+ {
1771
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT32),
1772
+ INT2NUM(sizeof(float)));
1773
+ CArray *co;
1774
+ GetCArray(vout, co);
1775
+
1776
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1777
+ iteration is one "fiber" along that axis with acc reset to
1778
+ INIT inside the macro. */
1779
+ int8_t slab_axes[CA_RANK_MAX];
1780
+ slab_axes[0] = (int8_t) axis;
1781
+ ca_iter_state st_in, st_out;
1782
+ int rc;
1783
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1784
+ slab_axes, 1, 0);
1785
+ if ( rc != CA_ITER_OK ) {
1786
+ rb_raise(rb_eRuntimeError,
1787
+ "cummax_ki: input init failed rc=%d", rc);
1788
+ }
1789
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1790
+ slab_axes, 1, CA_KERNEL_WRITE);
1791
+ if ( rc != CA_ITER_OK ) {
1792
+ ca_iter_state_finish(&st_in);
1793
+ rb_raise(rb_eRuntimeError,
1794
+ "cummax_ki: output init failed rc=%d", rc);
1795
+ }
1796
+
1797
+ boolean8_t *op_mask = NULL;
1798
+ char *co_root = (char *) co->ptr;
1799
+ if ( ca_has_mask(ca) ) {
1800
+ ca_create_mask(co);
1801
+ op_mask = (boolean8_t *) co->mask->ptr;
1802
+ }
1803
+
1804
+ char *pi, *po;
1805
+ boolean8_t *mi, *mo;
1806
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1807
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1808
+ boolean8_t *mo_fiber = op_mask
1809
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1810
+ : NULL;
1811
+ CA_SLAB_SCAN_T_GATED(float, float, st_in, pi, mi,
1812
+ st_out, po, mo_fiber, -INFINITY, if (v > acc) acc = v; r = acc);
1813
+ ca_iter_state_sync_slab(&st_out);
1814
+ }
1815
+ ca_iter_state_finish(&st_in);
1816
+ ca_iter_state_finish(&st_out);
1817
+ return vout;
1818
+ }
1819
+
1820
+ static VALUE
1821
+ cummax_ki_native_f64 (VALUE self, CArray *ca, int axis)
1822
+ {
1823
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
1824
+ INT2NUM(sizeof(double)));
1825
+ CArray *co;
1826
+ GetCArray(vout, co);
1827
+
1828
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1829
+ iteration is one "fiber" along that axis with acc reset to
1830
+ INIT inside the macro. */
1831
+ int8_t slab_axes[CA_RANK_MAX];
1832
+ slab_axes[0] = (int8_t) axis;
1833
+ ca_iter_state st_in, st_out;
1834
+ int rc;
1835
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1836
+ slab_axes, 1, 0);
1837
+ if ( rc != CA_ITER_OK ) {
1838
+ rb_raise(rb_eRuntimeError,
1839
+ "cummax_ki: input init failed rc=%d", rc);
1840
+ }
1841
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1842
+ slab_axes, 1, CA_KERNEL_WRITE);
1843
+ if ( rc != CA_ITER_OK ) {
1844
+ ca_iter_state_finish(&st_in);
1845
+ rb_raise(rb_eRuntimeError,
1846
+ "cummax_ki: output init failed rc=%d", rc);
1847
+ }
1848
+
1849
+ boolean8_t *op_mask = NULL;
1850
+ char *co_root = (char *) co->ptr;
1851
+ if ( ca_has_mask(ca) ) {
1852
+ ca_create_mask(co);
1853
+ op_mask = (boolean8_t *) co->mask->ptr;
1854
+ }
1855
+
1856
+ char *pi, *po;
1857
+ boolean8_t *mi, *mo;
1858
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1859
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1860
+ boolean8_t *mo_fiber = op_mask
1861
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1862
+ : NULL;
1863
+ CA_SLAB_SCAN_T_GATED(double, double, st_in, pi, mi,
1864
+ st_out, po, mo_fiber, -INFINITY, if (v > acc) acc = v; r = acc);
1865
+ ca_iter_state_sync_slab(&st_out);
1866
+ }
1867
+ ca_iter_state_finish(&st_in);
1868
+ ca_iter_state_finish(&st_out);
1869
+ return vout;
1870
+ }
1871
+
1872
+ static VALUE
1873
+ cummax_ki_native_bool (VALUE self, CArray *ca, int axis)
1874
+ {
1875
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
1876
+ INT2NUM(sizeof(uint64_t)));
1877
+ CArray *co;
1878
+ GetCArray(vout, co);
1879
+
1880
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1881
+ iteration is one "fiber" along that axis with acc reset to
1882
+ INIT inside the macro. */
1883
+ int8_t slab_axes[CA_RANK_MAX];
1884
+ slab_axes[0] = (int8_t) axis;
1885
+ ca_iter_state st_in, st_out;
1886
+ int rc;
1887
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1888
+ slab_axes, 1, 0);
1889
+ if ( rc != CA_ITER_OK ) {
1890
+ rb_raise(rb_eRuntimeError,
1891
+ "cummax_ki: input init failed rc=%d", rc);
1892
+ }
1893
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1894
+ slab_axes, 1, CA_KERNEL_WRITE);
1895
+ if ( rc != CA_ITER_OK ) {
1896
+ ca_iter_state_finish(&st_in);
1897
+ rb_raise(rb_eRuntimeError,
1898
+ "cummax_ki: output init failed rc=%d", rc);
1899
+ }
1900
+
1901
+ boolean8_t *op_mask = NULL;
1902
+ char *co_root = (char *) co->ptr;
1903
+ if ( ca_has_mask(ca) ) {
1904
+ ca_create_mask(co);
1905
+ op_mask = (boolean8_t *) co->mask->ptr;
1906
+ }
1907
+
1908
+ char *pi, *po;
1909
+ boolean8_t *mi, *mo;
1910
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1911
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1912
+ boolean8_t *mo_fiber = op_mask
1913
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1914
+ : NULL;
1915
+ CA_SLAB_SCAN_T_GATED(boolean8_t, uint64_t, st_in, pi, mi,
1916
+ st_out, po, mo_fiber, 0, if ((uint64_t) v > acc) acc = v; r = acc);
1917
+ ca_iter_state_sync_slab(&st_out);
1918
+ }
1919
+ ca_iter_state_finish(&st_in);
1920
+ ca_iter_state_finish(&st_out);
1921
+ return vout;
1922
+ }
1923
+
1924
+ static VALUE
1925
+ cummax_ki_native_object (VALUE self, CArray *ca, int axis)
1926
+ {
1927
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_OBJECT),
1928
+ INT2NUM(sizeof(VALUE)));
1929
+ CArray *co;
1930
+ GetCArray(vout, co);
1931
+
1932
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
1933
+ iteration is one "fiber" along that axis with acc reset to
1934
+ INIT inside the macro. */
1935
+ int8_t slab_axes[CA_RANK_MAX];
1936
+ slab_axes[0] = (int8_t) axis;
1937
+ ca_iter_state st_in, st_out;
1938
+ int rc;
1939
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1940
+ slab_axes, 1, 0);
1941
+ if ( rc != CA_ITER_OK ) {
1942
+ rb_raise(rb_eRuntimeError,
1943
+ "cummax_ki: input init failed rc=%d", rc);
1944
+ }
1945
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
1946
+ slab_axes, 1, CA_KERNEL_WRITE);
1947
+ if ( rc != CA_ITER_OK ) {
1948
+ ca_iter_state_finish(&st_in);
1949
+ rb_raise(rb_eRuntimeError,
1950
+ "cummax_ki: output init failed rc=%d", rc);
1951
+ }
1952
+
1953
+ boolean8_t *op_mask = NULL;
1954
+ char *co_root = (char *) co->ptr;
1955
+ if ( ca_has_mask(ca) ) {
1956
+ ca_create_mask(co);
1957
+ op_mask = (boolean8_t *) co->mask->ptr;
1958
+ }
1959
+
1960
+ char *pi, *po;
1961
+ boolean8_t *mi, *mo;
1962
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
1963
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
1964
+ boolean8_t *mo_fiber = op_mask
1965
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
1966
+ : NULL;
1967
+ CA_SLAB_SCAN_T_GATED(VALUE, VALUE, st_in, pi, mi,
1968
+ st_out, po, mo_fiber, Qnil, if (acc == Qnil) acc = v; else if (RTEST(rb_funcall(v, rb_intern(">"), 1, acc))) acc = v; r = acc);
1969
+ ca_iter_state_sync_slab(&st_out);
1970
+ }
1971
+ ca_iter_state_finish(&st_in);
1972
+ ca_iter_state_finish(&st_out);
1973
+ return vout;
1974
+ }
1975
+
1976
+ static VALUE
1977
+ rb_ca_cummax_ki (int argc, VALUE *argv, VALUE self)
1978
+ {
1979
+ CArray *src;
1980
+ GetCArray(self, src);
1981
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
1982
+ volatile VALUE raxis = Qnil;
1983
+ rb_scan_options(ropt, "axis", &raxis);
1984
+ if ( argc > 0 ) {
1985
+ rb_raise(rb_eArgError, "cummax_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.cummax(axis: 0)", argc);
1986
+ }
1987
+ if ( NIL_P(raxis) ) {
1988
+ volatile VALUE vflat = rb_funcall(self, rb_intern("flatten"), 0);
1989
+ CArray *fsrc;
1990
+ GetCArray(vflat, fsrc);
1991
+ switch ( fsrc->data_type ) {
1992
+ case CA_INT8: return cummax_ki_native_i8(vflat, fsrc, 0);
1993
+ case CA_UINT8: return cummax_ki_native_u8(vflat, fsrc, 0);
1994
+ case CA_INT16: return cummax_ki_native_i16(vflat, fsrc, 0);
1995
+ case CA_UINT16: return cummax_ki_native_u16(vflat, fsrc, 0);
1996
+ case CA_INT32: return cummax_ki_native_i32(vflat, fsrc, 0);
1997
+ case CA_UINT32: return cummax_ki_native_u32(vflat, fsrc, 0);
1998
+ case CA_INT64: return cummax_ki_native_i64(vflat, fsrc, 0);
1999
+ case CA_UINT64: return cummax_ki_native_u64(vflat, fsrc, 0);
2000
+ case CA_FLOAT32: return cummax_ki_native_f32(vflat, fsrc, 0);
2001
+ case CA_FLOAT64: return cummax_ki_native_f64(vflat, fsrc, 0);
2002
+ case CA_BOOLEAN: return cummax_ki_native_bool(vflat, fsrc, 0);
2003
+ case CA_OBJECT: return cummax_ki_native_object(vflat, fsrc, 0);
2004
+ default:
2005
+ rb_raise(rb_eCADataTypeError, "cummax_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool, object)", ca_type_name[fsrc->data_type]);
2006
+ }
2007
+ }
2008
+ if ( TYPE(raxis) == T_ARRAY ) {
2009
+ rb_raise(rb_eArgError, "cummax_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.cummax(axis: 0).cummax(axis: 1)");
2010
+ }
2011
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
2012
+ rb_raise(rb_eTypeError, "cummax_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
2013
+ }
2014
+ int axis = NUM2INT(raxis);
2015
+ if ( axis < 0 ) axis += src->ndim;
2016
+ if ( axis < 0 || axis >= src->ndim ) {
2017
+ rb_raise(rb_eArgError, "cummax_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
2018
+ }
2019
+ switch ( src->data_type ) {
2020
+ case CA_INT8: return cummax_ki_native_i8(self, src, axis);
2021
+ case CA_UINT8: return cummax_ki_native_u8(self, src, axis);
2022
+ case CA_INT16: return cummax_ki_native_i16(self, src, axis);
2023
+ case CA_UINT16: return cummax_ki_native_u16(self, src, axis);
2024
+ case CA_INT32: return cummax_ki_native_i32(self, src, axis);
2025
+ case CA_UINT32: return cummax_ki_native_u32(self, src, axis);
2026
+ case CA_INT64: return cummax_ki_native_i64(self, src, axis);
2027
+ case CA_UINT64: return cummax_ki_native_u64(self, src, axis);
2028
+ case CA_FLOAT32: return cummax_ki_native_f32(self, src, axis);
2029
+ case CA_FLOAT64: return cummax_ki_native_f64(self, src, axis);
2030
+ case CA_BOOLEAN: return cummax_ki_native_bool(self, src, axis);
2031
+ case CA_OBJECT: return cummax_ki_native_object(self, src, axis);
2032
+ default:
2033
+ rb_raise(rb_eCADataTypeError, "cummax_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool, object)", ca_type_name[src->data_type]);
2034
+ }
2035
+ return Qnil; /* unreachable */
2036
+ }
2037
+
2038
+ /* ===== cummin_ki ============================================ */
2039
+
2040
+ static VALUE
2041
+ cummin_ki_native_i8 (VALUE self, CArray *ca, int axis)
2042
+ {
2043
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT8),
2044
+ INT2NUM(sizeof(int8_t)));
2045
+ CArray *co;
2046
+ GetCArray(vout, co);
2047
+
2048
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2049
+ iteration is one "fiber" along that axis with acc reset to
2050
+ INIT inside the macro. */
2051
+ int8_t slab_axes[CA_RANK_MAX];
2052
+ slab_axes[0] = (int8_t) axis;
2053
+ ca_iter_state st_in, st_out;
2054
+ int rc;
2055
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2056
+ slab_axes, 1, 0);
2057
+ if ( rc != CA_ITER_OK ) {
2058
+ rb_raise(rb_eRuntimeError,
2059
+ "cummin_ki: input init failed rc=%d", rc);
2060
+ }
2061
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2062
+ slab_axes, 1, CA_KERNEL_WRITE);
2063
+ if ( rc != CA_ITER_OK ) {
2064
+ ca_iter_state_finish(&st_in);
2065
+ rb_raise(rb_eRuntimeError,
2066
+ "cummin_ki: output init failed rc=%d", rc);
2067
+ }
2068
+
2069
+ boolean8_t *op_mask = NULL;
2070
+ char *co_root = (char *) co->ptr;
2071
+ if ( ca_has_mask(ca) ) {
2072
+ ca_create_mask(co);
2073
+ op_mask = (boolean8_t *) co->mask->ptr;
2074
+ }
2075
+
2076
+ char *pi, *po;
2077
+ boolean8_t *mi, *mo;
2078
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2079
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2080
+ boolean8_t *mo_fiber = op_mask
2081
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2082
+ : NULL;
2083
+ CA_SLAB_SCAN_T_GATED(int8_t, int8_t, st_in, pi, mi,
2084
+ st_out, po, mo_fiber, INT8_MAX, if (v < acc) acc = v; r = acc);
2085
+ ca_iter_state_sync_slab(&st_out);
2086
+ }
2087
+ ca_iter_state_finish(&st_in);
2088
+ ca_iter_state_finish(&st_out);
2089
+ return vout;
2090
+ }
2091
+
2092
+ static VALUE
2093
+ cummin_ki_native_u8 (VALUE self, CArray *ca, int axis)
2094
+ {
2095
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT8),
2096
+ INT2NUM(sizeof(uint8_t)));
2097
+ CArray *co;
2098
+ GetCArray(vout, co);
2099
+
2100
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2101
+ iteration is one "fiber" along that axis with acc reset to
2102
+ INIT inside the macro. */
2103
+ int8_t slab_axes[CA_RANK_MAX];
2104
+ slab_axes[0] = (int8_t) axis;
2105
+ ca_iter_state st_in, st_out;
2106
+ int rc;
2107
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2108
+ slab_axes, 1, 0);
2109
+ if ( rc != CA_ITER_OK ) {
2110
+ rb_raise(rb_eRuntimeError,
2111
+ "cummin_ki: input init failed rc=%d", rc);
2112
+ }
2113
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2114
+ slab_axes, 1, CA_KERNEL_WRITE);
2115
+ if ( rc != CA_ITER_OK ) {
2116
+ ca_iter_state_finish(&st_in);
2117
+ rb_raise(rb_eRuntimeError,
2118
+ "cummin_ki: output init failed rc=%d", rc);
2119
+ }
2120
+
2121
+ boolean8_t *op_mask = NULL;
2122
+ char *co_root = (char *) co->ptr;
2123
+ if ( ca_has_mask(ca) ) {
2124
+ ca_create_mask(co);
2125
+ op_mask = (boolean8_t *) co->mask->ptr;
2126
+ }
2127
+
2128
+ char *pi, *po;
2129
+ boolean8_t *mi, *mo;
2130
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2131
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2132
+ boolean8_t *mo_fiber = op_mask
2133
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2134
+ : NULL;
2135
+ CA_SLAB_SCAN_T_GATED(uint8_t, uint8_t, st_in, pi, mi,
2136
+ st_out, po, mo_fiber, UINT8_MAX, if (v < acc) acc = v; r = acc);
2137
+ ca_iter_state_sync_slab(&st_out);
2138
+ }
2139
+ ca_iter_state_finish(&st_in);
2140
+ ca_iter_state_finish(&st_out);
2141
+ return vout;
2142
+ }
2143
+
2144
+ static VALUE
2145
+ cummin_ki_native_i16 (VALUE self, CArray *ca, int axis)
2146
+ {
2147
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT16),
2148
+ INT2NUM(sizeof(int16_t)));
2149
+ CArray *co;
2150
+ GetCArray(vout, co);
2151
+
2152
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2153
+ iteration is one "fiber" along that axis with acc reset to
2154
+ INIT inside the macro. */
2155
+ int8_t slab_axes[CA_RANK_MAX];
2156
+ slab_axes[0] = (int8_t) axis;
2157
+ ca_iter_state st_in, st_out;
2158
+ int rc;
2159
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2160
+ slab_axes, 1, 0);
2161
+ if ( rc != CA_ITER_OK ) {
2162
+ rb_raise(rb_eRuntimeError,
2163
+ "cummin_ki: input init failed rc=%d", rc);
2164
+ }
2165
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2166
+ slab_axes, 1, CA_KERNEL_WRITE);
2167
+ if ( rc != CA_ITER_OK ) {
2168
+ ca_iter_state_finish(&st_in);
2169
+ rb_raise(rb_eRuntimeError,
2170
+ "cummin_ki: output init failed rc=%d", rc);
2171
+ }
2172
+
2173
+ boolean8_t *op_mask = NULL;
2174
+ char *co_root = (char *) co->ptr;
2175
+ if ( ca_has_mask(ca) ) {
2176
+ ca_create_mask(co);
2177
+ op_mask = (boolean8_t *) co->mask->ptr;
2178
+ }
2179
+
2180
+ char *pi, *po;
2181
+ boolean8_t *mi, *mo;
2182
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2183
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2184
+ boolean8_t *mo_fiber = op_mask
2185
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2186
+ : NULL;
2187
+ CA_SLAB_SCAN_T_GATED(int16_t, int16_t, st_in, pi, mi,
2188
+ st_out, po, mo_fiber, INT16_MAX, if (v < acc) acc = v; r = acc);
2189
+ ca_iter_state_sync_slab(&st_out);
2190
+ }
2191
+ ca_iter_state_finish(&st_in);
2192
+ ca_iter_state_finish(&st_out);
2193
+ return vout;
2194
+ }
2195
+
2196
+ static VALUE
2197
+ cummin_ki_native_u16 (VALUE self, CArray *ca, int axis)
2198
+ {
2199
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT16),
2200
+ INT2NUM(sizeof(uint16_t)));
2201
+ CArray *co;
2202
+ GetCArray(vout, co);
2203
+
2204
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2205
+ iteration is one "fiber" along that axis with acc reset to
2206
+ INIT inside the macro. */
2207
+ int8_t slab_axes[CA_RANK_MAX];
2208
+ slab_axes[0] = (int8_t) axis;
2209
+ ca_iter_state st_in, st_out;
2210
+ int rc;
2211
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2212
+ slab_axes, 1, 0);
2213
+ if ( rc != CA_ITER_OK ) {
2214
+ rb_raise(rb_eRuntimeError,
2215
+ "cummin_ki: input init failed rc=%d", rc);
2216
+ }
2217
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2218
+ slab_axes, 1, CA_KERNEL_WRITE);
2219
+ if ( rc != CA_ITER_OK ) {
2220
+ ca_iter_state_finish(&st_in);
2221
+ rb_raise(rb_eRuntimeError,
2222
+ "cummin_ki: output init failed rc=%d", rc);
2223
+ }
2224
+
2225
+ boolean8_t *op_mask = NULL;
2226
+ char *co_root = (char *) co->ptr;
2227
+ if ( ca_has_mask(ca) ) {
2228
+ ca_create_mask(co);
2229
+ op_mask = (boolean8_t *) co->mask->ptr;
2230
+ }
2231
+
2232
+ char *pi, *po;
2233
+ boolean8_t *mi, *mo;
2234
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2235
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2236
+ boolean8_t *mo_fiber = op_mask
2237
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2238
+ : NULL;
2239
+ CA_SLAB_SCAN_T_GATED(uint16_t, uint16_t, st_in, pi, mi,
2240
+ st_out, po, mo_fiber, UINT16_MAX, if (v < acc) acc = v; r = acc);
2241
+ ca_iter_state_sync_slab(&st_out);
2242
+ }
2243
+ ca_iter_state_finish(&st_in);
2244
+ ca_iter_state_finish(&st_out);
2245
+ return vout;
2246
+ }
2247
+
2248
+ static VALUE
2249
+ cummin_ki_native_i32 (VALUE self, CArray *ca, int axis)
2250
+ {
2251
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT32),
2252
+ INT2NUM(sizeof(int32_t)));
2253
+ CArray *co;
2254
+ GetCArray(vout, co);
2255
+
2256
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2257
+ iteration is one "fiber" along that axis with acc reset to
2258
+ INIT inside the macro. */
2259
+ int8_t slab_axes[CA_RANK_MAX];
2260
+ slab_axes[0] = (int8_t) axis;
2261
+ ca_iter_state st_in, st_out;
2262
+ int rc;
2263
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2264
+ slab_axes, 1, 0);
2265
+ if ( rc != CA_ITER_OK ) {
2266
+ rb_raise(rb_eRuntimeError,
2267
+ "cummin_ki: input init failed rc=%d", rc);
2268
+ }
2269
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2270
+ slab_axes, 1, CA_KERNEL_WRITE);
2271
+ if ( rc != CA_ITER_OK ) {
2272
+ ca_iter_state_finish(&st_in);
2273
+ rb_raise(rb_eRuntimeError,
2274
+ "cummin_ki: output init failed rc=%d", rc);
2275
+ }
2276
+
2277
+ boolean8_t *op_mask = NULL;
2278
+ char *co_root = (char *) co->ptr;
2279
+ if ( ca_has_mask(ca) ) {
2280
+ ca_create_mask(co);
2281
+ op_mask = (boolean8_t *) co->mask->ptr;
2282
+ }
2283
+
2284
+ char *pi, *po;
2285
+ boolean8_t *mi, *mo;
2286
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2287
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2288
+ boolean8_t *mo_fiber = op_mask
2289
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2290
+ : NULL;
2291
+ CA_SLAB_SCAN_T_GATED(int32_t, int32_t, st_in, pi, mi,
2292
+ st_out, po, mo_fiber, INT32_MAX, if (v < acc) acc = v; r = acc);
2293
+ ca_iter_state_sync_slab(&st_out);
2294
+ }
2295
+ ca_iter_state_finish(&st_in);
2296
+ ca_iter_state_finish(&st_out);
2297
+ return vout;
2298
+ }
2299
+
2300
+ static VALUE
2301
+ cummin_ki_native_u32 (VALUE self, CArray *ca, int axis)
2302
+ {
2303
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT32),
2304
+ INT2NUM(sizeof(uint32_t)));
2305
+ CArray *co;
2306
+ GetCArray(vout, co);
2307
+
2308
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2309
+ iteration is one "fiber" along that axis with acc reset to
2310
+ INIT inside the macro. */
2311
+ int8_t slab_axes[CA_RANK_MAX];
2312
+ slab_axes[0] = (int8_t) axis;
2313
+ ca_iter_state st_in, st_out;
2314
+ int rc;
2315
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2316
+ slab_axes, 1, 0);
2317
+ if ( rc != CA_ITER_OK ) {
2318
+ rb_raise(rb_eRuntimeError,
2319
+ "cummin_ki: input init failed rc=%d", rc);
2320
+ }
2321
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2322
+ slab_axes, 1, CA_KERNEL_WRITE);
2323
+ if ( rc != CA_ITER_OK ) {
2324
+ ca_iter_state_finish(&st_in);
2325
+ rb_raise(rb_eRuntimeError,
2326
+ "cummin_ki: output init failed rc=%d", rc);
2327
+ }
2328
+
2329
+ boolean8_t *op_mask = NULL;
2330
+ char *co_root = (char *) co->ptr;
2331
+ if ( ca_has_mask(ca) ) {
2332
+ ca_create_mask(co);
2333
+ op_mask = (boolean8_t *) co->mask->ptr;
2334
+ }
2335
+
2336
+ char *pi, *po;
2337
+ boolean8_t *mi, *mo;
2338
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2339
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2340
+ boolean8_t *mo_fiber = op_mask
2341
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2342
+ : NULL;
2343
+ CA_SLAB_SCAN_T_GATED(uint32_t, uint32_t, st_in, pi, mi,
2344
+ st_out, po, mo_fiber, UINT32_MAX, if (v < acc) acc = v; r = acc);
2345
+ ca_iter_state_sync_slab(&st_out);
2346
+ }
2347
+ ca_iter_state_finish(&st_in);
2348
+ ca_iter_state_finish(&st_out);
2349
+ return vout;
2350
+ }
2351
+
2352
+ static VALUE
2353
+ cummin_ki_native_i64 (VALUE self, CArray *ca, int axis)
2354
+ {
2355
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2356
+ INT2NUM(sizeof(int64_t)));
2357
+ CArray *co;
2358
+ GetCArray(vout, co);
2359
+
2360
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2361
+ iteration is one "fiber" along that axis with acc reset to
2362
+ INIT inside the macro. */
2363
+ int8_t slab_axes[CA_RANK_MAX];
2364
+ slab_axes[0] = (int8_t) axis;
2365
+ ca_iter_state st_in, st_out;
2366
+ int rc;
2367
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2368
+ slab_axes, 1, 0);
2369
+ if ( rc != CA_ITER_OK ) {
2370
+ rb_raise(rb_eRuntimeError,
2371
+ "cummin_ki: input init failed rc=%d", rc);
2372
+ }
2373
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2374
+ slab_axes, 1, CA_KERNEL_WRITE);
2375
+ if ( rc != CA_ITER_OK ) {
2376
+ ca_iter_state_finish(&st_in);
2377
+ rb_raise(rb_eRuntimeError,
2378
+ "cummin_ki: output init failed rc=%d", rc);
2379
+ }
2380
+
2381
+ boolean8_t *op_mask = NULL;
2382
+ char *co_root = (char *) co->ptr;
2383
+ if ( ca_has_mask(ca) ) {
2384
+ ca_create_mask(co);
2385
+ op_mask = (boolean8_t *) co->mask->ptr;
2386
+ }
2387
+
2388
+ char *pi, *po;
2389
+ boolean8_t *mi, *mo;
2390
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2391
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2392
+ boolean8_t *mo_fiber = op_mask
2393
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2394
+ : NULL;
2395
+ CA_SLAB_SCAN_T_GATED(int64_t, int64_t, st_in, pi, mi,
2396
+ st_out, po, mo_fiber, INT64_MAX, if (v < acc) acc = v; r = acc);
2397
+ ca_iter_state_sync_slab(&st_out);
2398
+ }
2399
+ ca_iter_state_finish(&st_in);
2400
+ ca_iter_state_finish(&st_out);
2401
+ return vout;
2402
+ }
2403
+
2404
+ static VALUE
2405
+ cummin_ki_native_u64 (VALUE self, CArray *ca, int axis)
2406
+ {
2407
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
2408
+ INT2NUM(sizeof(uint64_t)));
2409
+ CArray *co;
2410
+ GetCArray(vout, co);
2411
+
2412
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2413
+ iteration is one "fiber" along that axis with acc reset to
2414
+ INIT inside the macro. */
2415
+ int8_t slab_axes[CA_RANK_MAX];
2416
+ slab_axes[0] = (int8_t) axis;
2417
+ ca_iter_state st_in, st_out;
2418
+ int rc;
2419
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2420
+ slab_axes, 1, 0);
2421
+ if ( rc != CA_ITER_OK ) {
2422
+ rb_raise(rb_eRuntimeError,
2423
+ "cummin_ki: input init failed rc=%d", rc);
2424
+ }
2425
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2426
+ slab_axes, 1, CA_KERNEL_WRITE);
2427
+ if ( rc != CA_ITER_OK ) {
2428
+ ca_iter_state_finish(&st_in);
2429
+ rb_raise(rb_eRuntimeError,
2430
+ "cummin_ki: output init failed rc=%d", rc);
2431
+ }
2432
+
2433
+ boolean8_t *op_mask = NULL;
2434
+ char *co_root = (char *) co->ptr;
2435
+ if ( ca_has_mask(ca) ) {
2436
+ ca_create_mask(co);
2437
+ op_mask = (boolean8_t *) co->mask->ptr;
2438
+ }
2439
+
2440
+ char *pi, *po;
2441
+ boolean8_t *mi, *mo;
2442
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2443
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2444
+ boolean8_t *mo_fiber = op_mask
2445
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2446
+ : NULL;
2447
+ CA_SLAB_SCAN_T_GATED(uint64_t, uint64_t, st_in, pi, mi,
2448
+ st_out, po, mo_fiber, UINT64_MAX, if (v < acc) acc = v; r = acc);
2449
+ ca_iter_state_sync_slab(&st_out);
2450
+ }
2451
+ ca_iter_state_finish(&st_in);
2452
+ ca_iter_state_finish(&st_out);
2453
+ return vout;
2454
+ }
2455
+
2456
+ static VALUE
2457
+ cummin_ki_native_f32 (VALUE self, CArray *ca, int axis)
2458
+ {
2459
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT32),
2460
+ INT2NUM(sizeof(float)));
2461
+ CArray *co;
2462
+ GetCArray(vout, co);
2463
+
2464
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2465
+ iteration is one "fiber" along that axis with acc reset to
2466
+ INIT inside the macro. */
2467
+ int8_t slab_axes[CA_RANK_MAX];
2468
+ slab_axes[0] = (int8_t) axis;
2469
+ ca_iter_state st_in, st_out;
2470
+ int rc;
2471
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2472
+ slab_axes, 1, 0);
2473
+ if ( rc != CA_ITER_OK ) {
2474
+ rb_raise(rb_eRuntimeError,
2475
+ "cummin_ki: input init failed rc=%d", rc);
2476
+ }
2477
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2478
+ slab_axes, 1, CA_KERNEL_WRITE);
2479
+ if ( rc != CA_ITER_OK ) {
2480
+ ca_iter_state_finish(&st_in);
2481
+ rb_raise(rb_eRuntimeError,
2482
+ "cummin_ki: output init failed rc=%d", rc);
2483
+ }
2484
+
2485
+ boolean8_t *op_mask = NULL;
2486
+ char *co_root = (char *) co->ptr;
2487
+ if ( ca_has_mask(ca) ) {
2488
+ ca_create_mask(co);
2489
+ op_mask = (boolean8_t *) co->mask->ptr;
2490
+ }
2491
+
2492
+ char *pi, *po;
2493
+ boolean8_t *mi, *mo;
2494
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2495
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2496
+ boolean8_t *mo_fiber = op_mask
2497
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2498
+ : NULL;
2499
+ CA_SLAB_SCAN_T_GATED(float, float, st_in, pi, mi,
2500
+ st_out, po, mo_fiber, INFINITY, if (v < acc) acc = v; r = acc);
2501
+ ca_iter_state_sync_slab(&st_out);
2502
+ }
2503
+ ca_iter_state_finish(&st_in);
2504
+ ca_iter_state_finish(&st_out);
2505
+ return vout;
2506
+ }
2507
+
2508
+ static VALUE
2509
+ cummin_ki_native_f64 (VALUE self, CArray *ca, int axis)
2510
+ {
2511
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_FLOAT64),
2512
+ INT2NUM(sizeof(double)));
2513
+ CArray *co;
2514
+ GetCArray(vout, co);
2515
+
2516
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2517
+ iteration is one "fiber" along that axis with acc reset to
2518
+ INIT inside the macro. */
2519
+ int8_t slab_axes[CA_RANK_MAX];
2520
+ slab_axes[0] = (int8_t) axis;
2521
+ ca_iter_state st_in, st_out;
2522
+ int rc;
2523
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2524
+ slab_axes, 1, 0);
2525
+ if ( rc != CA_ITER_OK ) {
2526
+ rb_raise(rb_eRuntimeError,
2527
+ "cummin_ki: input init failed rc=%d", rc);
2528
+ }
2529
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2530
+ slab_axes, 1, CA_KERNEL_WRITE);
2531
+ if ( rc != CA_ITER_OK ) {
2532
+ ca_iter_state_finish(&st_in);
2533
+ rb_raise(rb_eRuntimeError,
2534
+ "cummin_ki: output init failed rc=%d", rc);
2535
+ }
2536
+
2537
+ boolean8_t *op_mask = NULL;
2538
+ char *co_root = (char *) co->ptr;
2539
+ if ( ca_has_mask(ca) ) {
2540
+ ca_create_mask(co);
2541
+ op_mask = (boolean8_t *) co->mask->ptr;
2542
+ }
2543
+
2544
+ char *pi, *po;
2545
+ boolean8_t *mi, *mo;
2546
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2547
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2548
+ boolean8_t *mo_fiber = op_mask
2549
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2550
+ : NULL;
2551
+ CA_SLAB_SCAN_T_GATED(double, double, st_in, pi, mi,
2552
+ st_out, po, mo_fiber, INFINITY, if (v < acc) acc = v; r = acc);
2553
+ ca_iter_state_sync_slab(&st_out);
2554
+ }
2555
+ ca_iter_state_finish(&st_in);
2556
+ ca_iter_state_finish(&st_out);
2557
+ return vout;
2558
+ }
2559
+
2560
+ static VALUE
2561
+ cummin_ki_native_bool (VALUE self, CArray *ca, int axis)
2562
+ {
2563
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_UINT64),
2564
+ INT2NUM(sizeof(uint64_t)));
2565
+ CArray *co;
2566
+ GetCArray(vout, co);
2567
+
2568
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2569
+ iteration is one "fiber" along that axis with acc reset to
2570
+ INIT inside the macro. */
2571
+ int8_t slab_axes[CA_RANK_MAX];
2572
+ slab_axes[0] = (int8_t) axis;
2573
+ ca_iter_state st_in, st_out;
2574
+ int rc;
2575
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2576
+ slab_axes, 1, 0);
2577
+ if ( rc != CA_ITER_OK ) {
2578
+ rb_raise(rb_eRuntimeError,
2579
+ "cummin_ki: input init failed rc=%d", rc);
2580
+ }
2581
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2582
+ slab_axes, 1, CA_KERNEL_WRITE);
2583
+ if ( rc != CA_ITER_OK ) {
2584
+ ca_iter_state_finish(&st_in);
2585
+ rb_raise(rb_eRuntimeError,
2586
+ "cummin_ki: output init failed rc=%d", rc);
2587
+ }
2588
+
2589
+ boolean8_t *op_mask = NULL;
2590
+ char *co_root = (char *) co->ptr;
2591
+ if ( ca_has_mask(ca) ) {
2592
+ ca_create_mask(co);
2593
+ op_mask = (boolean8_t *) co->mask->ptr;
2594
+ }
2595
+
2596
+ char *pi, *po;
2597
+ boolean8_t *mi, *mo;
2598
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2599
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2600
+ boolean8_t *mo_fiber = op_mask
2601
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2602
+ : NULL;
2603
+ CA_SLAB_SCAN_T_GATED(boolean8_t, uint64_t, st_in, pi, mi,
2604
+ st_out, po, mo_fiber, 1, if ((uint64_t) v < acc) acc = v; r = acc);
2605
+ ca_iter_state_sync_slab(&st_out);
2606
+ }
2607
+ ca_iter_state_finish(&st_in);
2608
+ ca_iter_state_finish(&st_out);
2609
+ return vout;
2610
+ }
2611
+
2612
+ static VALUE
2613
+ cummin_ki_native_object (VALUE self, CArray *ca, int axis)
2614
+ {
2615
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_OBJECT),
2616
+ INT2NUM(sizeof(VALUE)));
2617
+ CArray *co;
2618
+ GetCArray(vout, co);
2619
+
2620
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2621
+ iteration is one "fiber" along that axis with acc reset to
2622
+ INIT inside the macro. */
2623
+ int8_t slab_axes[CA_RANK_MAX];
2624
+ slab_axes[0] = (int8_t) axis;
2625
+ ca_iter_state st_in, st_out;
2626
+ int rc;
2627
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2628
+ slab_axes, 1, 0);
2629
+ if ( rc != CA_ITER_OK ) {
2630
+ rb_raise(rb_eRuntimeError,
2631
+ "cummin_ki: input init failed rc=%d", rc);
2632
+ }
2633
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2634
+ slab_axes, 1, CA_KERNEL_WRITE);
2635
+ if ( rc != CA_ITER_OK ) {
2636
+ ca_iter_state_finish(&st_in);
2637
+ rb_raise(rb_eRuntimeError,
2638
+ "cummin_ki: output init failed rc=%d", rc);
2639
+ }
2640
+
2641
+ boolean8_t *op_mask = NULL;
2642
+ char *co_root = (char *) co->ptr;
2643
+ if ( ca_has_mask(ca) ) {
2644
+ ca_create_mask(co);
2645
+ op_mask = (boolean8_t *) co->mask->ptr;
2646
+ }
2647
+
2648
+ char *pi, *po;
2649
+ boolean8_t *mi, *mo;
2650
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2651
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2652
+ boolean8_t *mo_fiber = op_mask
2653
+ ? op_mask + (ca_size_t)(po - co_root) / (ca_size_t) co->bytes
2654
+ : NULL;
2655
+ CA_SLAB_SCAN_T_GATED(VALUE, VALUE, st_in, pi, mi,
2656
+ st_out, po, mo_fiber, Qnil, if (acc == Qnil) acc = v; else if (RTEST(rb_funcall(v, rb_intern("<"), 1, acc))) acc = v; r = acc);
2657
+ ca_iter_state_sync_slab(&st_out);
2658
+ }
2659
+ ca_iter_state_finish(&st_in);
2660
+ ca_iter_state_finish(&st_out);
2661
+ return vout;
2662
+ }
2663
+
2664
+ static VALUE
2665
+ rb_ca_cummin_ki (int argc, VALUE *argv, VALUE self)
2666
+ {
2667
+ CArray *src;
2668
+ GetCArray(self, src);
2669
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
2670
+ volatile VALUE raxis = Qnil;
2671
+ rb_scan_options(ropt, "axis", &raxis);
2672
+ if ( argc > 0 ) {
2673
+ rb_raise(rb_eArgError, "cummin_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.cummin(axis: 0)", argc);
2674
+ }
2675
+ if ( NIL_P(raxis) ) {
2676
+ volatile VALUE vflat = rb_funcall(self, rb_intern("flatten"), 0);
2677
+ CArray *fsrc;
2678
+ GetCArray(vflat, fsrc);
2679
+ switch ( fsrc->data_type ) {
2680
+ case CA_INT8: return cummin_ki_native_i8(vflat, fsrc, 0);
2681
+ case CA_UINT8: return cummin_ki_native_u8(vflat, fsrc, 0);
2682
+ case CA_INT16: return cummin_ki_native_i16(vflat, fsrc, 0);
2683
+ case CA_UINT16: return cummin_ki_native_u16(vflat, fsrc, 0);
2684
+ case CA_INT32: return cummin_ki_native_i32(vflat, fsrc, 0);
2685
+ case CA_UINT32: return cummin_ki_native_u32(vflat, fsrc, 0);
2686
+ case CA_INT64: return cummin_ki_native_i64(vflat, fsrc, 0);
2687
+ case CA_UINT64: return cummin_ki_native_u64(vflat, fsrc, 0);
2688
+ case CA_FLOAT32: return cummin_ki_native_f32(vflat, fsrc, 0);
2689
+ case CA_FLOAT64: return cummin_ki_native_f64(vflat, fsrc, 0);
2690
+ case CA_BOOLEAN: return cummin_ki_native_bool(vflat, fsrc, 0);
2691
+ case CA_OBJECT: return cummin_ki_native_object(vflat, fsrc, 0);
2692
+ default:
2693
+ rb_raise(rb_eCADataTypeError, "cummin_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool, object)", ca_type_name[fsrc->data_type]);
2694
+ }
2695
+ }
2696
+ if ( TYPE(raxis) == T_ARRAY ) {
2697
+ rb_raise(rb_eArgError, "cummin_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.cummin(axis: 0).cummin(axis: 1)");
2698
+ }
2699
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
2700
+ rb_raise(rb_eTypeError, "cummin_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
2701
+ }
2702
+ int axis = NUM2INT(raxis);
2703
+ if ( axis < 0 ) axis += src->ndim;
2704
+ if ( axis < 0 || axis >= src->ndim ) {
2705
+ rb_raise(rb_eArgError, "cummin_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
2706
+ }
2707
+ switch ( src->data_type ) {
2708
+ case CA_INT8: return cummin_ki_native_i8(self, src, axis);
2709
+ case CA_UINT8: return cummin_ki_native_u8(self, src, axis);
2710
+ case CA_INT16: return cummin_ki_native_i16(self, src, axis);
2711
+ case CA_UINT16: return cummin_ki_native_u16(self, src, axis);
2712
+ case CA_INT32: return cummin_ki_native_i32(self, src, axis);
2713
+ case CA_UINT32: return cummin_ki_native_u32(self, src, axis);
2714
+ case CA_INT64: return cummin_ki_native_i64(self, src, axis);
2715
+ case CA_UINT64: return cummin_ki_native_u64(self, src, axis);
2716
+ case CA_FLOAT32: return cummin_ki_native_f32(self, src, axis);
2717
+ case CA_FLOAT64: return cummin_ki_native_f64(self, src, axis);
2718
+ case CA_BOOLEAN: return cummin_ki_native_bool(self, src, axis);
2719
+ case CA_OBJECT: return cummin_ki_native_object(self, src, axis);
2720
+ default:
2721
+ rb_raise(rb_eCADataTypeError, "cummin_ki: source data_type :%s not supported (expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, bool, object)", ca_type_name[src->data_type]);
2722
+ }
2723
+ return Qnil; /* unreachable */
2724
+ }
2725
+
2726
+ /* ===== cumcount_ki ============================================ */
2727
+
2728
+ static VALUE
2729
+ cumcount_ki_native_i8 (VALUE self, CArray *ca, int axis)
2730
+ {
2731
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2732
+ INT2NUM(sizeof(int64_t)));
2733
+ CArray *co;
2734
+ GetCArray(vout, co);
2735
+
2736
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2737
+ iteration is one "fiber" along that axis with acc reset to
2738
+ INIT inside the macro. */
2739
+ int8_t slab_axes[CA_RANK_MAX];
2740
+ slab_axes[0] = (int8_t) axis;
2741
+ ca_iter_state st_in, st_out;
2742
+ int rc;
2743
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2744
+ slab_axes, 1, 0);
2745
+ if ( rc != CA_ITER_OK ) {
2746
+ rb_raise(rb_eRuntimeError,
2747
+ "cumcount_ki: input init failed rc=%d", rc);
2748
+ }
2749
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2750
+ slab_axes, 1, CA_KERNEL_WRITE);
2751
+ if ( rc != CA_ITER_OK ) {
2752
+ ca_iter_state_finish(&st_in);
2753
+ rb_raise(rb_eRuntimeError,
2754
+ "cumcount_ki: output init failed rc=%d", rc);
2755
+ }
2756
+
2757
+ char *pi, *po;
2758
+ boolean8_t *mi, *mo;
2759
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2760
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2761
+ CA_SLAB_SCAN_T(int8_t, int64_t, st_in, pi, mi,
2762
+ st_out, po, 0, (void) v; r = ++acc);
2763
+ ca_iter_state_sync_slab(&st_out);
2764
+ }
2765
+ ca_iter_state_finish(&st_in);
2766
+ ca_iter_state_finish(&st_out);
2767
+ return vout;
2768
+ }
2769
+
2770
+ static VALUE
2771
+ cumcount_ki_native_u8 (VALUE self, CArray *ca, int axis)
2772
+ {
2773
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2774
+ INT2NUM(sizeof(int64_t)));
2775
+ CArray *co;
2776
+ GetCArray(vout, co);
2777
+
2778
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2779
+ iteration is one "fiber" along that axis with acc reset to
2780
+ INIT inside the macro. */
2781
+ int8_t slab_axes[CA_RANK_MAX];
2782
+ slab_axes[0] = (int8_t) axis;
2783
+ ca_iter_state st_in, st_out;
2784
+ int rc;
2785
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2786
+ slab_axes, 1, 0);
2787
+ if ( rc != CA_ITER_OK ) {
2788
+ rb_raise(rb_eRuntimeError,
2789
+ "cumcount_ki: input init failed rc=%d", rc);
2790
+ }
2791
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2792
+ slab_axes, 1, CA_KERNEL_WRITE);
2793
+ if ( rc != CA_ITER_OK ) {
2794
+ ca_iter_state_finish(&st_in);
2795
+ rb_raise(rb_eRuntimeError,
2796
+ "cumcount_ki: output init failed rc=%d", rc);
2797
+ }
2798
+
2799
+ char *pi, *po;
2800
+ boolean8_t *mi, *mo;
2801
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2802
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2803
+ CA_SLAB_SCAN_T(uint8_t, int64_t, st_in, pi, mi,
2804
+ st_out, po, 0, (void) v; r = ++acc);
2805
+ ca_iter_state_sync_slab(&st_out);
2806
+ }
2807
+ ca_iter_state_finish(&st_in);
2808
+ ca_iter_state_finish(&st_out);
2809
+ return vout;
2810
+ }
2811
+
2812
+ static VALUE
2813
+ cumcount_ki_native_i16 (VALUE self, CArray *ca, int axis)
2814
+ {
2815
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2816
+ INT2NUM(sizeof(int64_t)));
2817
+ CArray *co;
2818
+ GetCArray(vout, co);
2819
+
2820
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2821
+ iteration is one "fiber" along that axis with acc reset to
2822
+ INIT inside the macro. */
2823
+ int8_t slab_axes[CA_RANK_MAX];
2824
+ slab_axes[0] = (int8_t) axis;
2825
+ ca_iter_state st_in, st_out;
2826
+ int rc;
2827
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2828
+ slab_axes, 1, 0);
2829
+ if ( rc != CA_ITER_OK ) {
2830
+ rb_raise(rb_eRuntimeError,
2831
+ "cumcount_ki: input init failed rc=%d", rc);
2832
+ }
2833
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2834
+ slab_axes, 1, CA_KERNEL_WRITE);
2835
+ if ( rc != CA_ITER_OK ) {
2836
+ ca_iter_state_finish(&st_in);
2837
+ rb_raise(rb_eRuntimeError,
2838
+ "cumcount_ki: output init failed rc=%d", rc);
2839
+ }
2840
+
2841
+ char *pi, *po;
2842
+ boolean8_t *mi, *mo;
2843
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2844
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2845
+ CA_SLAB_SCAN_T(int16_t, int64_t, st_in, pi, mi,
2846
+ st_out, po, 0, (void) v; r = ++acc);
2847
+ ca_iter_state_sync_slab(&st_out);
2848
+ }
2849
+ ca_iter_state_finish(&st_in);
2850
+ ca_iter_state_finish(&st_out);
2851
+ return vout;
2852
+ }
2853
+
2854
+ static VALUE
2855
+ cumcount_ki_native_u16 (VALUE self, CArray *ca, int axis)
2856
+ {
2857
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2858
+ INT2NUM(sizeof(int64_t)));
2859
+ CArray *co;
2860
+ GetCArray(vout, co);
2861
+
2862
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2863
+ iteration is one "fiber" along that axis with acc reset to
2864
+ INIT inside the macro. */
2865
+ int8_t slab_axes[CA_RANK_MAX];
2866
+ slab_axes[0] = (int8_t) axis;
2867
+ ca_iter_state st_in, st_out;
2868
+ int rc;
2869
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2870
+ slab_axes, 1, 0);
2871
+ if ( rc != CA_ITER_OK ) {
2872
+ rb_raise(rb_eRuntimeError,
2873
+ "cumcount_ki: input init failed rc=%d", rc);
2874
+ }
2875
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2876
+ slab_axes, 1, CA_KERNEL_WRITE);
2877
+ if ( rc != CA_ITER_OK ) {
2878
+ ca_iter_state_finish(&st_in);
2879
+ rb_raise(rb_eRuntimeError,
2880
+ "cumcount_ki: output init failed rc=%d", rc);
2881
+ }
2882
+
2883
+ char *pi, *po;
2884
+ boolean8_t *mi, *mo;
2885
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2886
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2887
+ CA_SLAB_SCAN_T(uint16_t, int64_t, st_in, pi, mi,
2888
+ st_out, po, 0, (void) v; r = ++acc);
2889
+ ca_iter_state_sync_slab(&st_out);
2890
+ }
2891
+ ca_iter_state_finish(&st_in);
2892
+ ca_iter_state_finish(&st_out);
2893
+ return vout;
2894
+ }
2895
+
2896
+ static VALUE
2897
+ cumcount_ki_native_i32 (VALUE self, CArray *ca, int axis)
2898
+ {
2899
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2900
+ INT2NUM(sizeof(int64_t)));
2901
+ CArray *co;
2902
+ GetCArray(vout, co);
2903
+
2904
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2905
+ iteration is one "fiber" along that axis with acc reset to
2906
+ INIT inside the macro. */
2907
+ int8_t slab_axes[CA_RANK_MAX];
2908
+ slab_axes[0] = (int8_t) axis;
2909
+ ca_iter_state st_in, st_out;
2910
+ int rc;
2911
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2912
+ slab_axes, 1, 0);
2913
+ if ( rc != CA_ITER_OK ) {
2914
+ rb_raise(rb_eRuntimeError,
2915
+ "cumcount_ki: input init failed rc=%d", rc);
2916
+ }
2917
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2918
+ slab_axes, 1, CA_KERNEL_WRITE);
2919
+ if ( rc != CA_ITER_OK ) {
2920
+ ca_iter_state_finish(&st_in);
2921
+ rb_raise(rb_eRuntimeError,
2922
+ "cumcount_ki: output init failed rc=%d", rc);
2923
+ }
2924
+
2925
+ char *pi, *po;
2926
+ boolean8_t *mi, *mo;
2927
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2928
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2929
+ CA_SLAB_SCAN_T(int32_t, int64_t, st_in, pi, mi,
2930
+ st_out, po, 0, (void) v; r = ++acc);
2931
+ ca_iter_state_sync_slab(&st_out);
2932
+ }
2933
+ ca_iter_state_finish(&st_in);
2934
+ ca_iter_state_finish(&st_out);
2935
+ return vout;
2936
+ }
2937
+
2938
+ static VALUE
2939
+ cumcount_ki_native_u32 (VALUE self, CArray *ca, int axis)
2940
+ {
2941
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2942
+ INT2NUM(sizeof(int64_t)));
2943
+ CArray *co;
2944
+ GetCArray(vout, co);
2945
+
2946
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2947
+ iteration is one "fiber" along that axis with acc reset to
2948
+ INIT inside the macro. */
2949
+ int8_t slab_axes[CA_RANK_MAX];
2950
+ slab_axes[0] = (int8_t) axis;
2951
+ ca_iter_state st_in, st_out;
2952
+ int rc;
2953
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2954
+ slab_axes, 1, 0);
2955
+ if ( rc != CA_ITER_OK ) {
2956
+ rb_raise(rb_eRuntimeError,
2957
+ "cumcount_ki: input init failed rc=%d", rc);
2958
+ }
2959
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
2960
+ slab_axes, 1, CA_KERNEL_WRITE);
2961
+ if ( rc != CA_ITER_OK ) {
2962
+ ca_iter_state_finish(&st_in);
2963
+ rb_raise(rb_eRuntimeError,
2964
+ "cumcount_ki: output init failed rc=%d", rc);
2965
+ }
2966
+
2967
+ char *pi, *po;
2968
+ boolean8_t *mi, *mo;
2969
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
2970
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
2971
+ CA_SLAB_SCAN_T(uint32_t, int64_t, st_in, pi, mi,
2972
+ st_out, po, 0, (void) v; r = ++acc);
2973
+ ca_iter_state_sync_slab(&st_out);
2974
+ }
2975
+ ca_iter_state_finish(&st_in);
2976
+ ca_iter_state_finish(&st_out);
2977
+ return vout;
2978
+ }
2979
+
2980
+ static VALUE
2981
+ cumcount_ki_native_i64 (VALUE self, CArray *ca, int axis)
2982
+ {
2983
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
2984
+ INT2NUM(sizeof(int64_t)));
2985
+ CArray *co;
2986
+ GetCArray(vout, co);
2987
+
2988
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
2989
+ iteration is one "fiber" along that axis with acc reset to
2990
+ INIT inside the macro. */
2991
+ int8_t slab_axes[CA_RANK_MAX];
2992
+ slab_axes[0] = (int8_t) axis;
2993
+ ca_iter_state st_in, st_out;
2994
+ int rc;
2995
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
2996
+ slab_axes, 1, 0);
2997
+ if ( rc != CA_ITER_OK ) {
2998
+ rb_raise(rb_eRuntimeError,
2999
+ "cumcount_ki: input init failed rc=%d", rc);
3000
+ }
3001
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3002
+ slab_axes, 1, CA_KERNEL_WRITE);
3003
+ if ( rc != CA_ITER_OK ) {
3004
+ ca_iter_state_finish(&st_in);
3005
+ rb_raise(rb_eRuntimeError,
3006
+ "cumcount_ki: output init failed rc=%d", rc);
3007
+ }
3008
+
3009
+ char *pi, *po;
3010
+ boolean8_t *mi, *mo;
3011
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3012
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3013
+ CA_SLAB_SCAN_T(int64_t, int64_t, st_in, pi, mi,
3014
+ st_out, po, 0, (void) v; r = ++acc);
3015
+ ca_iter_state_sync_slab(&st_out);
3016
+ }
3017
+ ca_iter_state_finish(&st_in);
3018
+ ca_iter_state_finish(&st_out);
3019
+ return vout;
3020
+ }
3021
+
3022
+ static VALUE
3023
+ cumcount_ki_native_u64 (VALUE self, CArray *ca, int axis)
3024
+ {
3025
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
3026
+ INT2NUM(sizeof(int64_t)));
3027
+ CArray *co;
3028
+ GetCArray(vout, co);
3029
+
3030
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3031
+ iteration is one "fiber" along that axis with acc reset to
3032
+ INIT inside the macro. */
3033
+ int8_t slab_axes[CA_RANK_MAX];
3034
+ slab_axes[0] = (int8_t) axis;
3035
+ ca_iter_state st_in, st_out;
3036
+ int rc;
3037
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3038
+ slab_axes, 1, 0);
3039
+ if ( rc != CA_ITER_OK ) {
3040
+ rb_raise(rb_eRuntimeError,
3041
+ "cumcount_ki: input init failed rc=%d", rc);
3042
+ }
3043
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3044
+ slab_axes, 1, CA_KERNEL_WRITE);
3045
+ if ( rc != CA_ITER_OK ) {
3046
+ ca_iter_state_finish(&st_in);
3047
+ rb_raise(rb_eRuntimeError,
3048
+ "cumcount_ki: output init failed rc=%d", rc);
3049
+ }
3050
+
3051
+ char *pi, *po;
3052
+ boolean8_t *mi, *mo;
3053
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3054
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3055
+ CA_SLAB_SCAN_T(uint64_t, int64_t, st_in, pi, mi,
3056
+ st_out, po, 0, (void) v; r = ++acc);
3057
+ ca_iter_state_sync_slab(&st_out);
3058
+ }
3059
+ ca_iter_state_finish(&st_in);
3060
+ ca_iter_state_finish(&st_out);
3061
+ return vout;
3062
+ }
3063
+
3064
+ static VALUE
3065
+ cumcount_ki_native_f32 (VALUE self, CArray *ca, int axis)
3066
+ {
3067
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
3068
+ INT2NUM(sizeof(int64_t)));
3069
+ CArray *co;
3070
+ GetCArray(vout, co);
3071
+
3072
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3073
+ iteration is one "fiber" along that axis with acc reset to
3074
+ INIT inside the macro. */
3075
+ int8_t slab_axes[CA_RANK_MAX];
3076
+ slab_axes[0] = (int8_t) axis;
3077
+ ca_iter_state st_in, st_out;
3078
+ int rc;
3079
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3080
+ slab_axes, 1, 0);
3081
+ if ( rc != CA_ITER_OK ) {
3082
+ rb_raise(rb_eRuntimeError,
3083
+ "cumcount_ki: input init failed rc=%d", rc);
3084
+ }
3085
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3086
+ slab_axes, 1, CA_KERNEL_WRITE);
3087
+ if ( rc != CA_ITER_OK ) {
3088
+ ca_iter_state_finish(&st_in);
3089
+ rb_raise(rb_eRuntimeError,
3090
+ "cumcount_ki: output init failed rc=%d", rc);
3091
+ }
3092
+
3093
+ char *pi, *po;
3094
+ boolean8_t *mi, *mo;
3095
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3096
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3097
+ CA_SLAB_SCAN_T(float, int64_t, st_in, pi, mi,
3098
+ st_out, po, 0, (void) v; r = ++acc);
3099
+ ca_iter_state_sync_slab(&st_out);
3100
+ }
3101
+ ca_iter_state_finish(&st_in);
3102
+ ca_iter_state_finish(&st_out);
3103
+ return vout;
3104
+ }
3105
+
3106
+ static VALUE
3107
+ cumcount_ki_native_f64 (VALUE self, CArray *ca, int axis)
3108
+ {
3109
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_INT64),
3110
+ INT2NUM(sizeof(int64_t)));
3111
+ CArray *co;
3112
+ GetCArray(vout, co);
3113
+
3114
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3115
+ iteration is one "fiber" along that axis with acc reset to
3116
+ INIT inside the macro. */
3117
+ int8_t slab_axes[CA_RANK_MAX];
3118
+ slab_axes[0] = (int8_t) axis;
3119
+ ca_iter_state st_in, st_out;
3120
+ int rc;
3121
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3122
+ slab_axes, 1, 0);
3123
+ if ( rc != CA_ITER_OK ) {
3124
+ rb_raise(rb_eRuntimeError,
3125
+ "cumcount_ki: input init failed rc=%d", rc);
3126
+ }
3127
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3128
+ slab_axes, 1, CA_KERNEL_WRITE);
3129
+ if ( rc != CA_ITER_OK ) {
3130
+ ca_iter_state_finish(&st_in);
3131
+ rb_raise(rb_eRuntimeError,
3132
+ "cumcount_ki: output init failed rc=%d", rc);
3133
+ }
3134
+
3135
+ char *pi, *po;
3136
+ boolean8_t *mi, *mo;
3137
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3138
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3139
+ CA_SLAB_SCAN_T(double, int64_t, st_in, pi, mi,
3140
+ st_out, po, 0, (void) v; r = ++acc);
3141
+ ca_iter_state_sync_slab(&st_out);
3142
+ }
3143
+ ca_iter_state_finish(&st_in);
3144
+ ca_iter_state_finish(&st_out);
3145
+ return vout;
3146
+ }
3147
+
3148
+ static VALUE
3149
+ rb_ca_cumcount_ki (int argc, VALUE *argv, VALUE self)
3150
+ {
3151
+ CArray *src;
3152
+ GetCArray(self, src);
3153
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
3154
+ volatile VALUE raxis = Qnil;
3155
+ rb_scan_options(ropt, "axis", &raxis);
3156
+ if ( argc > 0 ) {
3157
+ rb_raise(rb_eArgError, "cumcount_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.cumcount(axis: 0)", argc);
3158
+ }
3159
+ if ( NIL_P(raxis) ) {
3160
+ volatile VALUE vflat = rb_funcall(self, rb_intern("flatten"), 0);
3161
+ CArray *fsrc;
3162
+ GetCArray(vflat, fsrc);
3163
+ switch ( fsrc->data_type ) {
3164
+ case CA_INT8: return cumcount_ki_native_i8(vflat, fsrc, 0);
3165
+ case CA_UINT8: return cumcount_ki_native_u8(vflat, fsrc, 0);
3166
+ case CA_INT16: return cumcount_ki_native_i16(vflat, fsrc, 0);
3167
+ case CA_UINT16: return cumcount_ki_native_u16(vflat, fsrc, 0);
3168
+ case CA_INT32: return cumcount_ki_native_i32(vflat, fsrc, 0);
3169
+ case CA_UINT32: return cumcount_ki_native_u32(vflat, fsrc, 0);
3170
+ case CA_INT64: return cumcount_ki_native_i64(vflat, fsrc, 0);
3171
+ case CA_UINT64: return cumcount_ki_native_u64(vflat, fsrc, 0);
3172
+ case CA_FLOAT32: return cumcount_ki_native_f32(vflat, fsrc, 0);
3173
+ case CA_FLOAT64: return cumcount_ki_native_f64(vflat, fsrc, 0);
3174
+ default: {
3175
+ VALUE vsrc = rb_ca_wrap_readonly(vflat, INT2NUM(CA_FLOAT64));
3176
+ CArray *casted;
3177
+ GetCArray(vsrc, casted);
3178
+ return cumcount_ki_native_f64(vsrc, casted, 0);
3179
+ }
3180
+ }
3181
+ }
3182
+ if ( TYPE(raxis) == T_ARRAY ) {
3183
+ rb_raise(rb_eArgError, "cumcount_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.cumcount(axis: 0).cumcount(axis: 1)");
3184
+ }
3185
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
3186
+ rb_raise(rb_eTypeError, "cumcount_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
3187
+ }
3188
+ int axis = NUM2INT(raxis);
3189
+ if ( axis < 0 ) axis += src->ndim;
3190
+ if ( axis < 0 || axis >= src->ndim ) {
3191
+ rb_raise(rb_eArgError, "cumcount_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
3192
+ }
3193
+ switch ( src->data_type ) {
3194
+ case CA_INT8: return cumcount_ki_native_i8(self, src, axis);
3195
+ case CA_UINT8: return cumcount_ki_native_u8(self, src, axis);
3196
+ case CA_INT16: return cumcount_ki_native_i16(self, src, axis);
3197
+ case CA_UINT16: return cumcount_ki_native_u16(self, src, axis);
3198
+ case CA_INT32: return cumcount_ki_native_i32(self, src, axis);
3199
+ case CA_UINT32: return cumcount_ki_native_u32(self, src, axis);
3200
+ case CA_INT64: return cumcount_ki_native_i64(self, src, axis);
3201
+ case CA_UINT64: return cumcount_ki_native_u64(self, src, axis);
3202
+ case CA_FLOAT32: return cumcount_ki_native_f32(self, src, axis);
3203
+ case CA_FLOAT64: return cumcount_ki_native_f64(self, src, axis);
3204
+ default: {
3205
+ VALUE vsrc = rb_ca_wrap_readonly(self, INT2NUM(CA_FLOAT64));
3206
+ CArray *casted;
3207
+ GetCArray(vsrc, casted);
3208
+ return cumcount_ki_native_f64(vsrc, casted, axis);
3209
+ }
3210
+ }
3211
+ return Qnil; /* unreachable */
3212
+ }
3213
+
3214
+ /* ===== uniq_scan_ki ============================================ */
3215
+
3216
+ static VALUE
3217
+ uniq_scan_ki_native_i8 (VALUE self, CArray *ca, int axis)
3218
+ {
3219
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3220
+ INT2NUM(sizeof(boolean8_t)));
3221
+ CArray *co;
3222
+ GetCArray(vout, co);
3223
+
3224
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3225
+ iteration is one "fiber" along that axis with acc reset to
3226
+ INIT inside the macro. */
3227
+ int8_t slab_axes[CA_RANK_MAX];
3228
+ slab_axes[0] = (int8_t) axis;
3229
+ ca_iter_state st_in, st_out;
3230
+ int rc;
3231
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3232
+ slab_axes, 1, 0);
3233
+ if ( rc != CA_ITER_OK ) {
3234
+ rb_raise(rb_eRuntimeError,
3235
+ "uniq_scan_ki: input init failed rc=%d", rc);
3236
+ }
3237
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3238
+ slab_axes, 1, CA_KERNEL_WRITE);
3239
+ if ( rc != CA_ITER_OK ) {
3240
+ ca_iter_state_finish(&st_in);
3241
+ rb_raise(rb_eRuntimeError,
3242
+ "uniq_scan_ki: output init failed rc=%d", rc);
3243
+ }
3244
+
3245
+ char *pi, *po;
3246
+ boolean8_t *mi, *mo;
3247
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3248
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3249
+ CA_SLAB_SCAN_TA(int8_t, boolean8_t, int8_t, st_in, pi, mi,
3250
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3251
+ ca_iter_state_sync_slab(&st_out);
3252
+ }
3253
+ ca_iter_state_finish(&st_in);
3254
+ ca_iter_state_finish(&st_out);
3255
+ return vout;
3256
+ }
3257
+
3258
+ static VALUE
3259
+ uniq_scan_ki_native_u8 (VALUE self, CArray *ca, int axis)
3260
+ {
3261
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3262
+ INT2NUM(sizeof(boolean8_t)));
3263
+ CArray *co;
3264
+ GetCArray(vout, co);
3265
+
3266
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3267
+ iteration is one "fiber" along that axis with acc reset to
3268
+ INIT inside the macro. */
3269
+ int8_t slab_axes[CA_RANK_MAX];
3270
+ slab_axes[0] = (int8_t) axis;
3271
+ ca_iter_state st_in, st_out;
3272
+ int rc;
3273
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3274
+ slab_axes, 1, 0);
3275
+ if ( rc != CA_ITER_OK ) {
3276
+ rb_raise(rb_eRuntimeError,
3277
+ "uniq_scan_ki: input init failed rc=%d", rc);
3278
+ }
3279
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3280
+ slab_axes, 1, CA_KERNEL_WRITE);
3281
+ if ( rc != CA_ITER_OK ) {
3282
+ ca_iter_state_finish(&st_in);
3283
+ rb_raise(rb_eRuntimeError,
3284
+ "uniq_scan_ki: output init failed rc=%d", rc);
3285
+ }
3286
+
3287
+ char *pi, *po;
3288
+ boolean8_t *mi, *mo;
3289
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3290
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3291
+ CA_SLAB_SCAN_TA(uint8_t, boolean8_t, uint8_t, st_in, pi, mi,
3292
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3293
+ ca_iter_state_sync_slab(&st_out);
3294
+ }
3295
+ ca_iter_state_finish(&st_in);
3296
+ ca_iter_state_finish(&st_out);
3297
+ return vout;
3298
+ }
3299
+
3300
+ static VALUE
3301
+ uniq_scan_ki_native_i16 (VALUE self, CArray *ca, int axis)
3302
+ {
3303
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3304
+ INT2NUM(sizeof(boolean8_t)));
3305
+ CArray *co;
3306
+ GetCArray(vout, co);
3307
+
3308
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3309
+ iteration is one "fiber" along that axis with acc reset to
3310
+ INIT inside the macro. */
3311
+ int8_t slab_axes[CA_RANK_MAX];
3312
+ slab_axes[0] = (int8_t) axis;
3313
+ ca_iter_state st_in, st_out;
3314
+ int rc;
3315
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3316
+ slab_axes, 1, 0);
3317
+ if ( rc != CA_ITER_OK ) {
3318
+ rb_raise(rb_eRuntimeError,
3319
+ "uniq_scan_ki: input init failed rc=%d", rc);
3320
+ }
3321
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3322
+ slab_axes, 1, CA_KERNEL_WRITE);
3323
+ if ( rc != CA_ITER_OK ) {
3324
+ ca_iter_state_finish(&st_in);
3325
+ rb_raise(rb_eRuntimeError,
3326
+ "uniq_scan_ki: output init failed rc=%d", rc);
3327
+ }
3328
+
3329
+ char *pi, *po;
3330
+ boolean8_t *mi, *mo;
3331
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3332
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3333
+ CA_SLAB_SCAN_TA(int16_t, boolean8_t, int16_t, st_in, pi, mi,
3334
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3335
+ ca_iter_state_sync_slab(&st_out);
3336
+ }
3337
+ ca_iter_state_finish(&st_in);
3338
+ ca_iter_state_finish(&st_out);
3339
+ return vout;
3340
+ }
3341
+
3342
+ static VALUE
3343
+ uniq_scan_ki_native_u16 (VALUE self, CArray *ca, int axis)
3344
+ {
3345
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3346
+ INT2NUM(sizeof(boolean8_t)));
3347
+ CArray *co;
3348
+ GetCArray(vout, co);
3349
+
3350
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3351
+ iteration is one "fiber" along that axis with acc reset to
3352
+ INIT inside the macro. */
3353
+ int8_t slab_axes[CA_RANK_MAX];
3354
+ slab_axes[0] = (int8_t) axis;
3355
+ ca_iter_state st_in, st_out;
3356
+ int rc;
3357
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3358
+ slab_axes, 1, 0);
3359
+ if ( rc != CA_ITER_OK ) {
3360
+ rb_raise(rb_eRuntimeError,
3361
+ "uniq_scan_ki: input init failed rc=%d", rc);
3362
+ }
3363
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3364
+ slab_axes, 1, CA_KERNEL_WRITE);
3365
+ if ( rc != CA_ITER_OK ) {
3366
+ ca_iter_state_finish(&st_in);
3367
+ rb_raise(rb_eRuntimeError,
3368
+ "uniq_scan_ki: output init failed rc=%d", rc);
3369
+ }
3370
+
3371
+ char *pi, *po;
3372
+ boolean8_t *mi, *mo;
3373
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3374
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3375
+ CA_SLAB_SCAN_TA(uint16_t, boolean8_t, uint16_t, st_in, pi, mi,
3376
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3377
+ ca_iter_state_sync_slab(&st_out);
3378
+ }
3379
+ ca_iter_state_finish(&st_in);
3380
+ ca_iter_state_finish(&st_out);
3381
+ return vout;
3382
+ }
3383
+
3384
+ static VALUE
3385
+ uniq_scan_ki_native_i32 (VALUE self, CArray *ca, int axis)
3386
+ {
3387
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3388
+ INT2NUM(sizeof(boolean8_t)));
3389
+ CArray *co;
3390
+ GetCArray(vout, co);
3391
+
3392
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3393
+ iteration is one "fiber" along that axis with acc reset to
3394
+ INIT inside the macro. */
3395
+ int8_t slab_axes[CA_RANK_MAX];
3396
+ slab_axes[0] = (int8_t) axis;
3397
+ ca_iter_state st_in, st_out;
3398
+ int rc;
3399
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3400
+ slab_axes, 1, 0);
3401
+ if ( rc != CA_ITER_OK ) {
3402
+ rb_raise(rb_eRuntimeError,
3403
+ "uniq_scan_ki: input init failed rc=%d", rc);
3404
+ }
3405
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3406
+ slab_axes, 1, CA_KERNEL_WRITE);
3407
+ if ( rc != CA_ITER_OK ) {
3408
+ ca_iter_state_finish(&st_in);
3409
+ rb_raise(rb_eRuntimeError,
3410
+ "uniq_scan_ki: output init failed rc=%d", rc);
3411
+ }
3412
+
3413
+ char *pi, *po;
3414
+ boolean8_t *mi, *mo;
3415
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3416
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3417
+ CA_SLAB_SCAN_TA(int32_t, boolean8_t, int32_t, st_in, pi, mi,
3418
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3419
+ ca_iter_state_sync_slab(&st_out);
3420
+ }
3421
+ ca_iter_state_finish(&st_in);
3422
+ ca_iter_state_finish(&st_out);
3423
+ return vout;
3424
+ }
3425
+
3426
+ static VALUE
3427
+ uniq_scan_ki_native_u32 (VALUE self, CArray *ca, int axis)
3428
+ {
3429
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3430
+ INT2NUM(sizeof(boolean8_t)));
3431
+ CArray *co;
3432
+ GetCArray(vout, co);
3433
+
3434
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3435
+ iteration is one "fiber" along that axis with acc reset to
3436
+ INIT inside the macro. */
3437
+ int8_t slab_axes[CA_RANK_MAX];
3438
+ slab_axes[0] = (int8_t) axis;
3439
+ ca_iter_state st_in, st_out;
3440
+ int rc;
3441
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3442
+ slab_axes, 1, 0);
3443
+ if ( rc != CA_ITER_OK ) {
3444
+ rb_raise(rb_eRuntimeError,
3445
+ "uniq_scan_ki: input init failed rc=%d", rc);
3446
+ }
3447
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3448
+ slab_axes, 1, CA_KERNEL_WRITE);
3449
+ if ( rc != CA_ITER_OK ) {
3450
+ ca_iter_state_finish(&st_in);
3451
+ rb_raise(rb_eRuntimeError,
3452
+ "uniq_scan_ki: output init failed rc=%d", rc);
3453
+ }
3454
+
3455
+ char *pi, *po;
3456
+ boolean8_t *mi, *mo;
3457
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3458
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3459
+ CA_SLAB_SCAN_TA(uint32_t, boolean8_t, uint32_t, st_in, pi, mi,
3460
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3461
+ ca_iter_state_sync_slab(&st_out);
3462
+ }
3463
+ ca_iter_state_finish(&st_in);
3464
+ ca_iter_state_finish(&st_out);
3465
+ return vout;
3466
+ }
3467
+
3468
+ static VALUE
3469
+ uniq_scan_ki_native_i64 (VALUE self, CArray *ca, int axis)
3470
+ {
3471
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3472
+ INT2NUM(sizeof(boolean8_t)));
3473
+ CArray *co;
3474
+ GetCArray(vout, co);
3475
+
3476
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3477
+ iteration is one "fiber" along that axis with acc reset to
3478
+ INIT inside the macro. */
3479
+ int8_t slab_axes[CA_RANK_MAX];
3480
+ slab_axes[0] = (int8_t) axis;
3481
+ ca_iter_state st_in, st_out;
3482
+ int rc;
3483
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3484
+ slab_axes, 1, 0);
3485
+ if ( rc != CA_ITER_OK ) {
3486
+ rb_raise(rb_eRuntimeError,
3487
+ "uniq_scan_ki: input init failed rc=%d", rc);
3488
+ }
3489
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3490
+ slab_axes, 1, CA_KERNEL_WRITE);
3491
+ if ( rc != CA_ITER_OK ) {
3492
+ ca_iter_state_finish(&st_in);
3493
+ rb_raise(rb_eRuntimeError,
3494
+ "uniq_scan_ki: output init failed rc=%d", rc);
3495
+ }
3496
+
3497
+ char *pi, *po;
3498
+ boolean8_t *mi, *mo;
3499
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3500
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3501
+ CA_SLAB_SCAN_TA(int64_t, boolean8_t, int64_t, st_in, pi, mi,
3502
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3503
+ ca_iter_state_sync_slab(&st_out);
3504
+ }
3505
+ ca_iter_state_finish(&st_in);
3506
+ ca_iter_state_finish(&st_out);
3507
+ return vout;
3508
+ }
3509
+
3510
+ static VALUE
3511
+ uniq_scan_ki_native_u64 (VALUE self, CArray *ca, int axis)
3512
+ {
3513
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3514
+ INT2NUM(sizeof(boolean8_t)));
3515
+ CArray *co;
3516
+ GetCArray(vout, co);
3517
+
3518
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3519
+ iteration is one "fiber" along that axis with acc reset to
3520
+ INIT inside the macro. */
3521
+ int8_t slab_axes[CA_RANK_MAX];
3522
+ slab_axes[0] = (int8_t) axis;
3523
+ ca_iter_state st_in, st_out;
3524
+ int rc;
3525
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3526
+ slab_axes, 1, 0);
3527
+ if ( rc != CA_ITER_OK ) {
3528
+ rb_raise(rb_eRuntimeError,
3529
+ "uniq_scan_ki: input init failed rc=%d", rc);
3530
+ }
3531
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3532
+ slab_axes, 1, CA_KERNEL_WRITE);
3533
+ if ( rc != CA_ITER_OK ) {
3534
+ ca_iter_state_finish(&st_in);
3535
+ rb_raise(rb_eRuntimeError,
3536
+ "uniq_scan_ki: output init failed rc=%d", rc);
3537
+ }
3538
+
3539
+ char *pi, *po;
3540
+ boolean8_t *mi, *mo;
3541
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3542
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3543
+ CA_SLAB_SCAN_TA(uint64_t, boolean8_t, uint64_t, st_in, pi, mi,
3544
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3545
+ ca_iter_state_sync_slab(&st_out);
3546
+ }
3547
+ ca_iter_state_finish(&st_in);
3548
+ ca_iter_state_finish(&st_out);
3549
+ return vout;
3550
+ }
3551
+
3552
+ static VALUE
3553
+ uniq_scan_ki_native_f32 (VALUE self, CArray *ca, int axis)
3554
+ {
3555
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3556
+ INT2NUM(sizeof(boolean8_t)));
3557
+ CArray *co;
3558
+ GetCArray(vout, co);
3559
+
3560
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3561
+ iteration is one "fiber" along that axis with acc reset to
3562
+ INIT inside the macro. */
3563
+ int8_t slab_axes[CA_RANK_MAX];
3564
+ slab_axes[0] = (int8_t) axis;
3565
+ ca_iter_state st_in, st_out;
3566
+ int rc;
3567
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3568
+ slab_axes, 1, 0);
3569
+ if ( rc != CA_ITER_OK ) {
3570
+ rb_raise(rb_eRuntimeError,
3571
+ "uniq_scan_ki: input init failed rc=%d", rc);
3572
+ }
3573
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3574
+ slab_axes, 1, CA_KERNEL_WRITE);
3575
+ if ( rc != CA_ITER_OK ) {
3576
+ ca_iter_state_finish(&st_in);
3577
+ rb_raise(rb_eRuntimeError,
3578
+ "uniq_scan_ki: output init failed rc=%d", rc);
3579
+ }
3580
+
3581
+ char *pi, *po;
3582
+ boolean8_t *mi, *mo;
3583
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3584
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3585
+ CA_SLAB_SCAN_TA(float, boolean8_t, float, st_in, pi, mi,
3586
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3587
+ ca_iter_state_sync_slab(&st_out);
3588
+ }
3589
+ ca_iter_state_finish(&st_in);
3590
+ ca_iter_state_finish(&st_out);
3591
+ return vout;
3592
+ }
3593
+
3594
+ static VALUE
3595
+ uniq_scan_ki_native_f64 (VALUE self, CArray *ca, int axis)
3596
+ {
3597
+ VALUE vout = rb_ca_template_with_type(self, INT2NUM(CA_BOOLEAN),
3598
+ INT2NUM(sizeof(boolean8_t)));
3599
+ CArray *co;
3600
+ GetCArray(vout, co);
3601
+
3602
+ /* 1-axis scan: slab = the scan axis only. Each next_slab_axes
3603
+ iteration is one "fiber" along that axis with acc reset to
3604
+ INIT inside the macro. */
3605
+ int8_t slab_axes[CA_RANK_MAX];
3606
+ slab_axes[0] = (int8_t) axis;
3607
+ ca_iter_state st_in, st_out;
3608
+ int rc;
3609
+ rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3610
+ slab_axes, 1, 0);
3611
+ if ( rc != CA_ITER_OK ) {
3612
+ rb_raise(rb_eRuntimeError,
3613
+ "uniq_scan_ki: input init failed rc=%d", rc);
3614
+ }
3615
+ rc = ca_iter_state_init_l2(&st_out, co, CA_SLAB_AXES,
3616
+ slab_axes, 1, CA_KERNEL_WRITE);
3617
+ if ( rc != CA_ITER_OK ) {
3618
+ ca_iter_state_finish(&st_in);
3619
+ rb_raise(rb_eRuntimeError,
3620
+ "uniq_scan_ki: output init failed rc=%d", rc);
3621
+ }
3622
+
3623
+ char *pi, *po;
3624
+ boolean8_t *mi, *mo;
3625
+ while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
3626
+ ca_iter_state_next_slab_axes(&st_out, &po, &mo) ) {
3627
+ CA_SLAB_SCAN_TA(double, boolean8_t, double, st_in, pi, mi,
3628
+ st_out, po, 0, if (first) { acc = v; r = 0; } else if (v == acc) { r = 1; } else { acc = v; r = 0; });
3629
+ ca_iter_state_sync_slab(&st_out);
3630
+ }
3631
+ ca_iter_state_finish(&st_in);
3632
+ ca_iter_state_finish(&st_out);
3633
+ return vout;
3634
+ }
3635
+
3636
+ static VALUE
3637
+ rb_ca_uniq_scan_ki (int argc, VALUE *argv, VALUE self)
3638
+ {
3639
+ CArray *src;
3640
+ GetCArray(self, src);
3641
+ volatile VALUE ropt = rb_pop_options(&argc, &argv);
3642
+ volatile VALUE raxis = Qnil;
3643
+ rb_scan_options(ropt, "axis", &raxis);
3644
+ if ( argc > 0 ) {
3645
+ rb_raise(rb_eArgError, "uniq_scan_ki: positional axis is no longer accepted (got %d); use axis: kwarg, e.g. a.uniq_scan(axis: 0)", argc);
3646
+ }
3647
+ if ( NIL_P(raxis) ) {
3648
+ rb_raise(rb_eArgError, "uniq_scan_ki: axis: kwarg is required (single axis Integer; multi-axis scan is semantically ambiguous)");
3649
+ }
3650
+ if ( TYPE(raxis) == T_ARRAY ) {
3651
+ rb_raise(rb_eArgError, "uniq_scan_ki: axis: must be Integer (got Array); multi-axis scan is semantically ambiguous, chain explicitly: a.uniq_scan(axis: 0).uniq_scan(axis: 1)");
3652
+ }
3653
+ if ( ! rb_obj_is_kind_of(raxis, rb_cInteger) ) {
3654
+ rb_raise(rb_eTypeError, "uniq_scan_ki: axis: must be Integer (got %"PRIsVALUE")", rb_obj_class(raxis));
3655
+ }
3656
+ int axis = NUM2INT(raxis);
3657
+ if ( axis < 0 ) axis += src->ndim;
3658
+ if ( axis < 0 || axis >= src->ndim ) {
3659
+ rb_raise(rb_eArgError, "uniq_scan_ki: axis %d out of range for ndim %d", NUM2INT(raxis), src->ndim);
3660
+ }
3661
+ switch ( src->data_type ) {
3662
+ case CA_INT8: return uniq_scan_ki_native_i8(self, src, axis);
3663
+ case CA_UINT8: return uniq_scan_ki_native_u8(self, src, axis);
3664
+ case CA_INT16: return uniq_scan_ki_native_i16(self, src, axis);
3665
+ case CA_UINT16: return uniq_scan_ki_native_u16(self, src, axis);
3666
+ case CA_INT32: return uniq_scan_ki_native_i32(self, src, axis);
3667
+ case CA_UINT32: return uniq_scan_ki_native_u32(self, src, axis);
3668
+ case CA_INT64: return uniq_scan_ki_native_i64(self, src, axis);
3669
+ case CA_UINT64: return uniq_scan_ki_native_u64(self, src, axis);
3670
+ case CA_FLOAT32: return uniq_scan_ki_native_f32(self, src, axis);
3671
+ case CA_FLOAT64: return uniq_scan_ki_native_f64(self, src, axis);
3672
+ default:
3673
+ rb_raise(rb_eCADataTypeError, "uniq_scan_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]);
3674
+ }
3675
+ return Qnil; /* unreachable */
3676
+ }
3677
+
3678
+ void
3679
+ Init_carray_kernels_scan (void)
3680
+ {
3681
+ rb_define_method(rb_cCArray, "cumsum_ki", rb_ca_cumsum_ki, -1);
3682
+ rb_define_method(rb_cCArray, "cumsum", rb_ca_cumsum_ki, -1);
3683
+ rb_define_method(rb_cCArray, "cumprod_ki", rb_ca_cumprod_ki, -1);
3684
+ rb_define_method(rb_cCArray, "cumprod", rb_ca_cumprod_ki, -1);
3685
+ rb_define_method(rb_cCArray, "cummax_ki", rb_ca_cummax_ki, -1);
3686
+ rb_define_method(rb_cCArray, "cummax", rb_ca_cummax_ki, -1);
3687
+ rb_define_method(rb_cCArray, "cummin_ki", rb_ca_cummin_ki, -1);
3688
+ rb_define_method(rb_cCArray, "cummin", rb_ca_cummin_ki, -1);
3689
+ rb_define_method(rb_cCArray, "cumcount_ki", rb_ca_cumcount_ki, -1);
3690
+ rb_define_method(rb_cCArray, "cumcount", rb_ca_cumcount_ki, -1);
3691
+ rb_define_method(rb_cCArray, "uniq_scan_ki", rb_ca_uniq_scan_ki, -1);
3692
+ }