carray 3.0.1 → 3.0.3

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +824 -0
  3. data/README.md +5 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_dispatch.c +258 -4
  6. data/ext/ca_axis_group.c +368 -184
  7. data/ext/ca_binop_dispatch.c +54 -32
  8. data/ext/ca_binop_dispatch.h +1 -0
  9. data/ext/ca_categorical_iterator.c +90 -41
  10. data/ext/ca_compare.c +8 -2
  11. data/ext/ca_for_buffer.h +21 -68
  12. data/ext/ca_group_iter.c +27 -11
  13. data/ext/ca_kernel_iterator.c +960 -245
  14. data/ext/ca_kernel_iterator.h +352 -181
  15. data/ext/ca_monop_dispatch.c +4 -4
  16. data/ext/ca_monop_dispatch.h +4 -0
  17. data/ext/ca_obj_array.c +194 -42
  18. data/ext/ca_obj_bincmp.c +152 -121
  19. data/ext/ca_obj_binop.c +107 -210
  20. data/ext/ca_obj_bitarray.c +37 -24
  21. data/ext/ca_obj_bitfield.c +95 -62
  22. data/ext/ca_obj_block.c +5 -4
  23. data/ext/ca_obj_byte_swap.c +40 -40
  24. data/ext/ca_obj_const_string.c +180 -50
  25. data/ext/ca_obj_face.c +428 -62
  26. data/ext/ca_obj_face.h +107 -47
  27. data/ext/ca_obj_fake.c +21 -50
  28. data/ext/ca_obj_farray.c +1 -0
  29. data/ext/ca_obj_field.c +16 -3
  30. data/ext/ca_obj_fixlen_string.c +39 -26
  31. data/ext/ca_obj_grid.c +181 -124
  32. data/ext/ca_obj_meld.c +235 -55
  33. data/ext/ca_obj_moncmp.c +61 -61
  34. data/ext/ca_obj_monop.c +125 -107
  35. data/ext/ca_obj_object.c +551 -233
  36. data/ext/ca_obj_record.c +51 -16
  37. data/ext/ca_obj_reduce.c +5 -8
  38. data/ext/ca_obj_refer.c +117 -33
  39. data/ext/ca_obj_remap.c +57 -17
  40. data/ext/ca_obj_repeat.c +21 -5
  41. data/ext/ca_obj_roll.c +115 -11
  42. data/ext/ca_obj_select.c +88 -75
  43. data/ext/ca_obj_select_axis.c +58 -60
  44. data/ext/ca_obj_shift.c +22 -102
  45. data/ext/ca_obj_stack.c +223 -123
  46. data/ext/ca_obj_stride.c +267 -35
  47. data/ext/ca_obj_string.c +25 -22
  48. data/ext/ca_obj_tile.c +32 -16
  49. data/ext/ca_obj_time.c +23 -25
  50. data/ext/ca_obj_timedelta.c +21 -23
  51. data/ext/ca_obj_transpose.c +12 -3
  52. data/ext/ca_obj_triop.c +110 -117
  53. data/ext/ca_obj_window.c +157 -29
  54. data/ext/ca_op_ipower.c +25 -13
  55. data/ext/ca_op_powi.h +57 -30
  56. data/ext/ca_pow5_table.h +656 -0
  57. data/ext/ca_rng_normal.h +42 -0
  58. data/ext/ca_rng_xoshiro256pp.h +105 -0
  59. data/ext/ca_sort_kernels.h +70 -0
  60. data/ext/ca_sweep_engine.c +385 -198
  61. data/ext/ca_sweep_engine.h +31 -23
  62. data/ext/ca_triop_dispatch.c +4 -1
  63. data/ext/ca_triop_dispatch.h +5 -2
  64. data/ext/caframe_csv_reader.c +463 -0
  65. data/ext/carray.h +90 -28
  66. data/ext/carray_access.c +487 -231
  67. data/ext/carray_address_basis.c +731 -0
  68. data/ext/carray_attribute.c +45 -3
  69. data/ext/carray_bincount.c +32 -2
  70. data/ext/carray_broadcast.c +49 -17
  71. data/ext/carray_call_cfunc.c +667 -511
  72. data/ext/carray_cast.c +1556 -247
  73. data/ext/carray_cast_func.rb +34 -21
  74. data/ext/carray_conversion.c +197 -73
  75. data/ext/carray_copy.c +84 -38
  76. data/ext/carray_core.c +591 -119
  77. data/ext/carray_count.c +148 -96
  78. data/ext/carray_element.c +18 -27
  79. data/ext/carray_factorize.c +604 -291
  80. data/ext/carray_generate.c +76 -40
  81. data/ext/carray_histogram.c +152 -94
  82. data/ext/carray_hold.c +2 -1
  83. data/ext/carray_index_classifier.c +63 -96
  84. data/ext/carray_internal.h +400 -1
  85. data/ext/carray_lazy.c +834 -79
  86. data/ext/carray_loop.c +88 -66
  87. data/ext/carray_mask.c +705 -324
  88. data/ext/carray_math_kernel.h +1 -0
  89. data/ext/carray_median_percentile.c +263 -63
  90. data/ext/carray_memory_view.c +254 -248
  91. data/ext/carray_operator.c +1093 -363
  92. data/ext/carray_order.c +133 -69
  93. data/ext/carray_partition.c +102 -56
  94. data/ext/carray_random.c +582 -204
  95. data/ext/carray_scatter.c +308 -65
  96. data/ext/carray_segment.c +257 -0
  97. data/ext/carray_slab.c +183 -70
  98. data/ext/carray_sort.c +235 -240
  99. data/ext/carray_sort_kernel.c +8 -1
  100. data/ext/carray_struct.c +99 -21
  101. data/ext/carray_test.c +167 -64
  102. data/ext/carray_time_text.c +1182 -0
  103. data/ext/carray_utils.c +363 -98
  104. data/ext/extconf.rb +27 -2
  105. data/ext/mk_call_cfunc.rb +103 -118
  106. data/ext/mk_pow5_table.rb +35 -0
  107. data/ext/mkkernel.rb +1349 -851
  108. data/ext/ruby_carray.c +17 -2
  109. data/ext/version.h +4 -4
  110. data/ext/version.rb +4 -2
  111. data/lib/carray/attribute.rb +39 -0
  112. data/lib/carray/autoload_carray.rb +24 -3
  113. data/lib/carray/autoload_method_extension.rb +18 -0
  114. data/lib/carray/axis_group.rb +245 -20
  115. data/lib/carray/basics.rb +95 -25
  116. data/lib/carray/bincount_nd.rb +6 -0
  117. data/lib/carray/block_iterator.rb +200 -54
  118. data/lib/carray/boolean_reduce.rb +21 -29
  119. data/lib/carray/categorical.rb +244 -59
  120. data/lib/carray/categorical_iterator.rb +391 -757
  121. data/lib/carray/complex.rb +36 -29
  122. data/lib/carray/conditional.rb +94 -7
  123. data/lib/carray/const_string.rb +177 -27
  124. data/lib/carray/construct.rb +40 -0
  125. data/lib/carray/data_type_extension.rb +3 -0
  126. data/lib/carray/data_type_limits.rb +91 -0
  127. data/lib/carray/fixlen_string.rb +1 -1
  128. data/lib/carray/frame/concat.rb +157 -6
  129. data/lib/carray/frame/convert.rb +13 -7
  130. data/lib/carray/frame/csv_parser.rb +590 -76
  131. data/lib/carray/frame/describe.rb +79 -0
  132. data/lib/carray/frame/frame.rb +205 -35
  133. data/lib/carray/frame/group.rb +199 -40
  134. data/lib/carray/frame/io.rb +452 -60
  135. data/lib/carray/frame/join.rb +134 -46
  136. data/lib/carray/frame/records.rb +54 -19
  137. data/lib/carray/frame/reshape.rb +448 -0
  138. data/lib/carray/frame/sort.rb +26 -2
  139. data/lib/carray/frame/verbs.rb +726 -56
  140. data/lib/carray/frame.rb +2 -0
  141. data/lib/carray/fuse_source.rb +111 -2
  142. data/lib/carray/fusion.rb +229 -38
  143. data/lib/carray/inspect.rb +71 -20
  144. data/lib/carray/iterator.rb +157 -2
  145. data/lib/carray/lazy.rb +54 -67
  146. data/lib/carray/mask_gap_fill.rb +66 -50
  147. data/lib/carray/math.rb +32 -19
  148. data/lib/carray/meld_reduce.rb +40 -7
  149. data/lib/carray/methods/align_addr.rb +8 -4
  150. data/lib/carray/methods/bincount.rb +2 -2
  151. data/lib/carray/methods/bit_string.rb +14 -3
  152. data/lib/carray/methods/composition.rb +16 -10
  153. data/lib/carray/methods/discovery_along.rb +74 -0
  154. data/lib/carray/methods/factorize.rb +50 -0
  155. data/lib/carray/methods/gather_nd.rb +13 -2
  156. data/lib/carray/methods/insert_block.rb +9 -14
  157. data/lib/carray/methods/is_in.rb +130 -6
  158. data/lib/carray/methods/join.rb +1 -1
  159. data/lib/carray/methods/locate_addr.rb +235 -21
  160. data/lib/carray/methods/mask_duplicates.rb +35 -1
  161. data/lib/carray/methods/mode.rb +18 -1
  162. data/lib/carray/methods/nunique.rb +22 -1
  163. data/lib/carray/methods/repeat.rb +91 -0
  164. data/lib/carray/methods/resize.rb +21 -23
  165. data/lib/carray/methods/snap.rb +34 -12
  166. data/lib/carray/methods/unique.rb +52 -3
  167. data/lib/carray/record_order.rb +208 -0
  168. data/lib/carray/rng.rb +86 -0
  169. data/lib/carray/runtime.rb +14 -11
  170. data/lib/carray/segment_iterator.rb +990 -0
  171. data/lib/carray/serialize.rb +197 -27
  172. data/lib/carray/slab_iterator.rb +109 -40
  173. data/lib/carray/stack.rb +10 -4
  174. data/lib/carray/string_operation_extension.rb +9 -4
  175. data/lib/carray/struct.rb +142 -51
  176. data/lib/carray/struct_builder.rb +110 -14
  177. data/lib/carray/table.rb +2 -2
  178. data/lib/carray/time.rb +535 -105
  179. data/lib/carray/window_iterator.rb +259 -82
  180. data/lib/carray.rb +4 -2
  181. data/yard-stubs/ca_obj_array.rb +4 -4
  182. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  183. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  184. data/yard-stubs/ca_obj_block.rb +2 -7
  185. data/yard-stubs/ca_obj_fake.rb +1 -1
  186. data/yard-stubs/ca_obj_field.rb +1 -1
  187. data/yard-stubs/ca_obj_refer.rb +3 -3
  188. data/yard-stubs/ca_obj_roll.rb +0 -1
  189. data/yard-stubs/ca_obj_stride.rb +10 -7
  190. data/yard-stubs/ca_obj_transpose.rb +1 -1
  191. data/yard-stubs/ca_obj_window.rb +11 -4
  192. data/yard-stubs/carray_access.rb +6 -5
  193. data/yard-stubs/carray_broadcast.rb +2 -2
  194. data/yard-stubs/carray_cast.rb +78 -43
  195. data/yard-stubs/carray_conversion.rb +13 -1
  196. data/yard-stubs/carray_copy.rb +8 -3
  197. data/yard-stubs/carray_core.rb +3 -83
  198. data/yard-stubs/carray_count.rb +16 -2
  199. data/yard-stubs/carray_lazy.rb +210 -1
  200. data/yard-stubs/carray_loop.rb +4 -1
  201. data/yard-stubs/carray_mask.rb +34 -10
  202. data/yard-stubs/carray_math.rb +1499 -4
  203. data/yard-stubs/carray_median_percentile.rb +26 -8
  204. data/yard-stubs/carray_order.rb +43 -82
  205. data/yard-stubs/carray_scatter.rb +10 -3
  206. data/yard-stubs/carray_segment.rb +72 -0
  207. data/yard-stubs/carray_slab.rb +11 -8
  208. data/yard-stubs/carray_sort.rb +50 -8
  209. data/yard-stubs/carray_test.rb +10 -0
  210. data/yard-stubs/carray_utils.rb +0 -26
  211. metadata +19 -19
  212. data/ext/ca_for_each_element.h +0 -239
  213. data/ext/carray_build_flags.h +0 -3
  214. data/ext/carray_config.h +0 -28
  215. data/ext/carray_kernels_bincmp.c +0 -4446
  216. data/ext/carray_kernels_binop.c +0 -11001
  217. data/ext/carray_kernels_init.c +0 -1131
  218. data/ext/carray_kernels_map.c +0 -3467
  219. data/ext/carray_kernels_moncmp.c +0 -2097
  220. data/ext/carray_kernels_monop.c +0 -18313
  221. data/ext/carray_kernels_reduce_aggregate.c +0 -25837
  222. data/ext/carray_kernels_reduce_boolean.c +0 -330
  223. data/ext/carray_kernels_reduce_cumulative.c +0 -14593
  224. data/ext/carray_kernels_reduce_extreme.c +0 -16948
  225. data/ext/carray_kernels_reduce_variance.c +0 -3910
  226. data/ext/carray_kernels_scan.c +0 -3693
  227. data/ext/carray_kernels_search.c +0 -32138
  228. data/ext/carray_kernels_sort.c +0 -10626
  229. data/ext/carray_kernels_triop.c +0 -1392
@@ -0,0 +1,42 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_rng_normal.h -- uniform to standard normal, as text
4
+
5
+ Read the two ways ca_rng_xoshiro256pp.h is read: compiled into this
6
+ extension, and handed out through CArray::Rng::COMMON_SOURCE for
7
+ another gem to paste. The same rules apply -- no include guard,
8
+ nothing beyond <math.h>, `static inline` only.
9
+
10
+ Separate from any generator's file because it belongs to none of
11
+ them: it takes two uniforms and gives a normal, whichever generator
12
+ the uniforms came from. Whoever pastes it pastes it once however
13
+ many generators are drawing, which is why it is not simply repeated
14
+ inside each generator's text.
15
+
16
+ --------------------------------------------------------------------------- */
17
+
18
+ /* One standard normal from two uniforms in [0.0, 1.0), by Box-Muller.
19
+ *
20
+ * Exactly two, always. The classical form takes two uniforms and gives
21
+ * two normals, and keeping the second would make the cost one uniform
22
+ * apiece -- but the spare has to live somewhere between calls, and the
23
+ * place it would live is the generator's state. A kernel draws one
24
+ * number per cell and `CArray#random!` fills whole arrays, so a spare
25
+ * held across that boundary is a second kind of state to keep in step,
26
+ * on top of the one this design exists to keep in step. Two uniforms
27
+ * and no spare costs an extra draw, at about a nanosecond, and buys a
28
+ * rule with nothing behind it: one normal is two draws, wherever it is
29
+ * taken.
30
+ *
31
+ * `1.0 - u1` rather than `u1`, so the argument to log is in (0.0, 1.0]
32
+ * and never zero. Redrawing on a zero -- which is what the paired form
33
+ * does -- would make the number of uniforms per normal depend on the
34
+ * draw, and then "where is this generator" has no answer that can be
35
+ * worked out rather than run. */
36
+ static inline double
37
+ ca_rng_normal (double u1, double u2)
38
+ {
39
+ const double radius = sqrt(-2.0 * log(1.0 - u1));
40
+ const double theta = 2.0 * M_PI * u2;
41
+ return radius * cos(theta);
42
+ }
@@ -0,0 +1,105 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ ca_rng_xoshiro256pp.h -- the xoshiro256++ generator, as text
4
+
5
+ This file is not a header in the usual sense. It carries no include
6
+ guard and includes nothing, because it is read two ways:
7
+
8
+ - ext/carray_random.c #includes it, and the extension compiles it.
9
+ That is what `CArray#random!(rng: r)` runs.
10
+
11
+ - CArray::Rng::SOURCE[:xoshiro256pp] is this file's text, read at
12
+ runtime. carray-jit pastes it into the translation unit it
13
+ generates for a kernel, beside its own `static inline` helpers.
14
+ That is what a kernel's `random(rng:)` runs.
15
+
16
+ One text, so the two cannot drift: a kernel that draws after
17
+ `random!` continues the same sequence because it is running the same
18
+ code, not because two implementations were checked against each
19
+ other. Anything added here has to stay pasteable -- `static inline`,
20
+ no directives, and nothing beyond <stdint.h>, which both sides have.
21
+
22
+ xoshiro256++ 1.0 by David Blackman and Sebastiano Vigna, released to
23
+ the public domain (https://prng.di.unimi.it/xoshiro256plusplus.c).
24
+ The state is seeded through splitmix64, as its authors prescribe.
25
+
26
+ The state is held as int64_t[4] rather than uint64_t[4] so that it is
27
+ a plain CA_INT64 array a caller can look at. C says an object may be
28
+ read through the corresponding signed or unsigned type, so the cast
29
+ below is the language's own allowance and not a reinterpretation.
30
+
31
+ --------------------------------------------------------------------------- */
32
+
33
+ /* splitmix64: the state seeder. A single 64-bit seed is a poor state
34
+ for xoshiro on its own -- an all-but-zero state takes many draws to
35
+ escape -- so the seed is stretched through a generator whose output
36
+ is well mixed from the first call. */
37
+ static inline uint64_t
38
+ ca_splitmix64_next (uint64_t *x)
39
+ {
40
+ uint64_t z = (*x += 0x9E3779B97F4A7C15ULL);
41
+ z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9ULL;
42
+ z = (z ^ (z >> 27)) * 0x94D049BB133111EBULL;
43
+ return z ^ (z >> 31);
44
+ }
45
+
46
+ /* Fill a state from one seed. */
47
+ static inline void
48
+ ca_xoshiro256pp_seed (int64_t *s, uint64_t seed)
49
+ {
50
+ uint64_t *u = (uint64_t *) s;
51
+ uint64_t x = seed;
52
+ u[0] = ca_splitmix64_next(&x);
53
+ u[1] = ca_splitmix64_next(&x);
54
+ u[2] = ca_splitmix64_next(&x);
55
+ u[3] = ca_splitmix64_next(&x);
56
+ }
57
+
58
+ static inline uint64_t
59
+ ca_xoshiro256pp_rotl (uint64_t x, int k)
60
+ {
61
+ return (x << k) | (x >> (64 - k));
62
+ }
63
+
64
+ /* One draw: 64 random bits, the state advanced. */
65
+ static inline uint64_t
66
+ ca_xoshiro256pp_next (int64_t *s)
67
+ {
68
+ uint64_t *u = (uint64_t *) s;
69
+ const uint64_t result = ca_xoshiro256pp_rotl(u[0] + u[3], 23) + u[0];
70
+ const uint64_t t = u[1] << 17;
71
+
72
+ u[2] ^= u[0];
73
+ u[3] ^= u[1];
74
+ u[1] ^= u[2];
75
+ u[0] ^= u[3];
76
+ u[2] ^= t;
77
+ u[3] = ca_xoshiro256pp_rotl(u[3], 45);
78
+
79
+ return result;
80
+ }
81
+
82
+ /* A double in [0, 1). The top 53 bits are the ones taken: that is the
83
+ whole mantissa, so no two draws collide merely because the generator
84
+ handed back fewer bits than a double can hold. */
85
+ static inline double
86
+ ca_xoshiro256pp_next_real (int64_t *s)
87
+ {
88
+ return (double) (ca_xoshiro256pp_next(s) >> 11) * 0x1.0p-53;
89
+ }
90
+
91
+ /* One standard normal, which is two draws. ca_rng_normal is what turns
92
+ them into one, and it is in a file of its own because it belongs to no
93
+ generator.
94
+
95
+ The two draws are taken into locals rather than written as two
96
+ arguments: C does not say which order a call's arguments are
97
+ evaluated in, and these two are not interchangeable -- they advance a
98
+ state. */
99
+ static inline double
100
+ ca_xoshiro256pp_next_normal (int64_t *s)
101
+ {
102
+ const double u1 = ca_xoshiro256pp_next_real(s);
103
+ const double u2 = ca_xoshiro256pp_next_real(s);
104
+ return ca_rng_normal(u1, u2);
105
+ }
@@ -129,4 +129,74 @@ void ca_sort_merge_pair_u64 (ca_pair_u64 *a, ca_pair_u64 *aux, ca_size_t n);
129
129
  void ca_sort_merge_pair_f32 (ca_pair_f32 *a, ca_pair_f32 *aux, ca_size_t n);
130
130
  void ca_sort_merge_pair_f64 (ca_pair_f64 *a, ca_pair_f64 *aux, ca_size_t n);
131
131
 
132
+ /* Runs of this many elements are insertion-sorted before the merge passes. */
133
+ #define CA_SORT_INSERTION_THRESHOLD 16
134
+
135
+ /* The body of a stable bottom-up mergesort over TYPE, ordered by cmp alone
136
+ (the element type has no `<`), for a function taking
137
+ (TYPE *a, TYPE *aux, ca_size_t n, int (*cmp)(const void *, const void *))
138
+ aux holds n elements. cmp may raise -- an object comparator calls <=> --
139
+ and the raise unwinds through this code's frames, which hold nothing;
140
+ libc's qsort / mergesort would have to be unwound instead.
141
+
142
+ A comparison is costly here (a call into Ruby) and a move is cheap, so
143
+ the runs are insertion-sorted with each insertion point found by binary
144
+ search: log2(k) comparisons where a linear walk takes k/2. Merge passes
145
+ ping-pong between a and aux and skip a pair of runs already in order.
146
+ Stable: an element lands after every one that does not compare greater,
147
+ and a merge takes from the right run only on a strictly smaller one. */
148
+ #define CA_SORT_MERGE_BY_CMP(TYPE) \
149
+ { \
150
+ if ( n <= 1 ) return; \
151
+ for ( ca_size_t lo = 0; lo < n; lo += CA_SORT_INSERTION_THRESHOLD ) { \
152
+ ca_size_t hi = lo + CA_SORT_INSERTION_THRESHOLD; \
153
+ if ( hi > n ) hi = n; \
154
+ for ( ca_size_t k = lo + 1; k < hi; k++ ) { \
155
+ TYPE v = a[k]; \
156
+ ca_size_t l = lo, r = k; \
157
+ while ( l < r ) { \
158
+ ca_size_t mid = l + (r - l) / 2; \
159
+ if ( cmp(&a[mid], &v) > 0 ) r = mid; \
160
+ else l = mid + 1; \
161
+ } \
162
+ if ( l < k ) { \
163
+ memmove(a + l + 1, a + l, (size_t)(k - l) * sizeof(TYPE)); \
164
+ a[l] = v; \
165
+ } \
166
+ } \
167
+ } \
168
+ TYPE *cur = a; \
169
+ TYPE *next = aux; \
170
+ for ( ca_size_t width = CA_SORT_INSERTION_THRESHOLD; width < n; \
171
+ width <<= 1 ) { \
172
+ for ( ca_size_t lo = 0; lo < n; lo += (width << 1) ) { \
173
+ ca_size_t mid = lo + width; \
174
+ ca_size_t hi = lo + (width << 1); \
175
+ if ( mid > n ) mid = n; \
176
+ if ( hi > n ) hi = n; \
177
+ if ( mid >= hi || cmp(&cur[mid - 1], &cur[mid]) <= 0 ) { \
178
+ memcpy(next + lo, cur + lo, (size_t)(hi - lo) * sizeof(TYPE)); \
179
+ continue; \
180
+ } \
181
+ ca_size_t i = lo, j = mid, k = lo; \
182
+ while ( i < mid && j < hi ) { \
183
+ if ( cmp(&cur[j], &cur[i]) < 0 ) next[k++] = cur[j++]; \
184
+ else next[k++] = cur[i++]; \
185
+ } \
186
+ while ( i < mid ) next[k++] = cur[i++]; \
187
+ while ( j < hi ) next[k++] = cur[j++]; \
188
+ } \
189
+ { TYPE *t = cur; cur = next; next = t; } \
190
+ } \
191
+ if ( cur != a ) { \
192
+ memcpy(a, cur, (size_t) n * sizeof(TYPE)); \
193
+ } \
194
+ }
195
+
196
+ /* (VALUE, index) pairs, as the object lane of the sort kernels holds them. */
197
+ typedef struct ca_pair_object { VALUE v; ca_size_t i; } ca_pair_object;
198
+ void ca_sort_merge_pair_object (ca_pair_object *a, ca_pair_object *aux,
199
+ ca_size_t n,
200
+ int (*cmp)(const void *, const void *));
201
+
132
202
  #endif /* CA_SORT_KERNELS_H */