carray 3.0.3 → 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 +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +78 -10
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- 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/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +11 -4
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +182 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +53 -36
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_internal.h
CHANGED
|
@@ -102,9 +102,56 @@ void ca_gc_hold_pop_to (int depth);
|
|
|
102
102
|
void ca_gc_hold_buffer (void *ptr, ca_size_t n_elements);
|
|
103
103
|
void ca_gc_release_buffer (void *ptr);
|
|
104
104
|
|
|
105
|
+
/* Object cells are marked strictly (rb_gc_mark, which trusts what it is
|
|
106
|
+
given) as soon as anything can see their buffer: a view's ca->ptr from
|
|
107
|
+
the moment it is set (ca_mark), a held buffer from the moment it is held.
|
|
108
|
+
A fresh buffer that will carry object cells is therefore filled with
|
|
109
|
+
valid VALUEs before it is published, whether or not the code that fills
|
|
110
|
+
it can call Ruby. A buffer for an array's cells is allocated with
|
|
111
|
+
ca_alloc_cells; other fresh VALUE buffers are cleared with
|
|
112
|
+
ca_object_cells_clear before they are held. utils/check_cell_buffers.rb
|
|
113
|
+
finds a ptr allocated any other way. */
|
|
114
|
+
static inline void
|
|
115
|
+
ca_object_cells_clear (void *ptr, ca_size_t n_elements)
|
|
116
|
+
{
|
|
117
|
+
VALUE *p = (VALUE *) ptr;
|
|
118
|
+
while ( n_elements-- > 0 ) {
|
|
119
|
+
*p++ = Qnil;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* A boolean cell holds 0 or 1. Bytes copied in from outside (a String or
|
|
124
|
+
an IO through load_binary, a MemoryView) are read as true when non-zero,
|
|
125
|
+
so every reader of the array sees one value; an array that shares
|
|
126
|
+
another's bytes cannot be held to this, and is refused instead. */
|
|
127
|
+
static inline void
|
|
128
|
+
ca_boolean_normalize_bytes (void *ptr, ca_size_t n)
|
|
129
|
+
{
|
|
130
|
+
uint8_t *p = (uint8_t *) ptr;
|
|
131
|
+
for ( ca_size_t i = 0; i < n; i++ ) {
|
|
132
|
+
p[i] = ( p[i] != 0 );
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static inline char *
|
|
137
|
+
ca_alloc_cells (const CArray *ca)
|
|
138
|
+
{
|
|
139
|
+
char *p = (char *) xmalloc(ca_length(ca));
|
|
140
|
+
if ( ca->data_type == CA_OBJECT ) {
|
|
141
|
+
ca_object_cells_clear(p, ca->elements);
|
|
142
|
+
}
|
|
143
|
+
return p;
|
|
144
|
+
}
|
|
145
|
+
|
|
105
146
|
/* Copy the attributes src shows onto dst (a new entity with src's values). */
|
|
106
147
|
void rb_ca_inherit_attr (VALUE dst, VALUE src);
|
|
107
148
|
|
|
149
|
+
/* Give a dup / clone its own attribute Hash. */
|
|
150
|
+
void rb_ca_own_attr (VALUE self);
|
|
151
|
+
|
|
152
|
+
/* Record the Face a lifted view was taken from, for the attribute walk. */
|
|
153
|
+
void rb_ca_set_lifted_from (VALUE lifted, VALUE face);
|
|
154
|
+
|
|
108
155
|
/* A String read as a decimal number of an integer or float data_type
|
|
109
156
|
(carray_cast.c): _to answers 1 / 0 (UNDEF), _store raises. */
|
|
110
157
|
int ca_decimal_string_to (VALUE str, int8_t data_type, void *out);
|
|
@@ -154,6 +201,42 @@ VALUE ca_attach_window (int32_t n, CArray **list, const char *modes,
|
|
|
154
201
|
|
|
155
202
|
void ca_fill_or_free (CArray *co, VALUE (*fill)(VALUE), VALUE arg);
|
|
156
203
|
|
|
204
|
+
/* The same for what else a step that can raise leaves behind: a buffer
|
|
205
|
+
that belongs to nothing yet (freed with xfree), or arrays the caller
|
|
206
|
+
attached for the step (each detached once). A hand-written rb_protect
|
|
207
|
+
outside the files that implement these parts says why it is not one
|
|
208
|
+
of them; utils/check_protect_parts.rb finds one that does not. */
|
|
209
|
+
|
|
210
|
+
void ca_fill_or_xfree (void *buf, VALUE (*fill)(VALUE), VALUE arg);
|
|
211
|
+
void ca_fill_or_detach (int n, CArray **list, VALUE (*fill)(VALUE), VALUE arg);
|
|
212
|
+
|
|
213
|
+
/* A view takes its parent's mask by asking the parent whether it has one,
|
|
214
|
+
and a parent that is a CAObject answers in Ruby and can raise. A view's
|
|
215
|
+
setup therefore does not ask: its constructor calls this under
|
|
216
|
+
ca_fill_or_free once the struct holds everything the setup allocated,
|
|
217
|
+
and an initialize_copy, whose struct Ruby already owns, calls it
|
|
218
|
+
directly. `view` is the CArray * cast to VALUE. */
|
|
219
|
+
|
|
220
|
+
VALUE ca_view_inherit_mask (VALUE view);
|
|
221
|
+
|
|
222
|
+
/* Whether a CAGrid has a hole: a position whose index cell was masked,
|
|
223
|
+
which selects no parent cell. The descriptor engine has no hole, so
|
|
224
|
+
such a grid is delivered through its own transfers. */
|
|
225
|
+
int ca_grid_has_holes (void *ap);
|
|
226
|
+
|
|
227
|
+
/* The same for the mask a CAWindow / CAShift with an axis of MASK bounds
|
|
228
|
+
makes for itself (ca_obj_window.c). */
|
|
229
|
+
|
|
230
|
+
VALUE ca_window_create_bounds_mask (VALUE view);
|
|
231
|
+
|
|
232
|
+
/* ca_stride_setup without asking the parent for its mask; see
|
|
233
|
+
ca_view_inherit_mask. The in-tree subclasses use this. */
|
|
234
|
+
|
|
235
|
+
int ca_stride_setup_view (CAStride *ca, int8_t obj_type, CArray *parent,
|
|
236
|
+
int8_t data_type, ca_size_t bytes,
|
|
237
|
+
int8_t ndim, ca_size_t *dim,
|
|
238
|
+
ca_size_t *strides, ca_size_t base_offset);
|
|
239
|
+
|
|
157
240
|
/* Non-zero iff the object is an element-wise lazy view (CAMonOp / CABinOp /
|
|
158
241
|
CABinCmp / CAMonCmp / CALazyMarker). The streaming branch of the
|
|
159
242
|
mkkernel-generated reduction kernels tests this to decide whether it can
|
|
@@ -312,12 +395,80 @@ VALUE ca_answer_as_caller (VALUE (*body)(VALUE), VALUE arg);
|
|
|
312
395
|
long ca_integer_arg (VALUE v, const char *arg, const char *name);
|
|
313
396
|
ca_size_t ca_shape_elements (int8_t ndim, const ca_size_t *dim, ca_size_t bytes);
|
|
314
397
|
void ca_check_index_array (VALUE v);
|
|
398
|
+
VALUE ca_order_key (VALUE v, const char *name);
|
|
315
399
|
void ca_check_integer_fits (VALUE v, int8_t data_type);
|
|
400
|
+
VALUE ca_obj2integer_fitting (VALUE v, int8_t data_type);
|
|
316
401
|
int ca_integer_range_side (VALUE v, int8_t data_type);
|
|
317
402
|
int ca_bincmp_integer_prepare (volatile VALUE *self, volatile VALUE *other,
|
|
318
403
|
int op_id, int *signed_side);
|
|
319
404
|
int ca_bincmp_answer_when_negative (int op_id, int signed_side);
|
|
320
405
|
long ca_axis_integer (VALUE raxis, const char *name);
|
|
406
|
+
/* Refuse a write into a read-only array that is not frozen (carray_test.c);
|
|
407
|
+
every guard calls this rather than raising its own. */
|
|
408
|
+
NORETURN(void ca_refuse_read_only (void));
|
|
409
|
+
/* Refuse an operator with no kernel for `data_type`, naming the method and
|
|
410
|
+
the type (carray_operator.c); the eager operators and the lazy builders. */
|
|
411
|
+
NORETURN(void ca_op_refuse_unimplemented (VALUE operand, int8_t data_type,
|
|
412
|
+
VALUE eclass));
|
|
413
|
+
/* Refuse a rank above CA_RANK_MAX before any dim is written (carray_utils.c). */
|
|
414
|
+
void ca_check_rank_fits (long ndim, const char *name);
|
|
415
|
+
/* The checks of carray.h inside the library, each naming the method the
|
|
416
|
+
user called; the public ones stay as they are for extensions. */
|
|
417
|
+
#define CA_CHECK_DATA_TYPE_GIVEN(data_type) \
|
|
418
|
+
do { \
|
|
419
|
+
int ca_dt_ = (data_type); \
|
|
420
|
+
if ( ca_dt_ <= CA_NONE || ca_dt_ >= CA_NTYPE ) { \
|
|
421
|
+
rb_raise(rb_eArgError, "%s: invalid data_type id %i", \
|
|
422
|
+
ca_calling_method_name(), ca_dt_); \
|
|
423
|
+
} \
|
|
424
|
+
if ( ! ca_valid[ca_dt_] ) { \
|
|
425
|
+
rb_raise(rb_eCADataTypeError, "%s: data_type %s is disabled", \
|
|
426
|
+
ca_calling_method_name(), ca_type_name[ca_dt_]); \
|
|
427
|
+
} \
|
|
428
|
+
} while (0)
|
|
429
|
+
|
|
430
|
+
#define CA_CHECK_DIM_GIVEN(ndim, dim) \
|
|
431
|
+
do { \
|
|
432
|
+
int8_t i_; \
|
|
433
|
+
for (i_ = 0; i_ < (ndim); i_++) { \
|
|
434
|
+
if ( (dim)[i_] < 0 ) { \
|
|
435
|
+
rb_raise(rb_eArgError, "%s: negative size dimension at %i-dim", \
|
|
436
|
+
ca_calling_method_name(), i_); \
|
|
437
|
+
} \
|
|
438
|
+
} \
|
|
439
|
+
} while (0)
|
|
440
|
+
|
|
441
|
+
#define CA_CHECK_BYTES_GIVEN(data_type, bytes) \
|
|
442
|
+
do { \
|
|
443
|
+
if ( (data_type) == CA_FIXLEN ) { \
|
|
444
|
+
if ( (bytes) <= 0 ) { \
|
|
445
|
+
rb_raise(rb_eArgError, \
|
|
446
|
+
"%s: invalid bytes (a fixlen needs bytes: of 1 or more)", \
|
|
447
|
+
ca_calling_method_name()); \
|
|
448
|
+
} \
|
|
449
|
+
} \
|
|
450
|
+
else { \
|
|
451
|
+
(bytes) = ca_sizeof[(data_type)]; \
|
|
452
|
+
if ( (bytes) <= 0 ) { \
|
|
453
|
+
rb_raise(rb_eArgError, "%s: invalid bytes", ca_calling_method_name()); \
|
|
454
|
+
} \
|
|
455
|
+
} \
|
|
456
|
+
} while (0)
|
|
457
|
+
|
|
458
|
+
/* CA_CHECK_RANK inside the library: no axes at all is no shape, and above
|
|
459
|
+
CA_RANK_MAX goes to the part, which names the method. The public macro
|
|
460
|
+
stays as it is for extensions. */
|
|
461
|
+
#define CA_CHECK_RANK_GIVEN(ndim) \
|
|
462
|
+
do { \
|
|
463
|
+
long ca_nd_ = (long) (ndim); \
|
|
464
|
+
if ( ca_nd_ <= 0 ) { \
|
|
465
|
+
rb_raise(rb_eArgError, "invalid ndim"); \
|
|
466
|
+
} \
|
|
467
|
+
ca_check_rank_fits(ca_nd_, NULL); \
|
|
468
|
+
} while (0)
|
|
469
|
+
/* An `axis` argument as an axis in [0, ndim): the rule every entry taking
|
|
470
|
+
an axis from Ruby calls (carray_utils.c). */
|
|
471
|
+
int ca_normalize_axis_arg (VALUE raxis, int ndim, const char *name);
|
|
321
472
|
VALUE ca_fill_as (VALUE fill, int8_t data_type);
|
|
322
473
|
/* ---- Face MemoryView export (ca_obj_face.c) -------------------------------
|
|
323
474
|
|
|
@@ -328,6 +479,12 @@ VALUE ca_fill_as (VALUE fill, int8_t data_type);
|
|
|
328
479
|
void ca_face_register_memory_view (int obj_type, int exportable);
|
|
329
480
|
int ca_face_memory_view_exportable (CArray *ca);
|
|
330
481
|
|
|
482
|
+
/* The reference and the operand of a comparison brought into one space (see
|
|
483
|
+
ca_obj_face.c). *pref may be replaced by a converted copy and stays a
|
|
484
|
+
Face; the caller strips it. */
|
|
485
|
+
void ca_face_reconcile_pair (volatile VALUE *pref, volatile VALUE *poperand,
|
|
486
|
+
const char *name);
|
|
487
|
+
|
|
331
488
|
/* ---- Empty regions ---------------------------------------------------------
|
|
332
489
|
|
|
333
490
|
A region with a zero count on some axis has no cells. The per-cell walks
|
|
@@ -439,6 +596,28 @@ ca_obj_cmp (VALUE a, VALUE b)
|
|
|
439
596
|
return rb_cmpint(r, a, b);
|
|
440
597
|
}
|
|
441
598
|
|
|
599
|
+
/* The order sort and every order statistic (partition, median,
|
|
600
|
+
percentile, rank, nlargest, the search family) put cells in: a NaN
|
|
601
|
+
after every number, NaN ties NaN. Three-way (-1, 0, 1), ties not
|
|
602
|
+
broken. A descending order keeps NaN after the numbers too, so it
|
|
603
|
+
negates only the comparison of two numbers. ca_partition_nan_*
|
|
604
|
+
(ca_sort_kernels.h) moves the NaN of a float buffer to its tail by
|
|
605
|
+
the same rule; a new order kernel uses these and nothing of its own. */
|
|
606
|
+
#define CA_FLOAT_ORDER_CMP(a, b) \
|
|
607
|
+
( isnan(a) ? ( isnan(b) ? 0 : 1 ) \
|
|
608
|
+
: ( isnan(b) ? -1 : ( ( (a) > (b) ) - ( (a) < (b) ) ) ) )
|
|
609
|
+
|
|
610
|
+
/* The same order for object cells: a Float NaN after every other value,
|
|
611
|
+
other pairs by `<=>` (ca_obj_cmp, which refuses a pair it cannot
|
|
612
|
+
order). */
|
|
613
|
+
static inline int
|
|
614
|
+
ca_obj_order_cmp (VALUE a, VALUE b)
|
|
615
|
+
{
|
|
616
|
+
int nan_a = CA_OBJ_ISNAN(a), nan_b = CA_OBJ_ISNAN(b);
|
|
617
|
+
if ( nan_a || nan_b ) return nan_a - nan_b;
|
|
618
|
+
return ca_obj_cmp(a, b);
|
|
619
|
+
}
|
|
620
|
+
|
|
442
621
|
/* op names the contest: `<` for a minimum, `>` for a maximum. */
|
|
443
622
|
static inline int
|
|
444
623
|
ca_obj_extremum_replaces (VALUE v, VALUE acc, ID op)
|
|
@@ -450,37 +629,75 @@ ca_obj_extremum_replaces (VALUE v, VALUE acc, ID op)
|
|
|
450
629
|
return ( op == rb_intern("<") ) ? ( c < 0 ) : ( c > 0 );
|
|
451
630
|
}
|
|
452
631
|
|
|
632
|
+
/* Mask stand-ins. A view whose mask covers a parent that has no mask
|
|
633
|
+
reads an all-false stand-in there instead of giving the parent one:
|
|
634
|
+
asking about the mask, or writing nothing but false into it, gives the
|
|
635
|
+
parent no mask. The stand-in gives way to the parent's own mask once
|
|
636
|
+
the parent has one, or once a true has been written into it. A grid
|
|
637
|
+
with holes, a window or shift that masks its out-of-range cells, and a
|
|
638
|
+
stack or meld with parts that have no mask read their masks this way;
|
|
639
|
+
a new view that does should use these three and nothing of its own.
|
|
640
|
+
|
|
641
|
+
Every entry into the cells of such a mask (each transfer, fill, attach
|
|
642
|
+
and allocate slot, and any walk that reads its parents directly) first
|
|
643
|
+
asks ca_mask_standin_current what to read; every write that may have
|
|
644
|
+
put a true into the stand-in ends with ca_mask_standin_settle. */
|
|
645
|
+
|
|
646
|
+
/* A new stand-in for `parent`: all false, read-only when the parent is. */
|
|
647
|
+
CArray *ca_mask_standin_new (CArray *parent);
|
|
648
|
+
|
|
649
|
+
/* What `mask_view`, now reading `reading` in place of `parent`'s mask,
|
|
650
|
+
should read: the parent's own mask once the parent has one, otherwise
|
|
651
|
+
`reading` unchanged. Also unchanged while mask_view is attached with
|
|
652
|
+
its buffer out. */
|
|
653
|
+
CArray *ca_mask_standin_current (CArray *mask_view, CArray *reading,
|
|
654
|
+
CArray *parent, CArray *standin);
|
|
655
|
+
|
|
656
|
+
/* After a write into `standin`: add any true it now holds to the parent's
|
|
657
|
+
mask (made for it) and clear the stand-in. A parent that can never
|
|
658
|
+
have a mask (a value array, a mask array) refuses a true with
|
|
659
|
+
TypeError, the stand-in cleared. Nothing for a read-only stand-in. */
|
|
660
|
+
void ca_mask_standin_settle (CArray *parent, CArray *standin);
|
|
661
|
+
|
|
662
|
+
/* Whether any of n boolean cells at data is true: whether a write of
|
|
663
|
+
them can have put a true into a stand-in. */
|
|
664
|
+
static inline int
|
|
665
|
+
ca_mask_any_true (const void *data, ca_size_t n)
|
|
666
|
+
{
|
|
667
|
+
const boolean8_t *b = (const boolean8_t *) data;
|
|
668
|
+
ca_size_t i;
|
|
669
|
+
for ( i = 0; i < n; i++ ) {
|
|
670
|
+
if ( b[i] ) return 1;
|
|
671
|
+
}
|
|
672
|
+
return 0;
|
|
673
|
+
}
|
|
674
|
+
|
|
453
675
|
/* The mask a multi-parent view (CAStack, CAMeld) composes for parent `p`:
|
|
454
|
-
p's own mask when it has one
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
array or a mask array, which can never carry a mask, stays in place and
|
|
459
|
-
takes writes; writing false into it changes nothing, and a true written
|
|
460
|
-
into it is refused by ca_multi_parent_mask_check. */
|
|
676
|
+
p's own mask when it has one, otherwise a stand-in
|
|
677
|
+
(ca_mask_standin_new) stored in *standin for the view to free. The
|
|
678
|
+
stand-in of a value array or a mask array, which can never carry a
|
|
679
|
+
mask, stays in place for good. */
|
|
461
680
|
CArray *ca_multi_parent_mask (CArray *p, CArray **standin);
|
|
462
681
|
|
|
463
|
-
/*
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
is replaced when its parent has gained a mask, or, with for_write, by a
|
|
467
|
-
mask created on the parent. The mask's own transfer functions call this
|
|
468
|
-
on entry; it does nothing inside an attach window. */
|
|
682
|
+
/* ca_mask_standin_current for each part of a multi-parent view's mask.
|
|
683
|
+
`mask` is the view's mask (a CAStack or CAMeld over the parents'
|
|
684
|
+
masks), `parents` / `standins` the view's. */
|
|
469
685
|
void ca_multi_parent_mask_refresh (CArray *mask, CArray **parents,
|
|
470
|
-
CArray **standins, int32_t n
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
686
|
+
CArray **standins, int32_t n);
|
|
687
|
+
|
|
688
|
+
/* Before a write to a multi-parent view's mask: when a parent that can
|
|
689
|
+
never carry a mask (a value array, a mask array) is among the parents,
|
|
690
|
+
run the write `body(arg)` once against blank all-false masks in place of
|
|
691
|
+
every parent's mask and refuse it with that TypeError if it put a true
|
|
692
|
+
into such a parent's part. A refused write then changes no parent.
|
|
693
|
+
Does nothing when no such parent is there. */
|
|
694
|
+
void ca_multi_parent_mask_refuse_first (CArray *mask, CArray **parents,
|
|
695
|
+
CArray **standins, int32_t n,
|
|
696
|
+
VALUE (*body)(VALUE),
|
|
697
|
+
VALUE arg);
|
|
698
|
+
|
|
699
|
+
/* ca_mask_standin_settle for each part of a multi-parent view's mask
|
|
700
|
+
still reading its stand-in, the parts that can have no mask first. */
|
|
484
701
|
void ca_multi_parent_mask_settle (CArray *mask, CArray **parents,
|
|
485
702
|
CArray **standins, int32_t n);
|
|
486
703
|
|
|
@@ -492,6 +709,43 @@ void ca_multi_parent_mask_settle (CArray *mask, CArray **parents,
|
|
|
492
709
|
int8_t ca_promote_scalar_type (int8_t at, VALUE obj, int8_t st);
|
|
493
710
|
int8_t ca_value_match_type (int8_t t, int8_t a, int8_t b);
|
|
494
711
|
|
|
712
|
+
/* Whether a kernel can raise on a cell of type `dt`, so that a masked cell
|
|
713
|
+
must be skipped rather than computed: any op on an object cell (it calls
|
|
714
|
+
Ruby), an integer division, remainder or reciprocal by zero, and an
|
|
715
|
+
integer power of zero to a negative exponent. The eager operators and
|
|
716
|
+
the lazy views (and the plans CArray::Fusion hands an evaluator) ask
|
|
717
|
+
this alone. `op_id` is the kind's op number, or -1 when not known. */
|
|
718
|
+
enum { CA_OP_KIND_MONOP, CA_OP_KIND_BINOP, CA_OP_KIND_TRIOP,
|
|
719
|
+
CA_OP_KIND_MONCMP, CA_OP_KIND_BINCMP };
|
|
720
|
+
int ca_op_raises_on_cell (int kind, int op_id, int8_t dt);
|
|
721
|
+
|
|
722
|
+
/* The type a value query (a Ruby value or a CArray) and a reference of
|
|
723
|
+
type `ref` are compared in, as `eq` compares them: count(v) and the
|
|
724
|
+
search family read the reference through a view of that type. An
|
|
725
|
+
Integer that does not fit `ref` takes the type its value needs, where it
|
|
726
|
+
matches nothing. count(v) and the search family ask it for a numeric
|
|
727
|
+
reference (ca_query_match_applies): a Face query is answered by the Face
|
|
728
|
+
gate first, and a string reference compares in its own type, padding
|
|
729
|
+
included. */
|
|
730
|
+
int8_t ca_query_match_type (int8_t ref, VALUE query);
|
|
731
|
+
|
|
732
|
+
static inline int
|
|
733
|
+
ca_query_match_applies (CArray *ref, VALUE query)
|
|
734
|
+
{
|
|
735
|
+
if ( ! ( ca_is_integer_type(ref) || ca_is_float_type(ref)
|
|
736
|
+
|| ref->data_type == CA_BOOLEAN ) ) {
|
|
737
|
+
return 0;
|
|
738
|
+
}
|
|
739
|
+
if ( rb_obj_is_carray(query) ) {
|
|
740
|
+
CArray *q;
|
|
741
|
+
TypedData_Get_Struct(query, CArray, &carray_data_type, q);
|
|
742
|
+
if ( ca_is_face(q) ) {
|
|
743
|
+
return 0;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return 1;
|
|
747
|
+
}
|
|
748
|
+
|
|
495
749
|
/* Equality of two object cells, as the float lanes answer it: Ruby's `==`,
|
|
496
750
|
except that a Float NaN equals nothing, itself included. rb_equal alone
|
|
497
751
|
answers true for the same object, so whether two NaN cells matched would
|
|
@@ -517,13 +771,25 @@ ca_obj_equal (VALUE a, VALUE b)
|
|
|
517
771
|
A branch that only lends a pointer, or drops to memcpy when the data is
|
|
518
772
|
contiguous, runs the same code either way and does not test this.
|
|
519
773
|
|
|
774
|
+
CARRAY_GENERAL_PATH=2 goes one step further for the kernel iterator.
|
|
775
|
+
Besides switching the fast paths off, it makes the iterator deliver
|
|
776
|
+
every source the way it delivers a view it knows nothing about: the
|
|
777
|
+
whole view gathered into scratch through the view's own transfer
|
|
778
|
+
(ca_xfer_all), and on WRITE the changed cells sent back through it.
|
|
779
|
+
That walk keeps no promise of its own -- the view's transfer keeps
|
|
780
|
+
them -- so a run with 2 checks the iterator's other routes against
|
|
781
|
+
it. ca_iter_by_transfer_only() is constant 0 in a release build.
|
|
782
|
+
|
|
520
783
|
---------------------------------------------------------------------------- */
|
|
521
784
|
|
|
522
785
|
#ifdef CARRAY_DEV_BUILD
|
|
523
786
|
extern int ca_fast_paths_on;
|
|
524
|
-
|
|
787
|
+
extern int ca_iter_transfer_only_on;
|
|
788
|
+
#define ca_fast_paths_enabled() (ca_fast_paths_on)
|
|
789
|
+
#define ca_iter_by_transfer_only() (ca_iter_transfer_only_on)
|
|
525
790
|
#else
|
|
526
|
-
#define ca_fast_paths_enabled()
|
|
791
|
+
#define ca_fast_paths_enabled() (1)
|
|
792
|
+
#define ca_iter_by_transfer_only() (0)
|
|
527
793
|
#endif
|
|
528
794
|
|
|
529
795
|
/* A logical operator between a boolean array and an object array reads the
|
|
@@ -532,4 +798,45 @@ extern int ca_fast_paths_on;
|
|
|
532
798
|
void ca_binop_read_boolean_as_truth (int logical, volatile VALUE *pa,
|
|
533
799
|
volatile VALUE *pb);
|
|
534
800
|
|
|
801
|
+
/* The :linear percentile between the k-th and (k+1)-th of n sorted values,
|
|
802
|
+
lo and hi, at fraction r past the k-th: lo itself when r is 0 or there is
|
|
803
|
+
no (k+1)-th, else lo * (1 - r) + hi * r. A NaN sorts last, so a hi in the
|
|
804
|
+
NaN tail makes the answer NaN unless r is 0. The core's percentile and the
|
|
805
|
+
iterators' per-segment kernels answer through this one expression. */
|
|
806
|
+
static inline double
|
|
807
|
+
ca_percentile_linear (double lo, double hi, double r, ca_size_t k, ca_size_t n)
|
|
808
|
+
{
|
|
809
|
+
if ( r == 0.0 || k + 1 >= n ) return lo;
|
|
810
|
+
return lo * (1.0 - r) + hi * r;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
/* rb_ca_ptr2obj without the Face decode and the boolean true/false: a
|
|
814
|
+
boolean is 0 or 1 and a Face cell is its storage value. For the element
|
|
815
|
+
readers, which check the mask first and decode after (carray_cast.c). */
|
|
816
|
+
VALUE rb_ca_ptr2obj_storage (VALUE self, void *ptr);
|
|
817
|
+
|
|
818
|
+
/* Wrap a MemoryView producer without copying (carray_memory_view.c).
|
|
819
|
+
explicit_data_type must agree with a typed producer's format and names
|
|
820
|
+
a typeless one's type; typeless_data_type names only a typeless one's
|
|
821
|
+
(-1: none). writable asks the producer for a writable view and raises
|
|
822
|
+
when the source is read-only. wrap_readonly / wrap_writable take
|
|
823
|
+
their operand through this. */
|
|
824
|
+
VALUE ca_mv_wrap (VALUE obj, VALUE mask_obj, VALUE target_class,
|
|
825
|
+
int8_t explicit_data_type, int8_t typeless_data_type,
|
|
826
|
+
int writable);
|
|
827
|
+
|
|
828
|
+
/* The indexer's reading of one non-CArray key along an axis, and of the
|
|
829
|
+
rubber marker (carray_index_classifier.c). grid and CASelectAxis read
|
|
830
|
+
their keys through these, so a key means the same cells on every path. */
|
|
831
|
+
int ca_index_axis_key (VALUE arg, ca_size_t dim, int axis,
|
|
832
|
+
ca_size_t *start, ca_size_t *count, ca_size_t *step);
|
|
833
|
+
long ca_index_expand_rubber (int ndim, long argc, const VALUE *argv, VALUE *out);
|
|
834
|
+
/* Whether a key is a scalar one (an Integer or a Float), which picks one
|
|
835
|
+
cell and drops its axis. Whether it names a cell is checked when the
|
|
836
|
+
key is read. */
|
|
837
|
+
int ca_index_key_is_scalar (VALUE arg);
|
|
838
|
+
|
|
839
|
+
/* Whether this runs in the main Ractor (carray_utils.c). */
|
|
840
|
+
int ca_in_main_ractor (void);
|
|
841
|
+
|
|
535
842
|
#endif /* CARRAY_INTERNAL_H */
|