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_array.c
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
---------------------------------------------------------------------------- */
|
|
10
10
|
|
|
11
11
|
#include "carray.h"
|
|
12
|
+
#include "carray_internal.h"
|
|
12
13
|
|
|
13
14
|
/* -------------------------------------------------------------------- */
|
|
14
15
|
|
|
@@ -60,7 +61,10 @@ const rb_data_type_t carray_data_type = {
|
|
|
60
61
|
.dsize = ca_dsize,
|
|
61
62
|
.dcompact = NULL
|
|
62
63
|
},
|
|
63
|
-
|
|
64
|
+
/* A frozen entity is shared between Ractors: reading it writes nothing
|
|
65
|
+
to its struct (an entity takes no attach count), so each Ractor makes
|
|
66
|
+
its own views of it. */
|
|
67
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
|
|
64
68
|
};
|
|
65
69
|
|
|
66
70
|
const rb_data_type_t cawrap_data_type = {
|
|
@@ -84,7 +88,10 @@ const rb_data_type_t cscalar_data_type = {
|
|
|
84
88
|
.dsize = ca_dsize,
|
|
85
89
|
.dcompact = NULL
|
|
86
90
|
},
|
|
87
|
-
|
|
91
|
+
/* A frozen entity is shared between Ractors: reading it writes nothing
|
|
92
|
+
to its struct (an entity takes no attach count), so each Ractor makes
|
|
93
|
+
its own views of it. */
|
|
94
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
|
|
88
95
|
};
|
|
89
96
|
|
|
90
97
|
const rb_data_type_t caview_data_type = {
|
|
@@ -137,31 +144,16 @@ carray_setup_i (CArray *ca,
|
|
|
137
144
|
CArray *mask, int allocate, int use_calloc, char *adopt_ptr)
|
|
138
145
|
{
|
|
139
146
|
ca_size_t elements;
|
|
140
|
-
double length;
|
|
141
147
|
int8_t i;
|
|
142
148
|
ca_size_t k;
|
|
143
149
|
|
|
144
150
|
/* check arguments */
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
/* calculate total byte length using double to detect overflow */
|
|
151
|
-
length = bytes;
|
|
152
|
-
for (i=0; i<ndim; i++) {
|
|
153
|
-
length *= dim[i];
|
|
154
|
-
}
|
|
151
|
+
CA_CHECK_DATA_TYPE_GIVEN(data_type);
|
|
152
|
+
CA_CHECK_RANK_GIVEN(ndim);
|
|
153
|
+
CA_CHECK_DIM_GIVEN(ndim, dim);
|
|
154
|
+
CA_CHECK_BYTES_GIVEN(data_type, bytes);
|
|
155
155
|
|
|
156
|
-
|
|
157
|
-
rb_raise(rb_eRuntimeError, "too large byte length");
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/* calculate total number of elements (safe after length check above) */
|
|
161
|
-
elements = 1;
|
|
162
|
-
for (i=0; i<ndim; i++) {
|
|
163
|
-
elements *= dim[i];
|
|
164
|
-
}
|
|
156
|
+
elements = ca_shape_elements(ndim, dim, bytes);
|
|
165
157
|
|
|
166
158
|
/* An adopted buffer produces an owning entity (CA_OBJ_ARRAY), not a
|
|
167
159
|
wrap: free_carray xfree()s ca->ptr, so the caller's buffer must be
|
|
@@ -173,6 +165,12 @@ carray_setup_i (CArray *ca,
|
|
|
173
165
|
"cannot adopt a raw buffer as a CA_OBJECT array");
|
|
174
166
|
}
|
|
175
167
|
|
|
168
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
169
|
+
run them before it allocates. */
|
|
170
|
+
if ( ca == NULL ) {
|
|
171
|
+
return 0;
|
|
172
|
+
}
|
|
173
|
+
|
|
176
174
|
/* set values to the struct members */
|
|
177
175
|
if ( allocate || adopt_ptr ) {
|
|
178
176
|
ca->obj_type = CA_OBJ_ARRAY;
|
|
@@ -198,16 +196,14 @@ carray_setup_i (CArray *ca,
|
|
|
198
196
|
|
|
199
197
|
/* allocate memory for entity */
|
|
200
198
|
if ( use_calloc ) {
|
|
201
|
-
|
|
202
|
-
ca->ptr = xmalloc(elements * bytes);
|
|
199
|
+
ca->ptr = xmalloc(elements * bytes); /* cells: set to 0 below */
|
|
203
200
|
MEMZERO(ca->ptr, char, elements * bytes);
|
|
204
201
|
}
|
|
205
202
|
else {
|
|
206
|
-
|
|
207
|
-
ca->ptr = xmalloc(elements * bytes);
|
|
203
|
+
ca->ptr = xmalloc(elements * bytes); /* cells: set to 0 below */
|
|
208
204
|
}
|
|
209
205
|
|
|
210
|
-
/*
|
|
206
|
+
/* an object array starts with every cell 0 */
|
|
211
207
|
if ( allocate && data_type == CA_OBJECT ) {
|
|
212
208
|
volatile VALUE zero = SIZE2NUM(0);
|
|
213
209
|
VALUE *p = (VALUE *) ca->ptr;
|
|
@@ -223,6 +219,7 @@ carray_setup_i (CArray *ca,
|
|
|
223
219
|
|
|
224
220
|
ca->mask = NULL;
|
|
225
221
|
if ( mask ) {
|
|
222
|
+
/* mask: only initialize_copy passes one, on a struct Ruby owns */
|
|
226
223
|
ca_setup_mask(ca, mask);
|
|
227
224
|
}
|
|
228
225
|
|
|
@@ -251,9 +248,12 @@ ca_wrap_setup (CArray *ca,
|
|
|
251
248
|
int ret;
|
|
252
249
|
|
|
253
250
|
ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
|
|
254
|
-
if ( (!ptr) && (
|
|
251
|
+
if ( (!ptr) && ca_shape_elements(ndim, dim, bytes) != 0 ) {
|
|
255
252
|
rb_raise(rb_eRuntimeError, "wrapping NULL pointer with an non-empty array");
|
|
256
253
|
}
|
|
254
|
+
if ( ca == NULL ) { /* checks only */
|
|
255
|
+
return ret;
|
|
256
|
+
}
|
|
257
257
|
ca->ptr = ptr;
|
|
258
258
|
return ret;
|
|
259
259
|
}
|
|
@@ -266,26 +266,55 @@ ca_wrap_setup_null (CArray *ca,
|
|
|
266
266
|
int ret;
|
|
267
267
|
|
|
268
268
|
ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
|
|
269
|
-
ca
|
|
269
|
+
if ( ca != NULL ) {
|
|
270
|
+
ca->ptr = NULL;
|
|
271
|
+
}
|
|
270
272
|
return ret;
|
|
271
273
|
}
|
|
272
274
|
|
|
275
|
+
static VALUE
|
|
276
|
+
carray_new_copy_mask (VALUE arg)
|
|
277
|
+
{
|
|
278
|
+
void **a = (void **) arg;
|
|
279
|
+
ca_setup_mask((CArray *) a[0], (CArray *) a[1]);
|
|
280
|
+
return Qnil;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/* Reading the mask to copy can call Ruby (a CAObject's mask hooks) and
|
|
284
|
+
raise, while the new array belongs to no Ruby object yet. The array is
|
|
285
|
+
built without it, and the mask is copied in under ca_fill_or_free. */
|
|
286
|
+
static CArray *
|
|
287
|
+
carray_new_with_mask (CArray *ca, CArray *mask)
|
|
288
|
+
{
|
|
289
|
+
if ( mask ) {
|
|
290
|
+
void *a[2];
|
|
291
|
+
a[0] = ca;
|
|
292
|
+
a[1] = mask;
|
|
293
|
+
ca_fill_or_free(ca, carray_new_copy_mask, (VALUE) a);
|
|
294
|
+
}
|
|
295
|
+
return ca;
|
|
296
|
+
}
|
|
297
|
+
|
|
273
298
|
CArray *
|
|
274
299
|
carray_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
|
|
275
300
|
CArray *mask)
|
|
276
301
|
{
|
|
277
|
-
CArray *ca
|
|
278
|
-
carray_setup(
|
|
279
|
-
|
|
302
|
+
CArray *ca;
|
|
303
|
+
carray_setup(NULL, data_type, ndim, dim, bytes, NULL);
|
|
304
|
+
ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
|
|
305
|
+
carray_setup(ca, data_type, ndim, dim, bytes, NULL);
|
|
306
|
+
return carray_new_with_mask(ca, mask);
|
|
280
307
|
}
|
|
281
308
|
|
|
282
309
|
CArray *
|
|
283
310
|
carray_new_safe (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
|
|
284
311
|
CArray *mask)
|
|
285
312
|
{
|
|
286
|
-
CArray *ca
|
|
287
|
-
carray_safe_setup(
|
|
288
|
-
|
|
313
|
+
CArray *ca;
|
|
314
|
+
carray_safe_setup(NULL, data_type, ndim, dim, bytes, NULL);
|
|
315
|
+
ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
|
|
316
|
+
carray_safe_setup(ca, data_type, ndim, dim, bytes, NULL);
|
|
317
|
+
return carray_new_with_mask(ca, mask);
|
|
289
318
|
}
|
|
290
319
|
|
|
291
320
|
/* Create an entity that adopts a caller-provided data buffer instead of
|
|
@@ -301,6 +330,7 @@ carray_new_adopt (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes
|
|
|
301
330
|
if ( ! ptr ) {
|
|
302
331
|
rb_raise(rb_eRuntimeError, "carray_new_adopt: NULL data pointer");
|
|
303
332
|
}
|
|
333
|
+
carray_setup_i(NULL, data_type, ndim, dim, bytes, NULL, 0, 0, ptr);
|
|
304
334
|
ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
|
|
305
335
|
carray_setup_i(ca, data_type, ndim, dim, bytes, NULL, 0, 0, ptr);
|
|
306
336
|
return ca;
|
|
@@ -310,18 +340,22 @@ CAWrap *
|
|
|
310
340
|
ca_wrap_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
|
|
311
341
|
CArray *mask, char *ptr)
|
|
312
342
|
{
|
|
313
|
-
CAWrap *ca
|
|
314
|
-
ca_wrap_setup(
|
|
315
|
-
|
|
343
|
+
CAWrap *ca;
|
|
344
|
+
ca_wrap_setup(NULL, data_type, ndim, dim, bytes, NULL, ptr);
|
|
345
|
+
ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
|
|
346
|
+
ca_wrap_setup(ca, data_type, ndim, dim, bytes, NULL, ptr);
|
|
347
|
+
return (CAWrap *) carray_new_with_mask((CArray *) ca, mask);
|
|
316
348
|
}
|
|
317
349
|
|
|
318
350
|
CAWrap *
|
|
319
351
|
ca_wrap_new_null (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
|
|
320
352
|
CArray *mask)
|
|
321
353
|
{
|
|
322
|
-
CAWrap *ca
|
|
323
|
-
ca_wrap_setup_null(
|
|
324
|
-
|
|
354
|
+
CAWrap *ca;
|
|
355
|
+
ca_wrap_setup_null(NULL, data_type, ndim, dim, bytes, NULL);
|
|
356
|
+
ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
|
|
357
|
+
ca_wrap_setup_null(ca, data_type, ndim, dim, bytes, NULL);
|
|
358
|
+
return (CAWrap *) carray_new_with_mask((CArray *) ca, mask);
|
|
325
359
|
}
|
|
326
360
|
|
|
327
361
|
void
|
|
@@ -364,8 +398,14 @@ static int
|
|
|
364
398
|
cscalar_setup (CScalar *ca,
|
|
365
399
|
int8_t data_type, ca_size_t bytes, CArray *mask)
|
|
366
400
|
{
|
|
367
|
-
|
|
368
|
-
|
|
401
|
+
CA_CHECK_DATA_TYPE_GIVEN(data_type);
|
|
402
|
+
CA_CHECK_BYTES_GIVEN(data_type, bytes);
|
|
403
|
+
|
|
404
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
405
|
+
run them before it allocates. */
|
|
406
|
+
if ( ca == NULL ) {
|
|
407
|
+
return 0;
|
|
408
|
+
}
|
|
369
409
|
|
|
370
410
|
ca->obj_type = CA_OBJ_SCALAR;
|
|
371
411
|
ca->data_type = data_type;
|
|
@@ -374,7 +414,7 @@ cscalar_setup (CScalar *ca,
|
|
|
374
414
|
ca->bytes = bytes;
|
|
375
415
|
ca->elements = 1;
|
|
376
416
|
ca->dim = &(ca->_dim);
|
|
377
|
-
ca->ptr = xmalloc(bytes);
|
|
417
|
+
ca->ptr = xmalloc(bytes); /* cells: the one cell is set to 0 below */
|
|
378
418
|
ca->mask = NULL;
|
|
379
419
|
|
|
380
420
|
ca->dim[0] = 1;
|
|
@@ -387,6 +427,7 @@ cscalar_setup (CScalar *ca,
|
|
|
387
427
|
}
|
|
388
428
|
|
|
389
429
|
if ( mask ) {
|
|
430
|
+
/* mask: the constructors pass none (carray_new_with_mask copies it) */
|
|
390
431
|
ca_setup_mask((CArray *)ca, mask);
|
|
391
432
|
}
|
|
392
433
|
|
|
@@ -402,9 +443,11 @@ cscalar_setup (CScalar *ca,
|
|
|
402
443
|
CScalar *
|
|
403
444
|
cscalar_new (int8_t data_type, ca_size_t bytes, CArray *mask)
|
|
404
445
|
{
|
|
405
|
-
CScalar *ca
|
|
406
|
-
cscalar_setup(
|
|
407
|
-
|
|
446
|
+
CScalar *ca;
|
|
447
|
+
cscalar_setup(NULL, data_type, bytes, NULL);
|
|
448
|
+
ca = ALLOC(CScalar);
|
|
449
|
+
cscalar_setup(ca, data_type, bytes, NULL);
|
|
450
|
+
return (CScalar *) carray_new_with_mask((CArray *) ca, mask);
|
|
408
451
|
}
|
|
409
452
|
|
|
410
453
|
/*
|
|
@@ -414,7 +457,9 @@ cscalar_new (int8_t data_type, ca_size_t bytes, CArray *mask)
|
|
|
414
457
|
CScalar *
|
|
415
458
|
cscalar_new2 (int8_t data_type, ca_size_t bytes, char *val)
|
|
416
459
|
{
|
|
417
|
-
CScalar *ca
|
|
460
|
+
CScalar *ca;
|
|
461
|
+
cscalar_setup(NULL, data_type, bytes, NULL);
|
|
462
|
+
ca = ALLOC(CScalar);
|
|
418
463
|
cscalar_setup(ca, data_type, bytes, NULL);
|
|
419
464
|
memcpy(ca->ptr, val, ca->bytes);
|
|
420
465
|
return ca;
|
|
@@ -583,6 +628,8 @@ ca_fill_stride_buffer (char *dst, ca_size_t bytes, ca_size_t base, int8_t ndim,
|
|
|
583
628
|
ca_size_t inner_count, inner_step;
|
|
584
629
|
int8_t outer_ndim, k;
|
|
585
630
|
|
|
631
|
+
if ( ca_region_is_empty(ndim, counts) ) return;
|
|
632
|
+
|
|
586
633
|
if ( ndim <= 0 ) {
|
|
587
634
|
memcpy(dst + base * bytes, ptr, bytes);
|
|
588
635
|
return;
|
|
@@ -593,6 +640,7 @@ ca_fill_stride_buffer (char *dst, ca_size_t bytes, ca_size_t base, int8_t ndim,
|
|
|
593
640
|
outer_ndim = ndim - 1;
|
|
594
641
|
|
|
595
642
|
for ( k = 0; k < outer_ndim; k++ ) idx[k] = 0;
|
|
643
|
+
/* empty: the function returns on an empty region at its entry */
|
|
596
644
|
while ( 1 ) {
|
|
597
645
|
ca_size_t addr = base;
|
|
598
646
|
char *p;
|
|
@@ -826,7 +874,7 @@ rb_ca_s_allocate (VALUE klass)
|
|
|
826
874
|
}
|
|
827
875
|
|
|
828
876
|
/* Reads the (data_type, dim, bytes: nil) argument list that CArray.new
|
|
829
|
-
and CArray.
|
|
877
|
+
and CArray.empty_of_data_type share. The two differ only in whether the buffer
|
|
830
878
|
is filled, so the rule for reading their arguments -- the optional
|
|
831
879
|
bytes for a fixlen, the refusal of a Class, the guess of the data type,
|
|
832
880
|
the demand that dim be an Array -- is written once here. */
|
|
@@ -857,6 +905,7 @@ ca_scan_construct_args (int argc, VALUE *argv, int8_t *data_type,
|
|
|
857
905
|
rb_ca_guess_type_and_bytes(rtype, rbytes, data_type, bytes);
|
|
858
906
|
|
|
859
907
|
Check_Type(rdim, T_ARRAY);
|
|
908
|
+
CA_CHECK_RANK_GIVEN(RARRAY_LEN(rdim)); /* before dim[] is filled */
|
|
860
909
|
*ndim = RARRAY_LEN(rdim);
|
|
861
910
|
for (i=0; i<*ndim; i++) {
|
|
862
911
|
dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
|
|
@@ -886,6 +935,10 @@ rb_ca_initialize (int argc, VALUE *argv, VALUE self)
|
|
|
886
935
|
ca_scan_construct_args(argc, argv, &data_type, &bytes, &ndim, dim);
|
|
887
936
|
|
|
888
937
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
938
|
+
ca_check_uninitialized(ca);
|
|
939
|
+
/* Checks first: a rejected argument leaves the struct as allocated, so
|
|
940
|
+
it takes no pool and can be initialized again. */
|
|
941
|
+
carray_safe_setup(NULL, data_type, ndim, dim, bytes, NULL);
|
|
889
942
|
if ( ca_func[CA_OBJ_ARRAY].pool_init ) {
|
|
890
943
|
ca_array_pool_alloc(ca, CA_OBJ_ARRAY, ndim);
|
|
891
944
|
}
|
|
@@ -904,18 +957,20 @@ rb_ca_initialize (int argc, VALUE *argv, VALUE self)
|
|
|
904
957
|
with the multi-dimensional subscript yielded as individual
|
|
905
958
|
integer arguments, so |i|, |i,j|, |i,j,k| all work uniformly
|
|
906
959
|
across ranks. Block forms that want the whole subscript as
|
|
907
|
-
an Array should write |*idx|.
|
|
908
|
-
|
|
960
|
+
an Array should write |*idx|.
|
|
961
|
+
An array of no cells calls neither, as Array.new(0) { ... } does
|
|
962
|
+
not. */
|
|
963
|
+
if ( ca->elements == 0 ) {
|
|
964
|
+
;
|
|
965
|
+
}
|
|
966
|
+
else if ( rb_proc_arity(rb_block_proc()) == 0 ) {
|
|
909
967
|
volatile VALUE rval = rb_yield_values2(0, NULL);
|
|
910
968
|
rb_ca_store_all(self, rval);
|
|
911
969
|
}
|
|
912
970
|
else if ( ca->ndim > 0 ) {
|
|
913
971
|
ca_size_t idx[CA_RANK_MAX];
|
|
914
972
|
volatile VALUE ridx = rb_ary_new2(ca->ndim);
|
|
915
|
-
ca_attach(ca);
|
|
916
973
|
rb_ca_index_walk(self, ca, 0, idx, ridx, CA_LOOP_STORE);
|
|
917
|
-
ca_sync(ca);
|
|
918
|
-
ca_detach(ca);
|
|
919
974
|
}
|
|
920
975
|
else {
|
|
921
976
|
/* 0-D safety net (rare from CArray.new path): yield no args. */
|
|
@@ -1109,6 +1164,7 @@ rb_ca_initialize_copy (VALUE self, VALUE other)
|
|
|
1109
1164
|
rb_call_super(1, &other);
|
|
1110
1165
|
|
|
1111
1166
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1167
|
+
ca_check_uninitialized(ca);
|
|
1112
1168
|
TypedData_Get_Struct(other, CArray, &carray_data_type, cs);
|
|
1113
1169
|
|
|
1114
1170
|
ca_update_mask(cs);
|
|
@@ -1117,11 +1173,114 @@ rb_ca_initialize_copy (VALUE self, VALUE other)
|
|
|
1117
1173
|
}
|
|
1118
1174
|
carray_setup(ca, cs->data_type, cs->ndim, cs->dim, cs->bytes, cs->mask);
|
|
1119
1175
|
|
|
1120
|
-
|
|
1176
|
+
if ( cs->ptr ) {
|
|
1177
|
+
memcpy(ca->ptr, cs->ptr, ca_length(cs));
|
|
1178
|
+
}
|
|
1179
|
+
else {
|
|
1180
|
+
/* An entity cold at rest (a CAObject's mask, a source) is read
|
|
1181
|
+
through its slots. */
|
|
1182
|
+
ca_copy_data(cs, ca->ptr);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
return self;
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
/* dup and clone go through here before each class's initialize_copy. A
|
|
1189
|
+
view's copy is another view onto the same parent (Ruby's shallow copy),
|
|
1190
|
+
rebuilt by that class from the parent, so what the original was told
|
|
1191
|
+
about itself -- that it is a value array, read-only, a mask -- has to be
|
|
1192
|
+
carried across here, once for every class. An entity's copy owns new
|
|
1193
|
+
memory, so it is not a value array and its writability is its own, but
|
|
1194
|
+
a copy of a mask is still a mask (its class, CArrayMask, says so) and
|
|
1195
|
+
can no more hold a mask of its own than the original. */
|
|
1196
|
+
static void
|
|
1197
|
+
ca_dup_keep_state (VALUE self, VALUE other)
|
|
1198
|
+
{
|
|
1199
|
+
CArray *ca, *cs;
|
|
1200
|
+
if ( ! rb_obj_is_kind_of(other, rb_cCArray) ) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1204
|
+
TypedData_Get_Struct(other, CArray, &carray_data_type, cs);
|
|
1205
|
+
if ( ca_is_view(cs) ) {
|
|
1206
|
+
ca_keep_chain_flags(ca, cs);
|
|
1207
|
+
}
|
|
1208
|
+
else if ( ca_is_mask_array(cs) ) {
|
|
1209
|
+
ca_set_flag(ca, CA_FLAG_MASK_ARRAY);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1121
1212
|
|
|
1213
|
+
static VALUE
|
|
1214
|
+
rb_ca_initialize_dup (VALUE self, VALUE other)
|
|
1215
|
+
{
|
|
1216
|
+
rb_call_super(1, &other);
|
|
1217
|
+
ca_dup_keep_state(self, other);
|
|
1218
|
+
rb_ca_own_attr(self);
|
|
1122
1219
|
return self;
|
|
1123
1220
|
}
|
|
1124
1221
|
|
|
1222
|
+
/* clone freezes its result without calling #freeze, so the read-only flag
|
|
1223
|
+
that CArray#freeze sets would be missing: the copy refuses writes as
|
|
1224
|
+
frozen but answers read_only? false. Set it here when the result is
|
|
1225
|
+
going to be frozen (freeze: true, or freeze: omitted and the original
|
|
1226
|
+
frozen). */
|
|
1227
|
+
static VALUE
|
|
1228
|
+
rb_ca_initialize_clone (int argc, VALUE *argv, VALUE self)
|
|
1229
|
+
{
|
|
1230
|
+
VALUE orig, opts, vfreeze = Qnil;
|
|
1231
|
+
int will_freeze;
|
|
1232
|
+
|
|
1233
|
+
rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
|
|
1234
|
+
rb_scan_args(argc, argv, "1:", &orig, &opts);
|
|
1235
|
+
ca_dup_keep_state(self, orig);
|
|
1236
|
+
rb_ca_own_attr(self);
|
|
1237
|
+
|
|
1238
|
+
if ( ! NIL_P(opts) ) {
|
|
1239
|
+
vfreeze = rb_hash_lookup2(opts, ID2SYM(rb_intern("freeze")), Qnil);
|
|
1240
|
+
}
|
|
1241
|
+
will_freeze = NIL_P(vfreeze) ? OBJ_FROZEN(orig) : RTEST(vfreeze);
|
|
1242
|
+
if ( will_freeze ) {
|
|
1243
|
+
CArray *ca;
|
|
1244
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
1245
|
+
ca_set_flag(ca, CA_FLAG_READ_ONLY);
|
|
1246
|
+
}
|
|
1247
|
+
return self;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/* A wrap borrows memory it does not own. Object#dup would give the copy
|
|
1251
|
+
the wrap's class over memory the copy owns, so a subclass that names what
|
|
1252
|
+
it borrows (a libvips image's pixels) would name an array that borrows
|
|
1253
|
+
nothing. The copy is a plain CArray, as #copy is: the name goes with
|
|
1254
|
+
what is borrowed. */
|
|
1255
|
+
static VALUE
|
|
1256
|
+
rb_ca_wrap_dup (VALUE self)
|
|
1257
|
+
{
|
|
1258
|
+
return rb_ca_copy(self);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
static VALUE
|
|
1262
|
+
rb_ca_wrap_clone (int argc, VALUE *argv, VALUE self)
|
|
1263
|
+
{
|
|
1264
|
+
VALUE opt = Qnil, rfreeze = Qnil;
|
|
1265
|
+
volatile VALUE obj;
|
|
1266
|
+
rb_scan_args(argc, argv, "0:", &opt);
|
|
1267
|
+
if ( ! NIL_P(opt) ) {
|
|
1268
|
+
/* rb_get_kwargs refuses any key but freeze:, as Kernel#clone does. */
|
|
1269
|
+
ID kw[1];
|
|
1270
|
+
VALUE val[1];
|
|
1271
|
+
kw[0] = rb_intern("freeze");
|
|
1272
|
+
rb_get_kwargs(opt, kw, 0, 1, val);
|
|
1273
|
+
if ( val[0] != Qundef ) {
|
|
1274
|
+
rfreeze = val[0];
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
obj = rb_ca_copy(self);
|
|
1278
|
+
if ( RTEST(rfreeze) || ( NIL_P(rfreeze) && OBJ_FROZEN(self) ) ) {
|
|
1279
|
+
rb_obj_freeze(obj);
|
|
1280
|
+
}
|
|
1281
|
+
return obj;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1125
1284
|
/* @overload wrap (data_type, dim, bytes=0) { target }
|
|
1126
1285
|
|
|
1127
1286
|
[TBD] (Construction)
|
|
@@ -1144,6 +1303,7 @@ rb_ca_s_wrap (int argc, VALUE *argv, VALUE self)
|
|
|
1144
1303
|
rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
|
|
1145
1304
|
|
|
1146
1305
|
Check_Type(rdim, T_ARRAY);
|
|
1306
|
+
CA_CHECK_RANK_GIVEN(RARRAY_LEN(rdim)); /* before dim[] is filled */
|
|
1147
1307
|
ndim = RARRAY_LEN(rdim);
|
|
1148
1308
|
for (i=0; i<ndim; i++) {
|
|
1149
1309
|
dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
|
|
@@ -1212,6 +1372,7 @@ rb_cs_initialize (int argc, VALUE *argv, VALUE self)
|
|
|
1212
1372
|
rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
|
|
1213
1373
|
|
|
1214
1374
|
TypedData_Get_Struct(self, CScalar, &cscalar_data_type, ca);
|
|
1375
|
+
ca_check_uninitialized(ca);
|
|
1215
1376
|
cscalar_setup(ca, data_type, bytes, NULL);
|
|
1216
1377
|
|
|
1217
1378
|
if ( rb_block_given_p() ) {
|
|
@@ -1405,6 +1566,7 @@ rb_cs_initialize_copy (VALUE self, VALUE other)
|
|
|
1405
1566
|
CScalar *ca, *cs;
|
|
1406
1567
|
|
|
1407
1568
|
TypedData_Get_Struct(self, CScalar, &cscalar_data_type, ca);
|
|
1569
|
+
ca_check_uninitialized(ca);
|
|
1408
1570
|
TypedData_Get_Struct(other, CScalar, &cscalar_data_type, cs);
|
|
1409
1571
|
|
|
1410
1572
|
cscalar_setup(ca, cs->data_type, cs->bytes, NULL);
|
|
@@ -1447,6 +1609,7 @@ rb_ca_s_alloc_uninit (VALUE klass, VALUE rtype, VALUE rshape)
|
|
|
1447
1609
|
int8_t i;
|
|
1448
1610
|
rb_ca_guess_type_and_bytes(rtype, Qnil, &data_type, &bytes);
|
|
1449
1611
|
Check_Type(rshape, T_ARRAY);
|
|
1612
|
+
CA_CHECK_RANK_GIVEN(RARRAY_LEN(rshape)); /* before dim[] is filled */
|
|
1450
1613
|
ndim = (int8_t) RARRAY_LEN(rshape);
|
|
1451
1614
|
for (i = 0; i < ndim; i++) dim[i] = NUM2SIZE(rb_ary_entry(rshape, i));
|
|
1452
1615
|
return rb_carray_new(data_type, ndim, dim, bytes, NULL);
|
|
@@ -1490,7 +1653,7 @@ Init_ca_obj_array (void)
|
|
|
1490
1653
|
rb_define_method(rb_cCArray, "initialize", rb_ca_initialize, -1);
|
|
1491
1654
|
rb_define_singleton_method(rb_cCArray, "__alloc_uninit__",
|
|
1492
1655
|
rb_ca_s_alloc_uninit, 2);
|
|
1493
|
-
|
|
1656
|
+
rb_define_private_method(rb_singleton_class(rb_cCArray), "empty_of_data_type", rb_ca_s_empty, -1);
|
|
1494
1657
|
|
|
1495
1658
|
rb_define_singleton_method(rb_cCArray, "fixlen", rb_ca_s_fixlen, -1);
|
|
1496
1659
|
rb_define_singleton_method(rb_cCArray, "boolean", rb_ca_s_boolean, -1);
|
|
@@ -1521,6 +1684,10 @@ Init_ca_obj_array (void)
|
|
|
1521
1684
|
#endif
|
|
1522
1685
|
|
|
1523
1686
|
rb_define_method(rb_cCArray, "initialize_copy", rb_ca_initialize_copy, 1);
|
|
1687
|
+
rb_define_method(rb_cCArray, "initialize_dup", rb_ca_initialize_dup, 1);
|
|
1688
|
+
rb_define_method(rb_cCArray, "initialize_clone", rb_ca_initialize_clone, -1);
|
|
1689
|
+
rb_define_method(rb_cCAWrap, "dup", rb_ca_wrap_dup, 0);
|
|
1690
|
+
rb_define_method(rb_cCAWrap, "clone", rb_ca_wrap_clone, -1);
|
|
1524
1691
|
rb_define_singleton_method(rb_cCArray, "wrap", rb_ca_s_wrap, -1);
|
|
1525
1692
|
|
|
1526
1693
|
/* ------------------------------------------------------------------- */
|