carray 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +772 -297
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +229 -791
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +207 -240
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1341 -198
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +5 -15
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/mailmap +0 -1
  269. data/misc/Methods.ja.md +0 -182
  270. data/misc/NOTE +0 -51
  271. data/spec/Classes/CABitfield_spec.rb +0 -58
  272. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  273. data/spec/Classes/CABlock_spec.rb +0 -205
  274. data/spec/Classes/CAField_spec.rb +0 -39
  275. data/spec/Classes/CAGrid_spec.rb +0 -75
  276. data/spec/Classes/CAMap_spec.rb +0 -0
  277. data/spec/Classes/CAMapping_spec.rb +0 -105
  278. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  279. data/spec/Classes/CAObject_spec.rb +0 -33
  280. data/spec/Classes/CARefer_spec.rb +0 -93
  281. data/spec/Classes/CARepeat_spec.rb +0 -65
  282. data/spec/Classes/CASelect_spec.rb +0 -22
  283. data/spec/Classes/CAShift_spec.rb +0 -16
  284. data/spec/Classes/CAStruct_spec.rb +0 -71
  285. data/spec/Classes/CATranspose_spec.rb +0 -60
  286. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  287. data/spec/Classes/CAWindow_spec.rb +0 -54
  288. data/spec/Classes/CAWrap_spec.rb +0 -8
  289. data/spec/Classes/CArray_spec.rb +0 -184
  290. data/spec/Classes/CScalar_spec.rb +0 -55
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -0,0 +1,569 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ CAMonCmp — lazy monadic element-wise comparison view: is_nan /
4
+ is_inf / is_finite / is_invalid / signbit. Output data_type =
5
+ CA_BOOLEAN (1 byte); operand keeps its native data_type (per-dtype
6
+ kernels cover integer as well, so is_nan / is_inf on integer parents
7
+ return const-false and is_finite const-true without a cast layer).
8
+
9
+ xfer_stride model:
10
+ Output data_type (boolean8_t) differs from the operand data_type,
11
+ so the in-place chain-eval trick used by CAMonOp does not apply.
12
+ The parent is pulled into an operand-data_type scratch slab, then
13
+ the moncmp kernel writes boolean8_t into `data`:
14
+ 1. acquire scratch (slab_n * parent_bytes) — or use the parent's
15
+ live ptr directly via ca_moncmp_try_leaf_inplace
16
+ 2. ca_xfer_stride pulls the parent slab into scratch
17
+ 3. kernel: fn(n, m, scratch, 1, data, 1)
18
+ 4. release scratch
19
+
20
+ Peak scratch: 1 operand-data_type slab.
21
+
22
+ Mask propagation:
23
+ Per-dtype moncmp kernels write only at non-masked positions, so
24
+ the standard create_mask = parent.mask machinery carries mask bits
25
+ to the caller-visible result. No in-flight mask handling in
26
+ xfer_stride.
27
+
28
+ ---------------------------------------------------------------------------- */
29
+
30
+ #include "carray.h"
31
+ #include "carray_internal.h" /* ca_lazy_arena_* */
32
+ #include "ca_moncmp_dispatch.h"
33
+
34
+ extern void *ca_lazy_arena_acquire (ca_size_t bytes);
35
+ extern void ca_lazy_arena_release (void *ptr);
36
+
37
+ int8_t CA_OBJ_MONCMP;
38
+ VALUE rb_cCAMonCmp;
39
+
40
+ extern int8_t CA_OBJ_LAZY_MARKER;
41
+
42
+ /* ------------------------------------------------------------------- */
43
+ /* CAMonCmp struct */
44
+ /* ------------------------------------------------------------------- */
45
+
46
+ typedef struct CAMonCmp {
47
+ int16_t obj_type;
48
+ int8_t data_type; /* always CA_BOOLEAN */
49
+ int8_t ndim;
50
+ int32_t flags;
51
+ ca_size_t bytes; /* always 1 */
52
+ ca_size_t elements;
53
+ ca_size_t *dim;
54
+ char *ptr;
55
+ CArray *mask;
56
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
57
+ CArray *parent;
58
+ uint32_t attach;
59
+ uint8_t nosync;
60
+ /* CAMonCmp-specific tail */
61
+ uint16_t op_id;
62
+ } CAMonCmp;
63
+
64
+ static size_t
65
+ ca_moncmp_dsize (const void *ap)
66
+ {
67
+ const CAMonCmp *ca = (const CAMonCmp *) ap;
68
+ return sizeof(CAMonCmp) + ca->ndim * sizeof(ca_size_t);
69
+ }
70
+
71
+ /* Pool framework hooks: single ndim-sized tail (dim) in the _pool
72
+ buffer, uniform with the other pool-migrated views. */
73
+ static size_t
74
+ ca_moncmp_pool_bytes (int8_t ndim)
75
+ {
76
+ ca_size_t n = (ndim > 0) ? ndim : 1;
77
+ return (size_t) n * sizeof(ca_size_t);
78
+ }
79
+
80
+ static void
81
+ ca_moncmp_pool_init (void *ap, int8_t ndim)
82
+ {
83
+ CAMonCmp *ca = (CAMonCmp *) ap;
84
+ ca->dim = (ca_size_t *) ca->_pool;
85
+ }
86
+
87
+ const rb_data_type_t camoncmp_data_type = {
88
+ .parent = &caview_data_type,
89
+ .wrap_struct_name = "CAMonCmp",
90
+ .function = {
91
+ .dmark = ca_mark,
92
+ .dfree = ca_free,
93
+ .dsize = ca_moncmp_dsize,
94
+ .dcompact = NULL
95
+ },
96
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
97
+ };
98
+
99
+ /* ------------------------------------------------------------------- */
100
+ /* setup / new / free */
101
+ /* ------------------------------------------------------------------- */
102
+
103
+ static int
104
+ ca_moncmp_setup (CAMonCmp *ca, CArray *parent, uint16_t op_id)
105
+ {
106
+ ca->obj_type = CA_OBJ_MONCMP;
107
+ ca->data_type = CA_BOOLEAN;
108
+ ca->flags = CA_FLAG_READ_ONLY;
109
+ ca->ndim = parent->ndim;
110
+ ca->bytes = 1;
111
+ ca->elements = parent->elements;
112
+ ca->ptr = NULL;
113
+ ca->mask = NULL;
114
+ if ( ! ca->_pool ) {
115
+ ca->dim = ALLOC_N(ca_size_t, parent->ndim);
116
+ }
117
+ ca->parent = parent;
118
+ ca->attach = 0;
119
+ ca->nosync = 0;
120
+ ca->op_id = op_id;
121
+
122
+ memcpy(ca->dim, parent->dim, parent->ndim * sizeof(ca_size_t));
123
+
124
+ if ( ca_has_mask(parent) ) {
125
+ ca_create_mask(ca);
126
+ }
127
+ if ( ca_is_scalar(parent) ) {
128
+ ca_set_flag(ca, CA_FLAG_SCALAR);
129
+ }
130
+ return 0;
131
+ }
132
+
133
+ CAMonCmp *
134
+ ca_moncmp_new (CArray *parent, uint16_t op_id)
135
+ {
136
+ CAMonCmp *ca = (CAMonCmp *) ca_array_alloc(CA_OBJ_MONCMP, parent->ndim);
137
+ ca_moncmp_setup(ca, parent, op_id);
138
+ return ca;
139
+ }
140
+
141
+ static void
142
+ free_ca_moncmp (void *ap)
143
+ {
144
+ CAMonCmp *ca = (CAMonCmp *) ap;
145
+ if ( ca != NULL ) {
146
+ ca_free(ca->mask);
147
+ if ( ca->_pool ) {
148
+ ca_array_free(ca); /* dim lives in _pool */
149
+ }
150
+ else {
151
+ xfree(ca->dim);
152
+ xfree(ca);
153
+ }
154
+ }
155
+ }
156
+
157
+ /* ------------------------------------------------------------------- */
158
+ /* operation function table */
159
+ /* ------------------------------------------------------------------- */
160
+
161
+ static void ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts,
162
+ ca_size_t *counts,
163
+ ca_size_t *strides,
164
+ void *data, int dir);
165
+
166
+ static void *
167
+ ca_moncmp_func_clone (void *ap)
168
+ {
169
+ CAMonCmp *ca = (CAMonCmp *) ap;
170
+ return ca_moncmp_new(ca->parent, ca->op_id);
171
+ }
172
+
173
+ static void
174
+ ca_moncmp_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
175
+ {
176
+ CAMonCmp *ca = (CAMonCmp *) ap;
177
+ ca_size_t starts[CA_RANK_MAX];
178
+ ca_size_t counts[CA_RANK_MAX];
179
+ ca_size_t strides[CA_RANK_MAX];
180
+ int8_t k;
181
+
182
+ if ( dir != CA_XFER_GET ) {
183
+ rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_index PUT)");
184
+ }
185
+ for ( k = ca->ndim - 1; k >= 0; k-- ) {
186
+ starts[k] = idx[k];
187
+ counts[k] = 1;
188
+ strides[k] = 1;
189
+ }
190
+ ca_moncmp_func_xfer_stride(ca, starts, counts, strides, data, CA_XFER_GET);
191
+ }
192
+
193
+ static void
194
+ ca_moncmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
195
+ void *data, int dir)
196
+ {
197
+ CAMonCmp *ca = (CAMonCmp *) ap;
198
+ ca_size_t i;
199
+ char *out = (char *) data;
200
+
201
+ if ( dir != CA_XFER_GET ) {
202
+ rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_addrs PUT)");
203
+ }
204
+ for ( i = 0; i < n; i++ ) {
205
+ ca_size_t idx[CA_RANK_MAX];
206
+ ca_addr2index((CArray *)ca, addrs[i], idx);
207
+ ca_moncmp_func_xfer_index(ca, idx, out + i, CA_XFER_GET);
208
+ }
209
+ }
210
+
211
+ ca_size_t ca_moncmp_scratch_acquire_count = 0;
212
+ ca_size_t ca_moncmp_materialise_call_count = 0;
213
+ ca_size_t ca_moncmp_leaf_inplace_count = 0;
214
+
215
+ /* Leaf-operand in-place read: when the parent is an entity-like
216
+ contig source, hand parent->ptr + byte_offset directly to the
217
+ kernel and skip the arena acquire + xfer_stride pull. Mirrors the
218
+ sibling helper in ca_obj_bincmp.c. */
219
+ static int
220
+ ca_moncmp_try_leaf_inplace (CArray *p,
221
+ ca_size_t *starts, ca_size_t *counts,
222
+ ca_size_t expected_inner_byte_stride,
223
+ char **out_ptr)
224
+ {
225
+ ca_size_t row_strides[CA_RANK_MAX];
226
+ ca_size_t s, byte_off;
227
+ int8_t k;
228
+
229
+ if ( p->ptr == NULL ) return 0;
230
+ if ( p->bytes != expected_inner_byte_stride ) return 0;
231
+
232
+ s = p->bytes;
233
+ for ( k = p->ndim - 1; k >= 0; k-- ) {
234
+ row_strides[k] = s;
235
+ s *= p->dim[k];
236
+ }
237
+ byte_off = 0;
238
+ for ( k = 0; k < p->ndim; k++ ) {
239
+ if ( starts[k] < 0 || starts[k] + counts[k] > p->dim[k] ) return 0;
240
+ byte_off += starts[k] * row_strides[k];
241
+ }
242
+ *out_ptr = p->ptr + byte_off;
243
+ return 1;
244
+ }
245
+
246
+ static void
247
+ ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
248
+ ca_size_t *strides, void *data, int dir)
249
+ {
250
+ CAMonCmp *mc = (CAMonCmp *) ap;
251
+ ca_size_t slab_n;
252
+ int8_t k;
253
+ void *scratch;
254
+ ca_size_t operand_bytes;
255
+
256
+ if ( dir != CA_XFER_GET ) {
257
+ rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (xfer_stride PUT)");
258
+ }
259
+ ca_moncmp_materialise_call_count++;
260
+
261
+ slab_n = 1;
262
+ for ( k = 0; k < mc->ndim; k++ ) slab_n *= counts[k];
263
+
264
+ operand_bytes = mc->parent->bytes;
265
+
266
+ /* === 1. pull parent (leaf-opt or scratch) === */
267
+ int scratch_is_inplace = 0;
268
+ {
269
+ char *inplace = NULL;
270
+ if ( ca_moncmp_try_leaf_inplace(mc->parent, starts, counts,
271
+ operand_bytes, &inplace) ) {
272
+ scratch = inplace;
273
+ scratch_is_inplace = 1;
274
+ ca_moncmp_leaf_inplace_count++;
275
+ }
276
+ else {
277
+ ca_size_t scratch_strides[CA_RANK_MAX];
278
+ ca_size_t s = operand_bytes;
279
+ for ( k = mc->ndim - 1; k >= 0; k-- ) {
280
+ scratch_strides[k] = s;
281
+ s *= counts[k];
282
+ }
283
+ scratch = ca_lazy_arena_acquire(slab_n * operand_bytes);
284
+ ca_moncmp_scratch_acquire_count++;
285
+ ca_xfer_stride(mc->parent, starts, counts, scratch_strides, scratch,
286
+ CA_XFER_GET);
287
+ }
288
+ }
289
+
290
+ /* === 2. apply moncmp kernel ===
291
+ *
292
+ * Kernel signature (ext/carray.h):
293
+ * fn(n, m, ptr1, i1, ptr2, i2)
294
+ * where ptr2 is boolean8_t*
295
+ *
296
+ * Non-trapping: m=NULL (= SIMD fast path). Per-data_type kernel handles
297
+ * integer is_nan etc. internally.
298
+ */
299
+ {
300
+ ca_moncmp_func_t fn = ca_moncmp_kernel_lookup(mc->op_id,
301
+ mc->parent->data_type);
302
+ if ( fn == NULL ) {
303
+ if ( ! scratch_is_inplace ) ca_lazy_arena_release(scratch);
304
+ rb_raise(rb_eNotImpError,
305
+ "CAMonCmp: kernel not implemented (op_id=%u data_type=%d)",
306
+ (unsigned) mc->op_id, (int) mc->parent->data_type);
307
+ }
308
+ fn(slab_n, NULL,
309
+ (char *) scratch, 1,
310
+ (boolean8_t *) data, 1);
311
+ }
312
+
313
+ if ( ! scratch_is_inplace ) ca_lazy_arena_release(scratch);
314
+ }
315
+
316
+ static void
317
+ ca_moncmp_func_xfer_all (void *ap, void *data, int dir)
318
+ {
319
+ CAMonCmp *ca = (CAMonCmp *) ap;
320
+ ca_size_t starts[CA_RANK_MAX];
321
+ ca_size_t native[CA_RANK_MAX];
322
+ int8_t k;
323
+ ca_size_t s = 1;
324
+ for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
325
+ for ( k = 0; k < ca->ndim; k++ ) starts[k] = 0;
326
+ ca_xfer_stride(ca, starts, ca->dim, native, data, dir);
327
+ }
328
+
329
+ static void
330
+ ca_moncmp_func_allocate (void *ap)
331
+ {
332
+ CAMonCmp *ca = (CAMonCmp *) ap;
333
+ ca->ptr = xmalloc(ca_length(ca));
334
+ }
335
+
336
+ static void
337
+ ca_moncmp_func_attach (void *ap)
338
+ {
339
+ /* CAREFUL: self-fill through the public ca_xfer_stride dispatcher
340
+ hits its self-memcpy fast path (data == ca->ptr becomes a no-op
341
+ and the buffer stays as xmalloc garbage). Call the view's own
342
+ xfer_stride directly to force the actual gather+cast. */
343
+ CAMonCmp *ca = (CAMonCmp *) ap;
344
+ ca_size_t starts[CA_RANK_MAX];
345
+ ca_size_t native[CA_RANK_MAX];
346
+ int8_t k;
347
+ ca_size_t s;
348
+
349
+ ca->ptr = xmalloc(ca_length(ca));
350
+
351
+ s = ca->bytes;
352
+ for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
353
+ for ( k = 0; k < ca->ndim; k++ ) starts[k] = 0;
354
+ ca_moncmp_func_xfer_stride(ca, starts, ca->dim, native, ca->ptr, CA_XFER_GET);
355
+ }
356
+
357
+ static void
358
+ ca_moncmp_func_sync (void *ap)
359
+ {
360
+ /* read-only */
361
+ }
362
+
363
+ static void
364
+ ca_moncmp_func_detach (void *ap)
365
+ {
366
+ CAMonCmp *ca = (CAMonCmp *) ap;
367
+ xfree(ca->ptr);
368
+ ca->ptr = NULL;
369
+ }
370
+
371
+ NORETURN(static void ca_moncmp_func_fill_data (void *ap, void *ptr));
372
+ static void
373
+ ca_moncmp_func_fill_data (void *ap, void *ptr)
374
+ {
375
+ rb_raise(rb_eRuntimeError, "CAMonCmp is read-only (fill_data)");
376
+ }
377
+
378
+ static void
379
+ ca_moncmp_func_create_mask (void *ap)
380
+ {
381
+ CAMonCmp *mc = (CAMonCmp *) ap;
382
+ CArray *p = mc->parent;
383
+ if ( ! ca_has_mask(p) ) return;
384
+
385
+ mc->mask = (CArray *) carray_new(CA_BOOLEAN, mc->ndim, mc->dim, 0, NULL);
386
+ ca_attach(p->mask);
387
+ memcpy(mc->mask->ptr, p->mask->ptr, mc->elements);
388
+ ca_detach(p->mask);
389
+ }
390
+
391
+ ca_operation_function_t ca_moncmp_func = {
392
+ -1,
393
+ CA_VIEW_ARRAY,
394
+ free_ca_moncmp,
395
+ ca_moncmp_func_clone,
396
+ ca_moncmp_func_allocate,
397
+ ca_moncmp_func_attach,
398
+ ca_moncmp_func_sync,
399
+ ca_moncmp_func_detach,
400
+ ca_moncmp_func_fill_data,
401
+ ca_moncmp_func_create_mask,
402
+ ca_moncmp_func_xfer_index,
403
+ ca_moncmp_func_xfer_addrs,
404
+ NULL,
405
+ ca_moncmp_func_xfer_stride,
406
+ ca_moncmp_func_xfer_all,
407
+ };
408
+
409
+ /* ------------------------------------------------------------------- */
410
+ /* Public builder */
411
+ /* ------------------------------------------------------------------- */
412
+
413
+ static VALUE
414
+ collapse_marker (VALUE cary)
415
+ {
416
+ CArray *ca;
417
+ if ( ! rb_obj_is_carray(cary) ) return cary;
418
+ TypedData_Get_Struct(cary, CArray, &carray_data_type, ca);
419
+ if ( ca->obj_type == CA_OBJ_LAZY_MARKER ) {
420
+ return rb_ca_parent(cary);
421
+ }
422
+ return cary;
423
+ }
424
+
425
+ static VALUE
426
+ rb_ca_moncmp_new (VALUE p_cary, uint16_t op_id)
427
+ {
428
+ volatile VALUE obj;
429
+ CArray *p;
430
+ CAMonCmp *ca;
431
+ rb_check_carray_object(p_cary);
432
+ TypedData_Get_Struct(p_cary, CArray, &carray_data_type, p);
433
+ ca = ca_moncmp_new(p, op_id);
434
+ obj = ca_wrap_struct(ca);
435
+ rb_ca_set_parent(obj, p_cary);
436
+ return obj;
437
+ }
438
+
439
+ VALUE
440
+ rb_ca_moncmp_build (VALUE p_cary, uint16_t op_id)
441
+ {
442
+ volatile VALUE p_resolved = collapse_marker(p_cary);
443
+ return rb_ca_moncmp_new(p_resolved, op_id);
444
+ }
445
+
446
+ static VALUE
447
+ rb_ca_moncmp_s_build (VALUE klass, VALUE p_cary, VALUE op_id_val)
448
+ {
449
+ uint16_t op_id = (uint16_t) NUM2UINT(op_id_val);
450
+ (void) klass;
451
+ return rb_ca_moncmp_build(p_cary, op_id);
452
+ }
453
+
454
+ static VALUE
455
+ rb_ca_moncmp_op_id (VALUE self)
456
+ {
457
+ CAMonCmp *mc;
458
+ TypedData_Get_Struct(self, CAMonCmp, &camoncmp_data_type, mc);
459
+ return UINT2NUM(mc->op_id);
460
+ }
461
+
462
+ static VALUE
463
+ rb_ca_moncmp_s_reset_scratch_counter (VALUE klass)
464
+ {
465
+ (void) klass;
466
+ ca_moncmp_scratch_acquire_count = 0;
467
+ return Qnil;
468
+ }
469
+
470
+ static VALUE
471
+ rb_ca_moncmp_s_scratch_count (VALUE klass)
472
+ {
473
+ (void) klass;
474
+ return SIZE2NUM(ca_moncmp_scratch_acquire_count);
475
+ }
476
+
477
+ static VALUE
478
+ rb_ca_moncmp_s_reset_materialise_counter (VALUE klass)
479
+ {
480
+ (void) klass;
481
+ ca_moncmp_materialise_call_count = 0;
482
+ return Qnil;
483
+ }
484
+
485
+ static VALUE
486
+ rb_ca_moncmp_s_materialise_count (VALUE klass)
487
+ {
488
+ (void) klass;
489
+ return SIZE2NUM(ca_moncmp_materialise_call_count);
490
+ }
491
+
492
+ static VALUE
493
+ rb_ca_moncmp_s_reset_leaf_inplace_counter (VALUE klass)
494
+ {
495
+ (void) klass;
496
+ ca_moncmp_leaf_inplace_count = 0;
497
+ return Qnil;
498
+ }
499
+
500
+ static VALUE
501
+ rb_ca_moncmp_s_leaf_inplace_count (VALUE klass)
502
+ {
503
+ (void) klass;
504
+ return SIZE2NUM(ca_moncmp_leaf_inplace_count);
505
+ }
506
+
507
+ static VALUE
508
+ rb_ca_moncmp_s_allocate (VALUE klass)
509
+ {
510
+ CAMonCmp *ca;
511
+ return TypedData_Make_Struct(klass, CAMonCmp, &camoncmp_data_type, ca);
512
+ }
513
+
514
+ static VALUE
515
+ rb_ca_moncmp_initialize_copy (VALUE self, VALUE other)
516
+ {
517
+ CAMonCmp *ca, *cs;
518
+ TypedData_Get_Struct(self, CAMonCmp, &camoncmp_data_type, ca);
519
+ TypedData_Get_Struct(other, CAMonCmp, &camoncmp_data_type, cs);
520
+ if ( ca_func[CA_OBJ_MONCMP].pool_init ) {
521
+ ca_array_pool_alloc(ca, CA_OBJ_MONCMP, cs->parent->ndim);
522
+ }
523
+ ca_moncmp_setup(ca, cs->parent, cs->op_id);
524
+ return self;
525
+ }
526
+
527
+ void
528
+ Init_ca_obj_moncmp (void)
529
+ {
530
+ rb_cCAMonCmp = rb_define_class("CAMonCmp", rb_cCAView);
531
+
532
+ ca_moncmp_func.struct_size = sizeof(CAMonCmp);
533
+ ca_moncmp_func.pool_bytes = ca_moncmp_pool_bytes;
534
+ ca_moncmp_func.pool_init = ca_moncmp_pool_init;
535
+
536
+ CA_OBJ_MONCMP = ca_install_obj_type(rb_cCAMonCmp,
537
+ &camoncmp_data_type,
538
+ rb_cCArrayMask,
539
+ &carray_mask_data_type, &ca_moncmp_func, sizeof(ca_moncmp_func));
540
+ rb_define_const(rb_cObject, "CA_OBJ_MONCMP", INT2NUM(CA_OBJ_MONCMP));
541
+
542
+ rb_define_const(rb_cCAMonCmp, "OP_IS_NAN", INT2NUM(CA_MONCMP_IS_NAN));
543
+ rb_define_const(rb_cCAMonCmp, "OP_IS_INF", INT2NUM(CA_MONCMP_IS_INF));
544
+ rb_define_const(rb_cCAMonCmp, "OP_IS_FINITE", INT2NUM(CA_MONCMP_IS_FINITE));
545
+ rb_define_const(rb_cCAMonCmp, "OP_IS_INVALID", INT2NUM(CA_MONCMP_IS_INVALID));
546
+ rb_define_const(rb_cCAMonCmp, "OP_SIGNBIT", INT2NUM(CA_MONCMP_SIGNBIT));
547
+
548
+ rb_define_alloc_func(rb_cCAMonCmp, rb_ca_moncmp_s_allocate);
549
+ rb_define_method(rb_cCAMonCmp, "initialize_copy",
550
+ rb_ca_moncmp_initialize_copy, 1);
551
+
552
+ rb_define_singleton_method(rb_cCAMonCmp, "__build__",
553
+ rb_ca_moncmp_s_build, 2);
554
+
555
+ rb_define_method(rb_cCAMonCmp, "__op_id__", rb_ca_moncmp_op_id, 0);
556
+
557
+ rb_define_singleton_method(rb_cCAMonCmp, "__reset_scratch_counter__",
558
+ rb_ca_moncmp_s_reset_scratch_counter, 0);
559
+ rb_define_singleton_method(rb_cCAMonCmp, "__scratch_count__",
560
+ rb_ca_moncmp_s_scratch_count, 0);
561
+ rb_define_singleton_method(rb_cCAMonCmp, "__reset_materialise_counter__",
562
+ rb_ca_moncmp_s_reset_materialise_counter, 0);
563
+ rb_define_singleton_method(rb_cCAMonCmp, "__materialise_count__",
564
+ rb_ca_moncmp_s_materialise_count, 0);
565
+ rb_define_singleton_method(rb_cCAMonCmp, "__reset_leaf_inplace_counter__",
566
+ rb_ca_moncmp_s_reset_leaf_inplace_counter, 0);
567
+ rb_define_singleton_method(rb_cCAMonCmp, "__leaf_inplace_count__",
568
+ rb_ca_moncmp_s_leaf_inplace_count, 0);
569
+ }