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,480 @@
|
|
|
1
|
+
# ext/mk_call_cfunc.rb -- generator for ext/carray_call_cfunc.{c,h}
|
|
2
|
+
#
|
|
3
|
+
# Emits the ext-author-facing API `ca_call_cfunc_N` (= raw arity 1..7) and
|
|
4
|
+
# `ca_call_cfunc_M_N` (= typed dispatcher) used by external CArray gems
|
|
5
|
+
# (carray-gsl, etc.) to wrap C math functions over CArray operations.
|
|
6
|
+
#
|
|
7
|
+
# Generated 2026-06-10 as part of the PROPOSAL_EAGER_SLOWPATH_CHUNKING_ARENA
|
|
8
|
+
# attach-elimination flow extension (= D phase): the raw `ca_call_cfunc_N`
|
|
9
|
+
# template applies C.7-style alias / non-alias bifurcation for INPUT-only
|
|
10
|
+
# operands (= fsync[k] == '0') and ca_xfer_all-based safe mask gather (= no
|
|
11
|
+
# `ca_attach` on operand masks). OUTPUT operands (= fsync[k] == '1') still
|
|
12
|
+
# use ca_attach + ca_sync (= legitimate per the refined input-only-operand
|
|
13
|
+
# invariant).
|
|
14
|
+
#
|
|
15
|
+
# ABI 100% preserved: signatures, data_type semantics, fsync format, return
|
|
16
|
+
# behavior all unchanged. External gems link against the same symbols
|
|
17
|
+
# without source change.
|
|
18
|
+
#
|
|
19
|
+
# Why a generator? Each of the 7 raw + 13 typed variants is mechanically
|
|
20
|
+
# the same body with arity differences. Hand-keeping 1088 lines invites
|
|
21
|
+
# divergence (= the attach-safe rewrite would have to be repeated 20 times
|
|
22
|
+
# perfectly). The generator centralises the template so a single edit
|
|
23
|
+
# updates every variant. Add a new arity / typed pair by appending one
|
|
24
|
+
# line to the spec.
|
|
25
|
+
#
|
|
26
|
+
# Header (`carray_call_cfunc.h`) is emitted alongside the source so the
|
|
27
|
+
# extern declarations cannot drift from the function definitions. Both
|
|
28
|
+
# files are written in a single invocation; output paths default to
|
|
29
|
+
# `carray_call_cfunc.c` / `carray_call_cfunc.h` in the current directory
|
|
30
|
+
# and can be overridden as `ruby mk_call_cfunc.rb <src.c> <hdr.h>`.
|
|
31
|
+
|
|
32
|
+
# --- spec -------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
RAW_ARITIES = (1..7).to_a # ca_call_cfunc_1 .. _7
|
|
35
|
+
TYPED_PAIRS = [ # ca_call_cfunc_<m>_<n> (m outputs, n inputs)
|
|
36
|
+
[1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6],
|
|
37
|
+
[2, 1], [2, 2], [2, 3], [2, 4],
|
|
38
|
+
[3, 1], [3, 2], [3, 3],
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
# --- helpers ----------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
def void_p_list(n)
|
|
44
|
+
(0...n).map { |k| "void *p#{k}" }.join(", ")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# For _r variants: callback signature gains a trailing `void *userdata`.
|
|
48
|
+
def void_p_list_r(n)
|
|
49
|
+
void_p_list(n) + ", void *userdata"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def value_param_list(n, prefix: "rcx")
|
|
53
|
+
(0...n).map { |k| "VALUE #{prefix}#{k}" }.join(", ")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def args_p(n)
|
|
57
|
+
(0...n).map { |k| "p[#{k}]" }.join(", ")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# For _r variants: inner call gains a trailing `userdata` arg.
|
|
61
|
+
def args_p_r(n)
|
|
62
|
+
args_p(n) + ", userdata"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# --- signature builders -----------------------------------------------------
|
|
66
|
+
#
|
|
67
|
+
# Each builder returns the multi-line function prototype (without trailing
|
|
68
|
+
# `;` or `{`). Source emitters append the body; header emitters append `;`.
|
|
69
|
+
# Centralising signatures here prevents drift between `.c` and `.h`.
|
|
70
|
+
|
|
71
|
+
def sig_raw(n)
|
|
72
|
+
"VALUE\nca_call_cfunc_#{n} (void (*func)(#{void_p_list(n)}), const char *fsync,\n #{value_param_list(n)})"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def sig_raw_r(n)
|
|
76
|
+
"VALUE\nca_call_cfunc_#{n}_r (void (*func)(#{void_p_list_r(n)}), const char *fsync,\n #{value_param_list(n)},\n void *userdata)"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def typed_params(m, n, r: false)
|
|
80
|
+
dty = ->(k) { m == 1 ? "dty" : "dty#{k + 1}" }
|
|
81
|
+
out_data_type_params = (0...m).map { |k| "int8_t #{dty.(k)}" }
|
|
82
|
+
in_data_type_params = (0...n).map { |k| "int8_t dtx#{k + 1}" }
|
|
83
|
+
in_value_params = (0...n).map { |k| "volatile VALUE rx#{k + 1}" }
|
|
84
|
+
fp_args = ["void*"] * (m + n)
|
|
85
|
+
fp_args << "void *userdata" if r
|
|
86
|
+
func_sig = "void (*mathfunc)(#{fp_args.join(", ")})"
|
|
87
|
+
params = out_data_type_params + in_data_type_params + [func_sig] + in_value_params
|
|
88
|
+
params << "void *userdata" if r
|
|
89
|
+
params.join(", ")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def sig_typed(m, n)
|
|
93
|
+
"VALUE\nca_call_cfunc_#{m}_#{n} (#{typed_params(m, n)})"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def sig_typed_r(m, n)
|
|
97
|
+
"VALUE\nca_call_cfunc_#{m}_#{n}_r (#{typed_params(m, n, r: true)})"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Re-indent each non-blank line of `s` with `prefix`. `<<~` strips the
|
|
101
|
+
# common leading whitespace from a heredoc, which would leave our body
|
|
102
|
+
# at column 0; we want a 2-space body indent inside the function brace.
|
|
103
|
+
def indent(s, prefix = " ")
|
|
104
|
+
s.each_line.map { |l| l.strip.empty? ? l : prefix + l }.join
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# --- raw ca_call_cfunc_N ----------------------------------------------------
|
|
108
|
+
|
|
109
|
+
def emit_raw(n)
|
|
110
|
+
$src.puts sig_raw(n)
|
|
111
|
+
$src.puts "{"
|
|
112
|
+
$src.puts indent(<<~END_C)
|
|
113
|
+
CArray *cx[#{n}];
|
|
114
|
+
char *base[#{n}];
|
|
115
|
+
ca_size_t stride[#{n}];
|
|
116
|
+
char *owned_buf[#{n}];
|
|
117
|
+
int attached[#{n}];
|
|
118
|
+
ca_sweep_state_t state;
|
|
119
|
+
int k_op;
|
|
120
|
+
|
|
121
|
+
END_C
|
|
122
|
+
# extract CArray* from VALUE
|
|
123
|
+
(0...n).each do |k|
|
|
124
|
+
$src.puts " TypedData_Get_Struct(rcx#{k}, CArray, &carray_data_type, cx[#{k}]);"
|
|
125
|
+
end
|
|
126
|
+
$src.puts ""
|
|
127
|
+
$src.puts <<~END_C
|
|
128
|
+
/* sweep engine: per-operand acquire (alias / xmalloc + ca_xfer_all),
|
|
129
|
+
broadcast shape check, mask OR across INPUTs, mask propagate to
|
|
130
|
+
OUTPUTs. Lifecycle template lives in ext/ca_sweep_engine.{c,h}. */
|
|
131
|
+
state.n_ops = #{n};
|
|
132
|
+
state.fsync = fsync;
|
|
133
|
+
state.cx = cx;
|
|
134
|
+
state.base = base;
|
|
135
|
+
state.stride = stride;
|
|
136
|
+
state.owned_buf = owned_buf;
|
|
137
|
+
state.attached = attached;
|
|
138
|
+
state.no_mask = 0;
|
|
139
|
+
state.src_label = "ca_call_cfunc_#{n}";
|
|
140
|
+
|
|
141
|
+
ca_sweep_acquire(&state);
|
|
142
|
+
|
|
143
|
+
/* inner loop: advance per-cell ptrs and invoke user kernel func */
|
|
144
|
+
{
|
|
145
|
+
char *p[#{n}];
|
|
146
|
+
ca_size_t k;
|
|
147
|
+
if ( state.m0 ) {
|
|
148
|
+
for ( k = 0; k < state.n_kernel; k++ ) {
|
|
149
|
+
if ( ! state.m0[k] ) {
|
|
150
|
+
for ( k_op = 0; k_op < #{n}; k_op++ ) {
|
|
151
|
+
p[k_op] = base[k_op] + k * stride[k_op];
|
|
152
|
+
}
|
|
153
|
+
func(#{args_p(n)});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
for ( k = 0; k < state.n_kernel; k++ ) {
|
|
158
|
+
for ( k_op = 0; k_op < #{n}; k_op++ ) {
|
|
159
|
+
p[k_op] = base[k_op] + k * stride[k_op];
|
|
160
|
+
}
|
|
161
|
+
func(#{args_p(n)});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
ca_sweep_release(&state);
|
|
167
|
+
|
|
168
|
+
return rcx0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
END_C
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# --- raw ca_call_cfunc_N_r (reentrant: + void *userdata at signature tail) --
|
|
175
|
+
#
|
|
176
|
+
# Variant of emit_raw with a trailing `void *userdata` parameter passed
|
|
177
|
+
# through to every per-cell `func(...)` invocation as its last argument.
|
|
178
|
+
# Naming follows POSIX convention (qsort_r / bsearch_r / strtok_r), where
|
|
179
|
+
# `_r` marks a reentrant form that takes a thunk so the callback no longer
|
|
180
|
+
# depends on file-static / global state. Use when the callback needs to
|
|
181
|
+
# share state with the caller (e.g. accumulators, configuration flags,
|
|
182
|
+
# library plan handles) without resorting to file-static plumbing.
|
|
183
|
+
def emit_raw_r(n)
|
|
184
|
+
$src.puts sig_raw_r(n)
|
|
185
|
+
$src.puts "{"
|
|
186
|
+
$src.puts indent(<<~END_C)
|
|
187
|
+
CArray *cx[#{n}];
|
|
188
|
+
char *base[#{n}];
|
|
189
|
+
ca_size_t stride[#{n}];
|
|
190
|
+
char *owned_buf[#{n}];
|
|
191
|
+
int attached[#{n}];
|
|
192
|
+
ca_sweep_state_t state;
|
|
193
|
+
int k_op;
|
|
194
|
+
|
|
195
|
+
END_C
|
|
196
|
+
(0...n).each do |k|
|
|
197
|
+
$src.puts " TypedData_Get_Struct(rcx#{k}, CArray, &carray_data_type, cx[#{k}]);"
|
|
198
|
+
end
|
|
199
|
+
$src.puts ""
|
|
200
|
+
$src.puts <<~END_C
|
|
201
|
+
/* sweep engine: same lifecycle as ca_call_cfunc_#{n}; the difference is
|
|
202
|
+
the per-cell `func(...)` call has `userdata` as its last argument. */
|
|
203
|
+
state.n_ops = #{n};
|
|
204
|
+
state.fsync = fsync;
|
|
205
|
+
state.cx = cx;
|
|
206
|
+
state.base = base;
|
|
207
|
+
state.stride = stride;
|
|
208
|
+
state.owned_buf = owned_buf;
|
|
209
|
+
state.attached = attached;
|
|
210
|
+
state.no_mask = 0;
|
|
211
|
+
state.src_label = "ca_call_cfunc_#{n}_r";
|
|
212
|
+
|
|
213
|
+
ca_sweep_acquire(&state);
|
|
214
|
+
|
|
215
|
+
{
|
|
216
|
+
char *p[#{n}];
|
|
217
|
+
ca_size_t k;
|
|
218
|
+
if ( state.m0 ) {
|
|
219
|
+
for ( k = 0; k < state.n_kernel; k++ ) {
|
|
220
|
+
if ( ! state.m0[k] ) {
|
|
221
|
+
for ( k_op = 0; k_op < #{n}; k_op++ ) {
|
|
222
|
+
p[k_op] = base[k_op] + k * stride[k_op];
|
|
223
|
+
}
|
|
224
|
+
func(#{args_p_r(n)});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
for ( k = 0; k < state.n_kernel; k++ ) {
|
|
229
|
+
for ( k_op = 0; k_op < #{n}; k_op++ ) {
|
|
230
|
+
p[k_op] = base[k_op] + k * stride[k_op];
|
|
231
|
+
}
|
|
232
|
+
func(#{args_p_r(n)});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
ca_sweep_release(&state);
|
|
238
|
+
|
|
239
|
+
return rcx0;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
END_C
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# --- typed ca_call_cfunc_M_N ------------------------------------------------
|
|
246
|
+
|
|
247
|
+
def emit_typed(m, n)
|
|
248
|
+
total = m + n
|
|
249
|
+
# Naming convention (matches legacy ext/carray_call_cfunc.c byte-for-byte):
|
|
250
|
+
# M==1 : output data_type = `dty`, output var = `ry`
|
|
251
|
+
# M >1 : output data_types = `dty1..dtyM`, output vars = `ry1..ryM`
|
|
252
|
+
dty = ->(k) { m == 1 ? "dty" : "dty#{k + 1}" }
|
|
253
|
+
ry = ->(k) { m == 1 ? "ry" : "ry#{k + 1}" }
|
|
254
|
+
|
|
255
|
+
fsync_str = "1" * m + "0" * n
|
|
256
|
+
|
|
257
|
+
$src.puts sig_typed(m, n)
|
|
258
|
+
$src.puts "{"
|
|
259
|
+
|
|
260
|
+
# output VALUE declarations
|
|
261
|
+
out_decl = (0...m).map { |k| "#{ry.(k)} = Qnil" }.join(", ")
|
|
262
|
+
$src.puts " volatile VALUE #{out_decl};"
|
|
263
|
+
$src.puts ""
|
|
264
|
+
|
|
265
|
+
# wrap inputs readonly to declared input data_types
|
|
266
|
+
(0...n).each do |k|
|
|
267
|
+
$src.puts " rx#{k + 1} = rb_ca_wrap_readonly(rx#{k + 1}, INT2NUM(dtx#{k + 1}));"
|
|
268
|
+
end
|
|
269
|
+
$src.puts ""
|
|
270
|
+
|
|
271
|
+
# build one output template per output data_type, widening inputs as needed
|
|
272
|
+
(0...m).each do |out_k|
|
|
273
|
+
cur_dty = dty.(out_k)
|
|
274
|
+
conds = (0...n).map { |in_k| "#{cur_dty} != dtx#{in_k + 1}" }
|
|
275
|
+
wrapped = (0...n).map { |in_k|
|
|
276
|
+
"rb_ca_wrap_readonly(rx#{in_k + 1}, INT2NUM(#{cur_dty}))"
|
|
277
|
+
}
|
|
278
|
+
plain = (0...n).map { |in_k| "rx#{in_k + 1}" }
|
|
279
|
+
$src.puts " if ( #{conds.join(" || ")} ) {"
|
|
280
|
+
$src.puts " #{ry.(out_k)} = rb_ca_template_n(#{n}, #{wrapped.join(", ")});"
|
|
281
|
+
$src.puts " } else {"
|
|
282
|
+
$src.puts " #{ry.(out_k)} = rb_ca_template_n(#{n}, #{plain.join(", ")});"
|
|
283
|
+
$src.puts " }"
|
|
284
|
+
end
|
|
285
|
+
$src.puts ""
|
|
286
|
+
|
|
287
|
+
# delegate to lower-level ca_call_cfunc_(m+n)
|
|
288
|
+
args = (0...m).map { |k| ry.(k) } + (0...n).map { |k| "rx#{k + 1}" }
|
|
289
|
+
$src.puts " ca_call_cfunc_#{total}(mathfunc, \"#{fsync_str}\", #{args.join(", ")});"
|
|
290
|
+
$src.puts ""
|
|
291
|
+
|
|
292
|
+
# return: scalar-fetch each output if rank-0, then assemble
|
|
293
|
+
(0...m).each do |k|
|
|
294
|
+
$src.puts " if ( rb_ca_is_scalar(#{ry.(k)}) ) {"
|
|
295
|
+
$src.puts " #{ry.(k)} = rb_ca_fetch_addr(#{ry.(k)}, 0);"
|
|
296
|
+
$src.puts " }"
|
|
297
|
+
end
|
|
298
|
+
if m == 1
|
|
299
|
+
$src.puts " return #{ry.(0)};"
|
|
300
|
+
else
|
|
301
|
+
list = (0...m).map { |k| ry.(k) }.join(", ")
|
|
302
|
+
$src.puts " return rb_ary_new3(#{m}, #{list});"
|
|
303
|
+
end
|
|
304
|
+
$src.puts "}"
|
|
305
|
+
$src.puts ""
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
# --- typed ca_call_cfunc_M_N_r (reentrant variant) -------------------------
|
|
309
|
+
#
|
|
310
|
+
# Same as emit_typed but the callback signature and outer function gain a
|
|
311
|
+
# trailing `void *userdata`; the inner delegate calls ca_call_cfunc_(M+N)_r
|
|
312
|
+
# and forwards `userdata` through.
|
|
313
|
+
def emit_typed_r(m, n)
|
|
314
|
+
total = m + n
|
|
315
|
+
dty = ->(k) { m == 1 ? "dty" : "dty#{k + 1}" }
|
|
316
|
+
ry = ->(k) { m == 1 ? "ry" : "ry#{k + 1}" }
|
|
317
|
+
|
|
318
|
+
fsync_str = "1" * m + "0" * n
|
|
319
|
+
|
|
320
|
+
$src.puts sig_typed_r(m, n)
|
|
321
|
+
$src.puts "{"
|
|
322
|
+
|
|
323
|
+
out_decl = (0...m).map { |k| "#{ry.(k)} = Qnil" }.join(", ")
|
|
324
|
+
$src.puts " volatile VALUE #{out_decl};"
|
|
325
|
+
$src.puts ""
|
|
326
|
+
|
|
327
|
+
(0...n).each do |k|
|
|
328
|
+
$src.puts " rx#{k + 1} = rb_ca_wrap_readonly(rx#{k + 1}, INT2NUM(dtx#{k + 1}));"
|
|
329
|
+
end
|
|
330
|
+
$src.puts ""
|
|
331
|
+
|
|
332
|
+
(0...m).each do |out_k|
|
|
333
|
+
cur_dty = dty.(out_k)
|
|
334
|
+
conds = (0...n).map { |in_k| "#{cur_dty} != dtx#{in_k + 1}" }
|
|
335
|
+
wrapped = (0...n).map { |in_k|
|
|
336
|
+
"rb_ca_wrap_readonly(rx#{in_k + 1}, INT2NUM(#{cur_dty}))"
|
|
337
|
+
}
|
|
338
|
+
plain = (0...n).map { |in_k| "rx#{in_k + 1}" }
|
|
339
|
+
$src.puts " if ( #{conds.join(" || ")} ) {"
|
|
340
|
+
$src.puts " #{ry.(out_k)} = rb_ca_template_n(#{n}, #{wrapped.join(", ")});"
|
|
341
|
+
$src.puts " } else {"
|
|
342
|
+
$src.puts " #{ry.(out_k)} = rb_ca_template_n(#{n}, #{plain.join(", ")});"
|
|
343
|
+
$src.puts " }"
|
|
344
|
+
end
|
|
345
|
+
$src.puts ""
|
|
346
|
+
|
|
347
|
+
args = (0...m).map { |k| ry.(k) } + (0...n).map { |k| "rx#{k + 1}" }
|
|
348
|
+
$src.puts " ca_call_cfunc_#{total}_r(mathfunc, \"#{fsync_str}\", #{args.join(", ")}, userdata);"
|
|
349
|
+
$src.puts ""
|
|
350
|
+
|
|
351
|
+
(0...m).each do |k|
|
|
352
|
+
$src.puts " if ( rb_ca_is_scalar(#{ry.(k)}) ) {"
|
|
353
|
+
$src.puts " #{ry.(k)} = rb_ca_fetch_addr(#{ry.(k)}, 0);"
|
|
354
|
+
$src.puts " }"
|
|
355
|
+
end
|
|
356
|
+
if m == 1
|
|
357
|
+
$src.puts " return #{ry.(0)};"
|
|
358
|
+
else
|
|
359
|
+
list = (0...m).map { |k| ry.(k) }.join(", ")
|
|
360
|
+
$src.puts " return rb_ary_new3(#{m}, #{list});"
|
|
361
|
+
end
|
|
362
|
+
$src.puts "}"
|
|
363
|
+
$src.puts ""
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# --- header declaration emitters --------------------------------------------
|
|
367
|
+
|
|
368
|
+
def decl_raw(n) ; $hdr.puts sig_raw(n) + ";"; $hdr.puts ""; end
|
|
369
|
+
def decl_raw_r(n) ; $hdr.puts sig_raw_r(n) + ";"; $hdr.puts ""; end
|
|
370
|
+
def decl_typed(m, n) ; $hdr.puts sig_typed(m, n) + ";"; $hdr.puts ""; end
|
|
371
|
+
def decl_typed_r(m, n) ; $hdr.puts sig_typed_r(m, n) + ";"; $hdr.puts ""; end
|
|
372
|
+
|
|
373
|
+
# --- main -------------------------------------------------------------------
|
|
374
|
+
|
|
375
|
+
src_path = ARGV[0] || "carray_call_cfunc.c"
|
|
376
|
+
hdr_path = ARGV[1] || "carray_call_cfunc.h"
|
|
377
|
+
|
|
378
|
+
$src = File.open(src_path, "w")
|
|
379
|
+
$hdr = File.open(hdr_path, "w")
|
|
380
|
+
|
|
381
|
+
$src.puts <<~END_C
|
|
382
|
+
/* ---------------------------------------------------------------------------
|
|
383
|
+
*
|
|
384
|
+
* carray_call_cfunc.c -- ext-author math-call wrapper API
|
|
385
|
+
*
|
|
386
|
+
* GENERATED by ext/mk_call_cfunc.rb -- DO NOT EDIT
|
|
387
|
+
* To modify the template or add a new arity, edit mk_call_cfunc.rb
|
|
388
|
+
* and regenerate (= make / extconf re-runs the generator).
|
|
389
|
+
*
|
|
390
|
+
* Provides `ca_call_cfunc_N` (raw arity 1..7) and `ca_call_cfunc_M_N`
|
|
391
|
+
* (typed dispatcher) used by external CArray gems (carray-gsl, etc.)
|
|
392
|
+
* to wrap C math functions over CArray operations.
|
|
393
|
+
*
|
|
394
|
+
* Reentrant variants `ca_call_cfunc_N_r` and `ca_call_cfunc_M_N_r`
|
|
395
|
+
* (= POSIX `_r` convention, cf. qsort_r / bsearch_r / strtok_r) take
|
|
396
|
+
* a trailing `void *userdata` argument that is passed through to every
|
|
397
|
+
* per-cell callback invocation as its last argument. Use when the
|
|
398
|
+
* callback needs to share state with the caller (accumulators,
|
|
399
|
+
* configuration flags, library plan handles, ...) without resorting to
|
|
400
|
+
* file-static / global plumbing.
|
|
401
|
+
*
|
|
402
|
+
* Attach-safe: INPUT-only operands (= fsync[k] == '0') never call
|
|
403
|
+
* ca_attach on the operand or its mask (= alias check + ALLOCV +
|
|
404
|
+
* ca_xfer_all for non-alias). OUTPUT operands (= fsync[k] == '1')
|
|
405
|
+
* use ca_attach + ca_sync (= legitimate per the refined input-only-
|
|
406
|
+
* operand invariant established in PROPOSAL_EAGER_ELEMENTWISE_NO_ATTACH
|
|
407
|
+
* and extended in PROPOSAL_EAGER_SLOWPATH_CHUNKING_ARENA).
|
|
408
|
+
*
|
|
409
|
+
* L0.1 (PROPOSAL_L0_AUTHOR_SURFACE, 2026-06-11): the per-operand acquire
|
|
410
|
+
* + broadcast check + mask OR + release lifecycle is now factored out
|
|
411
|
+
* into ext/ca_sweep_engine.{c,h} (ca_sweep_acquire / ca_sweep_release). This
|
|
412
|
+
* file keeps the arity-dependent inner loop only. ABI unchanged.
|
|
413
|
+
*
|
|
414
|
+
* --------------------------------------------------------------------------- */
|
|
415
|
+
|
|
416
|
+
#include "carray.h"
|
|
417
|
+
#include "ca_sweep_engine.h"
|
|
418
|
+
#include <string.h>
|
|
419
|
+
|
|
420
|
+
END_C
|
|
421
|
+
|
|
422
|
+
$hdr.puts <<~END_H
|
|
423
|
+
/* ---------------------------------------------------------------------------
|
|
424
|
+
*
|
|
425
|
+
* carray_call_cfunc.h -- ext-author math-call wrapper API (declarations)
|
|
426
|
+
*
|
|
427
|
+
* GENERATED by ext/mk_call_cfunc.rb -- DO NOT EDIT
|
|
428
|
+
* Edit mk_call_cfunc.rb and rebuild to refresh both this header and
|
|
429
|
+
* the matching carray_call_cfunc.c.
|
|
430
|
+
*
|
|
431
|
+
* Included from carray.h so external gems pick up these prototypes
|
|
432
|
+
* transparently via `#include "carray.h"`. The generator co-emits
|
|
433
|
+
* source and header so the prototypes cannot drift from the function
|
|
434
|
+
* definitions. See carray_call_cfunc.c for the full design notes.
|
|
435
|
+
*
|
|
436
|
+
* --------------------------------------------------------------------------- */
|
|
437
|
+
|
|
438
|
+
#ifndef CARRAY_CALL_CFUNC_H
|
|
439
|
+
#define CARRAY_CALL_CFUNC_H
|
|
440
|
+
|
|
441
|
+
END_H
|
|
442
|
+
|
|
443
|
+
RAW_ARITIES.each do |n|
|
|
444
|
+
emit_raw(n)
|
|
445
|
+
decl_raw(n)
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
$src.puts "/* -------------------------------------------------------------------- */"
|
|
449
|
+
$src.puts "/* Typed dispatchers: M outputs, N inputs. Wrap each input readonly to */"
|
|
450
|
+
$src.puts "/* its declared data_type, allocate output template(s), delegate to raw. */"
|
|
451
|
+
$src.puts "/* -------------------------------------------------------------------- */"
|
|
452
|
+
$src.puts ""
|
|
453
|
+
|
|
454
|
+
TYPED_PAIRS.each do |m, n|
|
|
455
|
+
emit_typed(m, n)
|
|
456
|
+
decl_typed(m, n)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
$src.puts "/* -------------------------------------------------------------------- */"
|
|
460
|
+
$src.puts "/* Reentrant variants (`_r` suffix, POSIX convention): same as the */"
|
|
461
|
+
$src.puts "/* corresponding non-`_r` variant but the callback takes a trailing */"
|
|
462
|
+
$src.puts "/* `void *userdata` argument and the outer function takes a trailing */"
|
|
463
|
+
$src.puts "/* `void *userdata` parameter forwarded to every per-cell invocation. */"
|
|
464
|
+
$src.puts "/* -------------------------------------------------------------------- */"
|
|
465
|
+
$src.puts ""
|
|
466
|
+
|
|
467
|
+
RAW_ARITIES.each do |n|
|
|
468
|
+
emit_raw_r(n)
|
|
469
|
+
decl_raw_r(n)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
TYPED_PAIRS.each do |m, n|
|
|
473
|
+
emit_typed_r(m, n)
|
|
474
|
+
decl_typed_r(m, n)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
$hdr.puts "#endif /* CARRAY_CALL_CFUNC_H */"
|
|
478
|
+
|
|
479
|
+
$src.close
|
|
480
|
+
$hdr.close
|