carray 3.0.3 → 3.0.4

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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +264 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +1 -6
  7. data/ext/ca_axis_group.c +27 -27
  8. data/ext/ca_binop_dispatch.c +1 -29
  9. data/ext/ca_binop_dispatch.h +0 -1
  10. data/ext/ca_categorical_iterator.c +205 -134
  11. data/ext/ca_compare.c +7 -18
  12. data/ext/ca_group_iter.c +16 -17
  13. data/ext/ca_kernel_iterator.c +1234 -1994
  14. data/ext/ca_kernel_iterator.h +391 -437
  15. data/ext/ca_monop_dispatch.c +82 -59
  16. data/ext/ca_monop_dispatch.h +1 -0
  17. data/ext/ca_obj_array.c +96 -39
  18. data/ext/ca_obj_bincmp.c +24 -21
  19. data/ext/ca_obj_binop.c +15 -26
  20. data/ext/ca_obj_bitarray.c +3 -2
  21. data/ext/ca_obj_bitfield.c +5 -6
  22. data/ext/ca_obj_block.c +18 -9
  23. data/ext/ca_obj_byte_swap.c +5 -6
  24. data/ext/ca_obj_const_string.c +173 -19
  25. data/ext/ca_obj_face.c +238 -57
  26. data/ext/ca_obj_face.h +19 -0
  27. data/ext/ca_obj_fake.c +15 -29
  28. data/ext/ca_obj_farray.c +6 -3
  29. data/ext/ca_obj_field.c +17 -5
  30. data/ext/ca_obj_fixlen_string.c +2 -3
  31. data/ext/ca_obj_grid.c +406 -132
  32. data/ext/ca_obj_meld.c +172 -34
  33. data/ext/ca_obj_moncmp.c +23 -8
  34. data/ext/ca_obj_monop.c +67 -57
  35. data/ext/ca_obj_object.c +157 -51
  36. data/ext/ca_obj_record.c +12 -7
  37. data/ext/ca_obj_reduce.c +13 -8
  38. data/ext/ca_obj_refer.c +25 -27
  39. data/ext/ca_obj_remap.c +30 -9
  40. data/ext/ca_obj_repeat.c +9 -10
  41. data/ext/ca_obj_roll.c +6 -5
  42. data/ext/ca_obj_select.c +14 -9
  43. data/ext/ca_obj_select_axis.c +15 -47
  44. data/ext/ca_obj_shift.c +11 -1
  45. data/ext/ca_obj_stack.c +179 -34
  46. data/ext/ca_obj_stride.c +162 -115
  47. data/ext/ca_obj_string.c +71 -4
  48. data/ext/ca_obj_tile.c +6 -5
  49. data/ext/ca_obj_time.c +22 -6
  50. data/ext/ca_obj_timedelta.c +22 -6
  51. data/ext/ca_obj_transpose.c +5 -3
  52. data/ext/ca_obj_triop.c +23 -32
  53. data/ext/ca_obj_window.c +190 -26
  54. data/ext/ca_sweep_engine.c +2 -2
  55. data/ext/caframe_csv_reader.c +80 -1
  56. data/ext/carray.h +181 -75
  57. data/ext/carray_access.c +184 -96
  58. data/ext/carray_address_basis.c +343 -87
  59. data/ext/carray_attribute.c +89 -6
  60. data/ext/carray_bincount.c +10 -8
  61. data/ext/carray_broadcast.c +13 -8
  62. data/ext/carray_build_flags.h +3 -0
  63. data/ext/carray_call_cfunc.c +108 -0
  64. data/ext/carray_cast.c +142 -24
  65. data/ext/carray_cast_func.rb +46 -6
  66. data/ext/carray_class.c +4 -3
  67. data/ext/carray_config.h +28 -0
  68. data/ext/carray_conversion.c +16 -7
  69. data/ext/carray_copy.c +51 -14
  70. data/ext/carray_core.c +147 -55
  71. data/ext/carray_count.c +50 -20
  72. data/ext/carray_element.c +76 -33
  73. data/ext/carray_factorize.c +118 -64
  74. data/ext/carray_generate.c +191 -50
  75. data/ext/carray_histogram.c +62 -17
  76. data/ext/carray_hold.c +12 -15
  77. data/ext/carray_index_classifier.c +388 -176
  78. data/ext/carray_internal.h +336 -29
  79. data/ext/carray_kernels_bincmp.c +4453 -0
  80. data/ext/carray_kernels_binop.c +11368 -0
  81. data/ext/carray_kernels_init.c +1734 -0
  82. data/ext/carray_kernels_moncmp.c +2104 -0
  83. data/ext/carray_kernels_monop.c +18369 -0
  84. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  85. data/ext/carray_kernels_reduce_boolean.c +406 -0
  86. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  87. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  88. data/ext/carray_kernels_reduce_variance.c +3849 -0
  89. data/ext/carray_kernels_scan.c +4302 -0
  90. data/ext/carray_kernels_search.c +33829 -0
  91. data/ext/carray_kernels_sort.c +10906 -0
  92. data/ext/carray_kernels_triop.c +1864 -0
  93. data/ext/carray_key_windows.c +216 -0
  94. data/ext/carray_lazy.c +170 -111
  95. data/ext/carray_mask.c +292 -72
  96. data/ext/carray_median_percentile.c +82 -28
  97. data/ext/carray_memory_view.c +669 -561
  98. data/ext/carray_operator.c +124 -47
  99. data/ext/carray_order.c +384 -76
  100. data/ext/carray_partition.c +28 -27
  101. data/ext/carray_random.c +67 -13
  102. data/ext/carray_round.c +273 -0
  103. data/ext/carray_scatter.c +63 -38
  104. data/ext/carray_segment.c +3 -3
  105. data/ext/carray_slab.c +91 -28
  106. data/ext/carray_sort.c +35 -35
  107. data/ext/carray_struct.c +19 -18
  108. data/ext/carray_test.c +26 -5
  109. data/ext/carray_undef.c +4 -0
  110. data/ext/carray_utils.c +246 -45
  111. data/ext/mk_call_cfunc.rb +19 -2
  112. data/ext/mkkernel.rb +198 -240
  113. data/ext/ruby_carray.c +10 -4
  114. data/ext/version.h +4 -4
  115. data/lib/carray/attribute.rb +126 -22
  116. data/lib/carray/autoload_carray.rb +8 -31
  117. data/lib/carray/autoload_method_extension.rb +14 -5
  118. data/lib/carray/axis_group.rb +255 -106
  119. data/lib/carray/basics.rb +78 -10
  120. data/lib/carray/bincount_nd.rb +12 -2
  121. data/lib/carray/block_iterator.rb +126 -23
  122. data/lib/carray/boolean_reduce.rb +17 -17
  123. data/lib/carray/categorical.rb +165 -43
  124. data/lib/carray/categorical_iterator.rb +130 -27
  125. data/lib/carray/complex.rb +5 -5
  126. data/lib/carray/conditional.rb +67 -18
  127. data/lib/carray/const_string.rb +14 -5
  128. data/lib/carray/construct.rb +15 -11
  129. data/lib/carray/data_type_extension.rb +1 -0
  130. data/lib/carray/distance_limit.rb +77 -0
  131. data/lib/carray/fixlen_string.rb +7 -1
  132. data/lib/carray/frame/column_verbs.rb +70 -0
  133. data/lib/carray/frame/convert.rb +69 -0
  134. data/lib/carray/frame/csv_parser.rb +111 -17
  135. data/lib/carray/frame/describe.rb +3 -2
  136. data/lib/carray/frame/frame.rb +246 -21
  137. data/lib/carray/frame/group.rb +510 -95
  138. data/lib/carray/frame/io.rb +115 -28
  139. data/lib/carray/frame/join.rb +312 -51
  140. data/lib/carray/frame/records.rb +83 -7
  141. data/lib/carray/frame/reshape.rb +42 -35
  142. data/lib/carray/frame/sort.rb +7 -19
  143. data/lib/carray/frame/verbs.rb +188 -48
  144. data/lib/carray/frame/windows.rb +117 -0
  145. data/lib/carray/frame.rb +2 -0
  146. data/lib/carray/fuse_source.rb +11 -4
  147. data/lib/carray/fusion.rb +40 -16
  148. data/lib/carray/histogram.rb +6 -1
  149. data/lib/carray/inspect.rb +31 -8
  150. data/lib/carray/iterator.rb +85 -7
  151. data/lib/carray/key_windows.rb +620 -0
  152. data/lib/carray/lazy.rb +182 -183
  153. data/lib/carray/mask_gap_fill.rb +63 -57
  154. data/lib/carray/meld_reduce.rb +12 -14
  155. data/lib/carray/methods/bin.rb +26 -18
  156. data/lib/carray/methods/bincount.rb +16 -0
  157. data/lib/carray/methods/bit_string.rb +1 -1
  158. data/lib/carray/methods/choose.rb +16 -3
  159. data/lib/carray/methods/composition.rb +3 -1
  160. data/lib/carray/methods/gather_nd.rb +14 -5
  161. data/lib/carray/methods/insert_block.rb +2 -2
  162. data/lib/carray/methods/is_between.rb +59 -0
  163. data/lib/carray/methods/is_in.rb +53 -36
  164. data/lib/carray/methods/join.rb +1 -6
  165. data/lib/carray/methods/lag.rb +49 -0
  166. data/lib/carray/methods/locate_addr.rb +47 -51
  167. data/lib/carray/methods/mode.rb +1 -1
  168. data/lib/carray/methods/nunique.rb +11 -6
  169. data/lib/carray/methods/resize.rb +3 -3
  170. data/lib/carray/methods/value_counts.rb +4 -11
  171. data/lib/carray/record_order.rb +3 -3
  172. data/lib/carray/rng.rb +3 -0
  173. data/lib/carray/runtime.rb +53 -8
  174. data/lib/carray/segment_iterator.rb +313 -82
  175. data/lib/carray/serialize.rb +24 -10
  176. data/lib/carray/slab_iterator.rb +50 -0
  177. data/lib/carray/string.rb +105 -5
  178. data/lib/carray/string_operation_extension.rb +8 -1
  179. data/lib/carray/struct.rb +9 -21
  180. data/lib/carray/struct_builder.rb +19 -8
  181. data/lib/carray/time.rb +726 -104
  182. data/lib/carray/window_iterator.rb +122 -16
  183. data/lib/carray.rb +7 -0
  184. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  185. data/yard-stubs/ca_obj_field.rb +4 -0
  186. data/yard-stubs/ca_obj_grid.rb +21 -10
  187. data/yard-stubs/ca_obj_refer.rb +2 -1
  188. data/yard-stubs/ca_obj_roll.rb +2 -2
  189. data/yard-stubs/ca_obj_shift.rb +5 -1
  190. data/yard-stubs/ca_obj_tile.rb +1 -1
  191. data/yard-stubs/ca_obj_window.rb +8 -3
  192. data/yard-stubs/carray_access.rb +6 -1
  193. data/yard-stubs/carray_attribute.rb +0 -5
  194. data/yard-stubs/carray_cast.rb +10 -0
  195. data/yard-stubs/carray_conversion.rb +2 -1
  196. data/yard-stubs/carray_copy.rb +4 -2
  197. data/yard-stubs/carray_count.rb +4 -4
  198. data/yard-stubs/carray_element.rb +10 -4
  199. data/yard-stubs/carray_generate.rb +21 -1
  200. data/yard-stubs/carray_mask.rb +26 -2
  201. data/yard-stubs/carray_math.rb +27 -1
  202. data/yard-stubs/carray_median_percentile.rb +5 -2
  203. data/yard-stubs/carray_memory_view.rb +40 -23
  204. data/yard-stubs/carray_order.rb +29 -18
  205. data/yard-stubs/carray_random.rb +13 -4
  206. data/yard-stubs/carray_scatter.rb +14 -9
  207. data/yard-stubs/carray_slab.rb +9 -2
  208. data/yard-stubs/carray_sort.rb +6 -5
  209. data/yard-stubs/carray_test.rb +5 -3
  210. metadata +25 -3
  211. data/lib/carray/arrow_tensor.rb +0 -401
  212. data/lib/carray/table.rb +0 -108
@@ -0,0 +1,1864 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ carray_kernels.c -- GENERATED by ext/mkkernel.rb -- DO NOT EDIT
4
+
5
+ Kernel definitions live in mkkernel.rb (search for `MkKernel.reduce`).
6
+ Regenerate by running:
7
+
8
+ cd ext && ruby mkkernel.rb > carray_kernels.c
9
+
10
+ extconf.rb regenerates automatically when mkkernel.rb is touched.
11
+
12
+ --------------------------------------------------------------------------- */
13
+
14
+ #include "carray.h"
15
+ #include "ca_kernel_iterator.h"
16
+ #include "ca_sort_kernels.h" /* sort kernels: internal, not via the carray.h umbrella */
17
+ #include "carray_internal.h" /* ca_lazy_arena_*, ca_is_lazy_view (streaming reduce) */
18
+ #include "ca_obj_face.h" /* rb_ca_strip_face_value (Face ordering gate) */
19
+ #include <math.h>
20
+ #include <stdint.h>
21
+ #include <stdlib.h> /* qsort, mergesort (HAVE_MERGESORT) -- for :sort kind */
22
+
23
+ /* MEMO_REDUCTION_FASTPATH_ENTITY_ONLY_GUARD Tier 2: CAStack identity is
24
+ probed by operation-table function pointer (obj_type is runtime-
25
+ assigned, so no CA_OBJ_STACK compile-time constant exists). */
26
+ extern ca_operation_function_t ca_stack_func;
27
+ /* The square root of a variance: an ε-negative from rounding becomes 0,
28
+ a NaN stays NaN (fmax(NaN, 0.0) is 0.0). */
29
+ #ifndef CARRAY_SQRT_CLAMP_DEFINED
30
+ #define CARRAY_SQRT_CLAMP_DEFINED
31
+ static inline double ca_sqrt_clamp (double v) { return sqrt(v < 0.0 ? 0.0 : v); }
32
+ #endif
33
+
34
+ /* BOOL2VAL: bool -> Ruby (Qtrue/Qfalse). Used as ruby_scalar wrapper
35
+ for the all/any flat-reduction Ruby surface so `a.all` / `a.any`
36
+ return real true/false, not Integer 0/1. (BOOL2OBJ already exists
37
+ but returns Integer per CArray's boolean-as-int convention.) */
38
+ #ifndef CARRAY_BOOL2VAL_DEFINED
39
+ #define CARRAY_BOOL2VAL_DEFINED
40
+ static inline VALUE BOOL2VAL (boolean8_t x) { return x ? Qtrue : Qfalse; }
41
+ #endif
42
+
43
+ #include "ca_op_powi.h"
44
+ #include "ca_op_cmplx64.h"
45
+
46
+ /* ===== triop fma ============================================ */
47
+
48
+ static void
49
+ ca_triop_fma_int8_t (ca_size_t n, boolean8_t *m,
50
+ char *ptr1, ca_size_t i1,
51
+ char *ptr2, ca_size_t i2,
52
+ char *ptr3, ca_size_t i3,
53
+ char *ptr4, ca_size_t i4)
54
+ {
55
+ int8_t *q1 = (int8_t *) ptr1, *q2 = (int8_t *) ptr2,
56
+ *q3 = (int8_t *) ptr3, *q4 = (int8_t *) ptr4;
57
+ int8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
58
+ ca_size_t k;
59
+ if ( m ) {
60
+ boolean8_t *pm;
61
+ for (k=0; k<n; k++) {
62
+ pm = m + k;
63
+ if ( ! *pm ) {
64
+ p1 = q1 + k*i1;
65
+ p2 = q2 + k*i2;
66
+ p3 = q3 + k*i3;
67
+ p4 = q4 + k*i4;
68
+ { (*p4) = (*p1) * (*p2) + (*p3); }
69
+ }
70
+ }
71
+ } else {
72
+ for (k=0; k<n; k++) {
73
+ p1 = q1 + k*i1;
74
+ p2 = q2 + k*i2;
75
+ p3 = q3 + k*i3;
76
+ p4 = q4 + k*i4;
77
+ { (*p4) = (*p1) * (*p2) + (*p3); }
78
+ }
79
+ }
80
+ }
81
+
82
+ static void
83
+ ca_triop_fma_uint8_t (ca_size_t n, boolean8_t *m,
84
+ char *ptr1, ca_size_t i1,
85
+ char *ptr2, ca_size_t i2,
86
+ char *ptr3, ca_size_t i3,
87
+ char *ptr4, ca_size_t i4)
88
+ {
89
+ uint8_t *q1 = (uint8_t *) ptr1, *q2 = (uint8_t *) ptr2,
90
+ *q3 = (uint8_t *) ptr3, *q4 = (uint8_t *) ptr4;
91
+ uint8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
92
+ ca_size_t k;
93
+ if ( m ) {
94
+ boolean8_t *pm;
95
+ for (k=0; k<n; k++) {
96
+ pm = m + k;
97
+ if ( ! *pm ) {
98
+ p1 = q1 + k*i1;
99
+ p2 = q2 + k*i2;
100
+ p3 = q3 + k*i3;
101
+ p4 = q4 + k*i4;
102
+ { (*p4) = (*p1) * (*p2) + (*p3); }
103
+ }
104
+ }
105
+ } else {
106
+ for (k=0; k<n; k++) {
107
+ p1 = q1 + k*i1;
108
+ p2 = q2 + k*i2;
109
+ p3 = q3 + k*i3;
110
+ p4 = q4 + k*i4;
111
+ { (*p4) = (*p1) * (*p2) + (*p3); }
112
+ }
113
+ }
114
+ }
115
+
116
+ static void
117
+ ca_triop_fma_int16_t (ca_size_t n, boolean8_t *m,
118
+ char *ptr1, ca_size_t i1,
119
+ char *ptr2, ca_size_t i2,
120
+ char *ptr3, ca_size_t i3,
121
+ char *ptr4, ca_size_t i4)
122
+ {
123
+ int16_t *q1 = (int16_t *) ptr1, *q2 = (int16_t *) ptr2,
124
+ *q3 = (int16_t *) ptr3, *q4 = (int16_t *) ptr4;
125
+ int16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
126
+ ca_size_t k;
127
+ if ( m ) {
128
+ boolean8_t *pm;
129
+ for (k=0; k<n; k++) {
130
+ pm = m + k;
131
+ if ( ! *pm ) {
132
+ p1 = q1 + k*i1;
133
+ p2 = q2 + k*i2;
134
+ p3 = q3 + k*i3;
135
+ p4 = q4 + k*i4;
136
+ { (*p4) = (*p1) * (*p2) + (*p3); }
137
+ }
138
+ }
139
+ } else {
140
+ for (k=0; k<n; k++) {
141
+ p1 = q1 + k*i1;
142
+ p2 = q2 + k*i2;
143
+ p3 = q3 + k*i3;
144
+ p4 = q4 + k*i4;
145
+ { (*p4) = (*p1) * (*p2) + (*p3); }
146
+ }
147
+ }
148
+ }
149
+
150
+ static void
151
+ ca_triop_fma_uint16_t (ca_size_t n, boolean8_t *m,
152
+ char *ptr1, ca_size_t i1,
153
+ char *ptr2, ca_size_t i2,
154
+ char *ptr3, ca_size_t i3,
155
+ char *ptr4, ca_size_t i4)
156
+ {
157
+ uint16_t *q1 = (uint16_t *) ptr1, *q2 = (uint16_t *) ptr2,
158
+ *q3 = (uint16_t *) ptr3, *q4 = (uint16_t *) ptr4;
159
+ uint16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
160
+ ca_size_t k;
161
+ if ( m ) {
162
+ boolean8_t *pm;
163
+ for (k=0; k<n; k++) {
164
+ pm = m + k;
165
+ if ( ! *pm ) {
166
+ p1 = q1 + k*i1;
167
+ p2 = q2 + k*i2;
168
+ p3 = q3 + k*i3;
169
+ p4 = q4 + k*i4;
170
+ { (*p4) = (*p1) * (*p2) + (*p3); }
171
+ }
172
+ }
173
+ } else {
174
+ for (k=0; k<n; k++) {
175
+ p1 = q1 + k*i1;
176
+ p2 = q2 + k*i2;
177
+ p3 = q3 + k*i3;
178
+ p4 = q4 + k*i4;
179
+ { (*p4) = (*p1) * (*p2) + (*p3); }
180
+ }
181
+ }
182
+ }
183
+
184
+ static void
185
+ ca_triop_fma_int32_t (ca_size_t n, boolean8_t *m,
186
+ char *ptr1, ca_size_t i1,
187
+ char *ptr2, ca_size_t i2,
188
+ char *ptr3, ca_size_t i3,
189
+ char *ptr4, ca_size_t i4)
190
+ {
191
+ int32_t *q1 = (int32_t *) ptr1, *q2 = (int32_t *) ptr2,
192
+ *q3 = (int32_t *) ptr3, *q4 = (int32_t *) ptr4;
193
+ int32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
194
+ ca_size_t k;
195
+ if ( m ) {
196
+ boolean8_t *pm;
197
+ for (k=0; k<n; k++) {
198
+ pm = m + k;
199
+ if ( ! *pm ) {
200
+ p1 = q1 + k*i1;
201
+ p2 = q2 + k*i2;
202
+ p3 = q3 + k*i3;
203
+ p4 = q4 + k*i4;
204
+ { (*p4) = (*p1) * (*p2) + (*p3); }
205
+ }
206
+ }
207
+ } else {
208
+ for (k=0; k<n; k++) {
209
+ p1 = q1 + k*i1;
210
+ p2 = q2 + k*i2;
211
+ p3 = q3 + k*i3;
212
+ p4 = q4 + k*i4;
213
+ { (*p4) = (*p1) * (*p2) + (*p3); }
214
+ }
215
+ }
216
+ }
217
+
218
+ static void
219
+ ca_triop_fma_uint32_t (ca_size_t n, boolean8_t *m,
220
+ char *ptr1, ca_size_t i1,
221
+ char *ptr2, ca_size_t i2,
222
+ char *ptr3, ca_size_t i3,
223
+ char *ptr4, ca_size_t i4)
224
+ {
225
+ uint32_t *q1 = (uint32_t *) ptr1, *q2 = (uint32_t *) ptr2,
226
+ *q3 = (uint32_t *) ptr3, *q4 = (uint32_t *) ptr4;
227
+ uint32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
228
+ ca_size_t k;
229
+ if ( m ) {
230
+ boolean8_t *pm;
231
+ for (k=0; k<n; k++) {
232
+ pm = m + k;
233
+ if ( ! *pm ) {
234
+ p1 = q1 + k*i1;
235
+ p2 = q2 + k*i2;
236
+ p3 = q3 + k*i3;
237
+ p4 = q4 + k*i4;
238
+ { (*p4) = (*p1) * (*p2) + (*p3); }
239
+ }
240
+ }
241
+ } else {
242
+ for (k=0; k<n; k++) {
243
+ p1 = q1 + k*i1;
244
+ p2 = q2 + k*i2;
245
+ p3 = q3 + k*i3;
246
+ p4 = q4 + k*i4;
247
+ { (*p4) = (*p1) * (*p2) + (*p3); }
248
+ }
249
+ }
250
+ }
251
+
252
+ static void
253
+ ca_triop_fma_int64_t (ca_size_t n, boolean8_t *m,
254
+ char *ptr1, ca_size_t i1,
255
+ char *ptr2, ca_size_t i2,
256
+ char *ptr3, ca_size_t i3,
257
+ char *ptr4, ca_size_t i4)
258
+ {
259
+ int64_t *q1 = (int64_t *) ptr1, *q2 = (int64_t *) ptr2,
260
+ *q3 = (int64_t *) ptr3, *q4 = (int64_t *) ptr4;
261
+ int64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
262
+ ca_size_t k;
263
+ if ( m ) {
264
+ boolean8_t *pm;
265
+ for (k=0; k<n; k++) {
266
+ pm = m + k;
267
+ if ( ! *pm ) {
268
+ p1 = q1 + k*i1;
269
+ p2 = q2 + k*i2;
270
+ p3 = q3 + k*i3;
271
+ p4 = q4 + k*i4;
272
+ { (*p4) = (*p1) * (*p2) + (*p3); }
273
+ }
274
+ }
275
+ } else {
276
+ for (k=0; k<n; k++) {
277
+ p1 = q1 + k*i1;
278
+ p2 = q2 + k*i2;
279
+ p3 = q3 + k*i3;
280
+ p4 = q4 + k*i4;
281
+ { (*p4) = (*p1) * (*p2) + (*p3); }
282
+ }
283
+ }
284
+ }
285
+
286
+ static void
287
+ ca_triop_fma_uint64_t (ca_size_t n, boolean8_t *m,
288
+ char *ptr1, ca_size_t i1,
289
+ char *ptr2, ca_size_t i2,
290
+ char *ptr3, ca_size_t i3,
291
+ char *ptr4, ca_size_t i4)
292
+ {
293
+ uint64_t *q1 = (uint64_t *) ptr1, *q2 = (uint64_t *) ptr2,
294
+ *q3 = (uint64_t *) ptr3, *q4 = (uint64_t *) ptr4;
295
+ uint64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
296
+ ca_size_t k;
297
+ if ( m ) {
298
+ boolean8_t *pm;
299
+ for (k=0; k<n; k++) {
300
+ pm = m + k;
301
+ if ( ! *pm ) {
302
+ p1 = q1 + k*i1;
303
+ p2 = q2 + k*i2;
304
+ p3 = q3 + k*i3;
305
+ p4 = q4 + k*i4;
306
+ { (*p4) = (*p1) * (*p2) + (*p3); }
307
+ }
308
+ }
309
+ } else {
310
+ for (k=0; k<n; k++) {
311
+ p1 = q1 + k*i1;
312
+ p2 = q2 + k*i2;
313
+ p3 = q3 + k*i3;
314
+ p4 = q4 + k*i4;
315
+ { (*p4) = (*p1) * (*p2) + (*p3); }
316
+ }
317
+ }
318
+ }
319
+
320
+ static void
321
+ ca_triop_fma_float32_t (ca_size_t n, boolean8_t *m,
322
+ char *ptr1, ca_size_t i1,
323
+ char *ptr2, ca_size_t i2,
324
+ char *ptr3, ca_size_t i3,
325
+ char *ptr4, ca_size_t i4)
326
+ {
327
+ float *q1 = (float *) ptr1, *q2 = (float *) ptr2,
328
+ *q3 = (float *) ptr3, *q4 = (float *) ptr4;
329
+ float *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
330
+ ca_size_t k;
331
+ if ( m ) {
332
+ boolean8_t *pm;
333
+ for (k=0; k<n; k++) {
334
+ pm = m + k;
335
+ if ( ! *pm ) {
336
+ p1 = q1 + k*i1;
337
+ p2 = q2 + k*i2;
338
+ p3 = q3 + k*i3;
339
+ p4 = q4 + k*i4;
340
+ { (*p4) = fmaf((*p1), (*p2), (*p3)); }
341
+ }
342
+ }
343
+ } else {
344
+ for (k=0; k<n; k++) {
345
+ p1 = q1 + k*i1;
346
+ p2 = q2 + k*i2;
347
+ p3 = q3 + k*i3;
348
+ p4 = q4 + k*i4;
349
+ { (*p4) = fmaf((*p1), (*p2), (*p3)); }
350
+ }
351
+ }
352
+ }
353
+
354
+ static void
355
+ ca_triop_fma_float64_t (ca_size_t n, boolean8_t *m,
356
+ char *ptr1, ca_size_t i1,
357
+ char *ptr2, ca_size_t i2,
358
+ char *ptr3, ca_size_t i3,
359
+ char *ptr4, ca_size_t i4)
360
+ {
361
+ double *q1 = (double *) ptr1, *q2 = (double *) ptr2,
362
+ *q3 = (double *) ptr3, *q4 = (double *) ptr4;
363
+ double *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
364
+ ca_size_t k;
365
+ if ( m ) {
366
+ boolean8_t *pm;
367
+ for (k=0; k<n; k++) {
368
+ pm = m + k;
369
+ if ( ! *pm ) {
370
+ p1 = q1 + k*i1;
371
+ p2 = q2 + k*i2;
372
+ p3 = q3 + k*i3;
373
+ p4 = q4 + k*i4;
374
+ { (*p4) = fma((*p1), (*p2), (*p3)); }
375
+ }
376
+ }
377
+ } else {
378
+ for (k=0; k<n; k++) {
379
+ p1 = q1 + k*i1;
380
+ p2 = q2 + k*i2;
381
+ p3 = q3 + k*i3;
382
+ p4 = q4 + k*i4;
383
+ { (*p4) = fma((*p1), (*p2), (*p3)); }
384
+ }
385
+ }
386
+ }
387
+
388
+ static void
389
+ ca_triop_fma_cmplx64_t (ca_size_t n, boolean8_t *m,
390
+ char *ptr1, ca_size_t i1,
391
+ char *ptr2, ca_size_t i2,
392
+ char *ptr3, ca_size_t i3,
393
+ char *ptr4, ca_size_t i4)
394
+ {
395
+ cmplx64_t *q1 = (cmplx64_t *) ptr1, *q2 = (cmplx64_t *) ptr2,
396
+ *q3 = (cmplx64_t *) ptr3, *q4 = (cmplx64_t *) ptr4;
397
+ cmplx64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
398
+ ca_size_t k;
399
+ if ( m ) {
400
+ boolean8_t *pm;
401
+ for (k=0; k<n; k++) {
402
+ pm = m + k;
403
+ if ( ! *pm ) {
404
+ p1 = q1 + k*i1;
405
+ p2 = q2 + k*i2;
406
+ p3 = q3 + k*i3;
407
+ p4 = q4 + k*i4;
408
+ { (*p4) = (*p1) * (*p2) + (*p3); }
409
+ }
410
+ }
411
+ } else {
412
+ for (k=0; k<n; k++) {
413
+ p1 = q1 + k*i1;
414
+ p2 = q2 + k*i2;
415
+ p3 = q3 + k*i3;
416
+ p4 = q4 + k*i4;
417
+ { (*p4) = (*p1) * (*p2) + (*p3); }
418
+ }
419
+ }
420
+ }
421
+
422
+ static void
423
+ ca_triop_fma_cmplx128_t (ca_size_t n, boolean8_t *m,
424
+ char *ptr1, ca_size_t i1,
425
+ char *ptr2, ca_size_t i2,
426
+ char *ptr3, ca_size_t i3,
427
+ char *ptr4, ca_size_t i4)
428
+ {
429
+ cmplx128_t *q1 = (cmplx128_t *) ptr1, *q2 = (cmplx128_t *) ptr2,
430
+ *q3 = (cmplx128_t *) ptr3, *q4 = (cmplx128_t *) ptr4;
431
+ cmplx128_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
432
+ ca_size_t k;
433
+ if ( m ) {
434
+ boolean8_t *pm;
435
+ for (k=0; k<n; k++) {
436
+ pm = m + k;
437
+ if ( ! *pm ) {
438
+ p1 = q1 + k*i1;
439
+ p2 = q2 + k*i2;
440
+ p3 = q3 + k*i3;
441
+ p4 = q4 + k*i4;
442
+ { (*p4) = (*p1) * (*p2) + (*p3); }
443
+ }
444
+ }
445
+ } else {
446
+ for (k=0; k<n; k++) {
447
+ p1 = q1 + k*i1;
448
+ p2 = q2 + k*i2;
449
+ p3 = q3 + k*i3;
450
+ p4 = q4 + k*i4;
451
+ { (*p4) = (*p1) * (*p2) + (*p3); }
452
+ }
453
+ }
454
+ }
455
+
456
+ static void
457
+ ca_triop_fma_VALUE (ca_size_t n, boolean8_t *m,
458
+ char *ptr1, ca_size_t i1,
459
+ char *ptr2, ca_size_t i2,
460
+ char *ptr3, ca_size_t i3,
461
+ char *ptr4, ca_size_t i4)
462
+ {
463
+ VALUE *q1 = (VALUE *) ptr1, *q2 = (VALUE *) ptr2,
464
+ *q3 = (VALUE *) ptr3, *q4 = (VALUE *) ptr4;
465
+ VALUE *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
466
+ ca_size_t k;
467
+ if ( m ) {
468
+ boolean8_t *pm;
469
+ for (k=0; k<n; k++) {
470
+ pm = m + k;
471
+ if ( ! *pm ) {
472
+ p1 = q1 + k*i1;
473
+ p2 = q2 + k*i2;
474
+ p3 = q3 + k*i3;
475
+ p4 = q4 + k*i4;
476
+ { (*p4) = rb_funcall(rb_funcall((*p1), rb_intern("*"), 1, (*p2)), rb_intern("+"), 1, (*p3)); }
477
+ }
478
+ }
479
+ } else {
480
+ for (k=0; k<n; k++) {
481
+ p1 = q1 + k*i1;
482
+ p2 = q2 + k*i2;
483
+ p3 = q3 + k*i3;
484
+ p4 = q4 + k*i4;
485
+ { (*p4) = rb_funcall(rb_funcall((*p1), rb_intern("*"), 1, (*p2)), rb_intern("+"), 1, (*p3)); }
486
+ }
487
+ }
488
+ }
489
+
490
+ ca_triop_func_t
491
+ ca_triop_fma[CA_NTYPE] = {
492
+ ca_triop_not_implement,
493
+ ca_triop_not_implement,
494
+ ca_triop_fma_int8_t,
495
+ ca_triop_fma_uint8_t,
496
+ ca_triop_fma_int16_t,
497
+ ca_triop_fma_uint16_t,
498
+ ca_triop_fma_int32_t,
499
+ ca_triop_fma_uint32_t,
500
+ ca_triop_fma_int64_t,
501
+ ca_triop_fma_uint64_t,
502
+ ca_triop_fma_float32_t,
503
+ ca_triop_fma_float64_t,
504
+ ca_triop_not_implement,
505
+ ca_triop_fma_cmplx64_t,
506
+ ca_triop_fma_cmplx128_t,
507
+ ca_triop_not_implement,
508
+ ca_triop_fma_VALUE,
509
+ };
510
+
511
+ VALUE rb_ca_fma (VALUE self, VALUE other2, VALUE other3)
512
+ { return rb_ca_call_triop(self, other2, other3, ca_triop_fma); }
513
+
514
+ VALUE rb_ca_fma_bang (VALUE self, VALUE other2, VALUE other3)
515
+ { return rb_ca_call_triop_bang(self, other2, other3, ca_triop_fma); }
516
+
517
+ /* ===== triop fms ============================================ */
518
+
519
+ static void
520
+ ca_triop_fms_int8_t (ca_size_t n, boolean8_t *m,
521
+ char *ptr1, ca_size_t i1,
522
+ char *ptr2, ca_size_t i2,
523
+ char *ptr3, ca_size_t i3,
524
+ char *ptr4, ca_size_t i4)
525
+ {
526
+ int8_t *q1 = (int8_t *) ptr1, *q2 = (int8_t *) ptr2,
527
+ *q3 = (int8_t *) ptr3, *q4 = (int8_t *) ptr4;
528
+ int8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
529
+ ca_size_t k;
530
+ if ( m ) {
531
+ boolean8_t *pm;
532
+ for (k=0; k<n; k++) {
533
+ pm = m + k;
534
+ if ( ! *pm ) {
535
+ p1 = q1 + k*i1;
536
+ p2 = q2 + k*i2;
537
+ p3 = q3 + k*i3;
538
+ p4 = q4 + k*i4;
539
+ { (*p4) = (*p1) * (*p2) - (*p3); }
540
+ }
541
+ }
542
+ } else {
543
+ for (k=0; k<n; k++) {
544
+ p1 = q1 + k*i1;
545
+ p2 = q2 + k*i2;
546
+ p3 = q3 + k*i3;
547
+ p4 = q4 + k*i4;
548
+ { (*p4) = (*p1) * (*p2) - (*p3); }
549
+ }
550
+ }
551
+ }
552
+
553
+ static void
554
+ ca_triop_fms_uint8_t (ca_size_t n, boolean8_t *m,
555
+ char *ptr1, ca_size_t i1,
556
+ char *ptr2, ca_size_t i2,
557
+ char *ptr3, ca_size_t i3,
558
+ char *ptr4, ca_size_t i4)
559
+ {
560
+ uint8_t *q1 = (uint8_t *) ptr1, *q2 = (uint8_t *) ptr2,
561
+ *q3 = (uint8_t *) ptr3, *q4 = (uint8_t *) ptr4;
562
+ uint8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
563
+ ca_size_t k;
564
+ if ( m ) {
565
+ boolean8_t *pm;
566
+ for (k=0; k<n; k++) {
567
+ pm = m + k;
568
+ if ( ! *pm ) {
569
+ p1 = q1 + k*i1;
570
+ p2 = q2 + k*i2;
571
+ p3 = q3 + k*i3;
572
+ p4 = q4 + k*i4;
573
+ { (*p4) = (*p1) * (*p2) - (*p3); }
574
+ }
575
+ }
576
+ } else {
577
+ for (k=0; k<n; k++) {
578
+ p1 = q1 + k*i1;
579
+ p2 = q2 + k*i2;
580
+ p3 = q3 + k*i3;
581
+ p4 = q4 + k*i4;
582
+ { (*p4) = (*p1) * (*p2) - (*p3); }
583
+ }
584
+ }
585
+ }
586
+
587
+ static void
588
+ ca_triop_fms_int16_t (ca_size_t n, boolean8_t *m,
589
+ char *ptr1, ca_size_t i1,
590
+ char *ptr2, ca_size_t i2,
591
+ char *ptr3, ca_size_t i3,
592
+ char *ptr4, ca_size_t i4)
593
+ {
594
+ int16_t *q1 = (int16_t *) ptr1, *q2 = (int16_t *) ptr2,
595
+ *q3 = (int16_t *) ptr3, *q4 = (int16_t *) ptr4;
596
+ int16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
597
+ ca_size_t k;
598
+ if ( m ) {
599
+ boolean8_t *pm;
600
+ for (k=0; k<n; k++) {
601
+ pm = m + k;
602
+ if ( ! *pm ) {
603
+ p1 = q1 + k*i1;
604
+ p2 = q2 + k*i2;
605
+ p3 = q3 + k*i3;
606
+ p4 = q4 + k*i4;
607
+ { (*p4) = (*p1) * (*p2) - (*p3); }
608
+ }
609
+ }
610
+ } else {
611
+ for (k=0; k<n; k++) {
612
+ p1 = q1 + k*i1;
613
+ p2 = q2 + k*i2;
614
+ p3 = q3 + k*i3;
615
+ p4 = q4 + k*i4;
616
+ { (*p4) = (*p1) * (*p2) - (*p3); }
617
+ }
618
+ }
619
+ }
620
+
621
+ static void
622
+ ca_triop_fms_uint16_t (ca_size_t n, boolean8_t *m,
623
+ char *ptr1, ca_size_t i1,
624
+ char *ptr2, ca_size_t i2,
625
+ char *ptr3, ca_size_t i3,
626
+ char *ptr4, ca_size_t i4)
627
+ {
628
+ uint16_t *q1 = (uint16_t *) ptr1, *q2 = (uint16_t *) ptr2,
629
+ *q3 = (uint16_t *) ptr3, *q4 = (uint16_t *) ptr4;
630
+ uint16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
631
+ ca_size_t k;
632
+ if ( m ) {
633
+ boolean8_t *pm;
634
+ for (k=0; k<n; k++) {
635
+ pm = m + k;
636
+ if ( ! *pm ) {
637
+ p1 = q1 + k*i1;
638
+ p2 = q2 + k*i2;
639
+ p3 = q3 + k*i3;
640
+ p4 = q4 + k*i4;
641
+ { (*p4) = (*p1) * (*p2) - (*p3); }
642
+ }
643
+ }
644
+ } else {
645
+ for (k=0; k<n; k++) {
646
+ p1 = q1 + k*i1;
647
+ p2 = q2 + k*i2;
648
+ p3 = q3 + k*i3;
649
+ p4 = q4 + k*i4;
650
+ { (*p4) = (*p1) * (*p2) - (*p3); }
651
+ }
652
+ }
653
+ }
654
+
655
+ static void
656
+ ca_triop_fms_int32_t (ca_size_t n, boolean8_t *m,
657
+ char *ptr1, ca_size_t i1,
658
+ char *ptr2, ca_size_t i2,
659
+ char *ptr3, ca_size_t i3,
660
+ char *ptr4, ca_size_t i4)
661
+ {
662
+ int32_t *q1 = (int32_t *) ptr1, *q2 = (int32_t *) ptr2,
663
+ *q3 = (int32_t *) ptr3, *q4 = (int32_t *) ptr4;
664
+ int32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
665
+ ca_size_t k;
666
+ if ( m ) {
667
+ boolean8_t *pm;
668
+ for (k=0; k<n; k++) {
669
+ pm = m + k;
670
+ if ( ! *pm ) {
671
+ p1 = q1 + k*i1;
672
+ p2 = q2 + k*i2;
673
+ p3 = q3 + k*i3;
674
+ p4 = q4 + k*i4;
675
+ { (*p4) = (*p1) * (*p2) - (*p3); }
676
+ }
677
+ }
678
+ } else {
679
+ for (k=0; k<n; k++) {
680
+ p1 = q1 + k*i1;
681
+ p2 = q2 + k*i2;
682
+ p3 = q3 + k*i3;
683
+ p4 = q4 + k*i4;
684
+ { (*p4) = (*p1) * (*p2) - (*p3); }
685
+ }
686
+ }
687
+ }
688
+
689
+ static void
690
+ ca_triop_fms_uint32_t (ca_size_t n, boolean8_t *m,
691
+ char *ptr1, ca_size_t i1,
692
+ char *ptr2, ca_size_t i2,
693
+ char *ptr3, ca_size_t i3,
694
+ char *ptr4, ca_size_t i4)
695
+ {
696
+ uint32_t *q1 = (uint32_t *) ptr1, *q2 = (uint32_t *) ptr2,
697
+ *q3 = (uint32_t *) ptr3, *q4 = (uint32_t *) ptr4;
698
+ uint32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
699
+ ca_size_t k;
700
+ if ( m ) {
701
+ boolean8_t *pm;
702
+ for (k=0; k<n; k++) {
703
+ pm = m + k;
704
+ if ( ! *pm ) {
705
+ p1 = q1 + k*i1;
706
+ p2 = q2 + k*i2;
707
+ p3 = q3 + k*i3;
708
+ p4 = q4 + k*i4;
709
+ { (*p4) = (*p1) * (*p2) - (*p3); }
710
+ }
711
+ }
712
+ } else {
713
+ for (k=0; k<n; k++) {
714
+ p1 = q1 + k*i1;
715
+ p2 = q2 + k*i2;
716
+ p3 = q3 + k*i3;
717
+ p4 = q4 + k*i4;
718
+ { (*p4) = (*p1) * (*p2) - (*p3); }
719
+ }
720
+ }
721
+ }
722
+
723
+ static void
724
+ ca_triop_fms_int64_t (ca_size_t n, boolean8_t *m,
725
+ char *ptr1, ca_size_t i1,
726
+ char *ptr2, ca_size_t i2,
727
+ char *ptr3, ca_size_t i3,
728
+ char *ptr4, ca_size_t i4)
729
+ {
730
+ int64_t *q1 = (int64_t *) ptr1, *q2 = (int64_t *) ptr2,
731
+ *q3 = (int64_t *) ptr3, *q4 = (int64_t *) ptr4;
732
+ int64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
733
+ ca_size_t k;
734
+ if ( m ) {
735
+ boolean8_t *pm;
736
+ for (k=0; k<n; k++) {
737
+ pm = m + k;
738
+ if ( ! *pm ) {
739
+ p1 = q1 + k*i1;
740
+ p2 = q2 + k*i2;
741
+ p3 = q3 + k*i3;
742
+ p4 = q4 + k*i4;
743
+ { (*p4) = (*p1) * (*p2) - (*p3); }
744
+ }
745
+ }
746
+ } else {
747
+ for (k=0; k<n; k++) {
748
+ p1 = q1 + k*i1;
749
+ p2 = q2 + k*i2;
750
+ p3 = q3 + k*i3;
751
+ p4 = q4 + k*i4;
752
+ { (*p4) = (*p1) * (*p2) - (*p3); }
753
+ }
754
+ }
755
+ }
756
+
757
+ static void
758
+ ca_triop_fms_uint64_t (ca_size_t n, boolean8_t *m,
759
+ char *ptr1, ca_size_t i1,
760
+ char *ptr2, ca_size_t i2,
761
+ char *ptr3, ca_size_t i3,
762
+ char *ptr4, ca_size_t i4)
763
+ {
764
+ uint64_t *q1 = (uint64_t *) ptr1, *q2 = (uint64_t *) ptr2,
765
+ *q3 = (uint64_t *) ptr3, *q4 = (uint64_t *) ptr4;
766
+ uint64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
767
+ ca_size_t k;
768
+ if ( m ) {
769
+ boolean8_t *pm;
770
+ for (k=0; k<n; k++) {
771
+ pm = m + k;
772
+ if ( ! *pm ) {
773
+ p1 = q1 + k*i1;
774
+ p2 = q2 + k*i2;
775
+ p3 = q3 + k*i3;
776
+ p4 = q4 + k*i4;
777
+ { (*p4) = (*p1) * (*p2) - (*p3); }
778
+ }
779
+ }
780
+ } else {
781
+ for (k=0; k<n; k++) {
782
+ p1 = q1 + k*i1;
783
+ p2 = q2 + k*i2;
784
+ p3 = q3 + k*i3;
785
+ p4 = q4 + k*i4;
786
+ { (*p4) = (*p1) * (*p2) - (*p3); }
787
+ }
788
+ }
789
+ }
790
+
791
+ static void
792
+ ca_triop_fms_float32_t (ca_size_t n, boolean8_t *m,
793
+ char *ptr1, ca_size_t i1,
794
+ char *ptr2, ca_size_t i2,
795
+ char *ptr3, ca_size_t i3,
796
+ char *ptr4, ca_size_t i4)
797
+ {
798
+ float *q1 = (float *) ptr1, *q2 = (float *) ptr2,
799
+ *q3 = (float *) ptr3, *q4 = (float *) ptr4;
800
+ float *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
801
+ ca_size_t k;
802
+ if ( m ) {
803
+ boolean8_t *pm;
804
+ for (k=0; k<n; k++) {
805
+ pm = m + k;
806
+ if ( ! *pm ) {
807
+ p1 = q1 + k*i1;
808
+ p2 = q2 + k*i2;
809
+ p3 = q3 + k*i3;
810
+ p4 = q4 + k*i4;
811
+ { (*p4) = fmaf((*p1), (*p2), -(*p3)); }
812
+ }
813
+ }
814
+ } else {
815
+ for (k=0; k<n; k++) {
816
+ p1 = q1 + k*i1;
817
+ p2 = q2 + k*i2;
818
+ p3 = q3 + k*i3;
819
+ p4 = q4 + k*i4;
820
+ { (*p4) = fmaf((*p1), (*p2), -(*p3)); }
821
+ }
822
+ }
823
+ }
824
+
825
+ static void
826
+ ca_triop_fms_float64_t (ca_size_t n, boolean8_t *m,
827
+ char *ptr1, ca_size_t i1,
828
+ char *ptr2, ca_size_t i2,
829
+ char *ptr3, ca_size_t i3,
830
+ char *ptr4, ca_size_t i4)
831
+ {
832
+ double *q1 = (double *) ptr1, *q2 = (double *) ptr2,
833
+ *q3 = (double *) ptr3, *q4 = (double *) ptr4;
834
+ double *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
835
+ ca_size_t k;
836
+ if ( m ) {
837
+ boolean8_t *pm;
838
+ for (k=0; k<n; k++) {
839
+ pm = m + k;
840
+ if ( ! *pm ) {
841
+ p1 = q1 + k*i1;
842
+ p2 = q2 + k*i2;
843
+ p3 = q3 + k*i3;
844
+ p4 = q4 + k*i4;
845
+ { (*p4) = fma((*p1), (*p2), -(*p3)); }
846
+ }
847
+ }
848
+ } else {
849
+ for (k=0; k<n; k++) {
850
+ p1 = q1 + k*i1;
851
+ p2 = q2 + k*i2;
852
+ p3 = q3 + k*i3;
853
+ p4 = q4 + k*i4;
854
+ { (*p4) = fma((*p1), (*p2), -(*p3)); }
855
+ }
856
+ }
857
+ }
858
+
859
+ static void
860
+ ca_triop_fms_cmplx64_t (ca_size_t n, boolean8_t *m,
861
+ char *ptr1, ca_size_t i1,
862
+ char *ptr2, ca_size_t i2,
863
+ char *ptr3, ca_size_t i3,
864
+ char *ptr4, ca_size_t i4)
865
+ {
866
+ cmplx64_t *q1 = (cmplx64_t *) ptr1, *q2 = (cmplx64_t *) ptr2,
867
+ *q3 = (cmplx64_t *) ptr3, *q4 = (cmplx64_t *) ptr4;
868
+ cmplx64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
869
+ ca_size_t k;
870
+ if ( m ) {
871
+ boolean8_t *pm;
872
+ for (k=0; k<n; k++) {
873
+ pm = m + k;
874
+ if ( ! *pm ) {
875
+ p1 = q1 + k*i1;
876
+ p2 = q2 + k*i2;
877
+ p3 = q3 + k*i3;
878
+ p4 = q4 + k*i4;
879
+ { (*p4) = (*p1) * (*p2) - (*p3); }
880
+ }
881
+ }
882
+ } else {
883
+ for (k=0; k<n; k++) {
884
+ p1 = q1 + k*i1;
885
+ p2 = q2 + k*i2;
886
+ p3 = q3 + k*i3;
887
+ p4 = q4 + k*i4;
888
+ { (*p4) = (*p1) * (*p2) - (*p3); }
889
+ }
890
+ }
891
+ }
892
+
893
+ static void
894
+ ca_triop_fms_cmplx128_t (ca_size_t n, boolean8_t *m,
895
+ char *ptr1, ca_size_t i1,
896
+ char *ptr2, ca_size_t i2,
897
+ char *ptr3, ca_size_t i3,
898
+ char *ptr4, ca_size_t i4)
899
+ {
900
+ cmplx128_t *q1 = (cmplx128_t *) ptr1, *q2 = (cmplx128_t *) ptr2,
901
+ *q3 = (cmplx128_t *) ptr3, *q4 = (cmplx128_t *) ptr4;
902
+ cmplx128_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
903
+ ca_size_t k;
904
+ if ( m ) {
905
+ boolean8_t *pm;
906
+ for (k=0; k<n; k++) {
907
+ pm = m + k;
908
+ if ( ! *pm ) {
909
+ p1 = q1 + k*i1;
910
+ p2 = q2 + k*i2;
911
+ p3 = q3 + k*i3;
912
+ p4 = q4 + k*i4;
913
+ { (*p4) = (*p1) * (*p2) - (*p3); }
914
+ }
915
+ }
916
+ } else {
917
+ for (k=0; k<n; k++) {
918
+ p1 = q1 + k*i1;
919
+ p2 = q2 + k*i2;
920
+ p3 = q3 + k*i3;
921
+ p4 = q4 + k*i4;
922
+ { (*p4) = (*p1) * (*p2) - (*p3); }
923
+ }
924
+ }
925
+ }
926
+
927
+ static void
928
+ ca_triop_fms_VALUE (ca_size_t n, boolean8_t *m,
929
+ char *ptr1, ca_size_t i1,
930
+ char *ptr2, ca_size_t i2,
931
+ char *ptr3, ca_size_t i3,
932
+ char *ptr4, ca_size_t i4)
933
+ {
934
+ VALUE *q1 = (VALUE *) ptr1, *q2 = (VALUE *) ptr2,
935
+ *q3 = (VALUE *) ptr3, *q4 = (VALUE *) ptr4;
936
+ VALUE *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
937
+ ca_size_t k;
938
+ if ( m ) {
939
+ boolean8_t *pm;
940
+ for (k=0; k<n; k++) {
941
+ pm = m + k;
942
+ if ( ! *pm ) {
943
+ p1 = q1 + k*i1;
944
+ p2 = q2 + k*i2;
945
+ p3 = q3 + k*i3;
946
+ p4 = q4 + k*i4;
947
+ { (*p4) = rb_funcall(rb_funcall((*p1), rb_intern("*"), 1, (*p2)), rb_intern("-"), 1, (*p3)); }
948
+ }
949
+ }
950
+ } else {
951
+ for (k=0; k<n; k++) {
952
+ p1 = q1 + k*i1;
953
+ p2 = q2 + k*i2;
954
+ p3 = q3 + k*i3;
955
+ p4 = q4 + k*i4;
956
+ { (*p4) = rb_funcall(rb_funcall((*p1), rb_intern("*"), 1, (*p2)), rb_intern("-"), 1, (*p3)); }
957
+ }
958
+ }
959
+ }
960
+
961
+ ca_triop_func_t
962
+ ca_triop_fms[CA_NTYPE] = {
963
+ ca_triop_not_implement,
964
+ ca_triop_not_implement,
965
+ ca_triop_fms_int8_t,
966
+ ca_triop_fms_uint8_t,
967
+ ca_triop_fms_int16_t,
968
+ ca_triop_fms_uint16_t,
969
+ ca_triop_fms_int32_t,
970
+ ca_triop_fms_uint32_t,
971
+ ca_triop_fms_int64_t,
972
+ ca_triop_fms_uint64_t,
973
+ ca_triop_fms_float32_t,
974
+ ca_triop_fms_float64_t,
975
+ ca_triop_not_implement,
976
+ ca_triop_fms_cmplx64_t,
977
+ ca_triop_fms_cmplx128_t,
978
+ ca_triop_not_implement,
979
+ ca_triop_fms_VALUE,
980
+ };
981
+
982
+ VALUE rb_ca_fms (VALUE self, VALUE other2, VALUE other3)
983
+ { return rb_ca_call_triop(self, other2, other3, ca_triop_fms); }
984
+
985
+ VALUE rb_ca_fms_bang (VALUE self, VALUE other2, VALUE other3)
986
+ { return rb_ca_call_triop_bang(self, other2, other3, ca_triop_fms); }
987
+
988
+ /* ===== triop clip ============================================ */
989
+
990
+ static void
991
+ ca_triop_clip_int8_t (ca_size_t n, boolean8_t *m,
992
+ char *ptr1, ca_size_t i1,
993
+ char *ptr2, ca_size_t i2,
994
+ char *ptr3, ca_size_t i3,
995
+ char *ptr4, ca_size_t i4)
996
+ {
997
+ int8_t *q1 = (int8_t *) ptr1, *q2 = (int8_t *) ptr2,
998
+ *q3 = (int8_t *) ptr3, *q4 = (int8_t *) ptr4;
999
+ int8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1000
+ ca_size_t k;
1001
+ if ( m ) {
1002
+ boolean8_t *pm;
1003
+ for (k=0; k<n; k++) {
1004
+ pm = m + k;
1005
+ if ( ! *pm ) {
1006
+ p1 = q1 + k*i1;
1007
+ p2 = q2 + k*i2;
1008
+ p3 = q3 + k*i3;
1009
+ p4 = q4 + k*i4;
1010
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1011
+ }
1012
+ }
1013
+ } else {
1014
+ for (k=0; k<n; k++) {
1015
+ p1 = q1 + k*i1;
1016
+ p2 = q2 + k*i2;
1017
+ p3 = q3 + k*i3;
1018
+ p4 = q4 + k*i4;
1019
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1020
+ }
1021
+ }
1022
+ }
1023
+
1024
+ static void
1025
+ ca_triop_clip_uint8_t (ca_size_t n, boolean8_t *m,
1026
+ char *ptr1, ca_size_t i1,
1027
+ char *ptr2, ca_size_t i2,
1028
+ char *ptr3, ca_size_t i3,
1029
+ char *ptr4, ca_size_t i4)
1030
+ {
1031
+ uint8_t *q1 = (uint8_t *) ptr1, *q2 = (uint8_t *) ptr2,
1032
+ *q3 = (uint8_t *) ptr3, *q4 = (uint8_t *) ptr4;
1033
+ uint8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1034
+ ca_size_t k;
1035
+ if ( m ) {
1036
+ boolean8_t *pm;
1037
+ for (k=0; k<n; k++) {
1038
+ pm = m + k;
1039
+ if ( ! *pm ) {
1040
+ p1 = q1 + k*i1;
1041
+ p2 = q2 + k*i2;
1042
+ p3 = q3 + k*i3;
1043
+ p4 = q4 + k*i4;
1044
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1045
+ }
1046
+ }
1047
+ } else {
1048
+ for (k=0; k<n; k++) {
1049
+ p1 = q1 + k*i1;
1050
+ p2 = q2 + k*i2;
1051
+ p3 = q3 + k*i3;
1052
+ p4 = q4 + k*i4;
1053
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1054
+ }
1055
+ }
1056
+ }
1057
+
1058
+ static void
1059
+ ca_triop_clip_int16_t (ca_size_t n, boolean8_t *m,
1060
+ char *ptr1, ca_size_t i1,
1061
+ char *ptr2, ca_size_t i2,
1062
+ char *ptr3, ca_size_t i3,
1063
+ char *ptr4, ca_size_t i4)
1064
+ {
1065
+ int16_t *q1 = (int16_t *) ptr1, *q2 = (int16_t *) ptr2,
1066
+ *q3 = (int16_t *) ptr3, *q4 = (int16_t *) ptr4;
1067
+ int16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1068
+ ca_size_t k;
1069
+ if ( m ) {
1070
+ boolean8_t *pm;
1071
+ for (k=0; k<n; k++) {
1072
+ pm = m + k;
1073
+ if ( ! *pm ) {
1074
+ p1 = q1 + k*i1;
1075
+ p2 = q2 + k*i2;
1076
+ p3 = q3 + k*i3;
1077
+ p4 = q4 + k*i4;
1078
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1079
+ }
1080
+ }
1081
+ } else {
1082
+ for (k=0; k<n; k++) {
1083
+ p1 = q1 + k*i1;
1084
+ p2 = q2 + k*i2;
1085
+ p3 = q3 + k*i3;
1086
+ p4 = q4 + k*i4;
1087
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1088
+ }
1089
+ }
1090
+ }
1091
+
1092
+ static void
1093
+ ca_triop_clip_uint16_t (ca_size_t n, boolean8_t *m,
1094
+ char *ptr1, ca_size_t i1,
1095
+ char *ptr2, ca_size_t i2,
1096
+ char *ptr3, ca_size_t i3,
1097
+ char *ptr4, ca_size_t i4)
1098
+ {
1099
+ uint16_t *q1 = (uint16_t *) ptr1, *q2 = (uint16_t *) ptr2,
1100
+ *q3 = (uint16_t *) ptr3, *q4 = (uint16_t *) ptr4;
1101
+ uint16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1102
+ ca_size_t k;
1103
+ if ( m ) {
1104
+ boolean8_t *pm;
1105
+ for (k=0; k<n; k++) {
1106
+ pm = m + k;
1107
+ if ( ! *pm ) {
1108
+ p1 = q1 + k*i1;
1109
+ p2 = q2 + k*i2;
1110
+ p3 = q3 + k*i3;
1111
+ p4 = q4 + k*i4;
1112
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1113
+ }
1114
+ }
1115
+ } else {
1116
+ for (k=0; k<n; k++) {
1117
+ p1 = q1 + k*i1;
1118
+ p2 = q2 + k*i2;
1119
+ p3 = q3 + k*i3;
1120
+ p4 = q4 + k*i4;
1121
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1122
+ }
1123
+ }
1124
+ }
1125
+
1126
+ static void
1127
+ ca_triop_clip_int32_t (ca_size_t n, boolean8_t *m,
1128
+ char *ptr1, ca_size_t i1,
1129
+ char *ptr2, ca_size_t i2,
1130
+ char *ptr3, ca_size_t i3,
1131
+ char *ptr4, ca_size_t i4)
1132
+ {
1133
+ int32_t *q1 = (int32_t *) ptr1, *q2 = (int32_t *) ptr2,
1134
+ *q3 = (int32_t *) ptr3, *q4 = (int32_t *) ptr4;
1135
+ int32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1136
+ ca_size_t k;
1137
+ if ( m ) {
1138
+ boolean8_t *pm;
1139
+ for (k=0; k<n; k++) {
1140
+ pm = m + k;
1141
+ if ( ! *pm ) {
1142
+ p1 = q1 + k*i1;
1143
+ p2 = q2 + k*i2;
1144
+ p3 = q3 + k*i3;
1145
+ p4 = q4 + k*i4;
1146
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1147
+ }
1148
+ }
1149
+ } else {
1150
+ for (k=0; k<n; k++) {
1151
+ p1 = q1 + k*i1;
1152
+ p2 = q2 + k*i2;
1153
+ p3 = q3 + k*i3;
1154
+ p4 = q4 + k*i4;
1155
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1156
+ }
1157
+ }
1158
+ }
1159
+
1160
+ static void
1161
+ ca_triop_clip_uint32_t (ca_size_t n, boolean8_t *m,
1162
+ char *ptr1, ca_size_t i1,
1163
+ char *ptr2, ca_size_t i2,
1164
+ char *ptr3, ca_size_t i3,
1165
+ char *ptr4, ca_size_t i4)
1166
+ {
1167
+ uint32_t *q1 = (uint32_t *) ptr1, *q2 = (uint32_t *) ptr2,
1168
+ *q3 = (uint32_t *) ptr3, *q4 = (uint32_t *) ptr4;
1169
+ uint32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1170
+ ca_size_t k;
1171
+ if ( m ) {
1172
+ boolean8_t *pm;
1173
+ for (k=0; k<n; k++) {
1174
+ pm = m + k;
1175
+ if ( ! *pm ) {
1176
+ p1 = q1 + k*i1;
1177
+ p2 = q2 + k*i2;
1178
+ p3 = q3 + k*i3;
1179
+ p4 = q4 + k*i4;
1180
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1181
+ }
1182
+ }
1183
+ } else {
1184
+ for (k=0; k<n; k++) {
1185
+ p1 = q1 + k*i1;
1186
+ p2 = q2 + k*i2;
1187
+ p3 = q3 + k*i3;
1188
+ p4 = q4 + k*i4;
1189
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1190
+ }
1191
+ }
1192
+ }
1193
+
1194
+ static void
1195
+ ca_triop_clip_int64_t (ca_size_t n, boolean8_t *m,
1196
+ char *ptr1, ca_size_t i1,
1197
+ char *ptr2, ca_size_t i2,
1198
+ char *ptr3, ca_size_t i3,
1199
+ char *ptr4, ca_size_t i4)
1200
+ {
1201
+ int64_t *q1 = (int64_t *) ptr1, *q2 = (int64_t *) ptr2,
1202
+ *q3 = (int64_t *) ptr3, *q4 = (int64_t *) ptr4;
1203
+ int64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1204
+ ca_size_t k;
1205
+ if ( m ) {
1206
+ boolean8_t *pm;
1207
+ for (k=0; k<n; k++) {
1208
+ pm = m + k;
1209
+ if ( ! *pm ) {
1210
+ p1 = q1 + k*i1;
1211
+ p2 = q2 + k*i2;
1212
+ p3 = q3 + k*i3;
1213
+ p4 = q4 + k*i4;
1214
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1215
+ }
1216
+ }
1217
+ } else {
1218
+ for (k=0; k<n; k++) {
1219
+ p1 = q1 + k*i1;
1220
+ p2 = q2 + k*i2;
1221
+ p3 = q3 + k*i3;
1222
+ p4 = q4 + k*i4;
1223
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ static void
1229
+ ca_triop_clip_uint64_t (ca_size_t n, boolean8_t *m,
1230
+ char *ptr1, ca_size_t i1,
1231
+ char *ptr2, ca_size_t i2,
1232
+ char *ptr3, ca_size_t i3,
1233
+ char *ptr4, ca_size_t i4)
1234
+ {
1235
+ uint64_t *q1 = (uint64_t *) ptr1, *q2 = (uint64_t *) ptr2,
1236
+ *q3 = (uint64_t *) ptr3, *q4 = (uint64_t *) ptr4;
1237
+ uint64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1238
+ ca_size_t k;
1239
+ if ( m ) {
1240
+ boolean8_t *pm;
1241
+ for (k=0; k<n; k++) {
1242
+ pm = m + k;
1243
+ if ( ! *pm ) {
1244
+ p1 = q1 + k*i1;
1245
+ p2 = q2 + k*i2;
1246
+ p3 = q3 + k*i3;
1247
+ p4 = q4 + k*i4;
1248
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1249
+ }
1250
+ }
1251
+ } else {
1252
+ for (k=0; k<n; k++) {
1253
+ p1 = q1 + k*i1;
1254
+ p2 = q2 + k*i2;
1255
+ p3 = q3 + k*i3;
1256
+ p4 = q4 + k*i4;
1257
+ { (*p4) = ((*p1) < (*p2)) ? (*p2) : (((*p1) > (*p3)) ? (*p3) : (*p1)); }
1258
+ }
1259
+ }
1260
+ }
1261
+
1262
+ static void
1263
+ ca_triop_clip_float32_t (ca_size_t n, boolean8_t *m,
1264
+ char *ptr1, ca_size_t i1,
1265
+ char *ptr2, ca_size_t i2,
1266
+ char *ptr3, ca_size_t i3,
1267
+ char *ptr4, ca_size_t i4)
1268
+ {
1269
+ float *q1 = (float *) ptr1, *q2 = (float *) ptr2,
1270
+ *q3 = (float *) ptr3, *q4 = (float *) ptr4;
1271
+ float *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1272
+ ca_size_t k;
1273
+ if ( m ) {
1274
+ boolean8_t *pm;
1275
+ for (k=0; k<n; k++) {
1276
+ pm = m + k;
1277
+ if ( ! *pm ) {
1278
+ p1 = q1 + k*i1;
1279
+ p2 = q2 + k*i2;
1280
+ p3 = q3 + k*i3;
1281
+ p4 = q4 + k*i4;
1282
+ { (*p4) = isnan(*p1) ? (*p1) : fmin(fmax((*p1), (*p2)), (*p3)); }
1283
+ }
1284
+ }
1285
+ } else {
1286
+ for (k=0; k<n; k++) {
1287
+ p1 = q1 + k*i1;
1288
+ p2 = q2 + k*i2;
1289
+ p3 = q3 + k*i3;
1290
+ p4 = q4 + k*i4;
1291
+ { (*p4) = isnan(*p1) ? (*p1) : fmin(fmax((*p1), (*p2)), (*p3)); }
1292
+ }
1293
+ }
1294
+ }
1295
+
1296
+ static void
1297
+ ca_triop_clip_float64_t (ca_size_t n, boolean8_t *m,
1298
+ char *ptr1, ca_size_t i1,
1299
+ char *ptr2, ca_size_t i2,
1300
+ char *ptr3, ca_size_t i3,
1301
+ char *ptr4, ca_size_t i4)
1302
+ {
1303
+ double *q1 = (double *) ptr1, *q2 = (double *) ptr2,
1304
+ *q3 = (double *) ptr3, *q4 = (double *) ptr4;
1305
+ double *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1306
+ ca_size_t k;
1307
+ if ( m ) {
1308
+ boolean8_t *pm;
1309
+ for (k=0; k<n; k++) {
1310
+ pm = m + k;
1311
+ if ( ! *pm ) {
1312
+ p1 = q1 + k*i1;
1313
+ p2 = q2 + k*i2;
1314
+ p3 = q3 + k*i3;
1315
+ p4 = q4 + k*i4;
1316
+ { (*p4) = isnan(*p1) ? (*p1) : fmin(fmax((*p1), (*p2)), (*p3)); }
1317
+ }
1318
+ }
1319
+ } else {
1320
+ for (k=0; k<n; k++) {
1321
+ p1 = q1 + k*i1;
1322
+ p2 = q2 + k*i2;
1323
+ p3 = q3 + k*i3;
1324
+ p4 = q4 + k*i4;
1325
+ { (*p4) = isnan(*p1) ? (*p1) : fmin(fmax((*p1), (*p2)), (*p3)); }
1326
+ }
1327
+ }
1328
+ }
1329
+
1330
+ static void
1331
+ ca_triop_clip_VALUE (ca_size_t n, boolean8_t *m,
1332
+ char *ptr1, ca_size_t i1,
1333
+ char *ptr2, ca_size_t i2,
1334
+ char *ptr3, ca_size_t i3,
1335
+ char *ptr4, ca_size_t i4)
1336
+ {
1337
+ VALUE *q1 = (VALUE *) ptr1, *q2 = (VALUE *) ptr2,
1338
+ *q3 = (VALUE *) ptr3, *q4 = (VALUE *) ptr4;
1339
+ VALUE *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1340
+ ca_size_t k;
1341
+ if ( m ) {
1342
+ boolean8_t *pm;
1343
+ for (k=0; k<n; k++) {
1344
+ pm = m + k;
1345
+ if ( ! *pm ) {
1346
+ p1 = q1 + k*i1;
1347
+ p2 = q2 + k*i2;
1348
+ p3 = q3 + k*i3;
1349
+ p4 = q4 + k*i4;
1350
+ { { VALUE _v=(*p1); if (rb_funcall(_v, rb_intern("<"), 1, (*p2))) _v=(*p2); else if (rb_funcall(_v, rb_intern(">"), 1, (*p3))) _v=(*p3); (*p4) = _v; } }
1351
+ }
1352
+ }
1353
+ } else {
1354
+ for (k=0; k<n; k++) {
1355
+ p1 = q1 + k*i1;
1356
+ p2 = q2 + k*i2;
1357
+ p3 = q3 + k*i3;
1358
+ p4 = q4 + k*i4;
1359
+ { { VALUE _v=(*p1); if (rb_funcall(_v, rb_intern("<"), 1, (*p2))) _v=(*p2); else if (rb_funcall(_v, rb_intern(">"), 1, (*p3))) _v=(*p3); (*p4) = _v; } }
1360
+ }
1361
+ }
1362
+ }
1363
+
1364
+ ca_triop_func_t
1365
+ ca_triop_clip[CA_NTYPE] = {
1366
+ ca_triop_not_implement,
1367
+ ca_triop_not_implement,
1368
+ ca_triop_clip_int8_t,
1369
+ ca_triop_clip_uint8_t,
1370
+ ca_triop_clip_int16_t,
1371
+ ca_triop_clip_uint16_t,
1372
+ ca_triop_clip_int32_t,
1373
+ ca_triop_clip_uint32_t,
1374
+ ca_triop_clip_int64_t,
1375
+ ca_triop_clip_uint64_t,
1376
+ ca_triop_clip_float32_t,
1377
+ ca_triop_clip_float64_t,
1378
+ ca_triop_not_implement,
1379
+ ca_triop_not_implement,
1380
+ ca_triop_not_implement,
1381
+ ca_triop_not_implement,
1382
+ ca_triop_clip_VALUE,
1383
+ };
1384
+
1385
+ VALUE rb_ca_clip (VALUE self, VALUE other2, VALUE other3)
1386
+ { return rb_ca_call_triop(self, other2, other3, ca_triop_clip); }
1387
+
1388
+ /* ===== triop select ============================================ */
1389
+
1390
+ static void
1391
+ ca_triop_select_int8_t (ca_size_t n, boolean8_t *m,
1392
+ char *ptr1, ca_size_t i1,
1393
+ char *ptr2, ca_size_t i2,
1394
+ char *ptr3, ca_size_t i3,
1395
+ char *ptr4, ca_size_t i4)
1396
+ {
1397
+ int8_t *q1 = (int8_t *) ptr1, *q2 = (int8_t *) ptr2,
1398
+ *q3 = (int8_t *) ptr3, *q4 = (int8_t *) ptr4;
1399
+ int8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1400
+ ca_size_t k;
1401
+ if ( m ) {
1402
+ boolean8_t *pm;
1403
+ for (k=0; k<n; k++) {
1404
+ pm = m + k;
1405
+ if ( ! *pm ) {
1406
+ p1 = q1 + k*i1;
1407
+ p2 = q2 + k*i2;
1408
+ p3 = q3 + k*i3;
1409
+ p4 = q4 + k*i4;
1410
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1411
+ }
1412
+ }
1413
+ } else {
1414
+ for (k=0; k<n; k++) {
1415
+ p1 = q1 + k*i1;
1416
+ p2 = q2 + k*i2;
1417
+ p3 = q3 + k*i3;
1418
+ p4 = q4 + k*i4;
1419
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1420
+ }
1421
+ }
1422
+ }
1423
+
1424
+ static void
1425
+ ca_triop_select_uint8_t (ca_size_t n, boolean8_t *m,
1426
+ char *ptr1, ca_size_t i1,
1427
+ char *ptr2, ca_size_t i2,
1428
+ char *ptr3, ca_size_t i3,
1429
+ char *ptr4, ca_size_t i4)
1430
+ {
1431
+ uint8_t *q1 = (uint8_t *) ptr1, *q2 = (uint8_t *) ptr2,
1432
+ *q3 = (uint8_t *) ptr3, *q4 = (uint8_t *) ptr4;
1433
+ uint8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1434
+ ca_size_t k;
1435
+ if ( m ) {
1436
+ boolean8_t *pm;
1437
+ for (k=0; k<n; k++) {
1438
+ pm = m + k;
1439
+ if ( ! *pm ) {
1440
+ p1 = q1 + k*i1;
1441
+ p2 = q2 + k*i2;
1442
+ p3 = q3 + k*i3;
1443
+ p4 = q4 + k*i4;
1444
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1445
+ }
1446
+ }
1447
+ } else {
1448
+ for (k=0; k<n; k++) {
1449
+ p1 = q1 + k*i1;
1450
+ p2 = q2 + k*i2;
1451
+ p3 = q3 + k*i3;
1452
+ p4 = q4 + k*i4;
1453
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1454
+ }
1455
+ }
1456
+ }
1457
+
1458
+ static void
1459
+ ca_triop_select_int16_t (ca_size_t n, boolean8_t *m,
1460
+ char *ptr1, ca_size_t i1,
1461
+ char *ptr2, ca_size_t i2,
1462
+ char *ptr3, ca_size_t i3,
1463
+ char *ptr4, ca_size_t i4)
1464
+ {
1465
+ int16_t *q1 = (int16_t *) ptr1, *q2 = (int16_t *) ptr2,
1466
+ *q3 = (int16_t *) ptr3, *q4 = (int16_t *) ptr4;
1467
+ int16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1468
+ ca_size_t k;
1469
+ if ( m ) {
1470
+ boolean8_t *pm;
1471
+ for (k=0; k<n; k++) {
1472
+ pm = m + k;
1473
+ if ( ! *pm ) {
1474
+ p1 = q1 + k*i1;
1475
+ p2 = q2 + k*i2;
1476
+ p3 = q3 + k*i3;
1477
+ p4 = q4 + k*i4;
1478
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1479
+ }
1480
+ }
1481
+ } else {
1482
+ for (k=0; k<n; k++) {
1483
+ p1 = q1 + k*i1;
1484
+ p2 = q2 + k*i2;
1485
+ p3 = q3 + k*i3;
1486
+ p4 = q4 + k*i4;
1487
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1488
+ }
1489
+ }
1490
+ }
1491
+
1492
+ static void
1493
+ ca_triop_select_uint16_t (ca_size_t n, boolean8_t *m,
1494
+ char *ptr1, ca_size_t i1,
1495
+ char *ptr2, ca_size_t i2,
1496
+ char *ptr3, ca_size_t i3,
1497
+ char *ptr4, ca_size_t i4)
1498
+ {
1499
+ uint16_t *q1 = (uint16_t *) ptr1, *q2 = (uint16_t *) ptr2,
1500
+ *q3 = (uint16_t *) ptr3, *q4 = (uint16_t *) ptr4;
1501
+ uint16_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1502
+ ca_size_t k;
1503
+ if ( m ) {
1504
+ boolean8_t *pm;
1505
+ for (k=0; k<n; k++) {
1506
+ pm = m + k;
1507
+ if ( ! *pm ) {
1508
+ p1 = q1 + k*i1;
1509
+ p2 = q2 + k*i2;
1510
+ p3 = q3 + k*i3;
1511
+ p4 = q4 + k*i4;
1512
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1513
+ }
1514
+ }
1515
+ } else {
1516
+ for (k=0; k<n; k++) {
1517
+ p1 = q1 + k*i1;
1518
+ p2 = q2 + k*i2;
1519
+ p3 = q3 + k*i3;
1520
+ p4 = q4 + k*i4;
1521
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1522
+ }
1523
+ }
1524
+ }
1525
+
1526
+ static void
1527
+ ca_triop_select_int32_t (ca_size_t n, boolean8_t *m,
1528
+ char *ptr1, ca_size_t i1,
1529
+ char *ptr2, ca_size_t i2,
1530
+ char *ptr3, ca_size_t i3,
1531
+ char *ptr4, ca_size_t i4)
1532
+ {
1533
+ int32_t *q1 = (int32_t *) ptr1, *q2 = (int32_t *) ptr2,
1534
+ *q3 = (int32_t *) ptr3, *q4 = (int32_t *) ptr4;
1535
+ int32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1536
+ ca_size_t k;
1537
+ if ( m ) {
1538
+ boolean8_t *pm;
1539
+ for (k=0; k<n; k++) {
1540
+ pm = m + k;
1541
+ if ( ! *pm ) {
1542
+ p1 = q1 + k*i1;
1543
+ p2 = q2 + k*i2;
1544
+ p3 = q3 + k*i3;
1545
+ p4 = q4 + k*i4;
1546
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1547
+ }
1548
+ }
1549
+ } else {
1550
+ for (k=0; k<n; k++) {
1551
+ p1 = q1 + k*i1;
1552
+ p2 = q2 + k*i2;
1553
+ p3 = q3 + k*i3;
1554
+ p4 = q4 + k*i4;
1555
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1556
+ }
1557
+ }
1558
+ }
1559
+
1560
+ static void
1561
+ ca_triop_select_uint32_t (ca_size_t n, boolean8_t *m,
1562
+ char *ptr1, ca_size_t i1,
1563
+ char *ptr2, ca_size_t i2,
1564
+ char *ptr3, ca_size_t i3,
1565
+ char *ptr4, ca_size_t i4)
1566
+ {
1567
+ uint32_t *q1 = (uint32_t *) ptr1, *q2 = (uint32_t *) ptr2,
1568
+ *q3 = (uint32_t *) ptr3, *q4 = (uint32_t *) ptr4;
1569
+ uint32_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1570
+ ca_size_t k;
1571
+ if ( m ) {
1572
+ boolean8_t *pm;
1573
+ for (k=0; k<n; k++) {
1574
+ pm = m + k;
1575
+ if ( ! *pm ) {
1576
+ p1 = q1 + k*i1;
1577
+ p2 = q2 + k*i2;
1578
+ p3 = q3 + k*i3;
1579
+ p4 = q4 + k*i4;
1580
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1581
+ }
1582
+ }
1583
+ } else {
1584
+ for (k=0; k<n; k++) {
1585
+ p1 = q1 + k*i1;
1586
+ p2 = q2 + k*i2;
1587
+ p3 = q3 + k*i3;
1588
+ p4 = q4 + k*i4;
1589
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1590
+ }
1591
+ }
1592
+ }
1593
+
1594
+ static void
1595
+ ca_triop_select_int64_t (ca_size_t n, boolean8_t *m,
1596
+ char *ptr1, ca_size_t i1,
1597
+ char *ptr2, ca_size_t i2,
1598
+ char *ptr3, ca_size_t i3,
1599
+ char *ptr4, ca_size_t i4)
1600
+ {
1601
+ int64_t *q1 = (int64_t *) ptr1, *q2 = (int64_t *) ptr2,
1602
+ *q3 = (int64_t *) ptr3, *q4 = (int64_t *) ptr4;
1603
+ int64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1604
+ ca_size_t k;
1605
+ if ( m ) {
1606
+ boolean8_t *pm;
1607
+ for (k=0; k<n; k++) {
1608
+ pm = m + k;
1609
+ if ( ! *pm ) {
1610
+ p1 = q1 + k*i1;
1611
+ p2 = q2 + k*i2;
1612
+ p3 = q3 + k*i3;
1613
+ p4 = q4 + k*i4;
1614
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1615
+ }
1616
+ }
1617
+ } else {
1618
+ for (k=0; k<n; k++) {
1619
+ p1 = q1 + k*i1;
1620
+ p2 = q2 + k*i2;
1621
+ p3 = q3 + k*i3;
1622
+ p4 = q4 + k*i4;
1623
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1624
+ }
1625
+ }
1626
+ }
1627
+
1628
+ static void
1629
+ ca_triop_select_uint64_t (ca_size_t n, boolean8_t *m,
1630
+ char *ptr1, ca_size_t i1,
1631
+ char *ptr2, ca_size_t i2,
1632
+ char *ptr3, ca_size_t i3,
1633
+ char *ptr4, ca_size_t i4)
1634
+ {
1635
+ uint64_t *q1 = (uint64_t *) ptr1, *q2 = (uint64_t *) ptr2,
1636
+ *q3 = (uint64_t *) ptr3, *q4 = (uint64_t *) ptr4;
1637
+ uint64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1638
+ ca_size_t k;
1639
+ if ( m ) {
1640
+ boolean8_t *pm;
1641
+ for (k=0; k<n; k++) {
1642
+ pm = m + k;
1643
+ if ( ! *pm ) {
1644
+ p1 = q1 + k*i1;
1645
+ p2 = q2 + k*i2;
1646
+ p3 = q3 + k*i3;
1647
+ p4 = q4 + k*i4;
1648
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1649
+ }
1650
+ }
1651
+ } else {
1652
+ for (k=0; k<n; k++) {
1653
+ p1 = q1 + k*i1;
1654
+ p2 = q2 + k*i2;
1655
+ p3 = q3 + k*i3;
1656
+ p4 = q4 + k*i4;
1657
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1658
+ }
1659
+ }
1660
+ }
1661
+
1662
+ static void
1663
+ ca_triop_select_float32_t (ca_size_t n, boolean8_t *m,
1664
+ char *ptr1, ca_size_t i1,
1665
+ char *ptr2, ca_size_t i2,
1666
+ char *ptr3, ca_size_t i3,
1667
+ char *ptr4, ca_size_t i4)
1668
+ {
1669
+ float *q1 = (float *) ptr1, *q2 = (float *) ptr2,
1670
+ *q3 = (float *) ptr3, *q4 = (float *) ptr4;
1671
+ float *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1672
+ ca_size_t k;
1673
+ if ( m ) {
1674
+ boolean8_t *pm;
1675
+ for (k=0; k<n; k++) {
1676
+ pm = m + k;
1677
+ if ( ! *pm ) {
1678
+ p1 = q1 + k*i1;
1679
+ p2 = q2 + k*i2;
1680
+ p3 = q3 + k*i3;
1681
+ p4 = q4 + k*i4;
1682
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1683
+ }
1684
+ }
1685
+ } else {
1686
+ for (k=0; k<n; k++) {
1687
+ p1 = q1 + k*i1;
1688
+ p2 = q2 + k*i2;
1689
+ p3 = q3 + k*i3;
1690
+ p4 = q4 + k*i4;
1691
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1692
+ }
1693
+ }
1694
+ }
1695
+
1696
+ static void
1697
+ ca_triop_select_float64_t (ca_size_t n, boolean8_t *m,
1698
+ char *ptr1, ca_size_t i1,
1699
+ char *ptr2, ca_size_t i2,
1700
+ char *ptr3, ca_size_t i3,
1701
+ char *ptr4, ca_size_t i4)
1702
+ {
1703
+ double *q1 = (double *) ptr1, *q2 = (double *) ptr2,
1704
+ *q3 = (double *) ptr3, *q4 = (double *) ptr4;
1705
+ double *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1706
+ ca_size_t k;
1707
+ if ( m ) {
1708
+ boolean8_t *pm;
1709
+ for (k=0; k<n; k++) {
1710
+ pm = m + k;
1711
+ if ( ! *pm ) {
1712
+ p1 = q1 + k*i1;
1713
+ p2 = q2 + k*i2;
1714
+ p3 = q3 + k*i3;
1715
+ p4 = q4 + k*i4;
1716
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1717
+ }
1718
+ }
1719
+ } else {
1720
+ for (k=0; k<n; k++) {
1721
+ p1 = q1 + k*i1;
1722
+ p2 = q2 + k*i2;
1723
+ p3 = q3 + k*i3;
1724
+ p4 = q4 + k*i4;
1725
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1726
+ }
1727
+ }
1728
+ }
1729
+
1730
+ static void
1731
+ ca_triop_select_cmplx64_t (ca_size_t n, boolean8_t *m,
1732
+ char *ptr1, ca_size_t i1,
1733
+ char *ptr2, ca_size_t i2,
1734
+ char *ptr3, ca_size_t i3,
1735
+ char *ptr4, ca_size_t i4)
1736
+ {
1737
+ cmplx64_t *q1 = (cmplx64_t *) ptr1, *q2 = (cmplx64_t *) ptr2,
1738
+ *q3 = (cmplx64_t *) ptr3, *q4 = (cmplx64_t *) ptr4;
1739
+ cmplx64_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1740
+ ca_size_t k;
1741
+ if ( m ) {
1742
+ boolean8_t *pm;
1743
+ for (k=0; k<n; k++) {
1744
+ pm = m + k;
1745
+ if ( ! *pm ) {
1746
+ p1 = q1 + k*i1;
1747
+ p2 = q2 + k*i2;
1748
+ p3 = q3 + k*i3;
1749
+ p4 = q4 + k*i4;
1750
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1751
+ }
1752
+ }
1753
+ } else {
1754
+ for (k=0; k<n; k++) {
1755
+ p1 = q1 + k*i1;
1756
+ p2 = q2 + k*i2;
1757
+ p3 = q3 + k*i3;
1758
+ p4 = q4 + k*i4;
1759
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1760
+ }
1761
+ }
1762
+ }
1763
+
1764
+ static void
1765
+ ca_triop_select_cmplx128_t (ca_size_t n, boolean8_t *m,
1766
+ char *ptr1, ca_size_t i1,
1767
+ char *ptr2, ca_size_t i2,
1768
+ char *ptr3, ca_size_t i3,
1769
+ char *ptr4, ca_size_t i4)
1770
+ {
1771
+ cmplx128_t *q1 = (cmplx128_t *) ptr1, *q2 = (cmplx128_t *) ptr2,
1772
+ *q3 = (cmplx128_t *) ptr3, *q4 = (cmplx128_t *) ptr4;
1773
+ cmplx128_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1774
+ ca_size_t k;
1775
+ if ( m ) {
1776
+ boolean8_t *pm;
1777
+ for (k=0; k<n; k++) {
1778
+ pm = m + k;
1779
+ if ( ! *pm ) {
1780
+ p1 = q1 + k*i1;
1781
+ p2 = q2 + k*i2;
1782
+ p3 = q3 + k*i3;
1783
+ p4 = q4 + k*i4;
1784
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1785
+ }
1786
+ }
1787
+ } else {
1788
+ for (k=0; k<n; k++) {
1789
+ p1 = q1 + k*i1;
1790
+ p2 = q2 + k*i2;
1791
+ p3 = q3 + k*i3;
1792
+ p4 = q4 + k*i4;
1793
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1794
+ }
1795
+ }
1796
+ }
1797
+
1798
+ static void
1799
+ ca_triop_select_boolean8_t (ca_size_t n, boolean8_t *m,
1800
+ char *ptr1, ca_size_t i1,
1801
+ char *ptr2, ca_size_t i2,
1802
+ char *ptr3, ca_size_t i3,
1803
+ char *ptr4, ca_size_t i4)
1804
+ {
1805
+ boolean8_t *q1 = (boolean8_t *) ptr1, *q2 = (boolean8_t *) ptr2,
1806
+ *q3 = (boolean8_t *) ptr3, *q4 = (boolean8_t *) ptr4;
1807
+ boolean8_t *p1 = q1, *p2 = q2, *p3 = q3, *p4 = q4;
1808
+ ca_size_t k;
1809
+ if ( m ) {
1810
+ boolean8_t *pm;
1811
+ for (k=0; k<n; k++) {
1812
+ pm = m + k;
1813
+ if ( ! *pm ) {
1814
+ p1 = q1 + k*i1;
1815
+ p2 = q2 + k*i2;
1816
+ p3 = q3 + k*i3;
1817
+ p4 = q4 + k*i4;
1818
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1819
+ }
1820
+ }
1821
+ } else {
1822
+ for (k=0; k<n; k++) {
1823
+ p1 = q1 + k*i1;
1824
+ p2 = q2 + k*i2;
1825
+ p3 = q3 + k*i3;
1826
+ p4 = q4 + k*i4;
1827
+ { (*p4) = (*p1) ? (*p2) : (*p3); }
1828
+ }
1829
+ }
1830
+ }
1831
+
1832
+ ca_triop_func_t
1833
+ ca_triop_select[CA_NTYPE] = {
1834
+ ca_triop_not_implement,
1835
+ ca_triop_select_boolean8_t,
1836
+ ca_triop_select_int8_t,
1837
+ ca_triop_select_uint8_t,
1838
+ ca_triop_select_int16_t,
1839
+ ca_triop_select_uint16_t,
1840
+ ca_triop_select_int32_t,
1841
+ ca_triop_select_uint32_t,
1842
+ ca_triop_select_int64_t,
1843
+ ca_triop_select_uint64_t,
1844
+ ca_triop_select_float32_t,
1845
+ ca_triop_select_float64_t,
1846
+ ca_triop_not_implement,
1847
+ ca_triop_select_cmplx64_t,
1848
+ ca_triop_select_cmplx128_t,
1849
+ ca_triop_not_implement,
1850
+ ca_triop_not_implement,
1851
+ };
1852
+
1853
+ VALUE rb_ca_select (VALUE self, VALUE other2, VALUE other3)
1854
+ { return rb_ca_call_triop(self, other2, other3, ca_triop_select); }
1855
+
1856
+ void
1857
+ Init_carray_kernels_triop (void)
1858
+ {
1859
+ rb_define_method(rb_cCArray, "fma", rb_ca_fma, 2);
1860
+ rb_define_method(rb_cCArray, "fma!", rb_ca_fma_bang, 2);
1861
+ rb_define_method(rb_cCArray, "fms", rb_ca_fms, 2);
1862
+ rb_define_method(rb_cCArray, "fms!", rb_ca_fms_bang, 2);
1863
+ rb_define_method(rb_cCArray, "clamp_between", rb_ca_clip, 2);
1864
+ }