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_obj_repeat.c
CHANGED
|
@@ -39,20 +39,23 @@ ca_repeat_setup (CAStride *ca, CArray *parent, int8_t ndim, ca_size_t *count)
|
|
|
39
39
|
int8_t data_ndim = 0;
|
|
40
40
|
int8_t i, j;
|
|
41
41
|
|
|
42
|
+
if ( ndim < 0 || ndim > CA_RANK_MAX ) {
|
|
43
|
+
rb_raise(rb_eArgError, "invalid ndim %d", (int) ndim);
|
|
44
|
+
}
|
|
42
45
|
for (i = 0; i < ndim; i++) {
|
|
43
46
|
if (count[i] < 0) {
|
|
44
|
-
rb_raise(
|
|
47
|
+
rb_raise(rb_eArgError,
|
|
45
48
|
"negative size for %i-th dimension specified", i);
|
|
46
49
|
}
|
|
47
50
|
if (count[i]) nrpt *= count[i];
|
|
48
51
|
else data_ndim += 1;
|
|
49
52
|
}
|
|
50
53
|
if (data_ndim != parent->ndim) {
|
|
51
|
-
rb_raise(
|
|
54
|
+
rb_raise(rb_eArgError,
|
|
52
55
|
"mismatch in ndim between original array and determined by # of dummies");
|
|
53
56
|
}
|
|
54
57
|
if (((double) parent->elements) * nrpt > CA_LENGTH_MAX) {
|
|
55
|
-
rb_raise(
|
|
58
|
+
rb_raise(rb_eArgError, "too large byte length");
|
|
56
59
|
}
|
|
57
60
|
(void) total_elements_d;
|
|
58
61
|
|
|
@@ -77,6 +80,12 @@ ca_repeat_setup (CAStride *ca, CArray *parent, int8_t ndim, ca_size_t *count)
|
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
84
|
+
run them before it allocates. */
|
|
85
|
+
if ( ca == NULL ) {
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
80
89
|
ca_stride_setup(ca, CA_OBJ_REPEAT, parent,
|
|
81
90
|
parent->data_type, parent->bytes,
|
|
82
91
|
ndim, newdim, strides, 0);
|
|
@@ -91,7 +100,9 @@ ca_repeat_setup (CAStride *ca, CArray *parent, int8_t ndim, ca_size_t *count)
|
|
|
91
100
|
CAStride *
|
|
92
101
|
ca_repeat_new (CArray *parent, int8_t ndim, ca_size_t *count)
|
|
93
102
|
{
|
|
94
|
-
CAStride *ca
|
|
103
|
+
CAStride *ca;
|
|
104
|
+
ca_repeat_setup(NULL, parent, ndim, count);
|
|
105
|
+
ca = (CAStride *) ca_array_alloc(CA_OBJ_REPEAT, ndim);
|
|
95
106
|
ca_repeat_setup(ca, parent, ndim, count);
|
|
96
107
|
return ca;
|
|
97
108
|
}
|
|
@@ -155,7 +166,7 @@ rb_ca_repeat (int argc, VALUE *argv, VALUE self)
|
|
|
155
166
|
TypedData_Get_Struct(argv[0], CArray, &carray_data_type, ct);
|
|
156
167
|
}
|
|
157
168
|
if ( ct->ndim < ca->ndim ) {
|
|
158
|
-
rb_raise(
|
|
169
|
+
rb_raise(rb_eArgError, "invalid ndim to template");
|
|
159
170
|
}
|
|
160
171
|
args = rb_ary_new();
|
|
161
172
|
ndim = 0;
|
|
@@ -208,6 +219,10 @@ rb_ca_repeat (int argc, VALUE *argv, VALUE self)
|
|
|
208
219
|
return rb_ca_repeat((int)RARRAY_LEN(args), (VALUE *)RARRAY_CONST_PTR(args), self);
|
|
209
220
|
}
|
|
210
221
|
|
|
222
|
+
if ( argc > CA_RANK_MAX ) { /* count[] and dim[] hold CA_RANK_MAX */
|
|
223
|
+
rb_raise(rb_eArgError, "invalid ndim %d", argc);
|
|
224
|
+
}
|
|
225
|
+
|
|
211
226
|
repeat = 1;
|
|
212
227
|
for (i=0; i<argc; i++) {
|
|
213
228
|
if ( rb_obj_is_kind_of(argv[i], rb_cSymbol) ) {
|
|
@@ -255,6 +270,7 @@ rb_ca_repeat_initialize_copy (VALUE self, VALUE other)
|
|
|
255
270
|
{
|
|
256
271
|
CAStride *ca, *cs;
|
|
257
272
|
TypedData_Get_Struct(self, CAStride, &castride_data_type, ca);
|
|
273
|
+
ca_check_uninitialized(ca);
|
|
258
274
|
TypedData_Get_Struct(other, CAStride, &castride_data_type, cs);
|
|
259
275
|
if ( ca_func[CA_OBJ_REPEAT].pool_init ) {
|
|
260
276
|
ca_array_pool_alloc(ca, CA_OBJ_REPEAT, cs->ndim);
|
data/ext/ca_obj_roll.c
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
---------------------------------------------------------------------------- */
|
|
18
18
|
|
|
19
19
|
#include "carray.h"
|
|
20
|
+
#include "carray_internal.h"
|
|
20
21
|
#include "ca_composite_dispatch.h"
|
|
21
22
|
#include "ca_obj_face.h"
|
|
22
23
|
|
|
@@ -90,12 +91,15 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
|
|
|
90
91
|
|
|
91
92
|
elements = 1;
|
|
92
93
|
for (i = 0; i < ndim; i++) {
|
|
93
|
-
if ( parent->dim[i] <= 0 ) {
|
|
94
|
-
rb_raise(rb_eIndexError, "invalid parent dim for %d-th dimension", i);
|
|
95
|
-
}
|
|
96
94
|
elements *= parent->dim[i];
|
|
97
95
|
}
|
|
98
96
|
|
|
97
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
98
|
+
run them before it allocates. */
|
|
99
|
+
if ( ca == NULL ) {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
99
103
|
ca->obj_type = CA_OBJ_ROLL;
|
|
100
104
|
ca->data_type = parent->data_type;
|
|
101
105
|
ca->flags = 0;
|
|
@@ -114,8 +118,11 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
|
|
|
114
118
|
for (i = 0; i < ndim; i++) {
|
|
115
119
|
ca->dim[i] = parent->dim[i];
|
|
116
120
|
/* Normalise: ((shift[i] % dim[i]) + dim[i]) % dim[i] ∈ [0, dim[i]). */
|
|
117
|
-
ca_size_t s =
|
|
118
|
-
if (
|
|
121
|
+
ca_size_t s = 0; /* an empty axis has nothing to roll */
|
|
122
|
+
if ( parent->dim[i] > 0 ) {
|
|
123
|
+
s = shift[i] % parent->dim[i];
|
|
124
|
+
if ( s < 0 ) s += parent->dim[i];
|
|
125
|
+
}
|
|
119
126
|
ca->reps[i] = s;
|
|
120
127
|
}
|
|
121
128
|
|
|
@@ -129,7 +136,9 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
|
|
|
129
136
|
CARoll *
|
|
130
137
|
ca_roll_new (CArray *parent, ca_size_t *shift)
|
|
131
138
|
{
|
|
132
|
-
CARoll *ca
|
|
139
|
+
CARoll *ca;
|
|
140
|
+
ca_roll_setup(NULL, parent, shift);
|
|
141
|
+
ca = ALLOC(CARoll);
|
|
133
142
|
ca_roll_setup(ca, parent, shift);
|
|
134
143
|
return ca;
|
|
135
144
|
}
|
|
@@ -214,6 +223,7 @@ static void
|
|
|
214
223
|
ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
215
224
|
ca_size_t *strides, void *data, int dir)
|
|
216
225
|
{
|
|
226
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
217
227
|
CARoll *ca = (CARoll *) ap;
|
|
218
228
|
CArray *parent = ca->parent;
|
|
219
229
|
int8_t ndim = ca->ndim;
|
|
@@ -264,6 +274,95 @@ ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
264
274
|
return;
|
|
265
275
|
}
|
|
266
276
|
|
|
277
|
+
/* The inner range is one run of a parent row, or two when it wraps, and
|
|
278
|
+
the rows along the next axis out are consecutive parent rows except
|
|
279
|
+
across that axis's wrap. So each pass over the axes further out moves
|
|
280
|
+
at most two strided boxes per inner run, instead of one transfer per
|
|
281
|
+
row. A box over an unwrapped inner range is already the request's own
|
|
282
|
+
layout; a box over one of two inner runs goes through a scratch whose
|
|
283
|
+
rows are spliced into the request's. Object cells keep the per-row
|
|
284
|
+
path: a scratch would hold the VALUEs a parent produces where the GC
|
|
285
|
+
cannot see them. */
|
|
286
|
+
if ( inner >= 1 ) {
|
|
287
|
+
int8_t m = inner - 1;
|
|
288
|
+
ca_size_t dim_in = parent->dim[inner];
|
|
289
|
+
ca_size_t p0 = starts[inner] - ca->reps[inner];
|
|
290
|
+
ca_size_t seg_p[2], seg_n[2], seg_i[2];
|
|
291
|
+
int nseg, sg;
|
|
292
|
+
if (p0 < 0) p0 += dim_in;
|
|
293
|
+
if ( p0 + counts[inner] <= dim_in ) {
|
|
294
|
+
nseg = 1;
|
|
295
|
+
seg_p[0] = p0; seg_n[0] = counts[inner]; seg_i[0] = 0;
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
nseg = 2;
|
|
299
|
+
seg_p[0] = p0; seg_n[0] = dim_in - p0; seg_i[0] = 0;
|
|
300
|
+
seg_p[1] = 0; seg_n[1] = counts[inner] - seg_n[0]; seg_i[1] = seg_n[0];
|
|
301
|
+
}
|
|
302
|
+
if ( nseg == 1 || ca->data_type != CA_OBJECT ) {
|
|
303
|
+
volatile VALUE holder = 0;
|
|
304
|
+
char *tmp = NULL;
|
|
305
|
+
if ( nseg == 2 ) {
|
|
306
|
+
ca_size_t wide = seg_n[0] > seg_n[1] ? seg_n[0] : seg_n[1];
|
|
307
|
+
tmp = (char *) ALLOCV(holder, counts[m] * wide * ca->bytes);
|
|
308
|
+
}
|
|
309
|
+
for (k = 0; k < m; k++) o[k] = 0;
|
|
310
|
+
while (1) {
|
|
311
|
+
ca_size_t pbase = 0, doff = 0;
|
|
312
|
+
for (k = 0; k < m; k++) {
|
|
313
|
+
ca_size_t j = (starts[k] + o[k]) - ca->reps[k];
|
|
314
|
+
if (j < 0) j += parent->dim[k];
|
|
315
|
+
pbase += j * pnative[k];
|
|
316
|
+
doff += o[k] * dstride[k];
|
|
317
|
+
}
|
|
318
|
+
for (sg = 0; sg < nseg; sg++) {
|
|
319
|
+
ca_size_t r = 0;
|
|
320
|
+
while (r < counts[m]) {
|
|
321
|
+
ca_size_t pm = (starts[m] + r) - ca->reps[m];
|
|
322
|
+
ca_size_t run, q;
|
|
323
|
+
ca_size_t pstarts[CA_RANK_MAX], pcounts[CA_RANK_MAX], pstrides[CA_RANK_MAX];
|
|
324
|
+
char *rows = d + doff + r * dstride[m] + seg_i[sg] * ca->bytes;
|
|
325
|
+
ca_size_t rowb = seg_n[sg] * ca->bytes;
|
|
326
|
+
if (pm < 0) pm += parent->dim[m];
|
|
327
|
+
run = parent->dim[m] - pm;
|
|
328
|
+
if (run > counts[m] - r) run = counts[m] - r;
|
|
329
|
+
ca_addr2index((CArray *) parent,
|
|
330
|
+
(pbase + pm * pnative[m] + seg_p[sg] * pnative[inner])
|
|
331
|
+
/ parent->bytes, pstarts);
|
|
332
|
+
for (k = 0; k < ndim; k++) { pcounts[k] = 1; pstrides[k] = 0; }
|
|
333
|
+
pcounts[m] = run;
|
|
334
|
+
pstrides[m] = pnative[m];
|
|
335
|
+
pcounts[inner] = seg_n[sg];
|
|
336
|
+
pstrides[inner] = pnative[inner];
|
|
337
|
+
if ( nseg == 1 ) {
|
|
338
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, rows, dir);
|
|
339
|
+
}
|
|
340
|
+
else if ( dir == CA_XFER_GET ) {
|
|
341
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, tmp, dir);
|
|
342
|
+
for (q = 0; q < run; q++) {
|
|
343
|
+
memcpy(rows + q * dstride[m], tmp + q * rowb, rowb);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
for (q = 0; q < run; q++) {
|
|
348
|
+
memcpy(tmp + q * rowb, rows + q * dstride[m], rowb);
|
|
349
|
+
}
|
|
350
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, tmp, dir);
|
|
351
|
+
}
|
|
352
|
+
r += run;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
k = m - 1;
|
|
356
|
+
while (k >= 0) { if (++o[k] < counts[k]) break; o[k] = 0; k--; }
|
|
357
|
+
if (k < 0) break;
|
|
358
|
+
}
|
|
359
|
+
if ( tmp ) {
|
|
360
|
+
ALLOCV_END(holder);
|
|
361
|
+
}
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
267
366
|
for (k = 0; k < ndim; k++) o[k] = 0;
|
|
268
367
|
while (1) {
|
|
269
368
|
ca_size_t pbase = 0, doff = 0, i;
|
|
@@ -459,10 +558,13 @@ ca_roll_func_xfer_all (void *ap, void *data, int dir)
|
|
|
459
558
|
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
460
559
|
parent->ptr = parent_scratch;
|
|
461
560
|
ca_roll_iterate_regions(ca, (char *) data, dir == CA_XFER_PUT);
|
|
561
|
+
/* Put parent->ptr back before the PUT: the PUT can raise (a lazy
|
|
562
|
+
backing's sync failing), and the scratch is gone once this
|
|
563
|
+
frame is. */
|
|
564
|
+
parent->ptr = parent_ptr_saved;
|
|
462
565
|
if ( dir == CA_XFER_PUT ) {
|
|
463
566
|
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
464
567
|
}
|
|
465
|
-
parent->ptr = parent_ptr_saved;
|
|
466
568
|
ALLOCV_END(holder);
|
|
467
569
|
}
|
|
468
570
|
}
|
|
@@ -480,10 +582,7 @@ static void
|
|
|
480
582
|
ca_roll_func_create_mask (void *ap)
|
|
481
583
|
{
|
|
482
584
|
CARoll *ca = (CARoll *) ap;
|
|
483
|
-
|
|
484
|
-
if ( ! ca->parent->mask ) {
|
|
485
|
-
ca_create_mask(ca->parent);
|
|
486
|
-
}
|
|
585
|
+
ca_create_mask(ca->parent);
|
|
487
586
|
ca->mask = (CArray *) ca_roll_new(ca->parent->mask, ca->reps);
|
|
488
587
|
}
|
|
489
588
|
|
|
@@ -557,11 +656,13 @@ rb_ca_roll_initialize_copy (VALUE self, VALUE other)
|
|
|
557
656
|
{
|
|
558
657
|
CARoll *ca, *cs;
|
|
559
658
|
TypedData_Get_Struct(self, CARoll, &caroll_data_type, ca);
|
|
659
|
+
ca_check_uninitialized(ca);
|
|
560
660
|
TypedData_Get_Struct(other, CARoll, &caroll_data_type, cs);
|
|
561
661
|
ca_roll_setup(ca, cs->parent, cs->reps);
|
|
562
662
|
return self;
|
|
563
663
|
}
|
|
564
664
|
|
|
665
|
+
#ifdef CARRAY_DEV_BUILD
|
|
565
666
|
/* Debug-only accessor returning the roll descriptor as a Hash
|
|
566
667
|
(`shifts`, `n_regions`, `ndim`). Not part of the public surface. */
|
|
567
668
|
static VALUE
|
|
@@ -583,6 +684,7 @@ rb_ca_roll_descriptor (VALUE self)
|
|
|
583
684
|
rb_hash_aset(hash, ID2SYM(rb_intern("ndim")), INT2NUM(ca->ndim));
|
|
584
685
|
return hash;
|
|
585
686
|
}
|
|
687
|
+
#endif
|
|
586
688
|
|
|
587
689
|
void
|
|
588
690
|
Init_ca_obj_roll (void)
|
|
@@ -618,7 +720,9 @@ Init_ca_obj_roll (void)
|
|
|
618
720
|
rb_define_method(rb_cCARoll, "initialize_copy",
|
|
619
721
|
rb_ca_roll_initialize_copy, 1);
|
|
620
722
|
|
|
723
|
+
#ifdef CARRAY_DEV_BUILD
|
|
621
724
|
/* Debug accessor, not part of the public surface. */
|
|
622
725
|
rb_define_method(rb_cCARoll, "_roll_descriptor",
|
|
623
726
|
rb_ca_roll_descriptor, 0);
|
|
727
|
+
#endif
|
|
624
728
|
}
|
data/ext/ca_obj_select.c
CHANGED
|
@@ -83,22 +83,60 @@ VALUE rb_cCASelectMask;
|
|
|
83
83
|
|
|
84
84
|
/* ------------------------------------------------------------------- */
|
|
85
85
|
|
|
86
|
-
/*
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
/* Owned snapshot of the selector: masked selector cells become false.
|
|
87
|
+
After construction, mutating the caller's live selector does not affect
|
|
88
|
+
the view. Reading the selector can raise (a lazy boolean view), so the
|
|
89
|
+
snapshot is taken before the view struct is allocated, and a snapshot
|
|
90
|
+
whose fill raises is freed on the way out. */
|
|
91
|
+
static VALUE
|
|
92
|
+
ca_select_snapshot_masked (VALUE arg)
|
|
92
93
|
{
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
CArray **pair = (CArray **) arg;
|
|
95
|
+
CArray *select = pair[0], *snap = pair[1];
|
|
96
|
+
boolean8_t *q, *m;
|
|
95
97
|
ca_size_t i;
|
|
98
|
+
volatile VALUE holder = 0;
|
|
99
|
+
ca_copy_data(select, snap->ptr);
|
|
100
|
+
ca_update_mask(select);
|
|
101
|
+
m = ALLOCV_N(boolean8_t, holder, select->elements);
|
|
102
|
+
ca_copy_data(select->mask, (char *) m);
|
|
103
|
+
q = (boolean8_t *) snap->ptr;
|
|
104
|
+
for (i = 0; i < select->elements; i++) {
|
|
105
|
+
if ( m[i] ) {
|
|
106
|
+
q[i] = 0;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
ALLOCV_END(holder);
|
|
110
|
+
return Qnil;
|
|
111
|
+
}
|
|
96
112
|
|
|
113
|
+
CArray *
|
|
114
|
+
ca_select_snapshot (CArray *select)
|
|
115
|
+
{
|
|
97
116
|
if ( ! ca_is_boolean_type(select) ) {
|
|
98
117
|
rb_raise(rb_eRuntimeError,
|
|
99
118
|
"selection array for CASelect should be have "
|
|
100
119
|
"the data_type of CA_BOOLEAN");
|
|
101
120
|
}
|
|
121
|
+
if ( ca_has_mask(select) ) {
|
|
122
|
+
CArray *pair[2];
|
|
123
|
+
pair[0] = select;
|
|
124
|
+
pair[1] = ca_template(select);
|
|
125
|
+
ca_fill_or_free(pair[1], ca_select_snapshot_masked, (VALUE) pair);
|
|
126
|
+
return pair[1];
|
|
127
|
+
}
|
|
128
|
+
return ca_copy(select);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* Set up the view over `parent` from an owned selector snapshot (see
|
|
132
|
+
ca_select_snapshot) and pre-compute ca->indices (TRUE positions in flat
|
|
133
|
+
parent order). Does not raise. */
|
|
134
|
+
static int
|
|
135
|
+
ca_select_setup (CASelect *ca, CArray *parent, CArray *snapshot)
|
|
136
|
+
{
|
|
137
|
+
int8_t data_type;
|
|
138
|
+
ca_size_t bytes;
|
|
139
|
+
ca_size_t i;
|
|
102
140
|
|
|
103
141
|
data_type = parent->data_type;
|
|
104
142
|
bytes = parent->bytes;
|
|
@@ -114,26 +152,7 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
114
152
|
ca->attach = 0;
|
|
115
153
|
ca->nosync = 0;
|
|
116
154
|
ca->indices = NULL;
|
|
117
|
-
|
|
118
|
-
/* The `share` argument is preserved for source compatibility but
|
|
119
|
-
no longer toggles a live-reference path; both paths copy.
|
|
120
|
-
Masked selector cells become false in the snapshot. */
|
|
121
|
-
(void) share;
|
|
122
|
-
if ( ca_has_mask(select) ) {
|
|
123
|
-
boolean8_t *p, *q, *m;
|
|
124
|
-
ca->select = ca_template(select);
|
|
125
|
-
ca_attach(select);
|
|
126
|
-
q = (boolean8_t *) ca->select->ptr;
|
|
127
|
-
p = (boolean8_t *) select->ptr;
|
|
128
|
-
m = (boolean8_t *) select->mask->ptr;
|
|
129
|
-
for (i = 0; i < select->elements; i++) {
|
|
130
|
-
*q = ( *m ) ? 0 : *p;
|
|
131
|
-
q++; p++; m++;
|
|
132
|
-
}
|
|
133
|
-
ca_detach(select);
|
|
134
|
-
} else {
|
|
135
|
-
ca->select = ca_copy(select);
|
|
136
|
-
}
|
|
155
|
+
ca->select = snapshot;
|
|
137
156
|
|
|
138
157
|
/* Count TRUE positions and snapshot them into ca->indices. */
|
|
139
158
|
{
|
|
@@ -181,7 +200,7 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
181
200
|
ca->dim = &(ca->_dim);
|
|
182
201
|
ca->dim[0] = ca->elements;
|
|
183
202
|
|
|
184
|
-
if ( ca_is_scalar(
|
|
203
|
+
if ( ca_is_scalar(snapshot) ) {
|
|
185
204
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
186
205
|
}
|
|
187
206
|
|
|
@@ -191,8 +210,9 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
191
210
|
CArray *
|
|
192
211
|
ca_select_new (CArray *parent, CArray *select)
|
|
193
212
|
{
|
|
213
|
+
CArray *snapshot = ca_select_snapshot(select);
|
|
194
214
|
CASelect *ca = ALLOC(CASelect);
|
|
195
|
-
ca_select_setup(ca, parent,
|
|
215
|
+
ca_select_setup(ca, parent, snapshot);
|
|
196
216
|
return (CArray*) ca;
|
|
197
217
|
}
|
|
198
218
|
|
|
@@ -202,9 +222,7 @@ ca_select_new (CArray *parent, CArray *select)
|
|
|
202
222
|
CArray *
|
|
203
223
|
ca_select_new_share (CArray *parent, CArray *select)
|
|
204
224
|
{
|
|
205
|
-
|
|
206
|
-
ca_select_setup(ca, parent, select, 1);
|
|
207
|
-
return (CArray*) ca;
|
|
225
|
+
return ca_select_new(parent, select);
|
|
208
226
|
}
|
|
209
227
|
|
|
210
228
|
static void
|
|
@@ -337,6 +355,7 @@ static void
|
|
|
337
355
|
ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
338
356
|
ca_size_t *strides, void *data, int dir)
|
|
339
357
|
{
|
|
358
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
340
359
|
CASelect *ca = (CASelect *) ap;
|
|
341
360
|
CArray *parent = ca->parent;
|
|
342
361
|
ca_size_t n = counts[0];
|
|
@@ -399,24 +418,34 @@ ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
399
418
|
}
|
|
400
419
|
}
|
|
401
420
|
|
|
421
|
+
/* A parent with no memory to lend (ca_parent_lends_no_memory) is never
|
|
422
|
+
attached: the view owns its buffer, filled and drained through xfer_all,
|
|
423
|
+
which asks the parent for the selected cells only. The predicate asks
|
|
424
|
+
what the parent is, not whether it is attached now, so attach, sync and
|
|
425
|
+
detach all take the same branch. */
|
|
426
|
+
|
|
402
427
|
static void
|
|
403
428
|
ca_select_func_allocate (void *ap)
|
|
404
429
|
{
|
|
405
430
|
CASelect *ca = (CASelect *) ap;
|
|
406
|
-
|
|
431
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
432
|
+
ca_attach(ca->parent);
|
|
433
|
+
}
|
|
407
434
|
ca->ptr = xmalloc(ca_length(ca));
|
|
408
435
|
}
|
|
409
436
|
|
|
410
|
-
/* Every attach / sync / xfer_all / xfer_stride / fill_data path
|
|
411
|
-
dispatches through the descriptor engine with the same shape
|
|
412
|
-
CASelectAxis uses: one axis over a flattened parent. */
|
|
413
|
-
|
|
414
437
|
static void
|
|
415
438
|
ca_select_func_attach (void *ap)
|
|
416
439
|
{
|
|
417
440
|
CASelect *ca = (CASelect *) ap;
|
|
418
441
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
419
442
|
ca_size_t pdims[CA_RANK_MAX];
|
|
443
|
+
|
|
444
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
445
|
+
ca_axis_view_attach_owned(ca);
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
420
449
|
ca_attach(ca->parent);
|
|
421
450
|
ca_select_describe_axes(ca, desc, pdims);
|
|
422
451
|
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
@@ -429,6 +458,12 @@ ca_select_func_sync (void *ap)
|
|
|
429
458
|
CASelect *ca = (CASelect *) ap;
|
|
430
459
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
431
460
|
ca_size_t pdims[CA_RANK_MAX];
|
|
461
|
+
|
|
462
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
463
|
+
ca_axis_view_sync_owned(ca);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
432
467
|
ca_select_describe_axes(ca, desc, pdims);
|
|
433
468
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
434
469
|
ca->elements, ca->ptr);
|
|
@@ -439,16 +474,20 @@ static void
|
|
|
439
474
|
ca_select_func_detach (void *ap)
|
|
440
475
|
{
|
|
441
476
|
CASelect *ca = (CASelect *) ap;
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
477
|
+
if ( ca->ptr ) {
|
|
478
|
+
xfree(ca->ptr);
|
|
479
|
+
ca->ptr = NULL;
|
|
480
|
+
}
|
|
481
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
482
|
+
ca_detach(ca->parent);
|
|
483
|
+
}
|
|
445
484
|
}
|
|
446
485
|
|
|
447
|
-
/*
|
|
448
|
-
cold-parent 2-pass scratch branch below. */
|
|
486
|
+
/* The transfer against parent->ptr, for ca_axis_view_xfer_all. */
|
|
449
487
|
static void
|
|
450
|
-
ca_select_func_run_fast_path (
|
|
488
|
+
ca_select_func_run_fast_path (void *ap, char *data, int dir)
|
|
451
489
|
{
|
|
490
|
+
CASelect *ca = (CASelect *) ap;
|
|
452
491
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
453
492
|
ca_size_t pdims[CA_RANK_MAX];
|
|
454
493
|
ca_select_describe_axes(ca, desc, pdims);
|
|
@@ -461,33 +500,10 @@ ca_select_func_run_fast_path (CASelect *ca, char *data, int dir)
|
|
|
461
500
|
}
|
|
462
501
|
}
|
|
463
502
|
|
|
464
|
-
/* Cold parent is served by a 2-pass scratch (gather parent into a
|
|
465
|
-
local buffer, dispatch through the fast path against the buffer,
|
|
466
|
-
scatter back on PUT). Deliberately avoids ca_attach(parent) so
|
|
467
|
-
that a silent transitive attach cannot re-enter through here. */
|
|
468
503
|
static void
|
|
469
504
|
ca_select_func_xfer_all (void *ap, void *data, int dir)
|
|
470
505
|
{
|
|
471
|
-
|
|
472
|
-
if ( ca->parent->ptr ) {
|
|
473
|
-
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
{
|
|
477
|
-
volatile VALUE holder;
|
|
478
|
-
CArray *parent = ca->parent;
|
|
479
|
-
ca_size_t plen = parent->elements * parent->bytes;
|
|
480
|
-
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
481
|
-
char *parent_ptr_saved = parent->ptr;
|
|
482
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
483
|
-
parent->ptr = parent_scratch;
|
|
484
|
-
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
485
|
-
if ( dir == CA_XFER_PUT ) {
|
|
486
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
487
|
-
}
|
|
488
|
-
parent->ptr = parent_ptr_saved;
|
|
489
|
-
ALLOCV_END(holder);
|
|
490
|
-
}
|
|
506
|
+
ca_axis_view_xfer_all(ap, ca_select_func_run_fast_path, 1, data, dir);
|
|
491
507
|
}
|
|
492
508
|
|
|
493
509
|
static void
|
|
@@ -516,18 +532,14 @@ ca_select_func_fill_data (void *ap, void *ptr)
|
|
|
516
532
|
ca_select_describe_axes(ca, desc, pdims);
|
|
517
533
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
518
534
|
ca->elements, ptr);
|
|
519
|
-
|
|
520
|
-
ca_detach(ca->parent);
|
|
535
|
+
ca_sync_detach(ca->parent);
|
|
521
536
|
}
|
|
522
537
|
|
|
523
538
|
static void
|
|
524
539
|
ca_select_func_create_mask (void *ap)
|
|
525
540
|
{
|
|
526
541
|
CASelect *ca = (CASelect *) ap;
|
|
527
|
-
|
|
528
|
-
if ( ! ca->parent->mask ) {
|
|
529
|
-
ca_create_mask(ca->parent);
|
|
530
|
-
}
|
|
542
|
+
ca_create_mask(ca->parent);
|
|
531
543
|
ca->mask = (CArray *) ca_select_new_share(ca->parent->mask, ca->select);
|
|
532
544
|
}
|
|
533
545
|
|
|
@@ -609,11 +621,12 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
|
|
|
609
621
|
CASelect *ca, *cs;
|
|
610
622
|
|
|
611
623
|
TypedData_Get_Struct(self, CASelect, &caselect_data_type, ca);
|
|
624
|
+
ca_check_uninitialized(ca);
|
|
612
625
|
TypedData_Get_Struct(other, CASelect, &caselect_data_type, cs);
|
|
613
626
|
|
|
614
627
|
/* Re-snapshot from the source's selector copy so the two views
|
|
615
628
|
end up with independent indices buffers. */
|
|
616
|
-
ca_select_setup(ca, cs->parent, cs->select
|
|
629
|
+
ca_select_setup(ca, cs->parent, ca_select_snapshot(cs->select));
|
|
617
630
|
|
|
618
631
|
return self;
|
|
619
632
|
}
|