carray 3.0.0 → 3.0.2
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/.yardopts +2 -1
- data/CHANGELOG.md +845 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +33 -33
- data/carray.gemspec +12 -8
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +256 -114
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +121 -67
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +386 -74
- data/ext/ca_kernel_iterator.h +145 -45
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +88 -27
- data/ext/ca_obj_face.c +104 -0
- data/ext/ca_obj_face.h +48 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +21 -6
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +125 -22
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +107 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +178 -24
- data/ext/ca_obj_string.c +11 -5
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +94 -19
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +1 -5
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +362 -155
- data/ext/ca_sweep_engine.h +39 -9
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +148 -132
- data/ext/carray_access.c +83 -49
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +102 -9
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +2010 -335
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +184 -72
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +67 -32
- data/ext/carray_core.c +140 -13
- data/ext/carray_count.c +10 -11
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +72 -51
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +36 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +256 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +324 -54
- data/ext/carray_kernels_reduce_extreme.c +605 -58
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +5 -4
- data/ext/carray_kernels_search.c +187 -106
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +29 -13
- data/ext/carray_median_percentile.c +56 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +50 -53
- data/ext/carray_order.c +1 -1
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +391 -47
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +22 -24
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +323 -145
- data/ext/mkkernel.rb +651 -129
- data/ext/ruby_carray.c +28 -17
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +14 -1
- data/lib/carray/axis_group.rb +84 -7
- data/lib/carray/basics.rb +63 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +111 -25
- data/lib/carray/categorical.rb +154 -37
- data/lib/carray/categorical_iterator.rb +300 -151
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +61 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +21 -1
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +85 -21
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +224 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +32 -12
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +43 -16
- data/lib/carray/iterator.rb +147 -3
- data/lib/carray/lazy.rb +88 -73
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/is_in.rb +25 -14
- data/lib/carray/methods/locate_addr.rb +81 -3
- data/lib/carray/methods/mask_duplicates.rb +36 -2
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +23 -2
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +44 -4
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +77 -19
- data/lib/carray/string_operation_extension.rb +10 -6
- data/lib/carray/time.rb +906 -491
- data/lib/carray/window_iterator.rb +421 -27
- data/lib/carray.rb +7 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +68 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +57 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +34 -0
- data/yard-stubs/carray_count.rb +84 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +228 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +1615 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +103 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +252 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +59 -0
- data/yard-stubs/carray_sort.rb +165 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +67 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/ca_obj_refer.c
CHANGED
|
@@ -454,7 +454,7 @@ rb_ca_refer (int argc, VALUE *argv, VALUE self)
|
|
|
454
454
|
return obj;
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
|
-
|
|
457
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
458
458
|
return obj;
|
|
459
459
|
}
|
|
460
460
|
|
|
@@ -482,7 +482,31 @@ rb_ca_refer_new (VALUE self,
|
|
|
482
482
|
rb_set_options(ropt, "bytes,offset", SIZE2NUM(bytes), SIZE2NUM(offset));
|
|
483
483
|
rb_ary_store(list, 2, ropt);
|
|
484
484
|
|
|
485
|
-
|
|
485
|
+
{
|
|
486
|
+
volatile VALUE obj = rb_ca_refer(3, (VALUE *) RARRAY_CONST_PTR(list), self);
|
|
487
|
+
CArray *co;
|
|
488
|
+
|
|
489
|
+
/* CAREFUL: this is the internal builder -- some fifteen call sites want
|
|
490
|
+
the refer itself, not a wrapper on top of it. The public `refer` it
|
|
491
|
+
delegates to lifts a CALazyMarker, so strip that here.
|
|
492
|
+
|
|
493
|
+
Two things go wrong otherwise. rb_ca_value_array strips the mask off
|
|
494
|
+
what it gets back and marks the level it is handed; with a marker in
|
|
495
|
+
the way the refer underneath keeps its mask and never gets
|
|
496
|
+
CA_FLAG_VALUE_ARRAY, so the values read back as UNDEF. And builders
|
|
497
|
+
that stack further views on the result -- fancy indexing goes refer,
|
|
498
|
+
grid, refer -- end up with a marker buried in the middle of the
|
|
499
|
+
chain, which is the redundant-middle-wrapper that CAFace.md section
|
|
500
|
+
8.3 exists to prevent.
|
|
501
|
+
|
|
502
|
+
Faces stay lifted: rb_ca_value_array depends on that and says so
|
|
503
|
+
where it marks the storage level. */
|
|
504
|
+
TypedData_Get_Struct(obj, CArray, &carray_data_type, co);
|
|
505
|
+
if ( ca_is_lazy_marker(co) ) {
|
|
506
|
+
obj = rb_ca_parent(obj);
|
|
507
|
+
}
|
|
508
|
+
return obj;
|
|
509
|
+
}
|
|
486
510
|
}
|
|
487
511
|
|
|
488
512
|
/* CArray#reshape(*newdim) — returns a view of self with the new
|
|
@@ -605,7 +629,7 @@ rb_ca_reshape (int argc, VALUE *argv, VALUE self)
|
|
|
605
629
|
out_strides, out_base);
|
|
606
630
|
obj = ca_wrap_struct(cs);
|
|
607
631
|
rb_ca_set_parent(obj, self);
|
|
608
|
-
|
|
632
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
609
633
|
return obj;
|
|
610
634
|
}
|
|
611
635
|
}
|
|
@@ -614,7 +638,7 @@ rb_ca_reshape (int argc, VALUE *argv, VALUE self)
|
|
|
614
638
|
new_dim, ca->bytes, 0);
|
|
615
639
|
obj = ca_wrap_struct(cr);
|
|
616
640
|
rb_ca_set_parent(obj, self);
|
|
617
|
-
|
|
641
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
618
642
|
return obj;
|
|
619
643
|
}
|
|
620
644
|
|
|
@@ -642,7 +666,7 @@ rb_ca_flatten (VALUE self)
|
|
|
642
666
|
1, dim, out_strides, out_base);
|
|
643
667
|
obj = ca_wrap_struct(cs);
|
|
644
668
|
rb_ca_set_parent(obj, self);
|
|
645
|
-
|
|
669
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
646
670
|
return obj;
|
|
647
671
|
}
|
|
648
672
|
}
|
|
@@ -650,7 +674,7 @@ rb_ca_flatten (VALUE self)
|
|
|
650
674
|
cr = ca_refer_new(ca, ca->data_type, 1, dim, ca->bytes, 0);
|
|
651
675
|
obj = ca_wrap_struct(cr);
|
|
652
676
|
rb_ca_set_parent(obj, self);
|
|
653
|
-
|
|
677
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
654
678
|
return obj;
|
|
655
679
|
}
|
|
656
680
|
|
data/ext/ca_obj_roll.c
CHANGED
|
@@ -232,10 +232,18 @@ ca_roll_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
232
232
|
s = ca->bytes;
|
|
233
233
|
for (k = ndim - 1; k >= 0; k--) { dstride[k] = s; s *= counts[k]; }
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
235
|
+
/* The request is over the view's addresses, so a transposed / flat request
|
|
236
|
+
is legal and must not be composed axis-by-axis; see
|
|
237
|
+
ca_xfer_stride_request_is_axis_box (carray.h). */
|
|
238
|
+
if ( ! ca_xfer_stride_request_is_axis_box(ca, starts, counts, strides) ) {
|
|
239
|
+
structural = 0;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
for (k = 0; k < ndim; k++) {
|
|
243
|
+
if (strides[k] % rnative[k] != 0 || strides[k] / rnative[k] != 1) {
|
|
244
|
+
structural = 0;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
239
247
|
}
|
|
240
248
|
}
|
|
241
249
|
|
|
@@ -529,7 +537,7 @@ rb_ca_roll (int argc, VALUE *argv, VALUE self)
|
|
|
529
537
|
}
|
|
530
538
|
{
|
|
531
539
|
VALUE obj = rb_ca_roll_new(self, shift);
|
|
532
|
-
|
|
540
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
533
541
|
return obj;
|
|
534
542
|
}
|
|
535
543
|
}
|
data/ext/ca_obj_select.c
CHANGED
|
@@ -83,22 +83,57 @@ VALUE rb_cCASelectMask;
|
|
|
83
83
|
|
|
84
84
|
/* ------------------------------------------------------------------- */
|
|
85
85
|
|
|
86
|
-
/*
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
/* Owned snapshot of the selector: masked selector cells become false.
|
|
87
|
+
After construction, mutating the caller's live selector does not affect
|
|
88
|
+
the view. Reading the selector can raise (a lazy boolean view), so the
|
|
89
|
+
snapshot is taken before the view struct is allocated, and a snapshot
|
|
90
|
+
whose fill raises is freed on the way out. */
|
|
91
|
+
static VALUE
|
|
92
|
+
ca_select_snapshot_masked (VALUE arg)
|
|
92
93
|
{
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
CArray **pair = (CArray **) arg;
|
|
95
|
+
CArray *select = pair[0], *snap = pair[1];
|
|
96
|
+
boolean8_t *p, *q, *m;
|
|
95
97
|
ca_size_t i;
|
|
98
|
+
ca_attach(select);
|
|
99
|
+
q = (boolean8_t *) snap->ptr;
|
|
100
|
+
p = (boolean8_t *) select->ptr;
|
|
101
|
+
m = (boolean8_t *) select->mask->ptr;
|
|
102
|
+
for (i = 0; i < select->elements; i++) {
|
|
103
|
+
*q = ( *m ) ? 0 : *p;
|
|
104
|
+
q++; p++; m++;
|
|
105
|
+
}
|
|
106
|
+
ca_detach(select);
|
|
107
|
+
return Qnil;
|
|
108
|
+
}
|
|
96
109
|
|
|
110
|
+
static CArray *
|
|
111
|
+
ca_select_snapshot (CArray *select)
|
|
112
|
+
{
|
|
97
113
|
if ( ! ca_is_boolean_type(select) ) {
|
|
98
114
|
rb_raise(rb_eRuntimeError,
|
|
99
115
|
"selection array for CASelect should be have "
|
|
100
116
|
"the data_type of CA_BOOLEAN");
|
|
101
117
|
}
|
|
118
|
+
if ( ca_has_mask(select) ) {
|
|
119
|
+
CArray *pair[2];
|
|
120
|
+
pair[0] = select;
|
|
121
|
+
pair[1] = ca_template(select);
|
|
122
|
+
ca_fill_or_free(pair[1], ca_select_snapshot_masked, (VALUE) pair);
|
|
123
|
+
return pair[1];
|
|
124
|
+
}
|
|
125
|
+
return ca_copy(select);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Set up the view over `parent` from an owned selector snapshot (see
|
|
129
|
+
ca_select_snapshot) and pre-compute ca->indices (TRUE positions in flat
|
|
130
|
+
parent order). Does not raise. */
|
|
131
|
+
static int
|
|
132
|
+
ca_select_setup (CASelect *ca, CArray *parent, CArray *snapshot)
|
|
133
|
+
{
|
|
134
|
+
int8_t data_type;
|
|
135
|
+
ca_size_t bytes;
|
|
136
|
+
ca_size_t i;
|
|
102
137
|
|
|
103
138
|
data_type = parent->data_type;
|
|
104
139
|
bytes = parent->bytes;
|
|
@@ -114,26 +149,7 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
114
149
|
ca->attach = 0;
|
|
115
150
|
ca->nosync = 0;
|
|
116
151
|
ca->indices = NULL;
|
|
117
|
-
|
|
118
|
-
/* The `share` argument is preserved for source compatibility but
|
|
119
|
-
no longer toggles a live-reference path; both paths copy.
|
|
120
|
-
Masked selector cells become false in the snapshot. */
|
|
121
|
-
(void) share;
|
|
122
|
-
if ( ca_has_mask(select) ) {
|
|
123
|
-
boolean8_t *p, *q, *m;
|
|
124
|
-
ca->select = ca_template(select);
|
|
125
|
-
ca_attach(select);
|
|
126
|
-
q = (boolean8_t *) ca->select->ptr;
|
|
127
|
-
p = (boolean8_t *) select->ptr;
|
|
128
|
-
m = (boolean8_t *) select->mask->ptr;
|
|
129
|
-
for (i = 0; i < select->elements; i++) {
|
|
130
|
-
*q = ( *m ) ? 0 : *p;
|
|
131
|
-
q++; p++; m++;
|
|
132
|
-
}
|
|
133
|
-
ca_detach(select);
|
|
134
|
-
} else {
|
|
135
|
-
ca->select = ca_copy(select);
|
|
136
|
-
}
|
|
152
|
+
ca->select = snapshot;
|
|
137
153
|
|
|
138
154
|
/* Count TRUE positions and snapshot them into ca->indices. */
|
|
139
155
|
{
|
|
@@ -181,7 +197,7 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
181
197
|
ca->dim = &(ca->_dim);
|
|
182
198
|
ca->dim[0] = ca->elements;
|
|
183
199
|
|
|
184
|
-
if ( ca_is_scalar(
|
|
200
|
+
if ( ca_is_scalar(snapshot) ) {
|
|
185
201
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
186
202
|
}
|
|
187
203
|
|
|
@@ -191,8 +207,9 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
191
207
|
CArray *
|
|
192
208
|
ca_select_new (CArray *parent, CArray *select)
|
|
193
209
|
{
|
|
210
|
+
CArray *snapshot = ca_select_snapshot(select);
|
|
194
211
|
CASelect *ca = ALLOC(CASelect);
|
|
195
|
-
ca_select_setup(ca, parent,
|
|
212
|
+
ca_select_setup(ca, parent, snapshot);
|
|
196
213
|
return (CArray*) ca;
|
|
197
214
|
}
|
|
198
215
|
|
|
@@ -202,9 +219,7 @@ ca_select_new (CArray *parent, CArray *select)
|
|
|
202
219
|
CArray *
|
|
203
220
|
ca_select_new_share (CArray *parent, CArray *select)
|
|
204
221
|
{
|
|
205
|
-
|
|
206
|
-
ca_select_setup(ca, parent, select, 1);
|
|
207
|
-
return (CArray*) ca;
|
|
222
|
+
return ca_select_new(parent, select);
|
|
208
223
|
}
|
|
209
224
|
|
|
210
225
|
static void
|
|
@@ -613,7 +628,7 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
|
|
|
613
628
|
|
|
614
629
|
/* Re-snapshot from the source's selector copy so the two views
|
|
615
630
|
end up with independent indices buffers. */
|
|
616
|
-
ca_select_setup(ca, cs->parent, cs->select
|
|
631
|
+
ca_select_setup(ca, cs->parent, ca_select_snapshot(cs->select));
|
|
617
632
|
|
|
618
633
|
return self;
|
|
619
634
|
}
|
data/ext/ca_obj_select_axis.c
CHANGED
|
@@ -571,9 +571,17 @@ ca_select_axis_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
571
571
|
s = ca->bytes;
|
|
572
572
|
for (k = ndim - 1; k >= 0; k--) { dstride[k] = s; s *= counts[k]; }
|
|
573
573
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
574
|
+
/* The request is over the view's addresses, so a transposed / flat request
|
|
575
|
+
is legal and must not be composed axis-by-axis; see
|
|
576
|
+
ca_xfer_stride_request_is_axis_box (carray.h). */
|
|
577
|
+
if ( ! ca_xfer_stride_request_is_axis_box(ca, starts, counts, strides) ) {
|
|
578
|
+
aligned = 0;
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
for (k = 0; k < ndim; k++) {
|
|
582
|
+
if (strides[k] % cnative[k] != 0) { aligned = 0; break; }
|
|
583
|
+
src_step[k] = strides[k] / cnative[k];
|
|
584
|
+
}
|
|
577
585
|
}
|
|
578
586
|
|
|
579
587
|
if (!aligned) {
|
|
@@ -925,7 +933,7 @@ rb_ca_select_axis_s_new_debug (VALUE klass, VALUE rparent, VALUE rindirect,
|
|
|
925
933
|
obj = TypedData_Make_Struct(klass, CASelectAxis, &caselectaxis_data_type, ca);
|
|
926
934
|
ca_select_axis_setup(ca, parent, indirect_axis, selector,
|
|
927
935
|
ap_start_buf, ap_count_buf, ap_step_buf);
|
|
928
|
-
|
|
936
|
+
rb_ca_set_parent(obj, rparent);
|
|
929
937
|
rb_ivar_set(obj, rb_intern("_selector"), rselector);
|
|
930
938
|
return obj;
|
|
931
939
|
}
|
|
@@ -1066,8 +1074,10 @@ rb_ca_select_axis (int argc, VALUE *argv, VALUE self)
|
|
|
1066
1074
|
ca_select_axis_setup(ca, parent, indirect_axis, selector,
|
|
1067
1075
|
ap_start, ap_count, ap_step);
|
|
1068
1076
|
|
|
1069
|
-
/* Keep Ruby objects alive (parent and selector references).
|
|
1070
|
-
|
|
1077
|
+
/* Keep Ruby objects alive (parent and selector references). The parent
|
|
1078
|
+
goes through rb_ca_set_parent so #parent, #root_array and #ancestors
|
|
1079
|
+
read the same link here as they do through every other view. */
|
|
1080
|
+
rb_ca_set_parent(obj, self);
|
|
1071
1081
|
rb_ivar_set(obj, rb_intern("_selector"), rselector_keep);
|
|
1072
1082
|
return obj;
|
|
1073
1083
|
}
|
data/ext/ca_obj_shift.c
CHANGED
|
@@ -264,7 +264,7 @@ rb_ca_shift_new (VALUE cary, ca_size_t *shift, char *fill, int8_t *roll,
|
|
|
264
264
|
VALUE
|
|
265
265
|
rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
266
266
|
{
|
|
267
|
-
volatile VALUE obj, ropt, rfval =
|
|
267
|
+
volatile VALUE obj, ropt, rfval = CA_UNSPECIFIED, rroll = Qnil, rcs;
|
|
268
268
|
CArray *ca;
|
|
269
269
|
CScalar *cs;
|
|
270
270
|
ca_size_t shift[CA_RANK_MAX];
|
|
@@ -301,7 +301,7 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
301
301
|
"use fill_value: kwarg (e.g. shift(1, fill_value: -2))");
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
if ( rfval ==
|
|
304
|
+
if ( rfval == CA_UNSPECIFIED ) {
|
|
305
305
|
/* Default fill value = 0 (or INT2NUM(0) for OBJECT type) */
|
|
306
306
|
rcs = rb_cscalar_new(ca->data_type, ca->bytes, NULL);
|
|
307
307
|
TypedData_Get_Struct(rcs, CScalar, &cscalar_data_type, cs);
|
|
@@ -343,7 +343,7 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
343
343
|
|
|
344
344
|
obj = rb_ca_shift_new(self, shift, fill, roll, fill_mask);
|
|
345
345
|
|
|
346
|
-
|
|
346
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
347
347
|
return obj;
|
|
348
348
|
}
|
|
349
349
|
|
data/ext/ca_obj_stack.c
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
---------------------------------------------------------------------------- */
|
|
19
19
|
|
|
20
20
|
#include "carray.h"
|
|
21
|
+
#include "carray_internal.h" /* ca_attach_all */
|
|
21
22
|
#include "ca_composite_dispatch.h"
|
|
22
23
|
#include "ca_obj_face.h"
|
|
23
24
|
|
|
@@ -740,10 +741,7 @@ static void
|
|
|
740
741
|
ca_stack_func_allocate (void *ap)
|
|
741
742
|
{
|
|
742
743
|
CAStack *ca = (CAStack *) ap;
|
|
743
|
-
|
|
744
|
-
for ( k = 0; k < ca->n_parents; k++ ) {
|
|
745
|
-
ca_attach(ca->parents[k]);
|
|
746
|
-
}
|
|
744
|
+
ca_attach_all(ca->parents, ca->n_parents);
|
|
747
745
|
ca->ptr = xmalloc(ca_length(ca));
|
|
748
746
|
}
|
|
749
747
|
|
|
@@ -751,10 +749,7 @@ static void
|
|
|
751
749
|
ca_stack_func_attach (void *ap)
|
|
752
750
|
{
|
|
753
751
|
CAStack *ca = (CAStack *) ap;
|
|
754
|
-
|
|
755
|
-
for ( k = 0; k < ca->n_parents; k++ ) {
|
|
756
|
-
ca_attach(ca->parents[k]);
|
|
757
|
-
}
|
|
752
|
+
ca_attach_all(ca->parents, ca->n_parents);
|
|
758
753
|
ca->ptr = xmalloc(ca_length(ca));
|
|
759
754
|
ca_stack_func_xfer_all(ca, ca->ptr, CA_XFER_GET);
|
|
760
755
|
}
|
data/ext/ca_obj_stride.c
CHANGED
|
@@ -192,6 +192,19 @@ void ca_xfer_stride_tiled_transpose_2d (char *src_base, ca_size_t bytes,
|
|
|
192
192
|
ca_size_t *counts, ca_size_t *strides,
|
|
193
193
|
char *data, int dir);
|
|
194
194
|
|
|
195
|
+
/* Public form of the family test the fold walk below uses inline. The
|
|
196
|
+
family is defined by the operation table, not by a class or an
|
|
197
|
+
obj_type list: every member was installed with a copy of
|
|
198
|
+
ca_stride_func, so an externally installed view that shares the
|
|
199
|
+
table answers true as well. See carray.h for what membership does
|
|
200
|
+
and does not promise. */
|
|
201
|
+
int
|
|
202
|
+
ca_is_stride_family (const void *ap)
|
|
203
|
+
{
|
|
204
|
+
const CArray *ca = (const CArray *) ap;
|
|
205
|
+
return ( ca_func[ca->obj_type].attach == ca_stride_func.attach );
|
|
206
|
+
}
|
|
207
|
+
|
|
195
208
|
/* Compose `leaf->strides` and `leaf->base_offset` (which live in `parent`'s
|
|
196
209
|
own logical row-major contig byte space) into `out_strides` and
|
|
197
210
|
`out_base` expressed in `parent->parent`'s byte space.
|
|
@@ -616,9 +629,29 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
616
629
|
hand the whole region to the root in a SINGLE ca_xfer_stride (entity -> ptr
|
|
617
630
|
memcpy; boundary view -> one recursion).
|
|
618
631
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
632
|
+
CAREFUL: the request is given over this view's linear ADDRESSES (carray.h
|
|
633
|
+
xfer_stride contract), so request axis k does NOT have to be view axis k.
|
|
634
|
+
A caller is free to hand over a transposed region -- counts/strides in one
|
|
635
|
+
order, the packed destination in another -- which is exactly what a
|
|
636
|
+
column-major backend (carray-linalg's Fortran-LAPACK gather) does. Matching
|
|
637
|
+
request axis k to view axis k by dividing strides[k] by the axis-k native
|
|
638
|
+
step looks right and is wrong: an (n, 1) view has the same native step on
|
|
639
|
+
both axes, so a transposed request divides cleanly and then composes the
|
|
640
|
+
n-cell walk onto the length-1 axis, whose parent stride is 0 -- delivering
|
|
641
|
+
the first cell n times, with no error anywhere. Ask ca_stride_region_axes
|
|
642
|
+
which view axis each request axis really moves (the same question
|
|
643
|
+
fill_stride asks), and fall back to the per-cell walk when the region is
|
|
644
|
+
not a box over our axes.
|
|
645
|
+
|
|
646
|
+
Byte-matching requests only; the byte-mismatch reinterpret (CAField
|
|
647
|
+
.real/.imag) and non-box access fall back to per-cell xfer_index (which
|
|
648
|
+
handles the sub-byte case). */
|
|
649
|
+
|
|
650
|
+
static int ca_stride_region_axes (CAStride *ca, ca_size_t base, int8_t ndim,
|
|
651
|
+
ca_size_t *counts, ca_size_t *steps,
|
|
652
|
+
ca_size_t *base_idx, int8_t *axis_of,
|
|
653
|
+
ca_size_t *mult);
|
|
654
|
+
|
|
622
655
|
static void
|
|
623
656
|
ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
624
657
|
ca_size_t *strides, void *data, int dir)
|
|
@@ -629,7 +662,12 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
629
662
|
ca_size_t composed_base;
|
|
630
663
|
ca_size_t view_native[CA_RANK_MAX];
|
|
631
664
|
ca_size_t root_stride[CA_RANK_MAX];
|
|
665
|
+
ca_size_t steps[CA_RANK_MAX];
|
|
666
|
+
ca_size_t base_idx[CA_RANK_MAX];
|
|
667
|
+
ca_size_t mult[CA_RANK_MAX];
|
|
668
|
+
int8_t axis_of[CA_RANK_MAX];
|
|
632
669
|
ca_size_t root_base;
|
|
670
|
+
ca_size_t base_addr = 0;
|
|
633
671
|
ca_size_t s;
|
|
634
672
|
int8_t ndim = ca->ndim, k;
|
|
635
673
|
int aligned = 1;
|
|
@@ -639,26 +677,77 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
639
677
|
|
|
640
678
|
s = ca->bytes;
|
|
641
679
|
for (k = ndim - 1; k >= 0; k--) { view_native[k] = s; s *= ca->dim[k]; }
|
|
680
|
+
for (k = 0; k < ndim; k++) base_addr += starts[k] * view_native[k];
|
|
642
681
|
|
|
643
682
|
if (ca->bytes != root->bytes) {
|
|
644
683
|
aligned = 0;
|
|
645
684
|
}
|
|
646
685
|
else {
|
|
647
686
|
for (k = 0; k < ndim; k++) {
|
|
648
|
-
if (strides[k] %
|
|
687
|
+
if ( strides[k] % ca->bytes != 0 ) { aligned = 0; break; }
|
|
688
|
+
steps[k] = strides[k] / ca->bytes;
|
|
689
|
+
}
|
|
690
|
+
if ( aligned ) {
|
|
691
|
+
aligned = ca_stride_region_axes(ca, base_addr / ca->bytes, ndim,
|
|
692
|
+
counts, steps, base_idx, axis_of, mult);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if ( aligned ) {
|
|
697
|
+
/* Each request axis now names the view axis it moves (axis_of) and by how
|
|
698
|
+
many of that axis' cells (mult); a count-1 axis moves nothing and gets
|
|
699
|
+
stride 0, which the walk never follows. */
|
|
700
|
+
root_base = composed_base;
|
|
701
|
+
for (k = 0; k < ca->ndim; k++) {
|
|
702
|
+
root_base += base_idx[k] * composed_strides[k];
|
|
703
|
+
}
|
|
704
|
+
for (k = 0; k < ndim; k++) {
|
|
705
|
+
root_stride[k] = ( axis_of[k] >= 0 )
|
|
706
|
+
? mult[k] * composed_strides[axis_of[k]]
|
|
707
|
+
: 0;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/* Cold root that answers regions: compose the request into its addresses
|
|
712
|
+
and hand it over whole, exactly as xfer_all does for the whole view. A
|
|
713
|
+
root with no memory to lend (a lazy transform, a CAObject over a file)
|
|
714
|
+
has no ptr to walk, but it can still produce a region on request -- and
|
|
715
|
+
asking it once beats asking it once per cell, which is what the per-cell
|
|
716
|
+
descent below would do. Chunked consumers (the binop / sweep drivers'
|
|
717
|
+
per-chunk gather) arrive here, so the difference is the whole cost of
|
|
718
|
+
the transfer, not a constant factor.
|
|
719
|
+
|
|
720
|
+
The gate is xfer_all's: the root must have the slot, share this view's
|
|
721
|
+
cell width (else the composed offsets are not whole root elements), and
|
|
722
|
+
carry the same ndim (else its index space cannot hold this request's
|
|
723
|
+
axes). Anything narrower keeps the per-cell descent, which is correct
|
|
724
|
+
for all of them. Direction is not part of the gate: a root that refuses
|
|
725
|
+
writes refuses them per cell as well. */
|
|
726
|
+
if (aligned && !root->ptr && ca_func[root->obj_type].xfer_stride
|
|
727
|
+
&& ca->bytes == root->bytes && ndim == root->ndim) {
|
|
728
|
+
ca_size_t rstarts[CA_RANK_MAX];
|
|
729
|
+
if ( root_base % root->bytes == 0 ) {
|
|
730
|
+
ca_size_t raddr = root_base / root->bytes;
|
|
731
|
+
if ( raddr >= 0 && raddr < root->elements ) {
|
|
732
|
+
ca_addr2index(root, raddr, rstarts);
|
|
733
|
+
ca_xfer_stride(root, rstarts, counts, root_stride, d, dir);
|
|
734
|
+
return;
|
|
735
|
+
}
|
|
649
736
|
}
|
|
650
737
|
}
|
|
651
738
|
|
|
652
739
|
/* Per-cell fallback (correct, no whole-view attach): byte-mismatch
|
|
653
|
-
reinterpret (CAField),
|
|
654
|
-
|
|
655
|
-
|
|
740
|
+
reinterpret (CAField), a region that is not a box over our axes (a
|
|
741
|
+
transposed request onto a degenerate axis, a flat index over several
|
|
742
|
+
axes), or a cold non-entity root the branch above could not hand a
|
|
743
|
+
region to (its ndim differs from the view's -- e.g. a reshape over a
|
|
744
|
+
boundary -- or it has no region slot). ca_stride_func_xfer_index
|
|
745
|
+
composes one hop and delegates to the parent. */
|
|
656
746
|
if (!aligned || !root->ptr) {
|
|
657
|
-
ca_size_t idx[CA_RANK_MAX], doff = 0
|
|
658
|
-
for (k = 0; k < ndim; k++) base += starts[k] * view_native[k];
|
|
747
|
+
ca_size_t idx[CA_RANK_MAX], doff = 0;
|
|
659
748
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
660
749
|
while (1) {
|
|
661
|
-
ca_size_t off =
|
|
750
|
+
ca_size_t off = base_addr, vmidx[CA_RANK_MAX];
|
|
662
751
|
for (k = 0; k < ndim; k++) off += idx[k] * strides[k];
|
|
663
752
|
ca_addr2index((CArray *) ca, off / ca->bytes, vmidx);
|
|
664
753
|
ca_stride_func_xfer_index(ca, vmidx, d + doff, dir);
|
|
@@ -670,17 +759,11 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
670
759
|
return;
|
|
671
760
|
}
|
|
672
761
|
|
|
673
|
-
/* Structural: root has a live ptr (entity / attached).
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
reshape view over a 1-D entity
|
|
677
|
-
|
|
678
|
-
for (k = 0; k < ndim; k++) {
|
|
679
|
-
ca_size_t req_step = strides[k] / view_native[k];
|
|
680
|
-
root_base += starts[k] * composed_strides[k];
|
|
681
|
-
root_stride[k] = req_step * composed_strides[k];
|
|
682
|
-
}
|
|
683
|
-
/* Slab-merge, tile-block and the general driver all live in the shared
|
|
762
|
+
/* Structural: root has a live ptr (entity / attached). The request is
|
|
763
|
+
already in root's BYTE space (root_base / root_stride above), so the walk
|
|
764
|
+
runs in the VIEW's ndim -- independent of root's own ndim, which is what
|
|
765
|
+
lets a reshape view over a 1-D entity through. compose happened once.
|
|
766
|
+
Slab-merge, tile-block and the general driver all live in the shared
|
|
684
767
|
walker, which the central dispatcher's structural path also uses. */
|
|
685
768
|
ca_xfer_strided_walk(root->ptr + root_base, ca->bytes, ndim,
|
|
686
769
|
counts, root_stride, d, dir);
|
|
@@ -753,6 +836,59 @@ ca_stride_region_axes (CAStride *ca, ca_size_t base, int8_t ndim,
|
|
|
753
836
|
root in units root does not share, so there is no address to hand over
|
|
754
837
|
and the per-cell descent stands in. */
|
|
755
838
|
|
|
839
|
+
static void
|
|
840
|
+
ca_stride_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
|
|
841
|
+
{
|
|
842
|
+
CAStride *ca = (CAStride *) ap;
|
|
843
|
+
CArray *root;
|
|
844
|
+
ca_size_t composed_strides[CA_RANK_MAX];
|
|
845
|
+
ca_size_t composed_base;
|
|
846
|
+
ca_size_t rbytes;
|
|
847
|
+
ca_size_t *paddrs;
|
|
848
|
+
ca_size_t i;
|
|
849
|
+
int8_t k;
|
|
850
|
+
int all_aligned = 1;
|
|
851
|
+
volatile VALUE holder;
|
|
852
|
+
|
|
853
|
+
/* Addresses name cells one by one, so unlike fill_stride there is nothing
|
|
854
|
+
here that only the whole extent can express: translate each view address
|
|
855
|
+
into the root's and hand the list down in one call. Without this the
|
|
856
|
+
region is still the only thing touched -- ca_fill_addrs_default sees to
|
|
857
|
+
that -- but it costs the parent one call per cell, which is the whole
|
|
858
|
+
difference on a backing where a call is a request. */
|
|
859
|
+
if ( n == 0 ) {
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
864
|
+
rbytes = root->bytes;
|
|
865
|
+
|
|
866
|
+
if ( ca->bytes != rbytes ) {
|
|
867
|
+
ca_fill_addrs_default(ca, n, addrs, ptr);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
872
|
+
for ( i = 0; i < n; i++ ) {
|
|
873
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
874
|
+
ca_size_t off = composed_base;
|
|
875
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
876
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
877
|
+
off += idx[k] * composed_strides[k];
|
|
878
|
+
}
|
|
879
|
+
if ( off % rbytes != 0 ) { all_aligned = 0; break; }
|
|
880
|
+
paddrs[i] = off / rbytes;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if ( all_aligned ) {
|
|
884
|
+
ca_fill_addrs(root, n, paddrs, ptr);
|
|
885
|
+
}
|
|
886
|
+
else {
|
|
887
|
+
ca_fill_addrs_default(ca, n, addrs, ptr);
|
|
888
|
+
}
|
|
889
|
+
ALLOCV_END(holder);
|
|
890
|
+
}
|
|
891
|
+
|
|
756
892
|
static void
|
|
757
893
|
ca_stride_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
758
894
|
ca_size_t *counts, ca_size_t *steps, void *ptr)
|
|
@@ -920,6 +1056,15 @@ ca_stride_func_allocate (void *ap)
|
|
|
920
1056
|
}
|
|
921
1057
|
}
|
|
922
1058
|
|
|
1059
|
+
/* Region request into the cold-root attach buffer; a lazy root can raise. */
|
|
1060
|
+
static VALUE
|
|
1061
|
+
ca_stride_cold_fill (VALUE arg)
|
|
1062
|
+
{
|
|
1063
|
+
void **args = (void **) arg;
|
|
1064
|
+
ca_copy_data((CArray *) args[0], (char *) args[1]);
|
|
1065
|
+
return Qnil;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
923
1068
|
static void
|
|
924
1069
|
ca_stride_func_attach (void *ap)
|
|
925
1070
|
{
|
|
@@ -935,7 +1080,15 @@ ca_stride_func_attach (void *ap)
|
|
|
935
1080
|
view with a live ptr is what makes the per-cell dispatchers bypass the
|
|
936
1081
|
transfer slots. */
|
|
937
1082
|
char *buf = xmalloc(ca_length(ca));
|
|
938
|
-
|
|
1083
|
+
void *args[2];
|
|
1084
|
+
int tag = 0;
|
|
1085
|
+
args[0] = ca;
|
|
1086
|
+
args[1] = buf;
|
|
1087
|
+
rb_protect(ca_stride_cold_fill, (VALUE) args, &tag); /* root stays cold */
|
|
1088
|
+
if (tag) {
|
|
1089
|
+
xfree(buf);
|
|
1090
|
+
rb_jump_tag(tag);
|
|
1091
|
+
}
|
|
939
1092
|
ca->ptr = buf;
|
|
940
1093
|
return;
|
|
941
1094
|
}
|
|
@@ -1400,6 +1553,7 @@ ca_operation_function_t ca_stride_func = {
|
|
|
1400
1553
|
sizeof(CAStride), /* struct_size: pool framework */
|
|
1401
1554
|
ca_stride_pool_bytes, /* pool_bytes */
|
|
1402
1555
|
ca_stride_pool_init, /* pool_init */
|
|
1556
|
+
.fill_addrs = ca_stride_func_fill_addrs,
|
|
1403
1557
|
.fill_stride = ca_stride_func_fill_stride,
|
|
1404
1558
|
};
|
|
1405
1559
|
|
|
@@ -2239,7 +2393,7 @@ rb_ca_flip_build_view (VALUE self, CArray *parent, const int8_t *flip)
|
|
|
2239
2393
|
|
|
2240
2394
|
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2241
2395
|
ndim, outdim, outstrides, base_offset);
|
|
2242
|
-
|
|
2396
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2243
2397
|
return obj;
|
|
2244
2398
|
}
|
|
2245
2399
|
|
|
@@ -2462,7 +2616,7 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2462
2616
|
{
|
|
2463
2617
|
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
2464
2618
|
out_k, outdim, outstrides, base_offset);
|
|
2465
|
-
|
|
2619
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2466
2620
|
return obj;
|
|
2467
2621
|
}
|
|
2468
2622
|
}
|
data/ext/ca_obj_string.c
CHANGED
|
@@ -90,10 +90,14 @@ ca_string_setup (CAString *ca, CArray *parent)
|
|
|
90
90
|
|
|
91
91
|
ca->obj_type = CA_OBJ_STRING;
|
|
92
92
|
ca->data_type = CA_OBJECT;
|
|
93
|
-
/* ORDERABLE
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
/* ORDERABLE + COMPARABLE, and both hold by construction: a storage cell
|
|
94
|
+
IS the Ruby String the surface shows, so storage order is surface
|
|
95
|
+
order and an external String compares against storage directly, with
|
|
96
|
+
nothing to reconcile. (A unit-bearing Face like CATime is the case
|
|
97
|
+
that has to stop at ORDERABLE; this one carries no unit.) */
|
|
98
|
+
ca->flags = CA_FLAG_IS_FACE
|
|
99
|
+
| CA_FLAG_FACE_ORDERABLE_STORAGE
|
|
100
|
+
| CA_FLAG_FACE_COMPARABLE_STORAGE;
|
|
97
101
|
ca->ndim = parent->ndim;
|
|
98
102
|
ca->bytes = sizeof(VALUE);
|
|
99
103
|
ca->elements = parent->elements;
|
|
@@ -192,7 +196,9 @@ ca_operation_function_t ca_string_func = {
|
|
|
192
196
|
ca_face_xfer_addrs,
|
|
193
197
|
NULL, /* fold_stride: identity Face is not foldable */
|
|
194
198
|
ca_face_xfer_stride,
|
|
195
|
-
ca_face_xfer_all
|
|
199
|
+
ca_face_xfer_all,
|
|
200
|
+
.fill_addrs = ca_face_fill_addrs,
|
|
201
|
+
.fill_stride = ca_face_fill_stride,
|
|
196
202
|
};
|
|
197
203
|
|
|
198
204
|
/* ------------------------------------------------------------------- */
|