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
data/ext/extconf.rb CHANGED
@@ -38,11 +38,6 @@ end
38
38
 
39
39
  # --- ruby version code ---
40
40
 
41
- major = RbConfig::CONFIG['MAJOR'].to_i
42
- minor = RbConfig::CONFIG['MINOR'].to_i
43
- teeny = RbConfig::CONFIG['TEENY'].to_i
44
- RUBY_VERSION_CODE = major * 100 + minor * 10 + teeny
45
- $defs.push "-DRUBY_VERSION_CODE=#{RUBY_VERSION_CODE}"
46
41
 
47
42
  # --- add option "--sitelibdir=dir" ---
48
43
 
@@ -66,7 +61,101 @@ end
66
61
 
67
62
  # --- seting $CFLAGS
68
63
 
69
- $CFLAGS += " -Wall -O2"
64
+ $CFLAGS += " -Wall"
65
+
66
+ # --- in-build flag (CARRAY_BUILD)
67
+ #
68
+ # Marks a translation unit as part of carray itself, i.e. recompiled whenever
69
+ # ext/*.h changes. carray.h uses it to hand out the inline form of accessors
70
+ # that depend on struct layout (ca_is_entity indexes ca_func[], whose stride
71
+ # is sizeof(ca_operation_function_t)). Extensions built separately get the
72
+ # out-of-line form instead, so adding an operation-table slot cannot silently
73
+ # re-index the table underneath them.
74
+ #
75
+ # The fixtures under spec/spec_ai/ext_* deliberately do NOT set this -- they
76
+ # stand in for external extensions and should exercise the same surface.
77
+ #
78
+ # See devel/PROPOSAL_PARTIAL_FILL_WHOLE_ROOT_WRITEBACK.md section 6.1
79
+ #
80
+ $CFLAGS += " -DCARRAY_BUILD"
81
+
82
+ # --- dev-only build flag (CARRAY_DEV_BUILD)
83
+ #
84
+ # When `--enable-dev-build` is passed (or `rake build_ext` is invoked with
85
+ # CARRAY_DEV=1), define CARRAY_DEV_BUILD. This unlocks the smoke surface
86
+ # in ext/*.c (gated by #ifdef CARRAY_DEV_BUILD at the tail of each file
87
+ # + Init_ registration block) so spec_ai regression pins can run.
88
+ #
89
+ # Release builds (default) leave CARRAY_DEV_BUILD undefined → smoke fences
90
+ # compile to nothing → user-facing binary has no smoke API exposed.
91
+ #
92
+ # See devel/PROPOSAL_SMOKE_DEV_BUILD_GATE.md
93
+ #
94
+ if enable_config("dev-build", false)
95
+ $CFLAGS += " -DCARRAY_DEV_BUILD"
96
+ $stderr.puts "carray: CARRAY_DEV_BUILD enabled (smoke surface available)"
97
+ end
98
+
99
+ # --- probe for `-fopenmp-simd` (SL.1.0, PROPOSAL_REDUCTION_SIMD_LICENSE)
100
+ #
101
+ # `-fopenmp-simd` enables `#pragma omp simd` (and its `reduction(+:acc)`
102
+ # clause) without pulling in libomp. Used by SL.1.1+ contig-branch
103
+ # variants in CA_SLAB_REDUCE_T_{PLUS,MIN,MAX,STAR,VAR}_EX to let
104
+ # the compiler reassoc the reduction accumulator into SIMD lanes
105
+ # (worth ~5-8x on f64 reduction hot paths, per PoC bench 2026-06-12).
106
+ #
107
+ # - Apple clang / gcc 4.9+ / clang 3.9+ : supported.
108
+ # - MSVC / older compilers : probe fails, flag omitted,
109
+ # pragma silently ignored,
110
+ # code stays correct (graceful).
111
+ #
112
+ # Q1 closure (sparring round 1 2026-06-12): (A) try_compile.
113
+ #
114
+ simd_probe = <<~C
115
+ int main(void) {
116
+ double x = 0;
117
+ #pragma omp simd reduction(+:x)
118
+ for (int i = 0; i < 10; i++) x += i;
119
+ return (int)x;
120
+ }
121
+ C
122
+ if try_compile(simd_probe, "-fopenmp-simd")
123
+ $CFLAGS += " -fopenmp-simd"
124
+ $stderr.puts "carray: -fopenmp-simd enabled (SIMD reduction license)"
125
+ end
126
+
127
+ # --- probe for `-march=native` (opt-in)
128
+ #
129
+ # Widens SIMD codegen to whatever ISA extensions the build-machine CPU
130
+ # supports — AVX / AVX2 / AVX-512 on x86_64, SVE on newer aarch64.
131
+ #
132
+ # Default: on. Ruby gems are install-on-target — `gem install carray`
133
+ # runs extconf + gcc/clang on the machine that will also run the
134
+ # compiled binary, so build CPU == run CPU by construction and there
135
+ # is no cross-generation deployment risk. Baseline-SSE2 build on an
136
+ # AVX2/AVX-512 x86_64 box under-reports by 2-4x on reduction / element-
137
+ # wise kernels (observed 2026-07-18: i7-14700K bench showed no `vaddpd`,
138
+ # only `addpd` + `addsd`, AVX2 completely dormant), which is not what
139
+ # most users want.
140
+ #
141
+ # Opt out (only needed when building a portable pre-built binary gem
142
+ # meant to run on older CPUs than the build machine):
143
+ # ruby extconf.rb --disable-march-native
144
+ # CARRAY_MARCH_NATIVE=0 rake build_ext
145
+ #
146
+ # Probe uses try_compile with a trivial program; unsupported compilers
147
+ # fail the probe gracefully and stay on the baseline ISA.
148
+ #
149
+ default_on = ENV["CARRAY_MARCH_NATIVE"] != "0"
150
+ if enable_config("march-native", default_on)
151
+ arch_probe = "int main(void) { return 0; }\n"
152
+ if try_compile(arch_probe, "-march=native")
153
+ $CFLAGS += " -march=native"
154
+ $stderr.puts "carray: -march=native enabled (build-machine ISA extensions)"
155
+ else
156
+ $stderr.puts "carray: -march=native probe FAILED, keeping baseline SIMD"
157
+ end
158
+ end
70
159
  # $CFLAGS += " -m128bit-long-double" ### gcc only
71
160
  # $CFLAGS += " -Wno-absolute-value"
72
161
  # $LDFLAGS += " -L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
@@ -92,44 +181,17 @@ have_type("uint32_t", header)
92
181
  have_type("int64_t", header)
93
182
  have_type("uint64_t", header)
94
183
 
95
- if RUBY_VERSION_CODE < 191
96
- if have_type("long long", header)
97
- check_sizeof("long long")
98
- end
99
- if have_type("float", header)
100
- check_sizeof("float", header)
101
- end
102
- if have_type("double", header)
103
- check_sizeof("double", header)
104
- end
105
- if have_type("long double", header)
106
- check_sizeof("long double")
107
- end
108
- if have_header("complex.h")
109
- complex_h = "complex.h"
110
- if have_type("float complex", complex_h)
111
- check_sizeof("float complex", complex_h)
112
- end
113
- if have_type("double complex", complex_h)
114
- check_sizeof("double complex", complex_h)
115
- end
116
- else
117
- complex_h = nil
118
- end
184
+ have_type("long long", header)
185
+ have_type("float", header)
186
+ have_type("double", header)
187
+ # long double / long double complex were retired in carray-3.0
188
+ # (DROP_LONGDOUBLE); no probes needed.
189
+ if have_header("complex.h")
190
+ complex_h = "complex.h"
191
+ have_type("float complex", complex_h)
192
+ have_type("double complex", complex_h)
119
193
  else
120
- have_type("long long", header)
121
- have_type("float", header)
122
- have_type("double", header)
123
- if have_type("long double", header)
124
- check_sizeof("long double")
125
- end
126
- if have_header("complex.h")
127
- complex_h = "complex.h"
128
- have_type("float complex", complex_h)
129
- have_type("double complex", complex_h)
130
- else
131
- complex_h = nil
132
- end
194
+ complex_h = nil
133
195
  end
134
196
 
135
197
  # --- check tgmath.h
@@ -152,12 +214,55 @@ have_func("strptime", "time.h")
152
214
 
153
215
  have_func("rb_arithmetic_sequence_extract")
154
216
 
217
+ # --- check MemoryView protocol (Ruby 3.0+ required) ---
218
+
219
+ unless have_header("ruby/memory_view.h")
220
+ raise "ruby/memory_view.h not found; Ruby 3.0+ is required"
221
+ end
222
+
155
223
  # --- setup install files
156
224
 
157
225
  $INSTALLFILES = []
158
226
  $INSTALLFILES << ['carray.h', '$(archdir)']
159
227
  $INSTALLFILES << ['carray_config.h', '$(archdir)']
160
228
 
229
+ # --- ext-author / math-backend surface (PROPOSAL_CARRAY_H_REORG H.1)
230
+ #
231
+ # Two reasons a header belongs here, and only these two.
232
+ #
233
+ # (a) Reachable from `#include "carray.h"`. carray.h is a public umbrella
234
+ # that pulls carray_math_kernel.h and ca_kernel_iterator.h, which in
235
+ # turn pull the per-family dispatch headers and the iterator
236
+ # substrate. Every header in that transitive closure must ship, or a
237
+ # downstream gem's `#include "carray.h"` fails to resolve.
238
+ #
239
+ # (b) Not in the closure, but written for ext authors to include
240
+ # explicitly. ca_obj_face.h is the Face authoring surface: an
241
+ # external gem defines its own Face by including it directly.
242
+ #
243
+ # A header that is neither is internal, however useful it looks in-tree.
244
+ # ca_op_powi.h (op_powi_<type> helpers for the generated kernels) and
245
+ # ca_composite_dispatch.h (per-region gather/scatter routines behind
246
+ # CAWindow / CATile / CARoll attach) are consumed only by carray's own
247
+ # translation units, each of which includes them directly; shipping them
248
+ # would promote unstable internals to a downstream contract, so they stay
249
+ # out. carray_internal.h (layer 3) is likewise never installed.
250
+ #
251
+ %w[
252
+ carray_math_kernel.h
253
+ carray_call_cfunc.h
254
+ ca_axis_descriptor.h
255
+ ca_monop_dispatch.h
256
+ ca_binop_dispatch.h
257
+ ca_bincmp_dispatch.h
258
+ ca_moncmp_dispatch.h
259
+ ca_kernel_iterator.h
260
+ ca_iter_substrate.h
261
+ ca_obj_face.h
262
+ ].each do |h|
263
+ $INSTALLFILES << [h, '$(archdir)']
264
+ end
265
+
161
266
  # --- cygwin/mingw
162
267
  #
163
268
  # Installing the static link library "libcarray.a".
@@ -184,21 +289,49 @@ create_header(config_h)
184
289
 
185
290
  $defs = [] # Now these definitions are in carray_config.h.
186
291
 
187
- # --- create carray_math.c, carray_stat_proc.c
292
+ # --- generated sources
188
293
 
189
294
  if ( not File.exist?("carray_cast_func.c") ) or
190
295
  File.stat("carray_cast_func.rb").mtime > File.stat("carray_cast_func.c").mtime
191
296
  system("ruby carray_cast_func.rb > carray_cast_func.c")
192
297
  end
193
298
 
194
- if ( not File.exist?("carray_math.c") ) or
195
- File.stat("carray_math.rb").mtime > File.stat("carray_math.c").mtime
196
- system("ruby carray_math.rb")
299
+ # The kernels are generated as 15 files (10 kinds, with reduce split into 5
300
+ # sub-groups, plus an aggregator init.c) rather than one carray_kernels.c,
301
+ # which is what lets a parallel make actually parallelise. They land flat in
302
+ # ext/ so mkmf picks them up as $srcs.
303
+ #
304
+ # Generation happens here and only here; the Makefile does not regenerate
305
+ # anything. On the gem-install path that reads extconf -> mkkernel -> make
306
+ # compiling static sources, which is one pass with no race.
307
+ #
308
+ # carray_kernels.stamp is the mtime witness:
309
+ # - here: regenerate and touch it when mkkernel.rb is newer
310
+ # - in the Rakefile (rake build_ext): the same stamp triggers need_extconf
311
+ CARRAY_KERNELS_STAMP = "carray_kernels.stamp"
312
+ if ( not File.exist?(CARRAY_KERNELS_STAMP) ) or
313
+ File.stat("mkkernel.rb").mtime > File.stat(CARRAY_KERNELS_STAMP).mtime
314
+ # passing "." makes the generator write the split files into ext/
315
+ unless system("ruby mkkernel.rb .")
316
+ raise "mkkernel.rb failed to generate split kernel files"
317
+ end
318
+ require "fileutils"
319
+ FileUtils.touch(CARRAY_KERNELS_STAMP)
320
+ end
321
+ # clear out a single-stream carray_kernels.c left over from an older
322
+ # checkout; having both would give duplicate definitions
323
+ if File.exist?("carray_kernels.c")
324
+ File.unlink("carray_kernels.c")
325
+ end
326
+ # Fail here rather than at link time if the generator produced nothing.
327
+ if Dir.glob("carray_kernels_*.c").empty?
328
+ raise "no carray_kernels_*.c files found after mkkernel.rb; check the generator"
197
329
  end
198
330
 
199
- if ( not File.exist?("carray_stat_proc.c") ) or
200
- File.stat("carray_stat_proc.rb").mtime > File.stat("carray_stat_proc.c").mtime
201
- system("ruby carray_stat_proc.rb > carray_stat_proc.c")
331
+ if ( not File.exist?("carray_call_cfunc.c") ) or
332
+ ( not File.exist?("carray_call_cfunc.h") ) or
333
+ File.stat("mk_call_cfunc.rb").mtime > File.stat("carray_call_cfunc.c").mtime
334
+ system("ruby mk_call_cfunc.rb")
202
335
  end
203
336
 
204
337
  # --- create Makefile
@@ -225,18 +358,46 @@ GEMFILE = carray-${CA_VERSION}.gem
225
358
  carray_cast_func.c: carray_cast_func.rb
226
359
  ${RUBY} carray_cast_func.rb > carray_cast_func.c
227
360
 
228
- carray_stat_proc.c: carray_stat_proc.rb
229
- ${RUBY} carray_stat_proc.rb > carray_stat_proc.c
361
+ # P.5b.5: ext/mkmath.rb / ext/carray_math.rb retired (= residual hand-
362
+ # written ipower wrappers + lazy ipower kernel table now live in
363
+ # ext/ca_op_ipower.c, single file, no generation). No Makefile rule
364
+ # needed.
230
365
 
231
- carray_math.c: carray_math.rb
232
- ${RUBY} carray_math.rb
366
+ # There is deliberately no kernel-regeneration rule in the Makefile. Running
367
+ # mkkernel.rb belongs to the pre-generation block above, which is idempotent
368
+ # through carray_kernels.stamp.
369
+ #
370
+ # Two things went wrong when the Makefile did own it:
371
+ # - `carray_kernels_init.c: mkkernel.rb` declares one target for a recipe
372
+ # that writes 15 files. Under a parallel make on a filesystem with fine
373
+ # mtime granularity this raced: intermittent build failures
374
+ # (`as: can't create ... reduce_aggregate.o`) or the same file compiled
375
+ # twice. It showed up on Linux during gem install; on macOS the
376
+ # filesystem timing hid it.
377
+ # - Routing the rule through a stamp file does not help either: GNU make
378
+ # treats a no-recipe dependency as a reason to skip re-checking the mtime
379
+ # of the downstream .o, so a fresh .c can sit next to a stale .o and the
380
+ # build still reports success.
381
+ #
382
+ # Who does what now:
383
+ # - gem install: extconf.rb runs mkkernel, make compiles static sources.
384
+ # One pass, nothing to race.
385
+ # - `rake build_ext`: the Rakefile compares mkkernel.rb against
386
+ # carray_kernels.stamp and triggers need_extconf, so extconf reruns,
387
+ # mkkernel regenerates, the stamp is touched and make compiles.
388
+ # Transparent to the caller.
389
+ # - bare `cd ext && make`: changes to mkkernel.rb are not picked up. That
390
+ # is advanced usage -- run extconf explicitly after touching mkkernel.rb.
391
+
392
+ carray_call_cfunc.c carray_call_cfunc.h: mk_call_cfunc.rb
393
+ ${RUBY} mk_call_cfunc.rb
233
394
 
234
395
  yard:
235
396
  sh utils/create_rdoc.sh
236
397
 
237
398
  clean-generated:
238
399
  @rm -f carray_config.h lib/carray/config.rb
239
- @rm -f carray_cast_func.c carray_math.c carray_stat_proc.c
400
+ @rm -f carray_cast_func.c carray_kernels.c carray_kernels_*.c carray_kernels.stamp
240
401
  @rm -f ${GEMFILE}
241
402
  @rm -rf pkg
242
403
  @rm -f rdoc_ext.rb