carray 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
@@ -1,819 +1,1424 @@
1
1
  /* ---------------------------------------------------------------------------
2
-
3
- carray_math_call.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 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
+ * L0.1 (PROPOSAL_L0_AUTHOR_SURFACE, 2026-06-11): the per-operand acquire
29
+ * + broadcast check + mask OR + release lifecycle is now factored out
30
+ * into ext/ca_sweep_engine.{c,h} (ca_sweep_acquire / ca_sweep_release). This
31
+ * file keeps the arity-dependent inner loop only. ABI unchanged.
32
+ *
33
+ * --------------------------------------------------------------------------- */
10
34
 
11
35
  #include "carray.h"
36
+ #include "ca_sweep_engine.h"
37
+ #include <string.h>
12
38
 
13
39
  VALUE
14
40
  ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
15
- VALUE rcx0)
41
+ VALUE rcx0)
16
42
  {
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
-
43
+ CArray *cx[1];
44
+ char *base[1];
45
+ ca_size_t stride[1];
46
+ char *owned_buf[1];
47
+ int attached[1];
48
+ ca_sweep_state_t state;
49
+ int k_op;
50
+
51
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
52
+
53
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
54
+ broadcast shape check, mask OR across INPUTs, mask propagate to
55
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
56
+ state.n_ops = 1;
57
+ state.fsync = fsync;
58
+ state.cx = cx;
59
+ state.base = base;
60
+ state.stride = stride;
61
+ state.owned_buf = owned_buf;
62
+ state.attached = attached;
63
+ state.no_mask = 0;
64
+ state.src_label = "ca_call_cfunc_1";
65
+
66
+ ca_sweep_acquire(&state);
67
+
68
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
29
69
  {
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);
70
+ char *p[1];
71
+ ca_size_t k;
72
+ if ( state.m0 ) {
73
+ for ( k = 0; k < state.n_kernel; k++ ) {
74
+ if ( ! state.m0[k] ) {
75
+ for ( k_op = 0; k_op < 1; k_op++ ) {
76
+ p[k_op] = base[k_op] + k * stride[k_op];
77
+ }
78
+ func(p[0]);
79
+ }
80
+ }
81
+ } else {
82
+ for ( k = 0; k < state.n_kernel; k++ ) {
83
+ for ( k_op = 0; k_op < 1; k_op++ ) {
84
+ p[k_op] = base[k_op] + k * stride[k_op];
85
+ }
86
+ func(p[0]);
87
+ }
42
88
  }
43
89
  }
44
90
 
45
- ca_sync(cx0);
46
- ca_detach(cx0);
91
+ ca_sweep_release(&state);
47
92
 
48
93
  return rcx0;
49
94
  }
50
95
 
51
-
52
96
  VALUE
53
97
  ca_call_cfunc_2 (void (*func)(void *p0, void *p1), const char *fsync,
54
- VALUE rcx0, VALUE rcx1)
98
+ VALUE rcx0, VALUE rcx1)
55
99
  {
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");
100
+ CArray *cx[2];
101
+ char *base[2];
102
+ ca_size_t stride[2];
103
+ char *owned_buf[2];
104
+ int attached[2];
105
+ ca_sweep_state_t state;
106
+ int k_op;
107
+
108
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
109
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
110
+
111
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
112
+ broadcast shape check, mask OR across INPUTs, mask propagate to
113
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
114
+ state.n_ops = 2;
115
+ state.fsync = fsync;
116
+ state.cx = cx;
117
+ state.base = base;
118
+ state.stride = stride;
119
+ state.owned_buf = owned_buf;
120
+ state.attached = attached;
121
+ state.no_mask = 0;
122
+ state.src_label = "ca_call_cfunc_2";
123
+
124
+ ca_sweep_acquire(&state);
125
+
126
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
127
+ {
128
+ char *p[2];
129
+ ca_size_t k;
130
+ if ( state.m0 ) {
131
+ for ( k = 0; k < state.n_kernel; k++ ) {
132
+ if ( ! state.m0[k] ) {
133
+ for ( k_op = 0; k_op < 2; k_op++ ) {
134
+ p[k_op] = base[k_op] + k * stride[k_op];
135
+ }
136
+ func(p[0], p[1]);
137
+ }
138
+ }
139
+ } else {
140
+ for ( k = 0; k < state.n_kernel; k++ ) {
141
+ for ( k_op = 0; k_op < 2; k_op++ ) {
142
+ p[k_op] = base[k_op] + k * stride[k_op];
143
+ }
144
+ func(p[0], p[1]);
145
+ }
146
+ }
63
147
  }
64
148
 
65
- TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx0);
66
- TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx1);
149
+ ca_sweep_release(&state);
67
150
 
68
- ca_attach_n(2, cx0, cx1);
151
+ return rcx0;
152
+ }
69
153
 
154
+ VALUE
155
+ ca_call_cfunc_3 (void (*func)(void *p0, void *p1, void *p2), const char *fsync,
156
+ VALUE rcx0, VALUE rcx1, VALUE rcx2)
157
+ {
158
+ CArray *cx[3];
159
+ char *base[3];
160
+ ca_size_t stride[3];
161
+ char *owned_buf[3];
162
+ int attached[3];
163
+ ca_sweep_state_t state;
164
+ int k_op;
165
+
166
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
167
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
168
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
169
+
170
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
171
+ broadcast shape check, mask OR across INPUTs, mask propagate to
172
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
173
+ state.n_ops = 3;
174
+ state.fsync = fsync;
175
+ state.cx = cx;
176
+ state.base = base;
177
+ state.stride = stride;
178
+ state.owned_buf = owned_buf;
179
+ state.attached = attached;
180
+ state.no_mask = 0;
181
+ state.src_label = "ca_call_cfunc_3";
182
+
183
+ ca_sweep_acquire(&state);
184
+
185
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
70
186
  {
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);
187
+ char *p[3];
188
+ ca_size_t k;
189
+ if ( state.m0 ) {
190
+ for ( k = 0; k < state.n_kernel; k++ ) {
191
+ if ( ! state.m0[k] ) {
192
+ for ( k_op = 0; k_op < 3; k_op++ ) {
193
+ p[k_op] = base[k_op] + k * stride[k_op];
194
+ }
195
+ func(p[0], p[1], p[2]);
196
+ }
197
+ }
198
+ } else {
199
+ for ( k = 0; k < state.n_kernel; k++ ) {
200
+ for ( k_op = 0; k_op < 3; k_op++ ) {
201
+ p[k_op] = base[k_op] + k * stride[k_op];
202
+ }
203
+ func(p[0], p[1], p[2]);
204
+ }
205
+ }
78
206
  }
79
207
 
208
+ ca_sweep_release(&state);
209
+
210
+ return rcx0;
211
+ }
212
+
213
+ VALUE
214
+ ca_call_cfunc_4 (void (*func)(void *p0, void *p1, void *p2, void *p3), const char *fsync,
215
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3)
216
+ {
217
+ CArray *cx[4];
218
+ char *base[4];
219
+ ca_size_t stride[4];
220
+ char *owned_buf[4];
221
+ int attached[4];
222
+ ca_sweep_state_t state;
223
+ int k_op;
224
+
225
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
226
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
227
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
228
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
229
+
230
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
231
+ broadcast shape check, mask OR across INPUTs, mask propagate to
232
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
233
+ state.n_ops = 4;
234
+ state.fsync = fsync;
235
+ state.cx = cx;
236
+ state.base = base;
237
+ state.stride = stride;
238
+ state.owned_buf = owned_buf;
239
+ state.attached = attached;
240
+ state.no_mask = 0;
241
+ state.src_label = "ca_call_cfunc_4";
242
+
243
+ ca_sweep_acquire(&state);
244
+
245
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
80
246
  {
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);
247
+ char *p[4];
248
+ ca_size_t k;
249
+ if ( state.m0 ) {
250
+ for ( k = 0; k < state.n_kernel; k++ ) {
251
+ if ( ! state.m0[k] ) {
252
+ for ( k_op = 0; k_op < 4; k_op++ ) {
253
+ p[k_op] = base[k_op] + k * stride[k_op];
254
+ }
255
+ func(p[0], p[1], p[2], p[3]);
101
256
  }
102
257
  }
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);
258
+ } else {
259
+ for ( k = 0; k < state.n_kernel; k++ ) {
260
+ for ( k_op = 0; k_op < 4; k_op++ ) {
261
+ p[k_op] = base[k_op] + k * stride[k_op];
262
+ }
263
+ func(p[0], p[1], p[2], p[3]);
112
264
  }
113
265
  }
114
266
  }
115
- if ( fsync[0] == '1' ) ca_sync(cx0);
116
- if ( fsync[1] == '1' ) ca_sync(cx1);
117
- ca_detach_n(2, cx0, cx1);
118
267
 
119
- free(m0);
268
+ ca_sweep_release(&state);
120
269
 
121
270
  return rcx0;
122
271
  }
123
272
 
124
273
  VALUE
125
- ca_call_cfunc_3 (void (*func)(void *p0, void *p1, void *p2), const char *fsync,
126
- VALUE rcx0, VALUE rcx1, VALUE rcx2)
274
+ ca_call_cfunc_5 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4), const char *fsync,
275
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4)
127
276
  {
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");
277
+ CArray *cx[5];
278
+ char *base[5];
279
+ ca_size_t stride[5];
280
+ char *owned_buf[5];
281
+ int attached[5];
282
+ ca_sweep_state_t state;
283
+ int k_op;
284
+
285
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
286
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
287
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
288
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
289
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
290
+
291
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
292
+ broadcast shape check, mask OR across INPUTs, mask propagate to
293
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
294
+ state.n_ops = 5;
295
+ state.fsync = fsync;
296
+ state.cx = cx;
297
+ state.base = base;
298
+ state.stride = stride;
299
+ state.owned_buf = owned_buf;
300
+ state.attached = attached;
301
+ state.no_mask = 0;
302
+ state.src_label = "ca_call_cfunc_5";
303
+
304
+ ca_sweep_acquire(&state);
305
+
306
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
307
+ {
308
+ char *p[5];
309
+ ca_size_t k;
310
+ if ( state.m0 ) {
311
+ for ( k = 0; k < state.n_kernel; k++ ) {
312
+ if ( ! state.m0[k] ) {
313
+ for ( k_op = 0; k_op < 5; k_op++ ) {
314
+ p[k_op] = base[k_op] + k * stride[k_op];
315
+ }
316
+ func(p[0], p[1], p[2], p[3], p[4]);
317
+ }
318
+ }
319
+ } else {
320
+ for ( k = 0; k < state.n_kernel; k++ ) {
321
+ for ( k_op = 0; k_op < 5; k_op++ ) {
322
+ p[k_op] = base[k_op] + k * stride[k_op];
323
+ }
324
+ func(p[0], p[1], p[2], p[3], p[4]);
325
+ }
326
+ }
135
327
  }
136
328
 
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);
329
+ ca_sweep_release(&state);
140
330
 
141
- ca_attach_n(3, cx0, cx1, cx2);
331
+ return rcx0;
332
+ }
142
333
 
334
+ VALUE
335
+ ca_call_cfunc_6 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5), const char *fsync,
336
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5)
337
+ {
338
+ CArray *cx[6];
339
+ char *base[6];
340
+ ca_size_t stride[6];
341
+ char *owned_buf[6];
342
+ int attached[6];
343
+ ca_sweep_state_t state;
344
+ int k_op;
345
+
346
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
347
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
348
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
349
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
350
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
351
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
352
+
353
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
354
+ broadcast shape check, mask OR across INPUTs, mask propagate to
355
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
356
+ state.n_ops = 6;
357
+ state.fsync = fsync;
358
+ state.cx = cx;
359
+ state.base = base;
360
+ state.stride = stride;
361
+ state.owned_buf = owned_buf;
362
+ state.attached = attached;
363
+ state.no_mask = 0;
364
+ state.src_label = "ca_call_cfunc_6";
365
+
366
+ ca_sweep_acquire(&state);
367
+
368
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
143
369
  {
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);
370
+ char *p[6];
371
+ ca_size_t k;
372
+ if ( state.m0 ) {
373
+ for ( k = 0; k < state.n_kernel; k++ ) {
374
+ if ( ! state.m0[k] ) {
375
+ for ( k_op = 0; k_op < 6; k_op++ ) {
376
+ p[k_op] = base[k_op] + k * stride[k_op];
377
+ }
378
+ func(p[0], p[1], p[2], p[3], p[4], p[5]);
379
+ }
380
+ }
381
+ } else {
382
+ for ( k = 0; k < state.n_kernel; k++ ) {
383
+ for ( k_op = 0; k_op < 6; k_op++ ) {
384
+ p[k_op] = base[k_op] + k * stride[k_op];
385
+ }
386
+ func(p[0], p[1], p[2], p[3], p[4], p[5]);
387
+ }
388
+ }
153
389
  }
154
390
 
391
+ ca_sweep_release(&state);
392
+
393
+ return rcx0;
394
+ }
395
+
396
+ VALUE
397
+ ca_call_cfunc_7 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6), const char *fsync,
398
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6)
399
+ {
400
+ CArray *cx[7];
401
+ char *base[7];
402
+ ca_size_t stride[7];
403
+ char *owned_buf[7];
404
+ int attached[7];
405
+ ca_sweep_state_t state;
406
+ int k_op;
407
+
408
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
409
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
410
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
411
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
412
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
413
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
414
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
415
+
416
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
417
+ broadcast shape check, mask OR across INPUTs, mask propagate to
418
+ OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
419
+ state.n_ops = 7;
420
+ state.fsync = fsync;
421
+ state.cx = cx;
422
+ state.base = base;
423
+ state.stride = stride;
424
+ state.owned_buf = owned_buf;
425
+ state.attached = attached;
426
+ state.no_mask = 0;
427
+ state.src_label = "ca_call_cfunc_7";
428
+
429
+ ca_sweep_acquire(&state);
430
+
431
+ /* inner loop: advance per-cell ptrs and invoke user kernel func */
155
432
  {
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);
433
+ char *p[7];
434
+ ca_size_t k;
435
+ if ( state.m0 ) {
436
+ for ( k = 0; k < state.n_kernel; k++ ) {
437
+ if ( ! state.m0[k] ) {
438
+ for ( k_op = 0; k_op < 7; k_op++ ) {
439
+ p[k_op] = base[k_op] + k * stride[k_op];
440
+ }
441
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
179
442
  }
180
443
  }
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);
444
+ } else {
445
+ for ( k = 0; k < state.n_kernel; k++ ) {
446
+ for ( k_op = 0; k_op < 7; k_op++ ) {
447
+ p[k_op] = base[k_op] + k * stride[k_op];
448
+ }
449
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
191
450
  }
192
451
  }
193
452
  }
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
453
 
199
- free(m0);
454
+ ca_sweep_release(&state);
200
455
 
201
456
  return rcx0;
202
457
  }
203
458
 
459
+ /* -------------------------------------------------------------------- */
460
+ /* Typed dispatchers: M outputs, N inputs. Wrap each input readonly to */
461
+ /* its declared data_type, allocate output template(s), delegate to raw. */
462
+ /* -------------------------------------------------------------------- */
463
+
204
464
  VALUE
205
- 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)
465
+ ca_call_cfunc_1_1 (int8_t dty, int8_t dtx1, void (*mathfunc)(void*, void*), volatile VALUE rx1)
207
466
  {
208
- CArray *cx0, *cx1, *cx2, *cx3;
209
- boolean8_t *m0 = NULL, *m;
210
- ca_size_t n;
467
+ volatile VALUE ry = Qnil;
211
468
 
212
- if ( strlen(fsync) != 4 ) {
213
- rb_raise(rb_eRuntimeError,
214
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
469
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
470
+
471
+ if ( dty != dtx1 ) {
472
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
473
+ } else {
474
+ ry = rb_ca_template_n(1, rx1);
215
475
  }
216
476
 
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);
477
+ ca_call_cfunc_2(mathfunc, "10", ry, rx1);
221
478
 
222
- ca_attach_n(4, cx0, cx1, cx2, cx3);
479
+ if ( rb_ca_is_scalar(ry) ) {
480
+ ry = rb_ca_fetch_addr(ry, 0);
481
+ }
482
+ return ry;
483
+ }
223
484
 
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);
485
+ VALUE
486
+ 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)
487
+ {
488
+ volatile VALUE ry = Qnil;
489
+
490
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
491
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
492
+
493
+ if ( dty != dtx1 || dty != dtx2 ) {
494
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
495
+ } else {
496
+ ry = rb_ca_template_n(2, rx1, rx2);
497
+ }
498
+
499
+ ca_call_cfunc_3(mathfunc, "100", ry, rx1, rx2);
500
+
501
+ if ( rb_ca_is_scalar(ry) ) {
502
+ ry = rb_ca_fetch_addr(ry, 0);
503
+ }
504
+ return ry;
505
+ }
506
+
507
+ VALUE
508
+ 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)
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
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
515
+
516
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
517
+ 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)));
518
+ } else {
519
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
520
+ }
521
+
522
+ ca_call_cfunc_4(mathfunc, "1000", ry, rx1, rx2, rx3);
523
+
524
+ if ( rb_ca_is_scalar(ry) ) {
525
+ ry = rb_ca_fetch_addr(ry, 0);
526
+ }
527
+ return ry;
528
+ }
529
+
530
+ VALUE
531
+ 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)
532
+ {
533
+ volatile VALUE ry = Qnil;
534
+
535
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
536
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
537
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
538
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
539
+
540
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
541
+ 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)));
542
+ } else {
543
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
544
+ }
545
+
546
+ ca_call_cfunc_5(mathfunc, "10000", ry, rx1, rx2, rx3, rx4);
547
+
548
+ if ( rb_ca_is_scalar(ry) ) {
549
+ ry = rb_ca_fetch_addr(ry, 0);
550
+ }
551
+ return ry;
552
+ }
553
+
554
+ VALUE
555
+ 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)
556
+ {
557
+ volatile VALUE ry = Qnil;
558
+
559
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
560
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
561
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
562
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
563
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
564
+
565
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
566
+ 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)));
567
+ } else {
568
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
569
+ }
570
+
571
+ ca_call_cfunc_6(mathfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5);
572
+
573
+ if ( rb_ca_is_scalar(ry) ) {
574
+ ry = rb_ca_fetch_addr(ry, 0);
575
+ }
576
+ return ry;
577
+ }
578
+
579
+ VALUE
580
+ 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)
581
+ {
582
+ volatile VALUE ry = Qnil;
583
+
584
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
585
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
586
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
587
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
588
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
589
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
590
+
591
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
592
+ 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)));
593
+ } else {
594
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
595
+ }
596
+
597
+ ca_call_cfunc_7(mathfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6);
598
+
599
+ if ( rb_ca_is_scalar(ry) ) {
600
+ ry = rb_ca_fetch_addr(ry, 0);
601
+ }
602
+ return ry;
603
+ }
604
+
605
+ VALUE
606
+ ca_call_cfunc_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, void (*mathfunc)(void*, void*, void*), volatile VALUE rx1)
607
+ {
608
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
609
+
610
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
611
+
612
+ if ( dty1 != dtx1 ) {
613
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
614
+ } else {
615
+ ry1 = rb_ca_template_n(1, rx1);
616
+ }
617
+ if ( dty2 != dtx1 ) {
618
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
619
+ } else {
620
+ ry2 = rb_ca_template_n(1, rx1);
621
+ }
622
+
623
+ ca_call_cfunc_3(mathfunc, "110", ry1, ry2, rx1);
624
+
625
+ if ( rb_ca_is_scalar(ry1) ) {
626
+ ry1 = rb_ca_fetch_addr(ry1, 0);
627
+ }
628
+ if ( rb_ca_is_scalar(ry2) ) {
629
+ ry2 = rb_ca_fetch_addr(ry2, 0);
630
+ }
631
+ return rb_ary_new3(2, ry1, ry2);
632
+ }
633
+
634
+ VALUE
635
+ 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)
636
+ {
637
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
638
+
639
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
640
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
641
+
642
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
643
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
644
+ } else {
645
+ ry1 = rb_ca_template_n(2, rx1, rx2);
646
+ }
647
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
648
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
649
+ } else {
650
+ ry2 = rb_ca_template_n(2, rx1, rx2);
651
+ }
652
+
653
+ ca_call_cfunc_4(mathfunc, "1100", ry1, ry2, rx1, rx2);
654
+
655
+ if ( rb_ca_is_scalar(ry1) ) {
656
+ ry1 = rb_ca_fetch_addr(ry1, 0);
657
+ }
658
+ if ( rb_ca_is_scalar(ry2) ) {
659
+ ry2 = rb_ca_fetch_addr(ry2, 0);
660
+ }
661
+ return rb_ary_new3(2, ry1, ry2);
662
+ }
663
+
664
+ VALUE
665
+ 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)
666
+ {
667
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
668
+
669
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
670
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
671
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
672
+
673
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
674
+ 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)));
675
+ } else {
676
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
677
+ }
678
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
679
+ 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)));
680
+ } else {
681
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
682
+ }
683
+
684
+ ca_call_cfunc_5(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3);
685
+
686
+ if ( rb_ca_is_scalar(ry1) ) {
687
+ ry1 = rb_ca_fetch_addr(ry1, 0);
688
+ }
689
+ if ( rb_ca_is_scalar(ry2) ) {
690
+ ry2 = rb_ca_fetch_addr(ry2, 0);
691
+ }
692
+ return rb_ary_new3(2, ry1, ry2);
693
+ }
694
+
695
+ VALUE
696
+ 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)
697
+ {
698
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
699
+
700
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
701
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
702
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
703
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
704
+
705
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
706
+ 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)));
707
+ } else {
708
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
709
+ }
710
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
711
+ 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)));
712
+ } else {
713
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
714
+ }
715
+
716
+ ca_call_cfunc_6(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
717
+
718
+ if ( rb_ca_is_scalar(ry1) ) {
719
+ ry1 = rb_ca_fetch_addr(ry1, 0);
720
+ }
721
+ if ( rb_ca_is_scalar(ry2) ) {
722
+ ry2 = rb_ca_fetch_addr(ry2, 0);
723
+ }
724
+ return rb_ary_new3(2, ry1, ry2);
725
+ }
726
+
727
+ VALUE
728
+ 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)
729
+ {
730
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
731
+
732
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
733
+
734
+ if ( dty1 != dtx1 ) {
735
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
736
+ } else {
737
+ ry1 = rb_ca_template_n(1, rx1);
738
+ }
739
+ if ( dty2 != dtx1 ) {
740
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
741
+ } else {
742
+ ry2 = rb_ca_template_n(1, rx1);
743
+ }
744
+ if ( dty3 != dtx1 ) {
745
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
746
+ } else {
747
+ ry3 = rb_ca_template_n(1, rx1);
748
+ }
749
+
750
+ ca_call_cfunc_4(mathfunc, "1110", ry1, ry2, ry3, rx1);
751
+
752
+ if ( rb_ca_is_scalar(ry1) ) {
753
+ ry1 = rb_ca_fetch_addr(ry1, 0);
754
+ }
755
+ if ( rb_ca_is_scalar(ry2) ) {
756
+ ry2 = rb_ca_fetch_addr(ry2, 0);
757
+ }
758
+ if ( rb_ca_is_scalar(ry3) ) {
759
+ ry3 = rb_ca_fetch_addr(ry3, 0);
760
+ }
761
+ return rb_ary_new3(3, ry1, ry2, ry3);
762
+ }
763
+
764
+ VALUE
765
+ 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)
766
+ {
767
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
768
+
769
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
770
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
771
+
772
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
773
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
774
+ } else {
775
+ ry1 = rb_ca_template_n(2, rx1, rx2);
776
+ }
777
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
778
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
779
+ } else {
780
+ ry2 = rb_ca_template_n(2, rx1, rx2);
781
+ }
782
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
783
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
784
+ } else {
785
+ ry3 = rb_ca_template_n(2, rx1, rx2);
786
+ }
787
+
788
+ ca_call_cfunc_5(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2);
789
+
790
+ if ( rb_ca_is_scalar(ry1) ) {
791
+ ry1 = rb_ca_fetch_addr(ry1, 0);
792
+ }
793
+ if ( rb_ca_is_scalar(ry2) ) {
794
+ ry2 = rb_ca_fetch_addr(ry2, 0);
795
+ }
796
+ if ( rb_ca_is_scalar(ry3) ) {
797
+ ry3 = rb_ca_fetch_addr(ry3, 0);
798
+ }
799
+ return rb_ary_new3(3, ry1, ry2, ry3);
800
+ }
801
+
802
+ VALUE
803
+ 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)
804
+ {
805
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
806
+
807
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
808
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
809
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
810
+
811
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
812
+ 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)));
813
+ } else {
814
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
815
+ }
816
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
817
+ 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)));
818
+ } else {
819
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
820
+ }
821
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
822
+ 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)));
823
+ } else {
824
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
825
+ }
826
+
827
+ ca_call_cfunc_6(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
828
+
829
+ if ( rb_ca_is_scalar(ry1) ) {
830
+ ry1 = rb_ca_fetch_addr(ry1, 0);
831
+ }
832
+ if ( rb_ca_is_scalar(ry2) ) {
833
+ ry2 = rb_ca_fetch_addr(ry2, 0);
834
+ }
835
+ if ( rb_ca_is_scalar(ry3) ) {
836
+ ry3 = rb_ca_fetch_addr(ry3, 0);
236
837
  }
838
+ return rb_ary_new3(3, ry1, ry2, ry3);
839
+ }
840
+
841
+ /* -------------------------------------------------------------------- */
842
+ /* Reentrant variants (`_r` suffix, POSIX convention): same as the */
843
+ /* corresponding non-`_r` variant but the callback takes a trailing */
844
+ /* `void *userdata` argument and the outer function takes a trailing */
845
+ /* `void *userdata` parameter forwarded to every per-cell invocation. */
846
+ /* -------------------------------------------------------------------- */
847
+
848
+ VALUE
849
+ ca_call_cfunc_1_r (void (*func)(void *p0, void *userdata), const char *fsync,
850
+ VALUE rcx0,
851
+ void *userdata)
852
+ {
853
+ CArray *cx[1];
854
+ char *base[1];
855
+ ca_size_t stride[1];
856
+ char *owned_buf[1];
857
+ int attached[1];
858
+ ca_sweep_state_t state;
859
+ int k_op;
860
+
861
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
862
+
863
+ /* sweep engine: same lifecycle as ca_call_cfunc_1; the difference is
864
+ the per-cell `func(...)` call has `userdata` as its last argument. */
865
+ state.n_ops = 1;
866
+ state.fsync = fsync;
867
+ state.cx = cx;
868
+ state.base = base;
869
+ state.stride = stride;
870
+ state.owned_buf = owned_buf;
871
+ state.attached = attached;
872
+ state.no_mask = 0;
873
+ state.src_label = "ca_call_cfunc_1_r";
874
+
875
+ ca_sweep_acquire(&state);
237
876
 
238
877
  {
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);
878
+ char *p[1];
879
+ ca_size_t k;
880
+ if ( state.m0 ) {
881
+ for ( k = 0; k < state.n_kernel; k++ ) {
882
+ if ( ! state.m0[k] ) {
883
+ for ( k_op = 0; k_op < 1; k_op++ ) {
884
+ p[k_op] = base[k_op] + k * stride[k_op];
885
+ }
886
+ func(p[0], userdata);
266
887
  }
267
888
  }
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);
889
+ } else {
890
+ for ( k = 0; k < state.n_kernel; k++ ) {
891
+ for ( k_op = 0; k_op < 1; k_op++ ) {
892
+ p[k_op] = base[k_op] + k * stride[k_op];
893
+ }
894
+ func(p[0], userdata);
279
895
  }
280
896
  }
281
897
  }
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
898
 
288
- free(m0);
899
+ ca_sweep_release(&state);
289
900
 
290
901
  return rcx0;
291
902
  }
292
903
 
293
904
  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)
905
+ ca_call_cfunc_2_r (void (*func)(void *p0, void *p1, void *userdata), const char *fsync,
906
+ VALUE rcx0, VALUE rcx1,
907
+ void *userdata)
296
908
  {
297
- CArray *cx0, *cx1, *cx2, *cx3, *cx4;
298
- boolean8_t *m0 = NULL, *m;
299
- ca_size_t n;
909
+ CArray *cx[2];
910
+ char *base[2];
911
+ ca_size_t stride[2];
912
+ char *owned_buf[2];
913
+ int attached[2];
914
+ ca_sweep_state_t state;
915
+ int k_op;
916
+
917
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
918
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
919
+
920
+ /* sweep engine: same lifecycle as ca_call_cfunc_2; the difference is
921
+ the per-cell `func(...)` call has `userdata` as its last argument. */
922
+ state.n_ops = 2;
923
+ state.fsync = fsync;
924
+ state.cx = cx;
925
+ state.base = base;
926
+ state.stride = stride;
927
+ state.owned_buf = owned_buf;
928
+ state.attached = attached;
929
+ state.no_mask = 0;
930
+ state.src_label = "ca_call_cfunc_2_r";
931
+
932
+ ca_sweep_acquire(&state);
300
933
 
301
- if ( strlen(fsync) != 5 ) {
302
- rb_raise(rb_eRuntimeError,
303
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
934
+ {
935
+ char *p[2];
936
+ ca_size_t k;
937
+ if ( state.m0 ) {
938
+ for ( k = 0; k < state.n_kernel; k++ ) {
939
+ if ( ! state.m0[k] ) {
940
+ for ( k_op = 0; k_op < 2; k_op++ ) {
941
+ p[k_op] = base[k_op] + k * stride[k_op];
942
+ }
943
+ func(p[0], p[1], userdata);
944
+ }
945
+ }
946
+ } else {
947
+ for ( k = 0; k < state.n_kernel; k++ ) {
948
+ for ( k_op = 0; k_op < 2; k_op++ ) {
949
+ p[k_op] = base[k_op] + k * stride[k_op];
950
+ }
951
+ func(p[0], p[1], userdata);
952
+ }
953
+ }
304
954
  }
305
955
 
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);
956
+ ca_sweep_release(&state);
311
957
 
312
- ca_attach_n(5, cx0, cx1, cx2, cx3, cx4);
958
+ return rcx0;
959
+ }
313
960
 
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
- }
961
+ VALUE
962
+ ca_call_cfunc_3_r (void (*func)(void *p0, void *p1, void *p2, void *userdata), const char *fsync,
963
+ VALUE rcx0, VALUE rcx1, VALUE rcx2,
964
+ void *userdata)
965
+ {
966
+ CArray *cx[3];
967
+ char *base[3];
968
+ ca_size_t stride[3];
969
+ char *owned_buf[3];
970
+ int attached[3];
971
+ ca_sweep_state_t state;
972
+ int k_op;
973
+
974
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
975
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
976
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
977
+
978
+ /* sweep engine: same lifecycle as ca_call_cfunc_3; the difference is
979
+ the per-cell `func(...)` call has `userdata` as its last argument. */
980
+ state.n_ops = 3;
981
+ state.fsync = fsync;
982
+ state.cx = cx;
983
+ state.base = base;
984
+ state.stride = stride;
985
+ state.owned_buf = owned_buf;
986
+ state.attached = attached;
987
+ state.no_mask = 0;
988
+ state.src_label = "ca_call_cfunc_3_r";
989
+
990
+ ca_sweep_acquire(&state);
329
991
 
330
992
  {
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);
993
+ char *p[3];
994
+ ca_size_t k;
995
+ if ( state.m0 ) {
996
+ for ( k = 0; k < state.n_kernel; k++ ) {
997
+ if ( ! state.m0[k] ) {
998
+ for ( k_op = 0; k_op < 3; k_op++ ) {
999
+ p[k_op] = base[k_op] + k * stride[k_op];
1000
+ }
1001
+ func(p[0], p[1], p[2], userdata);
361
1002
  }
362
1003
  }
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);
1004
+ } else {
1005
+ for ( k = 0; k < state.n_kernel; k++ ) {
1006
+ for ( k_op = 0; k_op < 3; k_op++ ) {
1007
+ p[k_op] = base[k_op] + k * stride[k_op];
1008
+ }
1009
+ func(p[0], p[1], p[2], userdata);
375
1010
  }
376
1011
  }
377
1012
  }
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
1013
 
385
- free(m0);
1014
+ ca_sweep_release(&state);
386
1015
 
387
1016
  return rcx0;
388
1017
  }
389
1018
 
390
1019
  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)
1020
+ ca_call_cfunc_4_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *userdata), const char *fsync,
1021
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
1022
+ void *userdata)
393
1023
  {
394
- CArray *cx0, *cx1, *cx2, *cx3, *cx4, *cx5;
395
- boolean8_t *m0 = NULL, *m;
396
- ca_size_t n;
1024
+ CArray *cx[4];
1025
+ char *base[4];
1026
+ ca_size_t stride[4];
1027
+ char *owned_buf[4];
1028
+ int attached[4];
1029
+ ca_sweep_state_t state;
1030
+ int k_op;
1031
+
1032
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1033
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1034
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1035
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1036
+
1037
+ /* sweep engine: same lifecycle as ca_call_cfunc_4; the difference is
1038
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1039
+ state.n_ops = 4;
1040
+ state.fsync = fsync;
1041
+ state.cx = cx;
1042
+ state.base = base;
1043
+ state.stride = stride;
1044
+ state.owned_buf = owned_buf;
1045
+ state.attached = attached;
1046
+ state.no_mask = 0;
1047
+ state.src_label = "ca_call_cfunc_4_r";
1048
+
1049
+ ca_sweep_acquire(&state);
397
1050
 
398
- if ( strlen(fsync) != 6 ) {
399
- rb_raise(rb_eRuntimeError,
400
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
1051
+ {
1052
+ char *p[4];
1053
+ ca_size_t k;
1054
+ if ( state.m0 ) {
1055
+ for ( k = 0; k < state.n_kernel; k++ ) {
1056
+ if ( ! state.m0[k] ) {
1057
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1058
+ p[k_op] = base[k_op] + k * stride[k_op];
1059
+ }
1060
+ func(p[0], p[1], p[2], p[3], userdata);
1061
+ }
1062
+ }
1063
+ } else {
1064
+ for ( k = 0; k < state.n_kernel; k++ ) {
1065
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1066
+ p[k_op] = base[k_op] + k * stride[k_op];
1067
+ }
1068
+ func(p[0], p[1], p[2], p[3], userdata);
1069
+ }
1070
+ }
401
1071
  }
402
1072
 
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);
1073
+ ca_sweep_release(&state);
409
1074
 
410
- ca_attach_n(6, cx0, cx1, cx2, cx3, cx4, cx5);
1075
+ return rcx0;
1076
+ }
411
1077
 
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
- }
1078
+ VALUE
1079
+ ca_call_cfunc_5_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *userdata), const char *fsync,
1080
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
1081
+ void *userdata)
1082
+ {
1083
+ CArray *cx[5];
1084
+ char *base[5];
1085
+ ca_size_t stride[5];
1086
+ char *owned_buf[5];
1087
+ int attached[5];
1088
+ ca_sweep_state_t state;
1089
+ int k_op;
1090
+
1091
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1092
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1093
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1094
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1095
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1096
+
1097
+ /* sweep engine: same lifecycle as ca_call_cfunc_5; the difference is
1098
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1099
+ state.n_ops = 5;
1100
+ state.fsync = fsync;
1101
+ state.cx = cx;
1102
+ state.base = base;
1103
+ state.stride = stride;
1104
+ state.owned_buf = owned_buf;
1105
+ state.attached = attached;
1106
+ state.no_mask = 0;
1107
+ state.src_label = "ca_call_cfunc_5_r";
1108
+
1109
+ ca_sweep_acquire(&state);
429
1110
 
430
1111
  {
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);
1112
+ char *p[5];
1113
+ ca_size_t k;
1114
+ if ( state.m0 ) {
1115
+ for ( k = 0; k < state.n_kernel; k++ ) {
1116
+ if ( ! state.m0[k] ) {
1117
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1118
+ p[k_op] = base[k_op] + k * stride[k_op];
1119
+ }
1120
+ func(p[0], p[1], p[2], p[3], p[4], userdata);
464
1121
  }
465
1122
  }
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);
1123
+ } else {
1124
+ for ( k = 0; k < state.n_kernel; k++ ) {
1125
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1126
+ p[k_op] = base[k_op] + k * stride[k_op];
1127
+ }
1128
+ func(p[0], p[1], p[2], p[3], p[4], userdata);
479
1129
  }
480
1130
  }
481
1131
  }
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
1132
 
490
- free(m0);
1133
+ ca_sweep_release(&state);
491
1134
 
492
1135
  return rcx0;
493
1136
  }
494
1137
 
495
1138
  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)
1139
+ ca_call_cfunc_6_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *userdata), const char *fsync,
1140
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
1141
+ void *userdata)
498
1142
  {
499
- CArray *cx0, *cx1, *cx2, *cx3, *cx4, *cx5, *cx6;
500
- boolean8_t *m0 = NULL, *m;
501
- ca_size_t n;
1143
+ CArray *cx[6];
1144
+ char *base[6];
1145
+ ca_size_t stride[6];
1146
+ char *owned_buf[6];
1147
+ int attached[6];
1148
+ ca_sweep_state_t state;
1149
+ int k_op;
1150
+
1151
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1152
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1153
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1154
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1155
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1156
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1157
+
1158
+ /* sweep engine: same lifecycle as ca_call_cfunc_6; the difference is
1159
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1160
+ state.n_ops = 6;
1161
+ state.fsync = fsync;
1162
+ state.cx = cx;
1163
+ state.base = base;
1164
+ state.stride = stride;
1165
+ state.owned_buf = owned_buf;
1166
+ state.attached = attached;
1167
+ state.no_mask = 0;
1168
+ state.src_label = "ca_call_cfunc_6_r";
1169
+
1170
+ ca_sweep_acquire(&state);
502
1171
 
503
- if ( strlen(fsync) != 7 ) {
504
- rb_raise(rb_eRuntimeError,
505
- "[BUG] invalid length of fsync arg in rb_ca_call_mathfunc");
1172
+ {
1173
+ char *p[6];
1174
+ ca_size_t k;
1175
+ if ( state.m0 ) {
1176
+ for ( k = 0; k < state.n_kernel; k++ ) {
1177
+ if ( ! state.m0[k] ) {
1178
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1179
+ p[k_op] = base[k_op] + k * stride[k_op];
1180
+ }
1181
+ func(p[0], p[1], p[2], p[3], p[4], p[5], userdata);
1182
+ }
1183
+ }
1184
+ } else {
1185
+ for ( k = 0; k < state.n_kernel; k++ ) {
1186
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1187
+ p[k_op] = base[k_op] + k * stride[k_op];
1188
+ }
1189
+ func(p[0], p[1], p[2], p[3], p[4], p[5], userdata);
1190
+ }
1191
+ }
506
1192
  }
507
1193
 
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);
1194
+ ca_sweep_release(&state);
515
1195
 
516
- ca_attach_n(7, cx0, cx1, cx2, cx3, cx4, cx5, cx6);
1196
+ return rcx0;
1197
+ }
517
1198
 
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
- }
1199
+ VALUE
1200
+ 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,
1201
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
1202
+ void *userdata)
1203
+ {
1204
+ CArray *cx[7];
1205
+ char *base[7];
1206
+ ca_size_t stride[7];
1207
+ char *owned_buf[7];
1208
+ int attached[7];
1209
+ ca_sweep_state_t state;
1210
+ int k_op;
1211
+
1212
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1213
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1214
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1215
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1216
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1217
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1218
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
1219
+
1220
+ /* sweep engine: same lifecycle as ca_call_cfunc_7; the difference is
1221
+ the per-cell `func(...)` call has `userdata` as its last argument. */
1222
+ state.n_ops = 7;
1223
+ state.fsync = fsync;
1224
+ state.cx = cx;
1225
+ state.base = base;
1226
+ state.stride = stride;
1227
+ state.owned_buf = owned_buf;
1228
+ state.attached = attached;
1229
+ state.no_mask = 0;
1230
+ state.src_label = "ca_call_cfunc_7_r";
1231
+
1232
+ ca_sweep_acquire(&state);
537
1233
 
538
1234
  {
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);
1235
+ char *p[7];
1236
+ ca_size_t k;
1237
+ if ( state.m0 ) {
1238
+ for ( k = 0; k < state.n_kernel; k++ ) {
1239
+ if ( ! state.m0[k] ) {
1240
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1241
+ p[k_op] = base[k_op] + k * stride[k_op];
1242
+ }
1243
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], userdata);
575
1244
  }
576
1245
  }
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);
1246
+ } else {
1247
+ for ( k = 0; k < state.n_kernel; k++ ) {
1248
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1249
+ p[k_op] = base[k_op] + k * stride[k_op];
1250
+ }
1251
+ func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], userdata);
591
1252
  }
592
1253
  }
593
-
594
1254
  }
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
1255
 
604
- free(m0);
1256
+ ca_sweep_release(&state);
605
1257
 
606
1258
  return rcx0;
607
1259
  }
608
1260
 
609
- /* -------------------------------------------------------------------- */
610
-
611
1261
  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);
622
- }
623
- ca_call_cfunc_2(mathfunc, "10", ry, rx);
624
- if ( rb_ca_is_scalar(ry) ) {
625
- return rb_ca_fetch_addr(ry, 0);
1262
+ ca_call_cfunc_1_1_r (int8_t dty, int8_t dtx1, void (*mathfunc)(void*, void*, void *userdata), volatile VALUE rx1, void *userdata)
1263
+ {
1264
+ volatile VALUE ry = Qnil;
1265
+
1266
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1267
+
1268
+ if ( dty != dtx1 ) {
1269
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
1270
+ } else {
1271
+ ry = rb_ca_template_n(1, rx1);
626
1272
  }
627
- else {
628
- return ry;
1273
+
1274
+ ca_call_cfunc_2_r(mathfunc, "10", ry, rx1, userdata);
1275
+
1276
+ if ( rb_ca_is_scalar(ry) ) {
1277
+ ry = rb_ca_fetch_addr(ry, 0);
629
1278
  }
1279
+ return ry;
630
1280
  }
631
1281
 
632
1282
  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));
1283
+ 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)
1284
+ {
1285
+ volatile VALUE ry = Qnil;
1286
+
1287
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1288
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1289
+
643
1290
  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)));
647
- }
648
- else {
649
- ry = rb_ca_template_n(2, rx1, rx2);
1291
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
1292
+ } else {
1293
+ ry = rb_ca_template_n(2, rx1, rx2);
650
1294
  }
651
- ca_call_cfunc_3(mathfunc, "100", ry, rx1, rx2);
1295
+
1296
+ ca_call_cfunc_3_r(mathfunc, "100", ry, rx1, rx2, userdata);
1297
+
652
1298
  if ( rb_ca_is_scalar(ry) ) {
653
- return rb_ca_fetch_addr(ry, 0);
654
- }
655
- else {
656
- return ry;
1299
+ ry = rb_ca_fetch_addr(ry, 0);
657
1300
  }
1301
+ return ry;
658
1302
  }
659
1303
 
660
-
661
1304
  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);
1305
+ 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)
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
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1312
+
1313
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
1314
+ 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)));
1315
+ } else {
1316
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
682
1317
  }
683
- else {
684
- return ry;
1318
+
1319
+ ca_call_cfunc_4_r(mathfunc, "1000", ry, rx1, rx2, rx3, userdata);
1320
+
1321
+ if ( rb_ca_is_scalar(ry) ) {
1322
+ ry = rb_ca_fetch_addr(ry, 0);
685
1323
  }
1324
+ return ry;
686
1325
  }
687
1326
 
688
1327
  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);
711
- if ( rb_ca_is_scalar(ry) ) {
712
- return rb_ca_fetch_addr(ry, 0);
1328
+ 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)
1329
+ {
1330
+ volatile VALUE ry = Qnil;
1331
+
1332
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1333
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1334
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1335
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1336
+
1337
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
1338
+ 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)));
1339
+ } else {
1340
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
713
1341
  }
714
- else {
715
- return ry;
1342
+
1343
+ ca_call_cfunc_5_r(mathfunc, "10000", ry, rx1, rx2, rx3, rx4, userdata);
1344
+
1345
+ if ( rb_ca_is_scalar(ry) ) {
1346
+ ry = rb_ca_fetch_addr(ry, 0);
716
1347
  }
1348
+ return ry;
717
1349
  }
718
1350
 
719
1351
  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);
746
- if ( rb_ca_is_scalar(ry) ) {
747
- return rb_ca_fetch_addr(ry, 0);
1352
+ 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)
1353
+ {
1354
+ volatile VALUE ry = Qnil;
1355
+
1356
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1357
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1358
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1359
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1360
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
1361
+
1362
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
1363
+ 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)));
1364
+ } else {
1365
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
748
1366
  }
749
- else {
750
- return ry;
1367
+
1368
+ ca_call_cfunc_6_r(mathfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5, userdata);
1369
+
1370
+ if ( rb_ca_is_scalar(ry) ) {
1371
+ ry = rb_ca_fetch_addr(ry, 0);
751
1372
  }
1373
+ return ry;
752
1374
  }
753
1375
 
754
1376
  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);
785
- if ( rb_ca_is_scalar(ry) ) {
786
- return rb_ca_fetch_addr(ry, 0);
1377
+ 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)
1378
+ {
1379
+ volatile VALUE ry = Qnil;
1380
+
1381
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1382
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1383
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1384
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1385
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
1386
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
1387
+
1388
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
1389
+ 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)));
1390
+ } else {
1391
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
787
1392
  }
788
- else {
789
- return ry;
1393
+
1394
+ ca_call_cfunc_7_r(mathfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6, userdata);
1395
+
1396
+ if ( rb_ca_is_scalar(ry) ) {
1397
+ ry = rb_ca_fetch_addr(ry, 0);
790
1398
  }
1399
+ return ry;
791
1400
  }
792
1401
 
793
1402
  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));
1403
+ 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)
1404
+ {
1405
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1406
+
1407
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1408
+
802
1409
  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);
1410
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
1411
+ } else {
1412
+ ry1 = rb_ca_template_n(1, rx1);
808
1413
  }
809
1414
  if ( dty2 != dtx1 ) {
810
- ry2 = rb_ca_template_n(1,
811
- rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
1415
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
1416
+ } else {
1417
+ ry2 = rb_ca_template_n(1, rx1);
812
1418
  }
813
- else {
814
- ry2 = rb_ca_template_n(1, rx1);
815
- }
816
- ca_call_cfunc_3(mathfunc, "110", ry1, ry2, rx1);
1419
+
1420
+ ca_call_cfunc_3_r(mathfunc, "110", ry1, ry2, rx1, userdata);
1421
+
817
1422
  if ( rb_ca_is_scalar(ry1) ) {
818
1423
  ry1 = rb_ca_fetch_addr(ry1, 0);
819
1424
  }
@@ -823,36 +1428,27 @@ ca_call_cfunc_2_1 (int8_t dty1,
823
1428
  return rb_ary_new3(2, ry1, ry2);
824
1429
  }
825
1430
 
826
-
827
1431
  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));
1432
+ 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)
1433
+ {
1434
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1435
+
1436
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1437
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1438
+
839
1439
  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);
1440
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
1441
+ } else {
1442
+ ry1 = rb_ca_template_n(2, rx1, rx2);
846
1443
  }
847
1444
  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)));
851
- }
852
- else {
853
- ry2 = rb_ca_template_n(2, rx1, rx2);
1445
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
1446
+ } else {
1447
+ ry2 = rb_ca_template_n(2, rx1, rx2);
854
1448
  }
855
- ca_call_cfunc_4(mathfunc, "1100", ry1, ry2, rx1, rx2);
1449
+
1450
+ ca_call_cfunc_4_r(mathfunc, "1100", ry1, ry2, rx1, rx2, userdata);
1451
+
856
1452
  if ( rb_ca_is_scalar(ry1) ) {
857
1453
  ry1 = rb_ca_fetch_addr(ry1, 0);
858
1454
  }
@@ -863,39 +1459,27 @@ ca_call_cfunc_2_2 (int8_t dty1,
863
1459
  }
864
1460
 
865
1461
  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));
1462
+ 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)
1463
+ {
1464
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1465
+
1466
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1467
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1468
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1469
+
880
1470
  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);
1471
+ 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)));
1472
+ } else {
1473
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
888
1474
  }
889
1475
  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);
1476
+ 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)));
1477
+ } else {
1478
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
897
1479
  }
898
- ca_call_cfunc_5(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3);
1480
+
1481
+ ca_call_cfunc_5_r(mathfunc, "11000", ry1, ry2, rx1, rx2, rx3, userdata);
1482
+
899
1483
  if ( rb_ca_is_scalar(ry1) ) {
900
1484
  ry1 = rb_ca_fetch_addr(ry1, 0);
901
1485
  }
@@ -906,44 +1490,28 @@ ca_call_cfunc_2_3 (int8_t dty1,
906
1490
  }
907
1491
 
908
1492
  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));
1493
+ 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)
1494
+ {
1495
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
1496
+
1497
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1498
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1499
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1500
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
1501
+
926
1502
  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);
1503
+ 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)));
1504
+ } else {
1505
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
935
1506
  }
936
1507
  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)));
942
- }
943
- else {
944
- ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
1508
+ 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)));
1509
+ } else {
1510
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
945
1511
  }
946
- ca_call_cfunc_6(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
1512
+
1513
+ ca_call_cfunc_6_r(mathfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4, userdata);
1514
+
947
1515
  if ( rb_ca_is_scalar(ry1) ) {
948
1516
  ry1 = rb_ca_fetch_addr(ry1, 0);
949
1517
  }
@@ -954,37 +1522,30 @@ ca_call_cfunc_2_4 (int8_t dty1,
954
1522
  }
955
1523
 
956
1524
  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));
1525
+ 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)
1526
+ {
1527
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1528
+
1529
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1530
+
966
1531
  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);
1532
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
1533
+ } else {
1534
+ ry1 = rb_ca_template_n(1, rx1);
972
1535
  }
973
1536
  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);
1537
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
1538
+ } else {
1539
+ ry2 = rb_ca_template_n(1, rx1);
979
1540
  }
980
- if ( dty3 != dtx1 ) {
981
- ry3 = rb_ca_template_n(1,
982
- rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
1541
+ if ( dty3 != dtx1 ) {
1542
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
1543
+ } else {
1544
+ ry3 = rb_ca_template_n(1, rx1);
983
1545
  }
984
- else {
985
- ry3 = rb_ca_template_n(1, rx1);
986
- }
987
- ca_call_cfunc_4(mathfunc, "1110", ry1, ry2, ry3, rx1);
1546
+
1547
+ ca_call_cfunc_4_r(mathfunc, "1110", ry1, ry2, ry3, rx1, userdata);
1548
+
988
1549
  if ( rb_ca_is_scalar(ry1) ) {
989
1550
  ry1 = rb_ca_fetch_addr(ry1, 0);
990
1551
  }
@@ -998,43 +1559,31 @@ ca_call_cfunc_3_1 (int8_t dty1,
998
1559
  }
999
1560
 
1000
1561
  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));
1562
+ 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)
1563
+ {
1564
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1565
+
1566
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1567
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1568
+
1013
1569
  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);
1570
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
1571
+ } else {
1572
+ ry1 = rb_ca_template_n(2, rx1, rx2);
1020
1573
  }
1021
1574
  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);
1575
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
1576
+ } else {
1577
+ ry2 = rb_ca_template_n(2, rx1, rx2);
1028
1578
  }
1029
1579
  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)));
1580
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
1581
+ } else {
1582
+ ry3 = rb_ca_template_n(2, rx1, rx2);
1033
1583
  }
1034
- else {
1035
- ry3 = rb_ca_template_n(2, rx1, rx2);
1036
- }
1037
- ca_call_cfunc_5(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2);
1584
+
1585
+ ca_call_cfunc_5_r(mathfunc, "11100", ry1, ry2, ry3, rx1, rx2, userdata);
1586
+
1038
1587
  if ( rb_ca_is_scalar(ry1) ) {
1039
1588
  ry1 = rb_ca_fetch_addr(ry1, 0);
1040
1589
  }
@@ -1048,50 +1597,32 @@ ca_call_cfunc_3_2 (int8_t dty1,
1048
1597
  }
1049
1598
 
1050
1599
  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));
1600
+ 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)
1601
+ {
1602
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
1603
+
1604
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
1605
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
1606
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
1607
+
1066
1608
  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);
1609
+ 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)));
1610
+ } else {
1611
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
1074
1612
  }
1075
1613
  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);
1614
+ 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)));
1615
+ } else {
1616
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
1083
1617
  }
1084
1618
  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);
1619
+ 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)));
1620
+ } else {
1621
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
1092
1622
  }
1093
1623
 
1094
- ca_call_cfunc_6(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
1624
+ ca_call_cfunc_6_r(mathfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3, userdata);
1625
+
1095
1626
  if ( rb_ca_is_scalar(ry1) ) {
1096
1627
  ry1 = rb_ca_fetch_addr(ry1, 0);
1097
1628
  }
@@ -1103,3 +1634,4 @@ ca_call_cfunc_3_3 (int8_t dty1,
1103
1634
  }
1104
1635
  return rb_ary_new3(3, ry1, ry2, ry3);
1105
1636
  }
1637
+