carray 2.0.1 → 3.0.1

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