carray 3.0.3 → 3.0.5
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 +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- 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 +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- 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 +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -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 +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -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 +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -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 +105 -17
- 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 +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- 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 +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -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 +42 -6
- 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 +217 -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 +61 -37
- 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 +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- 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_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- 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_slab.c
CHANGED
|
@@ -28,8 +28,20 @@
|
|
|
28
28
|
--------------------------------------------------------------------------- */
|
|
29
29
|
|
|
30
30
|
#include "carray.h"
|
|
31
|
-
#include "carray_internal.h" /* ca_attach_window, ca_calling_method_name,
|
|
31
|
+
#include "carray_internal.h" /* ca_attach_window, ca_calling_method_name, ca_normalize_axis_arg */
|
|
32
32
|
#include "carray_slab.h"
|
|
33
|
+
#include "ca_obj_face.h"
|
|
34
|
+
|
|
35
|
+
/* Promise 8 of the kernel iterator: a slab may be lent to Ruby as a view
|
|
36
|
+
onto the source's own memory only when the source is an entity and the
|
|
37
|
+
walk reads that memory in place (alias_ptr is src->ptr, not a scratch or
|
|
38
|
+
a root it gathered from). Any other slab is a copy, and a view built on
|
|
39
|
+
it would read memory the walk frees or reuses. */
|
|
40
|
+
static int
|
|
41
|
+
ca_slab_walk_reads_src_in_place (const ca_iter_state *it, CArray *src)
|
|
42
|
+
{
|
|
43
|
+
return ca_is_entity(src) && it->alias_ptr == src->ptr;
|
|
44
|
+
}
|
|
33
45
|
|
|
34
46
|
/* Forward declarations: per-form loop bodies are defined later in this
|
|
35
47
|
file and take a state pointer directly. */
|
|
@@ -66,21 +78,14 @@ ca_slab_parse_axes (ca_slab_iter_state_t *st, VALUE axis_arg, int8_t src_ndim)
|
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
n = (int) RARRAY_LEN(arr);
|
|
69
|
-
if ( n < 1 || n > CA_RANK_MAX ) {
|
|
81
|
+
if ( n < 1 || n > CA_RANK_MAX ) { /* rank-check: a list of axes, no longer than the rank */
|
|
70
82
|
rb_raise(rb_eArgError,
|
|
71
83
|
"%s: axis count %d out of range [1..%d]",
|
|
72
84
|
ca_calling_method_name(), n, CA_RANK_MAX);
|
|
73
85
|
}
|
|
74
86
|
|
|
75
87
|
for ( i = 0; i < n; i++ ) {
|
|
76
|
-
int k = (
|
|
77
|
-
if ( k < 0 ) k += src_ndim;
|
|
78
|
-
if ( k < 0 || k >= src_ndim ) {
|
|
79
|
-
rb_raise(rb_eArgError,
|
|
80
|
-
"%s: axis %d out of range for ndim %d",
|
|
81
|
-
ca_calling_method_name(), NUM2INT(rb_ary_entry(arr, i)),
|
|
82
|
-
src_ndim);
|
|
83
|
-
}
|
|
88
|
+
int k = ca_normalize_axis_arg(rb_ary_entry(arr, i), src_ndim, NULL);
|
|
84
89
|
for ( j = 0; j < i; j++ ) {
|
|
85
90
|
if ( st->slab_axes[j] == (int8_t) k ) {
|
|
86
91
|
rb_raise(rb_eArgError,
|
|
@@ -341,6 +346,26 @@ ca_slab_build_output_view (int8_t data_type, ca_size_t bytes,
|
|
|
341
346
|
return TypedData_Wrap_Struct(rb_cCAWrap, &cawrap_data_type, cw);
|
|
342
347
|
}
|
|
343
348
|
|
|
349
|
+
/* The array the slab views move onto when the walk ends (see
|
|
350
|
+
slab_state_release_views), made with the carrier and held by it. It is
|
|
351
|
+
made here rather than at the end: the end runs in an ensure, after the
|
|
352
|
+
block, and an allocation failing there would leave the walk open and
|
|
353
|
+
the views pointing into freed scratch. */
|
|
354
|
+
static void
|
|
355
|
+
ca_slab_prepare_backing (ca_slab_iter_state_t *st)
|
|
356
|
+
{
|
|
357
|
+
CArray *cw, *backing;
|
|
358
|
+
volatile VALUE bv;
|
|
359
|
+
TypedData_Get_Struct(st->carrier, CArray, &carray_data_type, cw);
|
|
360
|
+
bv = rb_carray_new(cw->data_type, cw->ndim, cw->dim, cw->bytes, NULL);
|
|
361
|
+
TypedData_Get_Struct(bv, CArray, &carray_data_type, backing);
|
|
362
|
+
if ( cw->mask ) {
|
|
363
|
+
ca_create_mask(backing);
|
|
364
|
+
}
|
|
365
|
+
rb_ivar_set(st->carrier, rb_intern("__slab_backing__"), bv);
|
|
366
|
+
RB_GC_GUARD(bv);
|
|
367
|
+
}
|
|
368
|
+
|
|
344
369
|
/* Common setup of the input slab view for all 4 forms. Decides ALIAS
|
|
345
370
|
vs SCRATCH from T1's slab_strides[0] vs src->bytes equality, builds
|
|
346
371
|
the slab_view + (when SCRATCH) carrier in place. The mask travels
|
|
@@ -370,12 +395,13 @@ ca_slab_setup_input_slab_view (ca_slab_iter_state_t *st, CArray *src,
|
|
|
370
395
|
p_in via slab_strides into the scratch, present slab_view as
|
|
371
396
|
a CAStride over the carrier with contig strides.
|
|
372
397
|
|
|
373
|
-
Path (a) needs p_in to lie in src's own buffer
|
|
374
|
-
|
|
375
|
-
|
|
398
|
+
Path (a) needs p_in to lie in src's own buffer: src is an entity
|
|
399
|
+
and the iterator walks that buffer (alias_ptr is src->ptr, not a
|
|
400
|
+
scratch it gathered into). Any other source -- a view, whose cells
|
|
401
|
+
the iterator hands out from the root, a parent or its own scratch --
|
|
376
402
|
takes path (b): the iterator describes every slab by p_in and
|
|
377
403
|
slab_strides, whatever its mode. */
|
|
378
|
-
int contig =
|
|
404
|
+
int contig = ca_slab_walk_reads_src_in_place(st->t1, src)
|
|
379
405
|
&& ca_slab_strides_are_row_major_contig(slab_ndim,
|
|
380
406
|
st->t1->slab_dims,
|
|
381
407
|
st->t1->slab_strides,
|
|
@@ -436,9 +462,10 @@ ca_slab_setup_input_slab_view (ca_slab_iter_state_t *st, CArray *src,
|
|
|
436
462
|
dim[0] = fiber_len;
|
|
437
463
|
strides[0] = src->bytes;
|
|
438
464
|
/* A window onto src only when the fiber lies in src's own buffer:
|
|
439
|
-
an entity whose fiber is contiguous.
|
|
440
|
-
the root or the iterator's scratch, so it
|
|
441
|
-
|
|
465
|
+
an entity the iterator walks in place, whose fiber is contiguous.
|
|
466
|
+
A view's fiber comes from the root or the iterator's scratch, so it
|
|
467
|
+
goes through a carrier. */
|
|
468
|
+
in_alias = ca_slab_walk_reads_src_in_place(st->t1, src) && (in_stride == src->bytes);
|
|
442
469
|
|
|
443
470
|
if ( in_alias ) {
|
|
444
471
|
/* ALIAS: parent = src. ca_stride_setup auto-creates slab_view->mask
|
|
@@ -458,6 +485,10 @@ ca_slab_setup_input_slab_view (ca_slab_iter_state_t *st, CArray *src,
|
|
|
458
485
|
}
|
|
459
486
|
}
|
|
460
487
|
|
|
488
|
+
if ( st->carrier != Qnil ) {
|
|
489
|
+
ca_slab_prepare_backing(st);
|
|
490
|
+
}
|
|
491
|
+
|
|
461
492
|
/* The slab is a window onto the source when the fiber is contiguous and
|
|
462
493
|
a copy in the iterator's scratch when it is not, so writing through it
|
|
463
494
|
landed on one axis and vanished on the next. Nothing in the surface
|
|
@@ -494,8 +525,18 @@ ca_slab_advance_slab_view (ca_slab_iter_state_t *st,
|
|
|
494
525
|
slab_cs->base_offset = (ca_size_t) (p_in - src->ptr);
|
|
495
526
|
if ( slab_cs->mask != NULL ) {
|
|
496
527
|
CAStride *mask_cs = (CAStride *) slab_cs->mask;
|
|
497
|
-
|
|
498
|
-
|
|
528
|
+
if ( m_in != NULL ) {
|
|
529
|
+
mask_cs->ptr = (char *) m_in;
|
|
530
|
+
mask_cs->base_offset = (ca_size_t) ((char *) m_in - src->mask->ptr);
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
/* The walk was opened on a source without a mask and the block
|
|
534
|
+
has given it one since: there is no mask cursor, so the slab's
|
|
535
|
+
mask reads the source's mask at the cell the data starts on. */
|
|
536
|
+
mask_cs->ptr = NULL;
|
|
537
|
+
mask_cs->base_offset = (ca_size_t) ((p_in - src->ptr) / src->bytes)
|
|
538
|
+
* src->mask->bytes;
|
|
539
|
+
}
|
|
499
540
|
}
|
|
500
541
|
} else if ( st->own_data_scratch != NULL ) {
|
|
501
542
|
/* Non-contig multi-axis: K-D gather from src memory (via
|
|
@@ -515,7 +556,7 @@ ca_slab_advance_slab_view (ca_slab_iter_state_t *st,
|
|
|
515
556
|
both slab_view and carrier at the iter's delivered addr. */
|
|
516
557
|
slab_cs->ptr = p_in;
|
|
517
558
|
carrier_cw->ptr = p_in;
|
|
518
|
-
if ( slab_cs->mask != NULL ) {
|
|
559
|
+
if ( slab_cs->mask != NULL && m_in != NULL ) {
|
|
519
560
|
CAStride *mask_cs = (CAStride *) slab_cs->mask;
|
|
520
561
|
mask_cs->ptr = (char *) m_in;
|
|
521
562
|
carrier_cw->mask->ptr = (char *) m_in;
|
|
@@ -626,10 +667,26 @@ ca_map_slab_cast_body (VALUE arg)
|
|
|
626
667
|
return Qnil;
|
|
627
668
|
}
|
|
628
669
|
|
|
670
|
+
/* What the block sees of the slab: the slab view itself, or, over a Face,
|
|
671
|
+
the slab view under that Face, as `a[...]` would give it. The slab
|
|
672
|
+
view is moved per slab in place, and the Face reads through it, so one
|
|
673
|
+
is built per walk. */
|
|
674
|
+
static VALUE
|
|
675
|
+
ca_slab_piece (ca_slab_iter_state_t *st)
|
|
676
|
+
{
|
|
677
|
+
CArray *src;
|
|
678
|
+
TypedData_Get_Struct(st->self, CArray, &carray_data_type, src);
|
|
679
|
+
if ( ! ca_is_face(src) ) {
|
|
680
|
+
return st->slab_view;
|
|
681
|
+
}
|
|
682
|
+
return ca_face_lift(st->slab_view, st->self);
|
|
683
|
+
}
|
|
684
|
+
|
|
629
685
|
static VALUE
|
|
630
686
|
ca_slab_run_map (ca_slab_iter_state_t *st)
|
|
631
687
|
{
|
|
632
688
|
CArray *src;
|
|
689
|
+
volatile VALUE piece;
|
|
633
690
|
CArray *out;
|
|
634
691
|
uint32_t flags_in;
|
|
635
692
|
uint32_t flags_out;
|
|
@@ -715,6 +772,7 @@ ca_slab_run_map (ca_slab_iter_state_t *st)
|
|
|
715
772
|
TypedData_Get_Struct(st->output_slab_view, CAWrap,
|
|
716
773
|
&cawrap_data_type, out_slab_cw);
|
|
717
774
|
|
|
775
|
+
piece = ca_slab_piece(st);
|
|
718
776
|
while ( ca_iter_state_next_slab_axes(st->t1, &p_in, &m_in) &&
|
|
719
777
|
ca_iter_state_next_slab_axes(st->t1_out, &p_out, &m_out) ) {
|
|
720
778
|
VALUE result;
|
|
@@ -732,7 +790,7 @@ ca_slab_run_map (ca_slab_iter_state_t *st)
|
|
|
732
790
|
? st->own_out_scratch : p_out;
|
|
733
791
|
out_slab_cw->ptr = write_target;
|
|
734
792
|
|
|
735
|
-
result = rb_yield(
|
|
793
|
+
result = rb_yield(piece);
|
|
736
794
|
|
|
737
795
|
/* Strict shape check. */
|
|
738
796
|
if ( rb_obj_is_kind_of(result, rb_cCArray) ) {
|
|
@@ -827,7 +885,6 @@ ca_slab_reduce_setup (ca_slab_iter_state_t *st, CArray **out_src,
|
|
|
827
885
|
ca_size_t *out_n)
|
|
828
886
|
{
|
|
829
887
|
CArray *src;
|
|
830
|
-
CArray *out;
|
|
831
888
|
ca_size_t fiber_len;
|
|
832
889
|
ca_size_t out_dim[CA_RANK_MAX];
|
|
833
890
|
int8_t out_ndim;
|
|
@@ -870,7 +927,6 @@ ca_slab_reduce_setup (ca_slab_iter_state_t *st, CArray **out_src,
|
|
|
870
927
|
|
|
871
928
|
st->output = rb_carray_new(st->out_data_type, out_ndim, out_dim,
|
|
872
929
|
st->out_bytes, NULL);
|
|
873
|
-
TypedData_Get_Struct(st->output, CArray, &carray_data_type, out);
|
|
874
930
|
|
|
875
931
|
/* FIBER_CONTIG is naxes==1 only (T1 substrate contract). Multi-axis
|
|
876
932
|
omits the flag and uses bare CA_SLAB_AXES; T1 picks an in-src
|
|
@@ -898,10 +954,36 @@ ca_slab_reduce_setup (ca_slab_iter_state_t *st, CArray **out_src,
|
|
|
898
954
|
/* Per-slab block form: block receives the slab CArray, returns a
|
|
899
955
|
scalar; each scalar is cast into the corresponding output cell.
|
|
900
956
|
(`init:` absent ⇒ this path) */
|
|
957
|
+
/* Write one reduced value into the reduction output. UNDEF from the
|
|
958
|
+
block masks the cell, as storing UNDEF into an array does; obj2ptr
|
|
959
|
+
would read it as 0. */
|
|
960
|
+
static void
|
|
961
|
+
ca_slab_store_reduced (ca_slab_iter_state_t *st, CArray *out,
|
|
962
|
+
ca_size_t out_idx, VALUE value, char *scratch)
|
|
963
|
+
{
|
|
964
|
+
char *dst = out->ptr + out_idx * st->out_bytes;
|
|
965
|
+
if ( value == CA_UNDEF ) {
|
|
966
|
+
if ( out->mask == NULL ) {
|
|
967
|
+
ca_create_mask(out);
|
|
968
|
+
}
|
|
969
|
+
((boolean8_t *) out->mask->ptr)[out_idx] = 1;
|
|
970
|
+
if ( out->data_type == CA_OBJECT ) {
|
|
971
|
+
*(VALUE *) dst = INT2FIX(0);
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
memset(dst, 0, st->out_bytes);
|
|
975
|
+
}
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
rb_ca_obj2ptr(st->output, value, scratch);
|
|
979
|
+
memcpy(dst, scratch, st->out_bytes);
|
|
980
|
+
}
|
|
981
|
+
|
|
901
982
|
static VALUE
|
|
902
983
|
ca_slab_run_reduce_slab (ca_slab_iter_state_t *st)
|
|
903
984
|
{
|
|
904
985
|
CArray *src;
|
|
986
|
+
volatile VALUE piece;
|
|
905
987
|
CArray *out;
|
|
906
988
|
ca_size_t fiber_len;
|
|
907
989
|
char *p_in;
|
|
@@ -927,13 +1009,14 @@ ca_slab_run_reduce_slab (ca_slab_iter_state_t *st)
|
|
|
927
1009
|
scratch = (st->out_bytes <= (ca_size_t) sizeof(buf))
|
|
928
1010
|
? buf : ALLOCV_N(char, scratch_holder, st->out_bytes);
|
|
929
1011
|
|
|
1012
|
+
piece = ca_slab_piece(st);
|
|
930
1013
|
while ( ca_iter_state_next_slab_axes(st->t1, &p_in, &m_in) ) {
|
|
931
1014
|
VALUE result;
|
|
932
1015
|
|
|
933
1016
|
ca_slab_advance_slab_view(st, slab_cs, carrier_cw,
|
|
934
1017
|
src, p_in, m_in, in_alias);
|
|
935
1018
|
|
|
936
|
-
result = rb_yield(
|
|
1019
|
+
result = rb_yield(piece);
|
|
937
1020
|
|
|
938
1021
|
/* Strict scalar contract: block must return a scalar Ruby value
|
|
939
1022
|
(Numeric / Object / etc.). A CArray is a
|
|
@@ -952,8 +1035,7 @@ ca_slab_run_reduce_slab (ca_slab_iter_state_t *st)
|
|
|
952
1035
|
res->elements == 1 ? "" : "s");
|
|
953
1036
|
}
|
|
954
1037
|
|
|
955
|
-
|
|
956
|
-
memcpy(out->ptr + out_idx * st->out_bytes, scratch, st->out_bytes);
|
|
1038
|
+
ca_slab_store_reduced(st, out, out_idx, result, scratch);
|
|
957
1039
|
out_idx++;
|
|
958
1040
|
}
|
|
959
1041
|
|
|
@@ -968,6 +1050,7 @@ static VALUE
|
|
|
968
1050
|
ca_slab_run_reduce_fiber (ca_slab_iter_state_t *st)
|
|
969
1051
|
{
|
|
970
1052
|
CArray *src;
|
|
1053
|
+
volatile VALUE piece;
|
|
971
1054
|
CArray *out;
|
|
972
1055
|
ca_size_t fiber_len;
|
|
973
1056
|
char *p_in;
|
|
@@ -993,6 +1076,7 @@ ca_slab_run_reduce_fiber (ca_slab_iter_state_t *st)
|
|
|
993
1076
|
scratch = (st->out_bytes <= (ca_size_t) sizeof(buf))
|
|
994
1077
|
? buf : ALLOCV_N(char, scratch_holder, st->out_bytes);
|
|
995
1078
|
|
|
1079
|
+
piece = ca_slab_piece(st);
|
|
996
1080
|
while ( ca_iter_state_next_slab_axes(st->t1, &p_in, &m_in) ) {
|
|
997
1081
|
VALUE acc;
|
|
998
1082
|
ca_size_t i;
|
|
@@ -1010,7 +1094,7 @@ ca_slab_run_reduce_fiber (ca_slab_iter_state_t *st)
|
|
|
1010
1094
|
ca_size_t total = st->t1->slab_elements;
|
|
1011
1095
|
for ( i = 0; i < total; i++ ) {
|
|
1012
1096
|
VALUE x;
|
|
1013
|
-
x = rb_ca_fetch_index(
|
|
1097
|
+
x = rb_ca_fetch_index(piece, kidx);
|
|
1014
1098
|
acc = rb_yield_values(2, acc, x);
|
|
1015
1099
|
/* Increment kidx[] row-major. */
|
|
1016
1100
|
for ( k = slab_cs->ndim - 1; k >= 0; k-- ) {
|
|
@@ -1021,8 +1105,7 @@ ca_slab_run_reduce_fiber (ca_slab_iter_state_t *st)
|
|
|
1021
1105
|
(void) fiber_len;
|
|
1022
1106
|
}
|
|
1023
1107
|
|
|
1024
|
-
|
|
1025
|
-
memcpy(out->ptr + out_idx * st->out_bytes, scratch, st->out_bytes);
|
|
1108
|
+
ca_slab_store_reduced(st, out, out_idx, acc, scratch);
|
|
1026
1109
|
out_idx++;
|
|
1027
1110
|
}
|
|
1028
1111
|
|
|
@@ -1049,6 +1132,7 @@ static VALUE
|
|
|
1049
1132
|
ca_slab_run_each (ca_slab_iter_state_t *st)
|
|
1050
1133
|
{
|
|
1051
1134
|
CArray *src;
|
|
1135
|
+
volatile VALUE piece;
|
|
1052
1136
|
char *p_in;
|
|
1053
1137
|
boolean8_t *m_in;
|
|
1054
1138
|
CAStride *slab_cs;
|
|
@@ -1082,10 +1166,11 @@ ca_slab_run_each (ca_slab_iter_state_t *st)
|
|
|
1082
1166
|
TypedData_Get_Struct(st->carrier, CAWrap, &cawrap_data_type, carrier_cw);
|
|
1083
1167
|
}
|
|
1084
1168
|
|
|
1169
|
+
piece = ca_slab_piece(st);
|
|
1085
1170
|
while ( ca_iter_state_next_slab_axes(st->t1, &p_in, &m_in) ) {
|
|
1086
1171
|
ca_slab_advance_slab_view(st, slab_cs, carrier_cw,
|
|
1087
1172
|
src, p_in, m_in, in_alias);
|
|
1088
|
-
rb_yield(
|
|
1173
|
+
rb_yield(piece); /* return value discarded */
|
|
1089
1174
|
}
|
|
1090
1175
|
|
|
1091
1176
|
return st->self;
|
|
@@ -1115,8 +1200,9 @@ slab_state_run_body (VALUE arg)
|
|
|
1115
1200
|
as it has a ptr. Before the scratch they point into is freed, the
|
|
1116
1201
|
input slab and its carrier are moved onto a copy of the last slab,
|
|
1117
1202
|
held by the carrier, and the internal output view lets go of its
|
|
1118
|
-
buffer.
|
|
1119
|
-
|
|
1203
|
+
buffer. The copy is made into the array ca_slab_prepare_backing set
|
|
1204
|
+
aside, so nothing here allocates. A slab that is a window onto the
|
|
1205
|
+
source itself points into the source and needs nothing. */
|
|
1120
1206
|
static void
|
|
1121
1207
|
slab_state_release_views (ca_slab_iter_state_t *st)
|
|
1122
1208
|
{
|
|
@@ -1133,12 +1219,12 @@ slab_state_release_views (ca_slab_iter_state_t *st)
|
|
|
1133
1219
|
if ( cw->ptr == NULL ) {
|
|
1134
1220
|
return;
|
|
1135
1221
|
}
|
|
1136
|
-
|
|
1137
|
-
bv
|
|
1138
|
-
|
|
1139
|
-
|
|
1222
|
+
bv = rb_ivar_get(st->carrier, rb_intern("__slab_backing__"));
|
|
1223
|
+
TypedData_Get_Struct(bv, CArray, &carray_data_type, backing);
|
|
1224
|
+
memcpy(backing->ptr, cw->ptr, (size_t) (cw->elements * cw->bytes));
|
|
1225
|
+
if ( cw->mask && cw->mask->ptr ) {
|
|
1226
|
+
memcpy(backing->mask->ptr, cw->mask->ptr, (size_t) cw->elements);
|
|
1140
1227
|
}
|
|
1141
|
-
rb_ivar_set(st->carrier, rb_intern("__slab_backing__"), bv);
|
|
1142
1228
|
if ( cs->ptr ) {
|
|
1143
1229
|
cs->ptr = backing->ptr;
|
|
1144
1230
|
}
|