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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +824 -0
- data/README.md +5 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +258 -4
- data/ext/ca_axis_group.c +368 -184
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +90 -41
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +960 -245
- data/ext/ca_kernel_iterator.h +352 -181
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +194 -42
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +5 -4
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +180 -50
- data/ext/ca_obj_face.c +428 -62
- data/ext/ca_obj_face.h +107 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +39 -26
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +235 -55
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +551 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +88 -75
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -123
- data/ext/ca_obj_stride.c +267 -35
- data/ext/ca_obj_string.c +25 -22
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +157 -29
- data/ext/ca_op_ipower.c +25 -13
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +385 -198
- data/ext/ca_sweep_engine.h +31 -23
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +90 -28
- data/ext/carray_access.c +487 -231
- data/ext/carray_address_basis.c +731 -0
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +49 -17
- data/ext/carray_call_cfunc.c +667 -511
- data/ext/carray_cast.c +1556 -247
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +84 -38
- data/ext/carray_core.c +591 -119
- data/ext/carray_count.c +148 -96
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +604 -291
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +400 -1
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +88 -66
- data/ext/carray_mask.c +705 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +263 -63
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1093 -363
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +582 -204
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +183 -70
- data/ext/carray_sort.c +235 -240
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +103 -118
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1349 -851
- data/ext/ruby_carray.c +17 -2
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +18 -0
- data/lib/carray/axis_group.rb +245 -20
- data/lib/carray/basics.rb +95 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +200 -54
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +244 -59
- data/lib/carray/categorical_iterator.rb +391 -757
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +177 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +590 -76
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +205 -35
- data/lib/carray/frame/group.rb +199 -40
- data/lib/carray/frame/io.rb +452 -60
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +54 -19
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +726 -56
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +71 -20
- data/lib/carray/iterator.rb +157 -2
- data/lib/carray/lazy.rb +54 -67
- data/lib/carray/mask_gap_fill.rb +66 -50
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +130 -6
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +235 -21
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +91 -0
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +52 -3
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +109 -40
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +9 -4
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +535 -105
- data/lib/carray/window_iterator.rb +259 -82
- data/lib/carray.rb +4 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +11 -4
- data/yard-stubs/carray_access.rb +6 -5
- data/yard-stubs/carray_broadcast.rb +2 -2
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -83
- data/yard-stubs/carray_count.rb +16 -2
- data/yard-stubs/carray_lazy.rb +210 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +1499 -4
- data/yard-stubs/carray_median_percentile.rb +26 -8
- data/yard-stubs/carray_order.rb +43 -82
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +11 -8
- data/yard-stubs/carray_sort.rb +50 -8
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -25837
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14593
- data/ext/carray_kernels_reduce_extreme.c +0 -16948
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32138
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/ca_rng_normal.h
ADDED
|
@@ -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
|
+
}
|
data/ext/ca_sort_kernels.h
CHANGED
|
@@ -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 */
|