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_remap.c
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
CARemap — internal-only per-element gather view. Each output cell
|
|
4
|
+
(k0, k1, ..., k_{n-1}) reads the input cell at
|
|
5
|
+
parent.flatten[idx.flatten[k]].
|
|
6
|
+
|
|
7
|
+
Constraints:
|
|
8
|
+
- ref.dim == idx.dim (same shape, same ndim, per-axis dim match)
|
|
9
|
+
- idx.data_type == CA_SIZE (caller responsible)
|
|
10
|
+
- No public constructor — there is no `CArray#remap(idx)` or
|
|
11
|
+
`CARemap.new` surface; the class is only reachable via internal
|
|
12
|
+
helpers and the `ca[idx]` same-shape indexer fast path.
|
|
13
|
+
- The CARemap Ruby class IS rb_define_class'd: visibility lets users
|
|
14
|
+
see "this view came from a same-shape gather" when they inspect
|
|
15
|
+
`.class`. CA_OBJ_REMAP integer remains unexported as a Ruby
|
|
16
|
+
constant — it is an internal type tag.
|
|
17
|
+
|
|
18
|
+
---------------------------------------------------------------------------- */
|
|
19
|
+
|
|
20
|
+
#include "carray.h"
|
|
21
|
+
|
|
22
|
+
typedef struct {
|
|
23
|
+
int16_t obj_type;
|
|
24
|
+
int8_t data_type;
|
|
25
|
+
int8_t ndim;
|
|
26
|
+
int32_t flags;
|
|
27
|
+
ca_size_t bytes;
|
|
28
|
+
ca_size_t elements;
|
|
29
|
+
ca_size_t *dim;
|
|
30
|
+
char *ptr;
|
|
31
|
+
CArray *mask;
|
|
32
|
+
char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
|
|
33
|
+
CArray *parent; /* = ref */
|
|
34
|
+
uint32_t attach;
|
|
35
|
+
uint8_t nosync;
|
|
36
|
+
/* ---------- */
|
|
37
|
+
CArray *idx; /* shared reference; data_type = CA_SIZE, same shape as parent */
|
|
38
|
+
} CARemap;
|
|
39
|
+
|
|
40
|
+
static int8_t CA_OBJ_REMAP;
|
|
41
|
+
|
|
42
|
+
/* Ruby classes — rb_define_class'd in Init so users see the right
|
|
43
|
+
class name on .class inspection. No constructor is bound (no
|
|
44
|
+
rb_define_method "initialize" or alloc), so the class is unreachable
|
|
45
|
+
from Ruby code; only internal C helpers can construct CARemap. */
|
|
46
|
+
static VALUE rb_cCARemap;
|
|
47
|
+
static VALUE rb_cCARemapMask;
|
|
48
|
+
|
|
49
|
+
static size_t
|
|
50
|
+
ca_remap_dsize (const void *ap)
|
|
51
|
+
{
|
|
52
|
+
const CARemap *ca = (const CARemap *) ap;
|
|
53
|
+
return sizeof(CARemap) + ca->ndim * sizeof(ca_size_t);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Pool framework hooks: single ndim-sized tail (dim) in the _pool buffer. */
|
|
57
|
+
static size_t
|
|
58
|
+
ca_remap_pool_bytes (int8_t ndim)
|
|
59
|
+
{
|
|
60
|
+
ca_size_t n = (ndim > 0) ? ndim : 1;
|
|
61
|
+
return (size_t) n * sizeof(ca_size_t);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static void
|
|
65
|
+
ca_remap_pool_init (void *ap, int8_t ndim)
|
|
66
|
+
{
|
|
67
|
+
CARemap *ca = (CARemap *) ap;
|
|
68
|
+
ca->dim = (ca_size_t *) ca->_pool;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const rb_data_type_t caremap_data_type = {
|
|
72
|
+
.parent = &caview_data_type,
|
|
73
|
+
.wrap_struct_name = "CARemap",
|
|
74
|
+
.function = {
|
|
75
|
+
.dmark = ca_mark,
|
|
76
|
+
.dfree = ca_free,
|
|
77
|
+
.dsize = ca_remap_dsize,
|
|
78
|
+
.dcompact = NULL
|
|
79
|
+
},
|
|
80
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const rb_data_type_t caremap_mask_data_type = {
|
|
84
|
+
.parent = &caremap_data_type,
|
|
85
|
+
.wrap_struct_name = "CARemapMask",
|
|
86
|
+
.function = {
|
|
87
|
+
.dmark = NULL,
|
|
88
|
+
.dfree = ca_free_nop,
|
|
89
|
+
.dsize = ca_remap_dsize,
|
|
90
|
+
.dcompact = NULL
|
|
91
|
+
},
|
|
92
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
/* ------------------------------------------------------------------- */
|
|
96
|
+
/* Constraint enforcement: idx is CA_SIZE and ref.dim == idx.dim. */
|
|
97
|
+
|
|
98
|
+
static void
|
|
99
|
+
ca_remap_check_constraints (CArray *ref, CArray *idx)
|
|
100
|
+
{
|
|
101
|
+
int k;
|
|
102
|
+
|
|
103
|
+
if ( idx->data_type != CA_SIZE ) {
|
|
104
|
+
rb_raise(rb_eArgError,
|
|
105
|
+
"CARemap: idx data_type must be CA_SIZE (got %d)",
|
|
106
|
+
(int) idx->data_type);
|
|
107
|
+
}
|
|
108
|
+
if ( ref->ndim != idx->ndim ) {
|
|
109
|
+
rb_raise(rb_eArgError,
|
|
110
|
+
"CARemap: ref.ndim (%d) != idx.ndim (%d)",
|
|
111
|
+
(int) ref->ndim, (int) idx->ndim);
|
|
112
|
+
}
|
|
113
|
+
for ( k = 0; k < ref->ndim; k++ ) {
|
|
114
|
+
if ( ref->dim[k] != idx->dim[k] ) {
|
|
115
|
+
rb_raise(rb_eArgError,
|
|
116
|
+
"CARemap: shape mismatch at axis %d (ref=%lld, idx=%lld)",
|
|
117
|
+
k,
|
|
118
|
+
(long long) ref->dim[k],
|
|
119
|
+
(long long) idx->dim[k]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* ------------------------------------------------------------------- */
|
|
125
|
+
|
|
126
|
+
int
|
|
127
|
+
ca_remap_setup (CARemap *ca, CArray *ref, CArray *idx)
|
|
128
|
+
{
|
|
129
|
+
ca_remap_check_constraints(ref, idx);
|
|
130
|
+
|
|
131
|
+
ca->obj_type = CA_OBJ_REMAP;
|
|
132
|
+
ca->data_type = ref->data_type;
|
|
133
|
+
ca->flags = 0;
|
|
134
|
+
ca->ndim = ref->ndim;
|
|
135
|
+
ca->bytes = ref->bytes;
|
|
136
|
+
ca->elements = ref->elements;
|
|
137
|
+
ca->ptr = NULL;
|
|
138
|
+
ca->mask = NULL;
|
|
139
|
+
if ( ! ca->_pool ) {
|
|
140
|
+
ca->dim = ALLOC_N(ca_size_t, ref->ndim);
|
|
141
|
+
}
|
|
142
|
+
memcpy(ca->dim, ref->dim, ref->ndim * sizeof(ca_size_t));
|
|
143
|
+
|
|
144
|
+
ca->parent = ref;
|
|
145
|
+
ca->attach = 0;
|
|
146
|
+
ca->nosync = 0;
|
|
147
|
+
ca->idx = idx;
|
|
148
|
+
|
|
149
|
+
if ( ca_has_mask(ref) ) {
|
|
150
|
+
ca_create_mask(ca);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if ( ca_is_scalar(ref) ) {
|
|
154
|
+
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return 0;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
CARemap *
|
|
161
|
+
ca_remap_new (CArray *ref, CArray *idx)
|
|
162
|
+
{
|
|
163
|
+
CARemap *ca = (CARemap *) ca_array_alloc(CA_OBJ_REMAP, ref->ndim);
|
|
164
|
+
ca_remap_setup(ca, ref, idx);
|
|
165
|
+
return ca;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static void
|
|
169
|
+
free_ca_remap (void *ap)
|
|
170
|
+
{
|
|
171
|
+
CARemap *ca = (CARemap *) ap;
|
|
172
|
+
if ( ca != NULL ) {
|
|
173
|
+
ca_free(ca->mask);
|
|
174
|
+
/* ca->idx is a shared reference owned by the caller; no free here.
|
|
175
|
+
The Ruby-side parent linkage (rb_ca_set_parent on idx wrapper)
|
|
176
|
+
keeps it reachable for GC. */
|
|
177
|
+
if ( ca->_pool ) {
|
|
178
|
+
ca_array_free(ca); /* dim lives in _pool */
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
xfree(ca->dim);
|
|
182
|
+
xfree(ca);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Forward declarations for the xfer slot implementations, used by the
|
|
188
|
+
lifecycle slots above them in the dispatch table. */
|
|
189
|
+
static void ca_remap_func_xfer_addrs (void *ap, ca_size_t n,
|
|
190
|
+
ca_size_t *addrs, void *data, int dir);
|
|
191
|
+
static void ca_remap_func_xfer_all (void *ap, void *data, int dir);
|
|
192
|
+
|
|
193
|
+
/* ------------------------------------------------------------------- */
|
|
194
|
+
|
|
195
|
+
static void *
|
|
196
|
+
ca_remap_func_clone (void *ap)
|
|
197
|
+
{
|
|
198
|
+
CARemap *ca = (CARemap *) ap;
|
|
199
|
+
return ca_remap_new(ca->parent, ca->idx);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/* Lifecycle (xfer contract):
|
|
203
|
+
attach = allocate ptr + xfer_all(GET)
|
|
204
|
+
sync = xfer_all(PUT)
|
|
205
|
+
detach = xfree(ptr)
|
|
206
|
+
No ca_attach(parent) / ca_attach(idx) here — xfer_all resolves both
|
|
207
|
+
per-cell through the per-region ca_xfer_addrs dispatchers. */
|
|
208
|
+
|
|
209
|
+
static void
|
|
210
|
+
ca_remap_func_allocate (void *ap)
|
|
211
|
+
{
|
|
212
|
+
CARemap *ca = (CARemap *) ap;
|
|
213
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
static void
|
|
217
|
+
ca_remap_func_attach (void *ap)
|
|
218
|
+
{
|
|
219
|
+
CARemap *ca = (CARemap *) ap;
|
|
220
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
221
|
+
ca_remap_func_xfer_all(ca, ca->ptr, CA_XFER_GET);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static void
|
|
225
|
+
ca_remap_func_sync (void *ap)
|
|
226
|
+
{
|
|
227
|
+
CARemap *ca = (CARemap *) ap;
|
|
228
|
+
ca_remap_func_xfer_all(ca, ca->ptr, CA_XFER_PUT);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
static void
|
|
232
|
+
ca_remap_func_detach (void *ap)
|
|
233
|
+
{
|
|
234
|
+
CARemap *ca = (CARemap *) ap;
|
|
235
|
+
xfree(ca->ptr);
|
|
236
|
+
ca->ptr = NULL;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* fill_data: broadcast a single cell (`data` is one cell of size
|
|
240
|
+
ca->bytes) to every view position. Implementation = build a
|
|
241
|
+
row-major scratch of `data` repeated `elements` times, then route
|
|
242
|
+
through xfer_all(PUT). With repeats in idx this writes the same
|
|
243
|
+
parent cell multiple times — value is identical so the result is
|
|
244
|
+
well-defined (parent.flat[idx[k]] = value for each unique k). */
|
|
245
|
+
static void
|
|
246
|
+
ca_remap_func_fill_data (void *ap, void *data)
|
|
247
|
+
{
|
|
248
|
+
CARemap *ca = (CARemap *) ap;
|
|
249
|
+
ca_size_t n = ca->elements;
|
|
250
|
+
char *scratch;
|
|
251
|
+
ca_size_t i;
|
|
252
|
+
volatile VALUE holder;
|
|
253
|
+
|
|
254
|
+
if ( n == 0 ) return;
|
|
255
|
+
|
|
256
|
+
scratch = ALLOCV_N(char, holder, n * ca->bytes);
|
|
257
|
+
for ( i = 0; i < n; i++ ) {
|
|
258
|
+
memcpy(scratch + i * ca->bytes, data, ca->bytes);
|
|
259
|
+
}
|
|
260
|
+
ca_remap_func_xfer_all(ca, scratch, CA_XFER_PUT);
|
|
261
|
+
ALLOCV_END(holder);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static void
|
|
265
|
+
ca_remap_func_create_mask (void *ap)
|
|
266
|
+
{
|
|
267
|
+
CARemap *ca = (CARemap *) ap;
|
|
268
|
+
ca_update_mask(ca->parent);
|
|
269
|
+
if ( ! ca->parent->mask ) {
|
|
270
|
+
ca_create_mask(ca->parent);
|
|
271
|
+
}
|
|
272
|
+
/* Mask is a CARemap over (parent->mask, idx) — same shape, boolean. */
|
|
273
|
+
ca->mask = (CArray *) ca_remap_new(ca->parent->mask, ca->idx);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/* xfer_addrs: batched gather/scatter over a list of view flat addresses.
|
|
277
|
+
|
|
278
|
+
Per the same-shape invariant the view-flat addresses index ca->idx
|
|
279
|
+
identically (both have the same elements layout). Steps:
|
|
280
|
+
|
|
281
|
+
1. ALLOCV paddrs[n].
|
|
282
|
+
2. ca_xfer_addrs(ca->idx, n, addrs, paddrs, GET) — one batched
|
|
283
|
+
read of the parent flat addresses through ca->idx's own
|
|
284
|
+
xfer_addrs dispatcher (entity, view, view chain — all
|
|
285
|
+
transparent).
|
|
286
|
+
3. ca_xfer_addrs(ca->parent, n, paddrs, data, dir) — one batched
|
|
287
|
+
gather/scatter of the user payload against parent.
|
|
288
|
+
|
|
289
|
+
No ca_attach() of parent or idx; both reads are per-region dispatch.
|
|
290
|
+
This is the natural batched form of xfer_index (and xfer_index
|
|
291
|
+
routes through it). */
|
|
292
|
+
static void
|
|
293
|
+
ca_remap_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
294
|
+
void *data, int dir)
|
|
295
|
+
{
|
|
296
|
+
CARemap *ca = (CARemap *) ap;
|
|
297
|
+
ca_size_t *paddrs;
|
|
298
|
+
volatile VALUE holder;
|
|
299
|
+
|
|
300
|
+
if ( n == 0 ) return;
|
|
301
|
+
|
|
302
|
+
paddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
303
|
+
ca_xfer_addrs(ca->idx, n, addrs, paddrs, CA_XFER_GET);
|
|
304
|
+
ca_xfer_addrs(ca->parent, n, paddrs, data, dir);
|
|
305
|
+
ALLOCV_END(holder);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/* xfer_index — single-cell form delegated to xfer_addrs after
|
|
309
|
+
converting the view N-D index to a view flat address. Same-shape
|
|
310
|
+
invariant: ca_index2addr on ca itself (using ca->dim) yields the
|
|
311
|
+
right view flat that equally indexes ca->idx. */
|
|
312
|
+
static void
|
|
313
|
+
ca_remap_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
314
|
+
{
|
|
315
|
+
ca_size_t view_addr = ca_index2addr(ap, idx);
|
|
316
|
+
ca_remap_func_xfer_addrs(ap, 1, &view_addr, data, dir);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/* xfer_stride: CARemap is a never-fold per-element gather boundary --
|
|
320
|
+
no STRIDE structure to preserve. The region [starts[k],
|
|
321
|
+
starts[k]+counts[k]) is enumerated cell-by-cell, each cell resolved
|
|
322
|
+
to its view-flat address through the strides[] byte step, and
|
|
323
|
+
delivered through CARemap's own xfer_addrs (which then walks through
|
|
324
|
+
ca->idx to the parent addresses in two batched calls). data is
|
|
325
|
+
contiguous row-major over counts.
|
|
326
|
+
|
|
327
|
+
Same shape as CAReduce's xfer_stride (ca_obj_reduce.c). */
|
|
328
|
+
static void
|
|
329
|
+
ca_remap_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
330
|
+
ca_size_t *strides, void *data, int dir)
|
|
331
|
+
{
|
|
332
|
+
CARemap *ca = (CARemap *) ap;
|
|
333
|
+
int8_t ndim = ca->ndim;
|
|
334
|
+
ca_size_t native[CA_RANK_MAX], idx[CA_RANK_MAX];
|
|
335
|
+
ca_size_t *vaddrs;
|
|
336
|
+
ca_size_t base = 0, n = 1, i, s;
|
|
337
|
+
int8_t k;
|
|
338
|
+
volatile VALUE holder;
|
|
339
|
+
|
|
340
|
+
s = ca->bytes;
|
|
341
|
+
for ( k = ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
|
|
342
|
+
for ( k = 0; k < ndim; k++ ) { base += starts[k] * native[k]; n *= counts[k]; }
|
|
343
|
+
|
|
344
|
+
if ( n == 0 ) return;
|
|
345
|
+
|
|
346
|
+
vaddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
347
|
+
for ( k = 0; k < ndim; k++ ) idx[k] = 0;
|
|
348
|
+
for ( i = 0; i < n; i++ ) {
|
|
349
|
+
ca_size_t off = base;
|
|
350
|
+
for ( k = 0; k < ndim; k++ ) off += idx[k] * strides[k];
|
|
351
|
+
vaddrs[i] = off / ca->bytes;
|
|
352
|
+
k = ndim - 1;
|
|
353
|
+
while ( k >= 0 ) { if ( ++idx[k] < counts[k] ) break; idx[k] = 0; k--; }
|
|
354
|
+
}
|
|
355
|
+
ca_remap_func_xfer_addrs(ca, n, vaddrs, data, dir);
|
|
356
|
+
ALLOCV_END(holder);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/* xfer_all: whole-view delivery. Sequential view-flat addresses
|
|
360
|
+
[0..elements) routed through xfer_addrs -- one ALLOCV for the addr
|
|
361
|
+
list, then two batched ca_xfer_addrs calls inside xfer_addrs.
|
|
362
|
+
|
|
363
|
+
No ca_attach(parent) / ca_attach(idx). */
|
|
364
|
+
static void
|
|
365
|
+
ca_remap_func_xfer_all (void *ap, void *data, int dir)
|
|
366
|
+
{
|
|
367
|
+
CARemap *ca = (CARemap *) ap;
|
|
368
|
+
ca_size_t n = ca->elements;
|
|
369
|
+
ca_size_t *vaddrs;
|
|
370
|
+
ca_size_t i;
|
|
371
|
+
volatile VALUE holder;
|
|
372
|
+
|
|
373
|
+
if ( n == 0 ) return;
|
|
374
|
+
|
|
375
|
+
vaddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
376
|
+
for ( i = 0; i < n; i++ ) vaddrs[i] = i;
|
|
377
|
+
ca_remap_func_xfer_addrs(ca, n, vaddrs, data, dir);
|
|
378
|
+
ALLOCV_END(holder);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
ca_operation_function_t ca_remap_func = {
|
|
382
|
+
-1, /* obj_type — assigned by ca_install_obj_type */
|
|
383
|
+
CA_VIEW_ARRAY,
|
|
384
|
+
free_ca_remap,
|
|
385
|
+
ca_remap_func_clone,
|
|
386
|
+
ca_remap_func_allocate,
|
|
387
|
+
ca_remap_func_attach,
|
|
388
|
+
ca_remap_func_sync,
|
|
389
|
+
ca_remap_func_detach,
|
|
390
|
+
ca_remap_func_fill_data,
|
|
391
|
+
ca_remap_func_create_mask,
|
|
392
|
+
ca_remap_func_xfer_index,
|
|
393
|
+
ca_remap_func_xfer_addrs,
|
|
394
|
+
NULL, /* fold_stride: never-fold (per-element gather boundary) */
|
|
395
|
+
ca_remap_func_xfer_stride,
|
|
396
|
+
ca_remap_func_xfer_all,
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
/* ------------------------------------------------------------------- */
|
|
401
|
+
/* Ruby wrapper for ca_remap_new. Validates the (ref, idx) shape /
|
|
402
|
+
data_type invariants at the Ruby boundary, builds the view via
|
|
403
|
+
ca_remap_new, wraps as a CARemap VALUE, and sets the parent linkage.
|
|
404
|
+
|
|
405
|
+
Called from the `ca[idx]` same-shape indexer routing (carray_access.c)
|
|
406
|
+
and the sort / partition along-axis gather (carray_sort.c,
|
|
407
|
+
carray_partition.c). Callers are expected to have already checked the
|
|
408
|
+
routing preconditions (same shape, idx data_type == CA_SIZE);
|
|
409
|
+
ca_remap_setup raises ArgumentError on mismatch as a defensive
|
|
410
|
+
fallback. */
|
|
411
|
+
VALUE
|
|
412
|
+
rb_ca_remap_new (VALUE cary, VALUE rmapper)
|
|
413
|
+
{
|
|
414
|
+
volatile VALUE obj;
|
|
415
|
+
CArray *ref, *idx;
|
|
416
|
+
CARemap *ca;
|
|
417
|
+
|
|
418
|
+
rb_check_carray_object(cary);
|
|
419
|
+
rb_check_carray_object(rmapper);
|
|
420
|
+
TypedData_Get_Struct(cary, CArray, &carray_data_type, ref);
|
|
421
|
+
TypedData_Get_Struct(rmapper, CArray, &carray_data_type, idx);
|
|
422
|
+
|
|
423
|
+
ca = ca_remap_new(ref, idx);
|
|
424
|
+
obj = ca_wrap_struct(ca);
|
|
425
|
+
rb_ca_set_parent(obj, cary);
|
|
426
|
+
/* Hold a Ruby-side reference to the idx VALUE so its GC lifetime
|
|
427
|
+
covers the view's. ca->idx is a raw pointer into idx's struct;
|
|
428
|
+
keeping rmapper reachable through the view keeps it alive. */
|
|
429
|
+
rb_ivar_set(obj, rb_intern("remap_idx"), rmapper);
|
|
430
|
+
return obj;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/* Read-only accessor for the per-cell index CArray that defines this
|
|
434
|
+
CARemap's mapping. Returns the same CArray VALUE the caller passed
|
|
435
|
+
to ca[mapper] (= shared reference, not a copy). Companion to
|
|
436
|
+
CABlock#start / CAStride#strides / CAWindow#count etc. — the view
|
|
437
|
+
hierarchy is preserved so each named view class exposes its own
|
|
438
|
+
defining semantic state. */
|
|
439
|
+
static VALUE
|
|
440
|
+
rb_ca_remap_mapper (VALUE self)
|
|
441
|
+
{
|
|
442
|
+
return rb_ivar_get(self, rb_intern("remap_idx"));
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
void
|
|
447
|
+
Init_ca_obj_remap (void)
|
|
448
|
+
{
|
|
449
|
+
/* CARemap is a proper Ruby class so users can see "this view is a
|
|
450
|
+
per-element gather" on .class. No allocator, no initialize, no
|
|
451
|
+
`new` reachable from Ruby — construction is C-internal only.
|
|
452
|
+
CA_OBJ_REMAP integer remains unexported (it's an internal type
|
|
453
|
+
tag, not user-meaningful). */
|
|
454
|
+
rb_cCARemap = rb_define_class("CARemap", rb_cCAView);
|
|
455
|
+
rb_cCARemapMask = rb_define_class("CARemapMask", rb_cCARemap);
|
|
456
|
+
rb_undef_alloc_func(rb_cCARemap);
|
|
457
|
+
rb_undef_alloc_func(rb_cCARemapMask);
|
|
458
|
+
|
|
459
|
+
ca_remap_func.struct_size = sizeof(CARemap);
|
|
460
|
+
ca_remap_func.pool_bytes = ca_remap_pool_bytes;
|
|
461
|
+
ca_remap_func.pool_init = ca_remap_pool_init;
|
|
462
|
+
|
|
463
|
+
CA_OBJ_REMAP = ca_install_obj_type(rb_cCARemap,
|
|
464
|
+
&caremap_data_type,
|
|
465
|
+
rb_cCARemapMask,
|
|
466
|
+
&caremap_mask_data_type,
|
|
467
|
+
&ca_remap_func, sizeof(ca_remap_func));
|
|
468
|
+
|
|
469
|
+
/* Defining semantic state accessor — companion to CABlock#start /
|
|
470
|
+
CAStride#strides / CAWindow#count. The hierarchy-preserving
|
|
471
|
+
design implies each named view class exposes its own defining
|
|
472
|
+
state so user / test / debugger can ask "how is this view
|
|
473
|
+
mapping?" through ordinary Ruby. */
|
|
474
|
+
rb_define_method(rb_cCARemap, "mapper", rb_ca_remap_mapper, 0);
|
|
475
|
+
}
|