carray 3.0.3 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +105 -17
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- data/lib/carray/frame/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +42 -6
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +217 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +61 -37
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/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
|
|
|
@@ -235,6 +247,10 @@ ca_stride_compose_through (CAStride *leaf, CAStride *parent,
|
|
|
235
247
|
for (k = parent->ndim - 1; k >= 0; k--)
|
|
236
248
|
prod[k] = prod[k + 1] * parent->dim[k];
|
|
237
249
|
|
|
250
|
+
/* A parent with a zero-length axis has no cell for the leaf to start at
|
|
251
|
+
(and prod[] below would divide by zero). */
|
|
252
|
+
if (prod[0] == 0) return 0;
|
|
253
|
+
|
|
238
254
|
/* Compose base offset first. We need the per-dim base position
|
|
239
255
|
to validate stride composition against parent dim bounds (a small
|
|
240
256
|
forward stride starting near the end of a parent dim wraps into
|
|
@@ -443,6 +459,8 @@ ca_stride_compose_to_root (CAStride *leaf,
|
|
|
443
459
|
|
|
444
460
|
"Identity compose-fold" semantics:
|
|
445
461
|
- cand->bytes == root->bytes (no byte reinterpret)
|
|
462
|
+
- cand->data_type == root->data_type (no type reinterpret: a caller
|
|
463
|
+
may read the root's cells as typed values)
|
|
446
464
|
- composed_base == 0
|
|
447
465
|
- composed_strides[k] match row-major over cand->dim with cand->bytes
|
|
448
466
|
|
|
@@ -471,6 +489,7 @@ ca_resolve_attached_root_via_identity (CArray *cand)
|
|
|
471
489
|
ca_stride_compose_to_root(cs, &root, composed_strides, &composed_base);
|
|
472
490
|
if ( !root->ptr ) return cand;
|
|
473
491
|
if ( cs->bytes != root->bytes ) return cand;
|
|
492
|
+
if ( cs->data_type != root->data_type ) return cand;
|
|
474
493
|
if ( composed_base != 0 ) return cand;
|
|
475
494
|
|
|
476
495
|
s = root->bytes;
|
|
@@ -610,7 +629,7 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
610
629
|
ca_size_t composed_base;
|
|
611
630
|
ca_size_t rbytes;
|
|
612
631
|
ca_size_t *paddrs;
|
|
613
|
-
ca_size_t i
|
|
632
|
+
ca_size_t i;
|
|
614
633
|
int8_t k;
|
|
615
634
|
int all_aligned = 1;
|
|
616
635
|
volatile VALUE holder;
|
|
@@ -619,18 +638,12 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
619
638
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
620
639
|
rbytes = root->bytes;
|
|
621
640
|
|
|
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 ) {
|
|
641
|
+
/* Identity: same cell size, no offset, row-major composed strides (a
|
|
642
|
+
simple reshape / flatten of the root). A view address is then the
|
|
643
|
+
root address, whatever the addresses are, so the list goes through
|
|
644
|
+
as-is. Cascades through chains such as a[idx_2d] (outer reshape ->
|
|
645
|
+
CAGrid -> inner reshape -> entity). */
|
|
646
|
+
if ( ca->bytes == rbytes && composed_base == 0 ) {
|
|
634
647
|
ca_size_t s = rbytes;
|
|
635
648
|
int is_identity = 1;
|
|
636
649
|
for ( k = ca->ndim - 1; k >= 0; k-- ) {
|
|
@@ -643,36 +656,51 @@ ca_stride_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
643
656
|
}
|
|
644
657
|
}
|
|
645
658
|
|
|
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);
|
|
659
|
+
/* Whole-cell strides: translate in cell units, with no per-cell division. */
|
|
660
|
+
if ( ca->bytes == rbytes && composed_base % rbytes == 0 ) {
|
|
651
661
|
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;
|
|
662
|
+
if ( composed_strides[k] % rbytes != 0 ) { all_aligned = 0; break; }
|
|
660
663
|
}
|
|
661
664
|
}
|
|
665
|
+
else {
|
|
666
|
+
all_aligned = 0;
|
|
667
|
+
}
|
|
662
668
|
|
|
663
669
|
if ( all_aligned ) {
|
|
670
|
+
ca_size_t esteps[CA_RANK_MAX];
|
|
671
|
+
ca_size_t ebase = composed_base / rbytes;
|
|
672
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
673
|
+
esteps[k] = composed_strides[k] / rbytes;
|
|
674
|
+
}
|
|
675
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
676
|
+
if ( ca->ndim == 1 ) {
|
|
677
|
+
for ( i = 0; i < n; i++ ) {
|
|
678
|
+
paddrs[i] = ebase + addrs[i] * esteps[0];
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
else {
|
|
682
|
+
for ( i = 0; i < n; i++ ) {
|
|
683
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
684
|
+
ca_size_t off = ebase;
|
|
685
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
686
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
687
|
+
off += idx[k] * esteps[k];
|
|
688
|
+
}
|
|
689
|
+
paddrs[i] = off;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
664
692
|
ca_xfer_addrs(root, n, paddrs, data, dir);
|
|
693
|
+
ALLOCV_END(holder);
|
|
694
|
+
return;
|
|
665
695
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
}
|
|
696
|
+
|
|
697
|
+
/* Byte-mismatched reinterpret: deliver cell by cell via xfer_index
|
|
698
|
+
(still no whole-view attach -- delegates one cell at a time). */
|
|
699
|
+
for ( i = 0; i < n; i++ ) {
|
|
700
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
701
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
702
|
+
ca_stride_func_xfer_index(ca, idx, d + i * ca->bytes, dir);
|
|
674
703
|
}
|
|
675
|
-
ALLOCV_END(holder);
|
|
676
704
|
}
|
|
677
705
|
|
|
678
706
|
/* Optimised region delivery. Reached when ca->ptr == NULL (the central dispatcher handles the alias / attached case).
|
|
@@ -833,6 +861,7 @@ ca_stride_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
833
861
|
if (!aligned || !root->ptr) {
|
|
834
862
|
ca_size_t idx[CA_RANK_MAX], doff = 0;
|
|
835
863
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
864
|
+
/* empty: the slot returns on an empty region at its entry */
|
|
836
865
|
while (1) {
|
|
837
866
|
ca_size_t off = base_addr, vmidx[CA_RANK_MAX];
|
|
838
867
|
for (k = 0; k < ndim; k++) off += idx[k] * strides[k];
|
|
@@ -1085,8 +1114,9 @@ static int ca_layout_is_contiguous (int8_t ndim, const ca_size_t *dim,
|
|
|
1085
1114
|
composes a source down to its root.
|
|
1086
1115
|
|
|
1087
1116
|
Entities hold their own buffer. A CAStride-family root is one the fold
|
|
1088
|
-
declined to walk through (a
|
|
1089
|
-
onward
|
|
1117
|
+
declined to walk through (a reshape over a transpose); its own attach
|
|
1118
|
+
folds onward from itself, so the answer is the one for the root it folds
|
|
1119
|
+
to. What is left is the
|
|
1090
1120
|
boundary views that compute or fetch their contents -- CAObject, the lazy
|
|
1091
1121
|
per-element transforms, whatever a companion gem installed -- and of those,
|
|
1092
1122
|
only the ones with an xfer_stride slot can answer a region request at all.
|
|
@@ -1098,7 +1128,17 @@ ca_root_lends_no_memory (void *ap)
|
|
|
1098
1128
|
CArray *root = (CArray *) ap;
|
|
1099
1129
|
|
|
1100
1130
|
if ( ca_is_entity(root) ) return 0;
|
|
1101
|
-
if ( ca_func[root->obj_type].attach == ca_stride_func.attach )
|
|
1131
|
+
if ( ca_func[root->obj_type].attach == ca_stride_func.attach ) {
|
|
1132
|
+
/* The fold stopped at a CAStride (a reshape over a transpose). Its
|
|
1133
|
+
own attach folds onward from itself, so it lends memory exactly when
|
|
1134
|
+
the root it folds to does: over a computed root, attaching it
|
|
1135
|
+
produces all of it. */
|
|
1136
|
+
CArray *below;
|
|
1137
|
+
ca_size_t cs[CA_RANK_MAX];
|
|
1138
|
+
ca_size_t base;
|
|
1139
|
+
ca_stride_compose_to_root((CAStride *) root, &below, cs, &base);
|
|
1140
|
+
return ca_root_lends_no_memory(below);
|
|
1141
|
+
}
|
|
1102
1142
|
return ca_func[root->obj_type].xfer_stride != NULL;
|
|
1103
1143
|
}
|
|
1104
1144
|
|
|
@@ -1164,14 +1204,14 @@ ca_stride_func_allocate (void *ap)
|
|
|
1164
1204
|
|
|
1165
1205
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
1166
1206
|
if (ca_root_lends_no_memory(root)) {
|
|
1167
|
-
ca->ptr =
|
|
1207
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1168
1208
|
return;
|
|
1169
1209
|
}
|
|
1170
1210
|
ca_attach(root);
|
|
1171
1211
|
if (ca_layout_is_contiguous(ca->ndim, ca->dim, composed_strides, ca->bytes)) {
|
|
1172
1212
|
ca->ptr = root->ptr + composed_base;
|
|
1173
1213
|
} else {
|
|
1174
|
-
ca->ptr =
|
|
1214
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1175
1215
|
}
|
|
1176
1216
|
}
|
|
1177
1217
|
|
|
@@ -1200,14 +1240,9 @@ ca_stride_func_attach (void *ap)
|
|
|
1200
1240
|
transfer slots. */
|
|
1201
1241
|
char *buf = xmalloc(ca_length(ca));
|
|
1202
1242
|
void *args[2];
|
|
1203
|
-
int tag = 0;
|
|
1204
1243
|
args[0] = ca;
|
|
1205
1244
|
args[1] = buf;
|
|
1206
|
-
|
|
1207
|
-
if (tag) {
|
|
1208
|
-
xfree(buf);
|
|
1209
|
-
rb_jump_tag(tag);
|
|
1210
|
-
}
|
|
1245
|
+
ca_fill_or_xfree(buf, ca_stride_cold_fill, (VALUE) args); /* root stays cold */
|
|
1211
1246
|
ca->ptr = buf;
|
|
1212
1247
|
return;
|
|
1213
1248
|
}
|
|
@@ -1215,7 +1250,7 @@ ca_stride_func_attach (void *ap)
|
|
|
1215
1250
|
if (ca_layout_is_contiguous(ca->ndim, ca->dim, composed_strides, ca->bytes)) {
|
|
1216
1251
|
ca->ptr = root->ptr + composed_base;
|
|
1217
1252
|
} else {
|
|
1218
|
-
ca->ptr =
|
|
1253
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1219
1254
|
ca_stride_xfer_with_layout(ca, 0, root->ptr + composed_base, composed_strides);
|
|
1220
1255
|
}
|
|
1221
1256
|
}
|
|
@@ -1342,6 +1377,8 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1342
1377
|
char *ptr0 = ca->ptr;
|
|
1343
1378
|
char *ptr = (char *) data;
|
|
1344
1379
|
|
|
1380
|
+
if ( ca->elements == 0 ) return;
|
|
1381
|
+
|
|
1345
1382
|
ca_stride_compose_to_root(ca, &root, composed_strides, &composed_base);
|
|
1346
1383
|
|
|
1347
1384
|
/* Partial materialise: when the fold stops at a cold boundary view that knows how to deliver a region (has an
|
|
@@ -1458,6 +1495,7 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1458
1495
|
ca_size_t idx[CA_RANK_MAX], n = 0;
|
|
1459
1496
|
int8_t k;
|
|
1460
1497
|
for (k = 0; k < ca->ndim; k++) idx[k] = 0;
|
|
1498
|
+
/* empty: the slot returns on an empty view at its entry */
|
|
1461
1499
|
while (1) {
|
|
1462
1500
|
ca_size_t off = composed_base;
|
|
1463
1501
|
for (k = 0; k < ca->ndim; k++) off += idx[k] * composed_strides[k];
|
|
@@ -1471,6 +1509,52 @@ ca_stride_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1471
1509
|
return;
|
|
1472
1510
|
}
|
|
1473
1511
|
|
|
1512
|
+
/* A read through a byte reinterpret (CAField, a refer to another width)
|
|
1513
|
+
over a cold root: the root's addresses are not this view's cells, but
|
|
1514
|
+
each cell lies in a run of whole root elements. Ask the root for those
|
|
1515
|
+
elements and cut the cell's bytes out of them. A write keeps the
|
|
1516
|
+
whole-root round trip below: two cells can share a root element, and
|
|
1517
|
+
writing back each one's copy of it would drop the other's bytes. */
|
|
1518
|
+
if ( dir == CA_XFER_GET && ca->elements > 0 && ca->bytes != root->bytes
|
|
1519
|
+
&& ca_func[root->obj_type].xfer_stride ) {
|
|
1520
|
+
volatile VALUE ah = 0, sh = 0;
|
|
1521
|
+
ca_size_t rb = root->bytes, cb = ca->bytes;
|
|
1522
|
+
ca_size_t per = (cb + rb - 1) / rb + 1;
|
|
1523
|
+
ca_size_t *addrs = ALLOCV_N(ca_size_t, ah, ca->elements * per);
|
|
1524
|
+
char *scratch;
|
|
1525
|
+
ca_size_t idx[CA_RANK_MAX], n = 0, i;
|
|
1526
|
+
ca_size_t *first = ALLOCV_N(ca_size_t, sh, ca->elements);
|
|
1527
|
+
int8_t k;
|
|
1528
|
+
int ok = 1;
|
|
1529
|
+
for (k = 0; k < ca->ndim; k++) idx[k] = 0;
|
|
1530
|
+
for (i = 0; ok; i++) {
|
|
1531
|
+
ca_size_t off = composed_base, e, e_end;
|
|
1532
|
+
for (k = 0; k < ca->ndim; k++) off += idx[k] * composed_strides[k];
|
|
1533
|
+
if ( off < 0 || off + cb > root->elements * rb ) { ok = 0; break; }
|
|
1534
|
+
first[i] = n * rb + off % rb;
|
|
1535
|
+
for (e = off / rb, e_end = (off + cb - 1) / rb; e <= e_end; e++) {
|
|
1536
|
+
addrs[n++] = e;
|
|
1537
|
+
}
|
|
1538
|
+
k = ca->ndim - 1;
|
|
1539
|
+
while (k >= 0) { if (++idx[k] < ca->dim[k]) break; idx[k] = 0; k--; }
|
|
1540
|
+
if (k < 0) break;
|
|
1541
|
+
}
|
|
1542
|
+
if ( ok && n < root->elements ) {
|
|
1543
|
+
volatile VALUE dh = 0;
|
|
1544
|
+
scratch = ALLOCV_N(char, dh, n * rb);
|
|
1545
|
+
ca_xfer_addrs(root, n, addrs, scratch, CA_XFER_GET);
|
|
1546
|
+
for (i = 0; i < ca->elements; i++) {
|
|
1547
|
+
memcpy(ptr + i * cb, scratch + first[i], cb);
|
|
1548
|
+
}
|
|
1549
|
+
ALLOCV_END(dh);
|
|
1550
|
+
ALLOCV_END(sh);
|
|
1551
|
+
ALLOCV_END(ah);
|
|
1552
|
+
return;
|
|
1553
|
+
}
|
|
1554
|
+
ALLOCV_END(sh);
|
|
1555
|
+
ALLOCV_END(ah);
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1474
1558
|
/* Cold root without an xfer_stride slot, or an ndim mismatch the bridges
|
|
1475
1559
|
above could not express: materialise the root into scratch via
|
|
1476
1560
|
ca_xfer_all and run the direct strided gather/scatter against that.
|
|
@@ -1606,19 +1690,19 @@ ca_stride_func_fill_data (void *ap, void *ptr)
|
|
|
1606
1690
|
}
|
|
1607
1691
|
case 2: {
|
|
1608
1692
|
int16_t v; memcpy(&v, ptr, 2);
|
|
1609
|
-
|
|
1693
|
+
ca_u_int16_t *d = (ca_u_int16_t *) dst;
|
|
1610
1694
|
for (i = 0; i < inner_count; i++) d[i] = v;
|
|
1611
1695
|
break;
|
|
1612
1696
|
}
|
|
1613
1697
|
case 4: {
|
|
1614
1698
|
int32_t v; memcpy(&v, ptr, 4);
|
|
1615
|
-
|
|
1699
|
+
ca_u_int32_t *d = (ca_u_int32_t *) dst;
|
|
1616
1700
|
for (i = 0; i < inner_count; i++) d[i] = v;
|
|
1617
1701
|
break;
|
|
1618
1702
|
}
|
|
1619
1703
|
case 8: {
|
|
1620
1704
|
int64_t v; memcpy(&v, ptr, 8);
|
|
1621
|
-
|
|
1705
|
+
ca_u_int64_t *d = (ca_u_int64_t *) dst;
|
|
1622
1706
|
for (i = 0; i < inner_count; i++) d[i] = v;
|
|
1623
1707
|
break;
|
|
1624
1708
|
}
|
|
@@ -2078,16 +2162,17 @@ rb_ca_as_strided (int argc, VALUE *argv, VALUE self)
|
|
|
2078
2162
|
"shape (%ld) and strides (%ld) length mismatch",
|
|
2079
2163
|
len, RARRAY_LEN(rstrides));
|
|
2080
2164
|
}
|
|
2081
|
-
if (len <= 0
|
|
2165
|
+
if (len <= 0) {
|
|
2082
2166
|
rb_raise(rb_eArgError, "invalid ndim %ld", len);
|
|
2083
2167
|
}
|
|
2168
|
+
ca_check_rank_fits(len, NULL);
|
|
2084
2169
|
ndim = (int8_t) len;
|
|
2085
2170
|
for (i = 0; i < len; i++) {
|
|
2086
|
-
shape[i] =
|
|
2087
|
-
strides[i] =
|
|
2171
|
+
shape[i] = ca_integer_arg(RARRAY_AREF(rshape, i), "a length", NULL);
|
|
2172
|
+
strides[i] = ca_integer_arg(RARRAY_AREF(rstrides, i), "a stride", NULL);
|
|
2088
2173
|
}
|
|
2089
2174
|
if (! NIL_P(roffset)) {
|
|
2090
|
-
base_offset =
|
|
2175
|
+
base_offset = ca_integer_arg(roffset, "offset", NULL);
|
|
2091
2176
|
}
|
|
2092
2177
|
|
|
2093
2178
|
VALUE obj = rb_ca_stride_new(self, parent->data_type, parent->bytes,
|
|
@@ -2118,11 +2203,7 @@ rb_ca_sliding_windows (int argc, VALUE *argv, VALUE self)
|
|
|
2118
2203
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2119
2204
|
|
|
2120
2205
|
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
|
-
}
|
|
2206
|
+
ca_check_rank_fits(2 * (long) ndim, "sliding_windows");
|
|
2126
2207
|
|
|
2127
2208
|
rb_scan_args(argc, argv, "*:", (VALUE *) &rposary, (VALUE *) &ropt);
|
|
2128
2209
|
if (! NIL_P(ropt)) {
|
|
@@ -2138,12 +2219,12 @@ rb_ca_sliding_windows (int argc, VALUE *argv, VALUE self)
|
|
|
2138
2219
|
RARRAY_LEN(wary), (int) ndim);
|
|
2139
2220
|
}
|
|
2140
2221
|
for (i = 0; i < ndim; i++) {
|
|
2141
|
-
window[i] =
|
|
2222
|
+
window[i] = ca_integer_arg(RARRAY_AREF(wary, i), "a window size", NULL);
|
|
2142
2223
|
}
|
|
2143
2224
|
}
|
|
2144
2225
|
else if (nargs == ndim) {
|
|
2145
2226
|
for (i = 0; i < ndim; i++) {
|
|
2146
|
-
window[i] =
|
|
2227
|
+
window[i] = ca_integer_arg(RARRAY_AREF(rposary, i), "a window size", NULL);
|
|
2147
2228
|
}
|
|
2148
2229
|
}
|
|
2149
2230
|
else {
|
|
@@ -2162,11 +2243,11 @@ rb_ca_sliding_windows (int argc, VALUE *argv, VALUE self)
|
|
|
2162
2243
|
RARRAY_LEN(rstep), (int) ndim);
|
|
2163
2244
|
}
|
|
2164
2245
|
for (i = 0; i < ndim; i++) {
|
|
2165
|
-
step[i] =
|
|
2246
|
+
step[i] = ca_integer_arg(RARRAY_AREF(rstep, i), "a step", NULL);
|
|
2166
2247
|
}
|
|
2167
2248
|
}
|
|
2168
2249
|
else {
|
|
2169
|
-
ca_size_t s =
|
|
2250
|
+
ca_size_t s = ca_integer_arg(rstep, "step", NULL);
|
|
2170
2251
|
for (i = 0; i < ndim; i++) step[i] = s;
|
|
2171
2252
|
}
|
|
2172
2253
|
|
|
@@ -2249,13 +2330,13 @@ rb_ca_unfold (int argc, VALUE *argv, VALUE self)
|
|
|
2249
2330
|
}
|
|
2250
2331
|
nspatial = (int8_t) RARRAY_LEN(wary);
|
|
2251
2332
|
for (i = 0; i < nspatial; i++) {
|
|
2252
|
-
window[i] =
|
|
2333
|
+
window[i] = ca_integer_arg(RARRAY_AREF(wary, i), "a window size", NULL);
|
|
2253
2334
|
}
|
|
2254
2335
|
}
|
|
2255
2336
|
else if (nargs >= 1 && nargs <= ndim) {
|
|
2256
2337
|
nspatial = (int8_t) nargs;
|
|
2257
2338
|
for (i = 0; i < nspatial; i++) {
|
|
2258
|
-
window[i] =
|
|
2339
|
+
window[i] = ca_integer_arg(RARRAY_AREF(rposary, i), "a window size", NULL);
|
|
2259
2340
|
}
|
|
2260
2341
|
}
|
|
2261
2342
|
else {
|
|
@@ -2266,11 +2347,7 @@ rb_ca_unfold (int argc, VALUE *argv, VALUE self)
|
|
|
2266
2347
|
|
|
2267
2348
|
ntrail = ndim - nspatial;
|
|
2268
2349
|
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
|
-
}
|
|
2350
|
+
ca_check_rank_fits(outrank, "unfold");
|
|
2274
2351
|
|
|
2275
2352
|
if (NIL_P(rstep)) {
|
|
2276
2353
|
for (i = 0; i < nspatial; i++) step[i] = 1;
|
|
@@ -2282,11 +2359,11 @@ rb_ca_unfold (int argc, VALUE *argv, VALUE self)
|
|
|
2282
2359
|
RARRAY_LEN(rstep), (int) nspatial);
|
|
2283
2360
|
}
|
|
2284
2361
|
for (i = 0; i < nspatial; i++) {
|
|
2285
|
-
step[i] =
|
|
2362
|
+
step[i] = ca_integer_arg(RARRAY_AREF(rstep, i), "a step", NULL);
|
|
2286
2363
|
}
|
|
2287
2364
|
}
|
|
2288
2365
|
else {
|
|
2289
|
-
ca_size_t s =
|
|
2366
|
+
ca_size_t s = ca_integer_arg(rstep, "step", NULL);
|
|
2290
2367
|
for (i = 0; i < nspatial; i++) step[i] = s;
|
|
2291
2368
|
}
|
|
2292
2369
|
|
|
@@ -2354,11 +2431,7 @@ rb_ca_block_view (int argc, VALUE *argv, VALUE self)
|
|
|
2354
2431
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2355
2432
|
|
|
2356
2433
|
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
|
-
}
|
|
2434
|
+
ca_check_rank_fits(2 * (long) ndim, "block_view");
|
|
2362
2435
|
|
|
2363
2436
|
rb_scan_args(argc, argv, "*:", (VALUE *) &rposary, (VALUE *) &ropt);
|
|
2364
2437
|
rb_reject_options(ropt);
|
|
@@ -2372,12 +2445,12 @@ rb_ca_block_view (int argc, VALUE *argv, VALUE self)
|
|
|
2372
2445
|
RARRAY_LEN(bary), (int) ndim);
|
|
2373
2446
|
}
|
|
2374
2447
|
for (i = 0; i < ndim; i++) {
|
|
2375
|
-
block[i] =
|
|
2448
|
+
block[i] = ca_integer_arg(RARRAY_AREF(bary, i), "a block size", NULL);
|
|
2376
2449
|
}
|
|
2377
2450
|
}
|
|
2378
2451
|
else if (nargs == ndim) {
|
|
2379
2452
|
for (i = 0; i < ndim; i++) {
|
|
2380
|
-
block[i] =
|
|
2453
|
+
block[i] = ca_integer_arg(RARRAY_AREF(rposary, i), "a block size", NULL);
|
|
2381
2454
|
}
|
|
2382
2455
|
}
|
|
2383
2456
|
else {
|
|
@@ -2461,7 +2534,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2461
2534
|
(int) n_iter, (int) ndim);
|
|
2462
2535
|
}
|
|
2463
2536
|
for (i = 0; i < n_iter; i++) {
|
|
2464
|
-
iter_axes[i] =
|
|
2537
|
+
iter_axes[i] = ca_normalize_axis_arg(RARRAY_AREF(aary, i), ndim, NULL);
|
|
2465
2538
|
}
|
|
2466
2539
|
}
|
|
2467
2540
|
else if (nargs >= 1) {
|
|
@@ -2472,7 +2545,7 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2472
2545
|
}
|
|
2473
2546
|
n_iter = (int8_t) nargs;
|
|
2474
2547
|
for (i = 0; i < n_iter; i++) {
|
|
2475
|
-
iter_axes[i] =
|
|
2548
|
+
iter_axes[i] = ca_normalize_axis_arg(RARRAY_AREF(rposary, i), ndim, NULL);
|
|
2476
2549
|
}
|
|
2477
2550
|
}
|
|
2478
2551
|
else {
|
|
@@ -2480,23 +2553,16 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2480
2553
|
"dim_view: at least one iteration axis required");
|
|
2481
2554
|
}
|
|
2482
2555
|
|
|
2483
|
-
/*
|
|
2556
|
+
/* The axes are normalized as they are read; check distinctness. */
|
|
2484
2557
|
for (i = 0; i < ndim; i++) seen[i] = 0;
|
|
2485
2558
|
for (i = 0; i < n_iter; i++) {
|
|
2486
2559
|
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
2560
|
if (seen[a]) {
|
|
2494
2561
|
rb_raise(rb_eArgError,
|
|
2495
2562
|
"dim_view: duplicate iteration axis %lld",
|
|
2496
2563
|
(long long) a);
|
|
2497
2564
|
}
|
|
2498
2565
|
seen[a] = 1;
|
|
2499
|
-
iter_axes[i] = a;
|
|
2500
2566
|
}
|
|
2501
2567
|
|
|
2502
2568
|
/* imap: iter axes first (in given order), then remaining axes
|
|
@@ -2509,7 +2575,12 @@ rb_ca_dim_view (int argc, VALUE *argv, VALUE self)
|
|
|
2509
2575
|
if (! seen[i]) imap[k++] = i;
|
|
2510
2576
|
}
|
|
2511
2577
|
|
|
2512
|
-
|
|
2578
|
+
{
|
|
2579
|
+
/* A reordering of the axes, as transpose is: a Face stays its Face. */
|
|
2580
|
+
volatile VALUE obj = rb_ca_trans_new(self, imap);
|
|
2581
|
+
CA_WRAPPER_LIFT(obj, self, parent);
|
|
2582
|
+
return obj;
|
|
2583
|
+
}
|
|
2513
2584
|
}
|
|
2514
2585
|
|
|
2515
2586
|
/* flip(*axes) -- reverses the listed axes by negating their strides; with no
|
|
@@ -2568,12 +2639,8 @@ rb_ca_flip_axis (VALUE self, long axis)
|
|
|
2568
2639
|
rb_check_carray_object(self);
|
|
2569
2640
|
TypedData_Get_Struct(self, CArray, &carray_data_type, parent);
|
|
2570
2641
|
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
|
-
}
|
|
2642
|
+
long a = rb_ca_normalize_axis_for_ndim(axis, ndim, /* axis-check: a long from a C caller */
|
|
2643
|
+
"flip_axis");
|
|
2577
2644
|
int8_t flip[CA_RANK_MAX] = {0};
|
|
2578
2645
|
flip[a] = 1;
|
|
2579
2646
|
return rb_ca_flip_build_view(self, parent, flip);
|
|
@@ -2615,7 +2682,7 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2615
2682
|
(int) n_axes, (int) ndim);
|
|
2616
2683
|
}
|
|
2617
2684
|
for (i = 0; i < n_axes; i++) {
|
|
2618
|
-
axes[i] =
|
|
2685
|
+
axes[i] = ca_normalize_axis_arg(RARRAY_AREF(aary, i), ndim, NULL);
|
|
2619
2686
|
}
|
|
2620
2687
|
}
|
|
2621
2688
|
else {
|
|
@@ -2626,18 +2693,12 @@ rb_ca_flip (int argc, VALUE *argv, VALUE self)
|
|
|
2626
2693
|
}
|
|
2627
2694
|
n_axes = (int8_t) nargs;
|
|
2628
2695
|
for (i = 0; i < n_axes; i++) {
|
|
2629
|
-
axes[i] =
|
|
2696
|
+
axes[i] = ca_normalize_axis_arg(RARRAY_AREF(rposary, i), ndim, NULL);
|
|
2630
2697
|
}
|
|
2631
2698
|
}
|
|
2632
2699
|
|
|
2633
2700
|
for (i = 0; i < n_axes; i++) {
|
|
2634
2701
|
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
2702
|
if (flip[a]) {
|
|
2642
2703
|
rb_raise(rb_eArgError,
|
|
2643
2704
|
"flip: duplicate axis %lld",
|
|
@@ -2688,14 +2749,14 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2688
2749
|
|
|
2689
2750
|
/* offset from positional or keyword (not both) */
|
|
2690
2751
|
if (nargs == 0) {
|
|
2691
|
-
if (! NIL_P(roffset)) offset =
|
|
2752
|
+
if (! NIL_P(roffset)) offset = ca_integer_arg(roffset, "offset", NULL);
|
|
2692
2753
|
}
|
|
2693
2754
|
else if (nargs == 1) {
|
|
2694
2755
|
if (! NIL_P(roffset)) {
|
|
2695
2756
|
rb_raise(rb_eArgError,
|
|
2696
2757
|
"diagonal: give offset positionally OR as keyword, not both");
|
|
2697
2758
|
}
|
|
2698
|
-
offset =
|
|
2759
|
+
offset = ca_integer_arg(RARRAY_AREF(rposary, 0), "offset", NULL);
|
|
2699
2760
|
}
|
|
2700
2761
|
else {
|
|
2701
2762
|
rb_raise(rb_eArgError,
|
|
@@ -2711,18 +2772,8 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2711
2772
|
rb_raise(rb_eArgError,
|
|
2712
2773
|
"diagonal: axis: must be an Array of 2 integers");
|
|
2713
2774
|
}
|
|
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
|
-
}
|
|
2775
|
+
ai = ca_normalize_axis_arg(RARRAY_AREF(raxis, 0), ndim, NULL);
|
|
2776
|
+
aj = ca_normalize_axis_arg(RARRAY_AREF(raxis, 1), ndim, NULL);
|
|
2726
2777
|
if (ai == aj) {
|
|
2727
2778
|
rb_raise(rb_eArgError, "diagonal: axis[0] and axis[1] must be distinct");
|
|
2728
2779
|
}
|
|
@@ -2750,7 +2801,9 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2750
2801
|
base_offset = offset * parent_byte_stride[aj];
|
|
2751
2802
|
}
|
|
2752
2803
|
else {
|
|
2753
|
-
|
|
2804
|
+
/* compare before negating: -offset overflows for the most negative
|
|
2805
|
+
offset */
|
|
2806
|
+
ca_size_t neg = ( offset <= -parent->dim[ai] ) ? parent->dim[ai] : -offset;
|
|
2754
2807
|
if (neg >= parent->dim[ai]) {
|
|
2755
2808
|
diag_len = 0;
|
|
2756
2809
|
}
|
|
@@ -2761,6 +2814,9 @@ rb_ca_diagonal (int argc, VALUE *argv, VALUE self)
|
|
|
2761
2814
|
}
|
|
2762
2815
|
base_offset = neg * parent_byte_stride[ai];
|
|
2763
2816
|
}
|
|
2817
|
+
if (diag_len == 0) {
|
|
2818
|
+
base_offset = 0; /* an offset past the edge can overflow the product */
|
|
2819
|
+
}
|
|
2764
2820
|
|
|
2765
2821
|
/* build output: kept axes (in original order), then diagonal axis */
|
|
2766
2822
|
out_k = 0;
|