carray 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -0,0 +1,37 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ CAMonCmp dispatch table: routes a moncmp op id (`CA_MONCMP_*`) to the
4
+ per-data_type kernel function pointer.
5
+
6
+ Sibling of ca_obj_moncmp.c (the CAMonCmp view) and ca_bincmp_dispatch.c
7
+ (binary counterpart). Per-data_type kernel tables are declared in
8
+ ca_moncmp_dispatch.h.
9
+
10
+ Dispatched ops:
11
+ CA_MONCMP_IS_NAN -> ca_moncmp_is_nan [in_dt]
12
+ CA_MONCMP_IS_INF -> ca_moncmp_is_inf [in_dt]
13
+ CA_MONCMP_IS_FINITE -> ca_moncmp_is_finite [in_dt]
14
+ CA_MONCMP_IS_INVALID -> ca_moncmp_is_invalid [in_dt]
15
+ CA_MONCMP_SIGNBIT -> ca_moncmp_signbit [in_dt]
16
+
17
+ Float-flavoured ops (is_nan / is_inf / is_finite) accept integer inputs
18
+ too: the per-data_type kernel const-folds the predicate per cell (and
19
+ skips masked cells), so every data_type x op combination is valid.
20
+
21
+ ---------------------------------------------------------------------------- */
22
+
23
+ #include "carray.h"
24
+ #include "ca_moncmp_dispatch.h"
25
+
26
+ ca_moncmp_func_t
27
+ ca_moncmp_kernel_lookup (uint16_t op_id, int8_t in_dt)
28
+ {
29
+ switch (op_id) {
30
+ case CA_MONCMP_IS_NAN: return ca_moncmp_is_nan [in_dt];
31
+ case CA_MONCMP_IS_INF: return ca_moncmp_is_inf [in_dt];
32
+ case CA_MONCMP_IS_FINITE: return ca_moncmp_is_finite [in_dt];
33
+ case CA_MONCMP_IS_INVALID: return ca_moncmp_is_invalid [in_dt];
34
+ case CA_MONCMP_SIGNBIT: return ca_moncmp_signbit [in_dt];
35
+ default: return NULL;
36
+ }
37
+ }
@@ -0,0 +1,62 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_moncmp_dispatch.h
4
+
5
+ PROPOSAL_LAZY_ELEMENTWISE_VIEW Phase 4 (P.4.1) — CAMonCmp dispatch API.
6
+
7
+ rev2 §0.5 #3: integer is_nan / is_inf / is_finite use the existing
8
+ per-data_type kernels (= no constant-fold). The kernel for integer
9
+ data_types writes all-false (is_nan, is_inf) or all-true (is_finite) and
10
+ leaves masked cells untouched; the caller's output mask propagates
11
+ via the normal create_mask path.
12
+
13
+ P.4.1 scope: only :is_nan wired; remaining ops reserved. P.4.2
14
+ expands to 3 ops (= is_nan / is_inf / is_finite).
15
+
16
+ ---------------------------------------------------------------------------- */
17
+
18
+ #ifndef CA_MONCMP_DISPATCH_H
19
+ #define CA_MONCMP_DISPATCH_H
20
+
21
+ #include "carray.h"
22
+
23
+ /* ------------------------------------------------------------------- */
24
+ /* op_id enum */
25
+ /* ------------------------------------------------------------------- */
26
+
27
+ enum {
28
+ CA_MONCMP_IS_NAN = 0,
29
+ CA_MONCMP_IS_INF = 1,
30
+ CA_MONCMP_IS_FINITE = 2,
31
+ CA_MONCMP_IS_INVALID = 3,
32
+ CA_MONCMP_SIGNBIT = 4, /* M.1: PyTorch alignment */
33
+
34
+ CA_MONCMP_COUNT
35
+ };
36
+
37
+ /* ------------------------------------------------------------------- */
38
+ /* Kernel dispatch tables (per-data_type) */
39
+ /* ------------------------------------------------------------------- */
40
+
41
+ /* The per-data_type moncmp kernel tables (mkkernel-generated, write
42
+ boolean8_t output). Made public here (PROPOSAL_CARRAY_H_REORG H.2)
43
+ so external math-backend gems can swap a slot through the carray.h
44
+ umbrella with no hand-declared externs. */
45
+ extern ca_moncmp_func_t ca_moncmp_is_nan [CA_NTYPE];
46
+ extern ca_moncmp_func_t ca_moncmp_is_inf [CA_NTYPE];
47
+ extern ca_moncmp_func_t ca_moncmp_is_finite [CA_NTYPE];
48
+ extern ca_moncmp_func_t ca_moncmp_is_invalid [CA_NTYPE];
49
+ extern ca_moncmp_func_t ca_moncmp_signbit [CA_NTYPE];
50
+
51
+ /* ------------------------------------------------------------------- */
52
+ /* Dispatch API */
53
+ /* ------------------------------------------------------------------- */
54
+
55
+ /* Look up the moncmp kernel for (op_id, in_dt). Returns NULL if not
56
+ implemented at the requested data_type. All moncmp kernels write
57
+ boolean8_t to ptr2. No cast insertion needed (= kernel exists for
58
+ all numeric data_types including integer, where it const-folds inside
59
+ the kernel + preserves mask via skip semantics). */
60
+ ca_moncmp_func_t ca_moncmp_kernel_lookup (uint16_t op_id, int8_t in_dt);
61
+
62
+ #endif /* CA_MONCMP_DISPATCH_H */
@@ -0,0 +1,200 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ CAMonOp dispatch: hand-curated table-of-tables that maps a monop op id
4
+ (`CA_MONOP_*`) to the per-data_type kernel function.
5
+
6
+ Sibling of ca_obj_monop.c (the CAMonOp view), ca_binop_dispatch.c
7
+ (binary counterpart), and ca_moncmp_dispatch.c (boolean-output
8
+ unary). The per-data_type kernel tables (`ca_monop_sqrt[CA_NTYPE]`
9
+ etc.) are extern'd from the generated carray_kernels.c and declared
10
+ in ca_monop_dispatch.h.
11
+
12
+ ## Op categories (determines output data_type)
13
+
14
+ - **preserve** output = parent data_type. Examples: zero, one,
15
+ neg, abs_i, conj, not, ceil, floor, round, rcp,
16
+ trunc, square, byte_swap.
17
+ - **widening** output = `CA_FLOAT64` for integer/boolean parent,
18
+ else parent data_type. Examples: sqrt, exp,
19
+ log, sin, cos, atan, expm1, log1p, rsqrt,
20
+ deg_360, rad_2pi.
21
+ - **cast** `op_id >= CA_MONOP_CAST_BASE`. Output data_type =
22
+ `op_id - CA_MONOP_CAST_BASE`. Cast is handled
23
+ specially in xfer_stride via ca_cast_block; the
24
+ kernel lookup returns NULL.
25
+
26
+ Membership is queried by `ca_monop_is_cast` and `ca_monop_is_widening`
27
+ below. The widening predicate enumerates the widening op_ids
28
+ explicitly (= the WIDENING_BEGIN/END contiguous range plus a few ops
29
+ added after IMAG_I; see the function body).
30
+
31
+ ## Kernel input data_type
32
+
33
+ Same as output data_type. When kernel_input_data_type !=
34
+ parent.data_type, the CAMonOp builder inserts a CAMonOp(`:cast_<dt>`)
35
+ node between this op and parent (cast-before route). Cast ops are
36
+ the one exception: the kernel accepts whatever the upstream node
37
+ provides without further coercion.
38
+
39
+ ---------------------------------------------------------------------------- */
40
+
41
+ #include "carray.h"
42
+ #include "ca_monop_dispatch.h"
43
+
44
+ /* ------------------------------------------------------------------- */
45
+ /* op_id -> kernel table lookup */
46
+ /* ------------------------------------------------------------------- */
47
+
48
+ /* Returns the kernel for the given input data_type. Returns NULL for
49
+ cast ops (op_id >= CA_MONOP_CAST_BASE) and unknown op_ids; cast is
50
+ handled specially in xfer_stride via ca_cast_block. */
51
+ ca_monop_func_t
52
+ ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type)
53
+ {
54
+ switch (op_id) {
55
+ case CA_MONOP_ZERO: return ca_monop_zero[in_data_type];
56
+ case CA_MONOP_ONE: return ca_monop_one[in_data_type];
57
+ case CA_MONOP_FRAC: return ca_monop_frac[in_data_type];
58
+ case CA_MONOP_NEG: return ca_monop_neg[in_data_type];
59
+ case CA_MONOP_BIT_NEG: return ca_monop_bit_neg[in_data_type];
60
+ case CA_MONOP_ABS_I: return ca_monop_abs_i[in_data_type];
61
+ case CA_MONOP_CONJ: return ca_monop_conj[in_data_type];
62
+ case CA_MONOP_NOT: return ca_monop_not[in_data_type];
63
+
64
+ case CA_MONOP_CEIL: return ca_monop_ceil[in_data_type];
65
+ case CA_MONOP_FLOOR: return ca_monop_floor[in_data_type];
66
+ case CA_MONOP_ROUND: return ca_monop_round[in_data_type];
67
+ case CA_MONOP_RCP: return ca_monop_rcp[in_data_type];
68
+
69
+ case CA_MONOP_RAD: return ca_monop_rad[in_data_type];
70
+ case CA_MONOP_DEG: return ca_monop_deg[in_data_type];
71
+ case CA_MONOP_SQRT: return ca_monop_sqrt[in_data_type];
72
+ case CA_MONOP_EXP: return ca_monop_exp[in_data_type];
73
+ case CA_MONOP_EXP2: return ca_monop_exp2[in_data_type];
74
+ case CA_MONOP_EXP10: return ca_monop_exp10[in_data_type];
75
+ case CA_MONOP_LOG: return ca_monop_log[in_data_type];
76
+ case CA_MONOP_LOG10: return ca_monop_log10[in_data_type];
77
+ case CA_MONOP_LOG2: return ca_monop_log2[in_data_type];
78
+ case CA_MONOP_LOGB: return ca_monop_logb[in_data_type];
79
+ case CA_MONOP_SIN: return ca_monop_sin[in_data_type];
80
+ case CA_MONOP_COS: return ca_monop_cos[in_data_type];
81
+ case CA_MONOP_TAN: return ca_monop_tan[in_data_type];
82
+ case CA_MONOP_ASIN: return ca_monop_asin[in_data_type];
83
+ case CA_MONOP_ACOS: return ca_monop_acos[in_data_type];
84
+ case CA_MONOP_ATAN: return ca_monop_atan[in_data_type];
85
+ case CA_MONOP_SINH: return ca_monop_sinh[in_data_type];
86
+ case CA_MONOP_COSH: return ca_monop_cosh[in_data_type];
87
+ case CA_MONOP_TANH: return ca_monop_tanh[in_data_type];
88
+ case CA_MONOP_ASINH: return ca_monop_asinh[in_data_type];
89
+ case CA_MONOP_ACOSH: return ca_monop_acosh[in_data_type];
90
+ case CA_MONOP_ATANH: return ca_monop_atanh[in_data_type];
91
+
92
+ case CA_MONOP_BYTE_SWAP: return ca_monop_byte_swap[in_data_type];
93
+
94
+ case CA_MONOP_IMAG_I: return ca_monop_imag_i[in_data_type];
95
+
96
+ case CA_MONOP_EXPM1: return ca_monop_expm1 [in_data_type];
97
+ case CA_MONOP_LOG1P: return ca_monop_log1p [in_data_type];
98
+ case CA_MONOP_RSQRT: return ca_monop_rsqrt [in_data_type];
99
+ case CA_MONOP_TRUNC: return ca_monop_trunc [in_data_type];
100
+ case CA_MONOP_SQUARE: return ca_monop_square[in_data_type];
101
+
102
+ case CA_MONOP_DEG_360: return ca_monop_deg_360[in_data_type];
103
+ case CA_MONOP_DEG_180: return ca_monop_deg_180[in_data_type];
104
+ case CA_MONOP_RAD_2PI: return ca_monop_rad_2pi[in_data_type];
105
+ case CA_MONOP_RAD_PI: return ca_monop_rad_pi [in_data_type];
106
+
107
+ case CA_MONOP_SIGN: return ca_monop_sign [in_data_type];
108
+ case CA_MONOP_ARG_I: return ca_monop_arg_i [in_data_type];
109
+
110
+ default:
111
+ /* Cast ops or unknown — caller handles cast specially. */
112
+ return NULL;
113
+ }
114
+ }
115
+
116
+ /* ------------------------------------------------------------------- */
117
+ /* op category predicates */
118
+ /* ------------------------------------------------------------------- */
119
+
120
+ /* True if op widens integer / boolean parent to CA_FLOAT64. False for
121
+ preserve ops and cast ops. Widening ops are enumerated explicitly
122
+ because they were added in multiple groups outside the original
123
+ contiguous WIDENING_BEGIN..WIDENING_END range. */
124
+ static int
125
+ ca_monop_is_widening (uint16_t op_id)
126
+ {
127
+ if ( op_id >= CA_MONOP_WIDENING_BEGIN && op_id < CA_MONOP_WIDENING_END ) {
128
+ return 1;
129
+ }
130
+ /* Additional widening monfunc placed after IMAG_I. */
131
+ if ( op_id == CA_MONOP_EXPM1 ||
132
+ op_id == CA_MONOP_LOG1P ||
133
+ op_id == CA_MONOP_RSQRT ) {
134
+ return 1;
135
+ }
136
+ /* Angle normalisation widening monfunc. */
137
+ if ( op_id == CA_MONOP_DEG_360 ||
138
+ op_id == CA_MONOP_DEG_180 ||
139
+ op_id == CA_MONOP_RAD_2PI ||
140
+ op_id == CA_MONOP_RAD_PI ) {
141
+ return 1;
142
+ }
143
+ return 0;
144
+ }
145
+
146
+ int
147
+ ca_monop_is_cast (uint16_t op_id)
148
+ {
149
+ return (op_id >= CA_MONOP_CAST_BASE &&
150
+ op_id < CA_MONOP_CAST_BASE + CA_NTYPE);
151
+ }
152
+
153
+ /* True if this op produces a view that can be written through (= the
154
+ inverse operation is well-defined and used by store_into). Cast
155
+ and byte_swap qualify; pure functions like sqrt or sin do not. */
156
+ int
157
+ ca_monop_is_writable_view (uint16_t op_id)
158
+ {
159
+ return ca_monop_is_cast(op_id) || op_id == CA_MONOP_BYTE_SWAP;
160
+ }
161
+
162
+ /* ------------------------------------------------------------------- */
163
+ /* output data_type rule */
164
+ /* ------------------------------------------------------------------- */
165
+
166
+ int8_t
167
+ ca_lazy_promote_monop (uint16_t op_id, int8_t in_data_type)
168
+ {
169
+ if ( ca_monop_is_cast(op_id) ) {
170
+ return (int8_t)(op_id - CA_MONOP_CAST_BASE);
171
+ }
172
+ if ( ca_monop_is_widening(op_id) ) {
173
+ /* integer → f64, else preserve. Boolean (CA_BOOLEAN = 1) is also
174
+ widened to f64 (existing eager behaviour via wrap_readonly). */
175
+ if ( in_data_type < CA_FLOAT32 ) return CA_FLOAT64;
176
+ return in_data_type;
177
+ }
178
+ /* preserve */
179
+ return in_data_type;
180
+ }
181
+
182
+ /* ------------------------------------------------------------------- */
183
+ /* kernel input data_type rule (cast-before route) */
184
+ /* ------------------------------------------------------------------- */
185
+
186
+ /* Returns the data_type the kernel expects as input. For widening ops,
187
+ integer parent must be cast to f64 first because the kernel only has
188
+ f64/cmplx slots. For preserve ops, parent.data_type passes through.
189
+ For cast ops, the kernel accepts whatever the upstream node provides
190
+ (no further coercion). If the returned data_type differs from the
191
+ parent's real data_type, the caller inserts a CAMonOp(`:cast_<dt>`)
192
+ node. */
193
+ int8_t
194
+ ca_monop_kernel_input_data_type (uint16_t op_id, int8_t parent_data_type)
195
+ {
196
+ if ( ca_monop_is_cast(op_id) ) {
197
+ return parent_data_type;
198
+ }
199
+ return ca_lazy_promote_monop(op_id, parent_data_type);
200
+ }
@@ -0,0 +1,235 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_monop_dispatch.h
4
+
5
+ PROPOSAL_LAZY_ELEMENTWISE_VIEW Phase 1 (P.1.2) — CAMonOp dispatch API.
6
+
7
+ ---------------------------------------------------------------------------- */
8
+
9
+ #ifndef CA_MONOP_DISPATCH_H
10
+ #define CA_MONOP_DISPATCH_H
11
+
12
+ #include "carray.h"
13
+
14
+ /* ------------------------------------------------------------------- */
15
+ /* op_id enum */
16
+ /* ------------------------------------------------------------------- */
17
+
18
+ /* Three contiguous segments of normal op_ids, followed by a CAST segment
19
+ offset at CA_MONOP_CAST_BASE.
20
+
21
+ Numeric assignments are stable — callers and Ruby constants reference
22
+ them by name only. */
23
+ enum {
24
+ /* Preserve-data_type monop (8) */
25
+ CA_MONOP_ZERO = 0,
26
+ CA_MONOP_ONE = 1,
27
+ CA_MONOP_FRAC = 2,
28
+ CA_MONOP_NEG = 3,
29
+ CA_MONOP_BIT_NEG = 4,
30
+ CA_MONOP_ABS_I = 5,
31
+ CA_MONOP_CONJ = 6,
32
+ CA_MONOP_NOT = 7,
33
+
34
+ /* Preserve-data_type monfunc (4) */
35
+ CA_MONOP_CEIL = 8,
36
+ CA_MONOP_FLOOR = 9,
37
+ CA_MONOP_ROUND = 10,
38
+ CA_MONOP_RCP = 11,
39
+
40
+ /* Widening monfunc (22) */
41
+ CA_MONOP_WIDENING_BEGIN = 12,
42
+ CA_MONOP_RAD = 12,
43
+ CA_MONOP_DEG = 13,
44
+ CA_MONOP_SQRT = 14,
45
+ CA_MONOP_EXP = 15,
46
+ CA_MONOP_EXP2 = 16,
47
+ CA_MONOP_EXP10 = 17,
48
+ CA_MONOP_LOG = 18,
49
+ CA_MONOP_LOG10 = 19,
50
+ CA_MONOP_LOG2 = 20,
51
+ CA_MONOP_LOGB = 21,
52
+ CA_MONOP_SIN = 22,
53
+ CA_MONOP_COS = 23,
54
+ CA_MONOP_TAN = 24,
55
+ CA_MONOP_ASIN = 25,
56
+ CA_MONOP_ACOS = 26,
57
+ CA_MONOP_ATAN = 27,
58
+ CA_MONOP_SINH = 28,
59
+ CA_MONOP_COSH = 29,
60
+ CA_MONOP_TANH = 30,
61
+ CA_MONOP_ASINH = 31,
62
+ CA_MONOP_ACOSH = 32,
63
+ CA_MONOP_ATANH = 33,
64
+ CA_MONOP_WIDENING_END = 34, /* exclusive sentinel */
65
+
66
+ /* Phase 6 P.6.1 (Q3 Z): byte_swap is a single op_id with per-data_type
67
+ kernel table (= data_type-preserving, output.bytes == input.bytes,
68
+ CMPLX halves swapped independently inside the kernel). Placed
69
+ after WIDENING_END so the widening check (op_id < WIDENING_END)
70
+ correctly classifies it as preserve. kernel_lookup dispatches to
71
+ ca_monop_byte_swap[in_data_type] (ext/ca_op_byte_swap.c). */
72
+ CA_MONOP_BYTE_SWAP = 35,
73
+
74
+ /* imag_i (= cimag for complex stored into the same-data_type slot, 0 for
75
+ numeric). Same trick as abs_i: data_type-preserving kernel that puts
76
+ the desired value in the real component so a downstream
77
+ cast-to-float picks it up. Powers the lazy `.imag` chain (= 2-node
78
+ for complex parent, 1-node for non-complex). */
79
+ CA_MONOP_IMAG_I = 36,
80
+
81
+ /* M.1 (PyTorch alignment): additional monop / monfunc ops. Placed
82
+ after IMAG_I to preserve stable IDs of existing ops in the
83
+ 12..33 widening segment. `ca_monop_is_widening` is extended to
84
+ recognise EXPM1 / LOG1P / RSQRT. */
85
+ CA_MONOP_EXPM1 = 37, /* widening: exp(x) - 1 */
86
+ CA_MONOP_LOG1P = 38, /* widening: log(1 + x) */
87
+ CA_MONOP_RSQRT = 39, /* widening: 1 / sqrt(x) */
88
+ CA_MONOP_TRUNC = 40, /* preserve: toward-zero (int identity, float trunc) */
89
+ CA_MONOP_SQUARE = 41, /* preserve: x * x */
90
+
91
+ /* M.4 (angle normalisation migration from carray_mathfunc.c):
92
+ widening monfunc — integer auto-casts to f64, float in / float out
93
+ preserve. */
94
+ CA_MONOP_DEG_360 = 42, /* widening: fold into [0, 360) */
95
+ CA_MONOP_DEG_180 = 43, /* widening: fold into [-180, 180) */
96
+ CA_MONOP_RAD_2PI = 44, /* widening: fold into [0, 2pi) */
97
+ CA_MONOP_RAD_PI = 45, /* widening: fold into [-pi, pi) */
98
+
99
+ CA_MONOP_SIGN = 46, /* preserve: sign function (-1/0/1 for real,
100
+ unit vector for complex, 0/1 for uint/bool) */
101
+ CA_MONOP_ARG_I = 47, /* preserve: writes carg(z) into the slot
102
+ (float in-place, complex real component).
103
+ A chain cast_<float> extracts the real part
104
+ for the user-facing `arg` result — same
105
+ pattern as abs_i / imag_i. */
106
+
107
+ /* Cast ops live in a separate range so they cannot collide with the
108
+ normal ops. cast-to-data_type-X has op_id = CA_MONOP_CAST_BASE + X. */
109
+ CA_MONOP_CAST_BASE = 100,
110
+ };
111
+
112
+ /* ------------------------------------------------------------------- */
113
+ /* Kernel dispatch tables (per-data_type) */
114
+ /* ------------------------------------------------------------------- */
115
+
116
+ /* The per-data_type monop kernel tables. Defined in carray_kernels.c
117
+ (mkkernel-generated) and ext/ca_op_byte_swap.c (byte_swap). Made
118
+ public here (PROPOSAL_CARRAY_H_REORG H.2) so external math-backend
119
+ gems (e.g. carray-vmath-vforce) can swap a slot — e.g.
120
+ `ca_monop_sin[CA_FLOAT64] = my_vector_sin;` — through the carray.h
121
+ umbrella with no hand-declared externs. */
122
+
123
+ /* Preserve-data_type monop (8) */
124
+ extern ca_monop_func_t ca_monop_zero[CA_NTYPE];
125
+ extern ca_monop_func_t ca_monop_one[CA_NTYPE];
126
+ extern ca_monop_func_t ca_monop_frac[CA_NTYPE];
127
+ extern ca_monop_func_t ca_monop_neg[CA_NTYPE];
128
+ extern ca_monop_func_t ca_monop_bit_neg[CA_NTYPE];
129
+ extern ca_monop_func_t ca_monop_abs_i[CA_NTYPE];
130
+ extern ca_monop_func_t ca_monop_conj[CA_NTYPE];
131
+ extern ca_monop_func_t ca_monop_not[CA_NTYPE];
132
+
133
+ /* Preserve-data_type monfunc (4) */
134
+ extern ca_monop_func_t ca_monop_ceil[CA_NTYPE];
135
+ extern ca_monop_func_t ca_monop_floor[CA_NTYPE];
136
+ extern ca_monop_func_t ca_monop_round[CA_NTYPE];
137
+ extern ca_monop_func_t ca_monop_rcp[CA_NTYPE];
138
+
139
+ /* Widening monfunc (22) */
140
+ extern ca_monop_func_t ca_monop_rad[CA_NTYPE];
141
+ extern ca_monop_func_t ca_monop_deg[CA_NTYPE];
142
+ extern ca_monop_func_t ca_monop_sqrt[CA_NTYPE];
143
+ extern ca_monop_func_t ca_monop_exp[CA_NTYPE];
144
+ extern ca_monop_func_t ca_monop_exp2[CA_NTYPE];
145
+ extern ca_monop_func_t ca_monop_exp10[CA_NTYPE];
146
+ extern ca_monop_func_t ca_monop_log[CA_NTYPE];
147
+ extern ca_monop_func_t ca_monop_log10[CA_NTYPE];
148
+ extern ca_monop_func_t ca_monop_log2[CA_NTYPE];
149
+ extern ca_monop_func_t ca_monop_logb[CA_NTYPE];
150
+ extern ca_monop_func_t ca_monop_sin[CA_NTYPE];
151
+ extern ca_monop_func_t ca_monop_cos[CA_NTYPE];
152
+ extern ca_monop_func_t ca_monop_tan[CA_NTYPE];
153
+ extern ca_monop_func_t ca_monop_asin[CA_NTYPE];
154
+ extern ca_monop_func_t ca_monop_acos[CA_NTYPE];
155
+ extern ca_monop_func_t ca_monop_atan[CA_NTYPE];
156
+ extern ca_monop_func_t ca_monop_sinh[CA_NTYPE];
157
+ extern ca_monop_func_t ca_monop_cosh[CA_NTYPE];
158
+ extern ca_monop_func_t ca_monop_tanh[CA_NTYPE];
159
+ extern ca_monop_func_t ca_monop_asinh[CA_NTYPE];
160
+ extern ca_monop_func_t ca_monop_acosh[CA_NTYPE];
161
+ extern ca_monop_func_t ca_monop_atanh[CA_NTYPE];
162
+
163
+ /* byte_swap (hand-written, ext/ca_op_byte_swap.c) */
164
+ extern ca_monop_func_t ca_monop_byte_swap[CA_NTYPE];
165
+
166
+ /* imag_i: cimag for complex, 0 for numeric (mkkernel-generated) */
167
+ extern ca_monop_func_t ca_monop_imag_i[CA_NTYPE];
168
+
169
+ /* M.1: PyTorch-alignment additions (mkkernel-generated) */
170
+ extern ca_monop_func_t ca_monop_expm1 [CA_NTYPE];
171
+ extern ca_monop_func_t ca_monop_log1p [CA_NTYPE];
172
+ extern ca_monop_func_t ca_monop_rsqrt [CA_NTYPE];
173
+ extern ca_monop_func_t ca_monop_trunc [CA_NTYPE];
174
+ extern ca_monop_func_t ca_monop_square[CA_NTYPE];
175
+
176
+ /* M.4: angle normalisation migration (mkkernel-generated) */
177
+ extern ca_monop_func_t ca_monop_deg_360[CA_NTYPE];
178
+ extern ca_monop_func_t ca_monop_deg_180[CA_NTYPE];
179
+ extern ca_monop_func_t ca_monop_rad_2pi[CA_NTYPE];
180
+ extern ca_monop_func_t ca_monop_rad_pi [CA_NTYPE];
181
+
182
+ /* Preserve-data_type primitives added for lazy substrate coverage. */
183
+ extern ca_monop_func_t ca_monop_sign [CA_NTYPE];
184
+ extern ca_monop_func_t ca_monop_arg_i [CA_NTYPE];
185
+
186
+ /* ------------------------------------------------------------------- */
187
+ /* Dispatch API */
188
+ /* ------------------------------------------------------------------- */
189
+
190
+ /* Look up the per-data_type kernel for a normal monop op_id. Returns NULL
191
+ for cast op_ids (caller handles cast via ca_cast_block). */
192
+ ca_monop_func_t ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type);
193
+
194
+ /* Returns true iff op_id encodes a cast operation. */
195
+ int ca_monop_is_cast (uint16_t op_id);
196
+
197
+ /* Phase 6 P.6.3: returns true iff op_id is a "writable view" op
198
+ (= cast or byte_swap). These ops:
199
+ - support writable view lifecycle (CA_FLAG_READ_ONLY not set)
200
+ - have an inverse mapping for write-back (cast = reverse cast;
201
+ byte_swap = involution = same op applied twice)
202
+ - use CAFake-style attach/sync/detach lifecycle in CAMonOp
203
+ (ca_attach(parent) in allocate/attach, op apply to fill ca.ptr,
204
+ inverse op + memcpy to parent.ptr in sync, ca_detach(parent))
205
+ Non-cast / non-byte_swap monop / monfunc remain read-only with
206
+ chain materialise lifecycle. */
207
+ int ca_monop_is_writable_view (uint16_t op_id);
208
+
209
+ /* Phase 6 P.6.2 (Q9 α / Q13 α foundational helper): Returns true iff
210
+ `view` is a single-node CAMonOp with a cast op_id (= no further CAMonOp
211
+ in the parent chain). This is the discrimination predicate for the
212
+ F.6.2 per-fiber fused fast path after CAFake → CAMonOp(cast) typedef
213
+ migration: same architectural role as the current
214
+ `attach == ca_fake_func.attach` check in ca_kernel_iterator.c:336.
215
+
216
+ For chain CAMonOp (= depth ≥ 2, e.g. `a.lazy.sqrt.cast`), returns 0
217
+ so the existing chain materialise path (= arena-pooled scratches)
218
+ continues to handle the chain end-to-end.
219
+
220
+ `view` must be a non-NULL CArray*. Returns 0 for non-CAMonOp views.
221
+ Defined in ca_obj_monop.c so it can access the CAMonOp struct internals
222
+ (op_id tail field, parent pointer). */
223
+ int ca_monop_view_is_single_cast (CArray *view);
224
+
225
+ /* Compute the output data_type for (op_id, parent_data_type). Mirrors existing
226
+ eager mkmath rules. */
227
+ int8_t ca_lazy_promote_monop (uint16_t op_id, int8_t parent_data_type);
228
+
229
+ /* Compute the data_type the kernel expects as input. When != parent_data_type,
230
+ a CAMonOp(:cast_<data_type>) node must be inserted between this op and
231
+ its parent (finding #1, cast-before). For cast op_ids, returns
232
+ parent_data_type unchanged. */
233
+ int8_t ca_monop_kernel_input_data_type (uint16_t op_id, int8_t parent_data_type);
234
+
235
+ #endif /* CA_MONOP_DISPATCH_H */