carray 2.0.1 → 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 +772 -297
- 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 +229 -791
- 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 +207 -240
- 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 -329
- 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 +1341 -198
- 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 +5 -15
- 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/mailmap +0 -1
- 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/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_compare.c
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Shared element comparators by data_type (see ca_compare.h). The per-type
|
|
4
|
+
comparators take the (const void *, const void *) prototype directly, so
|
|
5
|
+
the dispatch table needs no function-pointer casts.
|
|
6
|
+
|
|
7
|
+
Internal C API (no Ruby surface). Indexed by data_type id via
|
|
8
|
+
`ca_elem_cmp[data_type]`. Callers include sort_addr_cmp
|
|
9
|
+
(carray_sort.c) and the comparator-based ca_quickselect_bytes path
|
|
10
|
+
(carray_partition.c).
|
|
11
|
+
|
|
12
|
+
--------------------------------------------------------------------------- */
|
|
13
|
+
|
|
14
|
+
#include "ruby.h"
|
|
15
|
+
#include "carray.h"
|
|
16
|
+
#include "ca_compare.h"
|
|
17
|
+
#include <math.h>
|
|
18
|
+
|
|
19
|
+
#define DEFINE_ELEM_CMP(type) \
|
|
20
|
+
static int \
|
|
21
|
+
elem_cmp_## type (const void *va, const void *vb) \
|
|
22
|
+
{ \
|
|
23
|
+
const type *a = (const type *) va; \
|
|
24
|
+
const type *b = (const type *) vb; \
|
|
25
|
+
if ( *a > *b ) return 1; \
|
|
26
|
+
if ( *a < *b ) return -1; \
|
|
27
|
+
return 0; \
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* Float order: NaN sorts last (matches the sort kernels' NaN-at-end). */
|
|
31
|
+
#define DEFINE_ELEM_CMP_FLOAT(type) \
|
|
32
|
+
static int \
|
|
33
|
+
elem_cmp_## type (const void *va, const void *vb) \
|
|
34
|
+
{ \
|
|
35
|
+
const type *a = (const type *) va; \
|
|
36
|
+
const type *b = (const type *) vb; \
|
|
37
|
+
if ( isnan(*a) && ( ! isnan(*b) ) ) return 1; \
|
|
38
|
+
if ( isnan(*b) && ( ! isnan(*a) ) ) return -1; \
|
|
39
|
+
if ( *a > *b ) return 1; \
|
|
40
|
+
if ( *a < *b ) return -1; \
|
|
41
|
+
return 0; \
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
DEFINE_ELEM_CMP(boolean8_t)
|
|
45
|
+
DEFINE_ELEM_CMP(int8_t)
|
|
46
|
+
DEFINE_ELEM_CMP(uint8_t)
|
|
47
|
+
DEFINE_ELEM_CMP(int16_t)
|
|
48
|
+
DEFINE_ELEM_CMP(uint16_t)
|
|
49
|
+
DEFINE_ELEM_CMP(int32_t)
|
|
50
|
+
DEFINE_ELEM_CMP(uint32_t)
|
|
51
|
+
DEFINE_ELEM_CMP(int64_t)
|
|
52
|
+
DEFINE_ELEM_CMP(uint64_t)
|
|
53
|
+
DEFINE_ELEM_CMP_FLOAT(float32_t)
|
|
54
|
+
DEFINE_ELEM_CMP_FLOAT(float64_t)
|
|
55
|
+
|
|
56
|
+
/* CA_OBJECT: compare via Ruby Comparable (`<=>`). */
|
|
57
|
+
static int
|
|
58
|
+
elem_cmp_VALUE (const void *va, const void *vb)
|
|
59
|
+
{
|
|
60
|
+
const VALUE *a = (const VALUE *) va;
|
|
61
|
+
const VALUE *b = (const VALUE *) vb;
|
|
62
|
+
return NUM2INT(rb_funcall(*a, rb_intern("<=>"), 1, *b));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* FIXLEN / retired / otherwise unorderable data_types: callers must handle
|
|
66
|
+
these themselves; reaching the table for them is a bug. */
|
|
67
|
+
static int
|
|
68
|
+
elem_cmp_unsupported (const void *va, const void *vb)
|
|
69
|
+
{
|
|
70
|
+
(void) va; (void) vb;
|
|
71
|
+
rb_raise(rb_eNotImpError,
|
|
72
|
+
"element comparison is not implemented for the data type");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
ca_cmp_func
|
|
76
|
+
ca_elem_cmp[CA_NTYPE] = {
|
|
77
|
+
elem_cmp_unsupported, /* CA_FIXLEN -- caller compares packed blobs itself */
|
|
78
|
+
elem_cmp_boolean8_t,
|
|
79
|
+
elem_cmp_int8_t,
|
|
80
|
+
elem_cmp_uint8_t,
|
|
81
|
+
elem_cmp_int16_t,
|
|
82
|
+
elem_cmp_uint16_t,
|
|
83
|
+
elem_cmp_int32_t,
|
|
84
|
+
elem_cmp_uint32_t,
|
|
85
|
+
elem_cmp_int64_t,
|
|
86
|
+
elem_cmp_uint64_t,
|
|
87
|
+
elem_cmp_float32_t,
|
|
88
|
+
elem_cmp_float64_t,
|
|
89
|
+
elem_cmp_unsupported, /* float128_t -- not supported */
|
|
90
|
+
elem_cmp_unsupported,
|
|
91
|
+
elem_cmp_unsupported,
|
|
92
|
+
elem_cmp_unsupported, /* cmplx256_t -- not supported */
|
|
93
|
+
elem_cmp_VALUE,
|
|
94
|
+
};
|
data/ext/ca_compare.h
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Element comparators by data_type: a 3-way compare (-1 / 0 / +1) of two
|
|
4
|
+
same-typed cells, with the (const void *, const void *) prototype that
|
|
5
|
+
libc qsort / bsearch expect. This is a shared *ordering primitive*, not
|
|
6
|
+
tied to any one algorithm: the index sort (carray_sort.c) and the binary
|
|
7
|
+
search (carray_order.c) both dispatch through ca_elem_cmp[data_type].
|
|
8
|
+
|
|
9
|
+
CA_FIXLEN (packed byte blobs) is intentionally `unsupported` in the table:
|
|
10
|
+
a 2-arg comparator cannot carry the element byte width, so each caller
|
|
11
|
+
compares fixlen cells itself (carray_order.c via a cmp_data wrapper for
|
|
12
|
+
bsearch; carray_sort.c via a direct memcmp). Float slots order NaN last.
|
|
13
|
+
|
|
14
|
+
--------------------------------------------------------------------------- */
|
|
15
|
+
|
|
16
|
+
#ifndef CA_COMPARE_H
|
|
17
|
+
#define CA_COMPARE_H
|
|
18
|
+
|
|
19
|
+
/* 3-way element comparator, qsort/bsearch-compatible signature. */
|
|
20
|
+
typedef int (*ca_cmp_func)(const void *, const void *);
|
|
21
|
+
|
|
22
|
+
/* Per-data_type element comparators, indexed by data_type (CA_NTYPE wide).
|
|
23
|
+
FIXLEN / retired / unused slots hold an unsupported stub that raises. */
|
|
24
|
+
extern ca_cmp_func ca_elem_cmp[CA_NTYPE];
|
|
25
|
+
|
|
26
|
+
#endif /* CA_COMPARE_H */
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Geometric primitives for region-mapped views (CAWindow / CATile /
|
|
4
|
+
CARoll): per-region strided gather, scatter, and broadcast fill.
|
|
5
|
+
See ca_composite_dispatch.h for the full per-function API contract.
|
|
6
|
+
|
|
7
|
+
Routines here are pure C, no Ruby VALUE handling. They operate on
|
|
8
|
+
raw pointers + byte stride arrays. Caller is responsible for parent
|
|
9
|
+
attach state and output buffer allocation.
|
|
10
|
+
|
|
11
|
+
---------------------------------------------------------------------------- */
|
|
12
|
+
|
|
13
|
+
#include "ca_composite_dispatch.h"
|
|
14
|
+
#include <string.h>
|
|
15
|
+
|
|
16
|
+
/* --------------------------------------------------------------------- */
|
|
17
|
+
/* ca_fill_typed */
|
|
18
|
+
/* */
|
|
19
|
+
/* Per-size typed-store loops let the compiler autovectorize (NEON / */
|
|
20
|
+
/* SSE), converting N tight memcpy(bytes) calls into one O(N) SIMD'd */
|
|
21
|
+
/* typed-store loop. Generic memcpy fallback covers CA_FIXLEN and */
|
|
22
|
+
/* unusual widths. */
|
|
23
|
+
/* --------------------------------------------------------------------- */
|
|
24
|
+
|
|
25
|
+
void
|
|
26
|
+
ca_fill_typed (char *dst, const char *val, ca_size_t bytes, ca_size_t n)
|
|
27
|
+
{
|
|
28
|
+
ca_size_t i;
|
|
29
|
+
switch ( bytes ) {
|
|
30
|
+
case 1: {
|
|
31
|
+
memset(dst, *(const unsigned char *)val, n);
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
case 2: {
|
|
35
|
+
uint16_t v = *(const uint16_t *)val;
|
|
36
|
+
uint16_t *p = (uint16_t *)dst;
|
|
37
|
+
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
case 4: {
|
|
41
|
+
uint32_t v = *(const uint32_t *)val;
|
|
42
|
+
uint32_t *p = (uint32_t *)dst;
|
|
43
|
+
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
case 8: {
|
|
47
|
+
uint64_t v = *(const uint64_t *)val;
|
|
48
|
+
uint64_t *p = (uint64_t *)dst;
|
|
49
|
+
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 16: {
|
|
53
|
+
/* complex128 etc. Two uint64_t stores per element. Compiler
|
|
54
|
+
pairs them into a NEON 128-bit or SSE2 store. */
|
|
55
|
+
uint64_t v0 = ((const uint64_t *)val)[0];
|
|
56
|
+
uint64_t v1 = ((const uint64_t *)val)[1];
|
|
57
|
+
uint64_t *p = (uint64_t *)dst;
|
|
58
|
+
for ( i = 0; i < n; i++ ) {
|
|
59
|
+
p[2*i] = v0;
|
|
60
|
+
p[2*i + 1] = v1;
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
default: {
|
|
65
|
+
/* Generic fallback: CA_FIXLEN (struct types), unusual widths. */
|
|
66
|
+
for ( i = 0; i < n; i++ ) memcpy(dst + i * bytes, val, bytes);
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* --------------------------------------------------------------------- */
|
|
73
|
+
/* ca_composite_region_gather */
|
|
74
|
+
/* */
|
|
75
|
+
/* Per-region strided memcpy from a parent sub-rectangle to an output */
|
|
76
|
+
/* sub-rectangle, with 1D / 2D / N-D fast paths. */
|
|
77
|
+
/* --------------------------------------------------------------------- */
|
|
78
|
+
|
|
79
|
+
void
|
|
80
|
+
ca_composite_region_gather (char *parent_ptr,
|
|
81
|
+
const ca_size_t *parent_strides,
|
|
82
|
+
const ca_size_t *parent_start,
|
|
83
|
+
char *out_ptr,
|
|
84
|
+
const ca_size_t *output_strides,
|
|
85
|
+
const ca_size_t *output_offset,
|
|
86
|
+
const ca_size_t *count,
|
|
87
|
+
int8_t ndim,
|
|
88
|
+
ca_size_t bytes)
|
|
89
|
+
{
|
|
90
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
91
|
+
ca_size_t parent_off, output_off, run_bytes, total_slabs, slab;
|
|
92
|
+
int8_t k;
|
|
93
|
+
int8_t outer_axes;
|
|
94
|
+
|
|
95
|
+
/* Initial byte offsets into parent and output. */
|
|
96
|
+
parent_off = 0;
|
|
97
|
+
output_off = 0;
|
|
98
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
99
|
+
parent_off += parent_start[k] * parent_strides[k];
|
|
100
|
+
output_off += output_offset[k] * output_strides[k];
|
|
101
|
+
idx[k] = 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Innermost axis contributes the contig run; outer axes are walked. */
|
|
105
|
+
run_bytes = count[ndim - 1] * bytes;
|
|
106
|
+
outer_axes = ndim - 1;
|
|
107
|
+
|
|
108
|
+
if ( outer_axes <= 0 ) {
|
|
109
|
+
/* 1-D shortcut: single memcpy. */
|
|
110
|
+
memcpy(out_ptr + output_off, parent_ptr + parent_off, run_bytes);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if ( outer_axes == 1 ) {
|
|
115
|
+
/* 2-D fast path: single outer axis, pointer-advancing loop. No
|
|
116
|
+
multi-dim cursor, no idx[] array — keeps the per-iter body tight
|
|
117
|
+
so SIMD-friendly memcpy can dominate. */
|
|
118
|
+
char *src = parent_ptr + parent_off;
|
|
119
|
+
char *dst = out_ptr + output_off;
|
|
120
|
+
ca_size_t step_p = parent_strides[0];
|
|
121
|
+
ca_size_t step_o = output_strides[0];
|
|
122
|
+
ca_size_t count0 = count[0];
|
|
123
|
+
ca_size_t i;
|
|
124
|
+
for ( i = 0; i < count0; i++ ) {
|
|
125
|
+
memcpy(dst, src, run_bytes);
|
|
126
|
+
dst += step_o;
|
|
127
|
+
src += step_p;
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* General N-D path (ndim >= 3): multi-dim cursor walk over outer axes. */
|
|
133
|
+
total_slabs = 1;
|
|
134
|
+
for ( k = 0; k < outer_axes; k++ ) {
|
|
135
|
+
total_slabs *= count[k];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for ( slab = 0; slab < total_slabs; slab++ ) {
|
|
139
|
+
memcpy(out_ptr + output_off, parent_ptr + parent_off, run_bytes);
|
|
140
|
+
|
|
141
|
+
/* Increment the multi-dim cursor (row-major, outer axes only). */
|
|
142
|
+
for ( k = outer_axes - 1; k >= 0; k-- ) {
|
|
143
|
+
idx[k]++;
|
|
144
|
+
parent_off += parent_strides[k];
|
|
145
|
+
output_off += output_strides[k];
|
|
146
|
+
if ( idx[k] < count[k] ) break;
|
|
147
|
+
parent_off -= parent_strides[k] * count[k];
|
|
148
|
+
output_off -= output_strides[k] * count[k];
|
|
149
|
+
idx[k] = 0;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/* --------------------------------------------------------------------- */
|
|
155
|
+
/* ca_composite_region_scatter */
|
|
156
|
+
/* */
|
|
157
|
+
/* Reverse direction of _gather: copies an input sub-rectangle back into */
|
|
158
|
+
/* a parent sub-rectangle (in_ptr -> parent_ptr). */
|
|
159
|
+
/* --------------------------------------------------------------------- */
|
|
160
|
+
|
|
161
|
+
void
|
|
162
|
+
ca_composite_region_scatter (char *parent_ptr,
|
|
163
|
+
const ca_size_t *parent_strides,
|
|
164
|
+
const ca_size_t *parent_start,
|
|
165
|
+
const char *in_ptr,
|
|
166
|
+
const ca_size_t *input_strides,
|
|
167
|
+
const ca_size_t *input_offset,
|
|
168
|
+
const ca_size_t *count,
|
|
169
|
+
int8_t ndim,
|
|
170
|
+
ca_size_t bytes)
|
|
171
|
+
{
|
|
172
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
173
|
+
ca_size_t parent_off, input_off, run_bytes, total_slabs, slab;
|
|
174
|
+
int8_t k;
|
|
175
|
+
int8_t outer_axes;
|
|
176
|
+
|
|
177
|
+
parent_off = 0;
|
|
178
|
+
input_off = 0;
|
|
179
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
180
|
+
parent_off += parent_start[k] * parent_strides[k];
|
|
181
|
+
input_off += input_offset[k] * input_strides[k];
|
|
182
|
+
idx[k] = 0;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
run_bytes = count[ndim - 1] * bytes;
|
|
186
|
+
outer_axes = ndim - 1;
|
|
187
|
+
|
|
188
|
+
if ( outer_axes <= 0 ) {
|
|
189
|
+
memcpy(parent_ptr + parent_off, in_ptr + input_off, run_bytes);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if ( outer_axes == 1 ) {
|
|
194
|
+
char *dst = parent_ptr + parent_off;
|
|
195
|
+
const char *src = in_ptr + input_off;
|
|
196
|
+
ca_size_t step_p = parent_strides[0];
|
|
197
|
+
ca_size_t step_i = input_strides[0];
|
|
198
|
+
ca_size_t count0 = count[0];
|
|
199
|
+
ca_size_t i;
|
|
200
|
+
for ( i = 0; i < count0; i++ ) {
|
|
201
|
+
memcpy(dst, src, run_bytes);
|
|
202
|
+
dst += step_p;
|
|
203
|
+
src += step_i;
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
total_slabs = 1;
|
|
209
|
+
for ( k = 0; k < outer_axes; k++ ) {
|
|
210
|
+
total_slabs *= count[k];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for ( slab = 0; slab < total_slabs; slab++ ) {
|
|
214
|
+
memcpy(parent_ptr + parent_off, in_ptr + input_off, run_bytes);
|
|
215
|
+
|
|
216
|
+
for ( k = outer_axes - 1; k >= 0; k-- ) {
|
|
217
|
+
idx[k]++;
|
|
218
|
+
parent_off += parent_strides[k];
|
|
219
|
+
input_off += input_strides[k];
|
|
220
|
+
if ( idx[k] < count[k] ) break;
|
|
221
|
+
parent_off -= parent_strides[k] * count[k];
|
|
222
|
+
input_off -= input_strides[k] * count[k];
|
|
223
|
+
idx[k] = 0;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* --------------------------------------------------------------------- */
|
|
229
|
+
/* ca_composite_fill_rect */
|
|
230
|
+
/* */
|
|
231
|
+
/* Fill a rectangle sub-region of out_ptr with `fill_value` (broadcast). */
|
|
232
|
+
/* Mirrors _region_gather but with a fixed source value (no source */
|
|
233
|
+
/* pointer/strides). 1D / 2D / N-D fast paths. */
|
|
234
|
+
/* --------------------------------------------------------------------- */
|
|
235
|
+
|
|
236
|
+
void
|
|
237
|
+
ca_composite_fill_rect (char *out_ptr,
|
|
238
|
+
const ca_size_t *output_strides,
|
|
239
|
+
const ca_size_t *offset,
|
|
240
|
+
const ca_size_t *count,
|
|
241
|
+
const char *fill_value,
|
|
242
|
+
ca_size_t bytes,
|
|
243
|
+
int8_t ndim)
|
|
244
|
+
{
|
|
245
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
246
|
+
ca_size_t output_off, total_slabs, slab;
|
|
247
|
+
int8_t k;
|
|
248
|
+
int8_t outer_axes;
|
|
249
|
+
ca_size_t inner_count;
|
|
250
|
+
|
|
251
|
+
/* Initial byte offset into output. */
|
|
252
|
+
output_off = 0;
|
|
253
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
254
|
+
output_off += offset[k] * output_strides[k];
|
|
255
|
+
idx[k] = 0;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* Innermost axis = SIMD typed fill of `count[ndim-1]` cells per slab. */
|
|
259
|
+
inner_count = count[ndim - 1];
|
|
260
|
+
outer_axes = ndim - 1;
|
|
261
|
+
|
|
262
|
+
/* Early exit on empty inner. */
|
|
263
|
+
if ( inner_count <= 0 ) return;
|
|
264
|
+
|
|
265
|
+
if ( outer_axes <= 0 ) {
|
|
266
|
+
/* 1-D: single typed-fill. */
|
|
267
|
+
ca_fill_typed(out_ptr + output_off, fill_value, bytes, inner_count);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if ( outer_axes == 1 ) {
|
|
272
|
+
/* 2-D fast path. */
|
|
273
|
+
ca_size_t step_o = output_strides[0];
|
|
274
|
+
ca_size_t count0 = count[0];
|
|
275
|
+
if ( count0 <= 0 ) return;
|
|
276
|
+
/* Contig-in-output detection: if successive "rows" of the strip
|
|
277
|
+
are adjacent in output memory (= step_o == inner_count * bytes),
|
|
278
|
+
merge into a single big typed-fill so SIMD bandwidth is fully used.
|
|
279
|
+
For complement-fill axis-0 strips this case fires (= the strip spans
|
|
280
|
+
the full inner extent of output along the rows it covers). */
|
|
281
|
+
if ( step_o == inner_count * bytes ) {
|
|
282
|
+
ca_fill_typed(out_ptr + output_off, fill_value, bytes,
|
|
283
|
+
count0 * inner_count);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
/* Generic per-row fill. */
|
|
287
|
+
{
|
|
288
|
+
char *dst = out_ptr + output_off;
|
|
289
|
+
ca_size_t i;
|
|
290
|
+
for ( i = 0; i < count0; i++ ) {
|
|
291
|
+
ca_fill_typed(dst, fill_value, bytes, inner_count);
|
|
292
|
+
dst += step_o;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* General N-D path (ndim >= 3): collapse all trailing axes whose
|
|
299
|
+
count == output_dim (= step matches contig stride) into the inner
|
|
300
|
+
run, walk only the truly outer axes via multi-dim cursor. */
|
|
301
|
+
{
|
|
302
|
+
int8_t walk_axes = outer_axes;
|
|
303
|
+
ca_size_t merged_inner = inner_count;
|
|
304
|
+
while ( walk_axes > 0
|
|
305
|
+
&& output_strides[walk_axes - 1] == merged_inner * bytes
|
|
306
|
+
&& count[walk_axes - 1] > 0 ) {
|
|
307
|
+
merged_inner *= count[walk_axes - 1];
|
|
308
|
+
walk_axes--;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if ( walk_axes == 0 ) {
|
|
312
|
+
/* Whole strip is contig in output. */
|
|
313
|
+
ca_fill_typed(out_ptr + output_off, fill_value, bytes, merged_inner);
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
total_slabs = 1;
|
|
318
|
+
for ( k = 0; k < walk_axes; k++ ) {
|
|
319
|
+
if ( count[k] <= 0 ) return;
|
|
320
|
+
total_slabs *= count[k];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
for ( slab = 0; slab < total_slabs; slab++ ) {
|
|
324
|
+
ca_fill_typed(out_ptr + output_off, fill_value, bytes, merged_inner);
|
|
325
|
+
|
|
326
|
+
for ( k = walk_axes - 1; k >= 0; k-- ) {
|
|
327
|
+
idx[k]++;
|
|
328
|
+
output_off += output_strides[k];
|
|
329
|
+
if ( idx[k] < count[k] ) break;
|
|
330
|
+
output_off -= output_strides[k] * count[k];
|
|
331
|
+
idx[k] = 0;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* --------------------------------------------------------------------- */
|
|
338
|
+
/* ca_composite_fill_complement */
|
|
339
|
+
/* */
|
|
340
|
+
/* Fill the complement of an alias rectangle. Enumerates up to 2*ndim */
|
|
341
|
+
/* disjoint strips and calls _fill_rect for each non-empty strip. */
|
|
342
|
+
/* */
|
|
343
|
+
/* Strip k "before": alias range on dims 0..k-1, */
|
|
344
|
+
/* [0..alias_offset[k]) on dim k, */
|
|
345
|
+
/* full [0..output_dim[i]) on dims k+1..ndim-1 */
|
|
346
|
+
/* Strip k "after": alias range on dims 0..k-1, */
|
|
347
|
+
/* [alias_offset[k]+alias_count[k]..output_dim[k]) */
|
|
348
|
+
/* on dim k, */
|
|
349
|
+
/* full on dims k+1..ndim-1 */
|
|
350
|
+
/* */
|
|
351
|
+
/* Strips are pairwise disjoint and together cover output minus alias. */
|
|
352
|
+
/* Caller must ensure alias rectangle is within output bounds. */
|
|
353
|
+
/* --------------------------------------------------------------------- */
|
|
354
|
+
|
|
355
|
+
void
|
|
356
|
+
ca_composite_fill_complement (char *out_ptr,
|
|
357
|
+
const ca_size_t *output_strides,
|
|
358
|
+
const ca_size_t *output_dim,
|
|
359
|
+
const ca_size_t *alias_offset,
|
|
360
|
+
const ca_size_t *alias_count,
|
|
361
|
+
const char *fill_value,
|
|
362
|
+
ca_size_t bytes,
|
|
363
|
+
int8_t ndim)
|
|
364
|
+
{
|
|
365
|
+
ca_size_t strip_offset[CA_RANK_MAX];
|
|
366
|
+
ca_size_t strip_count[CA_RANK_MAX];
|
|
367
|
+
int8_t k, m;
|
|
368
|
+
|
|
369
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
370
|
+
ca_size_t a_off = alias_offset[k];
|
|
371
|
+
ca_size_t a_cnt = alias_count[k];
|
|
372
|
+
ca_size_t a_end = a_off + a_cnt;
|
|
373
|
+
|
|
374
|
+
/* "Before" strip on axis k:
|
|
375
|
+
dims 0..k-1: alias range
|
|
376
|
+
dim k: [0..a_off)
|
|
377
|
+
dims k+1..N-1: full output extent */
|
|
378
|
+
if ( a_off > 0 ) {
|
|
379
|
+
for ( m = 0; m < k; m++ ) {
|
|
380
|
+
strip_offset[m] = alias_offset[m];
|
|
381
|
+
strip_count[m] = alias_count[m];
|
|
382
|
+
}
|
|
383
|
+
strip_offset[k] = 0;
|
|
384
|
+
strip_count[k] = a_off;
|
|
385
|
+
for ( m = k + 1; m < ndim; m++ ) {
|
|
386
|
+
strip_offset[m] = 0;
|
|
387
|
+
strip_count[m] = output_dim[m];
|
|
388
|
+
}
|
|
389
|
+
ca_composite_fill_rect(out_ptr, output_strides,
|
|
390
|
+
strip_offset, strip_count,
|
|
391
|
+
fill_value, bytes, ndim);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/* "After" strip on axis k:
|
|
395
|
+
dims 0..k-1: alias range
|
|
396
|
+
dim k: [a_end..output_dim[k])
|
|
397
|
+
dims k+1..N-1: full output extent */
|
|
398
|
+
if ( a_end < output_dim[k] ) {
|
|
399
|
+
for ( m = 0; m < k; m++ ) {
|
|
400
|
+
strip_offset[m] = alias_offset[m];
|
|
401
|
+
strip_count[m] = alias_count[m];
|
|
402
|
+
}
|
|
403
|
+
strip_offset[k] = a_end;
|
|
404
|
+
strip_count[k] = output_dim[k] - a_end;
|
|
405
|
+
for ( m = k + 1; m < ndim; m++ ) {
|
|
406
|
+
strip_offset[m] = 0;
|
|
407
|
+
strip_count[m] = output_dim[m];
|
|
408
|
+
}
|
|
409
|
+
ca_composite_fill_rect(out_ptr, output_strides,
|
|
410
|
+
strip_offset, strip_count,
|
|
411
|
+
fill_value, bytes, ndim);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Geometric primitives for region-mapped views (CAWindow / CATile /
|
|
4
|
+
CARoll). These helpers are the "per-region routine" called by each
|
|
5
|
+
region-mapped view's attach/sync path.
|
|
6
|
+
|
|
7
|
+
Design pattern (= split routines, not a tagged union over source kind):
|
|
8
|
+
- the region descriptor carries only geometric metadata
|
|
9
|
+
(output_offset, count); source info (parent, parent_start, fill_value)
|
|
10
|
+
is passed as a per-call parameter.
|
|
11
|
+
- ALIAS regions use _region_gather / _region_scatter; broadcast fill
|
|
12
|
+
is ca_fill_typed (full output) or _fill_rect / _fill_complement for
|
|
13
|
+
sub-regions.
|
|
14
|
+
|
|
15
|
+
---------------------------------------------------------------------------- */
|
|
16
|
+
|
|
17
|
+
#ifndef CA_COMPOSITE_DISPATCH_H
|
|
18
|
+
#define CA_COMPOSITE_DISPATCH_H
|
|
19
|
+
|
|
20
|
+
#include "carray.h"
|
|
21
|
+
|
|
22
|
+
/* Fill `n` cells of `dst`, each `bytes` wide, with the value at `val`.
|
|
23
|
+
|
|
24
|
+
SIMD-friendly typed-store dispatch on bytes ∈ {1, 2, 4, 8, 16}, generic
|
|
25
|
+
memcpy fallback for other widths (CA_FIXLEN, unusual struct sizes).
|
|
26
|
+
Compiler vectorises the uint16/32/64 stores into NEON / SSE2 stores.
|
|
27
|
+
|
|
28
|
+
Called from ca_obj_window.c and ca_axis_dispatch.c for the
|
|
29
|
+
broadcast-fill step. */
|
|
30
|
+
void ca_fill_typed (char *dst, const char *val,
|
|
31
|
+
ca_size_t bytes, ca_size_t n);
|
|
32
|
+
|
|
33
|
+
/* Strided memcpy from a sub-rectangle of `parent_ptr` to a sub-rectangle
|
|
34
|
+
of `out_ptr`. Both rectangles have the same shape (`count`).
|
|
35
|
+
|
|
36
|
+
parent_ptr : base pointer of parent's row-major contig buffer
|
|
37
|
+
(caller has attached parent; parent->ptr is valid)
|
|
38
|
+
parent_strides : per-axis byte stride within parent (row-major)
|
|
39
|
+
parent_start : per-axis start index in parent for the source rectangle
|
|
40
|
+
out_ptr : base pointer of the output buffer (row-major contig
|
|
41
|
+
over the view's own shape)
|
|
42
|
+
output_strides : per-axis byte stride within output
|
|
43
|
+
output_offset : per-axis start index in output for the destination rectangle
|
|
44
|
+
count : per-axis size of the rectangle (same for both)
|
|
45
|
+
ndim, bytes : view ndim and element bytes
|
|
46
|
+
|
|
47
|
+
Internal fast paths:
|
|
48
|
+
- ndim == 1: single memcpy
|
|
49
|
+
- ndim == 2 (outer_axes == 1): pointer-advancing 2D loop, no idx[]
|
|
50
|
+
- ndim >= 3: multi-dim cursor walk over outer axes
|
|
51
|
+
|
|
52
|
+
Called from the attach paths of ca_obj_window.c, ca_obj_tile.c and
|
|
53
|
+
ca_obj_roll.c. */
|
|
54
|
+
void ca_composite_region_gather (char *parent_ptr,
|
|
55
|
+
const ca_size_t *parent_strides,
|
|
56
|
+
const ca_size_t *parent_start,
|
|
57
|
+
char *out_ptr,
|
|
58
|
+
const ca_size_t *output_strides,
|
|
59
|
+
const ca_size_t *output_offset,
|
|
60
|
+
const ca_size_t *count,
|
|
61
|
+
int8_t ndim,
|
|
62
|
+
ca_size_t bytes);
|
|
63
|
+
|
|
64
|
+
/* Reverse direction: copy from out_ptr rectangle to parent rectangle.
|
|
65
|
+
Called from the sync (write-back) paths of ca_obj_window.c,
|
|
66
|
+
ca_obj_tile.c and ca_obj_roll.c. Same parameter geometry as
|
|
67
|
+
_region_gather. */
|
|
68
|
+
void ca_composite_region_scatter (char *parent_ptr,
|
|
69
|
+
const ca_size_t *parent_strides,
|
|
70
|
+
const ca_size_t *parent_start,
|
|
71
|
+
const char *in_ptr,
|
|
72
|
+
const ca_size_t *input_strides,
|
|
73
|
+
const ca_size_t *input_offset,
|
|
74
|
+
const ca_size_t *count,
|
|
75
|
+
int8_t ndim,
|
|
76
|
+
ca_size_t bytes);
|
|
77
|
+
|
|
78
|
+
/* Complement-aware fill.
|
|
79
|
+
|
|
80
|
+
ca_composite_fill_rect: fill a rectangle sub-region of out_ptr with
|
|
81
|
+
typed value `fill_value` (broadcast). Same rectangle geometry as
|
|
82
|
+
_region_gather but the source is a single value, not a parent
|
|
83
|
+
rectangle. 1D / 2D / N-D internal fast paths.
|
|
84
|
+
|
|
85
|
+
ca_composite_fill_complement: fill the complement of an alias
|
|
86
|
+
rectangle (= output minus alias). Enumerates up to 2*ndim disjoint
|
|
87
|
+
strip regions and calls _fill_rect for each non-empty strip. Each
|
|
88
|
+
strip is a rectangle:
|
|
89
|
+
axis k "before" strip: alias range on dims 0..k-1, [0..alias_offset[k])
|
|
90
|
+
on dim k, full on dims k+1..ndim-1
|
|
91
|
+
axis k "after" strip: alias range on dims 0..k-1,
|
|
92
|
+
[alias_offset[k]+alias_count[k]..output_dim[k])
|
|
93
|
+
on dim k, full on dims k+1..ndim-1
|
|
94
|
+
Strips are pairwise disjoint and together cover output minus alias.
|
|
95
|
+
|
|
96
|
+
Called from CAWindow's attach path: rather than fill_typed over the
|
|
97
|
+
entire output and then overwrite the alias rectangle, fill only the
|
|
98
|
+
complement strips (= no wasted writes on the alias region). */
|
|
99
|
+
void ca_composite_fill_rect (char *out_ptr,
|
|
100
|
+
const ca_size_t *output_strides,
|
|
101
|
+
const ca_size_t *offset,
|
|
102
|
+
const ca_size_t *count,
|
|
103
|
+
const char *fill_value,
|
|
104
|
+
ca_size_t bytes,
|
|
105
|
+
int8_t ndim);
|
|
106
|
+
|
|
107
|
+
void ca_composite_fill_complement (char *out_ptr,
|
|
108
|
+
const ca_size_t *output_strides,
|
|
109
|
+
const ca_size_t *output_dim,
|
|
110
|
+
const ca_size_t *alias_offset,
|
|
111
|
+
const ca_size_t *alias_count,
|
|
112
|
+
const char *fill_value,
|
|
113
|
+
ca_size_t bytes,
|
|
114
|
+
int8_t ndim);
|
|
115
|
+
|
|
116
|
+
#endif /* CA_COMPOSITE_DISPATCH_H */
|