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_obj_repeat.c
CHANGED
|
@@ -39,20 +39,21 @@ 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
|
+
ca_check_rank_fits(ndim, NULL);
|
|
42
43
|
for (i = 0; i < ndim; i++) {
|
|
43
44
|
if (count[i] < 0) {
|
|
44
|
-
rb_raise(
|
|
45
|
+
rb_raise(rb_eArgError,
|
|
45
46
|
"negative size for %i-th dimension specified", i);
|
|
46
47
|
}
|
|
47
48
|
if (count[i]) nrpt *= count[i];
|
|
48
49
|
else data_ndim += 1;
|
|
49
50
|
}
|
|
50
51
|
if (data_ndim != parent->ndim) {
|
|
51
|
-
rb_raise(
|
|
52
|
+
rb_raise(rb_eArgError,
|
|
52
53
|
"mismatch in ndim between original array and determined by # of dummies");
|
|
53
54
|
}
|
|
54
55
|
if (((double) parent->elements) * nrpt > CA_LENGTH_MAX) {
|
|
55
|
-
rb_raise(
|
|
56
|
+
rb_raise(rb_eArgError, "too large byte length");
|
|
56
57
|
}
|
|
57
58
|
(void) total_elements_d;
|
|
58
59
|
|
|
@@ -77,9 +78,15 @@ ca_repeat_setup (CAStride *ca, CArray *parent, int8_t ndim, ca_size_t *count)
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
82
|
+
run them before it allocates. */
|
|
83
|
+
if ( ca == NULL ) {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ca_stride_setup_view(ca, CA_OBJ_REPEAT, parent,
|
|
88
|
+
parent->data_type, parent->bytes,
|
|
89
|
+
ndim, newdim, strides, 0);
|
|
83
90
|
|
|
84
91
|
ca_set_flag(ca, CA_FLAG_READ_ONLY);
|
|
85
92
|
if (ca->mask) {
|
|
@@ -91,8 +98,11 @@ ca_repeat_setup (CAStride *ca, CArray *parent, int8_t ndim, ca_size_t *count)
|
|
|
91
98
|
CAStride *
|
|
92
99
|
ca_repeat_new (CArray *parent, int8_t ndim, ca_size_t *count)
|
|
93
100
|
{
|
|
94
|
-
CAStride *ca
|
|
101
|
+
CAStride *ca;
|
|
102
|
+
ca_repeat_setup(NULL, parent, ndim, count);
|
|
103
|
+
ca = (CAStride *) ca_array_alloc(CA_OBJ_REPEAT, ndim);
|
|
95
104
|
ca_repeat_setup(ca, parent, ndim, count);
|
|
105
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
96
106
|
return ca;
|
|
97
107
|
}
|
|
98
108
|
|
|
@@ -155,7 +165,7 @@ rb_ca_repeat (int argc, VALUE *argv, VALUE self)
|
|
|
155
165
|
TypedData_Get_Struct(argv[0], CArray, &carray_data_type, ct);
|
|
156
166
|
}
|
|
157
167
|
if ( ct->ndim < ca->ndim ) {
|
|
158
|
-
rb_raise(
|
|
168
|
+
rb_raise(rb_eArgError, "invalid ndim to template");
|
|
159
169
|
}
|
|
160
170
|
args = rb_ary_new();
|
|
161
171
|
ndim = 0;
|
|
@@ -205,9 +215,13 @@ rb_ca_repeat (int argc, VALUE *argv, VALUE self)
|
|
|
205
215
|
self = rb_ca_refer_new(self, ca->data_type, ndim, dim, ca->bytes, 0);
|
|
206
216
|
}
|
|
207
217
|
}
|
|
208
|
-
|
|
218
|
+
self = rb_ca_repeat((int)RARRAY_LEN(args), (VALUE *)RARRAY_CONST_PTR(args), self);
|
|
219
|
+
RB_GC_GUARD(args); /* the repeat reads its arguments out of args */
|
|
220
|
+
return self;
|
|
209
221
|
}
|
|
210
222
|
|
|
223
|
+
ca_check_rank_fits(argc, NULL); /* count[] and dim[] hold CA_RANK_MAX */
|
|
224
|
+
|
|
211
225
|
repeat = 1;
|
|
212
226
|
for (i=0; i<argc; i++) {
|
|
213
227
|
if ( rb_obj_is_kind_of(argv[i], rb_cSymbol) ) {
|
|
@@ -255,6 +269,7 @@ rb_ca_repeat_initialize_copy (VALUE self, VALUE other)
|
|
|
255
269
|
{
|
|
256
270
|
CAStride *ca, *cs;
|
|
257
271
|
TypedData_Get_Struct(self, CAStride, &castride_data_type, ca);
|
|
272
|
+
ca_check_uninitialized(ca);
|
|
258
273
|
TypedData_Get_Struct(other, CAStride, &castride_data_type, cs);
|
|
259
274
|
if ( ca_func[CA_OBJ_REPEAT].pool_init ) {
|
|
260
275
|
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,14 +118,14 @@ 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
|
|
|
122
|
-
if ( ca_has_mask(parent) ) {
|
|
123
|
-
ca_create_mask(ca);
|
|
124
|
-
}
|
|
125
129
|
|
|
126
130
|
return 0;
|
|
127
131
|
}
|
|
@@ -129,8 +133,11 @@ ca_roll_setup (CARoll *ca, CArray *parent, ca_size_t *shift)
|
|
|
129
133
|
CARoll *
|
|
130
134
|
ca_roll_new (CArray *parent, ca_size_t *shift)
|
|
131
135
|
{
|
|
132
|
-
CARoll *ca
|
|
136
|
+
CARoll *ca;
|
|
137
|
+
ca_roll_setup(NULL, parent, shift);
|
|
138
|
+
ca = ALLOC(CARoll);
|
|
133
139
|
ca_roll_setup(ca, parent, shift);
|
|
140
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
134
141
|
return ca;
|
|
135
142
|
}
|
|
136
143
|
|
|
@@ -214,6 +221,7 @@ static void
|
|
|
214
221
|
ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
215
222
|
ca_size_t *strides, void *data, int dir)
|
|
216
223
|
{
|
|
224
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
217
225
|
CARoll *ca = (CARoll *) ap;
|
|
218
226
|
CArray *parent = ca->parent;
|
|
219
227
|
int8_t ndim = ca->ndim;
|
|
@@ -251,6 +259,7 @@ ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
251
259
|
ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
|
|
252
260
|
for (k = 0; k < ndim; k++) base += starts[k] * rnative[k];
|
|
253
261
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
262
|
+
/* empty: the slot returns on an empty region at its entry */
|
|
254
263
|
while (1) {
|
|
255
264
|
ca_size_t roff = base, ridx[CA_RANK_MAX];
|
|
256
265
|
for (k = 0; k < ndim; k++) roff += idx[k] * strides[k];
|
|
@@ -264,7 +273,97 @@ ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
264
273
|
return;
|
|
265
274
|
}
|
|
266
275
|
|
|
276
|
+
/* The inner range is one run of a parent row, or two when it wraps, and
|
|
277
|
+
the rows along the next axis out are consecutive parent rows except
|
|
278
|
+
across that axis's wrap. So each pass over the axes further out moves
|
|
279
|
+
at most two strided boxes per inner run, instead of one transfer per
|
|
280
|
+
row. A box over an unwrapped inner range is already the request's own
|
|
281
|
+
layout; a box over one of two inner runs goes through a scratch whose
|
|
282
|
+
rows are spliced into the request's. Object cells keep the per-row
|
|
283
|
+
path: a scratch would hold the VALUEs a parent produces where the GC
|
|
284
|
+
cannot see them. */
|
|
285
|
+
if ( inner >= 1 ) {
|
|
286
|
+
int8_t m = inner - 1;
|
|
287
|
+
ca_size_t dim_in = parent->dim[inner];
|
|
288
|
+
ca_size_t p0 = starts[inner] - ca->reps[inner];
|
|
289
|
+
ca_size_t seg_p[2], seg_n[2], seg_i[2];
|
|
290
|
+
int nseg, sg;
|
|
291
|
+
if (p0 < 0) p0 += dim_in;
|
|
292
|
+
if ( p0 + counts[inner] <= dim_in ) {
|
|
293
|
+
nseg = 1;
|
|
294
|
+
seg_p[0] = p0; seg_n[0] = counts[inner]; seg_i[0] = 0;
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
nseg = 2;
|
|
298
|
+
seg_p[0] = p0; seg_n[0] = dim_in - p0; seg_i[0] = 0;
|
|
299
|
+
seg_p[1] = 0; seg_n[1] = counts[inner] - seg_n[0]; seg_i[1] = seg_n[0];
|
|
300
|
+
}
|
|
301
|
+
if ( nseg == 1 || ca->data_type != CA_OBJECT ) {
|
|
302
|
+
volatile VALUE holder = 0;
|
|
303
|
+
char *tmp = NULL;
|
|
304
|
+
if ( nseg == 2 ) {
|
|
305
|
+
ca_size_t wide = seg_n[0] > seg_n[1] ? seg_n[0] : seg_n[1];
|
|
306
|
+
tmp = (char *) ALLOCV(holder, counts[m] * wide * ca->bytes);
|
|
307
|
+
}
|
|
308
|
+
for (k = 0; k < m; k++) o[k] = 0;
|
|
309
|
+
while (1) {
|
|
310
|
+
ca_size_t pbase = 0, doff = 0;
|
|
311
|
+
for (k = 0; k < m; k++) {
|
|
312
|
+
ca_size_t j = (starts[k] + o[k]) - ca->reps[k];
|
|
313
|
+
if (j < 0) j += parent->dim[k];
|
|
314
|
+
pbase += j * pnative[k];
|
|
315
|
+
doff += o[k] * dstride[k];
|
|
316
|
+
}
|
|
317
|
+
for (sg = 0; sg < nseg; sg++) {
|
|
318
|
+
ca_size_t r = 0;
|
|
319
|
+
while (r < counts[m]) {
|
|
320
|
+
ca_size_t pm = (starts[m] + r) - ca->reps[m];
|
|
321
|
+
ca_size_t run, q;
|
|
322
|
+
ca_size_t pstarts[CA_RANK_MAX], pcounts[CA_RANK_MAX], pstrides[CA_RANK_MAX];
|
|
323
|
+
char *rows = d + doff + r * dstride[m] + seg_i[sg] * ca->bytes;
|
|
324
|
+
ca_size_t rowb = seg_n[sg] * ca->bytes;
|
|
325
|
+
if (pm < 0) pm += parent->dim[m];
|
|
326
|
+
run = parent->dim[m] - pm;
|
|
327
|
+
if (run > counts[m] - r) run = counts[m] - r;
|
|
328
|
+
ca_addr2index((CArray *) parent,
|
|
329
|
+
(pbase + pm * pnative[m] + seg_p[sg] * pnative[inner])
|
|
330
|
+
/ parent->bytes, pstarts);
|
|
331
|
+
for (k = 0; k < ndim; k++) { pcounts[k] = 1; pstrides[k] = 0; }
|
|
332
|
+
pcounts[m] = run;
|
|
333
|
+
pstrides[m] = pnative[m];
|
|
334
|
+
pcounts[inner] = seg_n[sg];
|
|
335
|
+
pstrides[inner] = pnative[inner];
|
|
336
|
+
if ( nseg == 1 ) {
|
|
337
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, rows, dir);
|
|
338
|
+
}
|
|
339
|
+
else if ( dir == CA_XFER_GET ) {
|
|
340
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, tmp, dir);
|
|
341
|
+
for (q = 0; q < run; q++) {
|
|
342
|
+
memcpy(rows + q * dstride[m], tmp + q * rowb, rowb);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
for (q = 0; q < run; q++) {
|
|
347
|
+
memcpy(tmp + q * rowb, rows + q * dstride[m], rowb);
|
|
348
|
+
}
|
|
349
|
+
ca_xfer_stride(parent, pstarts, pcounts, pstrides, tmp, dir);
|
|
350
|
+
}
|
|
351
|
+
r += run;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
k = m - 1;
|
|
355
|
+
while (k >= 0) { if (++o[k] < counts[k]) break; o[k] = 0; k--; }
|
|
356
|
+
if (k < 0) break;
|
|
357
|
+
}
|
|
358
|
+
if ( tmp ) {
|
|
359
|
+
ALLOCV_END(holder);
|
|
360
|
+
}
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
267
365
|
for (k = 0; k < ndim; k++) o[k] = 0;
|
|
366
|
+
/* empty: the slot returns on an empty region at its entry */
|
|
268
367
|
while (1) {
|
|
269
368
|
ca_size_t pbase = 0, doff = 0, i;
|
|
270
369
|
for (k = 0; k < inner; k++) {
|
|
@@ -407,7 +506,7 @@ ca_roll_func_allocate (void *ap)
|
|
|
407
506
|
{
|
|
408
507
|
CARoll *ca = (CARoll *) ap;
|
|
409
508
|
ca_attach(ca->parent);
|
|
410
|
-
ca->ptr =
|
|
509
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
411
510
|
}
|
|
412
511
|
|
|
413
512
|
static void
|
|
@@ -415,7 +514,7 @@ ca_roll_func_attach (void *ap)
|
|
|
415
514
|
{
|
|
416
515
|
CARoll *ca = (CARoll *) ap;
|
|
417
516
|
ca_attach(ca->parent);
|
|
418
|
-
ca->ptr =
|
|
517
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
419
518
|
ca_roll_iterate_regions(ca, ca->ptr, 0);
|
|
420
519
|
}
|
|
421
520
|
|
|
@@ -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,14 @@ 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);
|
|
662
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
562
663
|
return self;
|
|
563
664
|
}
|
|
564
665
|
|
|
666
|
+
#ifdef CARRAY_DEV_BUILD
|
|
565
667
|
/* Debug-only accessor returning the roll descriptor as a Hash
|
|
566
668
|
(`shifts`, `n_regions`, `ndim`). Not part of the public surface. */
|
|
567
669
|
static VALUE
|
|
@@ -583,6 +685,7 @@ rb_ca_roll_descriptor (VALUE self)
|
|
|
583
685
|
rb_hash_aset(hash, ID2SYM(rb_intern("ndim")), INT2NUM(ca->ndim));
|
|
584
686
|
return hash;
|
|
585
687
|
}
|
|
688
|
+
#endif
|
|
586
689
|
|
|
587
690
|
void
|
|
588
691
|
Init_ca_obj_roll (void)
|
|
@@ -618,7 +721,9 @@ Init_ca_obj_roll (void)
|
|
|
618
721
|
rb_define_method(rb_cCARoll, "initialize_copy",
|
|
619
722
|
rb_ca_roll_initialize_copy, 1);
|
|
620
723
|
|
|
724
|
+
#ifdef CARRAY_DEV_BUILD
|
|
621
725
|
/* Debug accessor, not part of the public surface. */
|
|
622
726
|
rb_define_method(rb_cCARoll, "_roll_descriptor",
|
|
623
727
|
rb_ca_roll_descriptor, 0);
|
|
728
|
+
#endif
|
|
624
729
|
}
|
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) ) {
|
|
@@ -159,15 +162,19 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *snapshot)
|
|
|
159
162
|
if ( s[i] ) count++;
|
|
160
163
|
}
|
|
161
164
|
ca->elements = count;
|
|
162
|
-
/*
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
165
|
+
/* One slot more than count: the loop below writes every position
|
|
166
|
+
and advances only on TRUE, so a run of FALSE after the last TRUE
|
|
167
|
+
writes slot `count`. Writing without a branch keeps a selector
|
|
168
|
+
with TRUE and FALSE mixed at random from mispredicting on most
|
|
169
|
+
cells. The extra slot also keeps count == 0 from malloc(0). */
|
|
170
|
+
ca->indices = (ca_size_t *) xmalloc(sizeof(ca_size_t) * (count + 1));
|
|
167
171
|
{
|
|
168
|
-
ca_size_t
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
ca_size_t *ix = ca->indices;
|
|
173
|
+
ca_size_t n = ca->select->elements;
|
|
174
|
+
ca_size_t j = 0;
|
|
175
|
+
for (i = 0; i < n; i++) {
|
|
176
|
+
ix[j] = i;
|
|
177
|
+
j += ( s[i] != 0 );
|
|
171
178
|
}
|
|
172
179
|
}
|
|
173
180
|
/* Constant-step detection: promotes to STRIDE descriptor kind
|
|
@@ -208,6 +215,7 @@ CArray *
|
|
|
208
215
|
ca_select_new (CArray *parent, CArray *select)
|
|
209
216
|
{
|
|
210
217
|
CArray *snapshot = ca_select_snapshot(select);
|
|
218
|
+
/* check: the setup checks nothing */
|
|
211
219
|
CASelect *ca = ALLOC(CASelect);
|
|
212
220
|
ca_select_setup(ca, parent, snapshot);
|
|
213
221
|
return (CArray*) ca;
|
|
@@ -352,6 +360,7 @@ static void
|
|
|
352
360
|
ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
353
361
|
ca_size_t *strides, void *data, int dir)
|
|
354
362
|
{
|
|
363
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
355
364
|
CASelect *ca = (CASelect *) ap;
|
|
356
365
|
CArray *parent = ca->parent;
|
|
357
366
|
ca_size_t n = counts[0];
|
|
@@ -414,24 +423,34 @@ ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
414
423
|
}
|
|
415
424
|
}
|
|
416
425
|
|
|
426
|
+
/* A parent with no memory to lend (ca_parent_lends_no_memory) is never
|
|
427
|
+
attached: the view owns its buffer, filled and drained through xfer_all,
|
|
428
|
+
which asks the parent for the selected cells only. The predicate asks
|
|
429
|
+
what the parent is, not whether it is attached now, so attach, sync and
|
|
430
|
+
detach all take the same branch. */
|
|
431
|
+
|
|
417
432
|
static void
|
|
418
433
|
ca_select_func_allocate (void *ap)
|
|
419
434
|
{
|
|
420
435
|
CASelect *ca = (CASelect *) ap;
|
|
421
|
-
|
|
422
|
-
|
|
436
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
437
|
+
ca_attach(ca->parent);
|
|
438
|
+
}
|
|
439
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
423
440
|
}
|
|
424
441
|
|
|
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
442
|
static void
|
|
430
443
|
ca_select_func_attach (void *ap)
|
|
431
444
|
{
|
|
432
445
|
CASelect *ca = (CASelect *) ap;
|
|
433
446
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
434
447
|
ca_size_t pdims[CA_RANK_MAX];
|
|
448
|
+
|
|
449
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
450
|
+
ca_axis_view_attach_owned(ca);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
435
454
|
ca_attach(ca->parent);
|
|
436
455
|
ca_select_describe_axes(ca, desc, pdims);
|
|
437
456
|
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
@@ -444,6 +463,12 @@ ca_select_func_sync (void *ap)
|
|
|
444
463
|
CASelect *ca = (CASelect *) ap;
|
|
445
464
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
446
465
|
ca_size_t pdims[CA_RANK_MAX];
|
|
466
|
+
|
|
467
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
468
|
+
ca_axis_view_sync_owned(ca);
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
447
472
|
ca_select_describe_axes(ca, desc, pdims);
|
|
448
473
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
449
474
|
ca->elements, ca->ptr);
|
|
@@ -454,16 +479,20 @@ static void
|
|
|
454
479
|
ca_select_func_detach (void *ap)
|
|
455
480
|
{
|
|
456
481
|
CASelect *ca = (CASelect *) ap;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
482
|
+
if ( ca->ptr ) {
|
|
483
|
+
xfree(ca->ptr);
|
|
484
|
+
ca->ptr = NULL;
|
|
485
|
+
}
|
|
486
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
487
|
+
ca_detach(ca->parent);
|
|
488
|
+
}
|
|
460
489
|
}
|
|
461
490
|
|
|
462
|
-
/*
|
|
463
|
-
cold-parent 2-pass scratch branch below. */
|
|
491
|
+
/* The transfer against parent->ptr, for ca_axis_view_xfer_all. */
|
|
464
492
|
static void
|
|
465
|
-
ca_select_func_run_fast_path (
|
|
493
|
+
ca_select_func_run_fast_path (void *ap, char *data, int dir)
|
|
466
494
|
{
|
|
495
|
+
CASelect *ca = (CASelect *) ap;
|
|
467
496
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
468
497
|
ca_size_t pdims[CA_RANK_MAX];
|
|
469
498
|
ca_select_describe_axes(ca, desc, pdims);
|
|
@@ -476,33 +505,10 @@ ca_select_func_run_fast_path (CASelect *ca, char *data, int dir)
|
|
|
476
505
|
}
|
|
477
506
|
}
|
|
478
507
|
|
|
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
508
|
static void
|
|
484
509
|
ca_select_func_xfer_all (void *ap, void *data, int dir)
|
|
485
510
|
{
|
|
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
|
-
}
|
|
511
|
+
ca_axis_view_xfer_all(ap, ca_select_func_run_fast_path, 1, data, dir);
|
|
506
512
|
}
|
|
507
513
|
|
|
508
514
|
static void
|
|
@@ -531,18 +537,14 @@ ca_select_func_fill_data (void *ap, void *ptr)
|
|
|
531
537
|
ca_select_describe_axes(ca, desc, pdims);
|
|
532
538
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
533
539
|
ca->elements, ptr);
|
|
534
|
-
|
|
535
|
-
ca_detach(ca->parent);
|
|
540
|
+
ca_sync_detach(ca->parent);
|
|
536
541
|
}
|
|
537
542
|
|
|
538
543
|
static void
|
|
539
544
|
ca_select_func_create_mask (void *ap)
|
|
540
545
|
{
|
|
541
546
|
CASelect *ca = (CASelect *) ap;
|
|
542
|
-
|
|
543
|
-
if ( ! ca->parent->mask ) {
|
|
544
|
-
ca_create_mask(ca->parent);
|
|
545
|
-
}
|
|
547
|
+
ca_create_mask(ca->parent);
|
|
546
548
|
ca->mask = (CArray *) ca_select_new_share(ca->parent->mask, ca->select);
|
|
547
549
|
}
|
|
548
550
|
|
|
@@ -624,6 +626,7 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
|
|
|
624
626
|
CASelect *ca, *cs;
|
|
625
627
|
|
|
626
628
|
TypedData_Get_Struct(self, CASelect, &caselect_data_type, ca);
|
|
629
|
+
ca_check_uninitialized(ca);
|
|
627
630
|
TypedData_Get_Struct(other, CASelect, &caselect_data_type, cs);
|
|
628
631
|
|
|
629
632
|
/* Re-snapshot from the source's selector copy so the two views
|