carray 3.0.2 → 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 +304 -0
- data/README.md +3 -4
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +225 -0
- data/ext/ca_axis_group.c +177 -99
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +66 -71
- 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 +663 -214
- data/ext/ca_kernel_iterator.h +231 -167
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +132 -22
- 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 +1 -0
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +96 -25
- data/ext/ca_obj_face.c +406 -64
- data/ext/ca_obj_face.h +92 -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 +21 -21
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +189 -107
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +543 -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 +47 -49
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -118
- data/ext/ca_obj_stride.c +195 -34
- data/ext/ca_obj_string.c +17 -18
- 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 +149 -27
- 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 +102 -79
- 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 +463 -0
- data/ext/carray.h +70 -27
- data/ext/carray_access.c +455 -211
- data/ext/carray_address_basis.c +177 -36
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +46 -14
- data/ext/carray_call_cfunc.c +0 -28
- data/ext/carray_cast.c +1444 -209
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +32 -11
- data/ext/carray_core.c +514 -122
- data/ext/carray_count.c +140 -87
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +569 -277
- 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 +385 -3
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +682 -316
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +221 -76
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1089 -359
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +273 -239
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +170 -70
- data/ext/carray_sort.c +215 -218
- 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 +0 -2
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1076 -846
- data/ext/ruby_carray.c +7 -1
- 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 +19 -0
- data/lib/carray/autoload_method_extension.rb +6 -0
- data/lib/carray/axis_group.rb +174 -26
- data/lib/carray/basics.rb +91 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +118 -48
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +94 -26
- data/lib/carray/categorical_iterator.rb +333 -826
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +46 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +589 -82
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +124 -25
- data/lib/carray/frame/group.rb +189 -63
- data/lib/carray/frame/io.rb +412 -72
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +37 -16
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +715 -48
- 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 +29 -11
- data/lib/carray/iterator.rb +14 -2
- data/lib/carray/lazy.rb +54 -30
- data/lib/carray/mask_gap_fill.rb +66 -52
- 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/factorize.rb +2 -2
- 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 +117 -4
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +177 -36
- data/lib/carray/methods/mode.rb +18 -1
- 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/record_order.rb +208 -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 +51 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +4 -3
- 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 +517 -103
- data/lib/carray/window_iterator.rb +127 -72
- data/lib/carray.rb +2 -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 +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 +1 -2
- data/yard-stubs/carray_access.rb +5 -4
- data/yard-stubs/carray_broadcast.rb +1 -1
- 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 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +25 -13
- data/yard-stubs/carray_median_percentile.rb +10 -6
- data/yard-stubs/carray_order.rb +34 -13
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +2 -1
- data/yard-stubs/carray_sort.rb +43 -3
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +11 -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 -26005
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14862
- data/ext/carray_kernels_reduce_extreme.c +0 -17494
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32218
- 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
|
@@ -93,21 +93,24 @@ ca_select_snapshot_masked (VALUE arg)
|
|
|
93
93
|
{
|
|
94
94
|
CArray **pair = (CArray **) arg;
|
|
95
95
|
CArray *select = pair[0], *snap = pair[1];
|
|
96
|
-
boolean8_t *
|
|
96
|
+
boolean8_t *q, *m;
|
|
97
97
|
ca_size_t i;
|
|
98
|
-
|
|
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);
|
|
99
103
|
q = (boolean8_t *) snap->ptr;
|
|
100
|
-
p = (boolean8_t *) select->ptr;
|
|
101
|
-
m = (boolean8_t *) select->mask->ptr;
|
|
102
104
|
for (i = 0; i < select->elements; i++) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
+
if ( m[i] ) {
|
|
106
|
+
q[i] = 0;
|
|
107
|
+
}
|
|
105
108
|
}
|
|
106
|
-
|
|
109
|
+
ALLOCV_END(holder);
|
|
107
110
|
return Qnil;
|
|
108
111
|
}
|
|
109
112
|
|
|
110
|
-
|
|
113
|
+
CArray *
|
|
111
114
|
ca_select_snapshot (CArray *select)
|
|
112
115
|
{
|
|
113
116
|
if ( ! ca_is_boolean_type(select) ) {
|
|
@@ -352,6 +355,7 @@ static void
|
|
|
352
355
|
ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
353
356
|
ca_size_t *strides, void *data, int dir)
|
|
354
357
|
{
|
|
358
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
355
359
|
CASelect *ca = (CASelect *) ap;
|
|
356
360
|
CArray *parent = ca->parent;
|
|
357
361
|
ca_size_t n = counts[0];
|
|
@@ -414,24 +418,34 @@ ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
414
418
|
}
|
|
415
419
|
}
|
|
416
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
|
+
|
|
417
427
|
static void
|
|
418
428
|
ca_select_func_allocate (void *ap)
|
|
419
429
|
{
|
|
420
430
|
CASelect *ca = (CASelect *) ap;
|
|
421
|
-
|
|
431
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
432
|
+
ca_attach(ca->parent);
|
|
433
|
+
}
|
|
422
434
|
ca->ptr = xmalloc(ca_length(ca));
|
|
423
435
|
}
|
|
424
436
|
|
|
425
|
-
/* Every attach / sync / xfer_all / xfer_stride / fill_data path
|
|
426
|
-
dispatches through the descriptor engine with the same shape
|
|
427
|
-
CASelectAxis uses: one axis over a flattened parent. */
|
|
428
|
-
|
|
429
437
|
static void
|
|
430
438
|
ca_select_func_attach (void *ap)
|
|
431
439
|
{
|
|
432
440
|
CASelect *ca = (CASelect *) ap;
|
|
433
441
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
434
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
|
+
|
|
435
449
|
ca_attach(ca->parent);
|
|
436
450
|
ca_select_describe_axes(ca, desc, pdims);
|
|
437
451
|
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
@@ -444,6 +458,12 @@ ca_select_func_sync (void *ap)
|
|
|
444
458
|
CASelect *ca = (CASelect *) ap;
|
|
445
459
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
446
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
|
+
|
|
447
467
|
ca_select_describe_axes(ca, desc, pdims);
|
|
448
468
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
449
469
|
ca->elements, ca->ptr);
|
|
@@ -454,16 +474,20 @@ static void
|
|
|
454
474
|
ca_select_func_detach (void *ap)
|
|
455
475
|
{
|
|
456
476
|
CASelect *ca = (CASelect *) ap;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
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
|
+
}
|
|
460
484
|
}
|
|
461
485
|
|
|
462
|
-
/*
|
|
463
|
-
cold-parent 2-pass scratch branch below. */
|
|
486
|
+
/* The transfer against parent->ptr, for ca_axis_view_xfer_all. */
|
|
464
487
|
static void
|
|
465
|
-
ca_select_func_run_fast_path (
|
|
488
|
+
ca_select_func_run_fast_path (void *ap, char *data, int dir)
|
|
466
489
|
{
|
|
490
|
+
CASelect *ca = (CASelect *) ap;
|
|
467
491
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
468
492
|
ca_size_t pdims[CA_RANK_MAX];
|
|
469
493
|
ca_select_describe_axes(ca, desc, pdims);
|
|
@@ -476,33 +500,10 @@ ca_select_func_run_fast_path (CASelect *ca, char *data, int dir)
|
|
|
476
500
|
}
|
|
477
501
|
}
|
|
478
502
|
|
|
479
|
-
/* Cold parent is served by a 2-pass scratch (gather parent into a
|
|
480
|
-
local buffer, dispatch through the fast path against the buffer,
|
|
481
|
-
scatter back on PUT). Deliberately avoids ca_attach(parent) so
|
|
482
|
-
that a silent transitive attach cannot re-enter through here. */
|
|
483
503
|
static void
|
|
484
504
|
ca_select_func_xfer_all (void *ap, void *data, int dir)
|
|
485
505
|
{
|
|
486
|
-
|
|
487
|
-
if ( ca->parent->ptr ) {
|
|
488
|
-
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
{
|
|
492
|
-
volatile VALUE holder;
|
|
493
|
-
CArray *parent = ca->parent;
|
|
494
|
-
ca_size_t plen = parent->elements * parent->bytes;
|
|
495
|
-
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
496
|
-
char *parent_ptr_saved = parent->ptr;
|
|
497
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
498
|
-
parent->ptr = parent_scratch;
|
|
499
|
-
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
500
|
-
if ( dir == CA_XFER_PUT ) {
|
|
501
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
502
|
-
}
|
|
503
|
-
parent->ptr = parent_ptr_saved;
|
|
504
|
-
ALLOCV_END(holder);
|
|
505
|
-
}
|
|
506
|
+
ca_axis_view_xfer_all(ap, ca_select_func_run_fast_path, 1, data, dir);
|
|
506
507
|
}
|
|
507
508
|
|
|
508
509
|
static void
|
|
@@ -531,18 +532,14 @@ ca_select_func_fill_data (void *ap, void *ptr)
|
|
|
531
532
|
ca_select_describe_axes(ca, desc, pdims);
|
|
532
533
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
533
534
|
ca->elements, ptr);
|
|
534
|
-
|
|
535
|
-
ca_detach(ca->parent);
|
|
535
|
+
ca_sync_detach(ca->parent);
|
|
536
536
|
}
|
|
537
537
|
|
|
538
538
|
static void
|
|
539
539
|
ca_select_func_create_mask (void *ap)
|
|
540
540
|
{
|
|
541
541
|
CASelect *ca = (CASelect *) ap;
|
|
542
|
-
|
|
543
|
-
if ( ! ca->parent->mask ) {
|
|
544
|
-
ca_create_mask(ca->parent);
|
|
545
|
-
}
|
|
542
|
+
ca_create_mask(ca->parent);
|
|
546
543
|
ca->mask = (CArray *) ca_select_new_share(ca->parent->mask, ca->select);
|
|
547
544
|
}
|
|
548
545
|
|
|
@@ -624,6 +621,7 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
|
|
|
624
621
|
CASelect *ca, *cs;
|
|
625
622
|
|
|
626
623
|
TypedData_Get_Struct(self, CASelect, &caselect_data_type, ca);
|
|
624
|
+
ca_check_uninitialized(ca);
|
|
627
625
|
TypedData_Get_Struct(other, CASelect, &caselect_data_type, cs);
|
|
628
626
|
|
|
629
627
|
/* Re-snapshot from the source's selector copy so the two views
|