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/ca_obj_stride.c
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
---------------------------------------------------------------------------- */
|
|
21
21
|
|
|
22
22
|
#include "carray.h"
|
|
23
|
-
#include "carray_internal.h" /*
|
|
23
|
+
#include "carray_internal.h" /* ca_normalize_axis_arg */
|
|
24
24
|
#include "ca_iter_substrate.h"
|
|
25
25
|
#include "ca_obj_face.h" /* ca_is_face, used by the compose-fold walk */
|
|
26
26
|
|
|
@@ -94,17 +94,15 @@ int8_t CA_OBJ_STRIDE; /* assigned at Init time via ca_install_obj_type */
|
|
|
94
94
|
override pattern and makes the C-level dispatch wire up correctly
|
|
95
95
|
on the first try. */
|
|
96
96
|
int
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
ca_stride_setup_view (CAStride *ca, int8_t obj_type, CArray *parent,
|
|
98
|
+
int8_t data_type, ca_size_t bytes,
|
|
99
|
+
int8_t ndim, ca_size_t *dim,
|
|
100
|
+
ca_size_t *strides, ca_size_t base_offset)
|
|
101
101
|
{
|
|
102
102
|
ca_size_t elements;
|
|
103
103
|
int i;
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
rb_raise(rb_eArgError, "invalid ndim %d", (int) ndim);
|
|
107
|
-
}
|
|
105
|
+
ca_check_rank_fits(ndim, NULL);
|
|
108
106
|
for (i = 0; i < ndim; i++) {
|
|
109
107
|
if (dim[i] < 0) {
|
|
110
108
|
rb_raise(rb_eIndexError,
|
|
@@ -144,10 +142,23 @@ ca_stride_setup (CAStride *ca, int8_t obj_type, CArray *parent,
|
|
|
144
142
|
ca->strides[i] = strides[i];
|
|
145
143
|
}
|
|
146
144
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
150
147
|
|
|
148
|
+
/* The public form also takes the parent's mask. A struct that no Ruby
|
|
149
|
+
object owns yet is lost if the parent's answer raises; the in-tree
|
|
150
|
+
constructors use ca_stride_setup_view and ca_view_inherit_mask. */
|
|
151
|
+
int
|
|
152
|
+
ca_stride_setup (CAStride *ca, int8_t obj_type, CArray *parent,
|
|
153
|
+
int8_t data_type, ca_size_t bytes,
|
|
154
|
+
int8_t ndim, ca_size_t *dim,
|
|
155
|
+
ca_size_t *strides, ca_size_t base_offset)
|
|
156
|
+
{
|
|
157
|
+
ca_stride_setup_view(ca, obj_type, parent, data_type, bytes,
|
|
158
|
+
ndim, dim, strides, base_offset);
|
|
159
|
+
if ( ca != NULL ) {
|
|
160
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
161
|
+
}
|
|
151
162
|
return 0;
|
|
152
163
|
}
|
|
153
164
|
|
|
@@ -158,11 +169,12 @@ ca_stride_new (int8_t obj_type, CArray *parent,
|
|
|
158
169
|
ca_size_t *strides, ca_size_t base_offset)
|
|
159
170
|
{
|
|
160
171
|
CAStride *ca;
|
|
161
|
-
|
|
162
|
-
|
|
172
|
+
ca_stride_setup_view(NULL, obj_type, parent,
|
|
173
|
+
data_type, bytes, ndim, dim, strides, base_offset);
|
|
163
174
|
ca = (CAStride *) ca_array_alloc(obj_type, ndim);
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
ca_stride_setup_view(ca, obj_type, parent,
|
|
176
|
+
data_type, bytes, ndim, dim, strides, base_offset);
|
|
177
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
166
178
|
return ca;
|
|
167
179
|
}
|
|
168
180
|
|
|
@@ -443,6 +455,8 @@ ca_stride_compose_to_root (CAStride *leaf,
|
|
|
443
455
|
|
|
444
456
|
"Identity compose-fold" semantics:
|
|
445
457
|
- cand->bytes == root->bytes (no byte reinterpret)
|
|
458
|
+
- cand->data_type == root->data_type (no type reinterpret: a caller
|
|
459
|
+
may read the root's cells as typed values)
|
|
446
460
|
- composed_base == 0
|
|
447
461
|
- composed_strides[k] match row-major over cand->dim with cand->bytes
|
|
448
462
|
|
|
@@ -471,6 +485,7 @@ ca_resolve_attached_root_via_identity (CArray *cand)
|
|
|
471
485
|
ca_stride_compose_to_root(cs, &root, composed_strides, &composed_base);
|
|
472
486
|
if ( !root->ptr ) return cand;
|
|
473
487
|
if ( cs->bytes != root->bytes ) return cand;
|
|
488
|
+
if ( cs->data_type != root->data_type ) return cand;
|
|
474
489
|
if ( composed_base != 0 ) return cand;
|
|
475
490
|
|
|
476
491
|
s = root->bytes;
|
|
@@ -610,7 +625,7 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
610
625
|
ca_size_t composed_base;
|
|
611
626
|
ca_size_t rbytes;
|
|
612
627
|
ca_size_t *paddrs;
|
|
613
|
-
ca_size_t i
|
|
628
|
+
ca_size_t i;
|
|
614
629
|
int8_t k;
|
|
615
630
|
int all_aligned = 1;
|
|
616
631
|
volatile VALUE holder;
|
|
@@ -619,18 +634,12 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
619
634
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
620
635
|
rbytes = root->bytes;
|
|
621
636
|
|
|
622
|
-
/*
|
|
623
|
-
|
|
624
|
-
root
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
simple reshape so addrs pass through, then CAGrid Y.1.b fast path
|
|
629
|
-
triggers on the recursive call, then inner CARefer simple reshape
|
|
630
|
-
pass-through to entity. Detection is O(ndim) + O(n). */
|
|
631
|
-
if ( n == ca->elements
|
|
632
|
-
&& ca->bytes == rbytes && composed_base == 0
|
|
633
|
-
&& ca_xfer_addrs_is_sequential_run(n, addrs, &base) && base == 0 ) {
|
|
637
|
+
/* Identity: same cell size, no offset, row-major composed strides (a
|
|
638
|
+
simple reshape / flatten of the root). A view address is then the
|
|
639
|
+
root address, whatever the addresses are, so the list goes through
|
|
640
|
+
as-is. Cascades through chains such as a[idx_2d] (outer reshape ->
|
|
641
|
+
CAGrid -> inner reshape -> entity). */
|
|
642
|
+
if ( ca->bytes == rbytes && composed_base == 0 ) {
|
|
634
643
|
ca_size_t s = rbytes;
|
|
635
644
|
int is_identity = 1;
|
|
636
645
|
for ( k = ca->ndim - 1; k >= 0; k-- ) {
|
|
@@ -643,36 +652,51 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
643
652
|
}
|
|
644
653
|
}
|
|
645
654
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
ca_size_t idx[CA_RANK_MAX];
|
|
649
|
-
ca_size_t off = composed_base;
|
|
650
|
-
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
655
|
+
/* Whole-cell strides: translate in cell units, with no per-cell division. */
|
|
656
|
+
if ( ca->bytes == rbytes && composed_base % rbytes == 0 ) {
|
|
651
657
|
for ( k = 0; k < ca->ndim; k++ ) {
|
|
652
|
-
|
|
653
|
-
}
|
|
654
|
-
if ( ca->bytes == rbytes && off % rbytes == 0 ) {
|
|
655
|
-
paddrs[i] = off / rbytes;
|
|
656
|
-
}
|
|
657
|
-
else {
|
|
658
|
-
all_aligned = 0;
|
|
659
|
-
break;
|
|
658
|
+
if ( composed_strides[k] % rbytes != 0 ) { all_aligned = 0; break; }
|
|
660
659
|
}
|
|
661
660
|
}
|
|
661
|
+
else {
|
|
662
|
+
all_aligned = 0;
|
|
663
|
+
}
|
|
662
664
|
|
|
663
665
|
if ( all_aligned ) {
|
|
666
|
+
ca_size_t esteps[CA_RANK_MAX];
|
|
667
|
+
ca_size_t ebase = composed_base / rbytes;
|
|
668
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
669
|
+
esteps[k] = composed_strides[k] / rbytes;
|
|
670
|
+
}
|
|
671
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
672
|
+
if ( ca->ndim == 1 ) {
|
|
673
|
+
for ( i = 0; i < n; i++ ) {
|
|
674
|
+
paddrs[i] = ebase + addrs[i] * esteps[0];
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
for ( i = 0; i < n; i++ ) {
|
|
679
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
680
|
+
ca_size_t off = ebase;
|
|
681
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
682
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
683
|
+
off += idx[k] * esteps[k];
|
|
684
|
+
}
|
|
685
|
+
paddrs[i] = off;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
664
688
|
ca_xfer_addrs(root, n, paddrs, data, dir);
|
|
689
|
+
ALLOCV_END(holder);
|
|
690
|
+
return;
|
|
665
691
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
692
|
+
|
|
693
|
+
/* Byte-mismatched reinterpret: deliver cell by cell via xfer_index
|
|
694
|
+
(still no whole-view attach -- delegates one cell at a time). */
|
|
695
|
+
for ( i = 0; i < n; i++ ) {
|
|
696
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
697
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
698
|
+
ca_stride_func_xfer_index(ca, idx, d + i * ca->bytes, dir);
|
|
674
699
|
}
|
|
675
|
-
ALLOCV_END(holder);
|
|
676
700
|
}
|
|
677
701
|
|
|
678
702
|
/* Optimised region delivery. Reached when ca->ptr == NULL (the central dispatcher handles the alias / attached case).
|
|
@@ -833,6 +857,7 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
833
857
|
if (!aligned || !root->ptr) {
|
|
834
858
|
ca_size_t idx[CA_RANK_MAX], doff = 0;
|
|
835
859
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
860
|
+
/* empty: the slot returns on an empty region at its entry */
|
|
836
861
|
while (1) {
|
|
837
862
|
ca_size_t off = base_addr, vmidx[CA_RANK_MAX];
|
|
838
863
|
for (k = 0; k < ndim; k++) off += idx[k] * strides[k];
|
|
@@ -1085,8 +1110,9 @@ static int ca_layout_is_contiguous (int8_t ndim, const ca_size_t *dim,
|
|
|
1085
1110
|
composes a source down to its root.
|
|
1086
1111
|
|
|
1087
1112
|
Entities hold their own buffer. A CAStride-family root is one the fold
|
|
1088
|
-
declined to walk through (a
|
|
1089
|
-
onward
|
|
1113
|
+
declined to walk through (a reshape over a transpose); its own attach
|
|
1114
|
+
folds onward from itself, so the answer is the one for the root it folds
|
|
1115
|
+
to. What is left is the
|
|
1090
1116
|
boundary views that compute or fetch their contents -- CAObject, the lazy
|
|
1091
1117
|
per-element transforms, whatever a companion gem installed -- and of those,
|
|
1092
1118
|
only the ones with an xfer_stride slot can answer a region request at all.
|
|
@@ -1098,7 +1124,17 @@ ca_root_lends_no_memory (void *ap)
|
|
|
1098
1124
|
CArray *root = (CArray *) ap;
|
|
1099
1125
|
|
|
1100
1126
|
if ( ca_is_entity(root) ) return 0;
|
|
1101
|
-
if ( ca_func[root->obj_type].attach == ca_stride_func.attach )
|
|
1127
|
+
if ( ca_func[root->obj_type].attach == ca_stride_func.attach ) {
|
|
1128
|
+
/* The fold stopped at a CAStride (a reshape over a transpose). Its
|
|
1129
|
+
own attach folds onward from itself, so it lends memory exactly when
|
|
1130
|
+
the root it folds to does: over a computed root, attaching it
|
|
1131
|
+
produces all of it. */
|
|
1132
|
+
CArray *below;
|
|
1133
|
+
ca_size_t cs[CA_RANK_MAX];
|
|
1134
|
+
ca_size_t base;
|
|
1135
|
+
ca_stride_compose_to_root((CAStride *) root, &below, cs, &base);
|
|
1136
|
+
return ca_root_lends_no_memory(below);
|
|
1137
|
+
}
|
|
1102
1138
|
return ca_func[root->obj_type].xfer_stride != NULL;
|
|
1103
1139
|
}
|
|
1104
1140
|
|
|
@@ -1164,14 +1200,14 @@ ca_stride_func_allocate (void *ap)
|
|
|
1164
1200
|
|
|
1165
1201
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
1166
1202
|
if (ca_root_lends_no_memory(root)) {
|
|
1167
|
-
ca->ptr =
|
|
1203
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1168
1204
|
return;
|
|
1169
1205
|
}
|
|
1170
1206
|
ca_attach(root);
|
|
1171
1207
|
if (ca_layout_is_contiguous(ca->ndim, ca->dim, composed_strides, ca->bytes)) {
|
|
1172
1208
|
ca->ptr = root->ptr + composed_base;
|
|
1173
1209
|
} else {
|
|
1174
|
-
ca->ptr =
|
|
1210
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1175
1211
|
}
|
|
1176
1212
|
}
|
|
1177
1213
|
|
|
@@ -1200,14 +1236,9 @@ ca_stride_func_attach (void *ap)
|
|
|
1200
1236
|
transfer slots. */
|
|
1201
1237
|
char *buf = xmalloc(ca_length(ca));
|
|
1202
1238
|
void *args[2];
|
|
1203
|
-
int tag = 0;
|
|
1204
1239
|
args[0] = ca;
|
|
1205
1240
|
args[1] = buf;
|
|
1206
|
-
|
|
1207
|
-
if (tag) {
|
|
1208
|
-
xfree(buf);
|
|
1209
|
-
rb_jump_tag(tag);
|
|
1210
|
-
}
|
|
1241
|
+
ca_fill_or_xfree(buf, ca_stride_cold_fill, (VALUE) args); /* root stays cold */
|
|
1211
1242
|
ca->ptr = buf;
|
|
1212
1243
|
return;
|
|
1213
1244
|
}
|
|
@@ -1215,7 +1246,7 @@ ca_stride_func_attach (void *ap)
|
|
|
1215
1246
|
if (ca_layout_is_contiguous(ca->ndim, ca->dim, composed_strides, ca->bytes)) {
|
|
1216
1247
|
ca->ptr = root->ptr + composed_base;
|
|
1217
1248
|
} else {
|
|
1218
|
-
ca->ptr =
|
|
1249
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1219
1250
|
ca_stride_xfer_with_layout(ca, 0, root->ptr + composed_base, composed_strides);
|
|
1220
1251
|
}
|
|
1221
1252
|
}
|
|
@@ -1342,6 +1373,8 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1342
1373
|
char *ptr0 = ca->ptr;
|
|
1343
1374
|
char *ptr = (char *) data;
|
|
1344
1375
|
|
|
1376
|
+
if ( ca->elements == 0 ) return;
|
|
1377
|
+
|
|
1345
1378
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
1346
1379
|
|
|
1347
1380
|
/* Partial materialise: when the fold stops at a cold boundary view that knows how to deliver a region (has an
|
|
@@ -1458,6 +1491,7 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1458
1491
|
ca_size_t idx[CA_RANK_MAX], n = 0;
|
|
1459
1492
|
int8_t k;
|
|
1460
1493
|
for (k = 0; k < ca->ndim; k++) idx[k] = 0;
|
|
1494
|
+
/* empty: the slot returns on an empty view at its entry */
|
|
1461
1495
|
while (1) {
|
|
1462
1496
|
ca_size_t off = composed_base;
|
|
1463
1497
|
for (k = 0; k < ca->ndim; k++) off += idx[k] * composed_strides[k];
|
|
@@ -1471,6 +1505,52 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1471
1505
|
return;
|
|
1472
1506
|
}
|
|
1473
1507
|
|
|
1508
|
+
/* A read through a byte reinterpret (CAField, a refer to another width)
|
|
1509
|
+
over a cold root: the root's addresses are not this view's cells, but
|
|
1510
|
+
each cell lies in a run of whole root elements. Ask the root for those
|
|
1511
|
+
elements and cut the cell's bytes out of them. A write keeps the
|
|
1512
|
+
whole-root round trip below: two cells can share a root element, and
|
|
1513
|
+
writing back each one's copy of it would drop the other's bytes. */
|
|
1514
|
+
if ( dir == CA_XFER_GET && ca->elements > 0 && ca->bytes != root->bytes
|
|
1515
|
+
&& ca_func[root->obj_type].xfer_stride ) {
|
|
1516
|
+
volatile VALUE ah = 0, sh = 0;
|
|
1517
|
+
ca_size_t rb = root->bytes, cb = ca->bytes;
|
|
1518
|
+
ca_size_t per = (cb + rb - 1) / rb + 1;
|
|
1519
|
+
ca_size_t *addrs = ALLOCV_N(ca_size_t, ah, ca->elements * per);
|
|
1520
|
+
char *scratch;
|
|
1521
|
+
ca_size_t idx[CA_RANK_MAX], n = 0, i;
|
|
1522
|
+
ca_size_t *first = ALLOCV_N(ca_size_t, sh, ca->elements);
|
|
1523
|
+
int8_t k;
|
|
1524
|
+
int ok = 1;
|
|
1525
|
+
for (k = 0; k < ca->ndim; k++) idx[k] = 0;
|
|
1526
|
+
for (i = 0; ok; i++) {
|
|
1527
|
+
ca_size_t off = composed_base, e, e_end;
|
|
1528
|
+
for (k = 0; k < ca->ndim; k++) off += idx[k] * composed_strides[k];
|
|
1529
|
+
if ( off < 0 || off + cb > root->elements * rb ) { ok = 0; break; }
|
|
1530
|
+
first[i] = n * rb + off % rb;
|
|
1531
|
+
for (e = off / rb, e_end = (off + cb - 1) / rb; e <= e_end; e++) {
|
|
1532
|
+
addrs[n++] = e;
|
|
1533
|
+
}
|
|
1534
|
+
k = ca->ndim - 1;
|
|
1535
|
+
while (k >= 0) { if (++idx[k] < ca->dim[k]) break; idx[k] = 0; k--; }
|
|
1536
|
+
if (k < 0) break;
|
|
1537
|
+
}
|
|
1538
|
+
if ( ok && n < root->elements ) {
|
|
1539
|
+
volatile VALUE dh = 0;
|
|
1540
|
+
scratch = ALLOCV_N(char, dh, n * rb);
|
|
1541
|
+
ca_xfer_addrs(root, n, addrs, scratch, CA_XFER_GET);
|
|
1542
|
+
for (i = 0; i < ca->elements; i++) {
|
|
1543
|
+
memcpy(ptr + i * cb, scratch + first[i], cb);
|
|
1544
|
+
}
|
|
1545
|
+
ALLOCV_END(dh);
|
|
1546
|
+
ALLOCV_END(sh);
|
|
1547
|
+
ALLOCV_END(ah);
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
ALLOCV_END(sh);
|
|
1551
|
+
ALLOCV_END(ah);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1474
1554
|
/* Cold root without an xfer_stride slot, or an ndim mismatch the bridges
|
|
1475
1555
|
above could not express: materialise the root into scratch via
|
|
1476
1556
|
ca_xfer_all and run the direct strided gather/scatter against that.
|
|
@@ -2078,9 +2158,10 @@ rb_ca_as_strided (int argc, VALUE *argv, VALUE self)
|
|
|
2078
2158
|
"shape (%ld) and strides (%ld) length mismatch",
|
|
2079
2159
|
len, RARRAY_LEN(rstrides));
|
|
2080
2160
|
}
|
|
2081
|
-
if (len <= 0
|
|
2161
|
+
if (len <= 0) {
|
|
2082
2162
|
rb_raise(rb_eArgError, "invalid ndim %ld", len);
|
|
2083
2163
|
}
|
|
2164
|
+
ca_check_rank_fits(len, NULL);
|
|
2084
2165
|
ndim = (int8_t) len;
|
|
2085
2166
|
for (i = 0; i < len; i++) {
|
|
2086
2167
|
shape[i] = NUM2SIZE(RARRAY_AREF(rshape, i));
|
|
@@ -2118,11 +2199,7 @@ rb_ca_sliding_windows (int argc, VALUE *argv, VALUE self)
|
|
|
2118
2199
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2119
2200
|
|
|
2120
2201
|
ndim = parent->ndim;
|
|
2121
|
-
|
|
2122
|
-
rb_raise(rb_eArgError,
|
|
2123
|
-
"sliding_windows: result rank %d exceeds CA_RANK_MAX (%d)",
|
|
2124
|
-
2 * (int) ndim, CA_RANK_MAX);
|
|
2125
|
-
}
|
|
2202
|
+
ca_check_rank_fits(2 * (long) ndim, "sliding_windows");
|
|
2126
2203
|
|
|
2127
2204
|
rb_scan_args(argc, argv, "*:", (VALUE *) &rposary, (VALUE *) &ropt);
|
|
2128
2205
|
if (! NIL_P(ropt)) {
|
|
@@ -2266,11 +2343,7 @@ rb_ca_unfold (int argc, VALUE *argv, VALUE self)
|
|
|
2266
2343
|
|
|
2267
2344
|
ntrail = ndim - nspatial;
|
|
2268
2345
|
outrank = (int) ndim + (int) nspatial;
|
|
2269
|
-
|
|
2270
|
-
rb_raise(rb_eArgError,
|
|
2271
|
-
"unfold: result rank %d exceeds CA_RANK_MAX (%d)",
|
|
2272
|
-
outrank, CA_RANK_MAX);
|
|
2273
|
-
}
|
|
2346
|
+
ca_check_rank_fits(outrank, "unfold");
|
|
2274
2347
|
|
|
2275
2348
|
if (NIL_P(rstep)) {
|
|
2276
2349
|
for (i = 0; i < nspatial; i++) step[i] = 1;
|
|
@@ -2354,11 +2427,7 @@ rb_ca_block_view (int argc, VALUE *argv, VALUE self)
|
|
|
2354
2427
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2355
2428
|
|
|
2356
2429
|
ndim = parent->ndim;
|
|
2357
|
-
|
|
2358
|
-
rb_raise(rb_eArgError,
|
|
2359
|
-
"block_view: result rank %d exceeds CA_RANK_MAX (%d)",
|
|
2360
|
-
2 * (int) ndim, CA_RANK_MAX);
|
|
2361
|
-
}
|
|
2430
|
+
ca_check_rank_fits(2 * (long) ndim, "block_view");
|
|
2362
2431
|
|
|
2363
2432
|
rb_scan_args(argc, argv, "*:", (VALUE *) &rposary, (VALUE *) &ropt);
|
|
2364
2433
|
rb_reject_options(ropt);
|
|
@@ -2461,7 +2530,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2461
2530
|
(int) n_iter, (int) ndim);
|
|
2462
2531
|
}
|
|
2463
2532
|
for (i = 0; i < n_iter; i++) {
|
|
2464
|
-
iter_axes[i] =
|
|
2533
|
+
iter_axes[i] = ca_normalize_axis_arg(RARRAY_AREF(aary, i), ndim, NULL);
|
|
2465
2534
|
}
|
|
2466
2535
|
}
|
|
2467
2536
|
else if (nargs >= 1) {
|
|
@@ -2472,7 +2541,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2472
2541
|
}
|
|
2473
2542
|
n_iter = (int8_t) nargs;
|
|
2474
2543
|
for (i = 0; i < n_iter; i++) {
|
|
2475
|
-
iter_axes[i] =
|
|
2544
|
+
iter_axes[i] = ca_normalize_axis_arg(RARRAY_AREF(rposary, i), ndim, NULL);
|
|
2476
2545
|
}
|
|
2477
2546
|
}
|
|
2478
2547
|
else {
|
|
@@ -2480,23 +2549,16 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2480
2549
|
"dim_view: at least one iteration axis required");
|
|
2481
2550
|
}
|
|
2482
2551
|
|
|
2483
|
-
/*
|
|
2552
|
+
/* The axes are normalized as they are read; check distinctness. */
|
|
2484
2553
|
for (i = 0; i < ndim; i++) seen[i] = 0;
|
|
2485
2554
|
for (i = 0; i < n_iter; i++) {
|
|
2486
2555
|
ca_size_t a = iter_axes[i];
|
|
2487
|
-
if (a < 0) a += ndim;
|
|
2488
|
-
if (a < 0 || a >= ndim) {
|
|
2489
|
-
rb_raise(rb_eArgError,
|
|
2490
|
-
"dim_view: axis %lld out of range for ndim %d",
|
|
2491
|
-
(long long) iter_axes[i], (int) ndim);
|
|
2492
|
-
}
|
|
2493
2556
|
if (seen[a]) {
|
|
2494
2557
|
rb_raise(rb_eArgError,
|
|
2495
2558
|
"dim_view: duplicate iteration axis %lld",
|
|
2496
2559
|
(long long) a);
|
|
2497
2560
|
}
|
|
2498
2561
|
seen[a] = 1;
|
|
2499
|
-
iter_axes[i] = a;
|
|
2500
2562
|
}
|
|
2501
2563
|
|
|
2502
2564
|
/* imap: iter axes first (in given order), then remaining axes
|
|
@@ -2568,12 +2630,8 @@ rb_ca_flip_axis (VALUE self, long axis)
|
|
|
2568
2630
|
rb_check_carray_object(self);
|
|
2569
2631
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2570
2632
|
int8_t ndim = parent->ndim;
|
|
2571
|
-
long a = (axis
|
|
2572
|
-
|
|
2573
|
-
rb_raise(rb_eArgError,
|
|
2574
|
-
"flip_axis: axis %ld out of range for ndim %d",
|
|
2575
|
-
axis, (int) ndim);
|
|
2576
|
-
}
|
|
2633
|
+
long a = rb_ca_normalize_axis_for_ndim(axis, ndim, /* axis-check: a long from a C caller */
|
|
2634
|
+
"flip_axis");
|
|
2577
2635
|
int8_t flip[CA_RANK_MAX] = {0};
|
|
2578
2636
|
flip[a] = 1;
|
|
2579
2637
|
return rb_ca_flip_build_view(self, parent, flip);
|
|
@@ -2615,7 +2673,7 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2615
2673
|
(int) n_axes, (int) ndim);
|
|
2616
2674
|
}
|
|
2617
2675
|
for (i = 0; i < n_axes; i++) {
|
|
2618
|
-
axes[i] =
|
|
2676
|
+
axes[i] = ca_normalize_axis_arg(RARRAY_AREF(aary, i), ndim, NULL);
|
|
2619
2677
|
}
|
|
2620
2678
|
}
|
|
2621
2679
|
else {
|
|
@@ -2626,18 +2684,12 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2626
2684
|
}
|
|
2627
2685
|
n_axes = (int8_t) nargs;
|
|
2628
2686
|
for (i = 0; i < n_axes; i++) {
|
|
2629
|
-
axes[i] =
|
|
2687
|
+
axes[i] = ca_normalize_axis_arg(RARRAY_AREF(rposary, i), ndim, NULL);
|
|
2630
2688
|
}
|
|
2631
2689
|
}
|
|
2632
2690
|
|
|
2633
2691
|
for (i = 0; i < n_axes; i++) {
|
|
2634
2692
|
ca_size_t a = axes[i];
|
|
2635
|
-
if (a < 0) a += ndim;
|
|
2636
|
-
if (a < 0 || a >= ndim) {
|
|
2637
|
-
rb_raise(rb_eArgError,
|
|
2638
|
-
"flip: axis %lld out of range for ndim %d",
|
|
2639
|
-
(long long) axes[i], (int) ndim);
|
|
2640
|
-
}
|
|
2641
2693
|
if (flip[a]) {
|
|
2642
2694
|
rb_raise(rb_eArgError,
|
|
2643
2695
|
"flip: duplicate axis %lld",
|
|
@@ -2711,18 +2763,8 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2711
2763
|
rb_raise(rb_eArgError,
|
|
2712
2764
|
"diagonal: axis: must be an Array of 2 integers");
|
|
2713
2765
|
}
|
|
2714
|
-
ai =
|
|
2715
|
-
aj =
|
|
2716
|
-
if (ai < 0) ai += ndim;
|
|
2717
|
-
if (aj < 0) aj += ndim;
|
|
2718
|
-
if (ai < 0 || ai >= ndim) {
|
|
2719
|
-
rb_raise(rb_eArgError, "diagonal: axis[0] out of range for ndim %d",
|
|
2720
|
-
(int) ndim);
|
|
2721
|
-
}
|
|
2722
|
-
if (aj < 0 || aj >= ndim) {
|
|
2723
|
-
rb_raise(rb_eArgError, "diagonal: axis[1] out of range for ndim %d",
|
|
2724
|
-
(int) ndim);
|
|
2725
|
-
}
|
|
2766
|
+
ai = ca_normalize_axis_arg(RARRAY_AREF(raxis, 0), ndim, NULL);
|
|
2767
|
+
aj = ca_normalize_axis_arg(RARRAY_AREF(raxis, 1), ndim, NULL);
|
|
2726
2768
|
if (ai == aj) {
|
|
2727
2769
|
rb_raise(rb_eArgError, "diagonal: axis[0] and axis[1] must be distinct");
|
|
2728
2770
|
}
|
|
@@ -2750,7 +2792,9 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2750
2792
|
base_offset = offset * parent_byte_stride[aj];
|
|
2751
2793
|
}
|
|
2752
2794
|
else {
|
|
2753
|
-
|
|
2795
|
+
/* compare before negating: -offset overflows for the most negative
|
|
2796
|
+
offset */
|
|
2797
|
+
ca_size_t neg = ( offset <= -parent->dim[ai] ) ? parent->dim[ai] : -offset;
|
|
2754
2798
|
if (neg >= parent->dim[ai]) {
|
|
2755
2799
|
diag_len = 0;
|
|
2756
2800
|
}
|
|
@@ -2761,6 +2805,9 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2761
2805
|
}
|
|
2762
2806
|
base_offset = neg * parent_byte_stride[ai];
|
|
2763
2807
|
}
|
|
2808
|
+
if (diag_len == 0) {
|
|
2809
|
+
base_offset = 0; /* an offset past the edge can overflow the product */
|
|
2810
|
+
}
|
|
2764
2811
|
|
|
2765
2812
|
/* build output: kept axes (in original order), then diagonal axis */
|
|
2766
2813
|
out_k = 0;
|
data/ext/ca_obj_string.c
CHANGED
|
@@ -76,7 +76,7 @@ const rb_data_type_t castring_data_type = {
|
|
|
76
76
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
int8_t CA_OBJ_STRING; /* non-static: read by the store path in carray_access.c */
|
|
80
80
|
static VALUE rb_cCAString;
|
|
81
81
|
|
|
82
82
|
/* ------------------------------------------------------------------- */
|
|
@@ -119,9 +119,6 @@ ca_string_setup (CAString *ca, CArray *parent)
|
|
|
119
119
|
ca->attach = 0;
|
|
120
120
|
ca->nosync = 0;
|
|
121
121
|
|
|
122
|
-
if ( ca_has_mask(parent) ) {
|
|
123
|
-
ca_create_mask((CArray *) ca);
|
|
124
|
-
}
|
|
125
122
|
|
|
126
123
|
if ( ca_is_scalar(parent) ) {
|
|
127
124
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
@@ -141,6 +138,7 @@ ca_string_new (CArray *parent)
|
|
|
141
138
|
ca_string_setup(NULL, parent);
|
|
142
139
|
ca = (CAString *) ca_array_alloc(CA_OBJ_STRING, parent->ndim);
|
|
143
140
|
ca_string_setup(ca, parent);
|
|
141
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
144
142
|
return ca;
|
|
145
143
|
}
|
|
146
144
|
|
|
@@ -200,6 +198,69 @@ ca_operation_function_t ca_string_func = {
|
|
|
200
198
|
|
|
201
199
|
/* ------------------------------------------------------------------- */
|
|
202
200
|
|
|
201
|
+
/* A CAString cell is a String; UNDEF (a masked cell) is no value. Refuse
|
|
202
|
+
anything else, naming what it is, so a cell of a CAString always answers
|
|
203
|
+
the String operations. */
|
|
204
|
+
NORETURN(static void ca_string_refuse_cell (VALUE v, const char *where));
|
|
205
|
+
|
|
206
|
+
static void
|
|
207
|
+
ca_string_refuse_cell (VALUE v, const char *where)
|
|
208
|
+
{
|
|
209
|
+
if ( NIL_P(v) ) {
|
|
210
|
+
rb_raise(rb_eTypeError,
|
|
211
|
+
"%s is nil, not a String (a CAString holds Strings; "
|
|
212
|
+
"UNDEF masks a cell)", where);
|
|
213
|
+
}
|
|
214
|
+
rb_raise(rb_eTypeError,
|
|
215
|
+
"%s is of class %s, not a String (a CAString holds Strings; "
|
|
216
|
+
"UNDEF masks a cell)", where, rb_obj_classname(v));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* Every cell of `parent` that is not masked is a String. */
|
|
220
|
+
static void
|
|
221
|
+
ca_string_check_cells (VALUE parent_val, CArray *parent)
|
|
222
|
+
{
|
|
223
|
+
ca_size_t i;
|
|
224
|
+
char where[64];
|
|
225
|
+
if ( ca_is_entity(parent) && parent->ptr ) {
|
|
226
|
+
VALUE *p = (VALUE *) parent->ptr;
|
|
227
|
+
boolean8_t *m = ( parent->mask && parent->mask->ptr )
|
|
228
|
+
? (boolean8_t *) parent->mask->ptr : NULL;
|
|
229
|
+
for (i = 0; i < parent->elements; i++) {
|
|
230
|
+
if ( m && m[i] ) continue;
|
|
231
|
+
if ( ! RB_TYPE_P(p[i], T_STRING) ) {
|
|
232
|
+
snprintf(where, sizeof(where), "cell %" PRId64, (int64_t) i);
|
|
233
|
+
ca_string_refuse_cell(p[i], where);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
volatile VALUE list =
|
|
239
|
+
rb_funcall(rb_funcall(parent_val, rb_intern("flatten"), 0),
|
|
240
|
+
rb_intern("to_a"), 0);
|
|
241
|
+
long n = RARRAY_LEN(list), j;
|
|
242
|
+
for (j = 0; j < n; j++) {
|
|
243
|
+
VALUE v = rb_ary_entry(list, j);
|
|
244
|
+
if ( v == CA_UNDEF ) continue;
|
|
245
|
+
if ( ! RB_TYPE_P(v, T_STRING) ) {
|
|
246
|
+
snprintf(where, sizeof(where), "cell %ld", j);
|
|
247
|
+
ca_string_refuse_cell(v, where);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* The write hook: a value stored into a CAString is a String. */
|
|
254
|
+
static VALUE
|
|
255
|
+
ca_string_element_to_storage (VALUE self, VALUE v)
|
|
256
|
+
{
|
|
257
|
+
(void) self;
|
|
258
|
+
if ( ! RB_TYPE_P(v, T_STRING) ) {
|
|
259
|
+
ca_string_refuse_cell(v, "a value stored into a CAString");
|
|
260
|
+
}
|
|
261
|
+
return v;
|
|
262
|
+
}
|
|
263
|
+
|
|
203
264
|
/* CAString.wrap(object_array) — zero-copy Face wrap of a CA_OBJECT array */
|
|
204
265
|
VALUE
|
|
205
266
|
rb_ca_string_wrap (VALUE parent_val)
|
|
@@ -211,6 +272,8 @@ rb_ca_string_wrap (VALUE parent_val)
|
|
|
211
272
|
rb_check_carray_object(parent_val);
|
|
212
273
|
TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
|
|
213
274
|
|
|
275
|
+
ca_string_setup(NULL, parent);
|
|
276
|
+
ca_string_check_cells(parent_val, parent);
|
|
214
277
|
ca = ca_string_new(parent);
|
|
215
278
|
obj = ca_wrap_struct(ca);
|
|
216
279
|
rb_ca_set_parent(obj, parent_val);
|
|
@@ -242,6 +305,7 @@ rb_ca_string_initialize_copy (VALUE self, VALUE other)
|
|
|
242
305
|
ca_array_pool_alloc(ca, CA_OBJ_STRING, cs->parent->ndim);
|
|
243
306
|
}
|
|
244
307
|
ca_string_setup(ca, cs->parent);
|
|
308
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
245
309
|
return self;
|
|
246
310
|
}
|
|
247
311
|
|
|
@@ -266,6 +330,9 @@ Init_ca_obj_string (void)
|
|
|
266
330
|
rb_ca_string_initialize_copy, 1);
|
|
267
331
|
rb_define_singleton_method(rb_cCAString, "wrap", rb_ca_string_wrap_method, 1);
|
|
268
332
|
|
|
333
|
+
ca_face_register_element_to_storage(CA_OBJ_STRING,
|
|
334
|
+
ca_string_element_to_storage);
|
|
335
|
+
|
|
269
336
|
/* A cell is the String itself, so the Face is the same over any parent:
|
|
270
337
|
CAStack / CAMeld / concatenate can carry it (unlike CAConstString, whose
|
|
271
338
|
cells point into one parent's buffer). */
|