carray 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +824 -0
- data/README.md +5 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +258 -4
- data/ext/ca_axis_group.c +368 -184
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +90 -41
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +960 -245
- data/ext/ca_kernel_iterator.h +352 -181
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +194 -42
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +5 -4
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +180 -50
- data/ext/ca_obj_face.c +428 -62
- data/ext/ca_obj_face.h +107 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +39 -26
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +235 -55
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +551 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +88 -75
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -123
- data/ext/ca_obj_stride.c +267 -35
- data/ext/ca_obj_string.c +25 -22
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +157 -29
- data/ext/ca_op_ipower.c +25 -13
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +385 -198
- data/ext/ca_sweep_engine.h +31 -23
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +90 -28
- data/ext/carray_access.c +487 -231
- data/ext/carray_address_basis.c +731 -0
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +49 -17
- data/ext/carray_call_cfunc.c +667 -511
- data/ext/carray_cast.c +1556 -247
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +84 -38
- data/ext/carray_core.c +591 -119
- data/ext/carray_count.c +148 -96
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +604 -291
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +400 -1
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +88 -66
- data/ext/carray_mask.c +705 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +263 -63
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1093 -363
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +582 -204
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +183 -70
- data/ext/carray_sort.c +235 -240
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +103 -118
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1349 -851
- data/ext/ruby_carray.c +17 -2
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +18 -0
- data/lib/carray/axis_group.rb +245 -20
- data/lib/carray/basics.rb +95 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +200 -54
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +244 -59
- data/lib/carray/categorical_iterator.rb +391 -757
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +177 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +590 -76
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +205 -35
- data/lib/carray/frame/group.rb +199 -40
- data/lib/carray/frame/io.rb +452 -60
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +54 -19
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +726 -56
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +71 -20
- data/lib/carray/iterator.rb +157 -2
- data/lib/carray/lazy.rb +54 -67
- data/lib/carray/mask_gap_fill.rb +66 -50
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +130 -6
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +235 -21
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +91 -0
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +52 -3
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +109 -40
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +9 -4
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +535 -105
- data/lib/carray/window_iterator.rb +259 -82
- data/lib/carray.rb +4 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +11 -4
- data/yard-stubs/carray_access.rb +6 -5
- data/yard-stubs/carray_broadcast.rb +2 -2
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -83
- data/yard-stubs/carray_count.rb +16 -2
- data/yard-stubs/carray_lazy.rb +210 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +1499 -4
- data/yard-stubs/carray_median_percentile.rb +26 -8
- data/yard-stubs/carray_order.rb +43 -82
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +11 -8
- data/yard-stubs/carray_sort.rb +50 -8
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -25837
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14593
- data/ext/carray_kernels_reduce_extreme.c +0 -16948
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32138
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/ca_obj_stride.c
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
---------------------------------------------------------------------------- */
|
|
21
21
|
|
|
22
22
|
#include "carray.h"
|
|
23
|
+
#include "carray_internal.h" /* ca_axis_integer */
|
|
23
24
|
#include "ca_iter_substrate.h"
|
|
24
25
|
#include "ca_obj_face.h" /* ca_is_face, used by the compose-fold walk */
|
|
25
26
|
|
|
@@ -104,13 +105,18 @@ ca_stride_setup (CAStride *ca, int8_t obj_type, CArray *parent,
|
|
|
104
105
|
if (ndim < 0 || ndim > CA_RANK_MAX) {
|
|
105
106
|
rb_raise(rb_eArgError, "invalid ndim %d", (int) ndim);
|
|
106
107
|
}
|
|
107
|
-
elements = 1;
|
|
108
108
|
for (i = 0; i < ndim; i++) {
|
|
109
109
|
if (dim[i] < 0) {
|
|
110
110
|
rb_raise(rb_eIndexError,
|
|
111
111
|
"invalid size for %i-th dimension (negative)", i);
|
|
112
112
|
}
|
|
113
|
-
|
|
113
|
+
}
|
|
114
|
+
elements = ca_shape_elements(ndim, dim, bytes);
|
|
115
|
+
|
|
116
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
117
|
+
run them before it allocates. */
|
|
118
|
+
if ( ca == NULL ) {
|
|
119
|
+
return 0;
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
ca->obj_type = obj_type;
|
|
@@ -151,7 +157,10 @@ ca_stride_new (int8_t obj_type, CArray *parent,
|
|
|
151
157
|
int8_t ndim, ca_size_t *dim,
|
|
152
158
|
ca_size_t *strides, ca_size_t base_offset)
|
|
153
159
|
{
|
|
154
|
-
CAStride *ca
|
|
160
|
+
CAStride *ca;
|
|
161
|
+
ca_stride_setup(NULL, obj_type, parent,
|
|
162
|
+
data_type, bytes, ndim, dim, strides, base_offset);
|
|
163
|
+
ca = (CAStride *) ca_array_alloc(obj_type, ndim);
|
|
155
164
|
ca_stride_setup(ca, obj_type, parent,
|
|
156
165
|
data_type, bytes, ndim, dim, strides, base_offset);
|
|
157
166
|
return ca;
|
|
@@ -292,6 +301,38 @@ ca_stride_compose_through (CAStride *leaf, CAStride *parent,
|
|
|
292
301
|
out_strides[k] = composed;
|
|
293
302
|
}
|
|
294
303
|
|
|
304
|
+
/* A leaf cell wider than the remainder of its first parent element
|
|
305
|
+
(CARefer reinterpreting two float64 as one complex128) covers several
|
|
306
|
+
consecutive parent elements, and the folded access reads the cell as
|
|
307
|
+
one run of bytes from out_base. That is only true when those parent
|
|
308
|
+
elements are adjacent in parent->parent's memory as well: every cell
|
|
309
|
+
must fit inside the parent's trailing row-major contiguous block.
|
|
310
|
+
Cell starts are flat0 + sum idx[k]*advance[k], so their residues
|
|
311
|
+
modulo the block size C step by g = gcd(C, advance...); every cell
|
|
312
|
+
fits when (flat0 mod g) + span <= g. */
|
|
313
|
+
if ( sub_byte + leaf->bytes > parent->bytes ) {
|
|
314
|
+
ca_size_t span = (sub_byte + leaf->bytes + parent->bytes - 1)
|
|
315
|
+
/ parent->bytes;
|
|
316
|
+
ca_size_t block = 1;
|
|
317
|
+
ca_size_t g, flat0 = leaf->base_offset / parent->bytes;
|
|
318
|
+
if ( parent->ndim > 0
|
|
319
|
+
&& parent->strides[parent->ndim - 1] == parent->bytes ) {
|
|
320
|
+
block = parent->dim[parent->ndim - 1];
|
|
321
|
+
for (m = parent->ndim - 2; m >= 0; m--) {
|
|
322
|
+
if ( parent->strides[m] != parent->strides[m + 1] * parent->dim[m + 1] )
|
|
323
|
+
break;
|
|
324
|
+
block *= parent->dim[m];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
g = block;
|
|
328
|
+
for (k = 0; k < leaf->ndim; k++) {
|
|
329
|
+
ca_size_t a = leaf->strides[k] / parent->bytes;
|
|
330
|
+
if ( a < 0 ) a = -a;
|
|
331
|
+
while ( a != 0 ) { ca_size_t r = g % a; g = a; a = r; }
|
|
332
|
+
}
|
|
333
|
+
if ( g == 0 || (flat0 % g) + span > g ) return 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
295
336
|
return 1;
|
|
296
337
|
}
|
|
297
338
|
|
|
@@ -512,19 +553,32 @@ ca_stride_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
|
512
553
|
ca_xfer_index(ca->parent, pidx, data, dir);
|
|
513
554
|
}
|
|
514
555
|
else {
|
|
515
|
-
|
|
516
|
-
|
|
556
|
+
/* Byte-mismatched reinterpret. The cell covers the parent elements
|
|
557
|
+
from off / pbytes through the one holding its last byte: one for a
|
|
558
|
+
narrower cell (CAField .real / .imag), several for a wider one
|
|
559
|
+
(CARefer reading two float64 as one complex128). Read all of
|
|
560
|
+
them; a store writes back all of them.
|
|
561
|
+
ALLOCV: the parent's fetch/store can raise (a CAObject parent runs
|
|
562
|
+
Ruby), and a raise must not leak the scratch. */
|
|
563
|
+
volatile VALUE holder;
|
|
564
|
+
ca_size_t addr = off / pbytes;
|
|
565
|
+
ca_size_t sub = off % pbytes;
|
|
566
|
+
ca_size_t span = (sub + ca->bytes + pbytes - 1) / pbytes;
|
|
567
|
+
ca_size_t i;
|
|
568
|
+
char *scratch = ALLOCV_N(char, holder, span * pbytes);
|
|
569
|
+
for (i = 0; i < span; i++) {
|
|
570
|
+
ca_fetch_addr(ca->parent, addr + i, scratch + i * pbytes);
|
|
571
|
+
}
|
|
517
572
|
if (dir == CA_XFER_GET) {
|
|
518
|
-
|
|
519
|
-
memcpy(data, scratch + (off % pbytes), ca->bytes);
|
|
573
|
+
memcpy(data, scratch + sub, ca->bytes);
|
|
520
574
|
}
|
|
521
575
|
else {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
576
|
+
memcpy(scratch + sub, data, ca->bytes);
|
|
577
|
+
for (i = 0; i < span; i++) {
|
|
578
|
+
ca_store_addr(ca->parent, addr + i, scratch + i * pbytes);
|
|
579
|
+
}
|
|
526
580
|
}
|
|
527
|
-
|
|
581
|
+
ALLOCV_END(holder);
|
|
528
582
|
}
|
|
529
583
|
}
|
|
530
584
|
}
|
|
@@ -656,6 +710,7 @@ static void
|
|
|
656
710
|
ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
657
711
|
ca_size_t *strides, void *data, int dir)
|
|
658
712
|
{
|
|
713
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
659
714
|
CAStride *ca = (CAStride *) ap;
|
|
660
715
|
CArray *root;
|
|
661
716
|
ca_size_t composed_strides[CA_RANK_MAX];
|
|
@@ -736,13 +791,45 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
736
791
|
}
|
|
737
792
|
}
|
|
738
793
|
|
|
794
|
+
/* A reshape over a 1-D cold root (ndim != root->ndim): the request has no
|
|
795
|
+
box in the root's single axis, but the root cells it touches lie in one
|
|
796
|
+
flat span. Ask the root for that span once and walk the request over
|
|
797
|
+
it, as xfer_all does for the whole view. A PUT reads the span first so
|
|
798
|
+
the cells between the requested ones go back unchanged. */
|
|
799
|
+
if (aligned && !root->ptr && ca_func[root->obj_type].xfer_stride
|
|
800
|
+
&& ca->bytes == root->bytes && root->ndim == 1
|
|
801
|
+
&& root_base % root->bytes == 0) {
|
|
802
|
+
ca_size_t span_lo = root_base;
|
|
803
|
+
ca_size_t span_hi = root_base + ca->bytes;
|
|
804
|
+
for (k = 0; k < ndim; k++) {
|
|
805
|
+
ca_size_t ext = (counts[k] - 1) * root_stride[k];
|
|
806
|
+
if ( root_stride[k] >= 0 ) span_hi += ext;
|
|
807
|
+
else span_lo += ext;
|
|
808
|
+
}
|
|
809
|
+
if ( span_lo >= 0 && span_hi <= root->elements * root->bytes ) {
|
|
810
|
+
volatile VALUE holder;
|
|
811
|
+
ca_size_t rlo = span_lo / root->bytes;
|
|
812
|
+
ca_size_t rcount = (span_hi - span_lo) / root->bytes;
|
|
813
|
+
ca_size_t rstep = root->bytes;
|
|
814
|
+
char *scratch = ALLOCV_N(char, holder, rcount * root->bytes);
|
|
815
|
+
ca_xfer_stride(root, &rlo, &rcount, &rstep, scratch, CA_XFER_GET);
|
|
816
|
+
ca_xfer_strided_walk(scratch + (root_base - span_lo), ca->bytes, ndim,
|
|
817
|
+
counts, root_stride, d, dir);
|
|
818
|
+
if ( dir == CA_XFER_PUT ) {
|
|
819
|
+
ca_xfer_stride(root, &rlo, &rcount, &rstep, scratch, CA_XFER_PUT);
|
|
820
|
+
}
|
|
821
|
+
ALLOCV_END(holder);
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
739
826
|
/* Per-cell fallback (correct, no whole-view attach): byte-mismatch
|
|
740
827
|
reinterpret (CAField), a region that is not a box over our axes (a
|
|
741
828
|
transposed request onto a degenerate axis, a flat index over several
|
|
742
|
-
axes), or a cold non-entity root the
|
|
743
|
-
region to (
|
|
744
|
-
|
|
745
|
-
|
|
829
|
+
axes), or a cold non-entity root the branches above could not hand a
|
|
830
|
+
region to (a reshape over a root of two or more axes, or one with no
|
|
831
|
+
region slot). ca_stride_func_xfer_index composes one hop and
|
|
832
|
+
delegates to the parent. */
|
|
746
833
|
if (!aligned || !root->ptr) {
|
|
747
834
|
ca_size_t idx[CA_RANK_MAX], doff = 0;
|
|
748
835
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
@@ -836,6 +923,59 @@ ca_stride_region_axes (CAStride *ca, ca_size_t base, int8_t ndim,
|
|
|
836
923
|
root in units root does not share, so there is no address to hand over
|
|
837
924
|
and the per-cell descent stands in. */
|
|
838
925
|
|
|
926
|
+
static void
|
|
927
|
+
ca_stride_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
|
|
928
|
+
{
|
|
929
|
+
CAStride *ca = (CAStride *) ap;
|
|
930
|
+
CArray *root;
|
|
931
|
+
ca_size_t composed_strides[CA_RANK_MAX];
|
|
932
|
+
ca_size_t composed_base;
|
|
933
|
+
ca_size_t rbytes;
|
|
934
|
+
ca_size_t *paddrs;
|
|
935
|
+
ca_size_t i;
|
|
936
|
+
int8_t k;
|
|
937
|
+
int all_aligned = 1;
|
|
938
|
+
volatile VALUE holder;
|
|
939
|
+
|
|
940
|
+
/* Addresses name cells one by one, so unlike fill_stride there is nothing
|
|
941
|
+
here that only the whole extent can express: translate each view address
|
|
942
|
+
into the root's and hand the list down in one call. Without this the
|
|
943
|
+
region is still the only thing touched -- ca_fill_addrs_default sees to
|
|
944
|
+
that -- but it costs the parent one call per cell, which is the whole
|
|
945
|
+
difference on a backing where a call is a request. */
|
|
946
|
+
if ( n == 0 ) {
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
951
|
+
rbytes = root->bytes;
|
|
952
|
+
|
|
953
|
+
if ( ca->bytes != rbytes ) {
|
|
954
|
+
ca_fill_addrs_default(ca, n, addrs, ptr);
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
959
|
+
for ( i = 0; i < n; i++ ) {
|
|
960
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
961
|
+
ca_size_t off = composed_base;
|
|
962
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
963
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
964
|
+
off += idx[k] * composed_strides[k];
|
|
965
|
+
}
|
|
966
|
+
if ( off % rbytes != 0 ) { all_aligned = 0; break; }
|
|
967
|
+
paddrs[i] = off / rbytes;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
if ( all_aligned ) {
|
|
971
|
+
ca_fill_addrs(root, n, paddrs, ptr);
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
ca_fill_addrs_default(ca, n, addrs, ptr);
|
|
975
|
+
}
|
|
976
|
+
ALLOCV_END(holder);
|
|
977
|
+
}
|
|
978
|
+
|
|
839
979
|
static void
|
|
840
980
|
ca_stride_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
841
981
|
ca_size_t *counts, ca_size_t *steps, void *ptr)
|
|
@@ -889,6 +1029,8 @@ ca_stride_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
|
889
1029
|
}
|
|
890
1030
|
|
|
891
1031
|
extern int ca_stride_is_contiguous (CAStride *ca); /* defined below; non-static for Tier A */
|
|
1032
|
+
static int ca_layout_is_contiguous (int8_t ndim, const ca_size_t *dim,
|
|
1033
|
+
const ca_size_t *strides, ca_size_t bytes);
|
|
892
1034
|
|
|
893
1035
|
/* Alias fast path:
|
|
894
1036
|
When the view's strides describe a contiguous row-major run, the
|
|
@@ -960,6 +1102,27 @@ ca_root_lends_no_memory (void *ap)
|
|
|
960
1102
|
return ca_func[root->obj_type].xfer_stride != NULL;
|
|
961
1103
|
}
|
|
962
1104
|
|
|
1105
|
+
/* The same question for the parent of a view that is not itself in the
|
|
1106
|
+
CAStride family (CAGrid, ...): whether the array its cells come from --
|
|
1107
|
+
the parent, or the root a CAStride parent folds to -- has no memory to
|
|
1108
|
+
lend. Like ca_root_lends_no_memory it asks only what those arrays are,
|
|
1109
|
+
so the lifecycle slots can rely on getting the same answer from attach
|
|
1110
|
+
to detach. */
|
|
1111
|
+
int
|
|
1112
|
+
ca_parent_lends_no_memory (void *ap)
|
|
1113
|
+
{
|
|
1114
|
+
CArray *parent = (CArray *) ap;
|
|
1115
|
+
|
|
1116
|
+
if ( ca_is_stride_family(parent) ) {
|
|
1117
|
+
CArray *root;
|
|
1118
|
+
ca_size_t cs[CA_RANK_MAX];
|
|
1119
|
+
ca_size_t base;
|
|
1120
|
+
ca_stride_compose_to_root((CAStride *) parent, &root, cs, &base);
|
|
1121
|
+
return ca_root_lends_no_memory(root);
|
|
1122
|
+
}
|
|
1123
|
+
return ca_root_lends_no_memory(parent);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
963
1126
|
/* ca_attach_is_alias asks the same question from carray_core.c: a view whose
|
|
964
1127
|
attach owns its buffer does not alias its parent, so writes through
|
|
965
1128
|
ca->ptr need a ca_sync and callers must not assume otherwise. */
|
|
@@ -979,7 +1142,16 @@ ca_stride_attach_aliases_root (CAStride *ca)
|
|
|
979
1142
|
return 1;
|
|
980
1143
|
}
|
|
981
1144
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
982
|
-
|
|
1145
|
+
/* The same test ca_stride_func_attach makes, and then the same question of
|
|
1146
|
+
the fold boundary. The leaf's own strides are in its parent's address
|
|
1147
|
+
space -- a block over a flip is contiguous there and not in the root --
|
|
1148
|
+
and a boundary that is itself a CAStride (a reshape over a transpose
|
|
1149
|
+
stops the fold) is one whose attach may build a buffer of its own, which
|
|
1150
|
+
this view would then alias without reaching the memory below it. */
|
|
1151
|
+
return !ca_root_lends_no_memory(root)
|
|
1152
|
+
&& ca_layout_is_contiguous(ca->ndim, ca->dim, composed_strides,
|
|
1153
|
+
ca->bytes)
|
|
1154
|
+
&& ca_attach_is_alias(root);
|
|
983
1155
|
}
|
|
984
1156
|
|
|
985
1157
|
static void
|
|
@@ -1003,6 +1175,15 @@ ca_stride_func_allocate (void *ap)
|
|
|
1003
1175
|
}
|
|
1004
1176
|
}
|
|
1005
1177
|
|
|
1178
|
+
/* Region request into the cold-root attach buffer; a lazy root can raise. */
|
|
1179
|
+
static VALUE
|
|
1180
|
+
ca_stride_cold_fill (VALUE arg)
|
|
1181
|
+
{
|
|
1182
|
+
void **args = (void **) arg;
|
|
1183
|
+
ca_copy_data((CArray *) args[0], (char *) args[1]);
|
|
1184
|
+
return Qnil;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1006
1187
|
static void
|
|
1007
1188
|
ca_stride_func_attach (void *ap)
|
|
1008
1189
|
{
|
|
@@ -1018,7 +1199,15 @@ ca_stride_func_attach (void *ap)
|
|
|
1018
1199
|
view with a live ptr is what makes the per-cell dispatchers bypass the
|
|
1019
1200
|
transfer slots. */
|
|
1020
1201
|
char *buf = xmalloc(ca_length(ca));
|
|
1021
|
-
|
|
1202
|
+
void *args[2];
|
|
1203
|
+
int tag = 0;
|
|
1204
|
+
args[0] = ca;
|
|
1205
|
+
args[1] = buf;
|
|
1206
|
+
rb_protect(ca_stride_cold_fill, (VALUE) args, &tag); /* root stays cold */
|
|
1207
|
+
if (tag) {
|
|
1208
|
+
xfree(buf);
|
|
1209
|
+
rb_jump_tag(tag);
|
|
1210
|
+
}
|
|
1022
1211
|
ca->ptr = buf;
|
|
1023
1212
|
return;
|
|
1024
1213
|
}
|
|
@@ -1254,6 +1443,34 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1254
1443
|
return;
|
|
1255
1444
|
}
|
|
1256
1445
|
|
|
1446
|
+
/* A request the bridges above could not express as a region goes to the
|
|
1447
|
+
root as the list of its cells. A write never makes a round trip of
|
|
1448
|
+
the whole root: a root that repeats its cells (CATile) would have the
|
|
1449
|
+
stale copies the caller never wrote land after the written ones, and a
|
|
1450
|
+
root that converts on the way would bring the unwritten cells back
|
|
1451
|
+
changed. A read does not make the root produce cells it was not asked
|
|
1452
|
+
for, unless it is asked for as many as it has. The root's addresses
|
|
1453
|
+
are whole elements here, as in the region hand-off above. */
|
|
1454
|
+
if ( ( dir == CA_XFER_PUT || ca->elements < root->elements )
|
|
1455
|
+
&& ca->bytes == root->bytes && composed_base % root->bytes == 0 ) {
|
|
1456
|
+
volatile VALUE holder;
|
|
1457
|
+
ca_size_t *addrs = ALLOCV_N(ca_size_t, holder, ca->elements);
|
|
1458
|
+
ca_size_t idx[CA_RANK_MAX], n = 0;
|
|
1459
|
+
int8_t k;
|
|
1460
|
+
for (k = 0; k < ca->ndim; k++) idx[k] = 0;
|
|
1461
|
+
while (1) {
|
|
1462
|
+
ca_size_t off = composed_base;
|
|
1463
|
+
for (k = 0; k < ca->ndim; k++) off += idx[k] * composed_strides[k];
|
|
1464
|
+
addrs[n++] = off / root->bytes;
|
|
1465
|
+
k = ca->ndim - 1;
|
|
1466
|
+
while (k >= 0) { if (++idx[k] < ca->dim[k]) break; idx[k] = 0; k--; }
|
|
1467
|
+
if (k < 0) break;
|
|
1468
|
+
}
|
|
1469
|
+
ca_xfer_addrs(root, n, addrs, ptr, dir);
|
|
1470
|
+
ALLOCV_END(holder);
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1257
1474
|
/* Cold root without an xfer_stride slot, or an ndim mismatch the bridges
|
|
1258
1475
|
above could not express: materialise the root into scratch via
|
|
1259
1476
|
ca_xfer_all and run the direct strided gather/scatter against that.
|
|
@@ -1272,11 +1489,14 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1272
1489
|
ca_stride_xfer_with_layout(ca, (dir == CA_XFER_PUT) ? 1 : 0,
|
|
1273
1490
|
root->ptr + composed_base, composed_strides);
|
|
1274
1491
|
ca->ptr = ptr0;
|
|
1492
|
+
/* Put root->ptr back before the PUT: the PUT can raise (a lazy
|
|
1493
|
+
backing's sync failing), and the scratch is gone once this frame
|
|
1494
|
+
is. */
|
|
1495
|
+
root->ptr = root_ptr_saved;
|
|
1275
1496
|
if ( dir == CA_XFER_PUT ) {
|
|
1276
1497
|
/* Push back scratch (modified by scatter) to root. */
|
|
1277
1498
|
ca_xfer_all(root, root_scratch, CA_XFER_PUT);
|
|
1278
1499
|
}
|
|
1279
|
-
root->ptr = root_ptr_saved;
|
|
1280
1500
|
ALLOCV_END(holder);
|
|
1281
1501
|
}
|
|
1282
1502
|
}
|
|
@@ -1483,6 +1703,7 @@ ca_operation_function_t ca_stride_func = {
|
|
|
1483
1703
|
sizeof(CAStride), /* struct_size: pool framework */
|
|
1484
1704
|
ca_stride_pool_bytes, /* pool_bytes */
|
|
1485
1705
|
ca_stride_pool_init, /* pool_init */
|
|
1706
|
+
.fill_addrs = ca_stride_func_fill_addrs,
|
|
1486
1707
|
.fill_stride = ca_stride_func_fill_stride,
|
|
1487
1708
|
};
|
|
1488
1709
|
|
|
@@ -1778,6 +1999,7 @@ rb_cs_initialize_copy (VALUE self, VALUE other)
|
|
|
1778
1999
|
{
|
|
1779
2000
|
CAStride *ca, *cs;
|
|
1780
2001
|
TypedData_Get_Struct(self, CAStride, &castride_data_type, ca);
|
|
2002
|
+
ca_check_uninitialized(ca);
|
|
1781
2003
|
TypedData_Get_Struct(other, CAStride, &castride_data_type, cs);
|
|
1782
2004
|
/* Pool framework: self was created by rb_cs_s_allocate (= TypedData_Make_Struct),
|
|
1783
2005
|
so ca->_pool is NULL. Wire up the pool before ca_stride_setup so the
|
|
@@ -1868,8 +2090,10 @@ rb_ca_as_strided (int argc, VALUE *argv, VALUE self)
|
|
|
1868
2090
|
base_offset = NUM2SIZE(roffset);
|
|
1869
2091
|
}
|
|
1870
2092
|
|
|
1871
|
-
|
|
1872
|
-
|
|
2093
|
+
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2094
|
+
ndim, shape, strides, base_offset);
|
|
2095
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2096
|
+
return obj;
|
|
1873
2097
|
}
|
|
1874
2098
|
|
|
1875
2099
|
/* sliding_windows(*window, step: nil) -- overlapping-window view over every
|
|
@@ -1980,8 +2204,10 @@ rb_ca_sliding_windows (int argc, VALUE *argv, VALUE self)
|
|
|
1980
2204
|
outstrides[ndim + i] = parent_byte_stride[i];
|
|
1981
2205
|
}
|
|
1982
2206
|
|
|
1983
|
-
|
|
1984
|
-
|
|
2207
|
+
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2208
|
+
(int8_t)(2 * ndim), outdim, outstrides, 0);
|
|
2209
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2210
|
+
return obj;
|
|
1985
2211
|
}
|
|
1986
2212
|
|
|
1987
2213
|
/* unfold(*window, step: nil) -- sliding_windows over the leading `S` axes
|
|
@@ -2102,8 +2328,10 @@ rb_ca_unfold (int argc, VALUE *argv, VALUE self)
|
|
|
2102
2328
|
outstrides[2 * nspatial + i] = parent_byte_stride[nspatial + i];
|
|
2103
2329
|
}
|
|
2104
2330
|
|
|
2105
|
-
|
|
2106
|
-
|
|
2331
|
+
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2332
|
+
(int8_t) outrank, outdim, outstrides, 0);
|
|
2333
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2334
|
+
return obj;
|
|
2107
2335
|
}
|
|
2108
2336
|
|
|
2109
2337
|
/* block_view(*block) -- non-overlapping tile view. Parent [d0..dN-1]
|
|
@@ -2187,8 +2415,12 @@ rb_ca_block_view (int argc, VALUE *argv, VALUE self)
|
|
|
2187
2415
|
outstrides[ndim + i] = parent_byte_stride[i];
|
|
2188
2416
|
}
|
|
2189
2417
|
|
|
2190
|
-
|
|
2191
|
-
|
|
2418
|
+
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2419
|
+
(int8_t)(2 * ndim), outdim, outstrides, 0);
|
|
2420
|
+
/* The Face stays on top, as for every view: a tile reduction over a
|
|
2421
|
+
bare block_view compared the Face's surface bytes. */
|
|
2422
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2423
|
+
return obj;
|
|
2192
2424
|
}
|
|
2193
2425
|
|
|
2194
2426
|
/* defined in ca_obj_transpose.c */
|
|
@@ -2229,7 +2461,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2229
2461
|
(int) n_iter, (int) ndim);
|
|
2230
2462
|
}
|
|
2231
2463
|
for (i = 0; i < n_iter; i++) {
|
|
2232
|
-
iter_axes[i] =
|
|
2464
|
+
iter_axes[i] = ca_axis_integer(RARRAY_AREF(aary, i), NULL);
|
|
2233
2465
|
}
|
|
2234
2466
|
}
|
|
2235
2467
|
else if (nargs >= 1) {
|
|
@@ -2240,7 +2472,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2240
2472
|
}
|
|
2241
2473
|
n_iter = (int8_t) nargs;
|
|
2242
2474
|
for (i = 0; i < n_iter; i++) {
|
|
2243
|
-
iter_axes[i] =
|
|
2475
|
+
iter_axes[i] = ca_axis_integer(RARRAY_AREF(rposary, i), NULL);
|
|
2244
2476
|
}
|
|
2245
2477
|
}
|
|
2246
2478
|
else {
|
|
@@ -2368,8 +2600,8 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2368
2600
|
|
|
2369
2601
|
for (i = 0; i < ndim; i++) flip[i] = 0;
|
|
2370
2602
|
|
|
2371
|
-
if (nargs == 0) {
|
|
2372
|
-
/* No args: flip every axis. */
|
|
2603
|
+
if (nargs == 0 || (nargs == 1 && NIL_P(RARRAY_AREF(rposary, 0)))) {
|
|
2604
|
+
/* No args, or a lone nil: flip every axis. */
|
|
2373
2605
|
for (i = 0; i < ndim; i++) flip[i] = 1;
|
|
2374
2606
|
n_axes = ndim;
|
|
2375
2607
|
}
|
|
@@ -2383,7 +2615,7 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2383
2615
|
(int) n_axes, (int) ndim);
|
|
2384
2616
|
}
|
|
2385
2617
|
for (i = 0; i < n_axes; i++) {
|
|
2386
|
-
axes[i] =
|
|
2618
|
+
axes[i] = ca_axis_integer(RARRAY_AREF(aary, i), NULL);
|
|
2387
2619
|
}
|
|
2388
2620
|
}
|
|
2389
2621
|
else {
|
|
@@ -2394,7 +2626,7 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2394
2626
|
}
|
|
2395
2627
|
n_axes = (int8_t) nargs;
|
|
2396
2628
|
for (i = 0; i < n_axes; i++) {
|
|
2397
|
-
axes[i] =
|
|
2629
|
+
axes[i] = ca_axis_integer(RARRAY_AREF(rposary, i), NULL);
|
|
2398
2630
|
}
|
|
2399
2631
|
}
|
|
2400
2632
|
|
|
@@ -2479,8 +2711,8 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2479
2711
|
rb_raise(rb_eArgError,
|
|
2480
2712
|
"diagonal: axis: must be an Array of 2 integers");
|
|
2481
2713
|
}
|
|
2482
|
-
ai =
|
|
2483
|
-
aj =
|
|
2714
|
+
ai = ca_axis_integer(RARRAY_AREF(raxis, 0), NULL);
|
|
2715
|
+
aj = ca_axis_integer(RARRAY_AREF(raxis, 1), NULL);
|
|
2484
2716
|
if (ai < 0) ai += ndim;
|
|
2485
2717
|
if (aj < 0) aj += ndim;
|
|
2486
2718
|
if (ai < 0 || ai >= ndim) {
|
data/ext/ca_obj_string.c
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
Surface data_type is CA_OBJECT (== storage): unlike the NonNumeric Faces
|
|
13
13
|
(CATime etc.) there is no CA_FIXLEN gate. Per-cell fetch returns
|
|
14
|
-
the stored String VALUE directly (no
|
|
14
|
+
the stored String VALUE directly (no storage_to_element decode). Numeric
|
|
15
15
|
dispatch lands on the :object kernels, so String-meaningful ops (+, sort
|
|
16
16
|
via <=>) work and nonsensical ones raise at the Ruby method call.
|
|
17
17
|
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
--------------------------------------------------------------------------- */
|
|
21
21
|
|
|
22
22
|
#include "carray.h"
|
|
23
|
+
#include "carray_internal.h"
|
|
23
24
|
#include "ca_obj_face.h"
|
|
24
25
|
|
|
25
26
|
typedef struct {
|
|
@@ -88,12 +89,22 @@ ca_string_setup (CAString *ca, CArray *parent)
|
|
|
88
89
|
"CAString requires object storage (parent.data_type != CA_OBJECT)");
|
|
89
90
|
}
|
|
90
91
|
|
|
92
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
93
|
+
run them before it allocates. */
|
|
94
|
+
if ( ca == NULL ) {
|
|
95
|
+
return 0;
|
|
96
|
+
}
|
|
97
|
+
|
|
91
98
|
ca->obj_type = CA_OBJ_STRING;
|
|
92
99
|
ca->data_type = CA_OBJECT;
|
|
93
|
-
/* ORDERABLE
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
/* ORDERABLE + COMPARABLE, and both hold by construction: a storage cell
|
|
101
|
+
IS the Ruby String the surface shows, so storage order is surface
|
|
102
|
+
order and an external String compares against storage directly, with
|
|
103
|
+
nothing to reconcile. (A unit-bearing Face like CATime is the case
|
|
104
|
+
that has to stop at ORDERABLE; this one carries no unit.) */
|
|
105
|
+
ca->flags = CA_FLAG_IS_FACE
|
|
106
|
+
| CA_FLAG_FACE_ORDERABLE_STORAGE
|
|
107
|
+
| CA_FLAG_FACE_COMPARABLE_STORAGE;
|
|
97
108
|
ca->ndim = parent->ndim;
|
|
98
109
|
ca->bytes = sizeof(VALUE);
|
|
99
110
|
ca->elements = parent->elements;
|
|
@@ -126,7 +137,9 @@ ca_string_setup (CAString *ca, CArray *parent)
|
|
|
126
137
|
CAString *
|
|
127
138
|
ca_string_new (CArray *parent)
|
|
128
139
|
{
|
|
129
|
-
CAString *ca
|
|
140
|
+
CAString *ca;
|
|
141
|
+
ca_string_setup(NULL, parent);
|
|
142
|
+
ca = (CAString *) ca_array_alloc(CA_OBJ_STRING, parent->ndim);
|
|
130
143
|
ca_string_setup(ca, parent);
|
|
131
144
|
return ca;
|
|
132
145
|
}
|
|
@@ -165,18 +178,6 @@ ca_string_func_allocate (void *ap)
|
|
|
165
178
|
ca->ptr = ca->parent->ptr;
|
|
166
179
|
}
|
|
167
180
|
|
|
168
|
-
static void
|
|
169
|
-
ca_string_func_create_mask (void *ap)
|
|
170
|
-
{
|
|
171
|
-
CAString *ca = (CAString *) ap;
|
|
172
|
-
ca_update_mask(ca->parent);
|
|
173
|
-
if ( ! ca->parent->mask ) {
|
|
174
|
-
ca_create_mask(ca->parent);
|
|
175
|
-
}
|
|
176
|
-
ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
|
|
177
|
-
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
181
|
ca_operation_function_t ca_string_func = {
|
|
181
182
|
-1, /* CA_OBJ_STRING — filled by ca_install_obj_type */
|
|
182
183
|
CA_VIEW_ARRAY,
|
|
@@ -187,7 +188,7 @@ ca_operation_function_t ca_string_func = {
|
|
|
187
188
|
ca_face_sync,
|
|
188
189
|
ca_face_detach,
|
|
189
190
|
ca_face_fill_data,
|
|
190
|
-
|
|
191
|
+
ca_view_func_create_mask,
|
|
191
192
|
ca_face_xfer_index,
|
|
192
193
|
ca_face_xfer_addrs,
|
|
193
194
|
NULL, /* fold_stride: identity Face is not foldable */
|
|
@@ -235,6 +236,7 @@ rb_ca_string_initialize_copy (VALUE self, VALUE other)
|
|
|
235
236
|
{
|
|
236
237
|
CAString *ca, *cs;
|
|
237
238
|
TypedData_Get_Struct(self, CAString, &castring_data_type, ca);
|
|
239
|
+
ca_check_uninitialized(ca);
|
|
238
240
|
TypedData_Get_Struct(other, CAString, &castring_data_type, cs);
|
|
239
241
|
if ( ca_func[CA_OBJ_STRING].pool_init ) {
|
|
240
242
|
ca_array_pool_alloc(ca, CA_OBJ_STRING, cs->parent->ndim);
|
|
@@ -264,7 +266,8 @@ Init_ca_obj_string (void)
|
|
|
264
266
|
rb_ca_string_initialize_copy, 1);
|
|
265
267
|
rb_define_singleton_method(rb_cCAString, "wrap", rb_ca_string_wrap_method, 1);
|
|
266
268
|
|
|
267
|
-
/*
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
/* A cell is the String itself, so the Face is the same over any parent:
|
|
270
|
+
CAStack / CAMeld / concatenate can carry it (unlike CAConstString, whose
|
|
271
|
+
cells point into one parent's buffer). */
|
|
272
|
+
ca_face_register_state_portable(CA_OBJ_STRING, 1);
|
|
270
273
|
}
|