carray 3.0.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -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_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/ca_compare.c
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include "ruby.h"
|
|
15
15
|
#include "carray.h"
|
|
16
16
|
#include "ca_compare.h"
|
|
17
|
+
#include "carray_internal.h" /* CA_FLOAT_ORDER_CMP, ca_obj_order_cmp */
|
|
17
18
|
#include <math.h>
|
|
18
19
|
|
|
19
20
|
#define DEFINE_ELEM_CMP(type) \
|
|
@@ -27,18 +28,14 @@ elem_cmp_## type (const void *va, const void *vb) \
|
|
|
27
28
|
return 0; \
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
/* Float order: NaN
|
|
31
|
+
/* Float order: NaN after every number (CA_FLOAT_ORDER_CMP). */
|
|
31
32
|
#define DEFINE_ELEM_CMP_FLOAT(type) \
|
|
32
33
|
static int \
|
|
33
34
|
elem_cmp_## type (const void *va, const void *vb) \
|
|
34
35
|
{ \
|
|
35
|
-
const type
|
|
36
|
-
const type
|
|
37
|
-
|
|
38
|
-
if ( isnan(*b) && ( ! isnan(*a) ) ) return -1; \
|
|
39
|
-
if ( *a > *b ) return 1; \
|
|
40
|
-
if ( *a < *b ) return -1; \
|
|
41
|
-
return 0; \
|
|
36
|
+
const type a = *(const type *) va; \
|
|
37
|
+
const type b = *(const type *) vb; \
|
|
38
|
+
return CA_FLOAT_ORDER_CMP(a, b); \
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
DEFINE_ELEM_CMP(boolean8_t)
|
|
@@ -53,13 +50,11 @@ DEFINE_ELEM_CMP(uint64_t)
|
|
|
53
50
|
DEFINE_ELEM_CMP_FLOAT(float32_t)
|
|
54
51
|
DEFINE_ELEM_CMP_FLOAT(float64_t)
|
|
55
52
|
|
|
56
|
-
/* CA_OBJECT:
|
|
53
|
+
/* CA_OBJECT: the object order (ca_obj_order_cmp). */
|
|
57
54
|
static int
|
|
58
55
|
elem_cmp_VALUE (const void *va, const void *vb)
|
|
59
56
|
{
|
|
60
|
-
const VALUE *
|
|
61
|
-
const VALUE *b = (const VALUE *) vb;
|
|
62
|
-
return NUM2INT(rb_funcall(*a, rb_intern("<=>"), 1, *b));
|
|
57
|
+
return ca_obj_order_cmp(*(const VALUE *) va, *(const VALUE *) vb);
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
/* FIXLEN / retired / otherwise unorderable data_types: callers must handle
|
data/ext/ca_for_buffer.h
CHANGED
|
@@ -1,43 +1,33 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
*
|
|
3
|
-
* ca_for_buffer.h --
|
|
4
|
-
*
|
|
3
|
+
* ca_for_buffer.h -- whole contig buffer handed to author / third-party
|
|
4
|
+
* library
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* C-side counterpart of Ruby's `ca.attach! { |a| ... }` block: the
|
|
7
|
+
* attach / sync / detach lifecycle is scoped to a body function, which
|
|
8
|
+
* receives a contig buffer ptr and element count and may do whatever
|
|
9
|
+
* (typically pass the ptr to a third-party library: FFTW, akima init,
|
|
10
|
+
* fitpack surf1, ...).
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* The buffer aliases ca->ptr when the array is a contig entity and is a
|
|
13
|
+
* materialised scratch otherwise. A writable call syncs the buffer back
|
|
14
|
+
* to the array's storage when the body returns.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* CA_WITH_BUFFER_WRITABLE(ca, T, ptr, n)
|
|
21
|
-
* Writable; same ptr/n semantics, plus ca_sync on block exit so
|
|
22
|
-
* author writes propagate back to the view's storage.
|
|
16
|
+
* The body may raise. The view is closed however the body is left: a
|
|
17
|
+
* writable view is synced first, so what the body wrote before raising
|
|
18
|
+
* reaches the view's storage, and the view is detached even if that sync
|
|
19
|
+
* raises. The body's exception is the one that propagates.
|
|
23
20
|
*
|
|
24
21
|
* Author pattern:
|
|
25
22
|
*
|
|
26
|
-
*
|
|
27
|
-
* ca_size_t n
|
|
28
|
-
*
|
|
23
|
+
* static void
|
|
24
|
+
* fft_body (void *user_data, void *ptr, ca_size_t n)
|
|
25
|
+
* {
|
|
26
|
+
* fftw_plan plan = (fftw_plan) user_data;
|
|
29
27
|
* fftw_execute_dft(plan, ptr, ptr);
|
|
30
28
|
* }
|
|
31
29
|
*
|
|
32
|
-
*
|
|
33
|
-
* - `break;` from body exits cleanly (= outer for's advance clause
|
|
34
|
-
* runs ca_sync / ca_detach).
|
|
35
|
-
* - `return;` from body LEAKS the attach; restructure to break.
|
|
36
|
-
* - Macros are NOT statement-equivalent (= nested for); no trailing
|
|
37
|
-
* `else`.
|
|
38
|
-
* - For Ruby-exception-safe lifecycle (e.g. when calling Ruby code or
|
|
39
|
-
* anything that may raise from inside the body), use the function
|
|
40
|
-
* form `rb_ca_call_with_buffer` instead (= rb_ensure-protected).
|
|
30
|
+
* rb_ca_call_with_buffer(rca, 1, fft_body, plan);
|
|
41
31
|
*
|
|
42
32
|
* --------------------------------------------------------------------------- */
|
|
43
33
|
|
|
@@ -47,46 +37,9 @@
|
|
|
47
37
|
#include "carray.h"
|
|
48
38
|
#include "ca_sweep_engine.h"
|
|
49
39
|
|
|
50
|
-
/*
|
|
51
|
-
|
|
52
|
-
/* Read-only: ca_attach (alias-when-possible) + author body + ca_detach. */
|
|
53
|
-
#define CA_WITH_BUFFER(_ca, T, _ptr, _n) \
|
|
54
|
-
for ( CArray *__cwv_ca = (CArray *)(_ca); \
|
|
55
|
-
__cwv_ca; \
|
|
56
|
-
ca_detach(__cwv_ca), __cwv_ca = NULL ) \
|
|
57
|
-
for ( int __cwv_once = (ca_attach(__cwv_ca), \
|
|
58
|
-
(_ptr) = (T *)__cwv_ca->ptr, \
|
|
59
|
-
(_n) = __cwv_ca->elements, \
|
|
60
|
-
1); \
|
|
61
|
-
__cwv_once; \
|
|
62
|
-
__cwv_once = 0 )
|
|
63
|
-
|
|
64
|
-
/* Writable: same as above + ca_sync on block exit. */
|
|
65
|
-
#define CA_WITH_BUFFER_WRITABLE(_ca, T, _ptr, _n) \
|
|
66
|
-
for ( CArray *__cwvw_ca = (CArray *)(_ca); \
|
|
67
|
-
__cwvw_ca; \
|
|
68
|
-
ca_sync(__cwvw_ca), ca_detach(__cwvw_ca), __cwvw_ca = NULL ) \
|
|
69
|
-
for ( int __cwvw_once = (ca_attach(__cwvw_ca), \
|
|
70
|
-
(_ptr) = (T *)__cwvw_ca->ptr, \
|
|
71
|
-
(_n) = __cwvw_ca->elements, \
|
|
72
|
-
1); \
|
|
73
|
-
__cwvw_once; \
|
|
74
|
-
__cwvw_once = 0 )
|
|
75
|
-
|
|
76
|
-
/* ---------- function form (rb_ensure-protected, AC8) ----------
|
|
77
|
-
*
|
|
78
|
-
* Use this when the body may raise a Ruby exception (= calling rb_funcall,
|
|
79
|
-
* type-checking with rb_check_type, indirect Ruby code, etc.). The
|
|
80
|
-
* engine ca_attach's the view, runs body via rb_ensure, then guarantees
|
|
81
|
-
* ca_sync (if writable) and ca_detach run before the exception
|
|
82
|
-
* propagates.
|
|
83
|
-
*
|
|
84
|
-
* body_fn(user_data, ptr, n_elements) -> may raise
|
|
40
|
+
/* body_fn(user_data, ptr, n_elements) -> may raise
|
|
85
41
|
*
|
|
86
|
-
* Returns
|
|
87
|
-
* function itself returns Qnil since rb_ensure body must be VALUE).
|
|
88
|
-
* For richer return semantics, box your result in user_data.
|
|
89
|
-
*/
|
|
42
|
+
* Returns nothing; box a result in user_data. */
|
|
90
43
|
typedef void (*ca_with_buffer_body_fn) (void *user_data, void *ptr,
|
|
91
44
|
ca_size_t n_elements);
|
|
92
45
|
|
data/ext/ca_group_iter.c
CHANGED
|
@@ -14,13 +14,14 @@
|
|
|
14
14
|
Split summary:
|
|
15
15
|
- ca_argv_has_group / rb_ca_fetch_group : here (called by carray_access.c)
|
|
16
16
|
- CAGroupIterator + the tier-1 reduction methods driving
|
|
17
|
-
|
|
17
|
+
__reduce_by_axis_groups__ : here
|
|
18
18
|
- reduce_plan / bundle assembly / output-axis permutation (metadata) : Ruby
|
|
19
|
-
- the O(N) compute kernel
|
|
19
|
+
- the O(N) compute kernel __reduce_by_axis_groups__ : ca_axis_group.c
|
|
20
20
|
|
|
21
21
|
--------------------------------------------------------------------------- */
|
|
22
22
|
|
|
23
23
|
#include "carray.h"
|
|
24
|
+
#include "carray_internal.h" /* ca_check_rank_fits */
|
|
24
25
|
|
|
25
26
|
/* lib/carray/axis_group.rb registers these classes here on first load (and
|
|
26
27
|
loading is wired so that load happens as soon as any categorical exists —
|
|
@@ -34,16 +35,20 @@ static VALUE rb_cCAGroupIterator = Qnil;
|
|
|
34
35
|
static ID id_value, id_spec, id_axis_group, id_reduce_plan, id_parse_axis;
|
|
35
36
|
static ID id_axis_group_reduce, id_reshape, id_transpose, id_labels;
|
|
36
37
|
|
|
37
|
-
/* CArray.
|
|
38
|
+
/* CArray.register_axis_group_classes(CACategorical, AxisGroup) — called
|
|
38
39
|
from the top of lib/carray/axis_group.rb so the C type gate can recognise
|
|
39
40
|
the classifier/spec types without triggering autoload on every [] call. */
|
|
40
41
|
static VALUE
|
|
41
42
|
rb_ca_register_axis_group_classes (VALUE klass, VALUE cat, VALUE ag)
|
|
42
43
|
{
|
|
44
|
+
static int registered = 0;
|
|
43
45
|
rb_cCategorical = cat;
|
|
44
46
|
rb_cAxisGroup = ag;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
if ( ! registered ) { /* one GC root per address, not per call */
|
|
48
|
+
rb_gc_register_address(&rb_cCategorical);
|
|
49
|
+
rb_gc_register_address(&rb_cAxisGroup);
|
|
50
|
+
registered = 1;
|
|
51
|
+
}
|
|
47
52
|
return Qnil;
|
|
48
53
|
}
|
|
49
54
|
|
|
@@ -116,7 +121,7 @@ rb_ca_fetch_group (int argc, VALUE *argv, VALUE self)
|
|
|
116
121
|
validates the slot layout = one slot per source axis). */
|
|
117
122
|
spec = rb_funcallv(self, id_axis_group, argc, argv);
|
|
118
123
|
}
|
|
119
|
-
return rb_funcall(rb_cCAGroupIterator, rb_intern("
|
|
124
|
+
return rb_funcall(rb_cCAGroupIterator, rb_intern("build_for"), 2, self, spec);
|
|
120
125
|
}
|
|
121
126
|
|
|
122
127
|
/* --- CAGroupIterator -------------------------------------------------------
|
|
@@ -171,9 +176,7 @@ group_iter_shape_output (VALUE result, VALUE group_dims, VALUE perm, VALUE squee
|
|
|
171
176
|
ng = RARRAY_LEN(group_dims);
|
|
172
177
|
nband = cr->ndim - 1;
|
|
173
178
|
nd = ng + nband;
|
|
174
|
-
|
|
175
|
-
rb_raise(rb_eRuntimeError, "axis_group: output ndim %ld too large", nd);
|
|
176
|
-
}
|
|
179
|
+
ca_check_rank_fits(nd, "axis_group");
|
|
177
180
|
for ( i = 0; i < ng; i++ ) {
|
|
178
181
|
dims[i] = RARRAY_AREF(group_dims, i);
|
|
179
182
|
}
|
|
@@ -215,7 +218,7 @@ group_iter_shape_output (VALUE result, VALUE group_dims, VALUE perm, VALUE squee
|
|
|
215
218
|
static VALUE
|
|
216
219
|
group_iter_reduce (int argc, VALUE *argv, VALUE self)
|
|
217
220
|
{
|
|
218
|
-
ID op_id = rb_frame_this_func();
|
|
221
|
+
ID op_id = rb_frame_this_func(); /* frame-name: picks the op, names no error */
|
|
219
222
|
VALUE op_sym = ID2SYM(op_id);
|
|
220
223
|
VALUE value = rb_ivar_get(self, id_value);
|
|
221
224
|
VALUE spec = rb_ivar_get(self, id_spec);
|
|
@@ -233,17 +236,19 @@ group_iter_reduce (int argc, VALUE *argv, VALUE self)
|
|
|
233
236
|
parsed = rb_funcall(rb_cAxisGroup, id_parse_axis,
|
|
234
237
|
1, (vaxis == Qundef) ? Qnil : vaxis);
|
|
235
238
|
if ( RTEST(RARRAY_AREF(parsed, 0)) == 0 ) {
|
|
236
|
-
/* no :group -> plain reduction on the value (grouping not engaged)
|
|
237
|
-
|
|
239
|
+
/* no :group -> plain reduction on the value (grouping not engaged),
|
|
240
|
+
with every keyword the caller gave */
|
|
241
|
+
if ( NIL_P(kw) ) {
|
|
238
242
|
return rb_funcall(value, op_id, 0);
|
|
239
243
|
}
|
|
240
|
-
|
|
241
|
-
VALUE h = rb_hash_new();
|
|
242
|
-
rb_hash_aset(h, ID2SYM(rb_intern("axis")), vaxis);
|
|
243
|
-
return rb_funcallv_kw(value, op_id, 1, &h, RB_PASS_KEYWORDS);
|
|
244
|
-
}
|
|
244
|
+
return rb_funcallv_kw(value, op_id, 1, &kw, RB_PASS_KEYWORDS);
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
/* min_count: / fill_value: are applied to the grouped result; any other
|
|
248
|
+
keyword is refused before the work is done. */
|
|
249
|
+
rb_funcall(self, rb_intern("check_reduce_keywords"), 2,
|
|
250
|
+
op_sym, NIL_P(kw) ? rb_hash_new() : kw);
|
|
251
|
+
|
|
247
252
|
/* group reduction */
|
|
248
253
|
fused = RARRAY_AREF(parsed, 1);
|
|
249
254
|
plan = rb_funcall(spec, id_reduce_plan, 1, fused);
|
|
@@ -253,9 +258,19 @@ group_iter_reduce (int argc, VALUE *argv, VALUE self)
|
|
|
253
258
|
perm = RARRAY_AREF(plan, 3);
|
|
254
259
|
squeeze = RARRAY_AREF(plan, 4);
|
|
255
260
|
|
|
261
|
+
/* a count reads only the mask, so a payload the kernel cannot read
|
|
262
|
+
(object, fixlen, ...) is counted through a boolean stand-in */
|
|
263
|
+
if ( op_id == rb_intern("count") || op_id == rb_intern("count_not_masked") ) {
|
|
264
|
+
value = rb_funcall(rb_cAxisGroup, rb_intern("count_stand_in"), 1, value);
|
|
265
|
+
}
|
|
256
266
|
result = rb_funcall(value, id_axis_group_reduce, 3,
|
|
257
267
|
group_axes, bundles, op_sym);
|
|
258
|
-
|
|
268
|
+
result = group_iter_shape_output(result, group_dims, perm, squeeze);
|
|
269
|
+
if ( ! NIL_P(kw) ) {
|
|
270
|
+
result = rb_funcall(self, rb_intern("finish_reduction"), 3,
|
|
271
|
+
op_sym, kw, result);
|
|
272
|
+
}
|
|
273
|
+
return result;
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
void
|
|
@@ -266,21 +281,21 @@ Init_ca_group_iter (void)
|
|
|
266
281
|
id_axis_group = rb_intern("axis_group");
|
|
267
282
|
id_reduce_plan = rb_intern("reduce_plan");
|
|
268
283
|
id_parse_axis = rb_intern("parse_axis");
|
|
269
|
-
id_axis_group_reduce = rb_intern("
|
|
284
|
+
id_axis_group_reduce = rb_intern("__reduce_by_axis_groups__");
|
|
270
285
|
id_reshape = rb_intern("reshape");
|
|
271
286
|
id_transpose = rb_intern("transpose");
|
|
272
287
|
id_labels = rb_intern("labels");
|
|
273
288
|
|
|
274
|
-
|
|
275
|
-
|
|
289
|
+
rb_define_private_method(rb_singleton_class(rb_cCArray), "register_axis_group_classes",
|
|
290
|
+
rb_ca_register_axis_group_classes, 2);
|
|
276
291
|
|
|
277
292
|
rb_cCAGroupIterator =
|
|
278
293
|
rb_define_class("CAGroupIterator",
|
|
279
294
|
rb_const_get(rb_cObject, rb_intern("CAIterator")));
|
|
280
295
|
rb_gc_register_address(&rb_cCAGroupIterator);
|
|
281
296
|
|
|
282
|
-
|
|
283
|
-
|
|
297
|
+
rb_define_private_method(rb_singleton_class(rb_cCAGroupIterator), "build_for",
|
|
298
|
+
rb_ca_group_iter_build, 2);
|
|
284
299
|
rb_define_method(rb_cCAGroupIterator, "value", rb_ca_group_iter_value, 0);
|
|
285
300
|
rb_define_method(rb_cCAGroupIterator, "spec", rb_ca_group_iter_spec, 0);
|
|
286
301
|
rb_define_method(rb_cCAGroupIterator, "labels", rb_ca_group_iter_labels, -1);
|