carray 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +5 -25
- data/CHANGELOG.md +16 -0
- data/LICENSE +1 -1
- data/NEWS.md +3 -0
- data/README.md +128 -44
- data/carray.gemspec +22 -24
- data/ext/ca_array_pool.c +91 -0
- data/ext/ca_axis_descriptor.h +186 -0
- data/ext/ca_axis_dispatch.c +924 -0
- data/ext/ca_axis_group.c +1208 -0
- data/ext/ca_bincmp_dispatch.c +76 -0
- data/ext/ca_bincmp_dispatch.h +85 -0
- data/ext/ca_binop_dispatch.c +125 -0
- data/ext/ca_binop_dispatch.h +159 -0
- data/ext/ca_categorical_iterator.c +1375 -0
- data/ext/ca_compare.c +94 -0
- data/ext/ca_compare.h +26 -0
- data/ext/ca_composite_dispatch.c +414 -0
- data/ext/ca_composite_dispatch.h +116 -0
- data/ext/ca_for_buffer.h +96 -0
- data/ext/ca_for_each_element.h +241 -0
- data/ext/ca_group_iter.c +304 -0
- data/ext/ca_iter_substrate.h +325 -0
- data/ext/ca_kernel_iterator.c +4321 -0
- data/ext/ca_kernel_iterator.h +2603 -0
- data/ext/ca_moncmp_dispatch.c +37 -0
- data/ext/ca_moncmp_dispatch.h +62 -0
- data/ext/ca_monop_dispatch.c +200 -0
- data/ext/ca_monop_dispatch.h +235 -0
- data/ext/ca_obj_array.c +355 -359
- data/ext/ca_obj_bincmp.c +809 -0
- data/ext/ca_obj_binop.c +892 -0
- data/ext/ca_obj_bitarray.c +369 -164
- data/ext/ca_obj_bitfield.c +294 -234
- data/ext/ca_obj_block.c +189 -711
- data/ext/ca_obj_byte_swap.c +766 -0
- data/ext/ca_obj_const_string.c +965 -0
- data/ext/ca_obj_face.c +670 -0
- data/ext/ca_obj_face.h +247 -0
- data/ext/ca_obj_fake.c +228 -100
- data/ext/ca_obj_farray.c +54 -441
- data/ext/ca_obj_field.c +82 -529
- data/ext/ca_obj_fixlen_string.c +306 -0
- data/ext/ca_obj_grid.c +858 -440
- data/ext/ca_obj_meld.c +1034 -0
- data/ext/ca_obj_moncmp.c +569 -0
- data/ext/ca_obj_monop.c +1111 -0
- data/ext/ca_obj_object.c +774 -298
- data/ext/ca_obj_record.c +468 -0
- data/ext/ca_obj_reduce.c +97 -82
- data/ext/ca_obj_refer.c +569 -459
- data/ext/ca_obj_remap.c +475 -0
- data/ext/ca_obj_repeat.c +92 -477
- data/ext/ca_obj_roll.c +616 -0
- data/ext/ca_obj_select.c +344 -296
- data/ext/ca_obj_select_axis.c +1296 -0
- data/ext/ca_obj_shift.c +230 -792
- data/ext/ca_obj_source.c +78 -0
- data/ext/ca_obj_stack.c +1173 -0
- data/ext/ca_obj_stride.c +2501 -0
- data/ext/ca_obj_string.c +268 -0
- data/ext/ca_obj_tile.c +614 -0
- data/ext/ca_obj_time.c +546 -0
- data/ext/ca_obj_timedelta.c +435 -0
- data/ext/ca_obj_transpose.c +62 -516
- data/ext/ca_obj_triop.c +746 -0
- data/ext/ca_obj_unbound_repeat.c +208 -241
- data/ext/ca_obj_window.c +1131 -563
- data/ext/ca_op_byte_swap.c +175 -0
- data/ext/ca_op_ipower.c +319 -0
- data/ext/ca_op_powi.h +88 -0
- data/ext/ca_sort_kernels.h +132 -0
- data/ext/ca_sweep_engine.c +430 -0
- data/ext/ca_sweep_engine.h +157 -0
- data/ext/ca_transform_common.c +228 -0
- data/ext/ca_triop_dispatch.c +55 -0
- data/ext/ca_triop_dispatch.h +62 -0
- data/ext/carray.h +795 -402
- data/ext/carray_access.c +831 -711
- data/ext/carray_attribute.c +98 -330
- data/ext/carray_bincount.c +255 -0
- data/ext/carray_broadcast.c +283 -0
- data/ext/carray_call_cfunc.c +1360 -828
- data/ext/carray_call_cfunc.h +160 -0
- data/ext/carray_cast.c +1212 -301
- data/ext/carray_cast_func.rb +81 -40
- data/ext/carray_class.c +53 -63
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +350 -346
- data/ext/carray_copy.c +156 -268
- data/ext/carray_core.c +1342 -199
- data/ext/carray_count.c +312 -0
- data/ext/carray_data_type.c +43 -19
- data/ext/carray_element.c +585 -213
- data/ext/carray_factorize.c +2542 -0
- data/ext/carray_generate.c +230 -559
- data/ext/carray_histogram.c +490 -0
- data/ext/carray_hold.c +228 -0
- data/ext/carray_index_classifier.c +1035 -0
- data/ext/carray_index_classifier.h +27 -0
- data/ext/carray_internal.h +120 -0
- data/ext/carray_kernels_bincmp.c +4445 -0
- data/ext/carray_kernels_binop.c +10979 -0
- data/ext/carray_kernels_init.c +36 -0
- data/ext/carray_kernels_map.c +3466 -0
- data/ext/carray_kernels_moncmp.c +2096 -0
- data/ext/carray_kernels_monop.c +18312 -0
- data/ext/carray_kernels_reduce_aggregate.c +25836 -0
- data/ext/carray_kernels_reduce_boolean.c +329 -0
- data/ext/carray_kernels_reduce_cumulative.c +14592 -0
- data/ext/carray_kernels_reduce_extreme.c +16947 -0
- data/ext/carray_kernels_reduce_variance.c +3909 -0
- data/ext/carray_kernels_scan.c +3692 -0
- data/ext/carray_kernels_search.c +32137 -0
- data/ext/carray_kernels_sort.c +10625 -0
- data/ext/carray_kernels_triop.c +1391 -0
- data/ext/carray_lazy.c +567 -0
- data/ext/carray_loop.c +88 -200
- data/ext/carray_mask.c +848 -154
- data/ext/carray_math_kernel.h +120 -0
- data/ext/carray_mathfunc.c +10 -241
- data/ext/carray_median_percentile.c +1257 -0
- data/ext/carray_memory_view.c +1625 -0
- data/ext/carray_operator.c +1526 -318
- data/ext/carray_order.c +664 -1394
- data/ext/carray_partition.c +416 -0
- data/ext/carray_random.c +518 -0
- data/ext/carray_scatter.c +357 -0
- data/ext/carray_slab.c +1219 -0
- data/ext/carray_slab.h +84 -0
- data/ext/carray_sort.c +829 -0
- data/ext/carray_sort_kernel.c +620 -0
- data/ext/carray_struct.c +695 -0
- data/ext/carray_test.c +343 -229
- data/ext/carray_undef.c +34 -17
- data/ext/carray_utils.c +175 -74
- data/ext/extconf.rb +216 -55
- data/ext/mk_call_cfunc.rb +480 -0
- data/ext/mkkernel.rb +8842 -0
- data/ext/ruby_carray.c +202 -101
- data/ext/version.h +4 -14
- data/ext/version.rb +5 -13
- data/lib/carray/arrow_tensor.rb +401 -0
- data/lib/carray/attribute.rb +166 -0
- data/lib/carray/autoload_carray.rb +220 -0
- data/lib/carray/autoload_method_extension.rb +44 -0
- data/lib/carray/axis_group.rb +711 -0
- data/lib/carray/basics.rb +481 -0
- data/lib/carray/bincount_nd.rb +358 -0
- data/lib/carray/block_iterator.rb +604 -0
- data/lib/carray/boolean_reduce.rb +109 -0
- data/lib/carray/categorical.rb +561 -0
- data/lib/carray/categorical_iterator.rb +1062 -0
- data/lib/carray/complex.rb +150 -0
- data/lib/carray/conditional.rb +216 -0
- data/lib/carray/const_string.rb +228 -0
- data/lib/carray/construct.rb +139 -328
- data/lib/carray/core_extensions.rb +240 -0
- data/lib/carray/data_type_extension.rb +233 -0
- data/lib/carray/fixlen_string.rb +95 -0
- data/lib/carray/frame/concat.rb +132 -0
- data/lib/carray/frame/convert.rb +95 -0
- data/lib/carray/frame/csv_parser.rb +211 -0
- data/lib/carray/frame/frame.rb +649 -0
- data/lib/carray/frame/group.rb +186 -0
- data/lib/carray/frame/io.rb +164 -0
- data/lib/carray/frame/join.rb +248 -0
- data/lib/carray/frame/records.rb +99 -0
- data/lib/carray/frame/sort.rb +113 -0
- data/lib/carray/frame/verbs.rb +299 -0
- data/lib/carray/frame.rb +16 -0
- data/lib/carray/histogram.rb +512 -0
- data/lib/carray/inspect.rb +37 -20
- data/lib/carray/iterator.rb +57 -349
- data/lib/carray/lazy.rb +889 -0
- data/lib/carray/mask_gap_fill.rb +200 -0
- data/lib/carray/math.rb +78 -342
- data/lib/carray/meld_reduce.rb +289 -0
- data/lib/carray/methods/align_addr.rb +116 -0
- data/lib/carray/methods/bin.rb +128 -0
- data/lib/carray/methods/bincount.rb +87 -0
- data/lib/carray/methods/bit_string.rb +92 -0
- data/lib/carray/methods/broadcast.rb +63 -0
- data/lib/carray/methods/choose.rb +39 -0
- data/lib/carray/methods/composition.rb +280 -0
- data/lib/carray/methods/gather_nd.rb +206 -0
- data/lib/carray/methods/index.rb +39 -0
- data/lib/carray/methods/insert_block.rb +99 -0
- data/lib/carray/methods/is_in.rb +141 -0
- data/lib/carray/methods/join.rb +90 -0
- data/lib/carray/methods/locate_addr.rb +47 -0
- data/lib/carray/methods/mask_duplicates.rb +41 -0
- data/lib/carray/methods/meshgrid.rb +91 -0
- data/lib/carray/methods/mode.rb +126 -0
- data/lib/carray/methods/nunique.rb +46 -0
- data/lib/carray/methods/resize.rb +56 -0
- data/lib/carray/methods/snap.rb +156 -0
- data/lib/carray/methods/string_format.rb +57 -0
- data/lib/carray/methods/unique.rb +47 -0
- data/lib/carray/methods/value_counts.rb +71 -0
- data/lib/carray/mkmf.rb +124 -101
- data/lib/carray/runtime.rb +108 -0
- data/lib/carray/serialize.rb +478 -167
- data/lib/carray/slab_iterator.rb +292 -0
- data/lib/carray/stack.rb +291 -0
- data/lib/carray/string.rb +56 -180
- data/lib/carray/string_operation_extension.rb +289 -0
- data/lib/carray/struct.rb +335 -323
- data/lib/carray/struct_builder.rb +697 -0
- data/lib/carray/table.rb +41 -2
- data/lib/carray/time.rb +2255 -38
- data/lib/carray/window_iterator.rb +655 -0
- data/lib/carray.rb +55 -57
- metadata +163 -130
- data/Rakefile +0 -51
- data/TODO.md +0 -18
- data/ext/ca_iter_block.c +0 -257
- data/ext/ca_iter_dimension.c +0 -299
- data/ext/ca_iter_window.c +0 -214
- data/ext/ca_obj_mapping.c +0 -644
- data/ext/carray_iterator.c +0 -641
- data/ext/carray_math.rb +0 -850
- data/ext/carray_numeric.c +0 -259
- data/ext/carray_sort_addr.c +0 -254
- data/ext/carray_stat.c +0 -2100
- data/ext/carray_stat_proc.rb +0 -1999
- data/ext/mkmath.rb +0 -741
- data/ext/ruby_ccomplex.c +0 -509
- data/ext/ruby_float_func.c +0 -86
- data/lib/carray/array.rb +0 -8
- data/lib/carray/autoload/autoload_base.rb +0 -19
- data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
- data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
- data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
- data/lib/carray/autoload/autoload_gem_random.rb +0 -8
- data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
- data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
- data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
- data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
- data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
- data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
- data/lib/carray/autoload/autoload_object_link.rb +0 -1
- data/lib/carray/autoload/autoload_object_pack.rb +0 -2
- data/lib/carray/autoload.rb +0 -141
- data/lib/carray/basic.rb +0 -191
- data/lib/carray/broadcast.rb +0 -101
- data/lib/carray/compose.rb +0 -315
- data/lib/carray/convert.rb +0 -115
- data/lib/carray/info.rb +0 -110
- data/lib/carray/io/imagemagick.rb +0 -235
- data/lib/carray/mask.rb +0 -102
- data/lib/carray/math/histogram.rb +0 -177
- data/lib/carray/math/recurrence.rb +0 -93
- data/lib/carray/object/ca_obj_iterator.rb +0 -50
- data/lib/carray/object/ca_obj_link.rb +0 -50
- data/lib/carray/object/ca_obj_pack.rb +0 -99
- data/lib/carray/obsolete.rb +0 -256
- data/lib/carray/ordering.rb +0 -181
- data/lib/carray/testing.rb +0 -51
- data/lib/carray/transform.rb +0 -109
- data/misc/Methods.ja.md +0 -182
- data/misc/NOTE +0 -51
- data/spec/Classes/CABitfield_spec.rb +0 -58
- data/spec/Classes/CABlockIterator_spec.rb +0 -114
- data/spec/Classes/CABlock_spec.rb +0 -205
- data/spec/Classes/CAField_spec.rb +0 -39
- data/spec/Classes/CAGrid_spec.rb +0 -75
- data/spec/Classes/CAMap_spec.rb +0 -0
- data/spec/Classes/CAMapping_spec.rb +0 -105
- data/spec/Classes/CAObject_attribute_spec.rb +0 -33
- data/spec/Classes/CAObject_spec.rb +0 -33
- data/spec/Classes/CARefer_spec.rb +0 -93
- data/spec/Classes/CARepeat_spec.rb +0 -65
- data/spec/Classes/CASelect_spec.rb +0 -22
- data/spec/Classes/CAShift_spec.rb +0 -16
- data/spec/Classes/CAStruct_spec.rb +0 -71
- data/spec/Classes/CATranspose_spec.rb +0 -60
- data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
- data/spec/Classes/CAWindow_spec.rb +0 -54
- data/spec/Classes/CAWrap_spec.rb +0 -8
- data/spec/Classes/CArray_spec.rb +0 -184
- data/spec/Classes/CScalar_spec.rb +0 -55
- data/spec/Classes/ex1.rb +0 -46
- data/spec/Features/feature_130_spec.rb +0 -19
- data/spec/Features/feature_attributes_spec.rb +0 -280
- data/spec/Features/feature_boolean_spec.rb +0 -98
- data/spec/Features/feature_broadcast.rb +0 -116
- data/spec/Features/feature_cast_function.rb +0 -19
- data/spec/Features/feature_cast_spec.rb +0 -33
- data/spec/Features/feature_class_spec.rb +0 -84
- data/spec/Features/feature_complex_spec.rb +0 -42
- data/spec/Features/feature_composite_spec.rb +0 -124
- data/spec/Features/feature_convert_spec.rb +0 -46
- data/spec/Features/feature_copy_spec.rb +0 -123
- data/spec/Features/feature_creation_spec.rb +0 -84
- data/spec/Features/feature_element_spec.rb +0 -144
- data/spec/Features/feature_extream_spec.rb +0 -54
- data/spec/Features/feature_generate_spec.rb +0 -74
- data/spec/Features/feature_index_spec.rb +0 -69
- data/spec/Features/feature_mask_spec.rb +0 -580
- data/spec/Features/feature_math_spec.rb +0 -97
- data/spec/Features/feature_order_spec.rb +0 -146
- data/spec/Features/feature_ref_store_spec.rb +0 -209
- data/spec/Features/feature_serialization_spec.rb +0 -125
- data/spec/Features/feature_stat_spec.rb +0 -397
- data/spec/Features/feature_virtual_spec.rb +0 -48
- data/spec/Features/method_eq_spec.rb +0 -81
- data/spec/Features/method_is_nan_spec.rb +0 -12
- data/spec/Features/method_map_spec.rb +0 -54
- data/spec/Features/method_max_with.rb +0 -20
- data/spec/Features/method_min_with.rb +0 -19
- data/spec/Features/method_ne_spec.rb +0 -18
- data/spec/Features/method_project_spec.rb +0 -188
- data/spec/Features/method_ref_spec.rb +0 -27
- data/spec/Features/method_round_spec.rb +0 -11
- data/spec/Features/method_s_linspace_spec.rb +0 -48
- data/spec/Features/method_s_span_spec.rb +0 -14
- data/spec/Features/method_seq_spec.rb +0 -47
- data/spec/Features/method_sort_with.rb +0 -43
- data/spec/Features/method_sorted_with.rb +0 -29
- data/spec/Features/method_span_spec.rb +0 -42
- data/spec/Features/method_wrap_readonly_spec.rb +0 -43
- data/spec/UnitTest/test_CAVirtual.rb +0 -214
- data/spec/spec_all.rb +0 -10
- data/utils/ca_ase.rb +0 -21
- data/utils/ca_methods.rb +0 -15
- data/utils/cast_checker.rb +0 -30
- data/utils/convert_test.rb +0 -73
- data/utils/extract_yard.rb +0 -22
- data/utils/guess_shape.rb +0 -76
- data/utils/monkey_patch_methods.rb +0 -62
- data/utils/remove_resource_fork.sh +0 -5
data/ext/ca_obj_select.c
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
CASelect view: 1-D gather of the parent through a boolean selector.
|
|
4
|
+
The view snapshots the selector at construction time and pre-computes
|
|
5
|
+
`indices[]` (the flat parent positions where the selector is TRUE).
|
|
6
|
+
|
|
7
|
+
Sibling of ca_axis_dispatch.c (the per-axis descriptor engine).
|
|
8
|
+
attach / sync / xfer_all / xfer_stride / fill_data all dispatch
|
|
9
|
+
through `ca_axis_dispatch_*` with a single 1-D INDEX descriptor over
|
|
10
|
+
a flattened parent (parent_axis_dims = {parent->elements}). When
|
|
11
|
+
the TRUE positions form a constant-step run, the descriptor is
|
|
12
|
+
promoted to STRIDE kind so the engine's contig-memcpy fast path
|
|
13
|
+
becomes available.
|
|
8
14
|
|
|
9
15
|
---------------------------------------------------------------------------- */
|
|
10
16
|
|
|
11
17
|
#include "carray.h"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class CASelect < CAVirtual # :nodoc:
|
|
15
|
-
end
|
|
16
|
-
*/
|
|
18
|
+
#include "carray_internal.h" /* per-obj_type view constructors */
|
|
19
|
+
#include "ca_obj_face.h"
|
|
17
20
|
|
|
18
21
|
typedef struct {
|
|
19
22
|
int16_t obj_type;
|
|
@@ -25,21 +28,38 @@ typedef struct {
|
|
|
25
28
|
ca_size_t *dim; /* point to _dim */
|
|
26
29
|
char *ptr;
|
|
27
30
|
CArray *mask;
|
|
31
|
+
char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
|
|
28
32
|
CArray *parent;
|
|
29
33
|
uint32_t attach;
|
|
30
34
|
uint8_t nosync;
|
|
31
35
|
/* ---------- */
|
|
32
|
-
CArray
|
|
36
|
+
CArray *select; /* snapshot of selector (boolean array, owned) */
|
|
37
|
+
ca_size_t *indices; /* snapshot of TRUE positions in flat parent
|
|
38
|
+
(length = ca->elements; engine consumes this) */
|
|
39
|
+
/* Constant-step detection on indices[]. When TRUE positions form
|
|
40
|
+
an arithmetic progression (consecutive TRUE block, all-TRUE,
|
|
41
|
+
equally spaced), the descriptor is emitted as STRIDE kind
|
|
42
|
+
instead of INDEX to unlock the engine's contig-memcpy path. */
|
|
43
|
+
uint8_t stride_kind;
|
|
44
|
+
ca_size_t stride_start;
|
|
45
|
+
ca_size_t stride_step;
|
|
33
46
|
ca_size_t _dim;
|
|
34
47
|
} CASelect;
|
|
35
48
|
|
|
49
|
+
static size_t
|
|
50
|
+
ca_select_dsize (const void *ap)
|
|
51
|
+
{
|
|
52
|
+
/* CASelect: dim points to _dim inside struct, no separate allocation */
|
|
53
|
+
return sizeof(CASelect);
|
|
54
|
+
}
|
|
55
|
+
|
|
36
56
|
const rb_data_type_t caselect_data_type = {
|
|
37
|
-
.parent = &
|
|
57
|
+
.parent = &caview_data_type,
|
|
38
58
|
.wrap_struct_name = "CASelect",
|
|
39
59
|
.function = {
|
|
40
60
|
.dmark = ca_mark,
|
|
41
61
|
.dfree = ca_free,
|
|
42
|
-
.dsize =
|
|
62
|
+
.dsize = ca_select_dsize,
|
|
43
63
|
.dcompact = NULL
|
|
44
64
|
},
|
|
45
65
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
@@ -51,7 +71,7 @@ const rb_data_type_t caselect_mask_data_type = {
|
|
|
51
71
|
.function = {
|
|
52
72
|
.dmark = NULL,
|
|
53
73
|
.dfree = ca_free_nop,
|
|
54
|
-
.dsize =
|
|
74
|
+
.dsize = ca_select_dsize,
|
|
55
75
|
.dcompact = NULL
|
|
56
76
|
},
|
|
57
77
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
@@ -63,12 +83,16 @@ VALUE rb_cCASelectMask;
|
|
|
63
83
|
|
|
64
84
|
/* ------------------------------------------------------------------- */
|
|
65
85
|
|
|
86
|
+
/* Snapshot the selector into ca->select (always a copy) and pre-compute
|
|
87
|
+
ca->indices (TRUE positions in flat parent order). Masked selector
|
|
88
|
+
cells become false in the snapshot. After construction, mutating
|
|
89
|
+
the caller's live selector does not affect the view. */
|
|
66
90
|
static int
|
|
67
91
|
ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
68
92
|
{
|
|
69
93
|
int8_t data_type;
|
|
70
94
|
ca_size_t bytes;
|
|
71
|
-
|
|
95
|
+
ca_size_t i;
|
|
72
96
|
|
|
73
97
|
if ( ! ca_is_boolean_type(select) ) {
|
|
74
98
|
rb_raise(rb_eRuntimeError,
|
|
@@ -84,51 +108,79 @@ ca_select_setup (CASelect *ca, CArray *parent, CArray *select, int share)
|
|
|
84
108
|
ca->flags = 0;
|
|
85
109
|
ca->ndim = 1;
|
|
86
110
|
ca->bytes = bytes;
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
ca->ptr = NULL;
|
|
112
|
+
ca->mask = NULL;
|
|
113
|
+
ca->parent = parent;
|
|
114
|
+
ca->attach = 0;
|
|
115
|
+
ca->nosync = 0;
|
|
116
|
+
ca->indices = NULL;
|
|
117
|
+
|
|
118
|
+
/* The `share` argument is preserved for source compatibility but
|
|
119
|
+
no longer toggles a live-reference path; both paths copy.
|
|
120
|
+
Masked selector cells become false in the snapshot. */
|
|
121
|
+
(void) share;
|
|
122
|
+
if ( ca_has_mask(select) ) {
|
|
123
|
+
boolean8_t *p, *q, *m;
|
|
124
|
+
ca->select = ca_template(select);
|
|
125
|
+
ca_attach(select);
|
|
126
|
+
q = (boolean8_t *) ca->select->ptr;
|
|
127
|
+
p = (boolean8_t *) select->ptr;
|
|
128
|
+
m = (boolean8_t *) select->mask->ptr;
|
|
129
|
+
for (i = 0; i < select->elements; i++) {
|
|
130
|
+
*q = ( *m ) ? 0 : *p;
|
|
131
|
+
q++; p++; m++;
|
|
108
132
|
}
|
|
133
|
+
ca_detach(select);
|
|
134
|
+
} else {
|
|
135
|
+
ca->select = ca_copy(select);
|
|
109
136
|
}
|
|
110
137
|
|
|
138
|
+
/* Count TRUE positions and snapshot them into ca->indices. */
|
|
111
139
|
{
|
|
112
|
-
int count = 0;
|
|
113
140
|
boolean8_t *s = (boolean8_t *) ca->select->ptr;
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
141
|
+
ca_size_t count = 0;
|
|
142
|
+
for (i = 0; i < ca->select->elements; i++) {
|
|
143
|
+
if ( s[i] ) count++;
|
|
144
|
+
}
|
|
145
|
+
ca->elements = count;
|
|
146
|
+
/* Placeholder 1-element allocation when count == 0 to avoid
|
|
147
|
+
malloc(0) implementation variance; the engine treats
|
|
148
|
+
elements==0 as a no-op so the contents are irrelevant. */
|
|
149
|
+
ca->indices = (ca_size_t *) xmalloc(
|
|
150
|
+
sizeof(ca_size_t) * (count > 0 ? count : 1));
|
|
151
|
+
{
|
|
152
|
+
ca_size_t j = 0;
|
|
153
|
+
for (i = 0; i < ca->select->elements; i++) {
|
|
154
|
+
if ( s[i] ) ca->indices[j++] = i;
|
|
117
155
|
}
|
|
118
|
-
s++;
|
|
119
156
|
}
|
|
120
|
-
|
|
157
|
+
/* Constant-step detection: promotes to STRIDE descriptor kind
|
|
158
|
+
when TRUE positions form an arithmetic progression. */
|
|
159
|
+
ca->stride_kind = 0;
|
|
160
|
+
ca->stride_start = 0;
|
|
161
|
+
ca->stride_step = 1;
|
|
162
|
+
if ( count >= 2 ) {
|
|
163
|
+
ca_size_t step = ca->indices[1] - ca->indices[0];
|
|
164
|
+
ca_size_t k;
|
|
165
|
+
int is_const = 1;
|
|
166
|
+
for ( k = 2; k < count; k++ ) {
|
|
167
|
+
if ( ca->indices[k] - ca->indices[k-1] != step ) { is_const = 0; break; }
|
|
168
|
+
}
|
|
169
|
+
if ( is_const ) {
|
|
170
|
+
ca->stride_kind = 1;
|
|
171
|
+
ca->stride_start = ca->indices[0];
|
|
172
|
+
ca->stride_step = step;
|
|
173
|
+
}
|
|
174
|
+
} else if ( count == 1 ) {
|
|
175
|
+
ca->stride_kind = 1;
|
|
176
|
+
ca->stride_start = ca->indices[0];
|
|
177
|
+
ca->stride_step = 1;
|
|
178
|
+
}
|
|
121
179
|
}
|
|
122
180
|
|
|
123
|
-
ca->ptr = NULL;
|
|
124
|
-
ca->mask = NULL;
|
|
125
181
|
ca->dim = &(ca->_dim);
|
|
126
182
|
ca->dim[0] = ca->elements;
|
|
127
183
|
|
|
128
|
-
ca->parent = parent;
|
|
129
|
-
ca->attach = 0;
|
|
130
|
-
ca->nosync = 0;
|
|
131
|
-
|
|
132
184
|
if ( ca_is_scalar(select) ) {
|
|
133
185
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
134
186
|
}
|
|
@@ -144,6 +196,9 @@ ca_select_new (CArray *parent, CArray *select)
|
|
|
144
196
|
return (CArray*) ca;
|
|
145
197
|
}
|
|
146
198
|
|
|
199
|
+
/* Alias for source compatibility. Both constructors produce a
|
|
200
|
+
snapshot view; the `share` name is retained because a handful of
|
|
201
|
+
internal call sites still pass a `share` flag. */
|
|
147
202
|
CArray *
|
|
148
203
|
ca_select_new_share (CArray *parent, CArray *select)
|
|
149
204
|
{
|
|
@@ -158,18 +213,40 @@ free_ca_select (void *ap)
|
|
|
158
213
|
CASelect *ca = (CASelect *) ap;
|
|
159
214
|
if ( ca != NULL ) {
|
|
160
215
|
ca_free(ca->mask);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
216
|
+
ca_free(ca->select); /* the snapshot is always owned */
|
|
217
|
+
if ( ca->indices ) xfree(ca->indices);
|
|
164
218
|
xfree(ca);
|
|
165
219
|
}
|
|
166
220
|
}
|
|
167
221
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
222
|
+
/* ------------------------------------------------------------------- */
|
|
223
|
+
/* Producer for the per-axis descriptor engine: emit a single 1-D axis.
|
|
224
|
+
Writes 1 entry into `out` and `out_parent_dims`. parent_axis_dims[0]
|
|
225
|
+
is the flattened parent length, so the engine treats the parent as
|
|
226
|
+
1-D regardless of its original shape. */
|
|
227
|
+
|
|
228
|
+
void
|
|
229
|
+
ca_select_describe_axes (void *ap, ca_axis_desc_t *out,
|
|
230
|
+
ca_size_t *out_parent_dims)
|
|
231
|
+
{
|
|
232
|
+
CASelect *ca = (CASelect *) ap;
|
|
233
|
+
out_parent_dims[0] = ca->parent->elements;
|
|
234
|
+
if ( ca->stride_kind ) {
|
|
235
|
+
/* Constant-step run: emit STRIDE so the engine's contig-memcpy
|
|
236
|
+
fast path is available (all-TRUE, block-TRUE, equally-spaced). */
|
|
237
|
+
out[0].kind = CA_AXIS_KIND_STRIDE;
|
|
238
|
+
out[0].count = ca->elements;
|
|
239
|
+
out[0].start = ca->stride_start;
|
|
240
|
+
out[0].step = ca->stride_step;
|
|
241
|
+
out[0].indices = NULL;
|
|
242
|
+
} else {
|
|
243
|
+
out[0].kind = CA_AXIS_KIND_INDEX;
|
|
244
|
+
out[0].count = ca->elements;
|
|
245
|
+
out[0].start = 0;
|
|
246
|
+
out[0].step = 0;
|
|
247
|
+
out[0].indices = ca->indices;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
173
250
|
|
|
174
251
|
/* ------------------------------------------------------------------- */
|
|
175
252
|
|
|
@@ -180,107 +257,146 @@ ca_select_func_clone (void *ap)
|
|
|
180
257
|
return ca_select_new_share(ca->parent, ca->select);
|
|
181
258
|
}
|
|
182
259
|
|
|
183
|
-
static
|
|
184
|
-
ca_select_func_ptr_at_addr (void *ap, ca_size_t addr)
|
|
185
|
-
{
|
|
186
|
-
CASelect *ca = (CASelect *) ap;
|
|
187
|
-
|
|
188
|
-
if ( ca->ptr ) {
|
|
189
|
-
return ca->ptr + ca->bytes * addr;
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
ca_size_t n, i, a;
|
|
193
|
-
ca_size_t elements = ca->select->elements;
|
|
194
|
-
boolean8_t s;
|
|
195
|
-
|
|
196
|
-
n = 0;
|
|
197
|
-
a = 0;
|
|
198
|
-
|
|
199
|
-
for (i=0; i<elements; i++) {
|
|
200
|
-
ca_fetch_addr(ca->select, i, &s);
|
|
201
|
-
if ( s ) {
|
|
202
|
-
if ( addr == a++ ) {
|
|
203
|
-
n = i;
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if ( ca_is_attached(ca->parent) ) {
|
|
210
|
-
return ca->parent->ptr + ca->bytes * n;
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
return ca_ptr_at_addr(ca->parent, n);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
260
|
+
static void ca_select_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data, int dir);
|
|
217
261
|
|
|
218
|
-
static
|
|
219
|
-
|
|
262
|
+
static void
|
|
263
|
+
ca_select_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
220
264
|
{
|
|
221
|
-
|
|
222
|
-
ca_size_t addr = idx[0];
|
|
223
|
-
|
|
224
|
-
if ( ca->ptr ) {
|
|
225
|
-
return ca->ptr + ca->bytes * addr;
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
return ca_select_func_ptr_at_addr(ca, idx[0]);
|
|
229
|
-
}
|
|
265
|
+
ca_select_func_xfer_addrs(ap, 1, &idx[0], data, dir);
|
|
230
266
|
}
|
|
231
267
|
|
|
268
|
+
/* Translate the incoming address list through ca->indices and deliver
|
|
269
|
+
to the parent in one call.
|
|
270
|
+
|
|
271
|
+
Fast path: when `addrs` covers the whole view sequentially and the
|
|
272
|
+
parent is attached, the pre-built ca->indices is handed straight to
|
|
273
|
+
the descriptor engine (zero copy, no ALLOCV). This is the same
|
|
274
|
+
1-D-INDEX-over-flat-parent dispatch attach / sync use, so a chain
|
|
275
|
+
like `a[idx_2d]` (which reshape/CAGrid folds down to whole-view
|
|
276
|
+
sequential addrs on CASelect) also lands on the fast path. */
|
|
232
277
|
static void
|
|
233
|
-
|
|
278
|
+
ca_select_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
279
|
+
void *data, int dir)
|
|
234
280
|
{
|
|
235
|
-
CASelect
|
|
236
|
-
|
|
237
|
-
ca_size_t
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
281
|
+
CASelect *ca = (CASelect *) ap;
|
|
282
|
+
CArray *parent = ca->parent;
|
|
283
|
+
ca_size_t *paddrs;
|
|
284
|
+
ca_size_t i, base;
|
|
285
|
+
volatile VALUE holder;
|
|
286
|
+
|
|
287
|
+
if ( n == ca->elements
|
|
288
|
+
&& ca_xfer_addrs_is_sequential_run(n, addrs, &base) && base == 0 ) {
|
|
289
|
+
CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
|
|
290
|
+
if ( eff_parent->ptr ) {
|
|
291
|
+
ca_axis_desc_t sub_axes[1];
|
|
292
|
+
ca_size_t parent_axis_dims[1];
|
|
293
|
+
parent_axis_dims[0] = parent->elements;
|
|
294
|
+
if ( ca->stride_kind ) {
|
|
295
|
+
sub_axes[0].kind = CA_AXIS_KIND_STRIDE;
|
|
296
|
+
sub_axes[0].count = ca->elements;
|
|
297
|
+
sub_axes[0].start = ca->stride_start;
|
|
298
|
+
sub_axes[0].step = ca->stride_step;
|
|
299
|
+
sub_axes[0].indices = NULL;
|
|
300
|
+
} else {
|
|
301
|
+
sub_axes[0].kind = CA_AXIS_KIND_INDEX;
|
|
302
|
+
sub_axes[0].count = ca->elements;
|
|
303
|
+
sub_axes[0].start = 0;
|
|
304
|
+
sub_axes[0].step = 0;
|
|
305
|
+
sub_axes[0].indices = ca->indices;
|
|
306
|
+
}
|
|
307
|
+
if ( dir == CA_XFER_GET ) {
|
|
308
|
+
ca_axis_dispatch_gather(eff_parent, parent_axis_dims, sub_axes, 1,
|
|
309
|
+
ca->bytes, ca->elements, NULL, (char *) data);
|
|
310
|
+
} else {
|
|
311
|
+
ca_axis_dispatch_scatter(eff_parent, parent_axis_dims, sub_axes, 1,
|
|
312
|
+
ca->bytes, ca->elements, (char *) data);
|
|
247
313
|
}
|
|
314
|
+
return;
|
|
248
315
|
}
|
|
249
316
|
}
|
|
250
|
-
ca_fetch_addr(ca->parent, n, ptr);
|
|
251
|
-
}
|
|
252
317
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
{
|
|
256
|
-
|
|
318
|
+
/* Per-cell remap fallback (arbitrary addrs or unattached parent). */
|
|
319
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
320
|
+
for ( i = 0; i < n; i++ ) {
|
|
321
|
+
paddrs[i] = ca->indices[addrs[i]];
|
|
322
|
+
}
|
|
323
|
+
ca_xfer_addrs(ca->parent, n, paddrs, data, dir);
|
|
324
|
+
ALLOCV_END(holder);
|
|
257
325
|
}
|
|
258
326
|
|
|
327
|
+
/* CASelect is the never-fold gather boundary: the incoming strided
|
|
328
|
+
region request describes a 1-D access into the selection, which
|
|
329
|
+
the view translates to a parent address list and delegates in one
|
|
330
|
+
call. `data` is contiguous (row-major over counts).
|
|
331
|
+
|
|
332
|
+
Access into the selection is
|
|
333
|
+
position = starts[0] + i * (strides[0] / bytes)
|
|
334
|
+
and ca->indices[position] is the parent address. ca->indices is a
|
|
335
|
+
construction-time snapshot, so no attach is required. */
|
|
259
336
|
static void
|
|
260
|
-
|
|
337
|
+
ca_select_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
338
|
+
ca_size_t *strides, void *data, int dir)
|
|
261
339
|
{
|
|
262
|
-
CASelect
|
|
263
|
-
|
|
264
|
-
ca_size_t
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
340
|
+
CASelect *ca = (CASelect *) ap;
|
|
341
|
+
CArray *parent = ca->parent;
|
|
342
|
+
ca_size_t n = counts[0];
|
|
343
|
+
ca_size_t step = strides[0] / ca->bytes; /* element step (may be negative) */
|
|
344
|
+
ca_size_t start = starts[0];
|
|
345
|
+
|
|
346
|
+
/* Attached-parent fast path: translate the sub-region request
|
|
347
|
+
(start / n / step over the 1-D INDEX view) into a transient
|
|
348
|
+
ca_axis_desc_t[1] and dispatch through the engine directly,
|
|
349
|
+
without calling ca_attach(parent). Collapses the per-cell
|
|
350
|
+
ca_xfer_addrs loop into a single batched engine call. */
|
|
351
|
+
if ( parent->ptr ) {
|
|
352
|
+
ca_axis_desc_t sub_axes[1];
|
|
353
|
+
ca_size_t parent_axis_dims[1];
|
|
354
|
+
ca_size_t *index_buf = NULL;
|
|
355
|
+
volatile VALUE index_holder = Qnil;
|
|
356
|
+
|
|
357
|
+
parent_axis_dims[0] = parent->elements; /* parent flattened */
|
|
358
|
+
sub_axes[0].kind = CA_AXIS_KIND_INDEX;
|
|
359
|
+
sub_axes[0].count = n;
|
|
360
|
+
sub_axes[0].start = 0;
|
|
361
|
+
sub_axes[0].step = 0;
|
|
362
|
+
|
|
363
|
+
if ( step == 1 ) {
|
|
364
|
+
/* zero-copy pointer offset into precomputed indices[] */
|
|
365
|
+
sub_axes[0].indices = ca->indices + start;
|
|
366
|
+
} else {
|
|
367
|
+
/* sub-sampled or reversed: materialise sub-indices */
|
|
368
|
+
ca_size_t i;
|
|
369
|
+
index_buf = ALLOCV_N(ca_size_t, index_holder, n);
|
|
370
|
+
for ( i = 0; i < n; i++ ) {
|
|
371
|
+
index_buf[i] = ca->indices[start + i * step];
|
|
274
372
|
}
|
|
373
|
+
sub_axes[0].indices = index_buf;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if ( dir == CA_XFER_GET ) {
|
|
377
|
+
ca_axis_dispatch_gather(parent, parent_axis_dims, sub_axes, 1,
|
|
378
|
+
ca->bytes, n, NULL, (char *)data);
|
|
379
|
+
} else {
|
|
380
|
+
ca_axis_dispatch_scatter(parent, parent_axis_dims, sub_axes, 1,
|
|
381
|
+
ca->bytes, n, (char *)data);
|
|
275
382
|
}
|
|
383
|
+
|
|
384
|
+
if ( index_buf != NULL ) ALLOCV_END(index_holder);
|
|
385
|
+
return;
|
|
276
386
|
}
|
|
277
|
-
ca_store_addr(ca->parent, n, ptr);
|
|
278
|
-
}
|
|
279
387
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
388
|
+
/* Fallback for unattached parent: per-cell ca_xfer_addrs. */
|
|
389
|
+
{
|
|
390
|
+
ca_size_t *paddrs;
|
|
391
|
+
ca_size_t i;
|
|
392
|
+
volatile VALUE holder;
|
|
393
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
394
|
+
for ( i = 0; i < n; i++ ) {
|
|
395
|
+
paddrs[i] = ca->indices[start + i * step];
|
|
396
|
+
}
|
|
397
|
+
ca_xfer_addrs(parent, n, paddrs, data, dir);
|
|
398
|
+
ALLOCV_END(holder);
|
|
399
|
+
}
|
|
284
400
|
}
|
|
285
401
|
|
|
286
402
|
static void
|
|
@@ -288,25 +404,34 @@ ca_select_func_allocate (void *ap)
|
|
|
288
404
|
{
|
|
289
405
|
CASelect *ca = (CASelect *) ap;
|
|
290
406
|
ca_attach(ca->parent);
|
|
291
|
-
|
|
292
|
-
ca->ptr = malloc_with_check(ca_length(ca));
|
|
407
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
293
408
|
}
|
|
294
409
|
|
|
410
|
+
/* Every attach / sync / xfer_all / xfer_stride / fill_data path
|
|
411
|
+
dispatches through the descriptor engine with the same shape
|
|
412
|
+
CASelectAxis uses: one axis over a flattened parent. */
|
|
413
|
+
|
|
295
414
|
static void
|
|
296
415
|
ca_select_func_attach (void *ap)
|
|
297
416
|
{
|
|
298
417
|
CASelect *ca = (CASelect *) ap;
|
|
418
|
+
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
419
|
+
ca_size_t pdims[CA_RANK_MAX];
|
|
299
420
|
ca_attach(ca->parent);
|
|
300
|
-
|
|
301
|
-
ca->ptr =
|
|
302
|
-
|
|
421
|
+
ca_select_describe_axes(ca, desc, pdims);
|
|
422
|
+
ca->ptr = ca_axis_dispatch_attach(ca->parent, pdims, desc, ca->ndim,
|
|
423
|
+
ca->bytes, ca->elements, NULL);
|
|
303
424
|
}
|
|
304
425
|
|
|
305
426
|
static void
|
|
306
427
|
ca_select_func_sync (void *ap)
|
|
307
428
|
{
|
|
308
429
|
CASelect *ca = (CASelect *) ap;
|
|
309
|
-
|
|
430
|
+
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
431
|
+
ca_size_t pdims[CA_RANK_MAX];
|
|
432
|
+
ca_select_describe_axes(ca, desc, pdims);
|
|
433
|
+
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
434
|
+
ca->elements, ca->ptr);
|
|
310
435
|
ca_sync(ca->parent);
|
|
311
436
|
}
|
|
312
437
|
|
|
@@ -314,37 +439,83 @@ static void
|
|
|
314
439
|
ca_select_func_detach (void *ap)
|
|
315
440
|
{
|
|
316
441
|
CASelect *ca = (CASelect *) ap;
|
|
317
|
-
|
|
442
|
+
xfree(ca->ptr);
|
|
318
443
|
ca->ptr = NULL;
|
|
319
444
|
ca_detach(ca->parent);
|
|
320
445
|
}
|
|
321
446
|
|
|
447
|
+
/* Fast-path core used by xfer_all's attached-parent branch and the
|
|
448
|
+
cold-parent 2-pass scratch branch below. */
|
|
322
449
|
static void
|
|
323
|
-
|
|
450
|
+
ca_select_func_run_fast_path (CASelect *ca, char *data, int dir)
|
|
324
451
|
{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
452
|
+
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
453
|
+
ca_size_t pdims[CA_RANK_MAX];
|
|
454
|
+
ca_select_describe_axes(ca, desc, pdims);
|
|
455
|
+
if ( dir == CA_XFER_GET ) {
|
|
456
|
+
ca_axis_dispatch_gather(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
457
|
+
ca->elements, NULL, data);
|
|
458
|
+
} else {
|
|
459
|
+
ca_axis_dispatch_scatter(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
460
|
+
ca->elements, data);
|
|
461
|
+
}
|
|
329
462
|
}
|
|
330
463
|
|
|
464
|
+
/* Cold parent is served by a 2-pass scratch (gather parent into a
|
|
465
|
+
local buffer, dispatch through the fast path against the buffer,
|
|
466
|
+
scatter back on PUT). Deliberately avoids ca_attach(parent) so
|
|
467
|
+
that a silent transitive attach cannot re-enter through here. */
|
|
331
468
|
static void
|
|
332
|
-
|
|
469
|
+
ca_select_func_xfer_all (void *ap, void *data, int dir)
|
|
333
470
|
{
|
|
334
471
|
CASelect *ca = (CASelect *) ap;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
472
|
+
if ( ca->parent->ptr ) {
|
|
473
|
+
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
{
|
|
477
|
+
volatile VALUE holder;
|
|
478
|
+
CArray *parent = ca->parent;
|
|
479
|
+
ca_size_t plen = parent->elements * parent->bytes;
|
|
480
|
+
char *parent_scratch = ALLOCV_N(char, holder, plen);
|
|
481
|
+
char *parent_ptr_saved = parent->ptr;
|
|
482
|
+
ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
|
|
483
|
+
parent->ptr = parent_scratch;
|
|
484
|
+
ca_select_func_run_fast_path(ca, (char *) data, dir);
|
|
485
|
+
if ( dir == CA_XFER_PUT ) {
|
|
486
|
+
ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
|
|
487
|
+
}
|
|
488
|
+
parent->ptr = parent_ptr_saved;
|
|
489
|
+
ALLOCV_END(holder);
|
|
490
|
+
}
|
|
339
491
|
}
|
|
340
492
|
|
|
341
|
-
|
|
342
493
|
static void
|
|
343
494
|
ca_select_func_fill_data (void *ap, void *ptr)
|
|
344
495
|
{
|
|
345
496
|
CASelect *ca = (CASelect *) ap;
|
|
497
|
+
ca_axis_desc_t desc[CA_RANK_MAX];
|
|
498
|
+
ca_size_t pdims[CA_RANK_MAX];
|
|
499
|
+
|
|
500
|
+
/* Writing only the selected cells still went through a whole-parent
|
|
501
|
+
attach and sync. Where that attach is a gather rather than an alias,
|
|
502
|
+
the unselected cells make the round trip for nothing -- and through a
|
|
503
|
+
lossy transform layer they do not come back the same. Descend per cell
|
|
504
|
+
instead; the cost then follows the selection. Kept in step with the
|
|
505
|
+
CAStride form, so both spellings of a partial fill behave alike.
|
|
506
|
+
(PROPOSAL_PARTIAL_FILL_WHOLE_ROOT_WRITEBACK.md sections 3.3 / 6.2) */
|
|
507
|
+
if ( !ca_is_attached(ca->parent) && !ca_attach_is_alias(ca->parent) ) {
|
|
508
|
+
/* indices[] are already the selected positions in the parent's flat
|
|
509
|
+
space, so the selection passes down as it stands -- one hop, no
|
|
510
|
+
attach, and the unselected cells are never named. */
|
|
511
|
+
ca_fill_addrs(ca->parent, ca->elements, ca->indices, ptr);
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
346
515
|
ca_attach(ca->parent);
|
|
347
|
-
|
|
516
|
+
ca_select_describe_axes(ca, desc, pdims);
|
|
517
|
+
ca_axis_dispatch_fill_value(ca->parent, pdims, desc, ca->ndim, ca->bytes,
|
|
518
|
+
ca->elements, ptr);
|
|
348
519
|
ca_sync(ca->parent);
|
|
349
520
|
ca_detach(ca->parent);
|
|
350
521
|
}
|
|
@@ -362,23 +533,20 @@ ca_select_func_create_mask (void *ap)
|
|
|
362
533
|
|
|
363
534
|
ca_operation_function_t ca_select_func = {
|
|
364
535
|
CA_OBJ_SELECT,
|
|
365
|
-
|
|
536
|
+
CA_VIEW_ARRAY,
|
|
366
537
|
free_ca_select,
|
|
367
538
|
ca_select_func_clone,
|
|
368
|
-
ca_select_func_ptr_at_addr,
|
|
369
|
-
ca_select_func_ptr_at_index,
|
|
370
|
-
ca_select_func_fetch_addr,
|
|
371
|
-
ca_select_func_fetch_index,
|
|
372
|
-
ca_select_func_store_addr,
|
|
373
|
-
ca_select_func_store_index,
|
|
374
539
|
ca_select_func_allocate,
|
|
375
540
|
ca_select_func_attach,
|
|
376
541
|
ca_select_func_sync,
|
|
377
542
|
ca_select_func_detach,
|
|
378
|
-
ca_select_func_copy_data,
|
|
379
|
-
ca_select_func_sync_data,
|
|
380
543
|
ca_select_func_fill_data,
|
|
381
544
|
ca_select_func_create_mask,
|
|
545
|
+
ca_select_func_xfer_index,
|
|
546
|
+
ca_select_func_xfer_addrs,
|
|
547
|
+
NULL, /* fold_stride: never fold — gather boundary */
|
|
548
|
+
ca_select_func_xfer_stride,
|
|
549
|
+
ca_select_func_xfer_all,
|
|
382
550
|
};
|
|
383
551
|
|
|
384
552
|
/* ------------------------------------------------------------------- */
|
|
@@ -399,13 +567,16 @@ rb_ca_select_new (VALUE cary, VALUE select)
|
|
|
399
567
|
}
|
|
400
568
|
obj = ca_wrap_struct(ca);
|
|
401
569
|
rb_ca_set_parent(obj, cary);
|
|
402
|
-
|
|
570
|
+
CA_FACE_LIFT_IF_FACE(obj, cary, parent);
|
|
403
571
|
return obj;
|
|
404
572
|
}
|
|
405
573
|
|
|
406
574
|
VALUE
|
|
407
575
|
rb_ca_select_new_share (VALUE cary, VALUE select)
|
|
408
576
|
{
|
|
577
|
+
/* Alias of the snapshot constructor. The `referred_index` ivar is
|
|
578
|
+
set so consumers that expect the original selector to be
|
|
579
|
+
reachable from the view object continue to find it. */
|
|
409
580
|
volatile VALUE obj;
|
|
410
581
|
CArray *parent, *cselect;
|
|
411
582
|
CASelect *ca;
|
|
@@ -419,136 +590,12 @@ rb_ca_select_new_share (VALUE cary, VALUE select)
|
|
|
419
590
|
}
|
|
420
591
|
obj = ca_wrap_struct(ca);
|
|
421
592
|
rb_ca_set_parent(obj, cary);
|
|
422
|
-
rb_ca_data_type_inherit(obj, cary);
|
|
423
593
|
rb_ivar_set(obj, rb_intern("referred_index"), select);
|
|
424
594
|
return obj;
|
|
425
595
|
}
|
|
426
596
|
|
|
427
597
|
/* -------------------------------------------------------------------- */
|
|
428
598
|
|
|
429
|
-
#define proc_select_to_ptr(type) \
|
|
430
|
-
{ \
|
|
431
|
-
type *p = (type *) ptr; \
|
|
432
|
-
type *q = (type *) ca->ptr; \
|
|
433
|
-
for (i=ca->elements; i; i--) { \
|
|
434
|
-
if ( *s ) { \
|
|
435
|
-
*p++ = *q; \
|
|
436
|
-
} \
|
|
437
|
-
q++; s++; \
|
|
438
|
-
} \
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
void
|
|
442
|
-
ca_select_to_ptr (CArray *ca, CArray *select, char *ptr)
|
|
443
|
-
{
|
|
444
|
-
boolean8_t *s = (boolean8_t*) select->ptr;
|
|
445
|
-
ca_size_t i;
|
|
446
|
-
|
|
447
|
-
switch ( ca->bytes ) {
|
|
448
|
-
case 1: proc_select_to_ptr(int8_t); break;
|
|
449
|
-
case 2: proc_select_to_ptr(int16_t); break;
|
|
450
|
-
case 4: proc_select_to_ptr(int32_t); break;
|
|
451
|
-
case 8: proc_select_to_ptr(float64_t); break;
|
|
452
|
-
default: {
|
|
453
|
-
char *p = ptr, *q = ca->ptr;
|
|
454
|
-
ca_size_t bytes = ca->bytes;
|
|
455
|
-
for (i=ca->elements; i; i--) {
|
|
456
|
-
if ( *s ) {
|
|
457
|
-
memcpy(q, p, bytes);
|
|
458
|
-
p+=bytes;
|
|
459
|
-
}
|
|
460
|
-
q+=bytes; s++;
|
|
461
|
-
}
|
|
462
|
-
break;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/* ------------------------------------------------------------------- */
|
|
469
|
-
|
|
470
|
-
#define proc_select_from_ptr(type) \
|
|
471
|
-
{ \
|
|
472
|
-
type *p = (type *) ptr; \
|
|
473
|
-
type *q = (type *) ca->ptr; \
|
|
474
|
-
for (i=ca->elements; i; i--) { \
|
|
475
|
-
if ( *s ) { \
|
|
476
|
-
*q = *p++; \
|
|
477
|
-
} \
|
|
478
|
-
q++; s++; \
|
|
479
|
-
} \
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
void
|
|
483
|
-
ca_select_from_ptr (CArray *ca, CArray *select, char *ptr)
|
|
484
|
-
{
|
|
485
|
-
boolean8_t *s = (boolean8_t *) select->ptr;
|
|
486
|
-
ca_size_t i;
|
|
487
|
-
|
|
488
|
-
switch ( ca->bytes ) {
|
|
489
|
-
case 1: proc_select_from_ptr(int8_t); break;
|
|
490
|
-
case 2: proc_select_from_ptr(int16_t); break;
|
|
491
|
-
case 4: proc_select_from_ptr(int32_t); break;
|
|
492
|
-
case 8: proc_select_from_ptr(float64_t); break;
|
|
493
|
-
default: {
|
|
494
|
-
char *p = ptr;
|
|
495
|
-
char *q = ca->ptr;
|
|
496
|
-
ca_size_t bytes = ca->bytes;
|
|
497
|
-
for (i=ca->elements; i; i--) {
|
|
498
|
-
if ( *s ) {
|
|
499
|
-
memcpy(q, p, bytes);
|
|
500
|
-
p+=bytes;
|
|
501
|
-
}
|
|
502
|
-
q+=bytes; s++;
|
|
503
|
-
}
|
|
504
|
-
break;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
/* ------------------------------------------------------------------- */
|
|
511
|
-
|
|
512
|
-
#define proc_select_fill(type) \
|
|
513
|
-
{ \
|
|
514
|
-
type *q = (type *) ca->ptr; \
|
|
515
|
-
type v = *(type *) valp; \
|
|
516
|
-
for (i=ca->elements; i; i--) { \
|
|
517
|
-
if ( *s ) { \
|
|
518
|
-
*q = v; \
|
|
519
|
-
} \
|
|
520
|
-
q++; s++; \
|
|
521
|
-
} \
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
void
|
|
525
|
-
ca_select_fill (CArray *ca, CArray *select, char *valp)
|
|
526
|
-
{
|
|
527
|
-
boolean8_t *s = (boolean8_t *) select->ptr;
|
|
528
|
-
ca_size_t i;
|
|
529
|
-
|
|
530
|
-
switch ( ca->bytes ) {
|
|
531
|
-
case 1: proc_select_fill(int8_t); break;
|
|
532
|
-
case 2: proc_select_fill(int16_t); break;
|
|
533
|
-
case 4: proc_select_fill(int32_t); break;
|
|
534
|
-
case 8: proc_select_fill(float64_t); break;
|
|
535
|
-
default: {
|
|
536
|
-
char *q = ca->ptr;
|
|
537
|
-
ca_size_t bytes = ca->bytes;
|
|
538
|
-
for (i=ca->elements; i; i--) {
|
|
539
|
-
if ( *s ) {
|
|
540
|
-
memcpy(q, valp, bytes);
|
|
541
|
-
}
|
|
542
|
-
q+=bytes; s++;
|
|
543
|
-
}
|
|
544
|
-
break;
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
/* ------------------------------------------------------------------- */
|
|
551
|
-
|
|
552
599
|
static VALUE
|
|
553
600
|
rb_cm_s_allocate (VALUE klass)
|
|
554
601
|
{
|
|
@@ -564,19 +611,20 @@ rb_cm_initialize_copy (VALUE self, VALUE other)
|
|
|
564
611
|
TypedData_Get_Struct(self, CASelect, &caselect_data_type, ca);
|
|
565
612
|
TypedData_Get_Struct(other, CASelect, &caselect_data_type, cs);
|
|
566
613
|
|
|
567
|
-
/*
|
|
614
|
+
/* Re-snapshot from the source's selector copy so the two views
|
|
615
|
+
end up with independent indices buffers. */
|
|
568
616
|
ca_select_setup(ca, cs->parent, cs->select, 1);
|
|
569
617
|
|
|
570
618
|
return self;
|
|
571
619
|
}
|
|
572
620
|
|
|
573
621
|
void
|
|
574
|
-
Init_ca_obj_select ()
|
|
622
|
+
Init_ca_obj_select (void)
|
|
575
623
|
{
|
|
576
|
-
/* rb_cCASelect
|
|
624
|
+
/* rb_cCASelect and CA_OBJ_SELECT are defined in ruby_carray.c;
|
|
625
|
+
this file only registers the constant + allocator. */
|
|
577
626
|
rb_define_const(rb_cObject, "CA_OBJ_SELECT", INT2NUM(CA_OBJ_SELECT));
|
|
578
627
|
|
|
579
628
|
rb_define_alloc_func(rb_cCASelect, rb_cm_s_allocate);
|
|
580
629
|
rb_define_method(rb_cCASelect, "initialize_copy", rb_cm_initialize_copy, 1);
|
|
581
630
|
}
|
|
582
|
-
|