carray 2.0.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +6 -25
  3. data/CHANGELOG.md +338 -0
  4. data/{NEWS.md → CHANGELOG.v1.md} +3 -0
  5. data/LICENSE +1 -1
  6. data/README.md +120 -36
  7. data/carray.gemspec +32 -30
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1244 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +124 -0
  15. data/ext/ca_binop_dispatch.h +152 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +239 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4367 -0
  26. data/ext/ca_kernel_iterator.h +2596 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +839 -0
  33. data/ext/ca_obj_binop.c +948 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +967 -0
  39. data/ext/ca_obj_face.c +750 -0
  40. data/ext/ca_obj_face.h +279 -0
  41. data/ext/ca_obj_fake.c +239 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +308 -0
  45. data/ext/ca_obj_grid.c +866 -440
  46. data/ext/ca_obj_meld.c +1039 -0
  47. data/ext/ca_obj_moncmp.c +588 -0
  48. data/ext/ca_obj_monop.c +1123 -0
  49. data/ext/ca_obj_object.c +866 -296
  50. data/ext/ca_obj_record.c +470 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +593 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +624 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1306 -0
  58. data/ext/ca_obj_shift.c +231 -793
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2584 -0
  62. data/ext/ca_obj_string.c +270 -0
  63. data/ext/ca_obj_tile.c +622 -0
  64. data/ext/ca_obj_time.c +548 -0
  65. data/ext/ca_obj_timedelta.c +437 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +785 -0
  68. data/ext/ca_obj_window.c +1202 -565
  69. data/ext/ca_op_byte_swap.c +175 -0
  70. data/ext/ca_op_cmplx64.h +123 -0
  71. data/ext/ca_op_ipower.c +316 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +473 -0
  75. data/ext/ca_sweep_engine.h +166 -0
  76. data/ext/ca_transform_common.c +235 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +810 -420
  80. data/ext/carray_access.c +873 -731
  81. data/ext/carray_attribute.c +98 -329
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +376 -0
  84. data/ext/carray_build_flags.h +3 -0
  85. data/ext/carray_call_cfunc.c +2897 -874
  86. data/ext/carray_call_cfunc.h +313 -0
  87. data/ext/carray_cast.c +1264 -315
  88. data/ext/carray_cast_func.rb +81 -40
  89. data/ext/carray_class.c +53 -63
  90. data/ext/carray_config.h +28 -0
  91. data/ext/carray_conversion.c +350 -346
  92. data/ext/carray_copy.c +168 -270
  93. data/ext/carray_core.c +1396 -206
  94. data/ext/carray_count.c +312 -0
  95. data/ext/carray_data_type.c +43 -19
  96. data/ext/carray_element.c +585 -213
  97. data/ext/carray_factorize.c +2542 -0
  98. data/ext/carray_generate.c +230 -559
  99. data/ext/carray_histogram.c +490 -0
  100. data/ext/carray_hold.c +228 -0
  101. data/ext/carray_index_classifier.c +1021 -0
  102. data/ext/carray_index_classifier.h +27 -0
  103. data/ext/carray_internal.h +136 -0
  104. data/ext/carray_kernels_bincmp.c +4446 -0
  105. data/ext/carray_kernels_binop.c +11001 -0
  106. data/ext/carray_kernels_init.c +1131 -0
  107. data/ext/carray_kernels_map.c +3467 -0
  108. data/ext/carray_kernels_moncmp.c +2097 -0
  109. data/ext/carray_kernels_monop.c +18313 -0
  110. data/ext/carray_kernels_reduce_aggregate.c +25837 -0
  111. data/ext/carray_kernels_reduce_boolean.c +330 -0
  112. data/ext/carray_kernels_reduce_cumulative.c +14593 -0
  113. data/ext/carray_kernels_reduce_extreme.c +16948 -0
  114. data/ext/carray_kernels_reduce_variance.c +3910 -0
  115. data/ext/carray_kernels_scan.c +3693 -0
  116. data/ext/carray_kernels_search.c +32138 -0
  117. data/ext/carray_kernels_sort.c +10626 -0
  118. data/ext/carray_kernels_triop.c +1392 -0
  119. data/ext/carray_lazy.c +737 -0
  120. data/ext/carray_loop.c +88 -200
  121. data/ext/carray_mask.c +853 -158
  122. data/ext/carray_math_kernel.h +120 -0
  123. data/ext/carray_mathfunc.c +10 -241
  124. data/ext/carray_median_percentile.c +1257 -0
  125. data/ext/carray_memory_view.c +1650 -0
  126. data/ext/carray_operator.c +1525 -320
  127. data/ext/carray_order.c +664 -1394
  128. data/ext/carray_partition.c +416 -0
  129. data/ext/carray_random.c +518 -0
  130. data/ext/carray_scatter.c +357 -0
  131. data/ext/carray_slab.c +1219 -0
  132. data/ext/carray_slab.h +84 -0
  133. data/ext/carray_sort.c +829 -0
  134. data/ext/carray_sort_kernel.c +620 -0
  135. data/ext/carray_struct.c +695 -0
  136. data/ext/carray_test.c +343 -229
  137. data/ext/carray_undef.c +34 -17
  138. data/ext/carray_utils.c +175 -74
  139. data/ext/extconf.rb +234 -55
  140. data/ext/mk_call_cfunc.rb +671 -0
  141. data/ext/mkkernel.rb +9096 -0
  142. data/ext/ruby_carray.c +211 -108
  143. data/ext/version.h +4 -14
  144. data/ext/version.rb +5 -13
  145. data/lib/carray/arrow_tensor.rb +401 -0
  146. data/lib/carray/attribute.rb +166 -0
  147. data/lib/carray/autoload_carray.rb +239 -0
  148. data/lib/carray/autoload_method_extension.rb +45 -0
  149. data/lib/carray/axis_group.rb +711 -0
  150. data/lib/carray/basics.rb +481 -0
  151. data/lib/carray/bincount_nd.rb +358 -0
  152. data/lib/carray/block_iterator.rb +614 -0
  153. data/lib/carray/boolean_reduce.rb +109 -0
  154. data/lib/carray/categorical.rb +561 -0
  155. data/lib/carray/categorical_iterator.rb +1084 -0
  156. data/lib/carray/complex.rb +150 -0
  157. data/lib/carray/conditional.rb +216 -0
  158. data/lib/carray/const_string.rb +228 -0
  159. data/lib/carray/construct.rb +160 -328
  160. data/lib/carray/core_extensions.rb +297 -0
  161. data/lib/carray/data_type_extension.rb +250 -0
  162. data/lib/carray/fixlen_string.rb +95 -0
  163. data/lib/carray/frame/concat.rb +132 -0
  164. data/lib/carray/frame/convert.rb +95 -0
  165. data/lib/carray/frame/csv_parser.rb +211 -0
  166. data/lib/carray/frame/frame.rb +642 -0
  167. data/lib/carray/frame/group.rb +186 -0
  168. data/lib/carray/frame/io.rb +321 -0
  169. data/lib/carray/frame/join.rb +248 -0
  170. data/lib/carray/frame/records.rb +99 -0
  171. data/lib/carray/frame/sort.rb +113 -0
  172. data/lib/carray/frame/verbs.rb +316 -0
  173. data/lib/carray/frame.rb +16 -0
  174. data/lib/carray/fuse_source.rb +123 -0
  175. data/lib/carray/fusion.rb +218 -0
  176. data/lib/carray/histogram.rb +512 -0
  177. data/lib/carray/inspect.rb +37 -26
  178. data/lib/carray/iterator.rb +58 -349
  179. data/lib/carray/lazy.rb +941 -0
  180. data/lib/carray/mask_gap_fill.rb +200 -0
  181. data/lib/carray/math.rb +78 -342
  182. data/lib/carray/meld_reduce.rb +289 -0
  183. data/lib/carray/methods/align_addr.rb +116 -0
  184. data/lib/carray/methods/bin.rb +128 -0
  185. data/lib/carray/methods/bincount.rb +87 -0
  186. data/lib/carray/methods/bit_string.rb +92 -0
  187. data/lib/carray/methods/broadcast.rb +63 -0
  188. data/lib/carray/methods/choose.rb +39 -0
  189. data/lib/carray/methods/composition.rb +280 -0
  190. data/lib/carray/methods/gather_nd.rb +206 -0
  191. data/lib/carray/methods/index.rb +39 -0
  192. data/lib/carray/methods/insert_block.rb +99 -0
  193. data/lib/carray/methods/is_in.rb +141 -0
  194. data/lib/carray/methods/join.rb +90 -0
  195. data/lib/carray/methods/locate_addr.rb +52 -0
  196. data/lib/carray/methods/mask_duplicates.rb +41 -0
  197. data/lib/carray/methods/meshgrid.rb +90 -0
  198. data/lib/carray/methods/mode.rb +126 -0
  199. data/lib/carray/methods/nunique.rb +46 -0
  200. data/lib/carray/methods/resize.rb +56 -0
  201. data/lib/carray/methods/snap.rb +161 -0
  202. data/lib/carray/methods/string_format.rb +57 -0
  203. data/lib/carray/methods/unique.rb +47 -0
  204. data/lib/carray/methods/value_counts.rb +71 -0
  205. data/lib/carray/mkmf.rb +124 -101
  206. data/lib/carray/runtime.rb +89 -0
  207. data/lib/carray/serialize.rb +478 -167
  208. data/lib/carray/slab_iterator.rb +305 -0
  209. data/lib/carray/stack.rb +291 -0
  210. data/lib/carray/string.rb +56 -180
  211. data/lib/carray/string_operation_extension.rb +289 -0
  212. data/lib/carray/struct.rb +335 -323
  213. data/lib/carray/struct_builder.rb +697 -0
  214. data/lib/carray/table.rb +41 -2
  215. data/lib/carray/time.rb +2654 -38
  216. data/lib/carray/window_iterator.rb +927 -0
  217. data/lib/carray.rb +55 -57
  218. data/yard-stubs/ca_obj_array.rb +385 -0
  219. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  220. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  221. data/yard-stubs/ca_obj_block.rb +73 -0
  222. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  223. data/yard-stubs/ca_obj_fake.rb +31 -0
  224. data/yard-stubs/ca_obj_farray.rb +32 -0
  225. data/yard-stubs/ca_obj_field.rb +45 -0
  226. data/yard-stubs/ca_obj_grid.rb +35 -0
  227. data/yard-stubs/ca_obj_refer.rb +72 -0
  228. data/yard-stubs/ca_obj_roll.rb +45 -0
  229. data/yard-stubs/ca_obj_shift.rb +43 -0
  230. data/yard-stubs/ca_obj_stride.rb +181 -0
  231. data/yard-stubs/ca_obj_tile.rb +29 -0
  232. data/yard-stubs/ca_obj_transpose.rb +40 -0
  233. data/yard-stubs/ca_obj_window.rb +49 -0
  234. data/yard-stubs/carray_access.rb +131 -0
  235. data/yard-stubs/carray_attribute.rb +246 -0
  236. data/yard-stubs/carray_broadcast.rb +37 -0
  237. data/yard-stubs/carray_cast.rb +489 -0
  238. data/yard-stubs/carray_class.rb +65 -0
  239. data/yard-stubs/carray_conversion.rb +76 -0
  240. data/yard-stubs/carray_copy.rb +79 -0
  241. data/yard-stubs/carray_core.rb +114 -0
  242. data/yard-stubs/carray_count.rb +79 -0
  243. data/yard-stubs/carray_element.rb +108 -0
  244. data/yard-stubs/carray_generate.rb +66 -0
  245. data/yard-stubs/carray_lazy.rb +23 -0
  246. data/yard-stubs/carray_loop.rb +140 -0
  247. data/yard-stubs/carray_mask.rb +259 -0
  248. data/yard-stubs/carray_math.rb +132 -0
  249. data/yard-stubs/carray_mathfunc.rb +45 -0
  250. data/yard-stubs/carray_median_percentile.rb +89 -0
  251. data/yard-stubs/carray_memory_view.rb +163 -0
  252. data/yard-stubs/carray_order.rb +312 -0
  253. data/yard-stubs/carray_random.rb +89 -0
  254. data/yard-stubs/carray_scatter.rb +106 -0
  255. data/yard-stubs/carray_slab.rb +57 -0
  256. data/yard-stubs/carray_sort.rb +163 -0
  257. data/yard-stubs/carray_test.rb +85 -0
  258. data/yard-stubs/carray_undef.rb +64 -0
  259. data/yard-stubs/carray_utils.rb +97 -0
  260. data/yard-stubs/ruby_carray.rb +193 -0
  261. metadata +220 -138
  262. data/Rakefile +0 -51
  263. data/TODO.md +0 -18
  264. data/ext/ca_iter_block.c +0 -257
  265. data/ext/ca_iter_dimension.c +0 -299
  266. data/ext/ca_iter_window.c +0 -214
  267. data/ext/ca_obj_mapping.c +0 -644
  268. data/ext/ca_obj_unbound_repeat.c +0 -529
  269. data/ext/carray_iterator.c +0 -641
  270. data/ext/carray_math.rb +0 -850
  271. data/ext/carray_numeric.c +0 -259
  272. data/ext/carray_sort_addr.c +0 -254
  273. data/ext/carray_stat.c +0 -2100
  274. data/ext/carray_stat_proc.rb +0 -1999
  275. data/ext/mkmath.rb +0 -741
  276. data/ext/ruby_ccomplex.c +0 -509
  277. data/ext/ruby_float_func.c +0 -86
  278. data/lib/carray/array.rb +0 -8
  279. data/lib/carray/autoload/autoload_base.rb +0 -19
  280. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  281. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  282. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  283. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  284. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  285. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  286. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  287. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  288. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  289. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  290. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  291. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  292. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  293. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  294. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  295. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  296. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  297. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  298. data/lib/carray/autoload.rb +0 -141
  299. data/lib/carray/basic.rb +0 -191
  300. data/lib/carray/broadcast.rb +0 -101
  301. data/lib/carray/compose.rb +0 -315
  302. data/lib/carray/convert.rb +0 -115
  303. data/lib/carray/info.rb +0 -110
  304. data/lib/carray/io/imagemagick.rb +0 -235
  305. data/lib/carray/mask.rb +0 -102
  306. data/lib/carray/math/histogram.rb +0 -177
  307. data/lib/carray/math/recurrence.rb +0 -93
  308. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  309. data/lib/carray/object/ca_obj_link.rb +0 -50
  310. data/lib/carray/object/ca_obj_pack.rb +0 -99
  311. data/lib/carray/obsolete.rb +0 -256
  312. data/lib/carray/ordering.rb +0 -181
  313. data/lib/carray/testing.rb +0 -51
  314. data/lib/carray/transform.rb +0 -109
  315. data/mailmap +0 -1
  316. data/misc/Methods.ja.md +0 -182
  317. data/misc/NOTE +0 -51
  318. data/spec/Classes/CABitfield_spec.rb +0 -58
  319. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  320. data/spec/Classes/CABlock_spec.rb +0 -205
  321. data/spec/Classes/CAField_spec.rb +0 -39
  322. data/spec/Classes/CAGrid_spec.rb +0 -75
  323. data/spec/Classes/CAMap_spec.rb +0 -0
  324. data/spec/Classes/CAMapping_spec.rb +0 -105
  325. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  326. data/spec/Classes/CAObject_spec.rb +0 -33
  327. data/spec/Classes/CARefer_spec.rb +0 -93
  328. data/spec/Classes/CARepeat_spec.rb +0 -65
  329. data/spec/Classes/CASelect_spec.rb +0 -22
  330. data/spec/Classes/CAShift_spec.rb +0 -16
  331. data/spec/Classes/CAStruct_spec.rb +0 -71
  332. data/spec/Classes/CATranspose_spec.rb +0 -60
  333. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  334. data/spec/Classes/CAWindow_spec.rb +0 -54
  335. data/spec/Classes/CAWrap_spec.rb +0 -8
  336. data/spec/Classes/CArray_spec.rb +0 -184
  337. data/spec/Classes/CScalar_spec.rb +0 -55
  338. data/spec/Features/feature_130_spec.rb +0 -19
  339. data/spec/Features/feature_attributes_spec.rb +0 -280
  340. data/spec/Features/feature_boolean_spec.rb +0 -98
  341. data/spec/Features/feature_broadcast.rb +0 -116
  342. data/spec/Features/feature_cast_function.rb +0 -19
  343. data/spec/Features/feature_cast_spec.rb +0 -33
  344. data/spec/Features/feature_class_spec.rb +0 -84
  345. data/spec/Features/feature_complex_spec.rb +0 -42
  346. data/spec/Features/feature_composite_spec.rb +0 -124
  347. data/spec/Features/feature_convert_spec.rb +0 -46
  348. data/spec/Features/feature_copy_spec.rb +0 -123
  349. data/spec/Features/feature_creation_spec.rb +0 -84
  350. data/spec/Features/feature_element_spec.rb +0 -144
  351. data/spec/Features/feature_extream_spec.rb +0 -54
  352. data/spec/Features/feature_generate_spec.rb +0 -74
  353. data/spec/Features/feature_index_spec.rb +0 -69
  354. data/spec/Features/feature_mask_spec.rb +0 -580
  355. data/spec/Features/feature_math_spec.rb +0 -97
  356. data/spec/Features/feature_order_spec.rb +0 -146
  357. data/spec/Features/feature_ref_store_spec.rb +0 -209
  358. data/spec/Features/feature_serialization_spec.rb +0 -125
  359. data/spec/Features/feature_stat_spec.rb +0 -397
  360. data/spec/Features/feature_virtual_spec.rb +0 -48
  361. data/spec/Features/method_eq_spec.rb +0 -81
  362. data/spec/Features/method_is_nan_spec.rb +0 -12
  363. data/spec/Features/method_map_spec.rb +0 -54
  364. data/spec/Features/method_max_with.rb +0 -20
  365. data/spec/Features/method_min_with.rb +0 -19
  366. data/spec/Features/method_ne_spec.rb +0 -18
  367. data/spec/Features/method_project_spec.rb +0 -188
  368. data/spec/Features/method_ref_spec.rb +0 -27
  369. data/spec/Features/method_round_spec.rb +0 -11
  370. data/spec/Features/method_s_linspace_spec.rb +0 -48
  371. data/spec/Features/method_s_span_spec.rb +0 -14
  372. data/spec/Features/method_seq_spec.rb +0 -47
  373. data/spec/Features/method_sort_with.rb +0 -43
  374. data/spec/Features/method_sorted_with.rb +0 -29
  375. data/spec/Features/method_span_spec.rb +0 -42
  376. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  377. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  378. data/spec/spec_all.rb +0 -10
  379. data/utils/ca_ase.rb +0 -21
  380. data/utils/ca_methods.rb +0 -15
  381. data/utils/cast_checker.rb +0 -30
  382. data/utils/convert_test.rb +0 -73
  383. data/utils/extract_yard.rb +0 -22
  384. data/utils/guess_shape.rb +0 -76
  385. data/utils/monkey_patch_methods.rb +0 -62
  386. data/utils/remove_resource_fork.sh +0 -5
@@ -1,819 +1,649 @@
1
1
  /* ---------------------------------------------------------------------------
2
-
3
- carray_math_call.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2025 Hiroki Motoyoshi
8
-
9
- ---------------------------------------------------------------------------- */
2
+ *
3
+ * carray_call_cfunc.c -- ext-author math-call wrapper API
4
+ *
5
+ * GENERATED by ext/mk_call_cfunc.rb -- DO NOT EDIT
6
+ * To modify the template or add a new arity, edit mk_call_cfunc.rb
7
+ * and regenerate (= make / extconf re-runs the generator).
8
+ *
9
+ * Provides `ca_call_cfunc_N` (raw arity 1..7) and `ca_call_cfunc_M_N`
10
+ * (typed dispatcher) used by external CArray gems (carray-gsl, etc.)
11
+ * to wrap C math functions over CArray operations.
12
+ *
13
+ * Reentrant variants `ca_call_cfunc_N_r` and `ca_call_cfunc_M_N_r`
14
+ * (= POSIX `_r` convention, cf. qsort_r / bsearch_r / strtok_r) take
15
+ * a trailing `void *userdata` argument that is passed through to every
16
+ * per-cell callback invocation as its last argument. Use when the
17
+ * callback needs to share state with the caller (accumulators,
18
+ * configuration flags, library plan handles, ...) without resorting to
19
+ * file-static / global plumbing.
20
+ *
21
+ * Attach-safe: INPUT-only operands (= fsync[k] == '0') never call
22
+ * ca_attach on the operand or its mask (= alias check + ALLOCV +
23
+ * ca_xfer_all for non-alias). OUTPUT operands (= fsync[k] == '1')
24
+ * use ca_attach + ca_sync (= legitimate per the refined input-only-
25
+ * operand invariant established in PROPOSAL_EAGER_ELEMENTWISE_NO_ATTACH
26
+ * and extended in PROPOSAL_EAGER_SLOWPATH_CHUNKING_ARENA).
27
+ *
28
+ * Slab variants `ca_call_cslab_N` / `ca_call_cslab_N_r` take the chunked
29
+ * path instead (ca_sweep_acquire_chunked / ca_sweep_next_chunk /
30
+ * ca_sweep_release_chunked) and hand the callback a whole chunk -- base /
31
+ * stride per operand, a cell count, and the chunk's slice of the mask --
32
+ * rather than one cell. A non-alias INPUT is then re-gathered into a
33
+ * ~32KB arena scratch per chunk rather than materialised whole, so input
34
+ * memory peak stops scaling with the operand; and the indirect call is
35
+ * paid once per chunk, so the author's inner loop is one the compiler can
36
+ * vectorise. Use cfunc when the per-cell body is what you have (a math
37
+ * function to wrap); use cslab when the operand is large, virtual, or the
38
+ * body is worth vectorising.
39
+ *
40
+ * L0.1 (PROPOSAL_L0_AUTHOR_SURFACE, 2026-06-11): the per-operand acquire
41
+ * + broadcast check + mask OR + release lifecycle is now factored out
42
+ * into ext/ca_sweep_engine.{c,h} (ca_sweep_acquire / ca_sweep_release). This
43
+ * file keeps the arity-dependent inner loop only. ABI unchanged.
44
+ *
45
+ * --------------------------------------------------------------------------- */
10
46
 
11
47
  #include "carray.h"
48
+ #include "ca_sweep_engine.h"
49
+ #include <string.h>
50
+
51
+ /* The chunk's iteration mask, or NULL when no INPUT operand carried one.
52
+ m0 is chunk-sized and re-gathered per chunk by ca_sweep_next_chunk, so
53
+ it is already the slice -- one byte per cell, indexed 0..chunk_n-1
54
+ alongside base[] and stride[]. */
55
+ static const boolean8_t *
56
+ ca_sweep_chunk_mask (ca_sweep_state_t *st)
57
+ {
58
+ return st->m0;
59
+ }
12
60
 
13
61
  VALUE
14
62
  ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
15
- VALUE rcx0)
63
+ VALUE rcx0)
16
64
  {
17
- CArray *cx0;
18
- ca_size_t n;
19
-
20
- if ( strlen(fsync) != 1 ) {
21
- rb_raise(rb_eRuntimeError,
22
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
23
- }
24
-
25
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
26
-
27
- ca_attach(cx0);
28
-
65
+ CArray *cx[1];
66
+ char *base[1];
67
+ ca_size_t stride[1];
68
+ char *owned_buf[1];
69
+ int attached[1];
70
+ ca_sweep_state_t state;
71
+ int k_op;
72
+
73
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
74
+
75
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
76
+ broadcast shape check, mask OR across INPUTs, mask propagate to
77
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
78
+ state.n_ops = 1;
79
+ state.fsync = fsync;
80
+ state.cx = cx;
81
+ state.base = base;
82
+ state.stride = stride;
83
+ state.owned_buf = owned_buf;
84
+ state.attached = attached;
85
+ state.no_mask = 0;
86
+ state.src_label = "ca_call_cfunc_1";
87
+
88
+ ca_sweep_acquire(&state);
89
+
90
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
29
91
  {
30
- char *p0;
31
- char *q0;
32
- ca_size_t s0;
33
- ca_size_t k;
34
- n = ca_set_iterator(1, cx0, &q0, &s0);
35
- s0 *= cx0->bytes;
36
- #ifdef _OPENMP
37
- #pragma omp parallel for private(p0)
38
- #endif
39
- for (k=0; k<n; k++) {
40
- p0 = q0 + k*s0;
41
- func(p0);
92
+ char *p[1];
93
+ ca_size_t k;
94
+ if ( state.m0 ) {
95
+ for ( k = 0; k < state.n_kernel; k++ ) {
96
+ if ( ! state.m0[k] ) {
97
+ for ( k_op = 0; k_op < 1; k_op++ ) {
98
+ p[k_op] = base[k_op] + k * stride[k_op];
99
+ }
100
+ func(p[0]);
101
+ }
102
+ }
103
+ } else {
104
+ for ( k = 0; k < state.n_kernel; k++ ) {
105
+ for ( k_op = 0; k_op < 1; k_op++ ) {
106
+ p[k_op] = base[k_op] + k * stride[k_op];
107
+ }
108
+ func(p[0]);
109
+ }
42
110
  }
43
111
  }
44
112
 
45
- ca_sync(cx0);
46
- ca_detach(cx0);
113
+ ca_sweep_release(&state);
47
114
 
48
115
  return rcx0;
49
116
  }
50
117
 
51
-
52
118
  VALUE
53
119
  ca_call_cfunc_2 (void (*func)(void *p0, void *p1), const char *fsync,
54
- VALUE rcx0, VALUE rcx1)
120
+ VALUE rcx0, VALUE rcx1)
55
121
  {
56
- CArray *cx0, *cx1;
57
- boolean8_t *m0 = NULL, *m;
58
- ca_size_t n;
59
-
60
- if ( strlen(fsync) != 2 ) {
61
- rb_raise(rb_eRuntimeError,
62
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
63
- }
64
-
65
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
66
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
67
-
68
- ca_attach_n(2, cx0, cx1);
69
-
70
- {
71
- CArray *cx[2];
72
- int i = 0;
73
- if ( fsync[0] == '0' ) cx[i++] = cx0;
74
- if ( fsync[1] == '0' ) cx[i++] = cx1;
75
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
76
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
77
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
78
- }
79
-
122
+ CArray *cx[2];
123
+ char *base[2];
124
+ ca_size_t stride[2];
125
+ char *owned_buf[2];
126
+ int attached[2];
127
+ ca_sweep_state_t state;
128
+ int k_op;
129
+
130
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
131
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
132
+
133
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
134
+ broadcast shape check, mask OR across INPUTs, mask propagate to
135
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
136
+ state.n_ops = 2;
137
+ state.fsync = fsync;
138
+ state.cx = cx;
139
+ state.base = base;
140
+ state.stride = stride;
141
+ state.owned_buf = owned_buf;
142
+ state.attached = attached;
143
+ state.no_mask = 0;
144
+ state.src_label = "ca_call_cfunc_2";
145
+
146
+ ca_sweep_acquire(&state);
147
+
148
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
80
149
  {
81
- char *p0, *p1;
82
- char *q0, *q1;
83
- ca_size_t s0, s1;
84
- ca_size_t k;
85
-
86
- n = ca_set_iterator(2, cx0, &q0, &s0,
87
- cx1, &q1, &s1);
88
- s0 *= cx0->bytes;
89
- s1 *= cx1->bytes;
90
-
91
- if ( m0 ) {
92
- #ifdef _OPENMP
93
- #pragma omp parallel for private(p0,p1)
94
- #endif
95
- for (k=0; k<n; k++) {
96
- m = m0 + k;
97
- if ( ! *m ) {
98
- p0 = q0 + k*s0;
99
- p1 = q1 + k*s1;
100
- func(p0, p1);
150
+ char *p[2];
151
+ ca_size_t k;
152
+ if ( state.m0 ) {
153
+ for ( k = 0; k < state.n_kernel; k++ ) {
154
+ if ( ! state.m0[k] ) {
155
+ for ( k_op = 0; k_op < 2; k_op++ ) {
156
+ p[k_op] = base[k_op] + k * stride[k_op];
157
+ }
158
+ func(p[0], p[1]);
101
159
  }
102
160
  }
103
- }
104
- else {
105
- #ifdef _OPENMP
106
- #pragma omp parallel for private(p0,p1)
107
- #endif
108
- for (k=0; k<n; k++) {
109
- p0 = q0 + k*s0;
110
- p1 = q1 + k*s1;
111
- func(p0, p1);
161
+ } else {
162
+ for ( k = 0; k < state.n_kernel; k++ ) {
163
+ for ( k_op = 0; k_op < 2; k_op++ ) {
164
+ p[k_op] = base[k_op] + k * stride[k_op];
165
+ }
166
+ func(p[0], p[1]);
112
167
  }
113
168
  }
114
169
  }
115
- if ( fsync[0] == '1' ) ca_sync(cx0);
116
- if ( fsync[1] == '1' ) ca_sync(cx1);
117
- ca_detach_n(2, cx0, cx1);
118
170
 
119
- free(m0);
171
+ ca_sweep_release(&state);
120
172
 
121
173
  return rcx0;
122
174
  }
123
175
 
124
176
  VALUE
125
177
  ca_call_cfunc_3 (void (*func)(void *p0, void *p1, void *p2), const char *fsync,
126
- VALUE rcx0, VALUE rcx1, VALUE rcx2)
178
+ VALUE rcx0, VALUE rcx1, VALUE rcx2)
127
179
  {
128
- CArray *cx0, *cx1, *cx2;
129
- boolean8_t *m0 = NULL, *m;
130
- ca_size_t n;
131
-
132
- if ( strlen(fsync) != 3 ) {
133
- rb_raise(rb_eRuntimeError,
134
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
135
- }
136
-
137
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
138
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
139
- TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx2);
140
-
141
- ca_attach_n(3, cx0, cx1, cx2);
142
-
143
- {
144
- CArray *cx[3];
145
- int i = 0;
146
- if ( fsync[0] == '0' ) cx[i++] = cx0;
147
- if ( fsync[1] == '0' ) cx[i++] = cx1;
148
- if ( fsync[2] == '0' ) cx[i++] = cx2;
149
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
150
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
151
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
152
- if ( fsync[2] == '1' ) ca_copy_mask_overwrite_n(cx2, cx2->elements, i, cx);
153
- }
154
-
180
+ CArray *cx[3];
181
+ char *base[3];
182
+ ca_size_t stride[3];
183
+ char *owned_buf[3];
184
+ int attached[3];
185
+ ca_sweep_state_t state;
186
+ int k_op;
187
+
188
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
189
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
190
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
191
+
192
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
193
+ broadcast shape check, mask OR across INPUTs, mask propagate to
194
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
195
+ state.n_ops = 3;
196
+ state.fsync = fsync;
197
+ state.cx = cx;
198
+ state.base = base;
199
+ state.stride = stride;
200
+ state.owned_buf = owned_buf;
201
+ state.attached = attached;
202
+ state.no_mask = 0;
203
+ state.src_label = "ca_call_cfunc_3";
204
+
205
+ ca_sweep_acquire(&state);
206
+
207
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
155
208
  {
156
- char *p0, *p1, *p2;
157
- char *q0, *q1, *q2;
158
- ca_size_t s0, s1, s2;
159
- ca_size_t k;
160
-
161
- n = ca_set_iterator(3, cx0, &q0, &s0,
162
- cx1, &q1, &s1,
163
- cx2, &q2, &s2);
164
- s0 *= cx0->bytes;
165
- s1 *= cx1->bytes;
166
- s2 *= cx2->bytes;
167
-
168
- if ( m0 ) {
169
- #ifdef _OPENMP
170
- #pragma omp parallel for private(p0,p1,p2)
171
- #endif
172
- for (k=0; k<n; k++) {
173
- m = m0 + k;
174
- if ( ! *m ) {
175
- p0 = q0 + k*s0;
176
- p1 = q1 + k*s1;
177
- p2 = q2 + k*s2;
178
- func(p0, p1, p2);
209
+ char *p[3];
210
+ ca_size_t k;
211
+ if ( state.m0 ) {
212
+ for ( k = 0; k < state.n_kernel; k++ ) {
213
+ if ( ! state.m0[k] ) {
214
+ for ( k_op = 0; k_op < 3; k_op++ ) {
215
+ p[k_op] = base[k_op] + k * stride[k_op];
216
+ }
217
+ func(p[0], p[1], p[2]);
179
218
  }
180
219
  }
181
- }
182
- else {
183
- #ifdef _OPENMP
184
- #pragma omp parallel for private(p0,p1,p2)
185
- #endif
186
- for (k=0; k<n; k++) {
187
- p0 = q0 + k*s0;
188
- p1 = q1 + k*s1;
189
- p2 = q2 + k*s2;
190
- func(p0, p1, p2);
220
+ } else {
221
+ for ( k = 0; k < state.n_kernel; k++ ) {
222
+ for ( k_op = 0; k_op < 3; k_op++ ) {
223
+ p[k_op] = base[k_op] + k * stride[k_op];
224
+ }
225
+ func(p[0], p[1], p[2]);
191
226
  }
192
227
  }
193
228
  }
194
- if ( fsync[0] == '1' ) ca_sync(cx0);
195
- if ( fsync[1] == '1' ) ca_sync(cx1);
196
- if ( fsync[2] == '1' ) ca_sync(cx2);
197
- ca_detach_n(3, cx0, cx1, cx2);
198
229
 
199
- free(m0);
230
+ ca_sweep_release(&state);
200
231
 
201
232
  return rcx0;
202
233
  }
203
234
 
204
235
  VALUE
205
236
  ca_call_cfunc_4 (void (*func)(void *p0, void *p1, void *p2, void *p3), const char *fsync,
206
- VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3)
237
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3)
207
238
  {
208
- CArray *cx0, *cx1, *cx2, *cx3;
209
- boolean8_t *m0 = NULL, *m;
210
- ca_size_t n;
211
-
212
- if ( strlen(fsync) != 4 ) {
213
- rb_raise(rb_eRuntimeError,
214
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
215
- }
216
-
217
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
218
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
219
- TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx2);
220
- TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx3);
221
-
222
- ca_attach_n(4, cx0, cx1, cx2, cx3);
223
-
224
- {
225
- CArray *cx[4];
226
- int i = 0;
227
- if ( fsync[0] == '0' ) cx[i++] = cx0;
228
- if ( fsync[1] == '0' ) cx[i++] = cx1;
229
- if ( fsync[2] == '0' ) cx[i++] = cx2;
230
- if ( fsync[3] == '0' ) cx[i++] = cx3;
231
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
232
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
233
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
234
- if ( fsync[2] == '1' ) ca_copy_mask_overwrite_n(cx2, cx2->elements, i, cx);
235
- if ( fsync[3] == '1' ) ca_copy_mask_overwrite_n(cx3, cx3->elements, i, cx);
236
- }
237
-
239
+ CArray *cx[4];
240
+ char *base[4];
241
+ ca_size_t stride[4];
242
+ char *owned_buf[4];
243
+ int attached[4];
244
+ ca_sweep_state_t state;
245
+ int k_op;
246
+
247
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
248
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
249
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
250
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
251
+
252
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
253
+ broadcast shape check, mask OR across INPUTs, mask propagate to
254
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
255
+ state.n_ops = 4;
256
+ state.fsync = fsync;
257
+ state.cx = cx;
258
+ state.base = base;
259
+ state.stride = stride;
260
+ state.owned_buf = owned_buf;
261
+ state.attached = attached;
262
+ state.no_mask = 0;
263
+ state.src_label = "ca_call_cfunc_4";
264
+
265
+ ca_sweep_acquire(&state);
266
+
267
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
238
268
  {
239
- char *p0, *p1, *p2, *p3;
240
- char *q0, *q1, *q2, *q3;
241
- ca_size_t s0, s1, s2, s3;
242
- ca_size_t k;
243
-
244
- n = ca_set_iterator(4, cx0, &q0, &s0,
245
- cx1, &q1, &s1,
246
- cx2, &q2, &s2,
247
- cx3, &q3, &s3);
248
-
249
- s0 *= cx0->bytes;
250
- s1 *= cx1->bytes;
251
- s2 *= cx2->bytes;
252
- s3 *= cx3->bytes;
253
-
254
- if ( m0 ) {
255
- #ifdef _OPENMP
256
- #pragma omp parallel for private(p0,p1,p2,p3)
257
- #endif
258
- for (k=0; k<n; k++) {
259
- m = m0 + k;
260
- if ( ! *m ) {
261
- p0 = q0 + k*s0;
262
- p1 = q1 + k*s1;
263
- p2 = q2 + k*s2;
264
- p3 = q3 + k*s3;
265
- func(p0, p1, p2, p3);
269
+ char *p[4];
270
+ ca_size_t k;
271
+ if ( state.m0 ) {
272
+ for ( k = 0; k < state.n_kernel; k++ ) {
273
+ if ( ! state.m0[k] ) {
274
+ for ( k_op = 0; k_op < 4; k_op++ ) {
275
+ p[k_op] = base[k_op] + k * stride[k_op];
276
+ }
277
+ func(p[0], p[1], p[2], p[3]);
266
278
  }
267
279
  }
268
- }
269
- else {
270
- #ifdef _OPENMP
271
- #pragma omp parallel for private(p0,p1,p2,p3)
272
- #endif
273
- for (k=0; k<n; k++) {
274
- p0 = q0 + k*s0;
275
- p1 = q1 + k*s1;
276
- p2 = q2 + k*s2;
277
- p3 = q3 + k*s3;
278
- func(p0, p1, p2, p3);
280
+ } else {
281
+ for ( k = 0; k < state.n_kernel; k++ ) {
282
+ for ( k_op = 0; k_op < 4; k_op++ ) {
283
+ p[k_op] = base[k_op] + k * stride[k_op];
284
+ }
285
+ func(p[0], p[1], p[2], p[3]);
279
286
  }
280
287
  }
281
288
  }
282
- if ( fsync[0] == '1' ) ca_sync(cx0);
283
- if ( fsync[1] == '1' ) ca_sync(cx1);
284
- if ( fsync[2] == '1' ) ca_sync(cx2);
285
- if ( fsync[3] == '1' ) ca_sync(cx3);
286
- ca_detach_n(4, cx0, cx1, cx2, cx3);
287
289
 
288
- free(m0);
290
+ ca_sweep_release(&state);
289
291
 
290
292
  return rcx0;
291
293
  }
292
294
 
293
295
  VALUE
294
- ca_call_cfunc_5 (void (*func)(void*,void*,void*,void*,void*), const char *fsync,
295
- VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4)
296
+ ca_call_cfunc_5 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4), const char *fsync,
297
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4)
296
298
  {
297
- CArray *cx0, *cx1, *cx2, *cx3, *cx4;
298
- boolean8_t *m0 = NULL, *m;
299
- ca_size_t n;
300
-
301
- if ( strlen(fsync) != 5 ) {
302
- rb_raise(rb_eRuntimeError,
303
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
304
- }
305
-
306
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
307
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
308
- TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx2);
309
- TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx3);
310
- TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx4);
311
-
312
- ca_attach_n(5, cx0, cx1, cx2, cx3, cx4);
313
-
314
- {
315
- CArray *cx[5];
316
- int i = 0;
317
- if ( fsync[0] == '0' ) cx[i++] = cx0;
318
- if ( fsync[1] == '0' ) cx[i++] = cx1;
319
- if ( fsync[2] == '0' ) cx[i++] = cx2;
320
- if ( fsync[3] == '0' ) cx[i++] = cx3;
321
- if ( fsync[4] == '0' ) cx[i++] = cx4;
322
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
323
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
324
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
325
- if ( fsync[2] == '1' ) ca_copy_mask_overwrite_n(cx2, cx2->elements, i, cx);
326
- if ( fsync[3] == '1' ) ca_copy_mask_overwrite_n(cx3, cx3->elements, i, cx);
327
- if ( fsync[4] == '1' ) ca_copy_mask_overwrite_n(cx4, cx4->elements, i, cx);
328
- }
329
-
299
+ CArray *cx[5];
300
+ char *base[5];
301
+ ca_size_t stride[5];
302
+ char *owned_buf[5];
303
+ int attached[5];
304
+ ca_sweep_state_t state;
305
+ int k_op;
306
+
307
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
308
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
309
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
310
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
311
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
312
+
313
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
314
+ broadcast shape check, mask OR across INPUTs, mask propagate to
315
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
316
+ state.n_ops = 5;
317
+ state.fsync = fsync;
318
+ state.cx = cx;
319
+ state.base = base;
320
+ state.stride = stride;
321
+ state.owned_buf = owned_buf;
322
+ state.attached = attached;
323
+ state.no_mask = 0;
324
+ state.src_label = "ca_call_cfunc_5";
325
+
326
+ ca_sweep_acquire(&state);
327
+
328
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
330
329
  {
331
- char *p0, *p1, *p2, *p3, *p4;
332
- char *q0, *q1, *q2, *q3, *q4;
333
- ca_size_t s0, s1, s2, s3, s4;
334
- ca_size_t k;
335
-
336
- n = ca_set_iterator(5, cx0, &q0, &s0,
337
- cx1, &q1, &s1,
338
- cx2, &q2, &s2,
339
- cx3, &q3, &s3,
340
- cx4, &q4, &s4);
341
-
342
- s0 *= cx0->bytes;
343
- s1 *= cx1->bytes;
344
- s2 *= cx2->bytes;
345
- s3 *= cx3->bytes;
346
- s4 *= cx4->bytes;
347
-
348
- if ( m0 ) {
349
- #ifdef _OPENMP
350
- #pragma omp parallel for private(p0,p1,p2,p3,p4)
351
- #endif
352
- for (k=0; k<n; k++) {
353
- m = m0 + k;
354
- if ( ! *m ) {
355
- p0 = q0 + k*s0;
356
- p1 = q1 + k*s1;
357
- p2 = q2 + k*s2;
358
- p3 = q3 + k*s3;
359
- p4 = q4 + k*s4;
360
- func(p0, p1, p2, p3, p4);
330
+ char *p[5];
331
+ ca_size_t k;
332
+ if ( state.m0 ) {
333
+ for ( k = 0; k < state.n_kernel; k++ ) {
334
+ if ( ! state.m0[k] ) {
335
+ for ( k_op = 0; k_op < 5; k_op++ ) {
336
+ p[k_op] = base[k_op] + k * stride[k_op];
337
+ }
338
+ func(p[0], p[1], p[2], p[3], p[4]);
361
339
  }
362
340
  }
363
- }
364
- else {
365
- #ifdef _OPENMP
366
- #pragma omp parallel for private(p0,p1,p2,p3,p4)
367
- #endif
368
- for (k=0; k<n; k++) {
369
- p0 = q0 + k*s0;
370
- p1 = q1 + k*s1;
371
- p2 = q2 + k*s2;
372
- p3 = q3 + k*s3;
373
- p4 = q4 + k*s4;
374
- func(p0, p1, p2, p3, p4);
341
+ } else {
342
+ for ( k = 0; k < state.n_kernel; k++ ) {
343
+ for ( k_op = 0; k_op < 5; k_op++ ) {
344
+ p[k_op] = base[k_op] + k * stride[k_op];
345
+ }
346
+ func(p[0], p[1], p[2], p[3], p[4]);
375
347
  }
376
348
  }
377
349
  }
378
- if ( fsync[0] == '1' ) ca_sync(cx0);
379
- if ( fsync[1] == '1' ) ca_sync(cx1);
380
- if ( fsync[2] == '1' ) ca_sync(cx2);
381
- if ( fsync[3] == '1' ) ca_sync(cx3);
382
- if ( fsync[4] == '1' ) ca_sync(cx4);
383
- ca_detach_n(5, cx0, cx1, cx2, cx3, cx4);
384
350
 
385
- free(m0);
351
+ ca_sweep_release(&state);
386
352
 
387
353
  return rcx0;
388
354
  }
389
355
 
390
356
  VALUE
391
- ca_call_cfunc_6 (void (*func)(void*,void*,void*,void*,void*,void*), const char *fsync,
392
- VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5)
357
+ ca_call_cfunc_6 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5), const char *fsync,
358
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5)
393
359
  {
394
- CArray *cx0, *cx1, *cx2, *cx3, *cx4, *cx5;
395
- boolean8_t *m0 = NULL, *m;
396
- ca_size_t n;
397
-
398
- if ( strlen(fsync) != 6 ) {
399
- rb_raise(rb_eRuntimeError,
400
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
401
- }
402
-
403
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
404
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
405
- TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx2);
406
- TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx3);
407
- TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx4);
408
- TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx5);
409
-
410
- ca_attach_n(6, cx0, cx1, cx2, cx3, cx4, cx5);
411
-
412
- {
413
- CArray *cx[6];
414
- int i = 0;
415
- if ( fsync[0] == '0' ) cx[i++] = cx0;
416
- if ( fsync[1] == '0' ) cx[i++] = cx1;
417
- if ( fsync[2] == '0' ) cx[i++] = cx2;
418
- if ( fsync[3] == '0' ) cx[i++] = cx3;
419
- if ( fsync[4] == '0' ) cx[i++] = cx4;
420
- if ( fsync[5] == '0' ) cx[i++] = cx5;
421
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
422
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
423
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
424
- if ( fsync[2] == '1' ) ca_copy_mask_overwrite_n(cx2, cx2->elements, i, cx);
425
- if ( fsync[3] == '1' ) ca_copy_mask_overwrite_n(cx3, cx3->elements, i, cx);
426
- if ( fsync[4] == '1' ) ca_copy_mask_overwrite_n(cx4, cx4->elements, i, cx);
427
- if ( fsync[5] == '1' ) ca_copy_mask_overwrite_n(cx5, cx5->elements, i, cx);
428
- }
429
-
360
+ CArray *cx[6];
361
+ char *base[6];
362
+ ca_size_t stride[6];
363
+ char *owned_buf[6];
364
+ int attached[6];
365
+ ca_sweep_state_t state;
366
+ int k_op;
367
+
368
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
369
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
370
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
371
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
372
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
373
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
374
+
375
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
376
+ broadcast shape check, mask OR across INPUTs, mask propagate to
377
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
378
+ state.n_ops = 6;
379
+ state.fsync = fsync;
380
+ state.cx = cx;
381
+ state.base = base;
382
+ state.stride = stride;
383
+ state.owned_buf = owned_buf;
384
+ state.attached = attached;
385
+ state.no_mask = 0;
386
+ state.src_label = "ca_call_cfunc_6";
387
+
388
+ ca_sweep_acquire(&state);
389
+
390
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
430
391
  {
431
- char *p0, *p1, *p2, *p3, *p4, *p5;
432
- char *q0, *q1, *q2, *q3, *q4, *q5;
433
- ca_size_t s0, s1, s2, s3, s4, s5;
434
- ca_size_t k;
435
-
436
- n = ca_set_iterator(6, cx0, &q0, &s0,
437
- cx1, &q1, &s1,
438
- cx2, &q2, &s2,
439
- cx3, &q3, &s3,
440
- cx4, &q4, &s4,
441
- cx5, &q5, &s5);
442
-
443
- s0 *= cx0->bytes;
444
- s1 *= cx1->bytes;
445
- s2 *= cx2->bytes;
446
- s3 *= cx3->bytes;
447
- s4 *= cx4->bytes;
448
- s5 *= cx5->bytes;
449
-
450
- if ( m0 ) {
451
- #ifdef _OPENMP
452
- #pragma omp parallel for private(p0,p1,p2,p3,p4,p5)
453
- #endif
454
- for (k=0; k<n; k++) {
455
- m = m0 + k;
456
- if ( ! *m ) {
457
- p0 = q0 + k*s0;
458
- p1 = q1 + k*s1;
459
- p2 = q2 + k*s2;
460
- p3 = q3 + k*s3;
461
- p4 = q4 + k*s4;
462
- p5 = q5 + k*s5;
463
- func(p0, p1, p2, p3, p4, p5);
392
+ char *p[6];
393
+ ca_size_t k;
394
+ if ( state.m0 ) {
395
+ for ( k = 0; k < state.n_kernel; k++ ) {
396
+ if ( ! state.m0[k] ) {
397
+ for ( k_op = 0; k_op < 6; k_op++ ) {
398
+ p[k_op] = base[k_op] + k * stride[k_op];
399
+ }
400
+ func(p[0], p[1], p[2], p[3], p[4], p[5]);
464
401
  }
465
402
  }
466
- }
467
- else {
468
- #ifdef _OPENMP
469
- #pragma omp parallel for private(p0,p1,p2,p3,p4,p5)
470
- #endif
471
- for (k=0; k<n; k++) {
472
- p0 = q0 + k*s0;
473
- p1 = q1 + k*s1;
474
- p2 = q2 + k*s2;
475
- p3 = q3 + k*s3;
476
- p4 = q4 + k*s4;
477
- p5 = q5 + k*s5;
478
- func(p0, p1, p2, p3, p4, p5);
403
+ } else {
404
+ for ( k = 0; k < state.n_kernel; k++ ) {
405
+ for ( k_op = 0; k_op < 6; k_op++ ) {
406
+ p[k_op] = base[k_op] + k * stride[k_op];
407
+ }
408
+ func(p[0], p[1], p[2], p[3], p[4], p[5]);
479
409
  }
480
410
  }
481
411
  }
482
- if ( fsync[0] == '1' ) ca_sync(cx0);
483
- if ( fsync[1] == '1' ) ca_sync(cx1);
484
- if ( fsync[2] == '1' ) ca_sync(cx2);
485
- if ( fsync[3] == '1' ) ca_sync(cx3);
486
- if ( fsync[4] == '1' ) ca_sync(cx4);
487
- if ( fsync[5] == '1' ) ca_sync(cx5);
488
- ca_detach_n(6, cx0, cx1, cx2, cx3, cx4, cx5);
489
412
 
490
- free(m0);
413
+ ca_sweep_release(&state);
491
414
 
492
415
  return rcx0;
493
416
  }
494
417
 
495
418
  VALUE
496
- ca_call_cfunc_7 (void (*func)(void*,void*,void*,void*,void*,void*,void*), const char *fsync,
497
- VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6)
419
+ ca_call_cfunc_7 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6), const char *fsync,
420
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6)
498
421
  {
499
- CArray *cx0, *cx1, *cx2, *cx3, *cx4, *cx5, *cx6;
500
- boolean8_t *m0 = NULL, *m;
501
- ca_size_t n;
502
-
503
- if ( strlen(fsync) != 7 ) {
504
- rb_raise(rb_eRuntimeError,
505
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
506
- }
507
-
508
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
509
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
510
- TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx2);
511
- TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx3);
512
- TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx4);
513
- TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx5);
514
- TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx6);
515
-
516
- ca_attach_n(7, cx0, cx1, cx2, cx3, cx4, cx5, cx6);
517
-
518
- {
519
- CArray *cx[7];
520
- int i = 0;
521
- if ( fsync[0] == '0' ) cx[i++] = cx0;
522
- if ( fsync[1] == '0' ) cx[i++] = cx1;
523
- if ( fsync[2] == '0' ) cx[i++] = cx2;
524
- if ( fsync[3] == '0' ) cx[i++] = cx3;
525
- if ( fsync[4] == '0' ) cx[i++] = cx4;
526
- if ( fsync[5] == '0' ) cx[i++] = cx5;
527
- if ( fsync[6] == '0' ) cx[i++] = cx6;
528
- m = m0 = ca_allocate_mask_iterator_n(i, cx);
529
- if ( fsync[0] == '1' ) ca_copy_mask_overwrite_n(cx0, cx0->elements, i, cx);
530
- if ( fsync[1] == '1' ) ca_copy_mask_overwrite_n(cx1, cx1->elements, i, cx);
531
- if ( fsync[2] == '1' ) ca_copy_mask_overwrite_n(cx2, cx2->elements, i, cx);
532
- if ( fsync[3] == '1' ) ca_copy_mask_overwrite_n(cx3, cx3->elements, i, cx);
533
- if ( fsync[4] == '1' ) ca_copy_mask_overwrite_n(cx4, cx4->elements, i, cx);
534
- if ( fsync[5] == '1' ) ca_copy_mask_overwrite_n(cx5, cx5->elements, i, cx);
535
- if ( fsync[6] == '1' ) ca_copy_mask_overwrite_n(cx6, cx6->elements, i, cx);
536
- }
537
-
422
+ CArray *cx[7];
423
+ char *base[7];
424
+ ca_size_t stride[7];
425
+ char *owned_buf[7];
426
+ int attached[7];
427
+ ca_sweep_state_t state;
428
+ int k_op;
429
+
430
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
431
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
432
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
433
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
434
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
435
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
436
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
437
+
438
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
439
+ broadcast shape check, mask OR across INPUTs, mask propagate to
440
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
441
+ state.n_ops = 7;
442
+ state.fsync = fsync;
443
+ state.cx = cx;
444
+ state.base = base;
445
+ state.stride = stride;
446
+ state.owned_buf = owned_buf;
447
+ state.attached = attached;
448
+ state.no_mask = 0;
449
+ state.src_label = "ca_call_cfunc_7";
450
+
451
+ ca_sweep_acquire(&state);
452
+
453
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
538
454
  {
539
- char *p0, *p1, *p2, *p3, *p4, *p5, *p6;
540
- char *q0, *q1, *q2, *q3, *q4, *q5, *q6;
541
- ca_size_t s0, s1, s2, s3, s4, s5, s6;
542
- ca_size_t k;
543
-
544
- n = ca_set_iterator(7, cx0, &q0, &s0,
545
- cx1, &q1, &s1,
546
- cx2, &q2, &s2,
547
- cx3, &q3, &s3,
548
- cx4, &q4, &s4,
549
- cx5, &q5, &s5,
550
- cx6, &q6, &s6);
551
-
552
- s0 *= cx0->bytes;
553
- s1 *= cx1->bytes;
554
- s2 *= cx2->bytes;
555
- s3 *= cx3->bytes;
556
- s4 *= cx4->bytes;
557
- s5 *= cx5->bytes;
558
- s6 *= cx6->bytes;
559
-
560
- if ( m0 ) {
561
- #ifdef _OPENMP
562
- #pragma omp parallel for private(p0,p1,p2,p3,p4,p5,p6)
563
- #endif
564
- for (k=0; k<n; k++) {
565
- m = m0 + k;
566
- if ( ! *m ) {
567
- p0 = q0 + k*s0;
568
- p1 = q1 + k*s1;
569
- p2 = q2 + k*s2;
570
- p3 = q3 + k*s3;
571
- p4 = q4 + k*s4;
572
- p5 = q5 + k*s5;
573
- p6 = q6 + k*s6;
574
- func(p0, p1, p2, p3, p4, p5, p6);
455
+ char *p[7];
456
+ ca_size_t k;
457
+ if ( state.m0 ) {
458
+ for ( k = 0; k < state.n_kernel; k++ ) {
459
+ if ( ! state.m0[k] ) {
460
+ for ( k_op = 0; k_op < 7; k_op++ ) {
461
+ p[k_op] = base[k_op] + k * stride[k_op];
462
+ }
463
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
575
464
  }
576
465
  }
577
- }
578
- else {
579
- #ifdef _OPENMP
580
- #pragma omp parallel for private(p0,p1,p2,p3,p4,p5,p6)
581
- #endif
582
- for (k=0; k<n; k++) {
583
- p0 = q0 + k*s0;
584
- p1 = q1 + k*s1;
585
- p2 = q2 + k*s2;
586
- p3 = q3 + k*s3;
587
- p4 = q4 + k*s4;
588
- p5 = q5 + k*s5;
589
- p6 = q6 + k*s6;
590
- func(p0, p1, p2, p3, p4, p5, p6);
466
+ } else {
467
+ for ( k = 0; k < state.n_kernel; k++ ) {
468
+ for ( k_op = 0; k_op < 7; k_op++ ) {
469
+ p[k_op] = base[k_op] + k * stride[k_op];
470
+ }
471
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
591
472
  }
592
473
  }
593
-
594
474
  }
595
- if ( fsync[0] == '1' ) ca_sync(cx0);
596
- if ( fsync[1] == '1' ) ca_sync(cx1);
597
- if ( fsync[2] == '1' ) ca_sync(cx2);
598
- if ( fsync[3] == '1' ) ca_sync(cx3);
599
- if ( fsync[4] == '1' ) ca_sync(cx4);
600
- if ( fsync[5] == '1' ) ca_sync(cx5);
601
- if ( fsync[6] == '1' ) ca_sync(cx6);
602
- ca_detach_n(7, cx0, cx1, cx2, cx3, cx4, cx5, cx6);
603
475
 
604
- free(m0);
476
+ ca_sweep_release(&state);
605
477
 
606
478
  return rcx0;
607
479
  }
608
480
 
481
+ /* -------------------------------------------------------------------- */
482
+ /* Typed dispatchers: M outputs, N inputs. Wrap each input readonly to */
483
+ /* its declared data_type, allocate output template(s), delegate to raw. */
609
484
  /* -------------------------------------------------------------------- */
610
485
 
611
486
  VALUE
612
- ca_call_cfunc_1_1 (int8_t dty, int8_t dtx,
613
- void (*mathfunc)(void*,void*), VALUE rx)
614
- {
615
- volatile VALUE ry;
616
- rx = rb_ca_wrap_readonly(rx, INT2NUM(dtx));
617
- if ( dty != dtx ) {
618
- ry = rb_ca_template(rb_ca_wrap_readonly(rx, INT2NUM(dty)));
619
- }
620
- else {
621
- ry = rb_ca_template(rx);
487
+ ca_call_cfunc_1_1 (int8_t dty, int8_t dtx1, void (*mathfunc)(void*, void*), volatile VALUE rx1)
488
+ {
489
+ volatile VALUE ry = Qnil;
490
+
491
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
492
+
493
+ if ( dty != dtx1 ) {
494
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
495
+ } else {
496
+ ry = rb_ca_template_n(1, rx1);
622
497
  }
623
- ca_call_cfunc_2(mathfunc, "10", ry, rx);
498
+
499
+ ca_call_cfunc_2(mathfunc, "10", ry, rx1);
500
+
624
501
  if ( rb_ca_is_scalar(ry) ) {
625
- return rb_ca_fetch_addr(ry, 0);
626
- }
627
- else {
628
- return ry;
502
+ ry = rb_ca_fetch_addr(ry, 0);
629
503
  }
504
+ return ry;
630
505
  }
631
506
 
632
507
  VALUE
633
- ca_call_cfunc_1_2 (int8_t dty,
634
- int8_t dtx1,
635
- int8_t dtx2,
636
- void (*mathfunc)(void*,void*,void*),
637
- volatile VALUE rx1,
638
- volatile VALUE rx2)
639
- {
640
- volatile VALUE ry = Qnil;
641
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
642
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
508
+ ca_call_cfunc_1_2 (int8_t dty, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2)
509
+ {
510
+ volatile VALUE ry = Qnil;
511
+
512
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
513
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
514
+
643
515
  if ( dty != dtx1 || dty != dtx2 ) {
644
- ry = rb_ca_template_n(2,
645
- rb_ca_wrap_readonly(rx1, INT2NUM(dty)),
646
- rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
516
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
517
+ } else {
518
+ ry = rb_ca_template_n(2, rx1, rx2);
647
519
  }
648
- else {
649
- ry = rb_ca_template_n(2, rx1, rx2);
650
- }
651
- ca_call_cfunc_3(mathfunc, "100", ry, rx1, rx2);
520
+
521
+ ca_call_cfunc_3(mathfunc, "100", ry, rx1, rx2);
522
+
652
523
  if ( rb_ca_is_scalar(ry) ) {
653
- return rb_ca_fetch_addr(ry, 0);
654
- }
655
- else {
656
- return ry;
524
+ ry = rb_ca_fetch_addr(ry, 0);
657
525
  }
526
+ return ry;
658
527
  }
659
528
 
660
-
661
529
  VALUE
662
- ca_call_cfunc_1_3 (int8_t dty,
663
- int8_t dtx1,
664
- int8_t dtx2,
665
- int8_t dtx3,
666
- void (*mathfunc)(void*,void*,void*,void*),
667
- volatile VALUE rx1,
668
- volatile VALUE rx2,
669
- volatile VALUE rx3)
670
- {
671
- volatile VALUE ry;
672
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
673
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
674
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
675
- ry = rb_ca_template_n(3,
676
- rb_ca_wrap_readonly(rx1, INT2NUM(dty)),
677
- rb_ca_wrap_readonly(rx2, INT2NUM(dty)),
678
- rb_ca_wrap_readonly(rx3, INT2NUM(dty)));
679
- ca_call_cfunc_4(mathfunc, "1000", ry, rx1, rx2, rx3);
680
- if ( rb_ca_is_scalar(ry) ) {
681
- return rb_ca_fetch_addr(ry, 0);
682
- }
683
- else {
684
- return ry;
685
- }
686
- }
687
-
688
- VALUE
689
- ca_call_cfunc_1_4 (int8_t dty,
690
- int8_t dtx1,
691
- int8_t dtx2,
692
- int8_t dtx3,
693
- int8_t dtx4,
694
- void (*mathfunc)(void*,void*,void*,void*,void*),
695
- volatile VALUE rx1,
696
- volatile VALUE rx2,
697
- volatile VALUE rx3,
698
- volatile VALUE rx4)
699
- {
700
- volatile VALUE ry;
701
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
702
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
703
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
704
- rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
705
- ry = rb_ca_template_n(4,
706
- rb_ca_wrap_readonly(rx1, INT2NUM(dty)),
707
- rb_ca_wrap_readonly(rx2, INT2NUM(dty)),
708
- rb_ca_wrap_readonly(rx3, INT2NUM(dty)),
709
- rb_ca_wrap_readonly(rx4, INT2NUM(dty)));
710
- ca_call_cfunc_5(mathfunc, "10000", ry, rx1, rx2, rx3, rx4);
530
+ ca_call_cfunc_1_3 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
531
+ {
532
+ volatile VALUE ry = Qnil;
533
+
534
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
535
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
536
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
537
+
538
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
539
+ ry = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)));
540
+ } else {
541
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
542
+ }
543
+
544
+ ca_call_cfunc_4(mathfunc, "1000", ry, rx1, rx2, rx3);
545
+
711
546
  if ( rb_ca_is_scalar(ry) ) {
712
- return rb_ca_fetch_addr(ry, 0);
713
- }
714
- else {
715
- return ry;
716
- }
717
- }
718
-
719
- VALUE
720
- ca_call_cfunc_1_5 (int8_t dty,
721
- int8_t dtx1,
722
- int8_t dtx2,
723
- int8_t dtx3,
724
- int8_t dtx4,
725
- int8_t dtx5,
726
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
727
- volatile VALUE rx1,
728
- volatile VALUE rx2,
729
- volatile VALUE rx3,
730
- volatile VALUE rx4,
731
- volatile VALUE rx5)
732
- {
733
- volatile VALUE ry;
734
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
735
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
736
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
737
- rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
738
- rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
739
- ry = rb_ca_template_n(5,
740
- rb_ca_wrap_readonly(rx1, INT2NUM(dty)),
741
- rb_ca_wrap_readonly(rx2, INT2NUM(dty)),
742
- rb_ca_wrap_readonly(rx3, INT2NUM(dty)),
743
- rb_ca_wrap_readonly(rx4, INT2NUM(dty)),
744
- rb_ca_wrap_readonly(rx5, INT2NUM(dty)));
745
- ca_call_cfunc_6(mathfunc, "10000", ry, rx1, rx2, rx3, rx4, rx5);
547
+ ry = rb_ca_fetch_addr(ry, 0);
548
+ }
549
+ return ry;
550
+ }
551
+
552
+ VALUE
553
+ ca_call_cfunc_1_4 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, void (*mathfunc)(void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
554
+ {
555
+ volatile VALUE ry = Qnil;
556
+
557
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
558
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
559
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
560
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
561
+
562
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
563
+ ry = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)));
564
+ } else {
565
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
566
+ }
567
+
568
+ ca_call_cfunc_5(mathfunc, "10000", ry, rx1, rx2, rx3, rx4);
569
+
746
570
  if ( rb_ca_is_scalar(ry) ) {
747
- return rb_ca_fetch_addr(ry, 0);
748
- }
749
- else {
750
- return ry;
751
- }
752
- }
753
-
754
- VALUE
755
- ca_call_cfunc_1_6 (int8_t dty,
756
- int8_t dtx1,
757
- int8_t dtx2,
758
- int8_t dtx3,
759
- int8_t dtx4,
760
- int8_t dtx5,
761
- int8_t dtx6,
762
- void (*mathfunc)(void*,void*,void*,void*,void*,void*,void*),
763
- volatile VALUE rx1,
764
- volatile VALUE rx2,
765
- volatile VALUE rx3,
766
- volatile VALUE rx4,
767
- volatile VALUE rx5,
768
- volatile VALUE rx6)
769
- {
770
- volatile VALUE ry;
771
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
772
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
773
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
774
- rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
775
- rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
776
- rx6 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx6));
777
- ry = rb_ca_template_n(5,
778
- rb_ca_wrap_readonly(rx1, INT2NUM(dty)),
779
- rb_ca_wrap_readonly(rx2, INT2NUM(dty)),
780
- rb_ca_wrap_readonly(rx3, INT2NUM(dty)),
781
- rb_ca_wrap_readonly(rx4, INT2NUM(dty)),
782
- rb_ca_wrap_readonly(rx5, INT2NUM(dty)),
783
- rb_ca_wrap_readonly(rx6, INT2NUM(dty)));
784
- ca_call_cfunc_7(mathfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5, rx6);
571
+ ry = rb_ca_fetch_addr(ry, 0);
572
+ }
573
+ return ry;
574
+ }
575
+
576
+ VALUE
577
+ ca_call_cfunc_1_5 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, void (*mathfunc)(void*, void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5)
578
+ {
579
+ volatile VALUE ry = Qnil;
580
+
581
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
582
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
583
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
584
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
585
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
586
+
587
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
588
+ ry = rb_ca_template_n(5, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)));
589
+ } else {
590
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
591
+ }
592
+
593
+ ca_call_cfunc_6(mathfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5);
594
+
785
595
  if ( rb_ca_is_scalar(ry) ) {
786
- return rb_ca_fetch_addr(ry, 0);
596
+ ry = rb_ca_fetch_addr(ry, 0);
787
597
  }
788
- else {
789
- return ry;
598
+ return ry;
599
+ }
600
+
601
+ VALUE
602
+ ca_call_cfunc_1_6 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6)
603
+ {
604
+ volatile VALUE ry = Qnil;
605
+
606
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
607
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
608
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
609
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
610
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
611
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
612
+
613
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
614
+ ry = rb_ca_template_n(6, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)), rb_ca_wrap_readonly(rx6, INT2NUM(dty)));
615
+ } else {
616
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
617
+ }
618
+
619
+ ca_call_cfunc_7(mathfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6);
620
+
621
+ if ( rb_ca_is_scalar(ry) ) {
622
+ ry = rb_ca_fetch_addr(ry, 0);
790
623
  }
624
+ return ry;
791
625
  }
792
626
 
793
627
  VALUE
794
- ca_call_cfunc_2_1 (int8_t dty1,
795
- int8_t dty2,
796
- int8_t dtx1,
797
- void (*mathfunc)(void*,void*,void*),
798
- volatile VALUE rx1)
799
- {
800
- volatile VALUE ry1 = Qnil, ry2 = Qnil;
801
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
628
+ ca_call_cfunc_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, void (*mathfunc)(void*, void*, void*), volatile VALUE rx1)
629
+ {
630
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
631
+
632
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
633
+
802
634
  if ( dty1 != dtx1 ) {
803
- ry1 = rb_ca_template_n(1,
804
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
805
- }
806
- else {
807
- ry1 = rb_ca_template_n(1, rx1);
635
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
636
+ } else {
637
+ ry1 = rb_ca_template_n(1, rx1);
808
638
  }
809
639
  if ( dty2 != dtx1 ) {
810
- ry2 = rb_ca_template_n(1,
811
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
640
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
641
+ } else {
642
+ ry2 = rb_ca_template_n(1, rx1);
812
643
  }
813
- else {
814
- ry2 = rb_ca_template_n(1, rx1);
815
- }
816
- ca_call_cfunc_3(mathfunc, "110", ry1, ry2, rx1);
644
+
645
+ ca_call_cfunc_3(mathfunc, "110", ry1, ry2, rx1);
646
+
817
647
  if ( rb_ca_is_scalar(ry1) ) {
818
648
  ry1 = rb_ca_fetch_addr(ry1, 0);
819
649
  }
@@ -823,36 +653,27 @@ ca_call_cfunc_2_1 (int8_t dty1,
823
653
  return rb_ary_new3(2, ry1, ry2);
824
654
  }
825
655
 
826
-
827
656
  VALUE
828
- ca_call_cfunc_2_2 (int8_t dty1,
829
- int8_t dty2,
830
- int8_t dtx1,
831
- int8_t dtx2,
832
- void (*mathfunc)(void*,void*,void*,void*),
833
- volatile VALUE rx1,
834
- volatile VALUE rx2)
835
- {
836
- volatile VALUE ry1 = Qnil, ry2 = Qnil;
837
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
838
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
657
+ ca_call_cfunc_2_2 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2)
658
+ {
659
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
660
+
661
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
662
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
663
+
839
664
  if ( dty1 != dtx1 || dty1 != dtx2 ) {
840
- ry1 = rb_ca_template_n(2,
841
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)),
842
- rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
843
- }
844
- else {
845
- ry1 = rb_ca_template_n(2, rx1, rx2);
665
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
666
+ } else {
667
+ ry1 = rb_ca_template_n(2, rx1, rx2);
846
668
  }
847
669
  if ( dty2 != dtx1 || dty2 != dtx2 ) {
848
- ry2 = rb_ca_template_n(2,
849
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)),
850
- rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
670
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
671
+ } else {
672
+ ry2 = rb_ca_template_n(2, rx1, rx2);
851
673
  }
852
- else {
853
- ry2 = rb_ca_template_n(2, rx1, rx2);
854
- }
855
- ca_call_cfunc_4(mathfunc, "1100", ry1, ry2, rx1, rx2);
674
+
675
+ ca_call_cfunc_4(mathfunc, "1100", ry1, ry2, rx1, rx2);
676
+
856
677
  if ( rb_ca_is_scalar(ry1) ) {
857
678
  ry1 = rb_ca_fetch_addr(ry1, 0);
858
679
  }
@@ -863,39 +684,27 @@ ca_call_cfunc_2_2 (int8_t dty1,
863
684
  }
864
685
 
865
686
  VALUE
866
- ca_call_cfunc_2_3 (int8_t dty1,
867
- int8_t dty2,
868
- int8_t dtx1,
869
- int8_t dtx2,
870
- int8_t dtx3,
871
- void (*mathfunc)(void*,void*,void*,void*,void*),
872
- volatile VALUE rx1,
873
- volatile VALUE rx2,
874
- volatile VALUE rx3)
875
- {
876
- volatile VALUE ry1 = Qnil, ry2 = Qnil;
877
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
878
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
879
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
687
+ ca_call_cfunc_2_3 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
688
+ {
689
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
690
+
691
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
692
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
693
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
694
+
880
695
  if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
881
- ry1 = rb_ca_template_n(3,
882
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)),
883
- rb_ca_wrap_readonly(rx2, INT2NUM(dty1)),
884
- rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
885
- }
886
- else {
887
- ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
696
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
697
+ } else {
698
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
888
699
  }
889
700
  if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
890
- ry2 = rb_ca_template_n(3,
891
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)),
892
- rb_ca_wrap_readonly(rx2, INT2NUM(dty2)),
893
- rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
894
- }
895
- else {
896
- ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
701
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
702
+ } else {
703
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
897
704
  }
898
- ca_call_cfunc_5(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3);
705
+
706
+ ca_call_cfunc_5(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3);
707
+
899
708
  if ( rb_ca_is_scalar(ry1) ) {
900
709
  ry1 = rb_ca_fetch_addr(ry1, 0);
901
710
  }
@@ -906,44 +715,28 @@ ca_call_cfunc_2_3 (int8_t dty1,
906
715
  }
907
716
 
908
717
  VALUE
909
- ca_call_cfunc_2_4 (int8_t dty1,
910
- int8_t dty2,
911
- int8_t dtx1,
912
- int8_t dtx2,
913
- int8_t dtx3,
914
- int8_t dtx4,
915
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
916
- volatile VALUE rx1,
917
- volatile VALUE rx2,
918
- volatile VALUE rx3,
919
- volatile VALUE rx4)
920
- {
921
- volatile VALUE ry1 = Qnil, ry2 = Qnil;
922
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
923
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
924
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
925
- rx4 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx4));
718
+ ca_call_cfunc_2_4 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, void (*mathfunc)(void*, void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
719
+ {
720
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
721
+
722
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
723
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
724
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
725
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
726
+
926
727
  if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
927
- ry1 = rb_ca_template_n(4,
928
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)),
929
- rb_ca_wrap_readonly(rx2, INT2NUM(dty1)),
930
- rb_ca_wrap_readonly(rx3, INT2NUM(dty1)),
931
- rb_ca_wrap_readonly(rx4, INT2NUM(dty1)));
932
- }
933
- else {
934
- ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
728
+ ry1 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)), rb_ca_wrap_readonly(rx4, INT2NUM(dty1)));
729
+ } else {
730
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
935
731
  }
936
732
  if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
937
- ry2 = rb_ca_template_n(4,
938
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)),
939
- rb_ca_wrap_readonly(rx2, INT2NUM(dty2)),
940
- rb_ca_wrap_readonly(rx3, INT2NUM(dty2)),
941
- rb_ca_wrap_readonly(rx4, INT2NUM(dty2)));
733
+ ry2 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)), rb_ca_wrap_readonly(rx4, INT2NUM(dty2)));
734
+ } else {
735
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
942
736
  }
943
- else {
944
- ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
945
- }
946
- ca_call_cfunc_6(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
737
+
738
+ ca_call_cfunc_6(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
739
+
947
740
  if ( rb_ca_is_scalar(ry1) ) {
948
741
  ry1 = rb_ca_fetch_addr(ry1, 0);
949
742
  }
@@ -954,37 +747,30 @@ ca_call_cfunc_2_4 (int8_t dty1,
954
747
  }
955
748
 
956
749
  VALUE
957
- ca_call_cfunc_3_1 (int8_t dty1,
958
- int8_t dty2,
959
- int8_t dty3,
960
- int8_t dtx1,
961
- void (*mathfunc)(void*,void*,void*,void*),
962
- volatile VALUE rx1)
963
- {
964
- volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
965
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
750
+ ca_call_cfunc_3_1 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, void (*mathfunc)(void*, void*, void*, void*), volatile VALUE rx1)
751
+ {
752
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
753
+
754
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
755
+
966
756
  if ( dty1 != dtx1 ) {
967
- ry1 = rb_ca_template_n(1,
968
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
969
- }
970
- else {
971
- ry1 = rb_ca_template_n(1, rx1);
757
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
758
+ } else {
759
+ ry1 = rb_ca_template_n(1, rx1);
972
760
  }
973
761
  if ( dty2 != dtx1 ) {
974
- ry2 = rb_ca_template_n(1,
975
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
976
- }
977
- else {
978
- ry2 = rb_ca_template_n(1, rx1);
762
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
763
+ } else {
764
+ ry2 = rb_ca_template_n(1, rx1);
979
765
  }
980
- if ( dty3 != dtx1 ) {
981
- ry3 = rb_ca_template_n(1,
982
- rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
766
+ if ( dty3 != dtx1 ) {
767
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
768
+ } else {
769
+ ry3 = rb_ca_template_n(1, rx1);
983
770
  }
984
- else {
985
- ry3 = rb_ca_template_n(1, rx1);
986
- }
987
- ca_call_cfunc_4(mathfunc, "1110", ry1, ry2, ry3, rx1);
771
+
772
+ ca_call_cfunc_4(mathfunc, "1110", ry1, ry2, ry3, rx1);
773
+
988
774
  if ( rb_ca_is_scalar(ry1) ) {
989
775
  ry1 = rb_ca_fetch_addr(ry1, 0);
990
776
  }
@@ -998,43 +784,31 @@ ca_call_cfunc_3_1 (int8_t dty1,
998
784
  }
999
785
 
1000
786
  VALUE
1001
- ca_call_cfunc_3_2 (int8_t dty1,
1002
- int8_t dty2,
1003
- int8_t dty3,
1004
- int8_t dtx1,
1005
- int8_t dtx2,
1006
- void (*mathfunc)(void*,void*,void*,void*,void*),
1007
- volatile VALUE rx1,
1008
- volatile VALUE rx2)
1009
- {
1010
- volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1011
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1012
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
787
+ ca_call_cfunc_3_2 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2)
788
+ {
789
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
790
+
791
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
792
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
793
+
1013
794
  if ( dty1 != dtx1 || dty1 != dtx2 ) {
1014
- ry1 = rb_ca_template_n(2,
1015
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)),
1016
- rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
1017
- }
1018
- else {
1019
- ry1 = rb_ca_template_n(2, rx1, rx2);
795
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
796
+ } else {
797
+ ry1 = rb_ca_template_n(2, rx1, rx2);
1020
798
  }
1021
799
  if ( dty2 != dtx1 || dty2 != dtx2 ) {
1022
- ry2 = rb_ca_template_n(2,
1023
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)),
1024
- rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
1025
- }
1026
- else {
1027
- ry2 = rb_ca_template_n(2, rx1, rx2);
800
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
801
+ } else {
802
+ ry2 = rb_ca_template_n(2, rx1, rx2);
1028
803
  }
1029
804
  if ( dty3 != dtx1 || dty3 != dtx2 ) {
1030
- ry3 = rb_ca_template_n(2,
1031
- rb_ca_wrap_readonly(rx1, INT2NUM(dty3)),
1032
- rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
805
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
806
+ } else {
807
+ ry3 = rb_ca_template_n(2, rx1, rx2);
1033
808
  }
1034
- else {
1035
- ry3 = rb_ca_template_n(2, rx1, rx2);
1036
- }
1037
- ca_call_cfunc_5(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2);
809
+
810
+ ca_call_cfunc_5(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2);
811
+
1038
812
  if ( rb_ca_is_scalar(ry1) ) {
1039
813
  ry1 = rb_ca_fetch_addr(ry1, 0);
1040
814
  }
@@ -1048,50 +822,32 @@ ca_call_cfunc_3_2 (int8_t dty1,
1048
822
  }
1049
823
 
1050
824
  VALUE
1051
- ca_call_cfunc_3_3 (int8_t dty1,
1052
- int8_t dty2,
1053
- int8_t dty3,
1054
- int8_t dtx1,
1055
- int8_t dtx2,
1056
- int8_t dtx3,
1057
- void (*mathfunc)(void*,void*,void*,void*,void*,void*),
1058
- volatile VALUE rx1,
1059
- volatile VALUE rx2,
1060
- volatile VALUE rx3)
1061
- {
1062
- volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1063
- rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1064
- rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1065
- rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
825
+ ca_call_cfunc_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*, void*), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
826
+ {
827
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
828
+
829
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
830
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
831
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
832
+
1066
833
  if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
1067
- ry1 = rb_ca_template_n(3,
1068
- rb_ca_wrap_readonly(rx1, INT2NUM(dty1)),
1069
- rb_ca_wrap_readonly(rx2, INT2NUM(dty1)),
1070
- rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
1071
- }
1072
- else {
1073
- ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
834
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
835
+ } else {
836
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
1074
837
  }
1075
838
  if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
1076
- ry2 = rb_ca_template_n(3,
1077
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)),
1078
- rb_ca_wrap_readonly(rx2, INT2NUM(dty2)),
1079
- rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
1080
- }
1081
- else {
1082
- ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
839
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
840
+ } else {
841
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
1083
842
  }
1084
843
  if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
1085
- ry3 = rb_ca_template_n(3,
1086
- rb_ca_wrap_readonly(rx1, INT2NUM(dty3)),
1087
- rb_ca_wrap_readonly(rx2, INT2NUM(dty3)),
1088
- rb_ca_wrap_readonly(rx3, INT2NUM(dty3)));
1089
- }
1090
- else {
1091
- ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
844
+ ry3 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)), rb_ca_wrap_readonly(rx3, INT2NUM(dty3)));
845
+ } else {
846
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
1092
847
  }
1093
848
 
1094
- ca_call_cfunc_6(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
849
+ ca_call_cfunc_6(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
850
+
1095
851
  if ( rb_ca_is_scalar(ry1) ) {
1096
852
  ry1 = rb_ca_fetch_addr(ry1, 0);
1097
853
  }
@@ -1103,3 +859,2270 @@ ca_call_cfunc_3_3 (int8_t dty1,
1103
859
  }
1104
860
  return rb_ary_new3(3, ry1, ry2, ry3);
1105
861
  }
862
+
863
+ /* -------------------------------------------------------------------- */
864
+ /* Reentrant variants (`_r` suffix, POSIX convention): same as the */
865
+ /* corresponding non-`_r` variant but the callback takes a trailing */
866
+ /* `void *userdata` argument and the outer function takes a trailing */
867
+ /* `void *userdata` parameter forwarded to every per-cell invocation. */
868
+ /* -------------------------------------------------------------------- */
869
+
870
+ VALUE
871
+ ca_call_cfunc_1_r (void (*func)(void *p0, void *userdata), const char *fsync,
872
+ VALUE rcx0,
873
+ void *userdata)
874
+ {
875
+ CArray *cx[1];
876
+ char *base[1];
877
+ ca_size_t stride[1];
878
+ char *owned_buf[1];
879
+ int attached[1];
880
+ ca_sweep_state_t state;
881
+ int k_op;
882
+
883
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
884
+
885
+ /* sweep engine: same lifecycle as ca_call_cfunc_1; the difference is
886
+ the per-cell `func(...)` call has `userdata` as its last argument. */
887
+ state.n_ops = 1;
888
+ state.fsync = fsync;
889
+ state.cx = cx;
890
+ state.base = base;
891
+ state.stride = stride;
892
+ state.owned_buf = owned_buf;
893
+ state.attached = attached;
894
+ state.no_mask = 0;
895
+ state.src_label = "ca_call_cfunc_1_r";
896
+
897
+ ca_sweep_acquire(&state);
898
+
899
+ {
900
+ char *p[1];
901
+ ca_size_t k;
902
+ if ( state.m0 ) {
903
+ for ( k = 0; k < state.n_kernel; k++ ) {
904
+ if ( ! state.m0[k] ) {
905
+ for ( k_op = 0; k_op < 1; k_op++ ) {
906
+ p[k_op] = base[k_op] + k * stride[k_op];
907
+ }
908
+ func(p[0], userdata);
909
+ }
910
+ }
911
+ } else {
912
+ for ( k = 0; k < state.n_kernel; k++ ) {
913
+ for ( k_op = 0; k_op < 1; k_op++ ) {
914
+ p[k_op] = base[k_op] + k * stride[k_op];
915
+ }
916
+ func(p[0], userdata);
917
+ }
918
+ }
919
+ }
920
+
921
+ ca_sweep_release(&state);
922
+
923
+ return rcx0;
924
+ }
925
+
926
+ VALUE
927
+ ca_call_cfunc_2_r (void (*func)(void *p0, void *p1, void *userdata), const char *fsync,
928
+ VALUE rcx0, VALUE rcx1,
929
+ void *userdata)
930
+ {
931
+ CArray *cx[2];
932
+ char *base[2];
933
+ ca_size_t stride[2];
934
+ char *owned_buf[2];
935
+ int attached[2];
936
+ ca_sweep_state_t state;
937
+ int k_op;
938
+
939
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
940
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
941
+
942
+ /* sweep engine: same lifecycle as ca_call_cfunc_2; the difference is
943
+ the per-cell `func(...)` call has `userdata` as its last argument. */
944
+ state.n_ops = 2;
945
+ state.fsync = fsync;
946
+ state.cx = cx;
947
+ state.base = base;
948
+ state.stride = stride;
949
+ state.owned_buf = owned_buf;
950
+ state.attached = attached;
951
+ state.no_mask = 0;
952
+ state.src_label = "ca_call_cfunc_2_r";
953
+
954
+ ca_sweep_acquire(&state);
955
+
956
+ {
957
+ char *p[2];
958
+ ca_size_t k;
959
+ if ( state.m0 ) {
960
+ for ( k = 0; k < state.n_kernel; k++ ) {
961
+ if ( ! state.m0[k] ) {
962
+ for ( k_op = 0; k_op < 2; k_op++ ) {
963
+ p[k_op] = base[k_op] + k * stride[k_op];
964
+ }
965
+ func(p[0], p[1], userdata);
966
+ }
967
+ }
968
+ } else {
969
+ for ( k = 0; k < state.n_kernel; k++ ) {
970
+ for ( k_op = 0; k_op < 2; k_op++ ) {
971
+ p[k_op] = base[k_op] + k * stride[k_op];
972
+ }
973
+ func(p[0], p[1], userdata);
974
+ }
975
+ }
976
+ }
977
+
978
+ ca_sweep_release(&state);
979
+
980
+ return rcx0;
981
+ }
982
+
983
+ VALUE
984
+ ca_call_cfunc_3_r (void (*func)(void *p0, void *p1, void *p2, void *userdata), const char *fsync,
985
+ VALUE rcx0, VALUE rcx1, VALUE rcx2,
986
+ void *userdata)
987
+ {
988
+ CArray *cx[3];
989
+ char *base[3];
990
+ ca_size_t stride[3];
991
+ char *owned_buf[3];
992
+ int attached[3];
993
+ ca_sweep_state_t state;
994
+ int k_op;
995
+
996
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
997
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
998
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
999
+
1000
+ /* sweep engine: same lifecycle as ca_call_cfunc_3; the difference is
1001
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1002
+ state.n_ops = 3;
1003
+ state.fsync = fsync;
1004
+ state.cx = cx;
1005
+ state.base = base;
1006
+ state.stride = stride;
1007
+ state.owned_buf = owned_buf;
1008
+ state.attached = attached;
1009
+ state.no_mask = 0;
1010
+ state.src_label = "ca_call_cfunc_3_r";
1011
+
1012
+ ca_sweep_acquire(&state);
1013
+
1014
+ {
1015
+ char *p[3];
1016
+ ca_size_t k;
1017
+ if ( state.m0 ) {
1018
+ for ( k = 0; k < state.n_kernel; k++ ) {
1019
+ if ( ! state.m0[k] ) {
1020
+ for ( k_op = 0; k_op < 3; k_op++ ) {
1021
+ p[k_op] = base[k_op] + k * stride[k_op];
1022
+ }
1023
+ func(p[0], p[1], p[2], userdata);
1024
+ }
1025
+ }
1026
+ } else {
1027
+ for ( k = 0; k < state.n_kernel; k++ ) {
1028
+ for ( k_op = 0; k_op < 3; k_op++ ) {
1029
+ p[k_op] = base[k_op] + k * stride[k_op];
1030
+ }
1031
+ func(p[0], p[1], p[2], userdata);
1032
+ }
1033
+ }
1034
+ }
1035
+
1036
+ ca_sweep_release(&state);
1037
+
1038
+ return rcx0;
1039
+ }
1040
+
1041
+ VALUE
1042
+ ca_call_cfunc_4_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *userdata), const char *fsync,
1043
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
1044
+ void *userdata)
1045
+ {
1046
+ CArray *cx[4];
1047
+ char *base[4];
1048
+ ca_size_t stride[4];
1049
+ char *owned_buf[4];
1050
+ int attached[4];
1051
+ ca_sweep_state_t state;
1052
+ int k_op;
1053
+
1054
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1055
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1056
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1057
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1058
+
1059
+ /* sweep engine: same lifecycle as ca_call_cfunc_4; the difference is
1060
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1061
+ state.n_ops = 4;
1062
+ state.fsync = fsync;
1063
+ state.cx = cx;
1064
+ state.base = base;
1065
+ state.stride = stride;
1066
+ state.owned_buf = owned_buf;
1067
+ state.attached = attached;
1068
+ state.no_mask = 0;
1069
+ state.src_label = "ca_call_cfunc_4_r";
1070
+
1071
+ ca_sweep_acquire(&state);
1072
+
1073
+ {
1074
+ char *p[4];
1075
+ ca_size_t k;
1076
+ if ( state.m0 ) {
1077
+ for ( k = 0; k < state.n_kernel; k++ ) {
1078
+ if ( ! state.m0[k] ) {
1079
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1080
+ p[k_op] = base[k_op] + k * stride[k_op];
1081
+ }
1082
+ func(p[0], p[1], p[2], p[3], userdata);
1083
+ }
1084
+ }
1085
+ } else {
1086
+ for ( k = 0; k < state.n_kernel; k++ ) {
1087
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1088
+ p[k_op] = base[k_op] + k * stride[k_op];
1089
+ }
1090
+ func(p[0], p[1], p[2], p[3], userdata);
1091
+ }
1092
+ }
1093
+ }
1094
+
1095
+ ca_sweep_release(&state);
1096
+
1097
+ return rcx0;
1098
+ }
1099
+
1100
+ VALUE
1101
+ ca_call_cfunc_5_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *userdata), const char *fsync,
1102
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
1103
+ void *userdata)
1104
+ {
1105
+ CArray *cx[5];
1106
+ char *base[5];
1107
+ ca_size_t stride[5];
1108
+ char *owned_buf[5];
1109
+ int attached[5];
1110
+ ca_sweep_state_t state;
1111
+ int k_op;
1112
+
1113
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1114
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1115
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1116
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1117
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1118
+
1119
+ /* sweep engine: same lifecycle as ca_call_cfunc_5; the difference is
1120
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1121
+ state.n_ops = 5;
1122
+ state.fsync = fsync;
1123
+ state.cx = cx;
1124
+ state.base = base;
1125
+ state.stride = stride;
1126
+ state.owned_buf = owned_buf;
1127
+ state.attached = attached;
1128
+ state.no_mask = 0;
1129
+ state.src_label = "ca_call_cfunc_5_r";
1130
+
1131
+ ca_sweep_acquire(&state);
1132
+
1133
+ {
1134
+ char *p[5];
1135
+ ca_size_t k;
1136
+ if ( state.m0 ) {
1137
+ for ( k = 0; k < state.n_kernel; k++ ) {
1138
+ if ( ! state.m0[k] ) {
1139
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1140
+ p[k_op] = base[k_op] + k * stride[k_op];
1141
+ }
1142
+ func(p[0], p[1], p[2], p[3], p[4], userdata);
1143
+ }
1144
+ }
1145
+ } else {
1146
+ for ( k = 0; k < state.n_kernel; k++ ) {
1147
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1148
+ p[k_op] = base[k_op] + k * stride[k_op];
1149
+ }
1150
+ func(p[0], p[1], p[2], p[3], p[4], userdata);
1151
+ }
1152
+ }
1153
+ }
1154
+
1155
+ ca_sweep_release(&state);
1156
+
1157
+ return rcx0;
1158
+ }
1159
+
1160
+ VALUE
1161
+ ca_call_cfunc_6_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *userdata), const char *fsync,
1162
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
1163
+ void *userdata)
1164
+ {
1165
+ CArray *cx[6];
1166
+ char *base[6];
1167
+ ca_size_t stride[6];
1168
+ char *owned_buf[6];
1169
+ int attached[6];
1170
+ ca_sweep_state_t state;
1171
+ int k_op;
1172
+
1173
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1174
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1175
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1176
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1177
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1178
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1179
+
1180
+ /* sweep engine: same lifecycle as ca_call_cfunc_6; the difference is
1181
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1182
+ state.n_ops = 6;
1183
+ state.fsync = fsync;
1184
+ state.cx = cx;
1185
+ state.base = base;
1186
+ state.stride = stride;
1187
+ state.owned_buf = owned_buf;
1188
+ state.attached = attached;
1189
+ state.no_mask = 0;
1190
+ state.src_label = "ca_call_cfunc_6_r";
1191
+
1192
+ ca_sweep_acquire(&state);
1193
+
1194
+ {
1195
+ char *p[6];
1196
+ ca_size_t k;
1197
+ if ( state.m0 ) {
1198
+ for ( k = 0; k < state.n_kernel; k++ ) {
1199
+ if ( ! state.m0[k] ) {
1200
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1201
+ p[k_op] = base[k_op] + k * stride[k_op];
1202
+ }
1203
+ func(p[0], p[1], p[2], p[3], p[4], p[5], userdata);
1204
+ }
1205
+ }
1206
+ } else {
1207
+ for ( k = 0; k < state.n_kernel; k++ ) {
1208
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1209
+ p[k_op] = base[k_op] + k * stride[k_op];
1210
+ }
1211
+ func(p[0], p[1], p[2], p[3], p[4], p[5], userdata);
1212
+ }
1213
+ }
1214
+ }
1215
+
1216
+ ca_sweep_release(&state);
1217
+
1218
+ return rcx0;
1219
+ }
1220
+
1221
+ VALUE
1222
+ ca_call_cfunc_7_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *userdata), const char *fsync,
1223
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
1224
+ void *userdata)
1225
+ {
1226
+ CArray *cx[7];
1227
+ char *base[7];
1228
+ ca_size_t stride[7];
1229
+ char *owned_buf[7];
1230
+ int attached[7];
1231
+ ca_sweep_state_t state;
1232
+ int k_op;
1233
+
1234
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1235
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1236
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1237
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1238
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1239
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1240
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
1241
+
1242
+ /* sweep engine: same lifecycle as ca_call_cfunc_7; the difference is
1243
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1244
+ state.n_ops = 7;
1245
+ state.fsync = fsync;
1246
+ state.cx = cx;
1247
+ state.base = base;
1248
+ state.stride = stride;
1249
+ state.owned_buf = owned_buf;
1250
+ state.attached = attached;
1251
+ state.no_mask = 0;
1252
+ state.src_label = "ca_call_cfunc_7_r";
1253
+
1254
+ ca_sweep_acquire(&state);
1255
+
1256
+ {
1257
+ char *p[7];
1258
+ ca_size_t k;
1259
+ if ( state.m0 ) {
1260
+ for ( k = 0; k < state.n_kernel; k++ ) {
1261
+ if ( ! state.m0[k] ) {
1262
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1263
+ p[k_op] = base[k_op] + k * stride[k_op];
1264
+ }
1265
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], userdata);
1266
+ }
1267
+ }
1268
+ } else {
1269
+ for ( k = 0; k < state.n_kernel; k++ ) {
1270
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1271
+ p[k_op] = base[k_op] + k * stride[k_op];
1272
+ }
1273
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], userdata);
1274
+ }
1275
+ }
1276
+ }
1277
+
1278
+ ca_sweep_release(&state);
1279
+
1280
+ return rcx0;
1281
+ }
1282
+
1283
+ VALUE
1284
+ ca_call_cfunc_1_1_r (int8_t dty, int8_t dtx1, void (*mathfunc)(void*, void*, void *userdata), volatile VALUE rx1, void *userdata)
1285
+ {
1286
+ volatile VALUE ry = Qnil;
1287
+
1288
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1289
+
1290
+ if ( dty != dtx1 ) {
1291
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
1292
+ } else {
1293
+ ry = rb_ca_template_n(1, rx1);
1294
+ }
1295
+
1296
+ ca_call_cfunc_2_r(mathfunc, "10", ry, rx1, userdata);
1297
+
1298
+ if ( rb_ca_is_scalar(ry) ) {
1299
+ ry = rb_ca_fetch_addr(ry, 0);
1300
+ }
1301
+ return ry;
1302
+ }
1303
+
1304
+ VALUE
1305
+ ca_call_cfunc_1_2_r (int8_t dty, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, void *userdata)
1306
+ {
1307
+ volatile VALUE ry = Qnil;
1308
+
1309
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1310
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1311
+
1312
+ if ( dty != dtx1 || dty != dtx2 ) {
1313
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
1314
+ } else {
1315
+ ry = rb_ca_template_n(2, rx1, rx2);
1316
+ }
1317
+
1318
+ ca_call_cfunc_3_r(mathfunc, "100", ry, rx1, rx2, userdata);
1319
+
1320
+ if ( rb_ca_is_scalar(ry) ) {
1321
+ ry = rb_ca_fetch_addr(ry, 0);
1322
+ }
1323
+ return ry;
1324
+ }
1325
+
1326
+ VALUE
1327
+ ca_call_cfunc_1_3_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
1328
+ {
1329
+ volatile VALUE ry = Qnil;
1330
+
1331
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1332
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1333
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1334
+
1335
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
1336
+ ry = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)));
1337
+ } else {
1338
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
1339
+ }
1340
+
1341
+ ca_call_cfunc_4_r(mathfunc, "1000", ry, rx1, rx2, rx3, userdata);
1342
+
1343
+ if ( rb_ca_is_scalar(ry) ) {
1344
+ ry = rb_ca_fetch_addr(ry, 0);
1345
+ }
1346
+ return ry;
1347
+ }
1348
+
1349
+ VALUE
1350
+ ca_call_cfunc_1_4_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, void (*mathfunc)(void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
1351
+ {
1352
+ volatile VALUE ry = Qnil;
1353
+
1354
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1355
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1356
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1357
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1358
+
1359
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
1360
+ ry = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)));
1361
+ } else {
1362
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
1363
+ }
1364
+
1365
+ ca_call_cfunc_5_r(mathfunc, "10000", ry, rx1, rx2, rx3, rx4, userdata);
1366
+
1367
+ if ( rb_ca_is_scalar(ry) ) {
1368
+ ry = rb_ca_fetch_addr(ry, 0);
1369
+ }
1370
+ return ry;
1371
+ }
1372
+
1373
+ VALUE
1374
+ ca_call_cfunc_1_5_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, void *userdata)
1375
+ {
1376
+ volatile VALUE ry = Qnil;
1377
+
1378
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1379
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1380
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1381
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1382
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
1383
+
1384
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
1385
+ ry = rb_ca_template_n(5, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)));
1386
+ } else {
1387
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
1388
+ }
1389
+
1390
+ ca_call_cfunc_6_r(mathfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5, userdata);
1391
+
1392
+ if ( rb_ca_is_scalar(ry) ) {
1393
+ ry = rb_ca_fetch_addr(ry, 0);
1394
+ }
1395
+ return ry;
1396
+ }
1397
+
1398
+ VALUE
1399
+ ca_call_cfunc_1_6_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6, void *userdata)
1400
+ {
1401
+ volatile VALUE ry = Qnil;
1402
+
1403
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1404
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1405
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1406
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1407
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
1408
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
1409
+
1410
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
1411
+ ry = rb_ca_template_n(6, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)), rb_ca_wrap_readonly(rx6, INT2NUM(dty)));
1412
+ } else {
1413
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
1414
+ }
1415
+
1416
+ ca_call_cfunc_7_r(mathfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6, userdata);
1417
+
1418
+ if ( rb_ca_is_scalar(ry) ) {
1419
+ ry = rb_ca_fetch_addr(ry, 0);
1420
+ }
1421
+ return ry;
1422
+ }
1423
+
1424
+ VALUE
1425
+ ca_call_cfunc_2_1_r (int8_t dty1, int8_t dty2, int8_t dtx1, void (*mathfunc)(void*, void*, void*, void *userdata), volatile VALUE rx1, void *userdata)
1426
+ {
1427
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1428
+
1429
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1430
+
1431
+ if ( dty1 != dtx1 ) {
1432
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
1433
+ } else {
1434
+ ry1 = rb_ca_template_n(1, rx1);
1435
+ }
1436
+ if ( dty2 != dtx1 ) {
1437
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
1438
+ } else {
1439
+ ry2 = rb_ca_template_n(1, rx1);
1440
+ }
1441
+
1442
+ ca_call_cfunc_3_r(mathfunc, "110", ry1, ry2, rx1, userdata);
1443
+
1444
+ if ( rb_ca_is_scalar(ry1) ) {
1445
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1446
+ }
1447
+ if ( rb_ca_is_scalar(ry2) ) {
1448
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1449
+ }
1450
+ return rb_ary_new3(2, ry1, ry2);
1451
+ }
1452
+
1453
+ VALUE
1454
+ ca_call_cfunc_2_2_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, void *userdata)
1455
+ {
1456
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1457
+
1458
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1459
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1460
+
1461
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
1462
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
1463
+ } else {
1464
+ ry1 = rb_ca_template_n(2, rx1, rx2);
1465
+ }
1466
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
1467
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
1468
+ } else {
1469
+ ry2 = rb_ca_template_n(2, rx1, rx2);
1470
+ }
1471
+
1472
+ ca_call_cfunc_4_r(mathfunc, "1100", ry1, ry2, rx1, rx2, userdata);
1473
+
1474
+ if ( rb_ca_is_scalar(ry1) ) {
1475
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1476
+ }
1477
+ if ( rb_ca_is_scalar(ry2) ) {
1478
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1479
+ }
1480
+ return rb_ary_new3(2, ry1, ry2);
1481
+ }
1482
+
1483
+ VALUE
1484
+ ca_call_cfunc_2_3_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
1485
+ {
1486
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1487
+
1488
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1489
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1490
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1491
+
1492
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
1493
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
1494
+ } else {
1495
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
1496
+ }
1497
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
1498
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
1499
+ } else {
1500
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
1501
+ }
1502
+
1503
+ ca_call_cfunc_5_r(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3, userdata);
1504
+
1505
+ if ( rb_ca_is_scalar(ry1) ) {
1506
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1507
+ }
1508
+ if ( rb_ca_is_scalar(ry2) ) {
1509
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1510
+ }
1511
+ return rb_ary_new3(2, ry1, ry2);
1512
+ }
1513
+
1514
+ VALUE
1515
+ ca_call_cfunc_2_4_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
1516
+ {
1517
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1518
+
1519
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1520
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1521
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1522
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1523
+
1524
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
1525
+ ry1 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)), rb_ca_wrap_readonly(rx4, INT2NUM(dty1)));
1526
+ } else {
1527
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
1528
+ }
1529
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
1530
+ ry2 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)), rb_ca_wrap_readonly(rx4, INT2NUM(dty2)));
1531
+ } else {
1532
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
1533
+ }
1534
+
1535
+ ca_call_cfunc_6_r(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4, userdata);
1536
+
1537
+ if ( rb_ca_is_scalar(ry1) ) {
1538
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1539
+ }
1540
+ if ( rb_ca_is_scalar(ry2) ) {
1541
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1542
+ }
1543
+ return rb_ary_new3(2, ry1, ry2);
1544
+ }
1545
+
1546
+ VALUE
1547
+ ca_call_cfunc_3_1_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, void (*mathfunc)(void*, void*, void*, void*, void *userdata), volatile VALUE rx1, void *userdata)
1548
+ {
1549
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1550
+
1551
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1552
+
1553
+ if ( dty1 != dtx1 ) {
1554
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
1555
+ } else {
1556
+ ry1 = rb_ca_template_n(1, rx1);
1557
+ }
1558
+ if ( dty2 != dtx1 ) {
1559
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
1560
+ } else {
1561
+ ry2 = rb_ca_template_n(1, rx1);
1562
+ }
1563
+ if ( dty3 != dtx1 ) {
1564
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
1565
+ } else {
1566
+ ry3 = rb_ca_template_n(1, rx1);
1567
+ }
1568
+
1569
+ ca_call_cfunc_4_r(mathfunc, "1110", ry1, ry2, ry3, rx1, userdata);
1570
+
1571
+ if ( rb_ca_is_scalar(ry1) ) {
1572
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1573
+ }
1574
+ if ( rb_ca_is_scalar(ry2) ) {
1575
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1576
+ }
1577
+ if ( rb_ca_is_scalar(ry3) ) {
1578
+ ry3 = rb_ca_fetch_addr(ry3, 0);
1579
+ }
1580
+ return rb_ary_new3(3, ry1, ry2, ry3);
1581
+ }
1582
+
1583
+ VALUE
1584
+ ca_call_cfunc_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, void (*mathfunc)(void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, void *userdata)
1585
+ {
1586
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1587
+
1588
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1589
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1590
+
1591
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
1592
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
1593
+ } else {
1594
+ ry1 = rb_ca_template_n(2, rx1, rx2);
1595
+ }
1596
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
1597
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
1598
+ } else {
1599
+ ry2 = rb_ca_template_n(2, rx1, rx2);
1600
+ }
1601
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
1602
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
1603
+ } else {
1604
+ ry3 = rb_ca_template_n(2, rx1, rx2);
1605
+ }
1606
+
1607
+ ca_call_cfunc_5_r(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2, userdata);
1608
+
1609
+ if ( rb_ca_is_scalar(ry1) ) {
1610
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1611
+ }
1612
+ if ( rb_ca_is_scalar(ry2) ) {
1613
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1614
+ }
1615
+ if ( rb_ca_is_scalar(ry3) ) {
1616
+ ry3 = rb_ca_fetch_addr(ry3, 0);
1617
+ }
1618
+ return rb_ary_new3(3, ry1, ry2, ry3);
1619
+ }
1620
+
1621
+ VALUE
1622
+ ca_call_cfunc_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
1623
+ {
1624
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1625
+
1626
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1627
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1628
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1629
+
1630
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
1631
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
1632
+ } else {
1633
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
1634
+ }
1635
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
1636
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
1637
+ } else {
1638
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
1639
+ }
1640
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
1641
+ ry3 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)), rb_ca_wrap_readonly(rx3, INT2NUM(dty3)));
1642
+ } else {
1643
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
1644
+ }
1645
+
1646
+ ca_call_cfunc_6_r(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3, userdata);
1647
+
1648
+ if ( rb_ca_is_scalar(ry1) ) {
1649
+ ry1 = rb_ca_fetch_addr(ry1, 0);
1650
+ }
1651
+ if ( rb_ca_is_scalar(ry2) ) {
1652
+ ry2 = rb_ca_fetch_addr(ry2, 0);
1653
+ }
1654
+ if ( rb_ca_is_scalar(ry3) ) {
1655
+ ry3 = rb_ca_fetch_addr(ry3, 0);
1656
+ }
1657
+ return rb_ary_new3(3, ry1, ry2, ry3);
1658
+ }
1659
+
1660
+ /* -------------------------------------------------------------------- */
1661
+ /* Slab variants: the chunked counterpart of ca_call_cfunc_N. The */
1662
+ /* callback is handed a whole chunk (base / stride / count / mask */
1663
+ /* slice) rather than one cell, and non-alias INPUTs are gathered */
1664
+ /* into a ~32KB arena scratch per chunk instead of materialised */
1665
+ /* whole, so input memory peak stops scaling with the operand. */
1666
+ /* -------------------------------------------------------------------- */
1667
+
1668
+ VALUE
1669
+ ca_call_cslab_1 (ca_cslab_t func, const char *fsync,
1670
+ VALUE rcx0)
1671
+ {
1672
+ CArray *cx[1];
1673
+ char *base[1];
1674
+ char *base_orig[1];
1675
+ ca_size_t stride[1];
1676
+ char *owned_buf[1];
1677
+ int attached[1];
1678
+ ca_sweep_state_t state;
1679
+
1680
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1681
+
1682
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1683
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1684
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1685
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1686
+ base_orig is the field the whole-buffer path leaves zero; the
1687
+ chunked path walks it, so it has to be given here. */
1688
+ state.n_ops = 1;
1689
+ state.fsync = fsync;
1690
+ state.cx = cx;
1691
+ state.base = base;
1692
+ state.base_orig = base_orig;
1693
+ state.stride = stride;
1694
+ state.owned_buf = owned_buf;
1695
+ state.attached = attached;
1696
+ state.no_mask = 0;
1697
+ state.src_label = "ca_call_cslab_1";
1698
+
1699
+ ca_sweep_acquire_chunked(&state);
1700
+
1701
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1702
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1703
+ at the arena scratch the chunk was just gathered into, which is
1704
+ packed, so stride[] is the element size and the author's inner loop
1705
+ sees contiguous data. */
1706
+ while ( ca_sweep_next_chunk(&state) ) {
1707
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1708
+ }
1709
+
1710
+ ca_sweep_release_chunked(&state);
1711
+
1712
+ return rcx0;
1713
+ }
1714
+
1715
+ VALUE
1716
+ ca_call_cslab_2 (ca_cslab_t func, const char *fsync,
1717
+ VALUE rcx0, VALUE rcx1)
1718
+ {
1719
+ CArray *cx[2];
1720
+ char *base[2];
1721
+ char *base_orig[2];
1722
+ ca_size_t stride[2];
1723
+ char *owned_buf[2];
1724
+ int attached[2];
1725
+ ca_sweep_state_t state;
1726
+
1727
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1728
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1729
+
1730
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1731
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1732
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1733
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1734
+ base_orig is the field the whole-buffer path leaves zero; the
1735
+ chunked path walks it, so it has to be given here. */
1736
+ state.n_ops = 2;
1737
+ state.fsync = fsync;
1738
+ state.cx = cx;
1739
+ state.base = base;
1740
+ state.base_orig = base_orig;
1741
+ state.stride = stride;
1742
+ state.owned_buf = owned_buf;
1743
+ state.attached = attached;
1744
+ state.no_mask = 0;
1745
+ state.src_label = "ca_call_cslab_2";
1746
+
1747
+ ca_sweep_acquire_chunked(&state);
1748
+
1749
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1750
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1751
+ at the arena scratch the chunk was just gathered into, which is
1752
+ packed, so stride[] is the element size and the author's inner loop
1753
+ sees contiguous data. */
1754
+ while ( ca_sweep_next_chunk(&state) ) {
1755
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1756
+ }
1757
+
1758
+ ca_sweep_release_chunked(&state);
1759
+
1760
+ return rcx0;
1761
+ }
1762
+
1763
+ VALUE
1764
+ ca_call_cslab_3 (ca_cslab_t func, const char *fsync,
1765
+ VALUE rcx0, VALUE rcx1, VALUE rcx2)
1766
+ {
1767
+ CArray *cx[3];
1768
+ char *base[3];
1769
+ char *base_orig[3];
1770
+ ca_size_t stride[3];
1771
+ char *owned_buf[3];
1772
+ int attached[3];
1773
+ ca_sweep_state_t state;
1774
+
1775
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1776
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1777
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1778
+
1779
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1780
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1781
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1782
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1783
+ base_orig is the field the whole-buffer path leaves zero; the
1784
+ chunked path walks it, so it has to be given here. */
1785
+ state.n_ops = 3;
1786
+ state.fsync = fsync;
1787
+ state.cx = cx;
1788
+ state.base = base;
1789
+ state.base_orig = base_orig;
1790
+ state.stride = stride;
1791
+ state.owned_buf = owned_buf;
1792
+ state.attached = attached;
1793
+ state.no_mask = 0;
1794
+ state.src_label = "ca_call_cslab_3";
1795
+
1796
+ ca_sweep_acquire_chunked(&state);
1797
+
1798
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1799
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1800
+ at the arena scratch the chunk was just gathered into, which is
1801
+ packed, so stride[] is the element size and the author's inner loop
1802
+ sees contiguous data. */
1803
+ while ( ca_sweep_next_chunk(&state) ) {
1804
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1805
+ }
1806
+
1807
+ ca_sweep_release_chunked(&state);
1808
+
1809
+ return rcx0;
1810
+ }
1811
+
1812
+ VALUE
1813
+ ca_call_cslab_4 (ca_cslab_t func, const char *fsync,
1814
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3)
1815
+ {
1816
+ CArray *cx[4];
1817
+ char *base[4];
1818
+ char *base_orig[4];
1819
+ ca_size_t stride[4];
1820
+ char *owned_buf[4];
1821
+ int attached[4];
1822
+ ca_sweep_state_t state;
1823
+
1824
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1825
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1826
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1827
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1828
+
1829
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1830
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1831
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1832
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1833
+ base_orig is the field the whole-buffer path leaves zero; the
1834
+ chunked path walks it, so it has to be given here. */
1835
+ state.n_ops = 4;
1836
+ state.fsync = fsync;
1837
+ state.cx = cx;
1838
+ state.base = base;
1839
+ state.base_orig = base_orig;
1840
+ state.stride = stride;
1841
+ state.owned_buf = owned_buf;
1842
+ state.attached = attached;
1843
+ state.no_mask = 0;
1844
+ state.src_label = "ca_call_cslab_4";
1845
+
1846
+ ca_sweep_acquire_chunked(&state);
1847
+
1848
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1849
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1850
+ at the arena scratch the chunk was just gathered into, which is
1851
+ packed, so stride[] is the element size and the author's inner loop
1852
+ sees contiguous data. */
1853
+ while ( ca_sweep_next_chunk(&state) ) {
1854
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1855
+ }
1856
+
1857
+ ca_sweep_release_chunked(&state);
1858
+
1859
+ return rcx0;
1860
+ }
1861
+
1862
+ VALUE
1863
+ ca_call_cslab_5 (ca_cslab_t func, const char *fsync,
1864
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4)
1865
+ {
1866
+ CArray *cx[5];
1867
+ char *base[5];
1868
+ char *base_orig[5];
1869
+ ca_size_t stride[5];
1870
+ char *owned_buf[5];
1871
+ int attached[5];
1872
+ ca_sweep_state_t state;
1873
+
1874
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1875
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1876
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1877
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1878
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1879
+
1880
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1881
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1882
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1883
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1884
+ base_orig is the field the whole-buffer path leaves zero; the
1885
+ chunked path walks it, so it has to be given here. */
1886
+ state.n_ops = 5;
1887
+ state.fsync = fsync;
1888
+ state.cx = cx;
1889
+ state.base = base;
1890
+ state.base_orig = base_orig;
1891
+ state.stride = stride;
1892
+ state.owned_buf = owned_buf;
1893
+ state.attached = attached;
1894
+ state.no_mask = 0;
1895
+ state.src_label = "ca_call_cslab_5";
1896
+
1897
+ ca_sweep_acquire_chunked(&state);
1898
+
1899
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1900
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1901
+ at the arena scratch the chunk was just gathered into, which is
1902
+ packed, so stride[] is the element size and the author's inner loop
1903
+ sees contiguous data. */
1904
+ while ( ca_sweep_next_chunk(&state) ) {
1905
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1906
+ }
1907
+
1908
+ ca_sweep_release_chunked(&state);
1909
+
1910
+ return rcx0;
1911
+ }
1912
+
1913
+ VALUE
1914
+ ca_call_cslab_6 (ca_cslab_t func, const char *fsync,
1915
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5)
1916
+ {
1917
+ CArray *cx[6];
1918
+ char *base[6];
1919
+ char *base_orig[6];
1920
+ ca_size_t stride[6];
1921
+ char *owned_buf[6];
1922
+ int attached[6];
1923
+ ca_sweep_state_t state;
1924
+
1925
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1926
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1927
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1928
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1929
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1930
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1931
+
1932
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1933
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1934
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1935
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1936
+ base_orig is the field the whole-buffer path leaves zero; the
1937
+ chunked path walks it, so it has to be given here. */
1938
+ state.n_ops = 6;
1939
+ state.fsync = fsync;
1940
+ state.cx = cx;
1941
+ state.base = base;
1942
+ state.base_orig = base_orig;
1943
+ state.stride = stride;
1944
+ state.owned_buf = owned_buf;
1945
+ state.attached = attached;
1946
+ state.no_mask = 0;
1947
+ state.src_label = "ca_call_cslab_6";
1948
+
1949
+ ca_sweep_acquire_chunked(&state);
1950
+
1951
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
1952
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
1953
+ at the arena scratch the chunk was just gathered into, which is
1954
+ packed, so stride[] is the element size and the author's inner loop
1955
+ sees contiguous data. */
1956
+ while ( ca_sweep_next_chunk(&state) ) {
1957
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
1958
+ }
1959
+
1960
+ ca_sweep_release_chunked(&state);
1961
+
1962
+ return rcx0;
1963
+ }
1964
+
1965
+ VALUE
1966
+ ca_call_cslab_7 (ca_cslab_t func, const char *fsync,
1967
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6)
1968
+ {
1969
+ CArray *cx[7];
1970
+ char *base[7];
1971
+ char *base_orig[7];
1972
+ ca_size_t stride[7];
1973
+ char *owned_buf[7];
1974
+ int attached[7];
1975
+ ca_sweep_state_t state;
1976
+
1977
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1978
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1979
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1980
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1981
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1982
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1983
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
1984
+
1985
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1986
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1987
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1988
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1989
+ base_orig is the field the whole-buffer path leaves zero; the
1990
+ chunked path walks it, so it has to be given here. */
1991
+ state.n_ops = 7;
1992
+ state.fsync = fsync;
1993
+ state.cx = cx;
1994
+ state.base = base;
1995
+ state.base_orig = base_orig;
1996
+ state.stride = stride;
1997
+ state.owned_buf = owned_buf;
1998
+ state.attached = attached;
1999
+ state.no_mask = 0;
2000
+ state.src_label = "ca_call_cslab_7";
2001
+
2002
+ ca_sweep_acquire_chunked(&state);
2003
+
2004
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2005
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2006
+ at the arena scratch the chunk was just gathered into, which is
2007
+ packed, so stride[] is the element size and the author's inner loop
2008
+ sees contiguous data. */
2009
+ while ( ca_sweep_next_chunk(&state) ) {
2010
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state));
2011
+ }
2012
+
2013
+ ca_sweep_release_chunked(&state);
2014
+
2015
+ return rcx0;
2016
+ }
2017
+
2018
+ VALUE
2019
+ ca_call_cslab_1_r (ca_cslab_r_t func, const char *fsync,
2020
+ VALUE rcx0,
2021
+ void *userdata)
2022
+ {
2023
+ CArray *cx[1];
2024
+ char *base[1];
2025
+ char *base_orig[1];
2026
+ ca_size_t stride[1];
2027
+ char *owned_buf[1];
2028
+ int attached[1];
2029
+ ca_sweep_state_t state;
2030
+
2031
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2032
+
2033
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2034
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2035
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2036
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2037
+ base_orig is the field the whole-buffer path leaves zero; the
2038
+ chunked path walks it, so it has to be given here. */
2039
+ state.n_ops = 1;
2040
+ state.fsync = fsync;
2041
+ state.cx = cx;
2042
+ state.base = base;
2043
+ state.base_orig = base_orig;
2044
+ state.stride = stride;
2045
+ state.owned_buf = owned_buf;
2046
+ state.attached = attached;
2047
+ state.no_mask = 0;
2048
+ state.src_label = "ca_call_cslab_1_r";
2049
+
2050
+ ca_sweep_acquire_chunked(&state);
2051
+
2052
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2053
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2054
+ at the arena scratch the chunk was just gathered into, which is
2055
+ packed, so stride[] is the element size and the author's inner loop
2056
+ sees contiguous data. */
2057
+ while ( ca_sweep_next_chunk(&state) ) {
2058
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2059
+ }
2060
+
2061
+ ca_sweep_release_chunked(&state);
2062
+
2063
+ return rcx0;
2064
+ }
2065
+
2066
+ VALUE
2067
+ ca_call_cslab_2_r (ca_cslab_r_t func, const char *fsync,
2068
+ VALUE rcx0, VALUE rcx1,
2069
+ void *userdata)
2070
+ {
2071
+ CArray *cx[2];
2072
+ char *base[2];
2073
+ char *base_orig[2];
2074
+ ca_size_t stride[2];
2075
+ char *owned_buf[2];
2076
+ int attached[2];
2077
+ ca_sweep_state_t state;
2078
+
2079
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2080
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2081
+
2082
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2083
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2084
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2085
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2086
+ base_orig is the field the whole-buffer path leaves zero; the
2087
+ chunked path walks it, so it has to be given here. */
2088
+ state.n_ops = 2;
2089
+ state.fsync = fsync;
2090
+ state.cx = cx;
2091
+ state.base = base;
2092
+ state.base_orig = base_orig;
2093
+ state.stride = stride;
2094
+ state.owned_buf = owned_buf;
2095
+ state.attached = attached;
2096
+ state.no_mask = 0;
2097
+ state.src_label = "ca_call_cslab_2_r";
2098
+
2099
+ ca_sweep_acquire_chunked(&state);
2100
+
2101
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2102
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2103
+ at the arena scratch the chunk was just gathered into, which is
2104
+ packed, so stride[] is the element size and the author's inner loop
2105
+ sees contiguous data. */
2106
+ while ( ca_sweep_next_chunk(&state) ) {
2107
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2108
+ }
2109
+
2110
+ ca_sweep_release_chunked(&state);
2111
+
2112
+ return rcx0;
2113
+ }
2114
+
2115
+ VALUE
2116
+ ca_call_cslab_3_r (ca_cslab_r_t func, const char *fsync,
2117
+ VALUE rcx0, VALUE rcx1, VALUE rcx2,
2118
+ void *userdata)
2119
+ {
2120
+ CArray *cx[3];
2121
+ char *base[3];
2122
+ char *base_orig[3];
2123
+ ca_size_t stride[3];
2124
+ char *owned_buf[3];
2125
+ int attached[3];
2126
+ ca_sweep_state_t state;
2127
+
2128
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2129
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2130
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2131
+
2132
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2133
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2134
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2135
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2136
+ base_orig is the field the whole-buffer path leaves zero; the
2137
+ chunked path walks it, so it has to be given here. */
2138
+ state.n_ops = 3;
2139
+ state.fsync = fsync;
2140
+ state.cx = cx;
2141
+ state.base = base;
2142
+ state.base_orig = base_orig;
2143
+ state.stride = stride;
2144
+ state.owned_buf = owned_buf;
2145
+ state.attached = attached;
2146
+ state.no_mask = 0;
2147
+ state.src_label = "ca_call_cslab_3_r";
2148
+
2149
+ ca_sweep_acquire_chunked(&state);
2150
+
2151
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2152
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2153
+ at the arena scratch the chunk was just gathered into, which is
2154
+ packed, so stride[] is the element size and the author's inner loop
2155
+ sees contiguous data. */
2156
+ while ( ca_sweep_next_chunk(&state) ) {
2157
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2158
+ }
2159
+
2160
+ ca_sweep_release_chunked(&state);
2161
+
2162
+ return rcx0;
2163
+ }
2164
+
2165
+ VALUE
2166
+ ca_call_cslab_4_r (ca_cslab_r_t func, const char *fsync,
2167
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
2168
+ void *userdata)
2169
+ {
2170
+ CArray *cx[4];
2171
+ char *base[4];
2172
+ char *base_orig[4];
2173
+ ca_size_t stride[4];
2174
+ char *owned_buf[4];
2175
+ int attached[4];
2176
+ ca_sweep_state_t state;
2177
+
2178
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2179
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2180
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2181
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2182
+
2183
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2184
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2185
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2186
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2187
+ base_orig is the field the whole-buffer path leaves zero; the
2188
+ chunked path walks it, so it has to be given here. */
2189
+ state.n_ops = 4;
2190
+ state.fsync = fsync;
2191
+ state.cx = cx;
2192
+ state.base = base;
2193
+ state.base_orig = base_orig;
2194
+ state.stride = stride;
2195
+ state.owned_buf = owned_buf;
2196
+ state.attached = attached;
2197
+ state.no_mask = 0;
2198
+ state.src_label = "ca_call_cslab_4_r";
2199
+
2200
+ ca_sweep_acquire_chunked(&state);
2201
+
2202
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2203
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2204
+ at the arena scratch the chunk was just gathered into, which is
2205
+ packed, so stride[] is the element size and the author's inner loop
2206
+ sees contiguous data. */
2207
+ while ( ca_sweep_next_chunk(&state) ) {
2208
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2209
+ }
2210
+
2211
+ ca_sweep_release_chunked(&state);
2212
+
2213
+ return rcx0;
2214
+ }
2215
+
2216
+ VALUE
2217
+ ca_call_cslab_5_r (ca_cslab_r_t func, const char *fsync,
2218
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
2219
+ void *userdata)
2220
+ {
2221
+ CArray *cx[5];
2222
+ char *base[5];
2223
+ char *base_orig[5];
2224
+ ca_size_t stride[5];
2225
+ char *owned_buf[5];
2226
+ int attached[5];
2227
+ ca_sweep_state_t state;
2228
+
2229
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2230
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2231
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2232
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2233
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2234
+
2235
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2236
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2237
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2238
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2239
+ base_orig is the field the whole-buffer path leaves zero; the
2240
+ chunked path walks it, so it has to be given here. */
2241
+ state.n_ops = 5;
2242
+ state.fsync = fsync;
2243
+ state.cx = cx;
2244
+ state.base = base;
2245
+ state.base_orig = base_orig;
2246
+ state.stride = stride;
2247
+ state.owned_buf = owned_buf;
2248
+ state.attached = attached;
2249
+ state.no_mask = 0;
2250
+ state.src_label = "ca_call_cslab_5_r";
2251
+
2252
+ ca_sweep_acquire_chunked(&state);
2253
+
2254
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2255
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2256
+ at the arena scratch the chunk was just gathered into, which is
2257
+ packed, so stride[] is the element size and the author's inner loop
2258
+ sees contiguous data. */
2259
+ while ( ca_sweep_next_chunk(&state) ) {
2260
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2261
+ }
2262
+
2263
+ ca_sweep_release_chunked(&state);
2264
+
2265
+ return rcx0;
2266
+ }
2267
+
2268
+ VALUE
2269
+ ca_call_cslab_6_r (ca_cslab_r_t func, const char *fsync,
2270
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
2271
+ void *userdata)
2272
+ {
2273
+ CArray *cx[6];
2274
+ char *base[6];
2275
+ char *base_orig[6];
2276
+ ca_size_t stride[6];
2277
+ char *owned_buf[6];
2278
+ int attached[6];
2279
+ ca_sweep_state_t state;
2280
+
2281
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2282
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2283
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2284
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2285
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2286
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2287
+
2288
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2289
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2290
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2291
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2292
+ base_orig is the field the whole-buffer path leaves zero; the
2293
+ chunked path walks it, so it has to be given here. */
2294
+ state.n_ops = 6;
2295
+ state.fsync = fsync;
2296
+ state.cx = cx;
2297
+ state.base = base;
2298
+ state.base_orig = base_orig;
2299
+ state.stride = stride;
2300
+ state.owned_buf = owned_buf;
2301
+ state.attached = attached;
2302
+ state.no_mask = 0;
2303
+ state.src_label = "ca_call_cslab_6_r";
2304
+
2305
+ ca_sweep_acquire_chunked(&state);
2306
+
2307
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2308
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2309
+ at the arena scratch the chunk was just gathered into, which is
2310
+ packed, so stride[] is the element size and the author's inner loop
2311
+ sees contiguous data. */
2312
+ while ( ca_sweep_next_chunk(&state) ) {
2313
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2314
+ }
2315
+
2316
+ ca_sweep_release_chunked(&state);
2317
+
2318
+ return rcx0;
2319
+ }
2320
+
2321
+ VALUE
2322
+ ca_call_cslab_7_r (ca_cslab_r_t func, const char *fsync,
2323
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
2324
+ void *userdata)
2325
+ {
2326
+ CArray *cx[7];
2327
+ char *base[7];
2328
+ char *base_orig[7];
2329
+ ca_size_t stride[7];
2330
+ char *owned_buf[7];
2331
+ int attached[7];
2332
+ ca_sweep_state_t state;
2333
+
2334
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2335
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2336
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2337
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2338
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2339
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2340
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
2341
+
2342
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2343
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2344
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2345
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2346
+ base_orig is the field the whole-buffer path leaves zero; the
2347
+ chunked path walks it, so it has to be given here. */
2348
+ state.n_ops = 7;
2349
+ state.fsync = fsync;
2350
+ state.cx = cx;
2351
+ state.base = base;
2352
+ state.base_orig = base_orig;
2353
+ state.stride = stride;
2354
+ state.owned_buf = owned_buf;
2355
+ state.attached = attached;
2356
+ state.no_mask = 0;
2357
+ state.src_label = "ca_call_cslab_7_r";
2358
+
2359
+ ca_sweep_acquire_chunked(&state);
2360
+
2361
+ /* outer loop: hand the author one chunk at a time. base[] is rewritten
2362
+ per chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points
2363
+ at the arena scratch the chunk was just gathered into, which is
2364
+ packed, so stride[] is the element size and the author's inner loop
2365
+ sees contiguous data. */
2366
+ while ( ca_sweep_next_chunk(&state) ) {
2367
+ func(base, stride, state.chunk_n, ca_sweep_chunk_mask(&state), userdata);
2368
+ }
2369
+
2370
+ ca_sweep_release_chunked(&state);
2371
+
2372
+ return rcx0;
2373
+ }
2374
+
2375
+ VALUE
2376
+ ca_call_cslab_1_1 (int8_t dty, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2377
+ {
2378
+ volatile VALUE ry = Qnil;
2379
+
2380
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2381
+
2382
+ if ( dty != dtx1 ) {
2383
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
2384
+ } else {
2385
+ ry = rb_ca_template_n(1, rx1);
2386
+ }
2387
+
2388
+ ca_call_cslab_2(slabfunc, "10", ry, rx1);
2389
+
2390
+ if ( rb_ca_is_scalar(ry) ) {
2391
+ ry = rb_ca_fetch_addr(ry, 0);
2392
+ }
2393
+ return ry;
2394
+ }
2395
+
2396
+ VALUE
2397
+ ca_call_cslab_1_2 (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2398
+ {
2399
+ volatile VALUE ry = Qnil;
2400
+
2401
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2402
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2403
+
2404
+ if ( dty != dtx1 || dty != dtx2 ) {
2405
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
2406
+ } else {
2407
+ ry = rb_ca_template_n(2, rx1, rx2);
2408
+ }
2409
+
2410
+ ca_call_cslab_3(slabfunc, "100", ry, rx1, rx2);
2411
+
2412
+ if ( rb_ca_is_scalar(ry) ) {
2413
+ ry = rb_ca_fetch_addr(ry, 0);
2414
+ }
2415
+ return ry;
2416
+ }
2417
+
2418
+ VALUE
2419
+ ca_call_cslab_1_3 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2420
+ {
2421
+ volatile VALUE ry = Qnil;
2422
+
2423
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2424
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2425
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2426
+
2427
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
2428
+ ry = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)));
2429
+ } else {
2430
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
2431
+ }
2432
+
2433
+ ca_call_cslab_4(slabfunc, "1000", ry, rx1, rx2, rx3);
2434
+
2435
+ if ( rb_ca_is_scalar(ry) ) {
2436
+ ry = rb_ca_fetch_addr(ry, 0);
2437
+ }
2438
+ return ry;
2439
+ }
2440
+
2441
+ VALUE
2442
+ ca_call_cslab_1_4 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
2443
+ {
2444
+ volatile VALUE ry = Qnil;
2445
+
2446
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2447
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2448
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2449
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2450
+
2451
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
2452
+ ry = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)));
2453
+ } else {
2454
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2455
+ }
2456
+
2457
+ ca_call_cslab_5(slabfunc, "10000", ry, rx1, rx2, rx3, rx4);
2458
+
2459
+ if ( rb_ca_is_scalar(ry) ) {
2460
+ ry = rb_ca_fetch_addr(ry, 0);
2461
+ }
2462
+ return ry;
2463
+ }
2464
+
2465
+ VALUE
2466
+ ca_call_cslab_1_5 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5)
2467
+ {
2468
+ volatile VALUE ry = Qnil;
2469
+
2470
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2471
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2472
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2473
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2474
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2475
+
2476
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
2477
+ ry = rb_ca_template_n(5, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)));
2478
+ } else {
2479
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
2480
+ }
2481
+
2482
+ ca_call_cslab_6(slabfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5);
2483
+
2484
+ if ( rb_ca_is_scalar(ry) ) {
2485
+ ry = rb_ca_fetch_addr(ry, 0);
2486
+ }
2487
+ return ry;
2488
+ }
2489
+
2490
+ VALUE
2491
+ ca_call_cslab_1_6 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6)
2492
+ {
2493
+ volatile VALUE ry = Qnil;
2494
+
2495
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2496
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2497
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2498
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2499
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2500
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
2501
+
2502
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
2503
+ ry = rb_ca_template_n(6, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)), rb_ca_wrap_readonly(rx6, INT2NUM(dty)));
2504
+ } else {
2505
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
2506
+ }
2507
+
2508
+ ca_call_cslab_7(slabfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6);
2509
+
2510
+ if ( rb_ca_is_scalar(ry) ) {
2511
+ ry = rb_ca_fetch_addr(ry, 0);
2512
+ }
2513
+ return ry;
2514
+ }
2515
+
2516
+ VALUE
2517
+ ca_call_cslab_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2518
+ {
2519
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2520
+
2521
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2522
+
2523
+ if ( dty1 != dtx1 ) {
2524
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
2525
+ } else {
2526
+ ry1 = rb_ca_template_n(1, rx1);
2527
+ }
2528
+ if ( dty2 != dtx1 ) {
2529
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
2530
+ } else {
2531
+ ry2 = rb_ca_template_n(1, rx1);
2532
+ }
2533
+
2534
+ ca_call_cslab_3(slabfunc, "110", ry1, ry2, rx1);
2535
+
2536
+ if ( rb_ca_is_scalar(ry1) ) {
2537
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2538
+ }
2539
+ if ( rb_ca_is_scalar(ry2) ) {
2540
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2541
+ }
2542
+ return rb_ary_new3(2, ry1, ry2);
2543
+ }
2544
+
2545
+ VALUE
2546
+ ca_call_cslab_2_2 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2547
+ {
2548
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2549
+
2550
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2551
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2552
+
2553
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
2554
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
2555
+ } else {
2556
+ ry1 = rb_ca_template_n(2, rx1, rx2);
2557
+ }
2558
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
2559
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
2560
+ } else {
2561
+ ry2 = rb_ca_template_n(2, rx1, rx2);
2562
+ }
2563
+
2564
+ ca_call_cslab_4(slabfunc, "1100", ry1, ry2, rx1, rx2);
2565
+
2566
+ if ( rb_ca_is_scalar(ry1) ) {
2567
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2568
+ }
2569
+ if ( rb_ca_is_scalar(ry2) ) {
2570
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2571
+ }
2572
+ return rb_ary_new3(2, ry1, ry2);
2573
+ }
2574
+
2575
+ VALUE
2576
+ ca_call_cslab_2_3 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2577
+ {
2578
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2579
+
2580
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2581
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2582
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2583
+
2584
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
2585
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
2586
+ } else {
2587
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
2588
+ }
2589
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
2590
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
2591
+ } else {
2592
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
2593
+ }
2594
+
2595
+ ca_call_cslab_5(slabfunc, "11000", ry1, ry2, rx1, rx2, rx3);
2596
+
2597
+ if ( rb_ca_is_scalar(ry1) ) {
2598
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2599
+ }
2600
+ if ( rb_ca_is_scalar(ry2) ) {
2601
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2602
+ }
2603
+ return rb_ary_new3(2, ry1, ry2);
2604
+ }
2605
+
2606
+ VALUE
2607
+ ca_call_cslab_2_4 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
2608
+ {
2609
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2610
+
2611
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2612
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2613
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2614
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2615
+
2616
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
2617
+ ry1 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)), rb_ca_wrap_readonly(rx4, INT2NUM(dty1)));
2618
+ } else {
2619
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2620
+ }
2621
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
2622
+ ry2 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)), rb_ca_wrap_readonly(rx4, INT2NUM(dty2)));
2623
+ } else {
2624
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2625
+ }
2626
+
2627
+ ca_call_cslab_6(slabfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
2628
+
2629
+ if ( rb_ca_is_scalar(ry1) ) {
2630
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2631
+ }
2632
+ if ( rb_ca_is_scalar(ry2) ) {
2633
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2634
+ }
2635
+ return rb_ary_new3(2, ry1, ry2);
2636
+ }
2637
+
2638
+ VALUE
2639
+ ca_call_cslab_3_1 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2640
+ {
2641
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2642
+
2643
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2644
+
2645
+ if ( dty1 != dtx1 ) {
2646
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
2647
+ } else {
2648
+ ry1 = rb_ca_template_n(1, rx1);
2649
+ }
2650
+ if ( dty2 != dtx1 ) {
2651
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
2652
+ } else {
2653
+ ry2 = rb_ca_template_n(1, rx1);
2654
+ }
2655
+ if ( dty3 != dtx1 ) {
2656
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
2657
+ } else {
2658
+ ry3 = rb_ca_template_n(1, rx1);
2659
+ }
2660
+
2661
+ ca_call_cslab_4(slabfunc, "1110", ry1, ry2, ry3, rx1);
2662
+
2663
+ if ( rb_ca_is_scalar(ry1) ) {
2664
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2665
+ }
2666
+ if ( rb_ca_is_scalar(ry2) ) {
2667
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2668
+ }
2669
+ if ( rb_ca_is_scalar(ry3) ) {
2670
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2671
+ }
2672
+ return rb_ary_new3(3, ry1, ry2, ry3);
2673
+ }
2674
+
2675
+ VALUE
2676
+ ca_call_cslab_3_2 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2677
+ {
2678
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2679
+
2680
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2681
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2682
+
2683
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
2684
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
2685
+ } else {
2686
+ ry1 = rb_ca_template_n(2, rx1, rx2);
2687
+ }
2688
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
2689
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
2690
+ } else {
2691
+ ry2 = rb_ca_template_n(2, rx1, rx2);
2692
+ }
2693
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
2694
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
2695
+ } else {
2696
+ ry3 = rb_ca_template_n(2, rx1, rx2);
2697
+ }
2698
+
2699
+ ca_call_cslab_5(slabfunc, "11100", ry1, ry2, ry3, rx1, rx2);
2700
+
2701
+ if ( rb_ca_is_scalar(ry1) ) {
2702
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2703
+ }
2704
+ if ( rb_ca_is_scalar(ry2) ) {
2705
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2706
+ }
2707
+ if ( rb_ca_is_scalar(ry3) ) {
2708
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2709
+ }
2710
+ return rb_ary_new3(3, ry1, ry2, ry3);
2711
+ }
2712
+
2713
+ VALUE
2714
+ ca_call_cslab_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2715
+ {
2716
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2717
+
2718
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2719
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2720
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2721
+
2722
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
2723
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
2724
+ } else {
2725
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
2726
+ }
2727
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
2728
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
2729
+ } else {
2730
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
2731
+ }
2732
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
2733
+ ry3 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)), rb_ca_wrap_readonly(rx3, INT2NUM(dty3)));
2734
+ } else {
2735
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
2736
+ }
2737
+
2738
+ ca_call_cslab_6(slabfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
2739
+
2740
+ if ( rb_ca_is_scalar(ry1) ) {
2741
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2742
+ }
2743
+ if ( rb_ca_is_scalar(ry2) ) {
2744
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2745
+ }
2746
+ if ( rb_ca_is_scalar(ry3) ) {
2747
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2748
+ }
2749
+ return rb_ary_new3(3, ry1, ry2, ry3);
2750
+ }
2751
+
2752
+ VALUE
2753
+ ca_call_cslab_1_1_r (int8_t dty, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
2754
+ {
2755
+ volatile VALUE ry = Qnil;
2756
+
2757
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2758
+
2759
+ if ( dty != dtx1 ) {
2760
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
2761
+ } else {
2762
+ ry = rb_ca_template_n(1, rx1);
2763
+ }
2764
+
2765
+ ca_call_cslab_2_r(slabfunc, "10", ry, rx1, userdata);
2766
+
2767
+ if ( rb_ca_is_scalar(ry) ) {
2768
+ ry = rb_ca_fetch_addr(ry, 0);
2769
+ }
2770
+ return ry;
2771
+ }
2772
+
2773
+ VALUE
2774
+ ca_call_cslab_1_2_r (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
2775
+ {
2776
+ volatile VALUE ry = Qnil;
2777
+
2778
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2779
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2780
+
2781
+ if ( dty != dtx1 || dty != dtx2 ) {
2782
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
2783
+ } else {
2784
+ ry = rb_ca_template_n(2, rx1, rx2);
2785
+ }
2786
+
2787
+ ca_call_cslab_3_r(slabfunc, "100", ry, rx1, rx2, userdata);
2788
+
2789
+ if ( rb_ca_is_scalar(ry) ) {
2790
+ ry = rb_ca_fetch_addr(ry, 0);
2791
+ }
2792
+ return ry;
2793
+ }
2794
+
2795
+ VALUE
2796
+ ca_call_cslab_1_3_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
2797
+ {
2798
+ volatile VALUE ry = Qnil;
2799
+
2800
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2801
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2802
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2803
+
2804
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
2805
+ ry = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)));
2806
+ } else {
2807
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
2808
+ }
2809
+
2810
+ ca_call_cslab_4_r(slabfunc, "1000", ry, rx1, rx2, rx3, userdata);
2811
+
2812
+ if ( rb_ca_is_scalar(ry) ) {
2813
+ ry = rb_ca_fetch_addr(ry, 0);
2814
+ }
2815
+ return ry;
2816
+ }
2817
+
2818
+ VALUE
2819
+ ca_call_cslab_1_4_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
2820
+ {
2821
+ volatile VALUE ry = Qnil;
2822
+
2823
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2824
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2825
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2826
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2827
+
2828
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
2829
+ ry = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)));
2830
+ } else {
2831
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2832
+ }
2833
+
2834
+ ca_call_cslab_5_r(slabfunc, "10000", ry, rx1, rx2, rx3, rx4, userdata);
2835
+
2836
+ if ( rb_ca_is_scalar(ry) ) {
2837
+ ry = rb_ca_fetch_addr(ry, 0);
2838
+ }
2839
+ return ry;
2840
+ }
2841
+
2842
+ VALUE
2843
+ ca_call_cslab_1_5_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, void *userdata)
2844
+ {
2845
+ volatile VALUE ry = Qnil;
2846
+
2847
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2848
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2849
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2850
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2851
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2852
+
2853
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
2854
+ ry = rb_ca_template_n(5, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)));
2855
+ } else {
2856
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
2857
+ }
2858
+
2859
+ ca_call_cslab_6_r(slabfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5, userdata);
2860
+
2861
+ if ( rb_ca_is_scalar(ry) ) {
2862
+ ry = rb_ca_fetch_addr(ry, 0);
2863
+ }
2864
+ return ry;
2865
+ }
2866
+
2867
+ VALUE
2868
+ ca_call_cslab_1_6_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6, void *userdata)
2869
+ {
2870
+ volatile VALUE ry = Qnil;
2871
+
2872
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2873
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2874
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2875
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2876
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2877
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
2878
+
2879
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
2880
+ ry = rb_ca_template_n(6, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)), rb_ca_wrap_readonly(rx3, INT2NUM(dty)), rb_ca_wrap_readonly(rx4, INT2NUM(dty)), rb_ca_wrap_readonly(rx5, INT2NUM(dty)), rb_ca_wrap_readonly(rx6, INT2NUM(dty)));
2881
+ } else {
2882
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
2883
+ }
2884
+
2885
+ ca_call_cslab_7_r(slabfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6, userdata);
2886
+
2887
+ if ( rb_ca_is_scalar(ry) ) {
2888
+ ry = rb_ca_fetch_addr(ry, 0);
2889
+ }
2890
+ return ry;
2891
+ }
2892
+
2893
+ VALUE
2894
+ ca_call_cslab_2_1_r (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
2895
+ {
2896
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2897
+
2898
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2899
+
2900
+ if ( dty1 != dtx1 ) {
2901
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
2902
+ } else {
2903
+ ry1 = rb_ca_template_n(1, rx1);
2904
+ }
2905
+ if ( dty2 != dtx1 ) {
2906
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
2907
+ } else {
2908
+ ry2 = rb_ca_template_n(1, rx1);
2909
+ }
2910
+
2911
+ ca_call_cslab_3_r(slabfunc, "110", ry1, ry2, rx1, userdata);
2912
+
2913
+ if ( rb_ca_is_scalar(ry1) ) {
2914
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2915
+ }
2916
+ if ( rb_ca_is_scalar(ry2) ) {
2917
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2918
+ }
2919
+ return rb_ary_new3(2, ry1, ry2);
2920
+ }
2921
+
2922
+ VALUE
2923
+ ca_call_cslab_2_2_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
2924
+ {
2925
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2926
+
2927
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2928
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2929
+
2930
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
2931
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
2932
+ } else {
2933
+ ry1 = rb_ca_template_n(2, rx1, rx2);
2934
+ }
2935
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
2936
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
2937
+ } else {
2938
+ ry2 = rb_ca_template_n(2, rx1, rx2);
2939
+ }
2940
+
2941
+ ca_call_cslab_4_r(slabfunc, "1100", ry1, ry2, rx1, rx2, userdata);
2942
+
2943
+ if ( rb_ca_is_scalar(ry1) ) {
2944
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2945
+ }
2946
+ if ( rb_ca_is_scalar(ry2) ) {
2947
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2948
+ }
2949
+ return rb_ary_new3(2, ry1, ry2);
2950
+ }
2951
+
2952
+ VALUE
2953
+ ca_call_cslab_2_3_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
2954
+ {
2955
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2956
+
2957
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2958
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2959
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2960
+
2961
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
2962
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
2963
+ } else {
2964
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
2965
+ }
2966
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
2967
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
2968
+ } else {
2969
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
2970
+ }
2971
+
2972
+ ca_call_cslab_5_r(slabfunc, "11000", ry1, ry2, rx1, rx2, rx3, userdata);
2973
+
2974
+ if ( rb_ca_is_scalar(ry1) ) {
2975
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2976
+ }
2977
+ if ( rb_ca_is_scalar(ry2) ) {
2978
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2979
+ }
2980
+ return rb_ary_new3(2, ry1, ry2);
2981
+ }
2982
+
2983
+ VALUE
2984
+ ca_call_cslab_2_4_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
2985
+ {
2986
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2987
+
2988
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2989
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2990
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2991
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2992
+
2993
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
2994
+ ry1 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)), rb_ca_wrap_readonly(rx4, INT2NUM(dty1)));
2995
+ } else {
2996
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2997
+ }
2998
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
2999
+ ry2 = rb_ca_template_n(4, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)), rb_ca_wrap_readonly(rx4, INT2NUM(dty2)));
3000
+ } else {
3001
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
3002
+ }
3003
+
3004
+ ca_call_cslab_6_r(slabfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4, userdata);
3005
+
3006
+ if ( rb_ca_is_scalar(ry1) ) {
3007
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3008
+ }
3009
+ if ( rb_ca_is_scalar(ry2) ) {
3010
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3011
+ }
3012
+ return rb_ary_new3(2, ry1, ry2);
3013
+ }
3014
+
3015
+ VALUE
3016
+ ca_call_cslab_3_1_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
3017
+ {
3018
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3019
+
3020
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3021
+
3022
+ if ( dty1 != dtx1 ) {
3023
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
3024
+ } else {
3025
+ ry1 = rb_ca_template_n(1, rx1);
3026
+ }
3027
+ if ( dty2 != dtx1 ) {
3028
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
3029
+ } else {
3030
+ ry2 = rb_ca_template_n(1, rx1);
3031
+ }
3032
+ if ( dty3 != dtx1 ) {
3033
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
3034
+ } else {
3035
+ ry3 = rb_ca_template_n(1, rx1);
3036
+ }
3037
+
3038
+ ca_call_cslab_4_r(slabfunc, "1110", ry1, ry2, ry3, rx1, userdata);
3039
+
3040
+ if ( rb_ca_is_scalar(ry1) ) {
3041
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3042
+ }
3043
+ if ( rb_ca_is_scalar(ry2) ) {
3044
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3045
+ }
3046
+ if ( rb_ca_is_scalar(ry3) ) {
3047
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3048
+ }
3049
+ return rb_ary_new3(3, ry1, ry2, ry3);
3050
+ }
3051
+
3052
+ VALUE
3053
+ ca_call_cslab_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
3054
+ {
3055
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3056
+
3057
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3058
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3059
+
3060
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
3061
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
3062
+ } else {
3063
+ ry1 = rb_ca_template_n(2, rx1, rx2);
3064
+ }
3065
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
3066
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
3067
+ } else {
3068
+ ry2 = rb_ca_template_n(2, rx1, rx2);
3069
+ }
3070
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
3071
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
3072
+ } else {
3073
+ ry3 = rb_ca_template_n(2, rx1, rx2);
3074
+ }
3075
+
3076
+ ca_call_cslab_5_r(slabfunc, "11100", ry1, ry2, ry3, rx1, rx2, userdata);
3077
+
3078
+ if ( rb_ca_is_scalar(ry1) ) {
3079
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3080
+ }
3081
+ if ( rb_ca_is_scalar(ry2) ) {
3082
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3083
+ }
3084
+ if ( rb_ca_is_scalar(ry3) ) {
3085
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3086
+ }
3087
+ return rb_ary_new3(3, ry1, ry2, ry3);
3088
+ }
3089
+
3090
+ VALUE
3091
+ ca_call_cslab_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
3092
+ {
3093
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3094
+
3095
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3096
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3097
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3098
+
3099
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
3100
+ ry1 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)), rb_ca_wrap_readonly(rx3, INT2NUM(dty1)));
3101
+ } else {
3102
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
3103
+ }
3104
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
3105
+ ry2 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)), rb_ca_wrap_readonly(rx3, INT2NUM(dty2)));
3106
+ } else {
3107
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
3108
+ }
3109
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
3110
+ ry3 = rb_ca_template_n(3, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)), rb_ca_wrap_readonly(rx3, INT2NUM(dty3)));
3111
+ } else {
3112
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
3113
+ }
3114
+
3115
+ ca_call_cslab_6_r(slabfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3, userdata);
3116
+
3117
+ if ( rb_ca_is_scalar(ry1) ) {
3118
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3119
+ }
3120
+ if ( rb_ca_is_scalar(ry2) ) {
3121
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3122
+ }
3123
+ if ( rb_ca_is_scalar(ry3) ) {
3124
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3125
+ }
3126
+ return rb_ary_new3(3, ry1, ry2, ry3);
3127
+ }
3128
+