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_window.c
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
#include "carray.h"
|
|
31
31
|
#include "ca_composite_dispatch.h"
|
|
32
32
|
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE, used by rb_ca_window */
|
|
33
|
+
#include "carray_internal.h" /* ca_axis_view_attach_owned */
|
|
33
34
|
|
|
34
35
|
/* should not be static variable as used by CAIteratorWindow */
|
|
35
36
|
|
|
@@ -82,11 +83,23 @@ ca_window_pool_init (void *ap, int8_t ndim)
|
|
|
82
83
|
ca->dim = ca->count; /* alias; ca_window_setup re-sets */
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
/* A window over an object array keeps its fill value, a VALUE, in a
|
|
87
|
+
buffer of its own, so it marks it; ca_mark covers only ca->ptr. */
|
|
88
|
+
void
|
|
89
|
+
ca_window_mark (void *ap)
|
|
90
|
+
{
|
|
91
|
+
CAWindow *ca = (CAWindow *) ap;
|
|
92
|
+
ca_mark(ca);
|
|
93
|
+
if ( ca->fill != NULL && ca_is_object_type(ca) ) {
|
|
94
|
+
rb_gc_mark(*(VALUE *) ca->fill);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
const rb_data_type_t cawindow_data_type = {
|
|
86
99
|
.parent = &caview_data_type,
|
|
87
100
|
.wrap_struct_name = "CAWindow",
|
|
88
101
|
.function = {
|
|
89
|
-
.dmark =
|
|
102
|
+
.dmark = ca_window_mark,
|
|
90
103
|
.dfree = ca_free,
|
|
91
104
|
.dsize = ca_window_dsize,
|
|
92
105
|
.dcompact = NULL
|
|
@@ -314,6 +327,7 @@ static void
|
|
|
314
327
|
ca_window_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
315
328
|
ca_size_t *strides, void *data, int dir)
|
|
316
329
|
{
|
|
330
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
317
331
|
CAWindow *w = (CAWindow *) ap;
|
|
318
332
|
CArray *parent = w->parent;
|
|
319
333
|
int8_t ndim = w->ndim;
|
|
@@ -667,11 +681,17 @@ ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
667
681
|
|
|
668
682
|
elements = 1;
|
|
669
683
|
for (i=0; i<ndim; i++) {
|
|
670
|
-
if ( count[i]
|
|
684
|
+
if ( count[i] < 0 ) { /* zero is an empty window */
|
|
671
685
|
rb_raise(rb_eIndexError,
|
|
672
|
-
"invalid size for %i-th dimension (negative
|
|
686
|
+
"invalid size for %i-th dimension (negative)", i);
|
|
673
687
|
}
|
|
674
|
-
|
|
688
|
+
}
|
|
689
|
+
elements = ca_shape_elements(ndim, count, bytes);
|
|
690
|
+
|
|
691
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
692
|
+
run them before it allocates. */
|
|
693
|
+
if ( ca == NULL ) {
|
|
694
|
+
return 0;
|
|
675
695
|
}
|
|
676
696
|
|
|
677
697
|
ca->obj_type = CA_OBJ_WINDOW;
|
|
@@ -746,7 +766,9 @@ CAWindow *
|
|
|
746
766
|
ca_window_new (CArray *parent,
|
|
747
767
|
ca_size_t *start, ca_size_t *count, uint8_t *bounds, char *fill)
|
|
748
768
|
{
|
|
749
|
-
CAWindow *ca
|
|
769
|
+
CAWindow *ca;
|
|
770
|
+
ca_window_setup(NULL, parent, start, count, bounds, fill);
|
|
771
|
+
ca = (CAWindow *) ca_array_alloc(CA_OBJ_WINDOW, parent->ndim);
|
|
750
772
|
ca_window_setup(ca, parent, start, count, bounds, fill);
|
|
751
773
|
return ca;
|
|
752
774
|
}
|
|
@@ -952,13 +974,52 @@ ca_window_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
952
974
|
ALLOCV_END(h1);
|
|
953
975
|
}
|
|
954
976
|
|
|
977
|
+
/* Whether this window over a parent with no memory to lend owns its buffer
|
|
978
|
+
rather than attaching the parent. Only FILL / MASK bounds qualify: their
|
|
979
|
+
xfer_stride hands the parent one region per row, where the other bounds
|
|
980
|
+
go cell by cell -- for a Ruby-backed parent, a call per cell, which costs
|
|
981
|
+
more than producing the parent once. Both inputs are fixed for the
|
|
982
|
+
life of the view, so attach, sync and detach take the same branch. */
|
|
983
|
+
static int
|
|
984
|
+
ca_window_owns_buffer (CAWindow *ca)
|
|
985
|
+
{
|
|
986
|
+
int8_t k;
|
|
987
|
+
for ( k = 0; k < ca->ndim; k++ ) {
|
|
988
|
+
if ( ca->bounds[k] != CA_BOUNDS_FILL && ca->bounds[k] != CA_BOUNDS_MASK ) {
|
|
989
|
+
return 0;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return ca_parent_lends_no_memory(ca->parent);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
/* The parent's storage the alias path points into: inner axes full and
|
|
996
|
+
interior, so the window is one contiguous run of the attached parent. */
|
|
997
|
+
static char *
|
|
998
|
+
ca_window_alias_ptr (CAWindow *ca)
|
|
999
|
+
{
|
|
1000
|
+
ca_size_t parent_row_stride = ca->bytes;
|
|
1001
|
+
int8_t k;
|
|
1002
|
+
for (k = ca->ndim - 1; k >= 1; k--) parent_row_stride *= ca->parent->dim[k];
|
|
1003
|
+
return ca->parent->ptr + ca->start[0] * parent_row_stride;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/* Agrees with attach on the alias path: sync has nothing to write back
|
|
1007
|
+
and detach frees nothing there, so a buffer of our own would take the
|
|
1008
|
+
writes and be dropped. */
|
|
955
1009
|
static void
|
|
956
1010
|
ca_window_func_allocate (void *ap)
|
|
957
1011
|
{
|
|
958
1012
|
CAWindow *ca = (CAWindow *) ap;
|
|
1013
|
+
if ( ca_window_owns_buffer(ca) ) {
|
|
1014
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
959
1017
|
ca_attach(ca->parent);
|
|
960
|
-
|
|
961
|
-
|
|
1018
|
+
if ( ca->embed_alias_eligible ) {
|
|
1019
|
+
ca->ptr = ca_window_alias_ptr(ca);
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
962
1023
|
}
|
|
963
1024
|
|
|
964
1025
|
/* The engine paths below emit a per-axis descriptor (ca_window_describe_axes)
|
|
@@ -973,6 +1034,10 @@ static void
|
|
|
973
1034
|
ca_window_func_attach (void *ap)
|
|
974
1035
|
{
|
|
975
1036
|
CAWindow *ca = (CAWindow *) ap;
|
|
1037
|
+
if ( ca_window_owns_buffer(ca) ) {
|
|
1038
|
+
ca_axis_view_attach_owned(ca);
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
976
1041
|
ca_attach(ca->parent);
|
|
977
1042
|
if ( ca->embed_alias_eligible ) {
|
|
978
1043
|
/* Alias path: inner axes full + interior, so the embedded region is a
|
|
@@ -981,10 +1046,7 @@ ca_window_func_attach (void *ap)
|
|
|
981
1046
|
CAREFUL: sync and detach must agree with this — sync has nothing to
|
|
982
1047
|
scatter back (the writes already landed in the parent) and detach must
|
|
983
1048
|
not xfree a pointer it does not own. */
|
|
984
|
-
|
|
985
|
-
int8_t k;
|
|
986
|
-
for (k = ca->ndim - 1; k >= 1; k--) parent_row_stride *= ca->parent->dim[k];
|
|
987
|
-
ca->ptr = ca->parent->ptr + ca->start[0] * parent_row_stride;
|
|
1049
|
+
ca->ptr = ca_window_alias_ptr(ca);
|
|
988
1050
|
} else if ( ca->embed_eligible ) {
|
|
989
1051
|
/* Embed path: allocate, then 1 fill + 1 strided memcpy. */
|
|
990
1052
|
ca_size_t out_len = ca->elements * ca->bytes;
|
|
@@ -1005,6 +1067,10 @@ static void
|
|
|
1005
1067
|
ca_window_func_sync (void *ap)
|
|
1006
1068
|
{
|
|
1007
1069
|
CAWindow *ca = (CAWindow *) ap;
|
|
1070
|
+
if ( ca_window_owns_buffer(ca) ) {
|
|
1071
|
+
ca_axis_view_sync_owned(ca);
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1008
1074
|
if ( ca->embed_alias_eligible ) {
|
|
1009
1075
|
/* Alias path: ca->ptr aliases the parent, so the writes already landed
|
|
1010
1076
|
in parent storage. Nothing to scatter back. */
|
|
@@ -1025,6 +1091,11 @@ static void
|
|
|
1025
1091
|
ca_window_func_detach (void *ap)
|
|
1026
1092
|
{
|
|
1027
1093
|
CAWindow *ca = (CAWindow *) ap;
|
|
1094
|
+
if ( ca_window_owns_buffer(ca) ) {
|
|
1095
|
+
xfree(ca->ptr);
|
|
1096
|
+
ca->ptr = NULL;
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1028
1099
|
/* Alias path: ca->ptr aliases parent storage; it is not ours to xfree. */
|
|
1029
1100
|
if ( ! ca->embed_alias_eligible ) {
|
|
1030
1101
|
xfree(ca->ptr);
|
|
@@ -1117,9 +1188,25 @@ ca_window_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1117
1188
|
}
|
|
1118
1189
|
}
|
|
1119
1190
|
|
|
1120
|
-
/*
|
|
1121
|
-
|
|
1122
|
-
|
|
1191
|
+
/* A parent with no memory to lend is asked for the cells of the window
|
|
1192
|
+
only, through xfer_stride over the whole view, when the bounds let that
|
|
1193
|
+
go row by row (see ca_window_owns_buffer). */
|
|
1194
|
+
if ( ca_window_owns_buffer(ca) ) {
|
|
1195
|
+
ca_size_t starts[CA_RANK_MAX], strides[CA_RANK_MAX], s;
|
|
1196
|
+
int8_t k;
|
|
1197
|
+
s = ca->bytes;
|
|
1198
|
+
for ( k = ca->ndim - 1; k >= 0; k-- ) {
|
|
1199
|
+
starts[k] = 0;
|
|
1200
|
+
strides[k] = s;
|
|
1201
|
+
s *= ca->dim[k];
|
|
1202
|
+
}
|
|
1203
|
+
ca_window_func_xfer_stride(ca, starts, ca->dim, strides, data, dir);
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
/* Any other cold parent: materialise it into a scratch buffer via
|
|
1208
|
+
ca_xfer_all, then run the normal fast path with the scratch standing in
|
|
1209
|
+
for parent->ptr. */
|
|
1123
1210
|
{
|
|
1124
1211
|
volatile VALUE holder;
|
|
1125
1212
|
CArray *parent = ca->parent;
|
|
@@ -1137,12 +1224,14 @@ ca_window_func_xfer_all (void *ap, void *data, int dir)
|
|
|
1137
1224
|
|
|
1138
1225
|
ca_window_func_run_fast_path(ca, (char *) data, dir);
|
|
1139
1226
|
|
|
1227
|
+
/* Put parent->ptr back before the PUT: the PUT can raise (a lazy
|
|
1228
|
+
backing's sync failing), and the scratch is gone once this
|
|
1229
|
+
frame is. */
|
|
1230
|
+
parent->ptr = parent_ptr_saved;
|
|
1140
1231
|
if ( dir == CA_XFER_PUT ) {
|
|
1141
1232
|
/* Push back scratch (modified by scatter) to parent. */
|
|
1142
1233
|
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
1143
1234
|
}
|
|
1144
|
-
|
|
1145
|
-
parent->ptr = parent_ptr_saved;
|
|
1146
1235
|
ALLOCV_END(holder);
|
|
1147
1236
|
}
|
|
1148
1237
|
}
|
|
@@ -1238,8 +1327,7 @@ ca_window_func_fill_data (void *ap, void *ptr)
|
|
|
1238
1327
|
ca_attach(ca->parent);
|
|
1239
1328
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1240
1329
|
ca->elements, ptr);
|
|
1241
|
-
|
|
1242
|
-
ca_detach(ca->parent);
|
|
1330
|
+
ca_sync_detach(ca->parent);
|
|
1243
1331
|
}
|
|
1244
1332
|
|
|
1245
1333
|
static void
|
|
@@ -1251,10 +1339,7 @@ ca_window_func_create_mask (void *ap)
|
|
|
1251
1339
|
int8_t i;
|
|
1252
1340
|
int any_mask;
|
|
1253
1341
|
|
|
1254
|
-
|
|
1255
|
-
if ( ! ca->parent->mask ) {
|
|
1256
|
-
ca_create_mask(ca->parent);
|
|
1257
|
-
}
|
|
1342
|
+
ca_create_mask(ca->parent);
|
|
1258
1343
|
|
|
1259
1344
|
/* Any MASK axis of the view becomes FILL in the mask sub-view, with the
|
|
1260
1345
|
mask cell forced to 1 (= "masked"). Other axes keep their policy. When
|
|
@@ -1270,8 +1355,15 @@ ca_window_func_create_mask (void *ap)
|
|
|
1270
1355
|
}
|
|
1271
1356
|
fill = any_mask ? 1 : 0;
|
|
1272
1357
|
|
|
1273
|
-
|
|
1274
|
-
|
|
1358
|
+
/* The mask has the view's own type, so CAShift (which shares this table)
|
|
1359
|
+
gets a CAShiftMask. */
|
|
1360
|
+
{
|
|
1361
|
+
CAWindow *m = (CAWindow *) ca_array_alloc(ca->obj_type, ca->ndim);
|
|
1362
|
+
ca_window_setup(m, ca->parent->mask,
|
|
1363
|
+
ca->start, ca->count, mbounds, (char*)&fill);
|
|
1364
|
+
m->obj_type = ca->obj_type;
|
|
1365
|
+
ca->mask = (CArray *) m;
|
|
1366
|
+
}
|
|
1275
1367
|
}
|
|
1276
1368
|
|
|
1277
1369
|
ca_operation_function_t ca_window_func = {
|
|
@@ -1416,12 +1508,18 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1416
1508
|
}
|
|
1417
1509
|
|
|
1418
1510
|
if ( ! NIL_P(rbounds) ) {
|
|
1511
|
+
/* A Symbol says the same thing as the String, and is what the window
|
|
1512
|
+
iterator (CArray#windows) is given -- accept both so the two spellings
|
|
1513
|
+
of one policy do not diverge. */
|
|
1514
|
+
if ( SYMBOL_P(rbounds) ) {
|
|
1515
|
+
rbounds = rb_sym2str(rbounds);
|
|
1516
|
+
}
|
|
1419
1517
|
switch ( TYPE(rbounds) ) {
|
|
1420
1518
|
case T_STRING:
|
|
1421
1519
|
cbounds = StringValuePtr(rbounds);
|
|
1422
1520
|
if ( rfval == CA_UNDEF && strncmp(cbounds, "fill", 4)
|
|
1423
1521
|
&& strncmp(cbounds, "mask", 4) ) {
|
|
1424
|
-
rb_raise(
|
|
1522
|
+
rb_raise(rb_eArgError, "conflicted bounds and fill_value");
|
|
1425
1523
|
}
|
|
1426
1524
|
if ( ! strncmp(cbounds, "ruby", 4) ) {
|
|
1427
1525
|
bounds = CA_BOUNDS_RUBY;
|
|
@@ -1452,7 +1550,7 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1452
1550
|
bounds = CA_BOUNDS_FILL;
|
|
1453
1551
|
}
|
|
1454
1552
|
else {
|
|
1455
|
-
rb_raise(
|
|
1553
|
+
rb_raise(rb_eArgError,
|
|
1456
1554
|
"unknown option value '%s' for :bounds", cbounds);
|
|
1457
1555
|
}
|
|
1458
1556
|
break;
|
|
@@ -1460,7 +1558,7 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1460
1558
|
bounds = NUM2INT(rbounds);
|
|
1461
1559
|
break;
|
|
1462
1560
|
default:
|
|
1463
|
-
rb_raise(
|
|
1561
|
+
rb_raise(rb_eArgError, "invalid option value for :bounds");
|
|
1464
1562
|
}
|
|
1465
1563
|
}
|
|
1466
1564
|
|
|
@@ -1485,6 +1583,7 @@ rb_ca_window_initialize_copy (VALUE self, VALUE other)
|
|
|
1485
1583
|
CAWindow *ca, *cs;
|
|
1486
1584
|
|
|
1487
1585
|
TypedData_Get_Struct(self, CAWindow, &cawindow_data_type, ca);
|
|
1586
|
+
ca_check_uninitialized(ca);
|
|
1488
1587
|
TypedData_Get_Struct(other, CAWindow, &cawindow_data_type, cs);
|
|
1489
1588
|
|
|
1490
1589
|
/* `self` came from rb_ca_window_s_allocate (TypedData_Make_Struct,
|
|
@@ -1582,6 +1681,34 @@ rb_ca_window_get_bounds (VALUE self)
|
|
|
1582
1681
|
return SIZE2NUM(cw->bounds[0]);
|
|
1583
1682
|
}
|
|
1584
1683
|
|
|
1684
|
+
/* The boundary rule on each axis, one Symbol per axis. `bounds` answers
|
|
1685
|
+
for axis 0 only, which is all CArray#window sets; a shift with `roll:`
|
|
1686
|
+
on some axes sets them one by one. */
|
|
1687
|
+
static VALUE
|
|
1688
|
+
rb_ca_window_axis_bounds (VALUE self)
|
|
1689
|
+
{
|
|
1690
|
+
volatile VALUE ary;
|
|
1691
|
+
CAWindow *cw;
|
|
1692
|
+
const char *name;
|
|
1693
|
+
int8_t i;
|
|
1694
|
+
TypedData_Get_Struct(self, CAWindow, &cawindow_data_type, cw);
|
|
1695
|
+
ary = rb_ary_new2(cw->ndim);
|
|
1696
|
+
for (i=0; i<cw->ndim; i++) {
|
|
1697
|
+
switch ( cw->bounds[i] ) {
|
|
1698
|
+
case CA_BOUNDS_RUBY: name = "ruby"; break;
|
|
1699
|
+
case CA_BOUNDS_STRICT: name = "strict"; break;
|
|
1700
|
+
case CA_BOUNDS_NEAREST: name = "nearest"; break;
|
|
1701
|
+
case CA_BOUNDS_PERIODIC: name = "periodic"; break;
|
|
1702
|
+
case CA_BOUNDS_REFLECT: name = "reflect"; break;
|
|
1703
|
+
case CA_BOUNDS_FILL: name = "fill"; break;
|
|
1704
|
+
case CA_BOUNDS_MASK: name = "mask"; break;
|
|
1705
|
+
default: name = "unknown"; break;
|
|
1706
|
+
}
|
|
1707
|
+
rb_ary_store(ary, i, ID2SYM(rb_intern(name)));
|
|
1708
|
+
}
|
|
1709
|
+
return ary;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1585
1712
|
#define rb_cw_get_attr_ary(name) \
|
|
1586
1713
|
rb_cw_## name (VALUE self) \
|
|
1587
1714
|
{ \
|
|
@@ -1597,7 +1724,6 @@ rb_ca_window_get_bounds (VALUE self)
|
|
|
1597
1724
|
}
|
|
1598
1725
|
|
|
1599
1726
|
static VALUE rb_cw_get_attr_ary(start);
|
|
1600
|
-
static VALUE rb_cw_get_attr_ary(count);
|
|
1601
1727
|
static VALUE rb_cw_get_attr_ary(size0);
|
|
1602
1728
|
|
|
1603
1729
|
#ifdef CARRAY_DEV_BUILD
|
|
@@ -1680,8 +1806,10 @@ Init_ca_obj_window (void)
|
|
|
1680
1806
|
|
|
1681
1807
|
rb_define_method(rb_cCAWindow, "bounds", rb_ca_window_get_bounds, 0);
|
|
1682
1808
|
|
|
1809
|
+
/* No `count` accessor: the per-axis window widths are what `shape`
|
|
1810
|
+
already answers, and the name belongs to CArray#count. */
|
|
1683
1811
|
rb_define_method(rb_cCAWindow, "start", rb_cw_start, 0);
|
|
1684
|
-
rb_define_method(rb_cCAWindow, "
|
|
1812
|
+
rb_define_method(rb_cCAWindow, "__axis_bounds__", rb_ca_window_axis_bounds, 0);
|
|
1685
1813
|
rb_define_method(rb_cCAWindow, "size0", rb_cw_size0, 0);
|
|
1686
1814
|
|
|
1687
1815
|
#ifdef CARRAY_DEV_BUILD
|
data/ext/ca_op_ipower.c
CHANGED
|
@@ -168,6 +168,19 @@ ca_ipower_cmplx128_t (ca_size_t n, boolean8_t *m,
|
|
|
168
168
|
while (n--) { (*p2) = op_powi_cmplx128_t(*p1, ipow); p1++; p2++; }
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
/* The data types the ipower kernels cover; checked before any window
|
|
172
|
+
opens, so the switches inside cannot fall through to a raise. */
|
|
173
|
+
static int
|
|
174
|
+
ca_ipower_type_ok (CArray *ca)
|
|
175
|
+
{
|
|
176
|
+
switch ( ca->data_type ) {
|
|
177
|
+
case CA_FLOAT32: case CA_FLOAT64: case CA_CMPLX64: case CA_CMPLX128:
|
|
178
|
+
return 1;
|
|
179
|
+
default:
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
171
184
|
/* Eager Float/Complex ** Integer producing a fresh entity output.
|
|
172
185
|
* ca is input-only, co is the write target. Mirrors rb_ca_call_monop
|
|
173
186
|
* (see carray_math* / carray_kernels.c) so operand attach is elided:
|
|
@@ -189,6 +202,10 @@ rb_ca_ipower (VALUE self, VALUE other)
|
|
|
189
202
|
|
|
190
203
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
191
204
|
|
|
205
|
+
if ( ! ca_ipower_type_ok(ca) ) {
|
|
206
|
+
rb_raise(rb_eCADataTypeError, "invalid data type for ipower");
|
|
207
|
+
}
|
|
208
|
+
|
|
192
209
|
co = ca_has_mask(ca) ? ca_template_safe(ca) : ca_template(ca);
|
|
193
210
|
obj = ca_wrap_struct(co);
|
|
194
211
|
|
|
@@ -196,7 +213,7 @@ rb_ca_ipower (VALUE self, VALUE other)
|
|
|
196
213
|
m = ( co->mask ) ? (boolean8_t *)co->mask->ptr : NULL;
|
|
197
214
|
|
|
198
215
|
if ( ca_attach_is_alias(ca) ) {
|
|
199
|
-
ca_attach(ca);
|
|
216
|
+
ca_attach(ca); /* window: nothing raises inside */
|
|
200
217
|
switch ( ca->data_type ) {
|
|
201
218
|
case CA_FLOAT32:
|
|
202
219
|
ca_ipower_float32_t(ca->elements, m, ca->ptr, ipow, co->ptr); break;
|
|
@@ -206,8 +223,6 @@ rb_ca_ipower (VALUE self, VALUE other)
|
|
|
206
223
|
ca_ipower_cmplx64_t(ca->elements, m, ca->ptr, ipow, co->ptr); break;
|
|
207
224
|
case CA_CMPLX128:
|
|
208
225
|
ca_ipower_cmplx128_t(ca->elements, m, ca->ptr, ipow, co->ptr); break;
|
|
209
|
-
default:
|
|
210
|
-
rb_raise(rb_eCADataTypeError, "invalid data type for ipower");
|
|
211
226
|
}
|
|
212
227
|
ca_detach(ca);
|
|
213
228
|
}
|
|
@@ -226,9 +241,6 @@ rb_ca_ipower (VALUE self, VALUE other)
|
|
|
226
241
|
ca_ipower_cmplx64_t(ca->elements, m, p1, ipow, co->ptr); break;
|
|
227
242
|
case CA_CMPLX128:
|
|
228
243
|
ca_ipower_cmplx128_t(ca->elements, m, p1, ipow, co->ptr); break;
|
|
229
|
-
default:
|
|
230
|
-
ALLOCV_END(h1);
|
|
231
|
-
rb_raise(rb_eCADataTypeError, "invalid data type for ipower");
|
|
232
244
|
}
|
|
233
245
|
ALLOCV_END(h1);
|
|
234
246
|
}
|
|
@@ -247,7 +259,11 @@ rb_ca_ipower_bang (VALUE self, VALUE other)
|
|
|
247
259
|
|
|
248
260
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
249
261
|
|
|
250
|
-
|
|
262
|
+
if ( ! ca_ipower_type_ok(ca) ) {
|
|
263
|
+
rb_raise(rb_eRuntimeError, "invalid data type for ipower");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
ca_attach(ca); /* window: nothing raises inside until ca_sync_detach */
|
|
251
267
|
|
|
252
268
|
m = ( ca->mask ) ? (boolean8_t *)ca->mask->ptr : NULL;
|
|
253
269
|
|
|
@@ -260,12 +276,9 @@ rb_ca_ipower_bang (VALUE self, VALUE other)
|
|
|
260
276
|
ca_ipower_cmplx64_t(ca->elements, m, ca->ptr, ipow, ca->ptr); break;
|
|
261
277
|
case CA_CMPLX128:
|
|
262
278
|
ca_ipower_cmplx128_t(ca->elements, m, ca->ptr, ipow, ca->ptr); break;
|
|
263
|
-
default:
|
|
264
|
-
rb_raise(rb_eRuntimeError, "invalid data type for ipower");
|
|
265
279
|
}
|
|
266
280
|
|
|
267
|
-
|
|
268
|
-
ca_detach(ca);
|
|
281
|
+
ca_sync_detach(ca);
|
|
269
282
|
|
|
270
283
|
return self;
|
|
271
284
|
}
|
|
@@ -273,8 +286,7 @@ rb_ca_ipower_bang (VALUE self, VALUE other)
|
|
|
273
286
|
/* CArray#pow(other) (alias `**`) — Float/Complex ** Integer takes the
|
|
274
287
|
* ipower fast path in this file; everything else falls through to the
|
|
275
288
|
* mkkernel-generated general pow/cpow (rb_ca_power in
|
|
276
|
-
* ext/carray_kernels.c).
|
|
277
|
-
* wrapping on the result. */
|
|
289
|
+
* ext/carray_kernels.c). */
|
|
278
290
|
static VALUE rb_ca_pow (VALUE self, VALUE other)
|
|
279
291
|
{
|
|
280
292
|
volatile VALUE obj;
|
data/ext/ca_op_powi.h
CHANGED
|
@@ -23,9 +23,19 @@
|
|
|
23
23
|
#include "carray.h"
|
|
24
24
|
#include <stdint.h>
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
/* The text between the two markers below is also handed, as it stands, to
|
|
27
|
+
an evaluator that compiles a kernel body calling op_powi_<type>
|
|
28
|
+
(CArray.__kernel_helpers__, written into the build by mkkernel.rb). It
|
|
29
|
+
may use only <stdint.h>, float32_t / float64_t and ca_zerodiv: what such
|
|
30
|
+
an evaluator's C declares. The complex instantiations stay outside. */
|
|
31
|
+
|
|
32
|
+
/* BEGIN kernel helpers */
|
|
33
|
+
|
|
34
|
+
/* x raised to a non-negative power, by binary exponentiation. The power
|
|
35
|
+
is unsigned so that the magnitude of INT64_MIN is representable. */
|
|
36
|
+
#define op_powi_magnitude(type) \
|
|
27
37
|
static inline type \
|
|
28
|
-
|
|
38
|
+
op_powi_mag_## type (type x, uint64_t p) \
|
|
29
39
|
{ \
|
|
30
40
|
type r=1; \
|
|
31
41
|
\
|
|
@@ -35,53 +45,70 @@ op_powi_## type (type x, int64_t p) \
|
|
|
35
45
|
case 0: return 1; \
|
|
36
46
|
case 1: return x; \
|
|
37
47
|
} \
|
|
38
|
-
if (p<0) { \
|
|
39
|
-
type den = op_powi_## type(x, -p); \
|
|
40
|
-
if (den==0) ca_zerodiv(); \
|
|
41
|
-
return 1/den; \
|
|
42
|
-
}\
|
|
43
48
|
while (p) { \
|
|
44
|
-
if (
|
|
49
|
+
if ( p & 1 ) r *= x; \
|
|
45
50
|
x *= x; \
|
|
46
|
-
p
|
|
51
|
+
p >>= 1; \
|
|
47
52
|
} \
|
|
48
53
|
return r; \
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
|
|
56
|
+
/* An integer to a negative power is 1/x^|p| in integer division, which is
|
|
57
|
+
decided by x alone: 0 has no reciprocal, 1 and -1 keep their magnitude,
|
|
58
|
+
anything larger truncates to 0. Answering it that way, rather than by
|
|
59
|
+
computing x^|p|, keeps a power that overflows -- 2 ** -64 -- from wrapping
|
|
60
|
+
to a zero divisor. */
|
|
61
|
+
#define op_powi(type) \
|
|
62
|
+
op_powi_magnitude(type) \
|
|
52
63
|
static inline type \
|
|
53
64
|
op_powi_## type (type x, int64_t p) \
|
|
54
65
|
{ \
|
|
55
|
-
|
|
56
|
-
\
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
case 0: return 1; \
|
|
61
|
-
case 1: return x; \
|
|
66
|
+
if ( p < 0 ) { \
|
|
67
|
+
if ( x == 0 ) ca_zerodiv(); \
|
|
68
|
+
if ( x == 1 ) return 1; \
|
|
69
|
+
if ( x == (type) -1 ) return ( p % 2 ) ? x : 1; \
|
|
70
|
+
return 0; \
|
|
62
71
|
} \
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
return op_powi_mag_## type(x, (uint64_t) p); \
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* An unsigned x is never -1; (type) -1 is its largest value. */
|
|
76
|
+
#define op_powi_u(type) \
|
|
77
|
+
op_powi_magnitude(type) \
|
|
78
|
+
static inline type \
|
|
79
|
+
op_powi_## type (type x, int64_t p) \
|
|
80
|
+
{ \
|
|
81
|
+
if ( p < 0 ) { \
|
|
82
|
+
if ( x == 0 ) ca_zerodiv(); \
|
|
83
|
+
return ( x == 1 ) ? 1 : 0; \
|
|
71
84
|
} \
|
|
72
|
-
return
|
|
85
|
+
return op_powi_mag_## type(x, (uint64_t) p); \
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#define op_powi_fc(type) \
|
|
89
|
+
op_powi_magnitude(type) \
|
|
90
|
+
static inline type \
|
|
91
|
+
op_powi_## type (type x, int64_t p) \
|
|
92
|
+
{ \
|
|
93
|
+
if ( p < 0 ) { \
|
|
94
|
+
return 1 / op_powi_mag_## type(x, (uint64_t) 0 - (uint64_t) p); \
|
|
95
|
+
} \
|
|
96
|
+
return op_powi_mag_## type(x, (uint64_t) p); \
|
|
73
97
|
}
|
|
74
98
|
|
|
75
99
|
op_powi(int8_t)
|
|
76
|
-
|
|
100
|
+
op_powi_u(uint8_t)
|
|
77
101
|
op_powi(int16_t)
|
|
78
|
-
|
|
102
|
+
op_powi_u(uint16_t)
|
|
79
103
|
op_powi(int32_t)
|
|
80
|
-
|
|
104
|
+
op_powi_u(uint32_t)
|
|
81
105
|
op_powi(int64_t)
|
|
82
|
-
|
|
106
|
+
op_powi_u(uint64_t)
|
|
83
107
|
op_powi_fc(float32_t)
|
|
84
108
|
op_powi_fc(float64_t)
|
|
109
|
+
|
|
110
|
+
/* END kernel helpers */
|
|
111
|
+
|
|
85
112
|
op_powi_fc(cmplx64_t)
|
|
86
113
|
op_powi_fc(cmplx128_t)
|
|
87
114
|
|