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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
*
|
|
3
|
+
* ca_sweep_engine.h -- sweep (xfer_all) author surface engine, shared helper
|
|
4
|
+
*
|
|
5
|
+
* Established in PROPOSAL_L0_AUTHOR_SURFACE L0.1 (2026-06-11). Extracts
|
|
6
|
+
* the xfer_all-aware lifecycle template previously duplicated 7-times in
|
|
7
|
+
* ext/carray_call_cfunc.c (= one body per arity 1..7) into a single shared
|
|
8
|
+
* helper. Same helper will back the forthcoming CA_FOR_EACH_ELEMENT macro
|
|
9
|
+
* family (L0.2a) and the WHOLE_BUFFER family (L0.2c).
|
|
10
|
+
*
|
|
11
|
+
* Lifecycle template:
|
|
12
|
+
* (1) per-operand acquire
|
|
13
|
+
* OUTPUT (fsync=='1') -> ca_attach + use ca->ptr (sync on release)
|
|
14
|
+
* INPUT (fsync=='0') alias-able -> ca_attach + use ca->ptr
|
|
15
|
+
* INPUT (fsync=='0') non-alias -> xmalloc + ca_xfer_all(GET)
|
|
16
|
+
* (2) broadcast shape check (scalar collapse + n_kernel agreement)
|
|
17
|
+
* (3) mask OR across INPUT operands -> m0 (xmalloc, NULL if none)
|
|
18
|
+
* (4) mask propagate to OUTPUT operands (overwrite output->mask)
|
|
19
|
+
* (5) caller runs the per-cell loop using base[] + stride[]
|
|
20
|
+
* (6) per-operand release (reverse order):
|
|
21
|
+
* sync OUTPUTs, detach attached or xfree owned_buf, xfree m0
|
|
22
|
+
*
|
|
23
|
+
* Why xmalloc instead of ALLOCV_N:
|
|
24
|
+
* ALLOCV_N uses alloca() for sizes < RUBY_ALLOCV_LIMIT (1024 B); the
|
|
25
|
+
* allocation is bound to the calling C frame. When the engine is
|
|
26
|
+
* extracted to a helper function, the alloca'd region would die on
|
|
27
|
+
* helper return. xmalloc/xfree is frame-independent and safe to
|
|
28
|
+
* carry across the helper boundary. Cost: one heap call per non-alias
|
|
29
|
+
* INPUT. For arrays that warrant a kernel loop the cost is negligible.
|
|
30
|
+
*
|
|
31
|
+
* --------------------------------------------------------------------------- */
|
|
32
|
+
|
|
33
|
+
#ifndef CA_SWEEP_ENGINE_H
|
|
34
|
+
#define CA_SWEEP_ENGINE_H
|
|
35
|
+
|
|
36
|
+
#include "carray.h"
|
|
37
|
+
|
|
38
|
+
/* Caller-allocated arrays of length n_ops:
|
|
39
|
+
* - cx[] IN: CArray pointers (caller fills before ca_sweep_acquire)
|
|
40
|
+
* - base[] OUT: per-op base ptr for the per-cell loop
|
|
41
|
+
* - stride[] OUT: per-cell stride in bytes (0 for scalar broadcast)
|
|
42
|
+
* - owned_buf[] OUT: xmalloc'd buffer (NULL if alias or OUTPUT path)
|
|
43
|
+
* - attached[] OUT: 1 if ca_attach was called (= release must ca_detach)
|
|
44
|
+
*
|
|
45
|
+
* Engine-allocated:
|
|
46
|
+
* - m0 OUT: xmalloc'd mask byte array, NULL if no INPUT has mask
|
|
47
|
+
* - n_kernel OUT: broadcast element count
|
|
48
|
+
*
|
|
49
|
+
* fsync: per-op '0'/'1' string of length n_ops. Lifetime must cover both
|
|
50
|
+
* ca_sweep_acquire and ca_sweep_release (caller-owned, typically a string
|
|
51
|
+
* literal or stack-stored).
|
|
52
|
+
*
|
|
53
|
+
* src_label: optional, included in [BUG] error message if fsync length
|
|
54
|
+
* mismatches; NULL falls back to "ca_sweep_acquire".
|
|
55
|
+
*/
|
|
56
|
+
typedef struct ca_sweep_state {
|
|
57
|
+
int n_ops;
|
|
58
|
+
const char *fsync;
|
|
59
|
+
CArray **cx;
|
|
60
|
+
char **base;
|
|
61
|
+
ca_size_t *stride;
|
|
62
|
+
char **owned_buf;
|
|
63
|
+
int *attached;
|
|
64
|
+
boolean8_t *m0;
|
|
65
|
+
ca_size_t n_kernel;
|
|
66
|
+
const char *src_label;
|
|
67
|
+
/* no_mask: if non-zero, ca_sweep_acquire raises when any INPUT operand has
|
|
68
|
+
* a mask. Used by the NO_MASK macro forms (CA_FOR_EACH_ELEMENT etc.) to
|
|
69
|
+
* implement Q3=(ii) runtime error policy. Default 0 (= masked INPUT OK,
|
|
70
|
+
* m0 built as usual). Caller sets before calling ca_sweep_acquire. */
|
|
71
|
+
int no_mask;
|
|
72
|
+
|
|
73
|
+
/* === chunked path fields (L0.1 chunk, PROPOSAL_L0_AUTHOR_SURFACE) === */
|
|
74
|
+
/* Used by ca_sweep_acquire_chunked / ca_sweep_next_chunk / ca_sweep_release_chunked
|
|
75
|
+
* (= the sweep ELEMENT macro family). Unused by the whole-materialise path
|
|
76
|
+
* (ca_sweep_acquire / ca_sweep_release) — cfunc and other whole-buffer callers
|
|
77
|
+
* leave these zero. */
|
|
78
|
+
char **base_orig; /* per-op original ptr (= ca->ptr for
|
|
79
|
+
alias/output; NULL for non-alias INPUT
|
|
80
|
+
that uses an arena chunk scratch).
|
|
81
|
+
Caller-allocated, length n_ops. */
|
|
82
|
+
ca_size_t chunk_n; /* current chunk element count */
|
|
83
|
+
ca_size_t chunk_off; /* current chunk start in flat addr */
|
|
84
|
+
ca_size_t chunk_n_max; /* max chunk size from ca_chunk_compute_n */
|
|
85
|
+
ca_size_t inner; /* product of dims except outermost (= row
|
|
86
|
+
size in elements for outer-axis chunking) */
|
|
87
|
+
int chunked_state; /* 0=pre-init, 1=active, 2=done */
|
|
88
|
+
} ca_sweep_state_t;
|
|
89
|
+
|
|
90
|
+
/* Validate fsync length, acquire per-op buffers, compute broadcast shape +
|
|
91
|
+
* strides, build mask m0, propagate mask to OUTPUTs. May raise (fsync
|
|
92
|
+
* length mismatch, shape mismatch). */
|
|
93
|
+
void ca_sweep_acquire (ca_sweep_state_t *st);
|
|
94
|
+
|
|
95
|
+
/* Reverse-order release: sync OUTPUTs, detach attached / xfree owned_buf,
|
|
96
|
+
* xfree m0. State is single-use; do not call acquire again on the same
|
|
97
|
+
* state without re-initializing the caller-owned arrays. */
|
|
98
|
+
void ca_sweep_release (ca_sweep_state_t *st);
|
|
99
|
+
|
|
100
|
+
/* Strict full-shape equality check used by INOUT macros (AC5: silent-
|
|
101
|
+
* corruption seam prevention). Raises if ndim differs or any dim[k]
|
|
102
|
+
* differs. Returns void; raises on mismatch. */
|
|
103
|
+
void ca_sweep_check_same_shape (CArray *ca_in, CArray *ca_out,
|
|
104
|
+
const char *src_label);
|
|
105
|
+
|
|
106
|
+
/* ===== Chunked path API (sweep ELEMENT macro family, L0.1 chunk) =====
|
|
107
|
+
*
|
|
108
|
+
* Unlike ca_sweep_acquire / ca_sweep_release (= whole-buffer materialise used
|
|
109
|
+
* by cfunc), the chunked path keeps INPUT memory peak bounded to chunk
|
|
110
|
+
* size (~32KB at f64 by default). AC2 ancestor cascade prevention plus
|
|
111
|
+
* memory peak guarantee: shrinking views materialise into chunk scratch
|
|
112
|
+
* sized to inner-axis multiples, not full operand size.
|
|
113
|
+
*
|
|
114
|
+
* Usage shape (inside a macro):
|
|
115
|
+
* ca_sweep_acquire_chunked(&st);
|
|
116
|
+
* while (ca_sweep_next_chunk(&st)) {
|
|
117
|
+
* for (k = 0; k < st.chunk_n; k++) {
|
|
118
|
+
* T x = *(T*)(st.base[0] + k * st.stride[0]);
|
|
119
|
+
* ...
|
|
120
|
+
* }
|
|
121
|
+
* }
|
|
122
|
+
* ca_sweep_release_chunked(&st);
|
|
123
|
+
*
|
|
124
|
+
* OUTPUT operand semantics:
|
|
125
|
+
* OUTPUT is ca_attach'd whole (= self IS write target, legitimate per
|
|
126
|
+
* E.7 invariant), and base[k] is rewritten per chunk as base_orig[k] +
|
|
127
|
+
* chunk_off * stride[k] so author writes land in the correct region.
|
|
128
|
+
* Final ca_sync runs in release_chunked. Output memory peak = entity
|
|
129
|
+
* size (= unavoidable; output buffer must exist).
|
|
130
|
+
*
|
|
131
|
+
* INPUT operand semantics:
|
|
132
|
+
* alias INPUT: base[k] = ca->ptr + chunk_off * stride[k], no gather.
|
|
133
|
+
* non-alias INPUT: arena scratch of size chunk_n_max * bytes is held
|
|
134
|
+
* for the entire walk; ca_chunked_gather rewrites it per chunk.
|
|
135
|
+
*
|
|
136
|
+
* Mask handling (m0):
|
|
137
|
+
* Built once in acquire_chunked at full size (= n_kernel bytes).
|
|
138
|
+
* Macros that want per-cell mask read at m0[chunk_off + k].
|
|
139
|
+
* Full-size m0 mirrors the whole path; per-chunk mask gather is a
|
|
140
|
+
* future optim.
|
|
141
|
+
*/
|
|
142
|
+
void ca_sweep_acquire_chunked (ca_sweep_state_t *st);
|
|
143
|
+
int ca_sweep_next_chunk (ca_sweep_state_t *st); /* 1 = chunk ready, 0 = done */
|
|
144
|
+
void ca_sweep_release_chunked (ca_sweep_state_t *st);
|
|
145
|
+
|
|
146
|
+
/* ===== Chunking helpers (extern-ified from carray_operator.c) ===== */
|
|
147
|
+
ca_size_t ca_chunk_inner_size (CArray *ca);
|
|
148
|
+
ca_size_t ca_chunk_compute_n (ca_size_t total, ca_size_t inner,
|
|
149
|
+
ca_size_t bytes_per_cell);
|
|
150
|
+
void ca_chunked_gather (CArray *ca, ca_size_t off, ca_size_t n,
|
|
151
|
+
void *dest);
|
|
152
|
+
|
|
153
|
+
/* Arena pool (extern-ified earlier by lazy substrate; reused here). */
|
|
154
|
+
extern void *ca_lazy_arena_acquire (ca_size_t bytes);
|
|
155
|
+
extern void ca_lazy_arena_release (void *ptr);
|
|
156
|
+
|
|
157
|
+
#endif /* CA_SWEEP_ENGINE_H */
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Shared substrate for byte-level 1:1 value-transform views (CAFake /
|
|
4
|
+
CAByteSwap). Implements the "compose to root + walk + transform in
|
|
5
|
+
flight" fast path used by xfer_stride (and indirectly by xfer_all via
|
|
6
|
+
thin-wrapper delegation).
|
|
7
|
+
|
|
8
|
+
Design and rationale: devel/PROPOSAL_TRANSFORM_FUSED_XFER.md.
|
|
9
|
+
|
|
10
|
+
---------------------------------------------------------------------------- */
|
|
11
|
+
|
|
12
|
+
#include "carray.h"
|
|
13
|
+
#include "ca_iter_substrate.h"
|
|
14
|
+
#include <string.h>
|
|
15
|
+
|
|
16
|
+
/* CAStride compose helper (ca_obj_stride.c). */
|
|
17
|
+
extern void ca_stride_compose_to_root (CAStride *leaf, CArray **out_root,
|
|
18
|
+
ca_size_t *out_strides,
|
|
19
|
+
ca_size_t *out_base);
|
|
20
|
+
extern ca_operation_function_t ca_stride_func;
|
|
21
|
+
|
|
22
|
+
/* ---------------------------------------------------------------------------
|
|
23
|
+
ca_xfer_stride_transform_fused
|
|
24
|
+
|
|
25
|
+
Walk parent's CAStride chain to its root (an entity with live ptr), then
|
|
26
|
+
for each inner row gather one strided run from root.ptr into a row scratch
|
|
27
|
+
in parent data_type and apply the per-view transform callback to write that
|
|
28
|
+
row to dst in view data_type. No whole-view scratch, no ca_attach -- a true
|
|
29
|
+
1-pass fused walk for both GET and PUT.
|
|
30
|
+
|
|
31
|
+
PUT is symmetric to GET: cast dst (view data_type) into row scratch (parent
|
|
32
|
+
data_type) via xform_put, then scatter row scratch into root.ptr strided.
|
|
33
|
+
|
|
34
|
+
Eligibility (returns 0 = fail, caller falls back to its existing path):
|
|
35
|
+
- parent is in the CAStride family (= ca_func[].attach matches)
|
|
36
|
+
- ndim >= 1
|
|
37
|
+
- compose_to_root yields a root with live ptr (= entity / attached)
|
|
38
|
+
|
|
39
|
+
Mask: not consulted. Post-xfer-reform data paths are mask-blind by
|
|
40
|
+
design; mask is propagated on a separate channel. See
|
|
41
|
+
PROPOSAL_TRANSFORM_FUSED_XFER.md for the audit.
|
|
42
|
+
|
|
43
|
+
row scratch sizing: stack 16 KB first, ALLOCV (alloca-like) for larger.
|
|
44
|
+
|
|
45
|
+
Callers (= the two transform views that wire xform_get/_put):
|
|
46
|
+
- ext/ca_obj_fake.c (CAFake; xform = type cast)
|
|
47
|
+
- ext/ca_obj_byte_swap.c (CAByteSwap; xform = endian swap)
|
|
48
|
+
The ca_transform_row_fn callback contract is declared in
|
|
49
|
+
ext/ca_iter_substrate.h.
|
|
50
|
+
--------------------------------------------------------------------------- */
|
|
51
|
+
|
|
52
|
+
#define CA_TRANSFORM_ROW_STACK_BYTES 16384
|
|
53
|
+
|
|
54
|
+
int
|
|
55
|
+
ca_xfer_stride_transform_fused (CArray *view,
|
|
56
|
+
CArray *parent,
|
|
57
|
+
ca_size_t *starts,
|
|
58
|
+
ca_size_t *counts,
|
|
59
|
+
ca_size_t *strides,
|
|
60
|
+
char *data,
|
|
61
|
+
int dir,
|
|
62
|
+
ca_transform_row_fn xform_get,
|
|
63
|
+
ca_transform_row_fn xform_put)
|
|
64
|
+
{
|
|
65
|
+
CArray *root;
|
|
66
|
+
ca_size_t composed_strides[CA_RANK_MAX];
|
|
67
|
+
ca_size_t composed_base;
|
|
68
|
+
ca_size_t parent_bytes, view_bytes;
|
|
69
|
+
int8_t ndim, k;
|
|
70
|
+
ca_size_t inner_count, inner_stride;
|
|
71
|
+
ca_size_t row_bytes;
|
|
72
|
+
char *row_buf;
|
|
73
|
+
char row_stack[CA_TRANSFORM_ROW_STACK_BYTES];
|
|
74
|
+
volatile VALUE holder = Qnil;
|
|
75
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
76
|
+
ca_size_t outer_total, n, doff;
|
|
77
|
+
|
|
78
|
+
/* ---- Eligibility ---- */
|
|
79
|
+
if ( view->ndim < 1 ) return 0;
|
|
80
|
+
if ( dir != CA_XFER_GET && dir != CA_XFER_PUT ) return 0;
|
|
81
|
+
|
|
82
|
+
parent_bytes = parent->bytes;
|
|
83
|
+
view_bytes = view->bytes;
|
|
84
|
+
ndim = view->ndim;
|
|
85
|
+
/* CAREFUL: must use counts[ndim-1] (the sub-region width), not
|
|
86
|
+
view->dim[ndim-1] (the full view width). Caller's data buffer is
|
|
87
|
+
sized for counts[], so a sub-region PUT through a CATranspose-of-
|
|
88
|
+
CAFake chain overflows the buffer if the full view dim is used. */
|
|
89
|
+
inner_count = counts[ndim - 1];
|
|
90
|
+
if ( inner_count == 0 ) return 1; /* trivially complete */
|
|
91
|
+
|
|
92
|
+
/* Compute view's natural row-major byte strides in view byte space. */
|
|
93
|
+
ca_size_t view_native[CA_RANK_MAX];
|
|
94
|
+
{
|
|
95
|
+
ca_size_t s = view_bytes;
|
|
96
|
+
for ( k = ndim - 1; k >= 0; k-- ) {
|
|
97
|
+
view_native[k] = s;
|
|
98
|
+
s *= view->dim[k];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ca_size_t eff_root_step[CA_RANK_MAX];
|
|
103
|
+
|
|
104
|
+
/* ---- Resolve parent's data source: two cases ---- */
|
|
105
|
+
if ( ca_func[parent->obj_type].attach == ca_stride_func.attach ) {
|
|
106
|
+
/* (A) CAStride family parent: compose stride chain down to root.
|
|
107
|
+
composed_strides[k] = root bytes per ONE view cell on axis k
|
|
108
|
+
(already accounts for parent's possibly-permuted layout).
|
|
109
|
+
Requires caller's strides to be natural multiples of view_native[]
|
|
110
|
+
so req_step is integer; otherwise fallback. */
|
|
111
|
+
ca_stride_compose_to_root((CAStride *)parent, &root,
|
|
112
|
+
composed_strides, &composed_base);
|
|
113
|
+
if ( !root->ptr ) return 0;
|
|
114
|
+
if ( parent->bytes != root->bytes ) return 0;
|
|
115
|
+
|
|
116
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
117
|
+
if ( view_native[k] == 0 ) return 0;
|
|
118
|
+
if ( strides[k] % view_native[k] != 0 ) return 0; /* non-natural */
|
|
119
|
+
ca_size_t req_step = strides[k] / view_native[k];
|
|
120
|
+
composed_base += starts[k] * composed_strides[k];
|
|
121
|
+
eff_root_step[k] = req_step * composed_strides[k];
|
|
122
|
+
}
|
|
123
|
+
} else if ( parent->ptr ) {
|
|
124
|
+
/* (B) Non-CAStride parent with live ptr (= entity / attached view).
|
|
125
|
+
Parent has linear row-major byte layout: bytes scale uniformly with
|
|
126
|
+
cells via parent_bytes/view_bytes ratio (CAFake is 1:1 shape
|
|
127
|
+
preserving). Use the universal "OLD CAFake" formula:
|
|
128
|
+
root byte step per axis-k iter = strides[k] * parent_bytes / view_bytes
|
|
129
|
+
root base contribution = starts[k] * parent_native[k]
|
|
130
|
+
This naturally handles transposed/sub-sampled caller strides. */
|
|
131
|
+
root = parent;
|
|
132
|
+
composed_base = 0;
|
|
133
|
+
if ( view_bytes == 0 ) return 0;
|
|
134
|
+
if ( parent_bytes % view_bytes != 0 && view_bytes % parent_bytes != 0 ) return 0;
|
|
135
|
+
|
|
136
|
+
ca_size_t parent_native[CA_RANK_MAX];
|
|
137
|
+
{
|
|
138
|
+
ca_size_t s = parent_bytes;
|
|
139
|
+
for ( k = parent->ndim - 1; k >= 0; k-- ) {
|
|
140
|
+
parent_native[k] = s;
|
|
141
|
+
s *= parent->dim[k];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
145
|
+
composed_base += starts[k] * parent_native[k];
|
|
146
|
+
eff_root_step[k] = strides[k] * parent_bytes / view_bytes;
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
/* Cold non-CAStride boundary (= CASelect etc. without ptr) -- fallback. */
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
inner_stride = eff_root_step[ndim - 1];
|
|
154
|
+
|
|
155
|
+
/* When the inner row is contig in root (= inner_stride == parent_bytes),
|
|
156
|
+
the scratch gather/scatter is redundant -- xform_get/_put can read or
|
|
157
|
+
write root->ptr+soff directly, saving the row_buf allocation and one
|
|
158
|
+
of the two memory passes per outer row. Transposed access through
|
|
159
|
+
CATranspose-of-CAFake has inner_stride != parent_bytes and falls
|
|
160
|
+
through to the scratch+gather path. See
|
|
161
|
+
PROPOSAL_XFER_STRIDE_PER_REGION_GAPS.md. */
|
|
162
|
+
int inner_contig = (inner_stride == parent_bytes);
|
|
163
|
+
|
|
164
|
+
/* A 2D tile-cache + bulk-cast variant of this loop was explored and
|
|
165
|
+
reverted: the existing per-row walker already streams source through
|
|
166
|
+
L2/L3, and the tile path loses to per-call cast dispatch overhead
|
|
167
|
+
and an extra untranspose pass. See
|
|
168
|
+
PROPOSAL_TRANSFORM_FUSED_XFER.md for the rejected-direction record.
|
|
169
|
+
A typed (src,dst)-specialised inner loop is the next candidate. */
|
|
170
|
+
|
|
171
|
+
/* ---- Row scratch (parent data_type, inner_count cells) ----
|
|
172
|
+
Skipped when inner_contig is true (= every outer iter uses the
|
|
173
|
+
direct fast path below). */
|
|
174
|
+
row_bytes = inner_count * parent_bytes;
|
|
175
|
+
row_buf = NULL;
|
|
176
|
+
if ( !inner_contig ) {
|
|
177
|
+
if ( row_bytes <= (ca_size_t)CA_TRANSFORM_ROW_STACK_BYTES ) {
|
|
178
|
+
row_buf = row_stack;
|
|
179
|
+
} else {
|
|
180
|
+
row_buf = ALLOCV_N(char, holder, row_bytes);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ---- Walk outer (ndim-1) axes on odometer ---- */
|
|
185
|
+
outer_total = 1;
|
|
186
|
+
for ( k = 0; k < ndim - 1; k++ ) outer_total *= counts[k];
|
|
187
|
+
for ( k = 0; k < ndim - 1; k++ ) idx[k] = 0;
|
|
188
|
+
doff = 0;
|
|
189
|
+
|
|
190
|
+
for ( n = 0; n < outer_total; n++ ) {
|
|
191
|
+
/* Outer offset into root for this inner row. */
|
|
192
|
+
ca_size_t soff = composed_base;
|
|
193
|
+
for ( k = 0; k < ndim - 1; k++ ) soff += idx[k] * eff_root_step[k];
|
|
194
|
+
|
|
195
|
+
if ( inner_contig ) {
|
|
196
|
+
/* Inner-row contig in root; no scratch needed. */
|
|
197
|
+
if ( dir == CA_XFER_GET ) {
|
|
198
|
+
xform_get(inner_count, parent, root->ptr + soff,
|
|
199
|
+
view, data + doff);
|
|
200
|
+
} else {
|
|
201
|
+
xform_put(inner_count, view, data + doff,
|
|
202
|
+
parent, root->ptr + soff);
|
|
203
|
+
}
|
|
204
|
+
} else if ( dir == CA_XFER_GET ) {
|
|
205
|
+
/* root.ptr+soff strided -> row_buf contig (parent data_type). */
|
|
206
|
+
ca_stride_gather_run(row_buf, root->ptr + soff,
|
|
207
|
+
parent_bytes, inner_count, inner_stride);
|
|
208
|
+
/* row_buf (parent data_type) -> data+doff (view data_type). */
|
|
209
|
+
xform_get(inner_count, parent, row_buf, view, data + doff);
|
|
210
|
+
} else {
|
|
211
|
+
/* data+doff (view data_type) -> row_buf contig (parent data_type). */
|
|
212
|
+
xform_put(inner_count, view, data + doff, parent, row_buf);
|
|
213
|
+
/* row_buf contig -> root.ptr+soff strided (parent data_type). */
|
|
214
|
+
ca_stride_scatter_run(root->ptr + soff, row_buf,
|
|
215
|
+
parent_bytes, inner_count, inner_stride);
|
|
216
|
+
}
|
|
217
|
+
doff += inner_count * view_bytes;
|
|
218
|
+
|
|
219
|
+
/* Odometer advance over the outer (ndim-1) axes. */
|
|
220
|
+
if ( ndim < 2 ) break;
|
|
221
|
+
k = ndim - 2;
|
|
222
|
+
while ( k >= 0 ) { if ( ++idx[k] < counts[k] ) break; idx[k] = 0; k--; }
|
|
223
|
+
if ( k < 0 ) break;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if ( holder != Qnil ) ALLOCV_END(holder);
|
|
227
|
+
return 1;
|
|
228
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
CATriOp dispatch: routes a triop op id (`CA_TRIOP_*`) to the per-
|
|
4
|
+
data_type kernel and computes the 3-way promotion.
|
|
5
|
+
|
|
6
|
+
Sibling of ca_binop_dispatch.c (binary counterpart) and
|
|
7
|
+
ca_obj_triop.c (the CATriOp view). Per-data_type kernel tables
|
|
8
|
+
are declared in ca_triop_dispatch.h.
|
|
9
|
+
|
|
10
|
+
All 3 operands are cast to the common promoted data_type before the
|
|
11
|
+
kernel runs (cast-before invariant, same as CABinOp). Output data_type
|
|
12
|
+
is the common promoted data_type.
|
|
13
|
+
|
|
14
|
+
---------------------------------------------------------------------------- */
|
|
15
|
+
|
|
16
|
+
#include "carray.h"
|
|
17
|
+
#include "ca_triop_dispatch.h"
|
|
18
|
+
|
|
19
|
+
/* ------------------------------------------------------------------- */
|
|
20
|
+
/* vvv kernel lookup */
|
|
21
|
+
/* ------------------------------------------------------------------- */
|
|
22
|
+
|
|
23
|
+
ca_triop_func_t
|
|
24
|
+
ca_triop_kernel_lookup_vvv (uint16_t op_id, int8_t common_dt)
|
|
25
|
+
{
|
|
26
|
+
switch (op_id) {
|
|
27
|
+
case CA_TRIOP_FMA: return ca_triop_fma [common_dt];
|
|
28
|
+
case CA_TRIOP_FMS: return ca_triop_fms [common_dt];
|
|
29
|
+
case CA_TRIOP_CLIP: return ca_triop_clip [common_dt];
|
|
30
|
+
default: return NULL;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* ------------------------------------------------------------------- */
|
|
35
|
+
/* 3-way promotion */
|
|
36
|
+
/* ------------------------------------------------------------------- */
|
|
37
|
+
|
|
38
|
+
int8_t
|
|
39
|
+
ca_lazy_promote_triop (uint16_t op_id, int8_t dt1, int8_t dt2, int8_t dt3)
|
|
40
|
+
{
|
|
41
|
+
(void) op_id; /* uniform 3-way promote across all currently-defined triops */
|
|
42
|
+
return (int8_t) ca_promote_type(ca_promote_type(dt1, dt2), dt3);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void
|
|
46
|
+
ca_triop_kernel_input_data_types (uint16_t op_id,
|
|
47
|
+
int8_t dt1, int8_t dt2, int8_t dt3,
|
|
48
|
+
int8_t *out_dt1, int8_t *out_dt2,
|
|
49
|
+
int8_t *out_dt3)
|
|
50
|
+
{
|
|
51
|
+
int8_t common = ca_lazy_promote_triop(op_id, dt1, dt2, dt3);
|
|
52
|
+
if ( out_dt1 ) *out_dt1 = common;
|
|
53
|
+
if ( out_dt2 ) *out_dt2 = common;
|
|
54
|
+
if ( out_dt3 ) *out_dt3 = common;
|
|
55
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
ca_triop_dispatch.h
|
|
4
|
+
|
|
5
|
+
CATriOp dispatch API — sibling of ca_binop_dispatch.h. Routes a
|
|
6
|
+
triop op id (`CA_TRIOP_*`) to the per-data_type kernel and computes
|
|
7
|
+
the 3-way input promotion.
|
|
8
|
+
|
|
9
|
+
Kernel signature: fn(n, mask, src1, i1, src2, i2, src3, i3, dst, i4)
|
|
10
|
+
All 3 operands are cast to the common data_type before the kernel
|
|
11
|
+
runs (cast-before invariant, mirrors CABinOp). Output data_type is
|
|
12
|
+
always the common data_type (preserve).
|
|
13
|
+
|
|
14
|
+
Scope: fma / fms / clip (see ext/mkkernel.rb :fma / :fms / :clip).
|
|
15
|
+
None of the currently-defined triops trap on integer zero divisor.
|
|
16
|
+
|
|
17
|
+
---------------------------------------------------------------------------- */
|
|
18
|
+
|
|
19
|
+
#ifndef CA_TRIOP_DISPATCH_H
|
|
20
|
+
#define CA_TRIOP_DISPATCH_H
|
|
21
|
+
|
|
22
|
+
#include "carray.h"
|
|
23
|
+
|
|
24
|
+
/* ------------------------------------------------------------------- */
|
|
25
|
+
/* op_id enum */
|
|
26
|
+
/* ------------------------------------------------------------------- */
|
|
27
|
+
|
|
28
|
+
enum {
|
|
29
|
+
CA_TRIOP_FMA = 0, /* a * b + c (single-rounding on float) */
|
|
30
|
+
CA_TRIOP_FMS = 1, /* a * b - c (single-rounding on float) */
|
|
31
|
+
CA_TRIOP_CLIP = 2, /* min(max(a, lo), hi), NaN-preserving */
|
|
32
|
+
|
|
33
|
+
CA_TRIOP_COUNT
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/* ------------------------------------------------------------------- */
|
|
37
|
+
/* Kernel dispatch tables (per-data_type) */
|
|
38
|
+
/* ------------------------------------------------------------------- */
|
|
39
|
+
|
|
40
|
+
extern ca_triop_func_t ca_triop_fma [CA_NTYPE];
|
|
41
|
+
extern ca_triop_func_t ca_triop_fms [CA_NTYPE];
|
|
42
|
+
extern ca_triop_func_t ca_triop_clip [CA_NTYPE];
|
|
43
|
+
|
|
44
|
+
/* ------------------------------------------------------------------- */
|
|
45
|
+
/* Dispatch API */
|
|
46
|
+
/* ------------------------------------------------------------------- */
|
|
47
|
+
|
|
48
|
+
/* Look up the triop kernel for (op_id, common_dt). Returns NULL if
|
|
49
|
+
not implemented at the requested data_type. */
|
|
50
|
+
ca_triop_func_t ca_triop_kernel_lookup_vvv (uint16_t op_id, int8_t common_dt);
|
|
51
|
+
|
|
52
|
+
/* 3-way promotion: common data_type of (dt1, dt2, dt3). */
|
|
53
|
+
int8_t ca_lazy_promote_triop (uint16_t op_id, int8_t dt1, int8_t dt2, int8_t dt3);
|
|
54
|
+
|
|
55
|
+
/* Each operand's cast-target data_type (= common data_type for all three,
|
|
56
|
+
the cast-before invariant). */
|
|
57
|
+
void ca_triop_kernel_input_data_types (uint16_t op_id,
|
|
58
|
+
int8_t dt1, int8_t dt2, int8_t dt3,
|
|
59
|
+
int8_t *out_dt1, int8_t *out_dt2,
|
|
60
|
+
int8_t *out_dt3);
|
|
61
|
+
|
|
62
|
+
#endif /* CA_TRIOP_DISPATCH_H */
|