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_grid.c
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
---------------------------------------------------------------------------- */
|
|
15
15
|
|
|
16
16
|
#include "carray.h"
|
|
17
|
+
#include "carray_internal.h" /* ca_attach_window */
|
|
17
18
|
|
|
18
19
|
/* Per-axis tagged kind. Each axis is either STRIDE (start/step/count,
|
|
19
20
|
no allocation) or INDEX (an owned ca_size_t index snapshot). A Range
|
|
@@ -122,53 +123,81 @@ static VALUE rb_cCAGridMask;
|
|
|
122
123
|
|
|
123
124
|
static int8_t CA_OBJ_GRID;
|
|
124
125
|
|
|
125
|
-
/*
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
ca_grid_setup (CAGrid *ca, CArray *parent, int8_t ndim,
|
|
132
|
-
cag_axis_t *protos, int share)
|
|
126
|
+
/* Raises when protos cannot describe a view of parent: an ndim that is
|
|
127
|
+
not parent's, a negative count, a byte length over the limit, or a
|
|
128
|
+
parent index out of range. Nothing is allocated here, so the caller
|
|
129
|
+
runs it before taking memory. */
|
|
130
|
+
static void
|
|
131
|
+
ca_grid_check_protos (CArray *parent, int8_t ndim, const cag_axis_t *protos)
|
|
133
132
|
{
|
|
134
133
|
int8_t k;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
double length;
|
|
138
|
-
ca_size_t *dim0;
|
|
134
|
+
ca_size_t j;
|
|
135
|
+
double length;
|
|
139
136
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
bytes = parent->bytes;
|
|
143
|
-
dim0 = parent->dim;
|
|
144
|
-
|
|
145
|
-
/* parent->ndim should equal ndim (= number of axes provided).
|
|
146
|
-
rb_ca_grid pads with nil when fewer args are given, so by the
|
|
147
|
-
time we get here ndim == parent->ndim. */
|
|
137
|
+
/* rb_ca_grid pads with nil when fewer args are given, so ndim ==
|
|
138
|
+
parent->ndim for every in-tree caller. */
|
|
148
139
|
if ( ndim != parent->ndim ) {
|
|
149
140
|
rb_raise(rb_eArgError,
|
|
150
141
|
"CAGrid: ndim mismatch (%d args vs parent->ndim %d)",
|
|
151
142
|
(int) ndim, (int) parent->ndim);
|
|
152
143
|
}
|
|
153
144
|
|
|
154
|
-
|
|
155
|
-
length = bytes;
|
|
145
|
+
length = parent->bytes;
|
|
156
146
|
for (k = 0; k < ndim; k++) {
|
|
157
147
|
if (protos[k].count < 0) {
|
|
158
|
-
rb_raise(
|
|
148
|
+
rb_raise(rb_eArgError, "negative size for %d-th dimension", k);
|
|
159
149
|
}
|
|
160
|
-
elements *= protos[k].count;
|
|
161
150
|
length *= protos[k].count;
|
|
162
151
|
}
|
|
163
152
|
if (length > CA_LENGTH_MAX) {
|
|
164
|
-
rb_raise(
|
|
153
|
+
rb_raise(rb_eArgError, "too large byte length");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (k = 0; k < ndim; k++) {
|
|
157
|
+
if ( protos[k].count <= 0 ) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (protos[k].kind == CAG_AXIS_STRIDE) {
|
|
161
|
+
ca_size_t first = protos[k].start;
|
|
162
|
+
ca_size_t last = first + (protos[k].count - 1) * protos[k].step;
|
|
163
|
+
CA_CHECK_INDEX(first, parent->dim[k]);
|
|
164
|
+
if (protos[k].count > 1) CA_CHECK_INDEX(last, parent->dim[k]);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
for (j = 0; j < protos[k].count; j++) {
|
|
168
|
+
ca_size_t v = protos[k].indices[j];
|
|
169
|
+
CA_CHECK_INDEX(v, parent->dim[k]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Setup: caller passes ndim + per-axis protos (cag_axis_t) that
|
|
176
|
+
ca_grid_check_protos has accepted. Copies the fields and, for INDEX
|
|
177
|
+
axes, snapshots the indices into an owned buffer. The share path
|
|
178
|
+
(share=1, used only by create_mask) aliases the caller's protos buffer
|
|
179
|
+
instead: the mask grid is owned and freed by the grid whose axes it
|
|
180
|
+
aliases (free_ca_grid skips the xfree under CA_FLAG_SHARE_INDEX). */
|
|
181
|
+
static int
|
|
182
|
+
ca_grid_setup (CAGrid *ca, CArray *parent, int8_t ndim,
|
|
183
|
+
cag_axis_t *protos, int share)
|
|
184
|
+
{
|
|
185
|
+
int8_t k;
|
|
186
|
+
ca_size_t elements;
|
|
187
|
+
|
|
188
|
+
CA_ASSUME(ndim >= 0 && ndim <= CA_RANK_MAX); /* bound loops/allocs over [CA_RANK_MAX] arrays */
|
|
189
|
+
|
|
190
|
+
{
|
|
191
|
+
ca_size_t counts[CA_RANK_MAX];
|
|
192
|
+
for (k = 0; k < ndim; k++) counts[k] = protos[k].count;
|
|
193
|
+
elements = ca_shape_elements(ndim, counts, parent->bytes);
|
|
165
194
|
}
|
|
166
195
|
|
|
167
196
|
ca->obj_type = CA_OBJ_GRID;
|
|
168
|
-
ca->data_type = data_type;
|
|
197
|
+
ca->data_type = parent->data_type;
|
|
169
198
|
ca->flags = 0;
|
|
170
199
|
ca->ndim = ndim;
|
|
171
|
-
ca->bytes = bytes;
|
|
200
|
+
ca->bytes = parent->bytes;
|
|
172
201
|
ca->elements = elements;
|
|
173
202
|
ca->ptr = NULL;
|
|
174
203
|
ca->mask = NULL;
|
|
@@ -196,13 +225,6 @@ ca_grid_setup (CAGrid *ca, CArray *parent, int8_t ndim,
|
|
|
196
225
|
ca->axes[k].start = protos[k].start;
|
|
197
226
|
ca->axes[k].step = protos[k].step;
|
|
198
227
|
ca->axes[k].indices = NULL;
|
|
199
|
-
/* Bounds check: first and last parent index must be in range. */
|
|
200
|
-
if (protos[k].count > 0) {
|
|
201
|
-
ca_size_t first = protos[k].start;
|
|
202
|
-
ca_size_t last = first + (protos[k].count - 1) * protos[k].step;
|
|
203
|
-
CA_CHECK_INDEX(first, dim0[k]);
|
|
204
|
-
if (protos[k].count > 1) CA_CHECK_INDEX(last, dim0[k]);
|
|
205
|
-
}
|
|
206
228
|
} else {
|
|
207
229
|
ca->axes[k].start = 0;
|
|
208
230
|
ca->axes[k].step = 0;
|
|
@@ -211,8 +233,7 @@ ca_grid_setup (CAGrid *ca, CArray *parent, int8_t ndim,
|
|
|
211
233
|
ca_size_t j;
|
|
212
234
|
for (j = 0; j < protos[k].count; j++) {
|
|
213
235
|
ca_size_t v = protos[k].indices[j];
|
|
214
|
-
|
|
215
|
-
ca->axes[k].indices[j] = v;
|
|
236
|
+
ca->axes[k].indices[j] = ( v < 0 ) ? v + parent->dim[k] : v;
|
|
216
237
|
}
|
|
217
238
|
}
|
|
218
239
|
}
|
|
@@ -228,7 +249,9 @@ ca_grid_setup (CAGrid *ca, CArray *parent, int8_t ndim,
|
|
|
228
249
|
CAGrid *
|
|
229
250
|
ca_grid_new (CArray *parent, int8_t ndim, cag_axis_t *protos)
|
|
230
251
|
{
|
|
231
|
-
CAGrid *ca
|
|
252
|
+
CAGrid *ca;
|
|
253
|
+
ca_grid_check_protos(parent, ndim, protos);
|
|
254
|
+
ca = (CAGrid *) ca_array_alloc(CA_OBJ_GRID, ndim);
|
|
232
255
|
ca_grid_setup(ca, parent, ndim, protos, 0);
|
|
233
256
|
return ca;
|
|
234
257
|
}
|
|
@@ -278,7 +301,7 @@ static void *
|
|
|
278
301
|
ca_grid_func_clone (void *ap)
|
|
279
302
|
{
|
|
280
303
|
CAGrid *ca = (CAGrid *) ap;
|
|
281
|
-
return
|
|
304
|
+
return ca_grid_new(ca->parent, ca->ndim, ca->axes);
|
|
282
305
|
}
|
|
283
306
|
|
|
284
307
|
/* Per-axis parent-index lookup. STRIDE = one multiply, INDEX = one
|
|
@@ -451,6 +474,7 @@ static void
|
|
|
451
474
|
ca_grid_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
452
475
|
ca_size_t *strides, void *data, int dir)
|
|
453
476
|
{
|
|
477
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
454
478
|
CAGrid *g = (CAGrid *) ap;
|
|
455
479
|
CArray *parent = g->parent;
|
|
456
480
|
int8_t ndim = g->ndim;
|
|
@@ -624,24 +648,39 @@ ca_grid_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
624
648
|
}
|
|
625
649
|
}
|
|
626
650
|
|
|
651
|
+
/* attach / sync / copy_data / sync_data / fill_data all go through the
|
|
652
|
+
descriptor engine (ca_axis_dispatch.c). This file supplies only
|
|
653
|
+
describe_axes; the engine does the rest.
|
|
654
|
+
|
|
655
|
+
A parent with no memory to lend (ca_parent_lends_no_memory) is never
|
|
656
|
+
attached: attaching it would produce all of its cells to serve the few
|
|
657
|
+
this grid selects. The grid then owns its buffer, filled and drained
|
|
658
|
+
through xfer_all, which asks the parent for the selected cells only.
|
|
659
|
+
The predicate asks what the parent is, not whether it is attached now,
|
|
660
|
+
so attach, sync and detach all take the same branch. */
|
|
661
|
+
|
|
627
662
|
static void
|
|
628
663
|
ca_grid_func_allocate (void *ap)
|
|
629
664
|
{
|
|
630
665
|
CAGrid *ca = (CAGrid *) ap;
|
|
631
|
-
|
|
666
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
667
|
+
ca_attach(ca->parent);
|
|
668
|
+
}
|
|
632
669
|
ca->ptr = xmalloc(ca_length(ca));
|
|
633
670
|
}
|
|
634
671
|
|
|
635
|
-
/* attach / sync / copy_data / sync_data / fill_data all go through the
|
|
636
|
-
descriptor engine (ca_axis_dispatch.c). This file supplies only
|
|
637
|
-
describe_axes; the engine does the rest. */
|
|
638
|
-
|
|
639
672
|
static void
|
|
640
673
|
ca_grid_func_attach (void *ap)
|
|
641
674
|
{
|
|
642
675
|
CAGrid *ca = (CAGrid *) ap;
|
|
643
676
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
644
677
|
ca_size_t pdims[CA_RANK_MAX];
|
|
678
|
+
|
|
679
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
680
|
+
ca_axis_view_attach_owned(ca);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
645
684
|
ca_attach(ca->parent);
|
|
646
685
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
647
686
|
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
@@ -654,6 +693,12 @@ ca_grid_func_sync (void *ap)
|
|
|
654
693
|
CAGrid *ca = (CAGrid *) ap;
|
|
655
694
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
656
695
|
ca_size_t pdims[CA_RANK_MAX];
|
|
696
|
+
|
|
697
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
698
|
+
ca_axis_view_sync_owned(ca);
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
|
|
657
702
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
658
703
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
659
704
|
ca->elements, ca->ptr);
|
|
@@ -666,16 +711,16 @@ ca_grid_func_detach (void *ap)
|
|
|
666
711
|
CAGrid *ca = (CAGrid *) ap;
|
|
667
712
|
xfree(ca->ptr);
|
|
668
713
|
ca->ptr = NULL;
|
|
669
|
-
|
|
714
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
715
|
+
ca_detach(ca->parent);
|
|
716
|
+
}
|
|
670
717
|
}
|
|
671
718
|
|
|
672
|
-
/*
|
|
673
|
-
of the parent. A cold parent uses a proper 2-pass -- materialise the
|
|
674
|
-
parent into scratch via ca_xfer_all, temporarily expose it as
|
|
675
|
-
parent->ptr, run the fast path, then (for PUT) write scratch back. */
|
|
719
|
+
/* The transfer against parent->ptr, for ca_axis_view_xfer_all. */
|
|
676
720
|
static void
|
|
677
|
-
ca_grid_func_run_fast_path (
|
|
721
|
+
ca_grid_func_run_fast_path (void *ap, char *data, int dir)
|
|
678
722
|
{
|
|
723
|
+
CAGrid *ca = (CAGrid *) ap;
|
|
679
724
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
680
725
|
ca_size_t pdims[CA_RANK_MAX];
|
|
681
726
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
@@ -691,27 +736,7 @@ ca_grid_func_run_fast_path (CAGrid *ca, char *data, int dir)
|
|
|
691
736
|
static void
|
|
692
737
|
ca_grid_func_xfer_all (void *ap, void *data, int dir)
|
|
693
738
|
{
|
|
694
|
-
|
|
695
|
-
if ( ca->parent->ptr ) {
|
|
696
|
-
ca_grid_func_run_fast_path(ca, (char *) data, dir);
|
|
697
|
-
return;
|
|
698
|
-
}
|
|
699
|
-
/* Proper 2-pass cold fallback. */
|
|
700
|
-
{
|
|
701
|
-
volatile VALUE holder;
|
|
702
|
-
CArray *parent = ca->parent;
|
|
703
|
-
ca_size_t plen = parent->elements * parent->bytes;
|
|
704
|
-
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
705
|
-
char *parent_ptr_saved = parent->ptr;
|
|
706
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
707
|
-
parent->ptr = parent_scratch;
|
|
708
|
-
ca_grid_func_run_fast_path(ca, (char *) data, dir);
|
|
709
|
-
if ( dir == CA_XFER_PUT ) {
|
|
710
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
711
|
-
}
|
|
712
|
-
parent->ptr = parent_ptr_saved;
|
|
713
|
-
ALLOCV_END(holder);
|
|
714
|
-
}
|
|
739
|
+
ca_axis_view_xfer_all(ap, ca_grid_func_run_fast_path, 1, data, dir);
|
|
715
740
|
}
|
|
716
741
|
|
|
717
742
|
static void
|
|
@@ -734,11 +759,10 @@ ca_grid_func_fill_data (void *ap, void *ptr)
|
|
|
734
759
|
return;
|
|
735
760
|
}
|
|
736
761
|
|
|
737
|
-
ca_attach(ca->parent);
|
|
762
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
738
763
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
739
764
|
ca->elements, ptr);
|
|
740
|
-
|
|
741
|
-
ca_detach(ca->parent);
|
|
765
|
+
ca_sync_detach(ca->parent);
|
|
742
766
|
}
|
|
743
767
|
|
|
744
768
|
static void
|
|
@@ -746,10 +770,7 @@ ca_grid_func_create_mask (void *ap)
|
|
|
746
770
|
{
|
|
747
771
|
CAGrid *ca = (CAGrid *) ap;
|
|
748
772
|
|
|
749
|
-
|
|
750
|
-
if ( ! ca->parent->mask ) {
|
|
751
|
-
ca_create_mask(ca->parent);
|
|
752
|
-
}
|
|
773
|
+
ca_create_mask(ca->parent);
|
|
753
774
|
|
|
754
775
|
ca->mask = (CArray *) ca_grid_new_share(ca->parent->mask,
|
|
755
776
|
ca->ndim, ca->axes);
|
|
@@ -824,6 +845,63 @@ cag_range_to_stride (VALUE range, ca_size_t dim_size,
|
|
|
824
845
|
return 1;
|
|
825
846
|
}
|
|
826
847
|
|
|
848
|
+
/* The INDEX axes of rb_ca_grid, read with their index arrays attached,
|
|
849
|
+
and the view built from them. */
|
|
850
|
+
|
|
851
|
+
typedef struct {
|
|
852
|
+
VALUE self;
|
|
853
|
+
CArray *ca;
|
|
854
|
+
CArray **ci;
|
|
855
|
+
cag_axis_t *protos;
|
|
856
|
+
} ca_grid_build_ctx_t;
|
|
857
|
+
|
|
858
|
+
static VALUE
|
|
859
|
+
ca_grid_build_body (VALUE arg)
|
|
860
|
+
{
|
|
861
|
+
ca_grid_build_ctx_t *c = (ca_grid_build_ctx_t *) arg;
|
|
862
|
+
volatile VALUE holders[CA_RANK_MAX];
|
|
863
|
+
volatile VALUE obj;
|
|
864
|
+
int8_t i;
|
|
865
|
+
|
|
866
|
+
for (i = 0; i < c->ca->ndim; i++) {
|
|
867
|
+
CArray *ci = c->ci[i];
|
|
868
|
+
holders[i] = Qfalse;
|
|
869
|
+
if ( ! ci ) {
|
|
870
|
+
continue;
|
|
871
|
+
}
|
|
872
|
+
c->protos[i].kind = CAG_AXIS_INDEX;
|
|
873
|
+
if ( ca_is_any_masked(ci) ) {
|
|
874
|
+
/* mask-filtered snapshot: skip masked cells. setup copies the
|
|
875
|
+
indices into its own buffer, so the snapshot only has to live
|
|
876
|
+
until ca_grid_new returns. */
|
|
877
|
+
ca_size_t gsize = ci->elements - ca_count_masked(ci);
|
|
878
|
+
ca_size_t *src = (ca_size_t *) ci->ptr;
|
|
879
|
+
boolean8_t *m = (boolean8_t *) ci->mask->ptr;
|
|
880
|
+
ca_size_t *tmp = ALLOCV_N(ca_size_t, holders[i], gsize > 0 ? gsize : 1);
|
|
881
|
+
ca_size_t j, n = 0;
|
|
882
|
+
for (j = 0; j < ci->elements; j++) {
|
|
883
|
+
if ( ! m[j] ) tmp[n++] = src[j];
|
|
884
|
+
}
|
|
885
|
+
c->protos[i].count = gsize;
|
|
886
|
+
c->protos[i].indices = tmp;
|
|
887
|
+
} else {
|
|
888
|
+
c->protos[i].count = ci->elements;
|
|
889
|
+
c->protos[i].indices = (ca_size_t *) ci->ptr;
|
|
890
|
+
}
|
|
891
|
+
c->protos[i].start = 0;
|
|
892
|
+
c->protos[i].step = 0;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
obj = rb_ca_grid_new(c->self, c->ca->ndim, c->protos);
|
|
896
|
+
|
|
897
|
+
for (i = 0; i < c->ca->ndim; i++) {
|
|
898
|
+
if ( c->ci[i] && holders[i] != Qfalse ) {
|
|
899
|
+
ALLOCV_END(holders[i]);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return obj;
|
|
903
|
+
}
|
|
904
|
+
|
|
827
905
|
VALUE
|
|
828
906
|
rb_ca_grid (int argc, VALUE *argv, VALUE self)
|
|
829
907
|
{
|
|
@@ -916,49 +994,30 @@ rb_ca_grid (int argc, VALUE *argv, VALUE self)
|
|
|
916
994
|
}
|
|
917
995
|
}
|
|
918
996
|
else if ( TYPE(rval) == T_ARRAY ) {
|
|
919
|
-
rb_raise(
|
|
997
|
+
rb_raise(rb_eTypeError, "grid: an axis is an Integer, a Range, nil or a CArray of indices (got Array)");
|
|
920
998
|
}
|
|
921
999
|
|
|
922
|
-
/* INDEX axis */
|
|
1000
|
+
/* INDEX axis: converted here, read once the window below opens */
|
|
1001
|
+
ca_check_index_array(rval);
|
|
923
1002
|
ci[i] = ca_wrap_readonly(rval, CA_SIZE);
|
|
924
1003
|
rb_ary_push(list, rval);
|
|
925
|
-
ca_attach(ci[i]);
|
|
926
|
-
|
|
927
|
-
protos[i].kind = CAG_AXIS_INDEX;
|
|
928
|
-
if ( ca_is_any_masked(ci[i]) ) {
|
|
929
|
-
/* mask-filtered snapshot: skip masked cells. We point protos[i]
|
|
930
|
-
.indices at a temp buffer alloc'd here and freed after setup
|
|
931
|
-
copies it (setup snapshots into its own ALLOC). Caller-side
|
|
932
|
-
lifetime: the temp lives until ca_grid_new returns. */
|
|
933
|
-
ca_size_t gsize = ci[i]->elements - ca_count_masked(ci[i]);
|
|
934
|
-
ca_size_t *src = (ca_size_t *) ci[i]->ptr;
|
|
935
|
-
boolean8_t *m = (boolean8_t *) ci[i]->mask->ptr;
|
|
936
|
-
ca_size_t *tmp = ALLOC_N(ca_size_t, gsize > 0 ? gsize : 1);
|
|
937
|
-
ca_size_t j, n = 0;
|
|
938
|
-
for (j = 0; j < ci[i]->elements; j++) {
|
|
939
|
-
if ( ! m[j] ) tmp[n++] = src[j];
|
|
940
|
-
}
|
|
941
|
-
protos[i].count = gsize;
|
|
942
|
-
protos[i].indices = tmp;
|
|
943
|
-
} else {
|
|
944
|
-
protos[i].count = ci[i]->elements;
|
|
945
|
-
protos[i].indices = (ca_size_t *) ci[i]->ptr;
|
|
946
|
-
}
|
|
947
|
-
protos[i].start = 0;
|
|
948
|
-
protos[i].step = 0;
|
|
949
1004
|
}
|
|
950
1005
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
1006
|
+
/* The index arrays are read with all of them attached, and building
|
|
1007
|
+
the view checks every index against the parent -- an index out of
|
|
1008
|
+
range raises there. So the reads and the build are a window body,
|
|
1009
|
+
which detaches the caller's index arrays however it ends. */
|
|
1010
|
+
{
|
|
1011
|
+
ca_grid_build_ctx_t c;
|
|
1012
|
+
char modes[CA_RANK_MAX + 1];
|
|
1013
|
+
memset(modes, 'r', (size_t) ca->ndim);
|
|
1014
|
+
modes[ca->ndim] = '\0';
|
|
1015
|
+
c.self = self;
|
|
1016
|
+
c.ca = ca;
|
|
1017
|
+
c.ci = ci;
|
|
1018
|
+
c.protos = protos;
|
|
1019
|
+
obj = ca_attach_window(ca->ndim, ci, modes, ca_grid_build_body,
|
|
1020
|
+
(VALUE) &c);
|
|
962
1021
|
}
|
|
963
1022
|
|
|
964
1023
|
return obj;
|
|
@@ -977,14 +1036,14 @@ rb_ca_grid_initialize_copy (VALUE self, VALUE other)
|
|
|
977
1036
|
CAGrid *ca, *cs;
|
|
978
1037
|
|
|
979
1038
|
TypedData_Get_Struct(self, CAGrid, &cagrid_data_type, ca);
|
|
1039
|
+
ca_check_uninitialized(ca);
|
|
980
1040
|
TypedData_Get_Struct(other, CAGrid, &cagrid_data_type, cs);
|
|
981
1041
|
|
|
982
1042
|
if ( ca_func[CA_OBJ_GRID].pool_init ) {
|
|
983
1043
|
ca_array_pool_alloc(ca, CA_OBJ_GRID, cs->ndim);
|
|
984
1044
|
}
|
|
985
|
-
/*
|
|
986
|
-
|
|
987
|
-
ca_grid_setup(ca, cs->parent, cs->ndim, cs->axes, 1);
|
|
1045
|
+
/* Copy the axes: the source may be collected before the copy. */
|
|
1046
|
+
ca_grid_setup(ca, cs->parent, cs->ndim, cs->axes, 0);
|
|
988
1047
|
|
|
989
1048
|
return self;
|
|
990
1049
|
}
|
|
@@ -1087,7 +1146,7 @@ rb_ca_grid_dispatch_attach_debug (VALUE self)
|
|
|
1087
1146
|
TypedData_Get_Struct(self, CAGrid, &cagrid_data_type, ca);
|
|
1088
1147
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
1089
1148
|
|
|
1090
|
-
ca_attach(ca->parent);
|
|
1149
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1091
1150
|
buf = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1092
1151
|
ca->elements, NULL);
|
|
1093
1152
|
ca_detach(ca->parent);
|
|
@@ -1118,11 +1177,10 @@ rb_ca_grid_dispatch_scatter_debug (VALUE self, VALUE in_str)
|
|
|
1118
1177
|
ca_size_t pdims[CA_RANK_MAX];
|
|
1119
1178
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
1120
1179
|
|
|
1121
|
-
ca_attach(ca->parent);
|
|
1180
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1122
1181
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1123
1182
|
ca->elements, RSTRING_PTR(in_str));
|
|
1124
|
-
|
|
1125
|
-
ca_detach(ca->parent);
|
|
1183
|
+
ca_sync_detach(ca->parent);
|
|
1126
1184
|
return Qnil;
|
|
1127
1185
|
}
|
|
1128
1186
|
|
|
@@ -1145,11 +1203,10 @@ rb_ca_grid_dispatch_fill_value_debug (VALUE self, VALUE val_str)
|
|
|
1145
1203
|
ca_size_t pdims[CA_RANK_MAX];
|
|
1146
1204
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
1147
1205
|
|
|
1148
|
-
ca_attach(ca->parent);
|
|
1206
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1149
1207
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1150
1208
|
ca->elements, RSTRING_PTR(val_str));
|
|
1151
|
-
|
|
1152
|
-
ca_detach(ca->parent);
|
|
1209
|
+
ca_sync_detach(ca->parent);
|
|
1153
1210
|
return Qnil;
|
|
1154
1211
|
}
|
|
1155
1212
|
#endif /* CARRAY_DEV_BUILD */
|