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_select_axis.c
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
- single INDIRECT axis (boolean), other axes AP (nil/Integer/Range)
|
|
13
13
|
- parent must be an entity CArray (no CAStride parent)
|
|
14
14
|
- selector copied at construction (fully static, fragility-free)
|
|
15
|
-
-
|
|
15
|
+
- a masked selector cell selects nothing (same rule as CASelect)
|
|
16
16
|
- slab copy uses straightforward nested-loop memcpy (no SIMD fast paths)
|
|
17
17
|
|
|
18
18
|
---------------------------------------------------------------------------- */
|
|
19
19
|
|
|
20
20
|
#include "carray.h"
|
|
21
|
+
#include "carray_internal.h" /* ca_select_snapshot */
|
|
21
22
|
|
|
22
23
|
typedef struct {
|
|
23
24
|
/* CAView prefix (mirrors carray.h ca_virtual layout) */
|
|
@@ -112,9 +113,11 @@ static int8_t CA_OBJ_SELECT_AXIS;
|
|
|
112
113
|
|
|
113
114
|
/* Benchmark-only bypass flag: when non-zero, rb_ca_grid skips the
|
|
114
115
|
CASelectAxis dispatch hook and falls through to the pre-CSA CAGrid path.
|
|
115
|
-
Exposed to Ruby as CArray._csa_bypass
|
|
116
|
+
Exposed to Ruby as CArray._csa_bypass= in development builds.
|
|
117
|
+
Production code never touches it. */
|
|
116
118
|
int ca_csa_dispatch_bypass = 0;
|
|
117
119
|
|
|
120
|
+
#ifdef CARRAY_DEV_BUILD
|
|
118
121
|
static VALUE
|
|
119
122
|
rb_ca_s_csa_bypass_eq (VALUE klass, VALUE val)
|
|
120
123
|
{
|
|
@@ -129,6 +132,7 @@ rb_ca_s_csa_bypass_p (VALUE klass)
|
|
|
129
132
|
(void) klass;
|
|
130
133
|
return ca_csa_dispatch_bypass ? Qtrue : Qfalse;
|
|
131
134
|
}
|
|
135
|
+
#endif
|
|
132
136
|
|
|
133
137
|
static VALUE rb_cCASelectAxis;
|
|
134
138
|
static VALUE rb_cCASelectAxisMask;
|
|
@@ -175,22 +179,18 @@ ca_select_axis_setup (CASelectAxis *ca, CArray *parent, int8_t indirect_axis,
|
|
|
175
179
|
(int) indirect_axis,
|
|
176
180
|
(long long) parent->dim[indirect_axis]);
|
|
177
181
|
}
|
|
178
|
-
if ( ca_has_mask(selector) ) {
|
|
179
|
-
rb_raise(rb_eArgError,
|
|
180
|
-
"CASelectAxis: selector boolean array must not have a mask. "
|
|
181
|
-
"Use `selector.strip_mask(false)` etc. to flatten first.");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
182
|
/* Validate AP axes */
|
|
185
183
|
for ( k = 0; k < ndim; k++ ) {
|
|
186
184
|
if ( k == indirect_axis ) continue;
|
|
187
185
|
if ( ap_step[k] == 0 ) {
|
|
188
186
|
rb_raise(rb_eArgError, "CASelectAxis: ap_step[%d] is 0", (int) k);
|
|
189
187
|
}
|
|
190
|
-
if ( ap_count[k]
|
|
191
|
-
rb_raise(rb_eArgError, "CASelectAxis: ap_count[%d]
|
|
188
|
+
if ( ap_count[k] < 0 ) {
|
|
189
|
+
rb_raise(rb_eArgError, "CASelectAxis: ap_count[%d] is negative", (int) k);
|
|
192
190
|
}
|
|
193
|
-
|
|
191
|
+
/* A zero count (an axis of length zero) selects no cells: the view is
|
|
192
|
+
empty and there is no first or last index to check. */
|
|
193
|
+
if ( ap_count[k] > 0 ) {
|
|
194
194
|
ca_size_t start_v = ap_start[k];
|
|
195
195
|
ca_size_t last_v = ap_start[k] + (ap_count[k] - 1) * ap_step[k];
|
|
196
196
|
if ( start_v < 0 || start_v >= parent->dim[k] ) {
|
|
@@ -222,8 +222,9 @@ ca_select_axis_setup (CASelectAxis *ca, CArray *parent, int8_t indirect_axis,
|
|
|
222
222
|
|
|
223
223
|
/* Copy selector (view owns its own copy; immune to external mutation).
|
|
224
224
|
The selector is small (1 axis length), so the copy cost is acceptable,
|
|
225
|
-
and it avoids the fragility CASelect has from live references.
|
|
226
|
-
|
|
225
|
+
and it avoids the fragility CASelect has from live references. A
|
|
226
|
+
masked selector cell selects nothing, as it does for CASelect. */
|
|
227
|
+
ca->selector = ca_select_snapshot(selector);
|
|
227
228
|
|
|
228
229
|
/* Allocate dim and AP arrays (pool path: already wired by pool_init). */
|
|
229
230
|
if ( ! ca->_pool ) {
|
|
@@ -548,6 +549,7 @@ static void
|
|
|
548
549
|
ca_select_axis_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
549
550
|
ca_size_t *strides, void *data, int dir)
|
|
550
551
|
{
|
|
552
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
551
553
|
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
552
554
|
CArray *parent = ca->parent;
|
|
553
555
|
int8_t ndim = ca->ndim;
|
|
@@ -710,25 +712,34 @@ ca_select_axis_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
710
712
|
}
|
|
711
713
|
}
|
|
712
714
|
|
|
715
|
+
/* A parent with no memory to lend (ca_parent_lends_no_memory) is never
|
|
716
|
+
attached: the view owns its buffer, filled and drained through xfer_all,
|
|
717
|
+
which asks the parent for the selected cells only. The predicate asks
|
|
718
|
+
what the parent is, not whether it is attached now, so attach, sync and
|
|
719
|
+
detach all take the same branch. */
|
|
720
|
+
|
|
713
721
|
static void
|
|
714
722
|
ca_select_axis_func_allocate (void *ap)
|
|
715
723
|
{
|
|
716
724
|
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
717
|
-
|
|
725
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
726
|
+
ca_attach(ca->parent);
|
|
727
|
+
}
|
|
718
728
|
ca->ptr = xmalloc(ca_length(ca));
|
|
719
729
|
}
|
|
720
730
|
|
|
721
|
-
/* attach / sync / copy_data / sync_data / fill_data all go through the
|
|
722
|
-
common descriptor engine. This file holds only describe_axes for
|
|
723
|
-
translating CSA state into the shared descriptor; the engine in
|
|
724
|
-
ext/ca_axis_dispatch.c does the rest. */
|
|
725
|
-
|
|
726
731
|
static void
|
|
727
732
|
ca_select_axis_func_attach (void *ap)
|
|
728
733
|
{
|
|
729
734
|
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
730
735
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
731
736
|
ca_size_t pdims[CA_RANK_MAX];
|
|
737
|
+
|
|
738
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
739
|
+
ca_axis_view_attach_owned(ca);
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
|
|
732
743
|
ca_attach(ca->parent);
|
|
733
744
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
734
745
|
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
@@ -741,6 +752,12 @@ ca_select_axis_func_sync (void *ap)
|
|
|
741
752
|
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
742
753
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
743
754
|
ca_size_t pdims[CA_RANK_MAX];
|
|
755
|
+
|
|
756
|
+
if ( ca_parent_lends_no_memory(ca->parent) ) {
|
|
757
|
+
ca_axis_view_sync_owned(ca);
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
|
|
744
761
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
745
762
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
746
763
|
ca->elements, ca->ptr);
|
|
@@ -756,16 +773,16 @@ ca_select_axis_func_detach (void *ap)
|
|
|
756
773
|
ca->ptr = NULL;
|
|
757
774
|
}
|
|
758
775
|
/* indices[] lives for the view's lifetime; freed in free_ca_select_axis. */
|
|
759
|
-
|
|
776
|
+
if ( ! ca_parent_lends_no_memory(ca->parent) ) {
|
|
777
|
+
ca_detach(ca->parent);
|
|
778
|
+
}
|
|
760
779
|
}
|
|
761
780
|
|
|
762
|
-
/*
|
|
763
|
-
of the parent. A cold parent uses a proper 2-pass (materialise the
|
|
764
|
-
parent into scratch, expose it as parent->ptr, run the fast path, then
|
|
765
|
-
write scratch back for PUT). */
|
|
781
|
+
/* The transfer against parent->ptr, for ca_axis_view_xfer_all. */
|
|
766
782
|
static void
|
|
767
|
-
ca_select_axis_func_run_fast_path (
|
|
783
|
+
ca_select_axis_func_run_fast_path (void *ap, char *data, int dir)
|
|
768
784
|
{
|
|
785
|
+
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
769
786
|
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
770
787
|
ca_size_t pdims[CA_RANK_MAX];
|
|
771
788
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
@@ -781,27 +798,7 @@ ca_select_axis_func_run_fast_path (CASelectAxis *ca, char *data, int dir)
|
|
|
781
798
|
static void
|
|
782
799
|
ca_select_axis_func_xfer_all (void *ap, void *data, int dir)
|
|
783
800
|
{
|
|
784
|
-
|
|
785
|
-
if ( ca->parent->ptr ) {
|
|
786
|
-
ca_select_axis_func_run_fast_path(ca, (char *) data, dir);
|
|
787
|
-
return;
|
|
788
|
-
}
|
|
789
|
-
/* Proper 2-pass cold fallback. */
|
|
790
|
-
{
|
|
791
|
-
volatile VALUE holder;
|
|
792
|
-
CArray *parent = ca->parent;
|
|
793
|
-
ca_size_t plen = parent->elements * parent->bytes;
|
|
794
|
-
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
795
|
-
char *parent_ptr_saved = parent->ptr;
|
|
796
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
797
|
-
parent->ptr = parent_scratch;
|
|
798
|
-
ca_select_axis_func_run_fast_path(ca, (char *) data, dir);
|
|
799
|
-
if ( dir == CA_XFER_PUT ) {
|
|
800
|
-
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
801
|
-
}
|
|
802
|
-
parent->ptr = parent_ptr_saved;
|
|
803
|
-
ALLOCV_END(holder);
|
|
804
|
-
}
|
|
801
|
+
ca_axis_view_xfer_all(ap, ca_select_axis_func_run_fast_path, 1, data, dir);
|
|
805
802
|
}
|
|
806
803
|
|
|
807
804
|
static void
|
|
@@ -824,21 +821,17 @@ ca_select_axis_func_fill_data (void *ap, void *val)
|
|
|
824
821
|
return;
|
|
825
822
|
}
|
|
826
823
|
|
|
827
|
-
ca_attach(ca->parent);
|
|
824
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
828
825
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
829
826
|
ca->elements, val);
|
|
830
|
-
|
|
831
|
-
ca_detach(ca->parent);
|
|
827
|
+
ca_sync_detach(ca->parent);
|
|
832
828
|
}
|
|
833
829
|
|
|
834
830
|
static void
|
|
835
831
|
ca_select_axis_func_create_mask (void *ap)
|
|
836
832
|
{
|
|
837
833
|
CASelectAxis *ca = (CASelectAxis *) ap;
|
|
838
|
-
|
|
839
|
-
if ( ! ca->parent->mask ) {
|
|
840
|
-
ca_create_mask(ca->parent);
|
|
841
|
-
}
|
|
834
|
+
ca_create_mask(ca->parent);
|
|
842
835
|
ca->mask = ca_select_axis_new(ca->parent->mask, ca->indirect_axis,
|
|
843
836
|
ca->selector,
|
|
844
837
|
ca->ap_start, ca->ap_count, ca->ap_step);
|
|
@@ -878,6 +871,7 @@ rb_ca_select_axis_initialize_copy (VALUE self, VALUE other)
|
|
|
878
871
|
{
|
|
879
872
|
CASelectAxis *ca, *cs;
|
|
880
873
|
TypedData_Get_Struct(self, CASelectAxis, &caselectaxis_data_type, ca);
|
|
874
|
+
ca_check_uninitialized(ca);
|
|
881
875
|
TypedData_Get_Struct(other, CASelectAxis, &caselectaxis_data_type, cs);
|
|
882
876
|
if ( ca_func[CA_OBJ_SELECT_AXIS].pool_init ) {
|
|
883
877
|
ca_array_pool_alloc(ca, CA_OBJ_SELECT_AXIS, cs->parent->ndim);
|
|
@@ -887,6 +881,7 @@ rb_ca_select_axis_initialize_copy (VALUE self, VALUE other)
|
|
|
887
881
|
return self;
|
|
888
882
|
}
|
|
889
883
|
|
|
884
|
+
#ifdef CARRAY_DEV_BUILD
|
|
890
885
|
/* Debug-only Ruby ctor:
|
|
891
886
|
CASelectAxis._new_debug(parent, indirect_axis, selector,
|
|
892
887
|
ap_start_arr, ap_count_arr, ap_step_arr)
|
|
@@ -937,6 +932,7 @@ rb_ca_select_axis_s_new_debug (VALUE klass, VALUE rparent, VALUE rindirect,
|
|
|
937
932
|
rb_ivar_set(obj, rb_intern("_selector"), rselector);
|
|
938
933
|
return obj;
|
|
939
934
|
}
|
|
935
|
+
#endif
|
|
940
936
|
|
|
941
937
|
/* ------------------------------------------------------------------- */
|
|
942
938
|
/* Indexer dispatch hook: called from rb_ca_grid */
|
|
@@ -1188,7 +1184,7 @@ rb_ca_select_axis_dispatch_attach_debug (VALUE self)
|
|
|
1188
1184
|
TypedData_Get_Struct(self, CASelectAxis, &caselectaxis_data_type, ca);
|
|
1189
1185
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
1190
1186
|
|
|
1191
|
-
ca_attach(ca->parent);
|
|
1187
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1192
1188
|
buf = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1193
1189
|
ca->elements, NULL);
|
|
1194
1190
|
ca_detach(ca->parent);
|
|
@@ -1222,11 +1218,10 @@ rb_ca_select_axis_dispatch_scatter_debug (VALUE self, VALUE in_str)
|
|
|
1222
1218
|
ca_size_t pdims[CA_RANK_MAX];
|
|
1223
1219
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
1224
1220
|
|
|
1225
|
-
ca_attach(ca->parent);
|
|
1221
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1226
1222
|
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1227
1223
|
ca->elements, RSTRING_PTR(in_str));
|
|
1228
|
-
|
|
1229
|
-
ca_detach(ca->parent);
|
|
1224
|
+
ca_sync_detach(ca->parent);
|
|
1230
1225
|
return Qnil;
|
|
1231
1226
|
}
|
|
1232
1227
|
|
|
@@ -1250,11 +1245,10 @@ rb_ca_select_axis_dispatch_fill_value_debug (VALUE self, VALUE val_str)
|
|
|
1250
1245
|
ca_size_t pdims[CA_RANK_MAX];
|
|
1251
1246
|
ca_select_axis_describe_axes(ca, desc, pdims);
|
|
1252
1247
|
|
|
1253
|
-
ca_attach(ca->parent);
|
|
1248
|
+
ca_attach(ca->parent); /* window: nothing raises inside */
|
|
1254
1249
|
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
1255
1250
|
ca->elements, RSTRING_PTR(val_str));
|
|
1256
|
-
|
|
1257
|
-
ca_detach(ca->parent);
|
|
1251
|
+
ca_sync_detach(ca->parent);
|
|
1258
1252
|
return Qnil;
|
|
1259
1253
|
}
|
|
1260
1254
|
#endif /* CARRAY_DEV_BUILD */
|
|
@@ -1281,9 +1275,11 @@ Init_ca_obj_select_axis (void)
|
|
|
1281
1275
|
rb_define_alloc_func(rb_cCASelectAxis, rb_ca_select_axis_s_allocate);
|
|
1282
1276
|
rb_define_method(rb_cCASelectAxis, "initialize_copy",
|
|
1283
1277
|
rb_ca_select_axis_initialize_copy, 1);
|
|
1278
|
+
#ifdef CARRAY_DEV_BUILD
|
|
1284
1279
|
/* Debug-only ctor for testing; not part of the public API. */
|
|
1285
1280
|
rb_define_singleton_method(rb_cCASelectAxis, "_new_debug",
|
|
1286
1281
|
rb_ca_select_axis_s_new_debug, 6);
|
|
1282
|
+
#endif
|
|
1287
1283
|
|
|
1288
1284
|
#ifdef CARRAY_DEV_BUILD
|
|
1289
1285
|
/* debug accessors (dev-only, stripped in release).
|
|
@@ -1300,7 +1296,9 @@ Init_ca_obj_select_axis (void)
|
|
|
1300
1296
|
rb_ca_select_axis_dispatch_fill_value_debug, 1);
|
|
1301
1297
|
#endif
|
|
1302
1298
|
|
|
1299
|
+
#ifdef CARRAY_DEV_BUILD
|
|
1303
1300
|
/* Benchmark-only bypass setter on CArray class. */
|
|
1304
1301
|
rb_define_singleton_method(rb_cCArray, "_csa_bypass=", rb_ca_s_csa_bypass_eq, 1);
|
|
1305
1302
|
rb_define_singleton_method(rb_cCArray, "_csa_bypass?", rb_ca_s_csa_bypass_p, 0);
|
|
1303
|
+
#endif
|
|
1306
1304
|
}
|
data/ext/ca_obj_shift.c
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
sync_data / fill_data / ptr_at_* / fetch_index / store_index) are
|
|
9
9
|
shared with CAWindow's per-axis bounds engine via the `ca_shift_func`
|
|
10
10
|
table, which is built by copying `ca_window_func` and only overriding
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
clone, so that cloning produces a CAShift. create_mask is shared: it
|
|
12
|
+
gives the mask the view's own obj_type.
|
|
13
13
|
|
|
14
14
|
User surface (CArray#shift) is documented in yard-stubs/ca_obj_shift.rb.
|
|
15
15
|
|
|
@@ -31,11 +31,13 @@ extern int ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
31
31
|
(rb_data_type_t *) cast would write into .rodata and SIGBUS on macOS. */
|
|
32
32
|
static size_t ca_shift_dsize (const void *ap);
|
|
33
33
|
|
|
34
|
+
extern void ca_window_mark (void *ap); /* ca_obj_window.c: marks the fill value */
|
|
35
|
+
|
|
34
36
|
const rb_data_type_t cashift_data_type = {
|
|
35
|
-
.parent = &
|
|
37
|
+
.parent = &cawindow_data_type,
|
|
36
38
|
.wrap_struct_name = "CAShift",
|
|
37
39
|
.function = {
|
|
38
|
-
.dmark =
|
|
40
|
+
.dmark = ca_window_mark,
|
|
39
41
|
.dfree = ca_free,
|
|
40
42
|
.dsize = ca_shift_dsize,
|
|
41
43
|
.dcompact = NULL
|
|
@@ -44,7 +46,7 @@ const rb_data_type_t cashift_data_type = {
|
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
/* CAREFUL: mask TypedData uses ca_free_nop. The mask CArray is owned
|
|
47
|
-
by the parent CAShift's `ca->mask` field and freed by
|
|
49
|
+
by the parent CAShift's `ca->mask` field and freed by the shared window free's
|
|
48
50
|
ca_free(ca->mask). If the wrapped Ruby VALUE (from the `ca.mask`
|
|
49
51
|
accessor / rb_ca_mask_array) also freed it, the result is a
|
|
50
52
|
double-free that explodes under GC stress. */
|
|
@@ -105,10 +107,13 @@ ca_shift_setup (CAShift *ca, CArray *parent,
|
|
|
105
107
|
/* Delegate to CAWindow setup. */
|
|
106
108
|
ca_window_setup((CAWindow *) ca, parent, start, count, bounds, fill);
|
|
107
109
|
|
|
110
|
+
if ( ca == NULL ) { /* checks only, see ca_window_setup */
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
|
|
108
114
|
/* Override obj_type so dispatch (ca_func[obj_type]) lands on the
|
|
109
115
|
CAShift-specific table (which differs from CAWindow only in
|
|
110
|
-
|
|
111
|
-
result). */
|
|
116
|
+
clone). */
|
|
112
117
|
ca->obj_type = CA_OBJ_SHIFT;
|
|
113
118
|
|
|
114
119
|
return 0;
|
|
@@ -118,37 +123,13 @@ CAShift *
|
|
|
118
123
|
ca_shift_new (CArray *parent, ca_size_t *shift, char *fill, int8_t *roll,
|
|
119
124
|
int fill_mask)
|
|
120
125
|
{
|
|
121
|
-
CAShift *ca
|
|
126
|
+
CAShift *ca;
|
|
127
|
+
ca_shift_setup(NULL, parent, shift, fill, roll, fill_mask);
|
|
128
|
+
ca = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, parent->ndim);
|
|
122
129
|
ca_shift_setup(ca, parent, shift, fill, roll, fill_mask);
|
|
123
130
|
return ca;
|
|
124
131
|
}
|
|
125
132
|
|
|
126
|
-
/* Free: same fields as CAWindow (same struct). CAShift goes through
|
|
127
|
-
ca_window_setup, so the same seven ndim-sized fields live in ca->_pool
|
|
128
|
-
(fill stays separate). */
|
|
129
|
-
static void
|
|
130
|
-
free_ca_shift (void *ap)
|
|
131
|
-
{
|
|
132
|
-
CAShift *ca = (CAShift *) ap;
|
|
133
|
-
if ( ca != NULL ) {
|
|
134
|
-
ca_free(ca->mask);
|
|
135
|
-
xfree(ca->fill); /* always separate (bytes-sized) */
|
|
136
|
-
if ( ca->_pool ) {
|
|
137
|
-
ca_array_free(ca);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
xfree(ca->bounds);
|
|
141
|
-
xfree(ca->start);
|
|
142
|
-
xfree(ca->count);
|
|
143
|
-
xfree(ca->size0);
|
|
144
|
-
xfree(ca->embed_parent_start);
|
|
145
|
-
xfree(ca->embed_count);
|
|
146
|
-
xfree(ca->embed_output_offset);
|
|
147
|
-
xfree(ca);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
133
|
/* Clone: produce a CAShift (not CAWindow) by rebuilding via setup.
|
|
153
134
|
Recover (shift[], roll[], fill_mask) from current (start[], bounds[]). */
|
|
154
135
|
static void *
|
|
@@ -174,69 +155,6 @@ ca_shift_func_clone (void *ap)
|
|
|
174
155
|
return ca_shift_new(ca->parent, shift, ca->fill, roll, fill_mask);
|
|
175
156
|
}
|
|
176
157
|
|
|
177
|
-
/* create_mask: produce a CAShift-typed mask (not CAWindow-typed).
|
|
178
|
-
Following the original ca_shift_func_create_mask semantics:
|
|
179
|
-
- Ensure parent has mask
|
|
180
|
-
- Build mask sub-view using same shift/roll, fill = 1 if fill_mask
|
|
181
|
-
else 0 (i.e. range-outside cells get masked when fill_mask was on,
|
|
182
|
-
unmasked otherwise) */
|
|
183
|
-
static void
|
|
184
|
-
ca_shift_func_create_mask (void *ap)
|
|
185
|
-
{
|
|
186
|
-
CAShift *ca = (CAShift *) ap;
|
|
187
|
-
ca_size_t shift[CA_RANK_MAX];
|
|
188
|
-
int8_t roll[CA_RANK_MAX];
|
|
189
|
-
boolean8_t fill_val;
|
|
190
|
-
int fill_mask_was_on = 0;
|
|
191
|
-
int8_t k;
|
|
192
|
-
|
|
193
|
-
ca_update_mask(ca->parent);
|
|
194
|
-
if ( ! ca->parent->mask ) {
|
|
195
|
-
ca_create_mask(ca->parent);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
for (k = 0; k < ca->ndim; k++) {
|
|
199
|
-
shift[k] = -ca->start[k];
|
|
200
|
-
if ( ca->bounds[k] == CA_BOUNDS_PERIODIC ) {
|
|
201
|
-
roll[k] = 1;
|
|
202
|
-
} else {
|
|
203
|
-
roll[k] = 0;
|
|
204
|
-
if ( ca->bounds[k] == CA_BOUNDS_MASK ) fill_mask_was_on = 1;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/* If MASK policy was set, the mask sub-view should mark out-of-range
|
|
209
|
-
cells as "masked" (fill value = 1). Otherwise out-of-range cells
|
|
210
|
-
get the fill value (fill = 0) and aren't masked. */
|
|
211
|
-
fill_val = fill_mask_was_on ? 1 : 0;
|
|
212
|
-
|
|
213
|
-
/* Build the mask as CAShift with same shift/roll but using fill_mask=0
|
|
214
|
-
(the mask itself shouldn't recursively create a mask) and fill = 0/1
|
|
215
|
-
boolean. Bounds for mask: replace MASK→FILL so the mask values are
|
|
216
|
-
written, not the mask's mask. */
|
|
217
|
-
{
|
|
218
|
-
/* Construct mask via direct ca_window_new with adjusted bounds. */
|
|
219
|
-
uint8_t mbounds[CA_RANK_MAX];
|
|
220
|
-
ca_size_t mstart[CA_RANK_MAX];
|
|
221
|
-
ca_size_t mcount[CA_RANK_MAX];
|
|
222
|
-
CAShift *m;
|
|
223
|
-
CA_ASSUME(ca->ndim >= 0 && ca->ndim <= CA_RANK_MAX); /* bound loop over [CA_RANK_MAX] arrays */
|
|
224
|
-
for (k = 0; k < ca->ndim; k++) {
|
|
225
|
-
mstart[k] = ca->start[k];
|
|
226
|
-
mcount[k] = ca->count[k];
|
|
227
|
-
mbounds[k] = ( ca->bounds[k] == CA_BOUNDS_MASK )
|
|
228
|
-
? CA_BOUNDS_FILL : ca->bounds[k];
|
|
229
|
-
}
|
|
230
|
-
/* CAShift-typed mask: allocate, setup as CAWindow with adjusted
|
|
231
|
-
bounds, bump obj_type. */
|
|
232
|
-
m = (CAShift *) ca_array_alloc(CA_OBJ_SHIFT, ca->ndim);
|
|
233
|
-
ca_window_setup((CAWindow *) m, ca->parent->mask,
|
|
234
|
-
mstart, mcount, mbounds, (char *) &fill_val);
|
|
235
|
-
m->obj_type = CA_OBJ_SHIFT;
|
|
236
|
-
ca->mask = (CArray *) m;
|
|
237
|
-
}
|
|
238
|
-
(void) shift; (void) roll; /* recovered above but unused in this block */
|
|
239
|
-
}
|
|
240
158
|
|
|
241
159
|
/* ------------------------------------------------------------------- */
|
|
242
160
|
|
|
@@ -319,9 +237,12 @@ rb_ca_shift (int argc, VALUE *argv, VALUE self)
|
|
|
319
237
|
fill_mask = 1;
|
|
320
238
|
}
|
|
321
239
|
else {
|
|
322
|
-
|
|
240
|
+
/* The fill is a value of the array (a struct, an instant for a Face):
|
|
241
|
+
rb_ca_obj2ptr writes it as one cell of the storage. */
|
|
242
|
+
rcs = rb_cscalar_new(ca_strip_face(ca)->data_type, ca->bytes, NULL);
|
|
323
243
|
TypedData_Get_Struct(rcs, CScalar, &cscalar_data_type, cs);
|
|
324
244
|
fill = cs->ptr;
|
|
245
|
+
rb_ca_obj2ptr(self, rfval, fill);
|
|
325
246
|
}
|
|
326
247
|
|
|
327
248
|
if ( NIL_P(rroll) ) {
|
|
@@ -366,6 +287,7 @@ rb_ca_shift_initialize_copy (VALUE self, VALUE other)
|
|
|
366
287
|
int8_t k;
|
|
367
288
|
|
|
368
289
|
TypedData_Get_Struct(self, CAShift, &cashift_data_type, ca);
|
|
290
|
+
ca_check_uninitialized(ca);
|
|
369
291
|
TypedData_Get_Struct(other, CAShift, &cashift_data_type, cs);
|
|
370
292
|
|
|
371
293
|
/* Recover shift/roll/fill_mask from cs (same scheme as clone). */
|
|
@@ -395,12 +317,10 @@ rb_ca_shift_initialize_copy (VALUE self, VALUE other)
|
|
|
395
317
|
void
|
|
396
318
|
Init_ca_obj_shift (void)
|
|
397
319
|
{
|
|
398
|
-
/* Build the CAShift op table by copying CAWindow's
|
|
399
|
-
|
|
320
|
+
/* Build the CAShift op table by copying CAWindow's; only clone has to
|
|
321
|
+
rebuild a CAShift. */
|
|
400
322
|
ca_shift_func = ca_window_func;
|
|
401
|
-
ca_shift_func.free_object = free_ca_shift;
|
|
402
323
|
ca_shift_func.clone = ca_shift_func_clone;
|
|
403
|
-
ca_shift_func.create_mask = ca_shift_func_create_mask;
|
|
404
324
|
|
|
405
325
|
rb_cCAShift = rb_define_class("CAShift", rb_cCAWindow);
|
|
406
326
|
rb_cCAShiftMask = rb_define_class("CAShiftMask", rb_cCAShift);
|