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_axis_descriptor.h
CHANGED
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
ca_axis_descriptor.h
|
|
4
4
|
|
|
5
|
-
Per-axis descriptor framework
|
|
6
|
-
|
|
5
|
+
Per-axis descriptor framework — shared C-level vocabulary that lets
|
|
6
|
+
CASelectAxis, CAGrid, CASelect, CAWindow, CAShift, and future
|
|
7
7
|
per-axis-mixed views describe each axis the same way so a common
|
|
8
|
-
attach dispatch engine (
|
|
9
|
-
uniformly.
|
|
10
|
-
|
|
11
|
-
See devel/PROPOSAL_AXIS_DESCRIPTOR_FRAMEWORK.md for the design.
|
|
8
|
+
attach dispatch engine (ca_axis_dispatch.c) can drive them uniformly.
|
|
12
9
|
|
|
13
10
|
Status: TWO-TIER FREEZE CONTRACT (3.0 onward), the same split
|
|
14
11
|
ca_kernel_iterator.h declares, for the same reason: this header is
|
|
@@ -50,14 +47,14 @@
|
|
|
50
47
|
When this header is included from carray.h mid-file, those typedefs
|
|
51
48
|
are already in scope by the time we reach the include site. */
|
|
52
49
|
|
|
53
|
-
/* ----
|
|
50
|
+
/* ---- per-axis descriptor types --------------------------------------------
|
|
54
51
|
|
|
55
52
|
STRIDE = linear stride axis: parent index = start + i*step,
|
|
56
53
|
i in [0, count). Subsumes nil / Integer / Range index args.
|
|
57
54
|
INDEX = integer index axis: parent index = indices[i],
|
|
58
55
|
i in [0, count). Subsumes integer-array (CAGrid)
|
|
59
56
|
and boolean-mask-after-snapshot (CASelectAxis) axes.
|
|
60
|
-
SHIFT = bound-aware stride axis (CAWindow/CAShift
|
|
57
|
+
SHIFT = bound-aware stride axis (CAWindow/CAShift):
|
|
61
58
|
parent index = start + i*step normalised by `policy`
|
|
62
59
|
(CA_BOUNDS_FILL / PERIODIC / REFLECT / NEAREST / ...)
|
|
63
60
|
against `size0` (= parent dim along this axis). When
|
|
@@ -86,16 +83,17 @@ typedef struct {
|
|
|
86
83
|
uint8_t policy; /* CA_BOUNDS_FILL / PERIODIC / REFLECT / ... */
|
|
87
84
|
} ca_axis_desc_t;
|
|
88
85
|
|
|
89
|
-
/* ----
|
|
86
|
+
/* ---- producer interface --------------------------------------------------
|
|
90
87
|
|
|
91
|
-
|
|
92
|
-
and `out_parent_dims` (caller-allocated, sized
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
A producer writes one entry per descriptor axis into `out`
|
|
89
|
+
(caller-allocated) and `out_parent_dims` (caller-allocated, sized
|
|
90
|
+
CA_RANK_MAX). The producers declared here are CASelectAxis and CAGrid;
|
|
91
|
+
CASelect and CAWindow have their own (ca_select_describe_axes /
|
|
92
|
+
ca_window_describe_axes).
|
|
95
93
|
|
|
96
94
|
`out_parent_dims[k]` is the **effective** parent dim along descriptor
|
|
97
|
-
axis k — for
|
|
98
|
-
flat-index
|
|
95
|
+
axis k — for CASelectAxis / CAGrid this is just `parent->dim[k]`, but
|
|
96
|
+
for a flat-index view (CASelect) it is
|
|
99
97
|
`{parent->elements}` (a single-axis flat view of parent). This
|
|
100
98
|
decouples descriptor.ndim from parent.ndim so the engine can drive
|
|
101
99
|
views whose iteration axes don't match the parent's physical shape.
|
|
@@ -103,13 +101,17 @@ typedef struct {
|
|
|
103
101
|
Pointer arguments are typed `void *` here to avoid pulling the
|
|
104
102
|
private CASelectAxis / CAGrid struct definitions (which live in
|
|
105
103
|
their respective .c files) into this header. Each implementation
|
|
106
|
-
casts to its concrete type inside the .c file.
|
|
104
|
+
casts to its concrete type inside the .c file.
|
|
105
|
+
|
|
106
|
+
An INDEX axis has no way to say "no cell": a CAGrid index that is
|
|
107
|
+
masked (a hole) is written as index 0, so a caller driving a holed grid
|
|
108
|
+
through the engine reads and writes parent cell 0 there. */
|
|
107
109
|
void ca_select_axis_describe_axes (void *ca, ca_axis_desc_t *out,
|
|
108
110
|
ca_size_t *out_parent_dims);
|
|
109
111
|
void ca_grid_describe_axes (void *ca, ca_axis_desc_t *out,
|
|
110
112
|
ca_size_t *out_parent_dims);
|
|
111
113
|
|
|
112
|
-
/* ----
|
|
114
|
+
/* ---- common attach engine -------------------------------------------------
|
|
113
115
|
|
|
114
116
|
Drives gather from `parent` into an output buffer driven by the
|
|
115
117
|
per-axis descriptor array. Caller must have parent attached before
|
|
@@ -119,14 +121,15 @@ void ca_grid_describe_axes (void *ca, ca_axis_desc_t *out,
|
|
|
119
121
|
descriptor axis (see producer interface above). The engine never
|
|
120
122
|
reads `parent->dim` directly — it only reads `parent->ptr` for
|
|
121
123
|
data access — which is what allows flat-index views to lie about
|
|
122
|
-
parent's apparent shape
|
|
124
|
+
parent's apparent shape.
|
|
123
125
|
|
|
124
126
|
`bound_fill` is the bytes-wide value written into gather output
|
|
125
|
-
cells whose SHIFT axes resolve to an out-of-bounds parent index
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
cells whose SHIFT axes resolve to an out-of-bounds parent index.
|
|
128
|
+
Pass NULL when no SHIFT axis is present (CASelectAxis / CAGrid /
|
|
129
|
+
CASelect); the engine ignores it. On scatter, the engine simply skips
|
|
130
|
+
parent writes for OOB cells regardless of bound_fill. A SHIFT axis
|
|
131
|
+
under the RUBY or STRICT policy raises IndexError part way through the
|
|
132
|
+
walk for an index outside the parent.
|
|
130
133
|
|
|
131
134
|
_gather — caller provides out_buf (must be sized total_elements*bytes)
|
|
132
135
|
_attach — wrapper that mallocs the buffer; caller xfrees
|
|
@@ -160,7 +163,7 @@ void ca_axis_dispatch_scatter (struct _CArray *parent,
|
|
|
160
163
|
ca_size_t total_elements,
|
|
161
164
|
const char *in_buf);
|
|
162
165
|
/* Broadcast scatter: write the single value `val` (bytes wide) into
|
|
163
|
-
every selected parent cell.
|
|
166
|
+
every selected parent cell.
|
|
164
167
|
(SHIFT axis OOB cells are skipped — fill semantics aren't
|
|
165
168
|
meaningful for broadcast-write since the destination value already
|
|
166
169
|
IS the broadcast value.) */
|
data/ext/ca_axis_dispatch.c
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
#include "carray.h"
|
|
43
43
|
#include "ca_iter_substrate.h"
|
|
44
44
|
#include "ca_composite_dispatch.h"
|
|
45
|
+
#include "carray_internal.h" /* ca_parent_lends_no_memory */
|
|
45
46
|
|
|
46
47
|
#include <string.h>
|
|
47
48
|
|
|
@@ -393,6 +394,100 @@ ca_axis_dispatch_fill_value_cb (ca_size_t off, int oob, ca_size_t n, void *vctx)
|
|
|
393
394
|
}
|
|
394
395
|
}
|
|
395
396
|
|
|
397
|
+
/* Rows whose innermost axis is a step-1 SHIFT axis. View cell i of the row
|
|
398
|
+
reads parent cell start + i, so the cells with 0 <= start + i < size0 form
|
|
399
|
+
one run and go to cb together. The cells before and after it are out of
|
|
400
|
+
range: under FILL / MASK every one of them is (cb gets each side as one
|
|
401
|
+
oob slab), under the other policies each maps to a cell of its own. */
|
|
402
|
+
static void
|
|
403
|
+
ca_axis_dispatch_shift_cell (const ca_axis_desc_t *ax, ca_size_t pstride,
|
|
404
|
+
ca_size_t row_off, ca_size_t i, ca_size_t bytes,
|
|
405
|
+
ca_slab_cb_t cb, void *ctx)
|
|
406
|
+
{
|
|
407
|
+
ca_size_t pi = ca_bounds_normalize_index(ax->policy, ax->size0,
|
|
408
|
+
ax->start + i);
|
|
409
|
+
if ( pi < 0 || pi >= ax->size0 ) {
|
|
410
|
+
cb(row_off, 1, bytes, ctx);
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
cb(row_off + pi * pstride, 0, bytes, ctx);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
static void
|
|
418
|
+
ca_axis_dispatch_for_each_shift_row (ca_axis_desc_t *laxes,
|
|
419
|
+
const ca_size_t *pstrides,
|
|
420
|
+
int8_t lndim,
|
|
421
|
+
ca_size_t bytes,
|
|
422
|
+
ca_size_t total_elements,
|
|
423
|
+
ca_slab_cb_t cb,
|
|
424
|
+
void *ctx)
|
|
425
|
+
{
|
|
426
|
+
int8_t inner = lndim - 1;
|
|
427
|
+
const ca_axis_desc_t *ax = &laxes[inner];
|
|
428
|
+
ca_size_t pstride = pstrides[inner];
|
|
429
|
+
ca_size_t count = ax->count;
|
|
430
|
+
int coalesce = ( ax->policy == CA_BOUNDS_FILL
|
|
431
|
+
|| ax->policy == CA_BOUNDS_MASK );
|
|
432
|
+
ca_op_prefix_axis_t prefix[CA_RANK_MAX];
|
|
433
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
434
|
+
ca_size_t lo, hi, n_rows, r, i;
|
|
435
|
+
int8_t k;
|
|
436
|
+
|
|
437
|
+
/* In-range view cells: lo <= i < hi. */
|
|
438
|
+
lo = -ax->start;
|
|
439
|
+
if ( lo < 0 ) lo = 0;
|
|
440
|
+
if ( lo > count ) lo = count;
|
|
441
|
+
hi = ax->size0 - ax->start;
|
|
442
|
+
if ( hi > count ) hi = count;
|
|
443
|
+
if ( hi < lo ) hi = lo;
|
|
444
|
+
|
|
445
|
+
ca_axis_dispatch_classify_prefix(laxes, pstrides, inner, prefix);
|
|
446
|
+
for ( k = 0; k < inner; k++ ) idx[k] = 0;
|
|
447
|
+
|
|
448
|
+
n_rows = total_elements / count;
|
|
449
|
+
for ( r = 0; r < n_rows; r++ ) {
|
|
450
|
+
int oob;
|
|
451
|
+
ca_size_t row_off = ca_axis_dispatch_prefix_offset(prefix, idx, inner,
|
|
452
|
+
&oob);
|
|
453
|
+
if ( oob ) {
|
|
454
|
+
cb(row_off, 1, count * bytes, ctx);
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
if ( lo > 0 ) {
|
|
458
|
+
if ( coalesce ) {
|
|
459
|
+
cb(row_off, 1, lo * bytes, ctx);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
for ( i = 0; i < lo; i++ ) {
|
|
463
|
+
ca_axis_dispatch_shift_cell(ax, pstride, row_off, i, bytes,
|
|
464
|
+
cb, ctx);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if ( hi > lo ) {
|
|
469
|
+
cb(row_off + (ax->start + lo) * pstride, 0, (hi - lo) * bytes, ctx);
|
|
470
|
+
}
|
|
471
|
+
if ( hi < count ) {
|
|
472
|
+
if ( coalesce ) {
|
|
473
|
+
cb(row_off, 1, (count - hi) * bytes, ctx);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
for ( i = hi; i < count; i++ ) {
|
|
477
|
+
ca_axis_dispatch_shift_cell(ax, pstride, row_off, i, bytes,
|
|
478
|
+
cb, ctx);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
for ( k = inner - 1; k >= 0; k-- ) {
|
|
485
|
+
if ( ++idx[k] < prefix[k].count ) break;
|
|
486
|
+
idx[k] = 0;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
396
491
|
/* Generic per-slab driver. Walks the (post-merge / post-layout)
|
|
397
492
|
prefix axes row-major and invokes `cb` once per slab iteration.
|
|
398
493
|
The all-slab case degenerates to a single `cb` invocation with
|
|
@@ -437,6 +532,17 @@ ca_axis_dispatch_for_each_slab (CArray *parent,
|
|
|
437
532
|
return;
|
|
438
533
|
}
|
|
439
534
|
|
|
535
|
+
/* Innermost SHIFT axis with step 1: the in-range part of each row is one
|
|
536
|
+
contiguous run of parent cells, so it goes to cb as one slab instead of
|
|
537
|
+
one cell at a time. */
|
|
538
|
+
if ( slab_start == lndim
|
|
539
|
+
&& laxes[lndim - 1].kind == CA_AXIS_KIND_SHIFT
|
|
540
|
+
&& laxes[lndim - 1].step == 1 ) {
|
|
541
|
+
ca_axis_dispatch_for_each_shift_row(laxes, pstrides, lndim, bytes,
|
|
542
|
+
total_elements, cb, ctx);
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
440
546
|
/* Pre-classify prefix axes once. Inner loop becomes branchless
|
|
441
547
|
modulo a per-axis kind tag whose value is constant across
|
|
442
548
|
iters. */
|
|
@@ -951,3 +1057,117 @@ ca_axis_dispatch_outer_has_shift (const ca_axis_desc_t *descs,
|
|
|
951
1057
|
}
|
|
952
1058
|
return 0;
|
|
953
1059
|
}
|
|
1060
|
+
|
|
1061
|
+
/* ==========================================================================
|
|
1062
|
+
Transfers of a descriptor view (CAGrid, CASelect, CASelectAxis, CAWindow)
|
|
1063
|
+
whose parent holds no ptr.
|
|
1064
|
+
|
|
1065
|
+
The engine above walks parent->ptr. A cold parent is handled by what it
|
|
1066
|
+
is:
|
|
1067
|
+
|
|
1068
|
+
- one ca_attach_is_alias accepts already has the memory: borrow it;
|
|
1069
|
+
- one with no memory to lend (ca_parent_lends_no_memory) is asked for
|
|
1070
|
+
the selected cells only, through the view's own xfer_stride over the
|
|
1071
|
+
whole view -- producing every cell of the parent to serve a selection
|
|
1072
|
+
would make the cost follow the parent's size;
|
|
1073
|
+
- anything else is gathered into a parent-shaped scratch that stands in
|
|
1074
|
+
for parent->ptr, and pushed back for PUT.
|
|
1075
|
+
========================================================================== */
|
|
1076
|
+
|
|
1077
|
+
/* The whole view as one region request to its own xfer_stride slot. */
|
|
1078
|
+
static void
|
|
1079
|
+
ca_axis_view_xfer_region (CArray *ca, void *data, int dir)
|
|
1080
|
+
{
|
|
1081
|
+
ca_size_t starts[CA_RANK_MAX], strides[CA_RANK_MAX], s;
|
|
1082
|
+
int8_t k;
|
|
1083
|
+
|
|
1084
|
+
/* The slot is called directly, past ca_xfer_stride's empty-region check. */
|
|
1085
|
+
if ( ca->elements == 0 ) return;
|
|
1086
|
+
|
|
1087
|
+
s = ca->bytes;
|
|
1088
|
+
for ( k = ca->ndim - 1; k >= 0; k-- ) {
|
|
1089
|
+
starts[k] = 0;
|
|
1090
|
+
strides[k] = s;
|
|
1091
|
+
s *= ca->dim[k];
|
|
1092
|
+
}
|
|
1093
|
+
ca_func[ca->obj_type].xfer_stride(ca, starts, ca->dim, strides, data, dir);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
void
|
|
1097
|
+
ca_axis_view_xfer_all (void *ap, ca_axis_view_fast_t fast, int region_ok,
|
|
1098
|
+
void *data, int dir)
|
|
1099
|
+
{
|
|
1100
|
+
CArray *ca = (CArray *) ap;
|
|
1101
|
+
CArray *parent = ((CAView *) ca)->parent;
|
|
1102
|
+
|
|
1103
|
+
if ( parent->ptr ) {
|
|
1104
|
+
fast(ca, (char *) data, dir);
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
if ( ca_attach_is_alias(parent) ) {
|
|
1109
|
+
ca_attach(parent); /* window: an alias attach, cannot raise */
|
|
1110
|
+
fast(ca, (char *) data, dir);
|
|
1111
|
+
ca_detach(parent);
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
if ( region_ok && ca_parent_lends_no_memory(parent) ) {
|
|
1116
|
+
ca_axis_view_xfer_region(ca, data, dir);
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
{
|
|
1121
|
+
volatile VALUE holder;
|
|
1122
|
+
ca_size_t plen = parent->elements * parent->bytes;
|
|
1123
|
+
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
1124
|
+
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
1125
|
+
parent->ptr = parent_scratch;
|
|
1126
|
+
fast(ca, (char *) data, dir);
|
|
1127
|
+
/* Put parent->ptr back before the PUT: the PUT can raise (a lazy
|
|
1128
|
+
backing's sync failing), and the scratch is gone once this frame
|
|
1129
|
+
is. */
|
|
1130
|
+
parent->ptr = NULL;
|
|
1131
|
+
if ( dir == CA_XFER_PUT ) {
|
|
1132
|
+
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
1133
|
+
}
|
|
1134
|
+
ALLOCV_END(holder);
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
/* The attach of a view that owns its buffer and fills it through its own
|
|
1139
|
+
transfers (a descriptor view whose parent has no memory to lend, CARemap,
|
|
1140
|
+
CAStack, CAMeld). The buffer is published only once filled -- a view
|
|
1141
|
+
with a live ptr makes the per-cell dispatchers bypass the transfer slots,
|
|
1142
|
+
and for CA_OBJECT the garbage cells of an unfilled buffer would be marked
|
|
1143
|
+
-- and a raise while filling frees it. The fill goes through ca_xfer_all,
|
|
1144
|
+
which holds the object cells against a collection while the transfers
|
|
1145
|
+
call Ruby. */
|
|
1146
|
+
|
|
1147
|
+
static VALUE
|
|
1148
|
+
ca_axis_view_fill_owned (VALUE arg)
|
|
1149
|
+
{
|
|
1150
|
+
void **args = (void **) arg;
|
|
1151
|
+
ca_xfer_all((CArray *) args[0], args[1], CA_XFER_GET);
|
|
1152
|
+
return Qnil;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
void
|
|
1156
|
+
ca_axis_view_attach_owned (void *ap)
|
|
1157
|
+
{
|
|
1158
|
+
CArray *ca = (CArray *) ap;
|
|
1159
|
+
char *buf = xmalloc(ca_length(ca) > 0 ? ca_length(ca) : 1);
|
|
1160
|
+
void *args[2];
|
|
1161
|
+
|
|
1162
|
+
args[0] = ca;
|
|
1163
|
+
args[1] = buf;
|
|
1164
|
+
ca_fill_or_xfree(buf, ca_axis_view_fill_owned, (VALUE) args);
|
|
1165
|
+
ca->ptr = buf;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
void
|
|
1169
|
+
ca_axis_view_sync_owned (void *ap)
|
|
1170
|
+
{
|
|
1171
|
+
CArray *ca = (CArray *) ap;
|
|
1172
|
+
ca_func[ca->obj_type].xfer_all(ca, ca->ptr, CA_XFER_PUT);
|
|
1173
|
+
}
|