carray 3.0.0 → 3.0.2

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +845 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +33 -33
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_dispatch.c +33 -4
  8. data/ext/ca_axis_group.c +256 -114
  9. data/ext/ca_binop_dispatch.c +5 -6
  10. data/ext/ca_binop_dispatch.h +0 -7
  11. data/ext/ca_categorical_iterator.c +121 -67
  12. data/ext/ca_for_each_element.h +6 -8
  13. data/ext/ca_group_iter.c +1 -1
  14. data/ext/ca_kernel_iterator.c +386 -74
  15. data/ext/ca_kernel_iterator.h +145 -45
  16. data/ext/ca_obj_array.c +62 -20
  17. data/ext/ca_obj_bincmp.c +57 -27
  18. data/ext/ca_obj_binop.c +86 -30
  19. data/ext/ca_obj_block.c +4 -4
  20. data/ext/ca_obj_const_string.c +88 -27
  21. data/ext/ca_obj_face.c +104 -0
  22. data/ext/ca_obj_face.h +48 -1
  23. data/ext/ca_obj_fake.c +11 -0
  24. data/ext/ca_obj_fixlen_string.c +21 -6
  25. data/ext/ca_obj_grid.c +11 -3
  26. data/ext/ca_obj_meld.c +125 -22
  27. data/ext/ca_obj_moncmp.c +33 -14
  28. data/ext/ca_obj_monop.c +19 -7
  29. data/ext/ca_obj_object.c +107 -4
  30. data/ext/ca_obj_record.c +3 -1
  31. data/ext/ca_obj_refer.c +30 -6
  32. data/ext/ca_obj_roll.c +13 -5
  33. data/ext/ca_obj_select.c +49 -34
  34. data/ext/ca_obj_select_axis.c +16 -6
  35. data/ext/ca_obj_shift.c +3 -3
  36. data/ext/ca_obj_stack.c +3 -8
  37. data/ext/ca_obj_stride.c +178 -24
  38. data/ext/ca_obj_string.c +11 -5
  39. data/ext/ca_obj_tile.c +13 -5
  40. data/ext/ca_obj_time.c +3 -1
  41. data/ext/ca_obj_timedelta.c +3 -1
  42. data/ext/ca_obj_transpose.c +1 -1
  43. data/ext/ca_obj_triop.c +62 -23
  44. data/ext/ca_obj_window.c +94 -19
  45. data/ext/ca_op_cmplx64.h +123 -0
  46. data/ext/ca_op_ipower.c +1 -5
  47. data/ext/ca_rng_normal.h +42 -0
  48. data/ext/ca_rng_xoshiro256pp.h +105 -0
  49. data/ext/ca_sort_kernels.h +5 -5
  50. data/ext/ca_sweep_engine.c +362 -155
  51. data/ext/ca_sweep_engine.h +39 -9
  52. data/ext/ca_transform_common.c +7 -0
  53. data/ext/carray.h +148 -132
  54. data/ext/carray_access.c +83 -49
  55. data/ext/carray_address_basis.c +590 -0
  56. data/ext/carray_bincount.c +8 -8
  57. data/ext/carray_broadcast.c +102 -9
  58. data/ext/carray_build_flags.h +3 -0
  59. data/ext/carray_call_cfunc.c +2010 -335
  60. data/ext/carray_call_cfunc.h +153 -0
  61. data/ext/carray_cast.c +184 -72
  62. data/ext/carray_conversion.c +22 -22
  63. data/ext/carray_copy.c +67 -32
  64. data/ext/carray_core.c +140 -13
  65. data/ext/carray_count.c +10 -11
  66. data/ext/carray_element.c +7 -7
  67. data/ext/carray_factorize.c +72 -51
  68. data/ext/carray_hold.c +1 -1
  69. data/ext/carray_index_classifier.c +7 -21
  70. data/ext/carray_internal.h +36 -3
  71. data/ext/carray_kernels_bincmp.c +1 -0
  72. data/ext/carray_kernels_binop.c +320 -298
  73. data/ext/carray_kernels_init.c +1095 -0
  74. data/ext/carray_kernels_map.c +1 -0
  75. data/ext/carray_kernels_moncmp.c +1 -0
  76. data/ext/carray_kernels_monop.c +412 -411
  77. data/ext/carray_kernels_reduce_aggregate.c +256 -87
  78. data/ext/carray_kernels_reduce_boolean.c +1 -0
  79. data/ext/carray_kernels_reduce_cumulative.c +324 -54
  80. data/ext/carray_kernels_reduce_extreme.c +605 -58
  81. data/ext/carray_kernels_reduce_variance.c +1 -0
  82. data/ext/carray_kernels_scan.c +5 -4
  83. data/ext/carray_kernels_search.c +187 -106
  84. data/ext/carray_kernels_sort.c +1 -0
  85. data/ext/carray_kernels_triop.c +1 -0
  86. data/ext/carray_lazy.c +175 -5
  87. data/ext/carray_loop.c +7 -1
  88. data/ext/carray_mask.c +29 -13
  89. data/ext/carray_median_percentile.c +56 -1
  90. data/ext/carray_memory_view.c +46 -21
  91. data/ext/carray_operator.c +50 -53
  92. data/ext/carray_order.c +1 -1
  93. data/ext/carray_partition.c +4 -4
  94. data/ext/carray_random.c +391 -47
  95. data/ext/carray_scatter.c +1 -1
  96. data/ext/carray_slab.c +13 -0
  97. data/ext/carray_sort.c +22 -24
  98. data/ext/carray_sort_kernel.c +10 -10
  99. data/ext/carray_test.c +1 -1
  100. data/ext/extconf.rb +18 -0
  101. data/ext/mk_call_cfunc.rb +323 -145
  102. data/ext/mkkernel.rb +651 -129
  103. data/ext/ruby_carray.c +28 -17
  104. data/ext/version.h +4 -4
  105. data/lib/carray/autoload_carray.rb +24 -3
  106. data/lib/carray/autoload_method_extension.rb +14 -1
  107. data/lib/carray/axis_group.rb +84 -7
  108. data/lib/carray/basics.rb +63 -59
  109. data/lib/carray/bincount_nd.rb +12 -12
  110. data/lib/carray/block_iterator.rb +111 -25
  111. data/lib/carray/categorical.rb +154 -37
  112. data/lib/carray/categorical_iterator.rb +300 -151
  113. data/lib/carray/conditional.rb +14 -14
  114. data/lib/carray/const_string.rb +131 -27
  115. data/lib/carray/construct.rb +61 -0
  116. data/lib/carray/core_extensions.rb +62 -5
  117. data/lib/carray/data_type_extension.rb +21 -1
  118. data/lib/carray/data_type_limits.rb +91 -0
  119. data/lib/carray/fixlen_string.rb +1 -1
  120. data/lib/carray/frame/concat.rb +3 -3
  121. data/lib/carray/frame/convert.rb +1 -1
  122. data/lib/carray/frame/csv_parser.rb +11 -4
  123. data/lib/carray/frame/frame.rb +85 -21
  124. data/lib/carray/frame/group.rb +36 -3
  125. data/lib/carray/frame/io.rb +224 -15
  126. data/lib/carray/frame/records.rb +18 -4
  127. data/lib/carray/frame/sort.rb +1 -1
  128. data/lib/carray/frame/verbs.rb +32 -12
  129. data/lib/carray/fuse_source.rb +123 -0
  130. data/lib/carray/fusion.rb +218 -0
  131. data/lib/carray/histogram.rb +16 -16
  132. data/lib/carray/inspect.rb +43 -16
  133. data/lib/carray/iterator.rb +147 -3
  134. data/lib/carray/lazy.rb +88 -73
  135. data/lib/carray/mask_gap_fill.rb +3 -1
  136. data/lib/carray/meld_reduce.rb +2 -2
  137. data/lib/carray/methods/align_addr.rb +1 -1
  138. data/lib/carray/methods/composition.rb +1 -1
  139. data/lib/carray/methods/discovery_along.rb +74 -0
  140. data/lib/carray/methods/factorize.rb +50 -0
  141. data/lib/carray/methods/is_in.rb +25 -14
  142. data/lib/carray/methods/locate_addr.rb +81 -3
  143. data/lib/carray/methods/mask_duplicates.rb +36 -2
  144. data/lib/carray/methods/meshgrid.rb +4 -5
  145. data/lib/carray/methods/mode.rb +2 -2
  146. data/lib/carray/methods/nunique.rb +23 -2
  147. data/lib/carray/methods/repeat.rb +110 -0
  148. data/lib/carray/methods/snap.rb +7 -2
  149. data/lib/carray/methods/unique.rb +44 -4
  150. data/lib/carray/methods/value_counts.rb +2 -2
  151. data/lib/carray/rng.rb +86 -0
  152. data/lib/carray/runtime.rb +0 -19
  153. data/lib/carray/slab_iterator.rb +77 -19
  154. data/lib/carray/string_operation_extension.rb +10 -6
  155. data/lib/carray/time.rb +906 -491
  156. data/lib/carray/window_iterator.rb +421 -27
  157. data/lib/carray.rb +7 -5
  158. data/yard-stubs/ca_obj_array.rb +385 -0
  159. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  160. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  161. data/yard-stubs/ca_obj_block.rb +68 -0
  162. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  163. data/yard-stubs/ca_obj_fake.rb +31 -0
  164. data/yard-stubs/ca_obj_farray.rb +32 -0
  165. data/yard-stubs/ca_obj_field.rb +45 -0
  166. data/yard-stubs/ca_obj_grid.rb +35 -0
  167. data/yard-stubs/ca_obj_refer.rb +72 -0
  168. data/yard-stubs/ca_obj_roll.rb +45 -0
  169. data/yard-stubs/ca_obj_shift.rb +43 -0
  170. data/yard-stubs/ca_obj_stride.rb +181 -0
  171. data/yard-stubs/ca_obj_tile.rb +29 -0
  172. data/yard-stubs/ca_obj_transpose.rb +40 -0
  173. data/yard-stubs/ca_obj_window.rb +57 -0
  174. data/yard-stubs/carray_access.rb +131 -0
  175. data/yard-stubs/carray_attribute.rb +246 -0
  176. data/yard-stubs/carray_broadcast.rb +37 -0
  177. data/yard-stubs/carray_cast.rb +489 -0
  178. data/yard-stubs/carray_class.rb +65 -0
  179. data/yard-stubs/carray_conversion.rb +76 -0
  180. data/yard-stubs/carray_copy.rb +79 -0
  181. data/yard-stubs/carray_core.rb +34 -0
  182. data/yard-stubs/carray_count.rb +84 -0
  183. data/yard-stubs/carray_element.rb +108 -0
  184. data/yard-stubs/carray_generate.rb +66 -0
  185. data/yard-stubs/carray_lazy.rb +228 -0
  186. data/yard-stubs/carray_loop.rb +140 -0
  187. data/yard-stubs/carray_mask.rb +259 -0
  188. data/yard-stubs/carray_math.rb +1615 -0
  189. data/yard-stubs/carray_mathfunc.rb +45 -0
  190. data/yard-stubs/carray_median_percentile.rb +103 -0
  191. data/yard-stubs/carray_memory_view.rb +163 -0
  192. data/yard-stubs/carray_order.rb +252 -0
  193. data/yard-stubs/carray_random.rb +89 -0
  194. data/yard-stubs/carray_scatter.rb +106 -0
  195. data/yard-stubs/carray_slab.rb +59 -0
  196. data/yard-stubs/carray_sort.rb +165 -0
  197. data/yard-stubs/carray_test.rb +85 -0
  198. data/yard-stubs/carray_undef.rb +64 -0
  199. data/yard-stubs/carray_utils.rb +97 -0
  200. data/yard-stubs/ruby_carray.rb +193 -0
  201. metadata +67 -10
  202. data/ext/ca_obj_unbound_repeat.c +0 -496
@@ -25,6 +25,18 @@
25
25
  * operand invariant established in PROPOSAL_EAGER_ELEMENTWISE_NO_ATTACH
26
26
  * and extended in PROPOSAL_EAGER_SLOWPATH_CHUNKING_ARENA).
27
27
  *
28
+ * Slab variants `ca_call_cslab_N` / `ca_call_cslab_N_r` take the chunked
29
+ * path instead (ca_sweep_acquire_chunked / ca_sweep_next_chunk /
30
+ * ca_sweep_release_chunked) and hand the callback a whole chunk -- base /
31
+ * stride per operand, a cell count, and the chunk's slice of the mask --
32
+ * rather than one cell. A non-alias INPUT is then re-gathered into a
33
+ * ~32KB arena scratch per chunk rather than materialised whole, so input
34
+ * memory peak stops scaling with the operand; and the indirect call is
35
+ * paid once per chunk, so the author's inner loop is one the compiler can
36
+ * vectorise. Use cfunc when the per-cell body is what you have (a math
37
+ * function to wrap); use cslab when the operand is large, virtual, or the
38
+ * body is worth vectorising.
39
+ *
28
40
  * L0.1 (PROPOSAL_L0_AUTHOR_SURFACE, 2026-06-11): the per-operand acquire
29
41
  * + broadcast check + mask OR + release lifecycle is now factored out
30
42
  * into ext/ca_sweep_engine.{c,h} (ca_sweep_acquire / ca_sweep_release). This
@@ -36,6 +48,80 @@
36
48
  #include "ca_sweep_engine.h"
37
49
  #include <string.h>
38
50
 
51
+ /* Chunk walk for the ca_call_cslab_N family, run by ca_sweep_run_chunked
52
+ so that a callback raising part way through gives back what the engine
53
+ holds. Hands the author one chunk at a time. base[] is rewritten per
54
+ chunk by ca_sweep_next_chunk -- for a non-alias INPUT it points at the
55
+ arena scratch the chunk was just gathered into, which is packed, so
56
+ stride[] is the element size and the author's inner loop sees
57
+ contiguous data. m0 is the chunk's iteration mask, or NULL when no
58
+ INPUT operand carried one: chunk-sized and re-gathered per chunk, so it
59
+ is already the slice -- one byte per cell, indexed 0..chunk_n-1
60
+ alongside base[] and stride[]. The arity does not appear here: the
61
+ operands reach the callback through base[] / stride[]. */
62
+ typedef struct {
63
+ ca_sweep_state_t *st;
64
+ ca_cslab_t func; /* ca_call_cslab_N */
65
+ ca_cslab_r_t func_r; /* ca_call_cslab_N_r */
66
+ void *userdata;
67
+ } ca_cslab_ctx_t;
68
+
69
+ static VALUE
70
+ ca_cslab_walk (VALUE arg)
71
+ {
72
+ ca_cslab_ctx_t *c = (ca_cslab_ctx_t *) arg;
73
+ ca_sweep_state_t *st = c->st;
74
+ while ( ca_sweep_next_chunk(st) ) {
75
+ c->func(st->base, st->stride, st->chunk_n, st->m0);
76
+ }
77
+ return Qnil;
78
+ }
79
+
80
+ static VALUE
81
+ ca_cslab_r_walk (VALUE arg)
82
+ {
83
+ ca_cslab_ctx_t *c = (ca_cslab_ctx_t *) arg;
84
+ ca_sweep_state_t *st = c->st;
85
+ while ( ca_sweep_next_chunk(st) ) {
86
+ c->func_r(st->base, st->stride, st->chunk_n, st->m0, c->userdata);
87
+ }
88
+ return Qnil;
89
+ }
90
+
91
+ typedef struct {
92
+ ca_sweep_state_t *st;
93
+ void (*func)(void *p0);
94
+ void *userdata;
95
+ } ca_call_cfunc_1_ctx_t;
96
+
97
+ static VALUE
98
+ ca_call_cfunc_1_walk (VALUE arg)
99
+ {
100
+ ca_call_cfunc_1_ctx_t *c = (ca_call_cfunc_1_ctx_t *) arg;
101
+ ca_sweep_state_t *st = c->st;
102
+ char *p[1];
103
+ ca_size_t k;
104
+ int k_op;
105
+ if ( st->m0 ) {
106
+ for ( k = 0; k < st->n_kernel; k++ ) {
107
+ if ( ! st->m0[k] ) {
108
+ for ( k_op = 0; k_op < 1; k_op++ ) {
109
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
110
+ }
111
+ c->func(p[0]);
112
+ }
113
+ }
114
+ } else {
115
+ for ( k = 0; k < st->n_kernel; k++ ) {
116
+ for ( k_op = 0; k_op < 1; k_op++ ) {
117
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
118
+ }
119
+ c->func(p[0]);
120
+ }
121
+ }
122
+ return Qnil;
123
+ }
124
+
39
125
  VALUE
40
126
  ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
41
127
  VALUE rcx0)
@@ -46,13 +132,13 @@ ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
46
132
  char *owned_buf[1];
47
133
  int attached[1];
48
134
  ca_sweep_state_t state;
49
- int k_op;
135
+ ca_call_cfunc_1_ctx_t ctx;
50
136
 
51
137
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
52
138
 
53
139
  /* 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}. */
140
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
141
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
56
142
  state.n_ops = 1;
57
143
  state.fsync = fsync;
58
144
  state.cx = cx;
@@ -65,32 +151,46 @@ ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
65
151
 
66
152
  ca_sweep_acquire(&state);
67
153
 
68
- /* inner loop: advance per-cell ptrs and invoke user kernel func */
69
- {
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]);
154
+ ctx.st = &state;
155
+ ctx.func = func;
156
+ ctx.userdata = NULL;
157
+ ca_sweep_run(&state, ca_call_cfunc_1_walk, (VALUE) &ctx);
158
+
159
+ return rcx0;
160
+ }
161
+
162
+ typedef struct {
163
+ ca_sweep_state_t *st;
164
+ void (*func)(void *p0, void *p1);
165
+ void *userdata;
166
+ } ca_call_cfunc_2_ctx_t;
167
+
168
+ static VALUE
169
+ ca_call_cfunc_2_walk (VALUE arg)
170
+ {
171
+ ca_call_cfunc_2_ctx_t *c = (ca_call_cfunc_2_ctx_t *) arg;
172
+ ca_sweep_state_t *st = c->st;
173
+ char *p[2];
174
+ ca_size_t k;
175
+ int k_op;
176
+ if ( st->m0 ) {
177
+ for ( k = 0; k < st->n_kernel; k++ ) {
178
+ if ( ! st->m0[k] ) {
179
+ for ( k_op = 0; k_op < 2; k_op++ ) {
180
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
79
181
  }
182
+ c->func(p[0], p[1]);
80
183
  }
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]);
184
+ }
185
+ } else {
186
+ for ( k = 0; k < st->n_kernel; k++ ) {
187
+ for ( k_op = 0; k_op < 2; k_op++ ) {
188
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
87
189
  }
190
+ c->func(p[0], p[1]);
88
191
  }
89
192
  }
90
-
91
- ca_sweep_release(&state);
92
-
93
- return rcx0;
193
+ return Qnil;
94
194
  }
95
195
 
96
196
  VALUE
@@ -103,14 +203,14 @@ ca_call_cfunc_2 (void (*func)(void *p0, void *p1), const char *fsync,
103
203
  char *owned_buf[2];
104
204
  int attached[2];
105
205
  ca_sweep_state_t state;
106
- int k_op;
206
+ ca_call_cfunc_2_ctx_t ctx;
107
207
 
108
208
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
109
209
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
110
210
 
111
211
  /* 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}. */
212
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
213
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
114
214
  state.n_ops = 2;
115
215
  state.fsync = fsync;
116
216
  state.cx = cx;
@@ -123,32 +223,46 @@ ca_call_cfunc_2 (void (*func)(void *p0, void *p1), const char *fsync,
123
223
 
124
224
  ca_sweep_acquire(&state);
125
225
 
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]);
226
+ ctx.st = &state;
227
+ ctx.func = func;
228
+ ctx.userdata = NULL;
229
+ ca_sweep_run(&state, ca_call_cfunc_2_walk, (VALUE) &ctx);
230
+
231
+ return rcx0;
232
+ }
233
+
234
+ typedef struct {
235
+ ca_sweep_state_t *st;
236
+ void (*func)(void *p0, void *p1, void *p2);
237
+ void *userdata;
238
+ } ca_call_cfunc_3_ctx_t;
239
+
240
+ static VALUE
241
+ ca_call_cfunc_3_walk (VALUE arg)
242
+ {
243
+ ca_call_cfunc_3_ctx_t *c = (ca_call_cfunc_3_ctx_t *) arg;
244
+ ca_sweep_state_t *st = c->st;
245
+ char *p[3];
246
+ ca_size_t k;
247
+ int k_op;
248
+ if ( st->m0 ) {
249
+ for ( k = 0; k < st->n_kernel; k++ ) {
250
+ if ( ! st->m0[k] ) {
251
+ for ( k_op = 0; k_op < 3; k_op++ ) {
252
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
137
253
  }
254
+ c->func(p[0], p[1], p[2]);
138
255
  }
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]);
256
+ }
257
+ } else {
258
+ for ( k = 0; k < st->n_kernel; k++ ) {
259
+ for ( k_op = 0; k_op < 3; k_op++ ) {
260
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
145
261
  }
262
+ c->func(p[0], p[1], p[2]);
146
263
  }
147
264
  }
148
-
149
- ca_sweep_release(&state);
150
-
151
- return rcx0;
265
+ return Qnil;
152
266
  }
153
267
 
154
268
  VALUE
@@ -161,15 +275,15 @@ ca_call_cfunc_3 (void (*func)(void *p0, void *p1, void *p2), const char *fsync,
161
275
  char *owned_buf[3];
162
276
  int attached[3];
163
277
  ca_sweep_state_t state;
164
- int k_op;
278
+ ca_call_cfunc_3_ctx_t ctx;
165
279
 
166
280
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
167
281
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
168
282
  TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
169
283
 
170
284
  /* 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}. */
285
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
286
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
173
287
  state.n_ops = 3;
174
288
  state.fsync = fsync;
175
289
  state.cx = cx;
@@ -182,32 +296,46 @@ ca_call_cfunc_3 (void (*func)(void *p0, void *p1, void *p2), const char *fsync,
182
296
 
183
297
  ca_sweep_acquire(&state);
184
298
 
185
- /* inner loop: advance per-cell ptrs and invoke user kernel func */
186
- {
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]);
299
+ ctx.st = &state;
300
+ ctx.func = func;
301
+ ctx.userdata = NULL;
302
+ ca_sweep_run(&state, ca_call_cfunc_3_walk, (VALUE) &ctx);
303
+
304
+ return rcx0;
305
+ }
306
+
307
+ typedef struct {
308
+ ca_sweep_state_t *st;
309
+ void (*func)(void *p0, void *p1, void *p2, void *p3);
310
+ void *userdata;
311
+ } ca_call_cfunc_4_ctx_t;
312
+
313
+ static VALUE
314
+ ca_call_cfunc_4_walk (VALUE arg)
315
+ {
316
+ ca_call_cfunc_4_ctx_t *c = (ca_call_cfunc_4_ctx_t *) arg;
317
+ ca_sweep_state_t *st = c->st;
318
+ char *p[4];
319
+ ca_size_t k;
320
+ int k_op;
321
+ if ( st->m0 ) {
322
+ for ( k = 0; k < st->n_kernel; k++ ) {
323
+ if ( ! st->m0[k] ) {
324
+ for ( k_op = 0; k_op < 4; k_op++ ) {
325
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
196
326
  }
327
+ c->func(p[0], p[1], p[2], p[3]);
197
328
  }
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]);
329
+ }
330
+ } else {
331
+ for ( k = 0; k < st->n_kernel; k++ ) {
332
+ for ( k_op = 0; k_op < 4; k_op++ ) {
333
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
204
334
  }
335
+ c->func(p[0], p[1], p[2], p[3]);
205
336
  }
206
337
  }
207
-
208
- ca_sweep_release(&state);
209
-
210
- return rcx0;
338
+ return Qnil;
211
339
  }
212
340
 
213
341
  VALUE
@@ -220,7 +348,7 @@ ca_call_cfunc_4 (void (*func)(void *p0, void *p1, void *p2, void *p3), const cha
220
348
  char *owned_buf[4];
221
349
  int attached[4];
222
350
  ca_sweep_state_t state;
223
- int k_op;
351
+ ca_call_cfunc_4_ctx_t ctx;
224
352
 
225
353
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
226
354
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -228,8 +356,8 @@ ca_call_cfunc_4 (void (*func)(void *p0, void *p1, void *p2, void *p3), const cha
228
356
  TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
229
357
 
230
358
  /* 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}. */
359
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
360
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
233
361
  state.n_ops = 4;
234
362
  state.fsync = fsync;
235
363
  state.cx = cx;
@@ -242,32 +370,46 @@ ca_call_cfunc_4 (void (*func)(void *p0, void *p1, void *p2, void *p3), const cha
242
370
 
243
371
  ca_sweep_acquire(&state);
244
372
 
245
- /* inner loop: advance per-cell ptrs and invoke user kernel func */
246
- {
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]);
373
+ ctx.st = &state;
374
+ ctx.func = func;
375
+ ctx.userdata = NULL;
376
+ ca_sweep_run(&state, ca_call_cfunc_4_walk, (VALUE) &ctx);
377
+
378
+ return rcx0;
379
+ }
380
+
381
+ typedef struct {
382
+ ca_sweep_state_t *st;
383
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4);
384
+ void *userdata;
385
+ } ca_call_cfunc_5_ctx_t;
386
+
387
+ static VALUE
388
+ ca_call_cfunc_5_walk (VALUE arg)
389
+ {
390
+ ca_call_cfunc_5_ctx_t *c = (ca_call_cfunc_5_ctx_t *) arg;
391
+ ca_sweep_state_t *st = c->st;
392
+ char *p[5];
393
+ ca_size_t k;
394
+ int k_op;
395
+ if ( st->m0 ) {
396
+ for ( k = 0; k < st->n_kernel; k++ ) {
397
+ if ( ! st->m0[k] ) {
398
+ for ( k_op = 0; k_op < 5; k_op++ ) {
399
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
256
400
  }
401
+ c->func(p[0], p[1], p[2], p[3], p[4]);
257
402
  }
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]);
403
+ }
404
+ } else {
405
+ for ( k = 0; k < st->n_kernel; k++ ) {
406
+ for ( k_op = 0; k_op < 5; k_op++ ) {
407
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
264
408
  }
409
+ c->func(p[0], p[1], p[2], p[3], p[4]);
265
410
  }
266
411
  }
267
-
268
- ca_sweep_release(&state);
269
-
270
- return rcx0;
412
+ return Qnil;
271
413
  }
272
414
 
273
415
  VALUE
@@ -280,7 +422,7 @@ ca_call_cfunc_5 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4),
280
422
  char *owned_buf[5];
281
423
  int attached[5];
282
424
  ca_sweep_state_t state;
283
- int k_op;
425
+ ca_call_cfunc_5_ctx_t ctx;
284
426
 
285
427
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
286
428
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -289,8 +431,8 @@ ca_call_cfunc_5 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4),
289
431
  TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
290
432
 
291
433
  /* 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}. */
434
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
435
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
294
436
  state.n_ops = 5;
295
437
  state.fsync = fsync;
296
438
  state.cx = cx;
@@ -303,32 +445,46 @@ ca_call_cfunc_5 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4),
303
445
 
304
446
  ca_sweep_acquire(&state);
305
447
 
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]);
448
+ ctx.st = &state;
449
+ ctx.func = func;
450
+ ctx.userdata = NULL;
451
+ ca_sweep_run(&state, ca_call_cfunc_5_walk, (VALUE) &ctx);
452
+
453
+ return rcx0;
454
+ }
455
+
456
+ typedef struct {
457
+ ca_sweep_state_t *st;
458
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5);
459
+ void *userdata;
460
+ } ca_call_cfunc_6_ctx_t;
461
+
462
+ static VALUE
463
+ ca_call_cfunc_6_walk (VALUE arg)
464
+ {
465
+ ca_call_cfunc_6_ctx_t *c = (ca_call_cfunc_6_ctx_t *) arg;
466
+ ca_sweep_state_t *st = c->st;
467
+ char *p[6];
468
+ ca_size_t k;
469
+ int k_op;
470
+ if ( st->m0 ) {
471
+ for ( k = 0; k < st->n_kernel; k++ ) {
472
+ if ( ! st->m0[k] ) {
473
+ for ( k_op = 0; k_op < 6; k_op++ ) {
474
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
317
475
  }
476
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5]);
318
477
  }
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]);
478
+ }
479
+ } else {
480
+ for ( k = 0; k < st->n_kernel; k++ ) {
481
+ for ( k_op = 0; k_op < 6; k_op++ ) {
482
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
325
483
  }
484
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5]);
326
485
  }
327
486
  }
328
-
329
- ca_sweep_release(&state);
330
-
331
- return rcx0;
487
+ return Qnil;
332
488
  }
333
489
 
334
490
  VALUE
@@ -341,7 +497,7 @@ ca_call_cfunc_6 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
341
497
  char *owned_buf[6];
342
498
  int attached[6];
343
499
  ca_sweep_state_t state;
344
- int k_op;
500
+ ca_call_cfunc_6_ctx_t ctx;
345
501
 
346
502
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
347
503
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -351,8 +507,8 @@ ca_call_cfunc_6 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
351
507
  TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
352
508
 
353
509
  /* 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}. */
510
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
511
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
356
512
  state.n_ops = 6;
357
513
  state.fsync = fsync;
358
514
  state.cx = cx;
@@ -365,32 +521,46 @@ ca_call_cfunc_6 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
365
521
 
366
522
  ca_sweep_acquire(&state);
367
523
 
368
- /* inner loop: advance per-cell ptrs and invoke user kernel func */
369
- {
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]);
524
+ ctx.st = &state;
525
+ ctx.func = func;
526
+ ctx.userdata = NULL;
527
+ ca_sweep_run(&state, ca_call_cfunc_6_walk, (VALUE) &ctx);
528
+
529
+ return rcx0;
530
+ }
531
+
532
+ typedef struct {
533
+ ca_sweep_state_t *st;
534
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6);
535
+ void *userdata;
536
+ } ca_call_cfunc_7_ctx_t;
537
+
538
+ static VALUE
539
+ ca_call_cfunc_7_walk (VALUE arg)
540
+ {
541
+ ca_call_cfunc_7_ctx_t *c = (ca_call_cfunc_7_ctx_t *) arg;
542
+ ca_sweep_state_t *st = c->st;
543
+ char *p[7];
544
+ ca_size_t k;
545
+ int k_op;
546
+ if ( st->m0 ) {
547
+ for ( k = 0; k < st->n_kernel; k++ ) {
548
+ if ( ! st->m0[k] ) {
549
+ for ( k_op = 0; k_op < 7; k_op++ ) {
550
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
379
551
  }
552
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
380
553
  }
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]);
554
+ }
555
+ } else {
556
+ for ( k = 0; k < st->n_kernel; k++ ) {
557
+ for ( k_op = 0; k_op < 7; k_op++ ) {
558
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
387
559
  }
560
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], p[6]);
388
561
  }
389
562
  }
390
-
391
- ca_sweep_release(&state);
392
-
393
- return rcx0;
563
+ return Qnil;
394
564
  }
395
565
 
396
566
  VALUE
@@ -403,7 +573,7 @@ ca_call_cfunc_7 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
403
573
  char *owned_buf[7];
404
574
  int attached[7];
405
575
  ca_sweep_state_t state;
406
- int k_op;
576
+ ca_call_cfunc_7_ctx_t ctx;
407
577
 
408
578
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
409
579
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -414,8 +584,8 @@ ca_call_cfunc_7 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
414
584
  TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
415
585
 
416
586
  /* 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}. */
587
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
588
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
419
589
  state.n_ops = 7;
420
590
  state.fsync = fsync;
421
591
  state.cx = cx;
@@ -428,30 +598,10 @@ ca_call_cfunc_7 (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4,
428
598
 
429
599
  ca_sweep_acquire(&state);
430
600
 
431
- /* inner loop: advance per-cell ptrs and invoke user kernel func */
432
- {
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]);
442
- }
443
- }
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]);
450
- }
451
- }
452
- }
453
-
454
- ca_sweep_release(&state);
601
+ ctx.st = &state;
602
+ ctx.func = func;
603
+ ctx.userdata = NULL;
604
+ ca_sweep_run(&state, ca_call_cfunc_7_walk, (VALUE) &ctx);
455
605
 
456
606
  return rcx0;
457
607
  }
@@ -845,6 +995,40 @@ ca_call_cfunc_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dt
845
995
  /* `void *userdata` parameter forwarded to every per-cell invocation. */
846
996
  /* -------------------------------------------------------------------- */
847
997
 
998
+ typedef struct {
999
+ ca_sweep_state_t *st;
1000
+ void (*func)(void *p0, void *userdata);
1001
+ void *userdata;
1002
+ } ca_call_cfunc_1_r_ctx_t;
1003
+
1004
+ static VALUE
1005
+ ca_call_cfunc_1_r_walk (VALUE arg)
1006
+ {
1007
+ ca_call_cfunc_1_r_ctx_t *c = (ca_call_cfunc_1_r_ctx_t *) arg;
1008
+ ca_sweep_state_t *st = c->st;
1009
+ char *p[1];
1010
+ ca_size_t k;
1011
+ int k_op;
1012
+ if ( st->m0 ) {
1013
+ for ( k = 0; k < st->n_kernel; k++ ) {
1014
+ if ( ! st->m0[k] ) {
1015
+ for ( k_op = 0; k_op < 1; k_op++ ) {
1016
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1017
+ }
1018
+ c->func(p[0], c->userdata);
1019
+ }
1020
+ }
1021
+ } else {
1022
+ for ( k = 0; k < st->n_kernel; k++ ) {
1023
+ for ( k_op = 0; k_op < 1; k_op++ ) {
1024
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1025
+ }
1026
+ c->func(p[0], c->userdata);
1027
+ }
1028
+ }
1029
+ return Qnil;
1030
+ }
1031
+
848
1032
  VALUE
849
1033
  ca_call_cfunc_1_r (void (*func)(void *p0, void *userdata), const char *fsync,
850
1034
  VALUE rcx0,
@@ -856,12 +1040,13 @@ ca_call_cfunc_1_r (void (*func)(void *p0, void *userdata), const char *fsync,
856
1040
  char *owned_buf[1];
857
1041
  int attached[1];
858
1042
  ca_sweep_state_t state;
859
- int k_op;
1043
+ ca_call_cfunc_1_r_ctx_t ctx;
860
1044
 
861
1045
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
862
1046
 
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. */
1047
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1048
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1049
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
865
1050
  state.n_ops = 1;
866
1051
  state.fsync = fsync;
867
1052
  state.cx = cx;
@@ -874,31 +1059,46 @@ ca_call_cfunc_1_r (void (*func)(void *p0, void *userdata), const char *fsync,
874
1059
 
875
1060
  ca_sweep_acquire(&state);
876
1061
 
877
- {
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);
1062
+ ctx.st = &state;
1063
+ ctx.func = func;
1064
+ ctx.userdata = userdata;
1065
+ ca_sweep_run(&state, ca_call_cfunc_1_r_walk, (VALUE) &ctx);
1066
+
1067
+ return rcx0;
1068
+ }
1069
+
1070
+ typedef struct {
1071
+ ca_sweep_state_t *st;
1072
+ void (*func)(void *p0, void *p1, void *userdata);
1073
+ void *userdata;
1074
+ } ca_call_cfunc_2_r_ctx_t;
1075
+
1076
+ static VALUE
1077
+ ca_call_cfunc_2_r_walk (VALUE arg)
1078
+ {
1079
+ ca_call_cfunc_2_r_ctx_t *c = (ca_call_cfunc_2_r_ctx_t *) arg;
1080
+ ca_sweep_state_t *st = c->st;
1081
+ char *p[2];
1082
+ ca_size_t k;
1083
+ int k_op;
1084
+ if ( st->m0 ) {
1085
+ for ( k = 0; k < st->n_kernel; k++ ) {
1086
+ if ( ! st->m0[k] ) {
1087
+ for ( k_op = 0; k_op < 2; k_op++ ) {
1088
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
887
1089
  }
1090
+ c->func(p[0], p[1], c->userdata);
888
1091
  }
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);
1092
+ }
1093
+ } else {
1094
+ for ( k = 0; k < st->n_kernel; k++ ) {
1095
+ for ( k_op = 0; k_op < 2; k_op++ ) {
1096
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
895
1097
  }
1098
+ c->func(p[0], p[1], c->userdata);
896
1099
  }
897
1100
  }
898
-
899
- ca_sweep_release(&state);
900
-
901
- return rcx0;
1101
+ return Qnil;
902
1102
  }
903
1103
 
904
1104
  VALUE
@@ -912,13 +1112,14 @@ ca_call_cfunc_2_r (void (*func)(void *p0, void *p1, void *userdata), const char
912
1112
  char *owned_buf[2];
913
1113
  int attached[2];
914
1114
  ca_sweep_state_t state;
915
- int k_op;
1115
+ ca_call_cfunc_2_r_ctx_t ctx;
916
1116
 
917
1117
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
918
1118
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
919
1119
 
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. */
1120
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1121
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1122
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
922
1123
  state.n_ops = 2;
923
1124
  state.fsync = fsync;
924
1125
  state.cx = cx;
@@ -931,31 +1132,46 @@ ca_call_cfunc_2_r (void (*func)(void *p0, void *p1, void *userdata), const char
931
1132
 
932
1133
  ca_sweep_acquire(&state);
933
1134
 
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);
1135
+ ctx.st = &state;
1136
+ ctx.func = func;
1137
+ ctx.userdata = userdata;
1138
+ ca_sweep_run(&state, ca_call_cfunc_2_r_walk, (VALUE) &ctx);
1139
+
1140
+ return rcx0;
1141
+ }
1142
+
1143
+ typedef struct {
1144
+ ca_sweep_state_t *st;
1145
+ void (*func)(void *p0, void *p1, void *p2, void *userdata);
1146
+ void *userdata;
1147
+ } ca_call_cfunc_3_r_ctx_t;
1148
+
1149
+ static VALUE
1150
+ ca_call_cfunc_3_r_walk (VALUE arg)
1151
+ {
1152
+ ca_call_cfunc_3_r_ctx_t *c = (ca_call_cfunc_3_r_ctx_t *) arg;
1153
+ ca_sweep_state_t *st = c->st;
1154
+ char *p[3];
1155
+ ca_size_t k;
1156
+ int k_op;
1157
+ if ( st->m0 ) {
1158
+ for ( k = 0; k < st->n_kernel; k++ ) {
1159
+ if ( ! st->m0[k] ) {
1160
+ for ( k_op = 0; k_op < 3; k_op++ ) {
1161
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
944
1162
  }
1163
+ c->func(p[0], p[1], p[2], c->userdata);
945
1164
  }
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);
1165
+ }
1166
+ } else {
1167
+ for ( k = 0; k < st->n_kernel; k++ ) {
1168
+ for ( k_op = 0; k_op < 3; k_op++ ) {
1169
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
952
1170
  }
1171
+ c->func(p[0], p[1], p[2], c->userdata);
953
1172
  }
954
1173
  }
955
-
956
- ca_sweep_release(&state);
957
-
958
- return rcx0;
1174
+ return Qnil;
959
1175
  }
960
1176
 
961
1177
  VALUE
@@ -969,14 +1185,15 @@ ca_call_cfunc_3_r (void (*func)(void *p0, void *p1, void *p2, void *userdata), c
969
1185
  char *owned_buf[3];
970
1186
  int attached[3];
971
1187
  ca_sweep_state_t state;
972
- int k_op;
1188
+ ca_call_cfunc_3_r_ctx_t ctx;
973
1189
 
974
1190
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
975
1191
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
976
1192
  TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
977
1193
 
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. */
1194
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1195
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1196
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
980
1197
  state.n_ops = 3;
981
1198
  state.fsync = fsync;
982
1199
  state.cx = cx;
@@ -989,31 +1206,46 @@ ca_call_cfunc_3_r (void (*func)(void *p0, void *p1, void *p2, void *userdata), c
989
1206
 
990
1207
  ca_sweep_acquire(&state);
991
1208
 
992
- {
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);
1209
+ ctx.st = &state;
1210
+ ctx.func = func;
1211
+ ctx.userdata = userdata;
1212
+ ca_sweep_run(&state, ca_call_cfunc_3_r_walk, (VALUE) &ctx);
1213
+
1214
+ return rcx0;
1215
+ }
1216
+
1217
+ typedef struct {
1218
+ ca_sweep_state_t *st;
1219
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *userdata);
1220
+ void *userdata;
1221
+ } ca_call_cfunc_4_r_ctx_t;
1222
+
1223
+ static VALUE
1224
+ ca_call_cfunc_4_r_walk (VALUE arg)
1225
+ {
1226
+ ca_call_cfunc_4_r_ctx_t *c = (ca_call_cfunc_4_r_ctx_t *) arg;
1227
+ ca_sweep_state_t *st = c->st;
1228
+ char *p[4];
1229
+ ca_size_t k;
1230
+ int k_op;
1231
+ if ( st->m0 ) {
1232
+ for ( k = 0; k < st->n_kernel; k++ ) {
1233
+ if ( ! st->m0[k] ) {
1234
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1235
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1002
1236
  }
1237
+ c->func(p[0], p[1], p[2], p[3], c->userdata);
1003
1238
  }
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);
1239
+ }
1240
+ } else {
1241
+ for ( k = 0; k < st->n_kernel; k++ ) {
1242
+ for ( k_op = 0; k_op < 4; k_op++ ) {
1243
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1010
1244
  }
1245
+ c->func(p[0], p[1], p[2], p[3], c->userdata);
1011
1246
  }
1012
1247
  }
1013
-
1014
- ca_sweep_release(&state);
1015
-
1016
- return rcx0;
1248
+ return Qnil;
1017
1249
  }
1018
1250
 
1019
1251
  VALUE
@@ -1027,15 +1259,16 @@ ca_call_cfunc_4_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *us
1027
1259
  char *owned_buf[4];
1028
1260
  int attached[4];
1029
1261
  ca_sweep_state_t state;
1030
- int k_op;
1262
+ ca_call_cfunc_4_r_ctx_t ctx;
1031
1263
 
1032
1264
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1033
1265
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1034
1266
  TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
1035
1267
  TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1036
1268
 
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. */
1269
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1270
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1271
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
1039
1272
  state.n_ops = 4;
1040
1273
  state.fsync = fsync;
1041
1274
  state.cx = cx;
@@ -1048,31 +1281,46 @@ ca_call_cfunc_4_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *us
1048
1281
 
1049
1282
  ca_sweep_acquire(&state);
1050
1283
 
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);
1284
+ ctx.st = &state;
1285
+ ctx.func = func;
1286
+ ctx.userdata = userdata;
1287
+ ca_sweep_run(&state, ca_call_cfunc_4_r_walk, (VALUE) &ctx);
1288
+
1289
+ return rcx0;
1290
+ }
1291
+
1292
+ typedef struct {
1293
+ ca_sweep_state_t *st;
1294
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *userdata);
1295
+ void *userdata;
1296
+ } ca_call_cfunc_5_r_ctx_t;
1297
+
1298
+ static VALUE
1299
+ ca_call_cfunc_5_r_walk (VALUE arg)
1300
+ {
1301
+ ca_call_cfunc_5_r_ctx_t *c = (ca_call_cfunc_5_r_ctx_t *) arg;
1302
+ ca_sweep_state_t *st = c->st;
1303
+ char *p[5];
1304
+ ca_size_t k;
1305
+ int k_op;
1306
+ if ( st->m0 ) {
1307
+ for ( k = 0; k < st->n_kernel; k++ ) {
1308
+ if ( ! st->m0[k] ) {
1309
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1310
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1061
1311
  }
1312
+ c->func(p[0], p[1], p[2], p[3], p[4], c->userdata);
1062
1313
  }
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);
1314
+ }
1315
+ } else {
1316
+ for ( k = 0; k < st->n_kernel; k++ ) {
1317
+ for ( k_op = 0; k_op < 5; k_op++ ) {
1318
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1069
1319
  }
1320
+ c->func(p[0], p[1], p[2], p[3], p[4], c->userdata);
1070
1321
  }
1071
1322
  }
1072
-
1073
- ca_sweep_release(&state);
1074
-
1075
- return rcx0;
1323
+ return Qnil;
1076
1324
  }
1077
1325
 
1078
1326
  VALUE
@@ -1086,7 +1334,7 @@ ca_call_cfunc_5_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1086
1334
  char *owned_buf[5];
1087
1335
  int attached[5];
1088
1336
  ca_sweep_state_t state;
1089
- int k_op;
1337
+ ca_call_cfunc_5_r_ctx_t ctx;
1090
1338
 
1091
1339
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1092
1340
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -1094,8 +1342,9 @@ ca_call_cfunc_5_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1094
1342
  TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
1095
1343
  TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1096
1344
 
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. */
1345
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1346
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1347
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
1099
1348
  state.n_ops = 5;
1100
1349
  state.fsync = fsync;
1101
1350
  state.cx = cx;
@@ -1108,31 +1357,46 @@ ca_call_cfunc_5_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1108
1357
 
1109
1358
  ca_sweep_acquire(&state);
1110
1359
 
1111
- {
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);
1360
+ ctx.st = &state;
1361
+ ctx.func = func;
1362
+ ctx.userdata = userdata;
1363
+ ca_sweep_run(&state, ca_call_cfunc_5_r_walk, (VALUE) &ctx);
1364
+
1365
+ return rcx0;
1366
+ }
1367
+
1368
+ typedef struct {
1369
+ ca_sweep_state_t *st;
1370
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *userdata);
1371
+ void *userdata;
1372
+ } ca_call_cfunc_6_r_ctx_t;
1373
+
1374
+ static VALUE
1375
+ ca_call_cfunc_6_r_walk (VALUE arg)
1376
+ {
1377
+ ca_call_cfunc_6_r_ctx_t *c = (ca_call_cfunc_6_r_ctx_t *) arg;
1378
+ ca_sweep_state_t *st = c->st;
1379
+ char *p[6];
1380
+ ca_size_t k;
1381
+ int k_op;
1382
+ if ( st->m0 ) {
1383
+ for ( k = 0; k < st->n_kernel; k++ ) {
1384
+ if ( ! st->m0[k] ) {
1385
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1386
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1121
1387
  }
1388
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], c->userdata);
1122
1389
  }
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);
1390
+ }
1391
+ } else {
1392
+ for ( k = 0; k < st->n_kernel; k++ ) {
1393
+ for ( k_op = 0; k_op < 6; k_op++ ) {
1394
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1129
1395
  }
1396
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], c->userdata);
1130
1397
  }
1131
1398
  }
1132
-
1133
- ca_sweep_release(&state);
1134
-
1135
- return rcx0;
1399
+ return Qnil;
1136
1400
  }
1137
1401
 
1138
1402
  VALUE
@@ -1146,7 +1410,7 @@ ca_call_cfunc_6_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1146
1410
  char *owned_buf[6];
1147
1411
  int attached[6];
1148
1412
  ca_sweep_state_t state;
1149
- int k_op;
1413
+ ca_call_cfunc_6_r_ctx_t ctx;
1150
1414
 
1151
1415
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1152
1416
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -1155,8 +1419,9 @@ ca_call_cfunc_6_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1155
1419
  TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
1156
1420
  TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1157
1421
 
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. */
1422
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1423
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1424
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
1160
1425
  state.n_ops = 6;
1161
1426
  state.fsync = fsync;
1162
1427
  state.cx = cx;
@@ -1169,31 +1434,46 @@ ca_call_cfunc_6_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1169
1434
 
1170
1435
  ca_sweep_acquire(&state);
1171
1436
 
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);
1437
+ ctx.st = &state;
1438
+ ctx.func = func;
1439
+ ctx.userdata = userdata;
1440
+ ca_sweep_run(&state, ca_call_cfunc_6_r_walk, (VALUE) &ctx);
1441
+
1442
+ return rcx0;
1443
+ }
1444
+
1445
+ typedef struct {
1446
+ ca_sweep_state_t *st;
1447
+ void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4, void *p5, void *p6, void *userdata);
1448
+ void *userdata;
1449
+ } ca_call_cfunc_7_r_ctx_t;
1450
+
1451
+ static VALUE
1452
+ ca_call_cfunc_7_r_walk (VALUE arg)
1453
+ {
1454
+ ca_call_cfunc_7_r_ctx_t *c = (ca_call_cfunc_7_r_ctx_t *) arg;
1455
+ ca_sweep_state_t *st = c->st;
1456
+ char *p[7];
1457
+ ca_size_t k;
1458
+ int k_op;
1459
+ if ( st->m0 ) {
1460
+ for ( k = 0; k < st->n_kernel; k++ ) {
1461
+ if ( ! st->m0[k] ) {
1462
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1463
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1182
1464
  }
1465
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], c->userdata);
1183
1466
  }
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);
1467
+ }
1468
+ } else {
1469
+ for ( k = 0; k < st->n_kernel; k++ ) {
1470
+ for ( k_op = 0; k_op < 7; k_op++ ) {
1471
+ p[k_op] = st->base[k_op] + k * st->stride[k_op];
1190
1472
  }
1473
+ c->func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], c->userdata);
1191
1474
  }
1192
1475
  }
1193
-
1194
- ca_sweep_release(&state);
1195
-
1196
- return rcx0;
1476
+ return Qnil;
1197
1477
  }
1198
1478
 
1199
1479
  VALUE
@@ -1207,7 +1487,7 @@ ca_call_cfunc_7_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1207
1487
  char *owned_buf[7];
1208
1488
  int attached[7];
1209
1489
  ca_sweep_state_t state;
1210
- int k_op;
1490
+ ca_call_cfunc_7_r_ctx_t ctx;
1211
1491
 
1212
1492
  TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1213
1493
  TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
@@ -1217,8 +1497,9 @@ ca_call_cfunc_7_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1217
1497
  TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
1218
1498
  TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
1219
1499
 
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. */
1500
+ /* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
1501
+ operand pairing, mask OR across INPUTs, mask propagate to OUTPUTs.
1502
+ Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
1222
1503
  state.n_ops = 7;
1223
1504
  state.fsync = fsync;
1224
1505
  state.cx = cx;
@@ -1231,29 +1512,10 @@ ca_call_cfunc_7_r (void (*func)(void *p0, void *p1, void *p2, void *p3, void *p4
1231
1512
 
1232
1513
  ca_sweep_acquire(&state);
1233
1514
 
1234
- {
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);
1244
- }
1245
- }
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);
1252
- }
1253
- }
1254
- }
1255
-
1256
- ca_sweep_release(&state);
1515
+ ctx.st = &state;
1516
+ ctx.func = func;
1517
+ ctx.userdata = userdata;
1518
+ ca_sweep_run(&state, ca_call_cfunc_7_r_walk, (VALUE) &ctx);
1257
1519
 
1258
1520
  return rcx0;
1259
1521
  }
@@ -1635,3 +1897,1416 @@ ca_call_cfunc_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t
1635
1897
  return rb_ary_new3(3, ry1, ry2, ry3);
1636
1898
  }
1637
1899
 
1900
+ /* -------------------------------------------------------------------- */
1901
+ /* Slab variants: the chunked counterpart of ca_call_cfunc_N. The */
1902
+ /* callback is handed a whole chunk (base / stride / count / mask */
1903
+ /* slice) rather than one cell, and non-alias INPUTs are gathered */
1904
+ /* into a ~32KB arena scratch per chunk instead of materialised */
1905
+ /* whole, so input memory peak stops scaling with the operand. */
1906
+ /* -------------------------------------------------------------------- */
1907
+
1908
+ VALUE
1909
+ ca_call_cslab_1 (ca_cslab_t func, const char *fsync,
1910
+ VALUE rcx0)
1911
+ {
1912
+ CArray *cx[1];
1913
+ char *base[1];
1914
+ char *base_orig[1];
1915
+ ca_size_t stride[1];
1916
+ char *owned_buf[1];
1917
+ int attached[1];
1918
+ ca_sweep_state_t state;
1919
+ ca_cslab_ctx_t ctx;
1920
+
1921
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1922
+
1923
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1924
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1925
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1926
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1927
+ base_orig is the field the whole-buffer path leaves zero; the
1928
+ chunked path walks it, so it has to be given here. */
1929
+ state.n_ops = 1;
1930
+ state.fsync = fsync;
1931
+ state.cx = cx;
1932
+ state.base = base;
1933
+ state.base_orig = base_orig;
1934
+ state.stride = stride;
1935
+ state.owned_buf = owned_buf;
1936
+ state.attached = attached;
1937
+ state.no_mask = 0;
1938
+ state.src_label = "ca_call_cslab_1";
1939
+
1940
+ ca_sweep_acquire_chunked(&state);
1941
+
1942
+ ctx.st = &state;
1943
+ ctx.func = func;
1944
+ ctx.func_r = NULL;
1945
+ ctx.userdata = NULL;
1946
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
1947
+
1948
+ return rcx0;
1949
+ }
1950
+
1951
+ VALUE
1952
+ ca_call_cslab_2 (ca_cslab_t func, const char *fsync,
1953
+ VALUE rcx0, VALUE rcx1)
1954
+ {
1955
+ CArray *cx[2];
1956
+ char *base[2];
1957
+ char *base_orig[2];
1958
+ ca_size_t stride[2];
1959
+ char *owned_buf[2];
1960
+ int attached[2];
1961
+ ca_sweep_state_t state;
1962
+ ca_cslab_ctx_t ctx;
1963
+
1964
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
1965
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
1966
+
1967
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
1968
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
1969
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
1970
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
1971
+ base_orig is the field the whole-buffer path leaves zero; the
1972
+ chunked path walks it, so it has to be given here. */
1973
+ state.n_ops = 2;
1974
+ state.fsync = fsync;
1975
+ state.cx = cx;
1976
+ state.base = base;
1977
+ state.base_orig = base_orig;
1978
+ state.stride = stride;
1979
+ state.owned_buf = owned_buf;
1980
+ state.attached = attached;
1981
+ state.no_mask = 0;
1982
+ state.src_label = "ca_call_cslab_2";
1983
+
1984
+ ca_sweep_acquire_chunked(&state);
1985
+
1986
+ ctx.st = &state;
1987
+ ctx.func = func;
1988
+ ctx.func_r = NULL;
1989
+ ctx.userdata = NULL;
1990
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
1991
+
1992
+ return rcx0;
1993
+ }
1994
+
1995
+ VALUE
1996
+ ca_call_cslab_3 (ca_cslab_t func, const char *fsync,
1997
+ VALUE rcx0, VALUE rcx1, VALUE rcx2)
1998
+ {
1999
+ CArray *cx[3];
2000
+ char *base[3];
2001
+ char *base_orig[3];
2002
+ ca_size_t stride[3];
2003
+ char *owned_buf[3];
2004
+ int attached[3];
2005
+ ca_sweep_state_t state;
2006
+ ca_cslab_ctx_t ctx;
2007
+
2008
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2009
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2010
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2011
+
2012
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2013
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2014
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2015
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2016
+ base_orig is the field the whole-buffer path leaves zero; the
2017
+ chunked path walks it, so it has to be given here. */
2018
+ state.n_ops = 3;
2019
+ state.fsync = fsync;
2020
+ state.cx = cx;
2021
+ state.base = base;
2022
+ state.base_orig = base_orig;
2023
+ state.stride = stride;
2024
+ state.owned_buf = owned_buf;
2025
+ state.attached = attached;
2026
+ state.no_mask = 0;
2027
+ state.src_label = "ca_call_cslab_3";
2028
+
2029
+ ca_sweep_acquire_chunked(&state);
2030
+
2031
+ ctx.st = &state;
2032
+ ctx.func = func;
2033
+ ctx.func_r = NULL;
2034
+ ctx.userdata = NULL;
2035
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
2036
+
2037
+ return rcx0;
2038
+ }
2039
+
2040
+ VALUE
2041
+ ca_call_cslab_4 (ca_cslab_t func, const char *fsync,
2042
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3)
2043
+ {
2044
+ CArray *cx[4];
2045
+ char *base[4];
2046
+ char *base_orig[4];
2047
+ ca_size_t stride[4];
2048
+ char *owned_buf[4];
2049
+ int attached[4];
2050
+ ca_sweep_state_t state;
2051
+ ca_cslab_ctx_t ctx;
2052
+
2053
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2054
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2055
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2056
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2057
+
2058
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2059
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2060
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2061
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2062
+ base_orig is the field the whole-buffer path leaves zero; the
2063
+ chunked path walks it, so it has to be given here. */
2064
+ state.n_ops = 4;
2065
+ state.fsync = fsync;
2066
+ state.cx = cx;
2067
+ state.base = base;
2068
+ state.base_orig = base_orig;
2069
+ state.stride = stride;
2070
+ state.owned_buf = owned_buf;
2071
+ state.attached = attached;
2072
+ state.no_mask = 0;
2073
+ state.src_label = "ca_call_cslab_4";
2074
+
2075
+ ca_sweep_acquire_chunked(&state);
2076
+
2077
+ ctx.st = &state;
2078
+ ctx.func = func;
2079
+ ctx.func_r = NULL;
2080
+ ctx.userdata = NULL;
2081
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
2082
+
2083
+ return rcx0;
2084
+ }
2085
+
2086
+ VALUE
2087
+ ca_call_cslab_5 (ca_cslab_t func, const char *fsync,
2088
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4)
2089
+ {
2090
+ CArray *cx[5];
2091
+ char *base[5];
2092
+ char *base_orig[5];
2093
+ ca_size_t stride[5];
2094
+ char *owned_buf[5];
2095
+ int attached[5];
2096
+ ca_sweep_state_t state;
2097
+ ca_cslab_ctx_t ctx;
2098
+
2099
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2100
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2101
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2102
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2103
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2104
+
2105
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2106
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2107
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2108
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2109
+ base_orig is the field the whole-buffer path leaves zero; the
2110
+ chunked path walks it, so it has to be given here. */
2111
+ state.n_ops = 5;
2112
+ state.fsync = fsync;
2113
+ state.cx = cx;
2114
+ state.base = base;
2115
+ state.base_orig = base_orig;
2116
+ state.stride = stride;
2117
+ state.owned_buf = owned_buf;
2118
+ state.attached = attached;
2119
+ state.no_mask = 0;
2120
+ state.src_label = "ca_call_cslab_5";
2121
+
2122
+ ca_sweep_acquire_chunked(&state);
2123
+
2124
+ ctx.st = &state;
2125
+ ctx.func = func;
2126
+ ctx.func_r = NULL;
2127
+ ctx.userdata = NULL;
2128
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
2129
+
2130
+ return rcx0;
2131
+ }
2132
+
2133
+ VALUE
2134
+ ca_call_cslab_6 (ca_cslab_t func, const char *fsync,
2135
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5)
2136
+ {
2137
+ CArray *cx[6];
2138
+ char *base[6];
2139
+ char *base_orig[6];
2140
+ ca_size_t stride[6];
2141
+ char *owned_buf[6];
2142
+ int attached[6];
2143
+ ca_sweep_state_t state;
2144
+ ca_cslab_ctx_t ctx;
2145
+
2146
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2147
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2148
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2149
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2150
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2151
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2152
+
2153
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2154
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2155
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2156
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2157
+ base_orig is the field the whole-buffer path leaves zero; the
2158
+ chunked path walks it, so it has to be given here. */
2159
+ state.n_ops = 6;
2160
+ state.fsync = fsync;
2161
+ state.cx = cx;
2162
+ state.base = base;
2163
+ state.base_orig = base_orig;
2164
+ state.stride = stride;
2165
+ state.owned_buf = owned_buf;
2166
+ state.attached = attached;
2167
+ state.no_mask = 0;
2168
+ state.src_label = "ca_call_cslab_6";
2169
+
2170
+ ca_sweep_acquire_chunked(&state);
2171
+
2172
+ ctx.st = &state;
2173
+ ctx.func = func;
2174
+ ctx.func_r = NULL;
2175
+ ctx.userdata = NULL;
2176
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
2177
+
2178
+ return rcx0;
2179
+ }
2180
+
2181
+ VALUE
2182
+ ca_call_cslab_7 (ca_cslab_t func, const char *fsync,
2183
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6)
2184
+ {
2185
+ CArray *cx[7];
2186
+ char *base[7];
2187
+ char *base_orig[7];
2188
+ ca_size_t stride[7];
2189
+ char *owned_buf[7];
2190
+ int attached[7];
2191
+ ca_sweep_state_t state;
2192
+ ca_cslab_ctx_t ctx;
2193
+
2194
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2195
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2196
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2197
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2198
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2199
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2200
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
2201
+
2202
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2203
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2204
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2205
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2206
+ base_orig is the field the whole-buffer path leaves zero; the
2207
+ chunked path walks it, so it has to be given here. */
2208
+ state.n_ops = 7;
2209
+ state.fsync = fsync;
2210
+ state.cx = cx;
2211
+ state.base = base;
2212
+ state.base_orig = base_orig;
2213
+ state.stride = stride;
2214
+ state.owned_buf = owned_buf;
2215
+ state.attached = attached;
2216
+ state.no_mask = 0;
2217
+ state.src_label = "ca_call_cslab_7";
2218
+
2219
+ ca_sweep_acquire_chunked(&state);
2220
+
2221
+ ctx.st = &state;
2222
+ ctx.func = func;
2223
+ ctx.func_r = NULL;
2224
+ ctx.userdata = NULL;
2225
+ ca_sweep_run_chunked(&state, ca_cslab_walk, (VALUE) &ctx);
2226
+
2227
+ return rcx0;
2228
+ }
2229
+
2230
+ VALUE
2231
+ ca_call_cslab_1_r (ca_cslab_r_t func, const char *fsync,
2232
+ VALUE rcx0,
2233
+ void *userdata)
2234
+ {
2235
+ CArray *cx[1];
2236
+ char *base[1];
2237
+ char *base_orig[1];
2238
+ ca_size_t stride[1];
2239
+ char *owned_buf[1];
2240
+ int attached[1];
2241
+ ca_sweep_state_t state;
2242
+ ca_cslab_ctx_t ctx;
2243
+
2244
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2245
+
2246
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2247
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2248
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2249
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2250
+ base_orig is the field the whole-buffer path leaves zero; the
2251
+ chunked path walks it, so it has to be given here. */
2252
+ state.n_ops = 1;
2253
+ state.fsync = fsync;
2254
+ state.cx = cx;
2255
+ state.base = base;
2256
+ state.base_orig = base_orig;
2257
+ state.stride = stride;
2258
+ state.owned_buf = owned_buf;
2259
+ state.attached = attached;
2260
+ state.no_mask = 0;
2261
+ state.src_label = "ca_call_cslab_1_r";
2262
+
2263
+ ca_sweep_acquire_chunked(&state);
2264
+
2265
+ ctx.st = &state;
2266
+ ctx.func = NULL;
2267
+ ctx.func_r = func;
2268
+ ctx.userdata = userdata;
2269
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2270
+
2271
+ return rcx0;
2272
+ }
2273
+
2274
+ VALUE
2275
+ ca_call_cslab_2_r (ca_cslab_r_t func, const char *fsync,
2276
+ VALUE rcx0, VALUE rcx1,
2277
+ void *userdata)
2278
+ {
2279
+ CArray *cx[2];
2280
+ char *base[2];
2281
+ char *base_orig[2];
2282
+ ca_size_t stride[2];
2283
+ char *owned_buf[2];
2284
+ int attached[2];
2285
+ ca_sweep_state_t state;
2286
+ ca_cslab_ctx_t ctx;
2287
+
2288
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2289
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2290
+
2291
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2292
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2293
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2294
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2295
+ base_orig is the field the whole-buffer path leaves zero; the
2296
+ chunked path walks it, so it has to be given here. */
2297
+ state.n_ops = 2;
2298
+ state.fsync = fsync;
2299
+ state.cx = cx;
2300
+ state.base = base;
2301
+ state.base_orig = base_orig;
2302
+ state.stride = stride;
2303
+ state.owned_buf = owned_buf;
2304
+ state.attached = attached;
2305
+ state.no_mask = 0;
2306
+ state.src_label = "ca_call_cslab_2_r";
2307
+
2308
+ ca_sweep_acquire_chunked(&state);
2309
+
2310
+ ctx.st = &state;
2311
+ ctx.func = NULL;
2312
+ ctx.func_r = func;
2313
+ ctx.userdata = userdata;
2314
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2315
+
2316
+ return rcx0;
2317
+ }
2318
+
2319
+ VALUE
2320
+ ca_call_cslab_3_r (ca_cslab_r_t func, const char *fsync,
2321
+ VALUE rcx0, VALUE rcx1, VALUE rcx2,
2322
+ void *userdata)
2323
+ {
2324
+ CArray *cx[3];
2325
+ char *base[3];
2326
+ char *base_orig[3];
2327
+ ca_size_t stride[3];
2328
+ char *owned_buf[3];
2329
+ int attached[3];
2330
+ ca_sweep_state_t state;
2331
+ ca_cslab_ctx_t ctx;
2332
+
2333
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2334
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2335
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2336
+
2337
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2338
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2339
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2340
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2341
+ base_orig is the field the whole-buffer path leaves zero; the
2342
+ chunked path walks it, so it has to be given here. */
2343
+ state.n_ops = 3;
2344
+ state.fsync = fsync;
2345
+ state.cx = cx;
2346
+ state.base = base;
2347
+ state.base_orig = base_orig;
2348
+ state.stride = stride;
2349
+ state.owned_buf = owned_buf;
2350
+ state.attached = attached;
2351
+ state.no_mask = 0;
2352
+ state.src_label = "ca_call_cslab_3_r";
2353
+
2354
+ ca_sweep_acquire_chunked(&state);
2355
+
2356
+ ctx.st = &state;
2357
+ ctx.func = NULL;
2358
+ ctx.func_r = func;
2359
+ ctx.userdata = userdata;
2360
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2361
+
2362
+ return rcx0;
2363
+ }
2364
+
2365
+ VALUE
2366
+ ca_call_cslab_4_r (ca_cslab_r_t func, const char *fsync,
2367
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
2368
+ void *userdata)
2369
+ {
2370
+ CArray *cx[4];
2371
+ char *base[4];
2372
+ char *base_orig[4];
2373
+ ca_size_t stride[4];
2374
+ char *owned_buf[4];
2375
+ int attached[4];
2376
+ ca_sweep_state_t state;
2377
+ ca_cslab_ctx_t ctx;
2378
+
2379
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2380
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2381
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2382
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2383
+
2384
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2385
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2386
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2387
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2388
+ base_orig is the field the whole-buffer path leaves zero; the
2389
+ chunked path walks it, so it has to be given here. */
2390
+ state.n_ops = 4;
2391
+ state.fsync = fsync;
2392
+ state.cx = cx;
2393
+ state.base = base;
2394
+ state.base_orig = base_orig;
2395
+ state.stride = stride;
2396
+ state.owned_buf = owned_buf;
2397
+ state.attached = attached;
2398
+ state.no_mask = 0;
2399
+ state.src_label = "ca_call_cslab_4_r";
2400
+
2401
+ ca_sweep_acquire_chunked(&state);
2402
+
2403
+ ctx.st = &state;
2404
+ ctx.func = NULL;
2405
+ ctx.func_r = func;
2406
+ ctx.userdata = userdata;
2407
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2408
+
2409
+ return rcx0;
2410
+ }
2411
+
2412
+ VALUE
2413
+ ca_call_cslab_5_r (ca_cslab_r_t func, const char *fsync,
2414
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
2415
+ void *userdata)
2416
+ {
2417
+ CArray *cx[5];
2418
+ char *base[5];
2419
+ char *base_orig[5];
2420
+ ca_size_t stride[5];
2421
+ char *owned_buf[5];
2422
+ int attached[5];
2423
+ ca_sweep_state_t state;
2424
+ ca_cslab_ctx_t ctx;
2425
+
2426
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2427
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2428
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2429
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2430
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2431
+
2432
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2433
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2434
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2435
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2436
+ base_orig is the field the whole-buffer path leaves zero; the
2437
+ chunked path walks it, so it has to be given here. */
2438
+ state.n_ops = 5;
2439
+ state.fsync = fsync;
2440
+ state.cx = cx;
2441
+ state.base = base;
2442
+ state.base_orig = base_orig;
2443
+ state.stride = stride;
2444
+ state.owned_buf = owned_buf;
2445
+ state.attached = attached;
2446
+ state.no_mask = 0;
2447
+ state.src_label = "ca_call_cslab_5_r";
2448
+
2449
+ ca_sweep_acquire_chunked(&state);
2450
+
2451
+ ctx.st = &state;
2452
+ ctx.func = NULL;
2453
+ ctx.func_r = func;
2454
+ ctx.userdata = userdata;
2455
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2456
+
2457
+ return rcx0;
2458
+ }
2459
+
2460
+ VALUE
2461
+ ca_call_cslab_6_r (ca_cslab_r_t func, const char *fsync,
2462
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
2463
+ void *userdata)
2464
+ {
2465
+ CArray *cx[6];
2466
+ char *base[6];
2467
+ char *base_orig[6];
2468
+ ca_size_t stride[6];
2469
+ char *owned_buf[6];
2470
+ int attached[6];
2471
+ ca_sweep_state_t state;
2472
+ ca_cslab_ctx_t ctx;
2473
+
2474
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2475
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2476
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2477
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2478
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2479
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2480
+
2481
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2482
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2483
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2484
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2485
+ base_orig is the field the whole-buffer path leaves zero; the
2486
+ chunked path walks it, so it has to be given here. */
2487
+ state.n_ops = 6;
2488
+ state.fsync = fsync;
2489
+ state.cx = cx;
2490
+ state.base = base;
2491
+ state.base_orig = base_orig;
2492
+ state.stride = stride;
2493
+ state.owned_buf = owned_buf;
2494
+ state.attached = attached;
2495
+ state.no_mask = 0;
2496
+ state.src_label = "ca_call_cslab_6_r";
2497
+
2498
+ ca_sweep_acquire_chunked(&state);
2499
+
2500
+ ctx.st = &state;
2501
+ ctx.func = NULL;
2502
+ ctx.func_r = func;
2503
+ ctx.userdata = userdata;
2504
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2505
+
2506
+ return rcx0;
2507
+ }
2508
+
2509
+ VALUE
2510
+ ca_call_cslab_7_r (ca_cslab_r_t func, const char *fsync,
2511
+ VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
2512
+ void *userdata)
2513
+ {
2514
+ CArray *cx[7];
2515
+ char *base[7];
2516
+ char *base_orig[7];
2517
+ ca_size_t stride[7];
2518
+ char *owned_buf[7];
2519
+ int attached[7];
2520
+ ca_sweep_state_t state;
2521
+ ca_cslab_ctx_t ctx;
2522
+
2523
+ TypedData_Get_Struct(rcx0, CArray, &carray_data_type, cx[0]);
2524
+ TypedData_Get_Struct(rcx1, CArray, &carray_data_type, cx[1]);
2525
+ TypedData_Get_Struct(rcx2, CArray, &carray_data_type, cx[2]);
2526
+ TypedData_Get_Struct(rcx3, CArray, &carray_data_type, cx[3]);
2527
+ TypedData_Get_Struct(rcx4, CArray, &carray_data_type, cx[4]);
2528
+ TypedData_Get_Struct(rcx5, CArray, &carray_data_type, cx[5]);
2529
+ TypedData_Get_Struct(rcx6, CArray, &carray_data_type, cx[6]);
2530
+
2531
+ /* sweep engine, chunked path: per-operand acquire (attach for OUTPUT
2532
+ and alias INPUT, arena chunk scratch for non-alias INPUT), broadcast
2533
+ shape check, mask OR across INPUTs, mask propagate to OUTPUTs at
2534
+ release. Lifecycle template lives in ext/ca_sweep_engine.{c,h}.
2535
+ base_orig is the field the whole-buffer path leaves zero; the
2536
+ chunked path walks it, so it has to be given here. */
2537
+ state.n_ops = 7;
2538
+ state.fsync = fsync;
2539
+ state.cx = cx;
2540
+ state.base = base;
2541
+ state.base_orig = base_orig;
2542
+ state.stride = stride;
2543
+ state.owned_buf = owned_buf;
2544
+ state.attached = attached;
2545
+ state.no_mask = 0;
2546
+ state.src_label = "ca_call_cslab_7_r";
2547
+
2548
+ ca_sweep_acquire_chunked(&state);
2549
+
2550
+ ctx.st = &state;
2551
+ ctx.func = NULL;
2552
+ ctx.func_r = func;
2553
+ ctx.userdata = userdata;
2554
+ ca_sweep_run_chunked(&state, ca_cslab_r_walk, (VALUE) &ctx);
2555
+
2556
+ return rcx0;
2557
+ }
2558
+
2559
+ VALUE
2560
+ ca_call_cslab_1_1 (int8_t dty, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2561
+ {
2562
+ volatile VALUE ry = Qnil;
2563
+
2564
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2565
+
2566
+ if ( dty != dtx1 ) {
2567
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
2568
+ } else {
2569
+ ry = rb_ca_template_n(1, rx1);
2570
+ }
2571
+
2572
+ ca_call_cslab_2(slabfunc, "10", ry, rx1);
2573
+
2574
+ if ( rb_ca_is_scalar(ry) ) {
2575
+ ry = rb_ca_fetch_addr(ry, 0);
2576
+ }
2577
+ return ry;
2578
+ }
2579
+
2580
+ VALUE
2581
+ ca_call_cslab_1_2 (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2582
+ {
2583
+ volatile VALUE ry = Qnil;
2584
+
2585
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2586
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2587
+
2588
+ if ( dty != dtx1 || dty != dtx2 ) {
2589
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
2590
+ } else {
2591
+ ry = rb_ca_template_n(2, rx1, rx2);
2592
+ }
2593
+
2594
+ ca_call_cslab_3(slabfunc, "100", ry, rx1, rx2);
2595
+
2596
+ if ( rb_ca_is_scalar(ry) ) {
2597
+ ry = rb_ca_fetch_addr(ry, 0);
2598
+ }
2599
+ return ry;
2600
+ }
2601
+
2602
+ VALUE
2603
+ ca_call_cslab_1_3 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2604
+ {
2605
+ volatile VALUE ry = Qnil;
2606
+
2607
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2608
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2609
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2610
+
2611
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
2612
+ 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)));
2613
+ } else {
2614
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
2615
+ }
2616
+
2617
+ ca_call_cslab_4(slabfunc, "1000", ry, rx1, rx2, rx3);
2618
+
2619
+ if ( rb_ca_is_scalar(ry) ) {
2620
+ ry = rb_ca_fetch_addr(ry, 0);
2621
+ }
2622
+ return ry;
2623
+ }
2624
+
2625
+ VALUE
2626
+ ca_call_cslab_1_4 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
2627
+ {
2628
+ volatile VALUE ry = Qnil;
2629
+
2630
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2631
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2632
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2633
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2634
+
2635
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
2636
+ 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)));
2637
+ } else {
2638
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2639
+ }
2640
+
2641
+ ca_call_cslab_5(slabfunc, "10000", ry, rx1, rx2, rx3, rx4);
2642
+
2643
+ if ( rb_ca_is_scalar(ry) ) {
2644
+ ry = rb_ca_fetch_addr(ry, 0);
2645
+ }
2646
+ return ry;
2647
+ }
2648
+
2649
+ VALUE
2650
+ ca_call_cslab_1_5 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5)
2651
+ {
2652
+ volatile VALUE ry = Qnil;
2653
+
2654
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2655
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2656
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2657
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2658
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2659
+
2660
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
2661
+ 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)));
2662
+ } else {
2663
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
2664
+ }
2665
+
2666
+ ca_call_cslab_6(slabfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5);
2667
+
2668
+ if ( rb_ca_is_scalar(ry) ) {
2669
+ ry = rb_ca_fetch_addr(ry, 0);
2670
+ }
2671
+ return ry;
2672
+ }
2673
+
2674
+ VALUE
2675
+ ca_call_cslab_1_6 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6)
2676
+ {
2677
+ volatile VALUE ry = Qnil;
2678
+
2679
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2680
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2681
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2682
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2683
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
2684
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
2685
+
2686
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
2687
+ 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)));
2688
+ } else {
2689
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
2690
+ }
2691
+
2692
+ ca_call_cslab_7(slabfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6);
2693
+
2694
+ if ( rb_ca_is_scalar(ry) ) {
2695
+ ry = rb_ca_fetch_addr(ry, 0);
2696
+ }
2697
+ return ry;
2698
+ }
2699
+
2700
+ VALUE
2701
+ ca_call_cslab_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2702
+ {
2703
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2704
+
2705
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2706
+
2707
+ if ( dty1 != dtx1 ) {
2708
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
2709
+ } else {
2710
+ ry1 = rb_ca_template_n(1, rx1);
2711
+ }
2712
+ if ( dty2 != dtx1 ) {
2713
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
2714
+ } else {
2715
+ ry2 = rb_ca_template_n(1, rx1);
2716
+ }
2717
+
2718
+ ca_call_cslab_3(slabfunc, "110", ry1, ry2, rx1);
2719
+
2720
+ if ( rb_ca_is_scalar(ry1) ) {
2721
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2722
+ }
2723
+ if ( rb_ca_is_scalar(ry2) ) {
2724
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2725
+ }
2726
+ return rb_ary_new3(2, ry1, ry2);
2727
+ }
2728
+
2729
+ VALUE
2730
+ ca_call_cslab_2_2 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2731
+ {
2732
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2733
+
2734
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2735
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2736
+
2737
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
2738
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
2739
+ } else {
2740
+ ry1 = rb_ca_template_n(2, rx1, rx2);
2741
+ }
2742
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
2743
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
2744
+ } else {
2745
+ ry2 = rb_ca_template_n(2, rx1, rx2);
2746
+ }
2747
+
2748
+ ca_call_cslab_4(slabfunc, "1100", ry1, ry2, rx1, rx2);
2749
+
2750
+ if ( rb_ca_is_scalar(ry1) ) {
2751
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2752
+ }
2753
+ if ( rb_ca_is_scalar(ry2) ) {
2754
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2755
+ }
2756
+ return rb_ary_new3(2, ry1, ry2);
2757
+ }
2758
+
2759
+ VALUE
2760
+ ca_call_cslab_2_3 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2761
+ {
2762
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2763
+
2764
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2765
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2766
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2767
+
2768
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
2769
+ 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)));
2770
+ } else {
2771
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
2772
+ }
2773
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
2774
+ 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)));
2775
+ } else {
2776
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
2777
+ }
2778
+
2779
+ ca_call_cslab_5(slabfunc, "11000", ry1, ry2, rx1, rx2, rx3);
2780
+
2781
+ if ( rb_ca_is_scalar(ry1) ) {
2782
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2783
+ }
2784
+ if ( rb_ca_is_scalar(ry2) ) {
2785
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2786
+ }
2787
+ return rb_ary_new3(2, ry1, ry2);
2788
+ }
2789
+
2790
+ VALUE
2791
+ ca_call_cslab_2_4 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4)
2792
+ {
2793
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
2794
+
2795
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2796
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2797
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2798
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
2799
+
2800
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
2801
+ 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)));
2802
+ } else {
2803
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2804
+ }
2805
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
2806
+ 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)));
2807
+ } else {
2808
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
2809
+ }
2810
+
2811
+ ca_call_cslab_6(slabfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4);
2812
+
2813
+ if ( rb_ca_is_scalar(ry1) ) {
2814
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2815
+ }
2816
+ if ( rb_ca_is_scalar(ry2) ) {
2817
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2818
+ }
2819
+ return rb_ary_new3(2, ry1, ry2);
2820
+ }
2821
+
2822
+ VALUE
2823
+ ca_call_cslab_3_1 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1)
2824
+ {
2825
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2826
+
2827
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2828
+
2829
+ if ( dty1 != dtx1 ) {
2830
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
2831
+ } else {
2832
+ ry1 = rb_ca_template_n(1, rx1);
2833
+ }
2834
+ if ( dty2 != dtx1 ) {
2835
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
2836
+ } else {
2837
+ ry2 = rb_ca_template_n(1, rx1);
2838
+ }
2839
+ if ( dty3 != dtx1 ) {
2840
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
2841
+ } else {
2842
+ ry3 = rb_ca_template_n(1, rx1);
2843
+ }
2844
+
2845
+ ca_call_cslab_4(slabfunc, "1110", ry1, ry2, ry3, rx1);
2846
+
2847
+ if ( rb_ca_is_scalar(ry1) ) {
2848
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2849
+ }
2850
+ if ( rb_ca_is_scalar(ry2) ) {
2851
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2852
+ }
2853
+ if ( rb_ca_is_scalar(ry3) ) {
2854
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2855
+ }
2856
+ return rb_ary_new3(3, ry1, ry2, ry3);
2857
+ }
2858
+
2859
+ VALUE
2860
+ ca_call_cslab_3_2 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2)
2861
+ {
2862
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2863
+
2864
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2865
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2866
+
2867
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
2868
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
2869
+ } else {
2870
+ ry1 = rb_ca_template_n(2, rx1, rx2);
2871
+ }
2872
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
2873
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
2874
+ } else {
2875
+ ry2 = rb_ca_template_n(2, rx1, rx2);
2876
+ }
2877
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
2878
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
2879
+ } else {
2880
+ ry3 = rb_ca_template_n(2, rx1, rx2);
2881
+ }
2882
+
2883
+ ca_call_cslab_5(slabfunc, "11100", ry1, ry2, ry3, rx1, rx2);
2884
+
2885
+ if ( rb_ca_is_scalar(ry1) ) {
2886
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2887
+ }
2888
+ if ( rb_ca_is_scalar(ry2) ) {
2889
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2890
+ }
2891
+ if ( rb_ca_is_scalar(ry3) ) {
2892
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2893
+ }
2894
+ return rb_ary_new3(3, ry1, ry2, ry3);
2895
+ }
2896
+
2897
+ VALUE
2898
+ ca_call_cslab_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3)
2899
+ {
2900
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
2901
+
2902
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2903
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2904
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2905
+
2906
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
2907
+ 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)));
2908
+ } else {
2909
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
2910
+ }
2911
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
2912
+ 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)));
2913
+ } else {
2914
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
2915
+ }
2916
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
2917
+ 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)));
2918
+ } else {
2919
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
2920
+ }
2921
+
2922
+ ca_call_cslab_6(slabfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3);
2923
+
2924
+ if ( rb_ca_is_scalar(ry1) ) {
2925
+ ry1 = rb_ca_fetch_addr(ry1, 0);
2926
+ }
2927
+ if ( rb_ca_is_scalar(ry2) ) {
2928
+ ry2 = rb_ca_fetch_addr(ry2, 0);
2929
+ }
2930
+ if ( rb_ca_is_scalar(ry3) ) {
2931
+ ry3 = rb_ca_fetch_addr(ry3, 0);
2932
+ }
2933
+ return rb_ary_new3(3, ry1, ry2, ry3);
2934
+ }
2935
+
2936
+ VALUE
2937
+ ca_call_cslab_1_1_r (int8_t dty, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
2938
+ {
2939
+ volatile VALUE ry = Qnil;
2940
+
2941
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2942
+
2943
+ if ( dty != dtx1 ) {
2944
+ ry = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty)));
2945
+ } else {
2946
+ ry = rb_ca_template_n(1, rx1);
2947
+ }
2948
+
2949
+ ca_call_cslab_2_r(slabfunc, "10", ry, rx1, userdata);
2950
+
2951
+ if ( rb_ca_is_scalar(ry) ) {
2952
+ ry = rb_ca_fetch_addr(ry, 0);
2953
+ }
2954
+ return ry;
2955
+ }
2956
+
2957
+ VALUE
2958
+ ca_call_cslab_1_2_r (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
2959
+ {
2960
+ volatile VALUE ry = Qnil;
2961
+
2962
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2963
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2964
+
2965
+ if ( dty != dtx1 || dty != dtx2 ) {
2966
+ ry = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty)), rb_ca_wrap_readonly(rx2, INT2NUM(dty)));
2967
+ } else {
2968
+ ry = rb_ca_template_n(2, rx1, rx2);
2969
+ }
2970
+
2971
+ ca_call_cslab_3_r(slabfunc, "100", ry, rx1, rx2, userdata);
2972
+
2973
+ if ( rb_ca_is_scalar(ry) ) {
2974
+ ry = rb_ca_fetch_addr(ry, 0);
2975
+ }
2976
+ return ry;
2977
+ }
2978
+
2979
+ VALUE
2980
+ ca_call_cslab_1_3_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
2981
+ {
2982
+ volatile VALUE ry = Qnil;
2983
+
2984
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
2985
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
2986
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
2987
+
2988
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 ) {
2989
+ 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)));
2990
+ } else {
2991
+ ry = rb_ca_template_n(3, rx1, rx2, rx3);
2992
+ }
2993
+
2994
+ ca_call_cslab_4_r(slabfunc, "1000", ry, rx1, rx2, rx3, userdata);
2995
+
2996
+ if ( rb_ca_is_scalar(ry) ) {
2997
+ ry = rb_ca_fetch_addr(ry, 0);
2998
+ }
2999
+ return ry;
3000
+ }
3001
+
3002
+ VALUE
3003
+ ca_call_cslab_1_4_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
3004
+ {
3005
+ volatile VALUE ry = Qnil;
3006
+
3007
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3008
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3009
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3010
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
3011
+
3012
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 ) {
3013
+ 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)));
3014
+ } else {
3015
+ ry = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
3016
+ }
3017
+
3018
+ ca_call_cslab_5_r(slabfunc, "10000", ry, rx1, rx2, rx3, rx4, userdata);
3019
+
3020
+ if ( rb_ca_is_scalar(ry) ) {
3021
+ ry = rb_ca_fetch_addr(ry, 0);
3022
+ }
3023
+ return ry;
3024
+ }
3025
+
3026
+ VALUE
3027
+ ca_call_cslab_1_5_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, void *userdata)
3028
+ {
3029
+ volatile VALUE ry = Qnil;
3030
+
3031
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3032
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3033
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3034
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
3035
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
3036
+
3037
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 ) {
3038
+ 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)));
3039
+ } else {
3040
+ ry = rb_ca_template_n(5, rx1, rx2, rx3, rx4, rx5);
3041
+ }
3042
+
3043
+ ca_call_cslab_6_r(slabfunc, "100000", ry, rx1, rx2, rx3, rx4, rx5, userdata);
3044
+
3045
+ if ( rb_ca_is_scalar(ry) ) {
3046
+ ry = rb_ca_fetch_addr(ry, 0);
3047
+ }
3048
+ return ry;
3049
+ }
3050
+
3051
+ VALUE
3052
+ ca_call_cslab_1_6_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6, void *userdata)
3053
+ {
3054
+ volatile VALUE ry = Qnil;
3055
+
3056
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3057
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3058
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3059
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
3060
+ rx5 = rb_ca_wrap_readonly(rx5, INT2NUM(dtx5));
3061
+ rx6 = rb_ca_wrap_readonly(rx6, INT2NUM(dtx6));
3062
+
3063
+ if ( dty != dtx1 || dty != dtx2 || dty != dtx3 || dty != dtx4 || dty != dtx5 || dty != dtx6 ) {
3064
+ 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)));
3065
+ } else {
3066
+ ry = rb_ca_template_n(6, rx1, rx2, rx3, rx4, rx5, rx6);
3067
+ }
3068
+
3069
+ ca_call_cslab_7_r(slabfunc, "1000000", ry, rx1, rx2, rx3, rx4, rx5, rx6, userdata);
3070
+
3071
+ if ( rb_ca_is_scalar(ry) ) {
3072
+ ry = rb_ca_fetch_addr(ry, 0);
3073
+ }
3074
+ return ry;
3075
+ }
3076
+
3077
+ VALUE
3078
+ ca_call_cslab_2_1_r (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
3079
+ {
3080
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
3081
+
3082
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3083
+
3084
+ if ( dty1 != dtx1 ) {
3085
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
3086
+ } else {
3087
+ ry1 = rb_ca_template_n(1, rx1);
3088
+ }
3089
+ if ( dty2 != dtx1 ) {
3090
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
3091
+ } else {
3092
+ ry2 = rb_ca_template_n(1, rx1);
3093
+ }
3094
+
3095
+ ca_call_cslab_3_r(slabfunc, "110", ry1, ry2, rx1, userdata);
3096
+
3097
+ if ( rb_ca_is_scalar(ry1) ) {
3098
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3099
+ }
3100
+ if ( rb_ca_is_scalar(ry2) ) {
3101
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3102
+ }
3103
+ return rb_ary_new3(2, ry1, ry2);
3104
+ }
3105
+
3106
+ VALUE
3107
+ ca_call_cslab_2_2_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
3108
+ {
3109
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
3110
+
3111
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3112
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3113
+
3114
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
3115
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
3116
+ } else {
3117
+ ry1 = rb_ca_template_n(2, rx1, rx2);
3118
+ }
3119
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
3120
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
3121
+ } else {
3122
+ ry2 = rb_ca_template_n(2, rx1, rx2);
3123
+ }
3124
+
3125
+ ca_call_cslab_4_r(slabfunc, "1100", ry1, ry2, rx1, rx2, userdata);
3126
+
3127
+ if ( rb_ca_is_scalar(ry1) ) {
3128
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3129
+ }
3130
+ if ( rb_ca_is_scalar(ry2) ) {
3131
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3132
+ }
3133
+ return rb_ary_new3(2, ry1, ry2);
3134
+ }
3135
+
3136
+ VALUE
3137
+ ca_call_cslab_2_3_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
3138
+ {
3139
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
3140
+
3141
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3142
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3143
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3144
+
3145
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
3146
+ 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)));
3147
+ } else {
3148
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
3149
+ }
3150
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
3151
+ 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)));
3152
+ } else {
3153
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
3154
+ }
3155
+
3156
+ ca_call_cslab_5_r(slabfunc, "11000", ry1, ry2, rx1, rx2, rx3, userdata);
3157
+
3158
+ if ( rb_ca_is_scalar(ry1) ) {
3159
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3160
+ }
3161
+ if ( rb_ca_is_scalar(ry2) ) {
3162
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3163
+ }
3164
+ return rb_ary_new3(2, ry1, ry2);
3165
+ }
3166
+
3167
+ VALUE
3168
+ ca_call_cslab_2_4_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata)
3169
+ {
3170
+ volatile VALUE ry1 = Qnil, ry2 = Qnil;
3171
+
3172
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3173
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3174
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3175
+ rx4 = rb_ca_wrap_readonly(rx4, INT2NUM(dtx4));
3176
+
3177
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 || dty1 != dtx4 ) {
3178
+ 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)));
3179
+ } else {
3180
+ ry1 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
3181
+ }
3182
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 || dty2 != dtx4 ) {
3183
+ 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)));
3184
+ } else {
3185
+ ry2 = rb_ca_template_n(4, rx1, rx2, rx3, rx4);
3186
+ }
3187
+
3188
+ ca_call_cslab_6_r(slabfunc, "110000", ry1, ry2, rx1, rx2, rx3, rx4, userdata);
3189
+
3190
+ if ( rb_ca_is_scalar(ry1) ) {
3191
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3192
+ }
3193
+ if ( rb_ca_is_scalar(ry2) ) {
3194
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3195
+ }
3196
+ return rb_ary_new3(2, ry1, ry2);
3197
+ }
3198
+
3199
+ VALUE
3200
+ ca_call_cslab_3_1_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata)
3201
+ {
3202
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3203
+
3204
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3205
+
3206
+ if ( dty1 != dtx1 ) {
3207
+ ry1 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)));
3208
+ } else {
3209
+ ry1 = rb_ca_template_n(1, rx1);
3210
+ }
3211
+ if ( dty2 != dtx1 ) {
3212
+ ry2 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)));
3213
+ } else {
3214
+ ry2 = rb_ca_template_n(1, rx1);
3215
+ }
3216
+ if ( dty3 != dtx1 ) {
3217
+ ry3 = rb_ca_template_n(1, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)));
3218
+ } else {
3219
+ ry3 = rb_ca_template_n(1, rx1);
3220
+ }
3221
+
3222
+ ca_call_cslab_4_r(slabfunc, "1110", ry1, ry2, ry3, rx1, userdata);
3223
+
3224
+ if ( rb_ca_is_scalar(ry1) ) {
3225
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3226
+ }
3227
+ if ( rb_ca_is_scalar(ry2) ) {
3228
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3229
+ }
3230
+ if ( rb_ca_is_scalar(ry3) ) {
3231
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3232
+ }
3233
+ return rb_ary_new3(3, ry1, ry2, ry3);
3234
+ }
3235
+
3236
+ VALUE
3237
+ ca_call_cslab_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata)
3238
+ {
3239
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3240
+
3241
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3242
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3243
+
3244
+ if ( dty1 != dtx1 || dty1 != dtx2 ) {
3245
+ ry1 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty1)), rb_ca_wrap_readonly(rx2, INT2NUM(dty1)));
3246
+ } else {
3247
+ ry1 = rb_ca_template_n(2, rx1, rx2);
3248
+ }
3249
+ if ( dty2 != dtx1 || dty2 != dtx2 ) {
3250
+ ry2 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty2)), rb_ca_wrap_readonly(rx2, INT2NUM(dty2)));
3251
+ } else {
3252
+ ry2 = rb_ca_template_n(2, rx1, rx2);
3253
+ }
3254
+ if ( dty3 != dtx1 || dty3 != dtx2 ) {
3255
+ ry3 = rb_ca_template_n(2, rb_ca_wrap_readonly(rx1, INT2NUM(dty3)), rb_ca_wrap_readonly(rx2, INT2NUM(dty3)));
3256
+ } else {
3257
+ ry3 = rb_ca_template_n(2, rx1, rx2);
3258
+ }
3259
+
3260
+ ca_call_cslab_5_r(slabfunc, "11100", ry1, ry2, ry3, rx1, rx2, userdata);
3261
+
3262
+ if ( rb_ca_is_scalar(ry1) ) {
3263
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3264
+ }
3265
+ if ( rb_ca_is_scalar(ry2) ) {
3266
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3267
+ }
3268
+ if ( rb_ca_is_scalar(ry3) ) {
3269
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3270
+ }
3271
+ return rb_ary_new3(3, ry1, ry2, ry3);
3272
+ }
3273
+
3274
+ VALUE
3275
+ ca_call_cslab_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata)
3276
+ {
3277
+ volatile VALUE ry1 = Qnil, ry2 = Qnil, ry3 = Qnil;
3278
+
3279
+ rx1 = rb_ca_wrap_readonly(rx1, INT2NUM(dtx1));
3280
+ rx2 = rb_ca_wrap_readonly(rx2, INT2NUM(dtx2));
3281
+ rx3 = rb_ca_wrap_readonly(rx3, INT2NUM(dtx3));
3282
+
3283
+ if ( dty1 != dtx1 || dty1 != dtx2 || dty1 != dtx3 ) {
3284
+ 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)));
3285
+ } else {
3286
+ ry1 = rb_ca_template_n(3, rx1, rx2, rx3);
3287
+ }
3288
+ if ( dty2 != dtx1 || dty2 != dtx2 || dty2 != dtx3 ) {
3289
+ 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)));
3290
+ } else {
3291
+ ry2 = rb_ca_template_n(3, rx1, rx2, rx3);
3292
+ }
3293
+ if ( dty3 != dtx1 || dty3 != dtx2 || dty3 != dtx3 ) {
3294
+ 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)));
3295
+ } else {
3296
+ ry3 = rb_ca_template_n(3, rx1, rx2, rx3);
3297
+ }
3298
+
3299
+ ca_call_cslab_6_r(slabfunc, "111000", ry1, ry2, ry3, rx1, rx2, rx3, userdata);
3300
+
3301
+ if ( rb_ca_is_scalar(ry1) ) {
3302
+ ry1 = rb_ca_fetch_addr(ry1, 0);
3303
+ }
3304
+ if ( rb_ca_is_scalar(ry2) ) {
3305
+ ry2 = rb_ca_fetch_addr(ry2, 0);
3306
+ }
3307
+ if ( rb_ca_is_scalar(ry3) ) {
3308
+ ry3 = rb_ca_fetch_addr(ry3, 0);
3309
+ }
3310
+ return rb_ary_new3(3, ry1, ry2, ry3);
3311
+ }
3312
+