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,132 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
ca_sort_kernels.h
|
|
4
|
+
|
|
5
|
+
Portable textbook sort kernels (PROPOSAL_PORTABLE_TEXTBOOK_SORT).
|
|
6
|
+
|
|
7
|
+
P.1 / P.2 : quicksort + mergesort over the 10 numeric dtypes
|
|
8
|
+
(i8 / u8 / i16 / u16 / i32 / u32 / i64 / u64 / f32 / f64)
|
|
9
|
+
P.3 : NaN pre-partition for f32 / f64
|
|
10
|
+
P.4 : pair (value + index) variants for argsort kernels —
|
|
11
|
+
sort_index / sort_addr / partition_index family
|
|
12
|
+
P.9 : value-level quickselect for partition_copy
|
|
13
|
+
|
|
14
|
+
Status: ext-internal. Signatures may change across 3.x while the
|
|
15
|
+
textbook sort family evolves. Included from carray.h so internal
|
|
16
|
+
consumers (carray_sort_kernel.c, carray_order.c, carray_kernels.c,
|
|
17
|
+
mkkernel emit) reach it transparently via `#include "carray.h"`.
|
|
18
|
+
|
|
19
|
+
Depends on int8_t .. uint64_t / float32_t / double / ca_size_t
|
|
20
|
+
typedefs from carray.h — when this header is included from carray.h
|
|
21
|
+
mid-file, those typedefs are already in scope by the time we reach
|
|
22
|
+
the include site.
|
|
23
|
+
|
|
24
|
+
--------------------------------------------------------------------------- */
|
|
25
|
+
|
|
26
|
+
#ifndef CA_SORT_KERNELS_H
|
|
27
|
+
#define CA_SORT_KERNELS_H 1
|
|
28
|
+
|
|
29
|
+
/* Needs int8_t .. uint64_t / float32_t / double / ca_size_t. No longer
|
|
30
|
+
pulled mid-carray.h (PROPOSAL_CARRAY_H_REORG H.4.1), so include carray.h
|
|
31
|
+
directly to be self-sufficient when a consumer includes this header.
|
|
32
|
+
Guard-protected, so the re-entry is a no-op when carray.h is already in
|
|
33
|
+
flight. */
|
|
34
|
+
#include "carray.h"
|
|
35
|
+
|
|
36
|
+
/* P.1 / P.2: quicksort over 10 numeric dtypes. */
|
|
37
|
+
void ca_sort_quick_i8 (int8_t *a, ca_size_t n);
|
|
38
|
+
void ca_sort_quick_u8 (uint8_t *a, ca_size_t n);
|
|
39
|
+
void ca_sort_quick_i16 (int16_t *a, ca_size_t n);
|
|
40
|
+
void ca_sort_quick_u16 (uint16_t *a, ca_size_t n);
|
|
41
|
+
void ca_sort_quick_i32 (int32_t *a, ca_size_t n);
|
|
42
|
+
void ca_sort_quick_u32 (uint32_t *a, ca_size_t n);
|
|
43
|
+
void ca_sort_quick_i64 (int64_t *a, ca_size_t n);
|
|
44
|
+
void ca_sort_quick_u64 (uint64_t *a, ca_size_t n);
|
|
45
|
+
void ca_sort_quick_f32 (float32_t *a, ca_size_t n);
|
|
46
|
+
void ca_sort_quick_f64 (double *a, ca_size_t n);
|
|
47
|
+
|
|
48
|
+
/* P.1 / P.2: mergesort over 10 numeric dtypes (`aux` is caller-supplied
|
|
49
|
+
scratch buffer of the same length / dtype as `a`). */
|
|
50
|
+
void ca_sort_merge_i8 (int8_t *a, int8_t *aux, ca_size_t n);
|
|
51
|
+
void ca_sort_merge_u8 (uint8_t *a, uint8_t *aux, ca_size_t n);
|
|
52
|
+
void ca_sort_merge_i16 (int16_t *a, int16_t *aux, ca_size_t n);
|
|
53
|
+
void ca_sort_merge_u16 (uint16_t *a, uint16_t *aux, ca_size_t n);
|
|
54
|
+
void ca_sort_merge_i32 (int32_t *a, int32_t *aux, ca_size_t n);
|
|
55
|
+
void ca_sort_merge_u32 (uint32_t *a, uint32_t *aux, ca_size_t n);
|
|
56
|
+
void ca_sort_merge_i64 (int64_t *a, int64_t *aux, ca_size_t n);
|
|
57
|
+
void ca_sort_merge_u64 (uint64_t *a, uint64_t *aux, ca_size_t n);
|
|
58
|
+
void ca_sort_merge_f32 (float32_t *a, float32_t *aux, ca_size_t n);
|
|
59
|
+
void ca_sort_merge_f64 (double *a, double *aux, ca_size_t n);
|
|
60
|
+
|
|
61
|
+
/* P.3: NaN pre-partition for float dtypes (Hoare 1-pass, returns finite count). */
|
|
62
|
+
ca_size_t ca_partition_nan_f32 (float32_t *a, ca_size_t n);
|
|
63
|
+
ca_size_t ca_partition_nan_f64 (double *a, ca_size_t n);
|
|
64
|
+
|
|
65
|
+
/* P.4: pair variant of NaN pre-partition for float argsort kernels. */
|
|
66
|
+
struct ca_pair_f32;
|
|
67
|
+
struct ca_pair_f64;
|
|
68
|
+
ca_size_t ca_partition_nan_pair_f32 (struct ca_pair_f32 *a, ca_size_t n);
|
|
69
|
+
ca_size_t ca_partition_nan_pair_f64 (struct ca_pair_f64 *a, ca_size_t n);
|
|
70
|
+
|
|
71
|
+
/* P.9: value-level quickselect for partition_copy.
|
|
72
|
+
Reorders a[0..n) so that a[kth] is exact + left/right regions
|
|
73
|
+
satisfy <= / >= contracts. Order within each region unspecified. */
|
|
74
|
+
void ca_partition_quick_i8 (int8_t *a, ca_size_t n, ca_size_t kth);
|
|
75
|
+
void ca_partition_quick_u8 (uint8_t *a, ca_size_t n, ca_size_t kth);
|
|
76
|
+
void ca_partition_quick_i16 (int16_t *a, ca_size_t n, ca_size_t kth);
|
|
77
|
+
void ca_partition_quick_u16 (uint16_t *a, ca_size_t n, ca_size_t kth);
|
|
78
|
+
void ca_partition_quick_i32 (int32_t *a, ca_size_t n, ca_size_t kth);
|
|
79
|
+
void ca_partition_quick_u32 (uint32_t *a, ca_size_t n, ca_size_t kth);
|
|
80
|
+
void ca_partition_quick_i64 (int64_t *a, ca_size_t n, ca_size_t kth);
|
|
81
|
+
void ca_partition_quick_u64 (uint64_t *a, ca_size_t n, ca_size_t kth);
|
|
82
|
+
void ca_partition_quick_f32 (float32_t *a, ca_size_t n, ca_size_t kth);
|
|
83
|
+
void ca_partition_quick_f64 (double *a, ca_size_t n, ca_size_t kth);
|
|
84
|
+
|
|
85
|
+
/* P.4: pair sort kernels (= argsort: sort_index / sort_addr). The pair
|
|
86
|
+
struct is opaque to mkkernel-emitted callers via void*; each kernel
|
|
87
|
+
has its own well-defined layout: { TYPE v; ca_size_t i; } with natural
|
|
88
|
+
alignment padding. */
|
|
89
|
+
struct ca_pair_i8 { int8_t v; ca_size_t i; };
|
|
90
|
+
struct ca_pair_u8 { uint8_t v; ca_size_t i; };
|
|
91
|
+
struct ca_pair_i16 { int16_t v; ca_size_t i; };
|
|
92
|
+
struct ca_pair_u16 { uint16_t v; ca_size_t i; };
|
|
93
|
+
struct ca_pair_i32 { int32_t v; ca_size_t i; };
|
|
94
|
+
struct ca_pair_u32 { uint32_t v; ca_size_t i; };
|
|
95
|
+
struct ca_pair_i64 { int64_t v; ca_size_t i; };
|
|
96
|
+
struct ca_pair_u64 { uint64_t v; ca_size_t i; };
|
|
97
|
+
struct ca_pair_f32 { float32_t v; ca_size_t i; };
|
|
98
|
+
struct ca_pair_f64 { double v; ca_size_t i; };
|
|
99
|
+
typedef struct ca_pair_i8 ca_pair_i8;
|
|
100
|
+
typedef struct ca_pair_u8 ca_pair_u8;
|
|
101
|
+
typedef struct ca_pair_i16 ca_pair_i16;
|
|
102
|
+
typedef struct ca_pair_u16 ca_pair_u16;
|
|
103
|
+
typedef struct ca_pair_i32 ca_pair_i32;
|
|
104
|
+
typedef struct ca_pair_u32 ca_pair_u32;
|
|
105
|
+
typedef struct ca_pair_i64 ca_pair_i64;
|
|
106
|
+
typedef struct ca_pair_u64 ca_pair_u64;
|
|
107
|
+
typedef struct ca_pair_f32 ca_pair_f32;
|
|
108
|
+
typedef struct ca_pair_f64 ca_pair_f64;
|
|
109
|
+
|
|
110
|
+
void ca_sort_quick_pair_i8 (ca_pair_i8 *a, ca_size_t n);
|
|
111
|
+
void ca_sort_quick_pair_u8 (ca_pair_u8 *a, ca_size_t n);
|
|
112
|
+
void ca_sort_quick_pair_i16 (ca_pair_i16 *a, ca_size_t n);
|
|
113
|
+
void ca_sort_quick_pair_u16 (ca_pair_u16 *a, ca_size_t n);
|
|
114
|
+
void ca_sort_quick_pair_i32 (ca_pair_i32 *a, ca_size_t n);
|
|
115
|
+
void ca_sort_quick_pair_u32 (ca_pair_u32 *a, ca_size_t n);
|
|
116
|
+
void ca_sort_quick_pair_i64 (ca_pair_i64 *a, ca_size_t n);
|
|
117
|
+
void ca_sort_quick_pair_u64 (ca_pair_u64 *a, ca_size_t n);
|
|
118
|
+
void ca_sort_quick_pair_f32 (ca_pair_f32 *a, ca_size_t n);
|
|
119
|
+
void ca_sort_quick_pair_f64 (ca_pair_f64 *a, ca_size_t n);
|
|
120
|
+
|
|
121
|
+
void ca_sort_merge_pair_i8 (ca_pair_i8 *a, ca_pair_i8 *aux, ca_size_t n);
|
|
122
|
+
void ca_sort_merge_pair_u8 (ca_pair_u8 *a, ca_pair_u8 *aux, ca_size_t n);
|
|
123
|
+
void ca_sort_merge_pair_i16 (ca_pair_i16 *a, ca_pair_i16 *aux, ca_size_t n);
|
|
124
|
+
void ca_sort_merge_pair_u16 (ca_pair_u16 *a, ca_pair_u16 *aux, ca_size_t n);
|
|
125
|
+
void ca_sort_merge_pair_i32 (ca_pair_i32 *a, ca_pair_i32 *aux, ca_size_t n);
|
|
126
|
+
void ca_sort_merge_pair_u32 (ca_pair_u32 *a, ca_pair_u32 *aux, ca_size_t n);
|
|
127
|
+
void ca_sort_merge_pair_i64 (ca_pair_i64 *a, ca_pair_i64 *aux, ca_size_t n);
|
|
128
|
+
void ca_sort_merge_pair_u64 (ca_pair_u64 *a, ca_pair_u64 *aux, ca_size_t n);
|
|
129
|
+
void ca_sort_merge_pair_f32 (ca_pair_f32 *a, ca_pair_f32 *aux, ca_size_t n);
|
|
130
|
+
void ca_sort_merge_pair_f64 (ca_pair_f64 *a, ca_pair_f64 *aux, ca_size_t n);
|
|
131
|
+
|
|
132
|
+
#endif /* CA_SORT_KERNELS_H */
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
Sweep (xfer_all) author-surface engine: shared acquire / release
|
|
4
|
+
bodies for the ca_call_cfunc trampolines generated by
|
|
5
|
+
mk_call_cfunc.rb. See ca_sweep_engine.h for the full lifecycle
|
|
6
|
+
template.
|
|
7
|
+
|
|
8
|
+
Two paths:
|
|
9
|
+
whole-buffer ca_sweep_acquire / _release — xmalloc scratch
|
|
10
|
+
chunked ca_sweep_acquire_chunked / _next_chunk / _release_chunked
|
|
11
|
+
— arena scratch
|
|
12
|
+
|
|
13
|
+
Both propagate INPUT masks to OUTPUT masks and honor the NO_MASK
|
|
14
|
+
form guard (masked INPUT + NO_MASK = raise, since a NO_MASK kernel
|
|
15
|
+
cannot observe masked cells).
|
|
16
|
+
|
|
17
|
+
---------------------------------------------------------------------------- */
|
|
18
|
+
|
|
19
|
+
#include "carray.h"
|
|
20
|
+
#include "carray_internal.h" /* ca_lazy_arena_* */
|
|
21
|
+
#include "ca_sweep_engine.h"
|
|
22
|
+
#include "ca_for_buffer.h"
|
|
23
|
+
#include <string.h>
|
|
24
|
+
|
|
25
|
+
void
|
|
26
|
+
ca_sweep_acquire (ca_sweep_state_t *st)
|
|
27
|
+
{
|
|
28
|
+
int k_op;
|
|
29
|
+
int any_input_mask = 0;
|
|
30
|
+
|
|
31
|
+
if ((int) strlen(st->fsync) != st->n_ops) {
|
|
32
|
+
rb_raise(rb_eRuntimeError,
|
|
33
|
+
"[BUG] invalid length of fsync arg in %s (expected %d)",
|
|
34
|
+
st->src_label ? st->src_label : "ca_sweep_acquire",
|
|
35
|
+
st->n_ops);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
39
|
+
st->base[k_op] = NULL;
|
|
40
|
+
st->owned_buf[k_op] = NULL;
|
|
41
|
+
st->attached[k_op] = 0;
|
|
42
|
+
}
|
|
43
|
+
st->m0 = NULL;
|
|
44
|
+
st->n_kernel = 1;
|
|
45
|
+
/* CAREFUL: do not reset st->no_mask here — caller sets it before
|
|
46
|
+
* acquire and the NO_MASK guard below consumes it. */
|
|
47
|
+
|
|
48
|
+
/* Per-operand acquire:
|
|
49
|
+
* OUTPUT (fsync == '1') -> ca_attach + base = ca->ptr
|
|
50
|
+
* INPUT alias -> ca_attach + base = ca->ptr
|
|
51
|
+
* INPUT non-alias non-scalar -> xmalloc scratch + ca_xfer_all
|
|
52
|
+
* INPUT non-alias never attaches the operand itself; the scratch
|
|
53
|
+
* copy carries the values into the kernel. */
|
|
54
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
55
|
+
CArray *ca = st->cx[k_op];
|
|
56
|
+
if (st->fsync[k_op] == '1') {
|
|
57
|
+
ca_attach(ca);
|
|
58
|
+
st->base[k_op] = (char *) ca->ptr;
|
|
59
|
+
st->attached[k_op] = 1;
|
|
60
|
+
} else if (ca_attach_is_alias(ca)) {
|
|
61
|
+
ca_attach(ca);
|
|
62
|
+
st->base[k_op] = (char *) ca->ptr;
|
|
63
|
+
st->attached[k_op] = 1;
|
|
64
|
+
} else {
|
|
65
|
+
ca_size_t bytes_total = ca->elements * ca->bytes;
|
|
66
|
+
st->owned_buf[k_op] = xmalloc(bytes_total);
|
|
67
|
+
st->base[k_op] = st->owned_buf[k_op];
|
|
68
|
+
ca_xfer_all(ca, st->base[k_op], CA_XFER_GET);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/* compute n_kernel (= broadcast shape) and per-cell strides */
|
|
73
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
74
|
+
CArray *ca = st->cx[k_op];
|
|
75
|
+
if (ca_is_scalar(ca)) {
|
|
76
|
+
st->stride[k_op] = 0;
|
|
77
|
+
} else {
|
|
78
|
+
st->stride[k_op] = ca->bytes;
|
|
79
|
+
if (st->n_kernel == 1) {
|
|
80
|
+
st->n_kernel = ca->elements;
|
|
81
|
+
} else if (ca->elements != st->n_kernel) {
|
|
82
|
+
rb_raise(rb_eRuntimeError, "data size mismatch in operation");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* iter mask m0 = OR of INPUT operand masks, gathered via ca_xfer_all
|
|
88
|
+
so no operand mask attach happens. Stays NULL if no INPUT masks. */
|
|
89
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
90
|
+
if (st->fsync[k_op] == '0' && ca_has_mask(st->cx[k_op])) {
|
|
91
|
+
any_input_mask = 1;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (any_input_mask && st->no_mask) {
|
|
96
|
+
rb_raise(rb_eRuntimeError,
|
|
97
|
+
"%s: masked INPUT not allowed in NO_MASK form "
|
|
98
|
+
"(use the *_MASKED form to handle masked cells explicitly)",
|
|
99
|
+
st->src_label ? st->src_label : "ca_sweep_acquire");
|
|
100
|
+
}
|
|
101
|
+
if (any_input_mask) {
|
|
102
|
+
st->m0 = xmalloc(st->n_kernel);
|
|
103
|
+
memset(st->m0, 0, st->n_kernel);
|
|
104
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
105
|
+
CArray *ca = st->cx[k_op];
|
|
106
|
+
if (st->fsync[k_op] != '0') continue;
|
|
107
|
+
ca_update_mask(ca);
|
|
108
|
+
if (!ca->mask) continue;
|
|
109
|
+
if (ca_is_scalar(ca)) {
|
|
110
|
+
boolean8_t bit = 0;
|
|
111
|
+
ca_xfer_all(ca->mask, &bit, CA_XFER_GET);
|
|
112
|
+
if (bit) memset(st->m0, 1, st->n_kernel);
|
|
113
|
+
} else {
|
|
114
|
+
boolean8_t *ms = xmalloc(st->n_kernel);
|
|
115
|
+
ca_size_t j;
|
|
116
|
+
ca_xfer_all(ca->mask, ms, CA_XFER_GET);
|
|
117
|
+
for (j = 0; j < st->n_kernel; j++) st->m0[j] |= ms[j];
|
|
118
|
+
xfree(ms);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Overwrite each OUTPUT mask with the iter mask (creating the
|
|
124
|
+
OUTPUT mask if it did not exist). No-op when m0 is NULL. */
|
|
125
|
+
if (st->m0) {
|
|
126
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
127
|
+
CArray *ca = st->cx[k_op];
|
|
128
|
+
if (st->fsync[k_op] != '1') continue;
|
|
129
|
+
ca_update_mask(ca);
|
|
130
|
+
if (!ca->mask) ca_create_mask(ca);
|
|
131
|
+
memcpy(ca->mask->ptr, st->m0, st->n_kernel);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void
|
|
137
|
+
ca_sweep_release (ca_sweep_state_t *st)
|
|
138
|
+
{
|
|
139
|
+
int k_op;
|
|
140
|
+
/* sync OUTPUTs (reverse order) */
|
|
141
|
+
for (k_op = st->n_ops - 1; k_op >= 0; k_op--) {
|
|
142
|
+
if (st->fsync[k_op] == '1') ca_sync(st->cx[k_op]);
|
|
143
|
+
}
|
|
144
|
+
/* detach attached / xfree owned buffers (reverse order) */
|
|
145
|
+
for (k_op = st->n_ops - 1; k_op >= 0; k_op--) {
|
|
146
|
+
if (st->attached[k_op]) {
|
|
147
|
+
ca_detach(st->cx[k_op]);
|
|
148
|
+
} else if (st->owned_buf[k_op]) {
|
|
149
|
+
xfree(st->owned_buf[k_op]);
|
|
150
|
+
st->owned_buf[k_op] = NULL;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (st->m0) {
|
|
154
|
+
xfree(st->m0);
|
|
155
|
+
st->m0 = NULL;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* ===== Chunked path implementation ===== */
|
|
160
|
+
|
|
161
|
+
void
|
|
162
|
+
ca_sweep_acquire_chunked (ca_sweep_state_t *st)
|
|
163
|
+
{
|
|
164
|
+
int k_op;
|
|
165
|
+
int any_input_mask = 0;
|
|
166
|
+
CArray *shape_donor = NULL;
|
|
167
|
+
|
|
168
|
+
if ((int) strlen(st->fsync) != st->n_ops) {
|
|
169
|
+
rb_raise(rb_eRuntimeError,
|
|
170
|
+
"[BUG] invalid length of fsync arg in %s (expected %d)",
|
|
171
|
+
st->src_label ? st->src_label : "ca_sweep_acquire_chunked",
|
|
172
|
+
st->n_ops);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
176
|
+
st->base[k_op] = NULL;
|
|
177
|
+
st->base_orig[k_op] = NULL;
|
|
178
|
+
st->owned_buf[k_op] = NULL;
|
|
179
|
+
st->attached[k_op] = 0;
|
|
180
|
+
}
|
|
181
|
+
st->m0 = NULL;
|
|
182
|
+
st->n_kernel = 1;
|
|
183
|
+
st->chunk_off = 0;
|
|
184
|
+
st->chunk_n = 0;
|
|
185
|
+
st->chunk_n_max = 0;
|
|
186
|
+
st->inner = 1;
|
|
187
|
+
st->chunked_state = 0;
|
|
188
|
+
|
|
189
|
+
/* compute broadcast shape (n_kernel + strides) from operand shapes.
|
|
190
|
+
* scalar operands collapse to stride 0; non-scalar operands must agree
|
|
191
|
+
* on element count. shape_donor is the first non-scalar operand and
|
|
192
|
+
* defines the chunking inner-axis size. */
|
|
193
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
194
|
+
CArray *ca = st->cx[k_op];
|
|
195
|
+
if (ca_is_scalar(ca)) {
|
|
196
|
+
st->stride[k_op] = 0;
|
|
197
|
+
} else {
|
|
198
|
+
st->stride[k_op] = ca->bytes;
|
|
199
|
+
if (st->n_kernel == 1) {
|
|
200
|
+
st->n_kernel = ca->elements;
|
|
201
|
+
shape_donor = ca;
|
|
202
|
+
} else if (ca->elements != st->n_kernel) {
|
|
203
|
+
rb_raise(rb_eRuntimeError, "data size mismatch in operation");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* chunk-size policy: inner = donor's product of dims[1..]; chunk_n_max
|
|
209
|
+
* = compute_n on donor->bytes (= dtype-dependent 32KB target). */
|
|
210
|
+
if (shape_donor) {
|
|
211
|
+
st->inner = ca_chunk_inner_size(shape_donor);
|
|
212
|
+
st->chunk_n_max = ca_chunk_compute_n(st->n_kernel, st->inner,
|
|
213
|
+
shape_donor->bytes);
|
|
214
|
+
} else {
|
|
215
|
+
/* all-scalar: single 1-cell chunk */
|
|
216
|
+
st->inner = 1;
|
|
217
|
+
st->chunk_n_max = 1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* per-operand acquire:
|
|
221
|
+
* OUTPUT (fsync == '1') : ca_attach + base_orig = ca->ptr (legitimate)
|
|
222
|
+
* INPUT alias : ca_attach + base_orig = ca->ptr (zero-copy)
|
|
223
|
+
* INPUT non-alias non-scalar : arena chunk scratch of chunk_n_max bytes
|
|
224
|
+
* INPUT scalar : ca_attach + base_orig = ca->ptr (1 cell)
|
|
225
|
+
*/
|
|
226
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
227
|
+
CArray *ca = st->cx[k_op];
|
|
228
|
+
if (st->fsync[k_op] == '1') {
|
|
229
|
+
ca_attach(ca);
|
|
230
|
+
st->base_orig[k_op] = (char *) ca->ptr;
|
|
231
|
+
st->attached[k_op] = 1;
|
|
232
|
+
} else if (ca_is_scalar(ca) || ca_attach_is_alias(ca)) {
|
|
233
|
+
ca_attach(ca);
|
|
234
|
+
st->base_orig[k_op] = (char *) ca->ptr;
|
|
235
|
+
st->attached[k_op] = 1;
|
|
236
|
+
} else {
|
|
237
|
+
/* non-alias non-scalar INPUT: arena scratch sized for chunk_n_max */
|
|
238
|
+
ca_size_t scratch_bytes = st->chunk_n_max * ca->bytes;
|
|
239
|
+
st->owned_buf[k_op] = (char *) ca_lazy_arena_acquire(scratch_bytes);
|
|
240
|
+
/* base_orig stays NULL -- per-chunk gather lands the data in
|
|
241
|
+
* owned_buf[k_op]; base[k_op] will be set to owned_buf[k_op] at
|
|
242
|
+
* each chunk boundary. */
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/* iter mask = OR of INPUT operand masks (full size, n_kernel bytes).
|
|
247
|
+
* Per-chunk mask gather is a future optim; this MVP gathers once. */
|
|
248
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
249
|
+
if (st->fsync[k_op] == '0' && ca_has_mask(st->cx[k_op])) {
|
|
250
|
+
any_input_mask = 1;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (any_input_mask && st->no_mask) {
|
|
255
|
+
rb_raise(rb_eRuntimeError,
|
|
256
|
+
"%s: masked INPUT not allowed in NO_MASK form "
|
|
257
|
+
"(use the *_MASKED form to handle masked cells explicitly)",
|
|
258
|
+
st->src_label ? st->src_label : "ca_sweep_acquire_chunked");
|
|
259
|
+
}
|
|
260
|
+
if (any_input_mask) {
|
|
261
|
+
st->m0 = (boolean8_t *) ca_lazy_arena_acquire(st->n_kernel);
|
|
262
|
+
memset(st->m0, 0, st->n_kernel);
|
|
263
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
264
|
+
CArray *ca = st->cx[k_op];
|
|
265
|
+
if (st->fsync[k_op] != '0') continue;
|
|
266
|
+
ca_update_mask(ca);
|
|
267
|
+
if (!ca->mask) continue;
|
|
268
|
+
if (ca_is_scalar(ca)) {
|
|
269
|
+
boolean8_t bit = 0;
|
|
270
|
+
ca_xfer_all(ca->mask, &bit, CA_XFER_GET);
|
|
271
|
+
if (bit) memset(st->m0, 1, st->n_kernel);
|
|
272
|
+
} else {
|
|
273
|
+
boolean8_t *ms = (boolean8_t *) ca_lazy_arena_acquire(st->n_kernel);
|
|
274
|
+
ca_size_t j;
|
|
275
|
+
ca_xfer_all(ca->mask, ms, CA_XFER_GET);
|
|
276
|
+
for (j = 0; j < st->n_kernel; j++) st->m0[j] |= ms[j];
|
|
277
|
+
ca_lazy_arena_release(ms);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* CAREFUL: m0 -> OUTPUT mask propagation is deferred to release
|
|
283
|
+
* time so that author per-cell m_out writes during the chunk loop
|
|
284
|
+
* are captured in the final OUTPUT mask. Do not fold this into
|
|
285
|
+
* acquire; doing so would clobber the author's writes. */
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
int
|
|
289
|
+
ca_sweep_next_chunk (ca_sweep_state_t *st)
|
|
290
|
+
{
|
|
291
|
+
int k_op;
|
|
292
|
+
ca_size_t off, n;
|
|
293
|
+
|
|
294
|
+
if (st->chunked_state == 0) {
|
|
295
|
+
/* first chunk */
|
|
296
|
+
st->chunk_off = 0;
|
|
297
|
+
st->chunked_state = 1;
|
|
298
|
+
} else {
|
|
299
|
+
/* advance */
|
|
300
|
+
st->chunk_off += st->chunk_n;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (st->chunk_off >= st->n_kernel) {
|
|
304
|
+
st->chunked_state = 2;
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
off = st->chunk_off;
|
|
309
|
+
n = st->chunk_n_max;
|
|
310
|
+
if (off + n > st->n_kernel) n = st->n_kernel - off;
|
|
311
|
+
st->chunk_n = n;
|
|
312
|
+
|
|
313
|
+
/* set up base[] for the upcoming chunk */
|
|
314
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
315
|
+
CArray *ca = st->cx[k_op];
|
|
316
|
+
if (st->stride[k_op] == 0) {
|
|
317
|
+
/* scalar: stride 0, base is the single-cell ptr (base_orig) */
|
|
318
|
+
st->base[k_op] = st->base_orig[k_op];
|
|
319
|
+
} else if (st->base_orig[k_op]) {
|
|
320
|
+
/* alias INPUT or OUTPUT: walk through ca->ptr by chunk_off */
|
|
321
|
+
st->base[k_op] = st->base_orig[k_op] + off * st->stride[k_op];
|
|
322
|
+
} else {
|
|
323
|
+
/* non-alias INPUT: per-chunk gather into owned_buf (arena) */
|
|
324
|
+
ca_chunked_gather(ca, off, n, st->owned_buf[k_op]);
|
|
325
|
+
st->base[k_op] = st->owned_buf[k_op];
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return 1;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
void
|
|
333
|
+
ca_sweep_release_chunked (ca_sweep_state_t *st)
|
|
334
|
+
{
|
|
335
|
+
int k_op;
|
|
336
|
+
/* Propagate (possibly author-mutated) m0 to OUTPUT mask before
|
|
337
|
+
* sync. For INOUT_MASKED forms this captures the author's per-cell
|
|
338
|
+
* m_out writes; other forms behave the same as the whole-buffer
|
|
339
|
+
* acquire-time propagation. */
|
|
340
|
+
if (st->m0) {
|
|
341
|
+
for (k_op = 0; k_op < st->n_ops; k_op++) {
|
|
342
|
+
CArray *ca = st->cx[k_op];
|
|
343
|
+
if (st->fsync[k_op] != '1') continue;
|
|
344
|
+
ca_update_mask(ca);
|
|
345
|
+
if (!ca->mask) ca_create_mask(ca);
|
|
346
|
+
memcpy(ca->mask->ptr, st->m0, st->n_kernel);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/* sync OUTPUTs (reverse order, regardless of whether chunk loop ran) */
|
|
350
|
+
for (k_op = st->n_ops - 1; k_op >= 0; k_op--) {
|
|
351
|
+
if (st->fsync[k_op] == '1') ca_sync(st->cx[k_op]);
|
|
352
|
+
}
|
|
353
|
+
/* detach attached / release arena scratch buffers (reverse order) */
|
|
354
|
+
for (k_op = st->n_ops - 1; k_op >= 0; k_op--) {
|
|
355
|
+
if (st->attached[k_op]) {
|
|
356
|
+
ca_detach(st->cx[k_op]);
|
|
357
|
+
} else if (st->owned_buf[k_op]) {
|
|
358
|
+
ca_lazy_arena_release(st->owned_buf[k_op]);
|
|
359
|
+
st->owned_buf[k_op] = NULL;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
if (st->m0) {
|
|
363
|
+
ca_lazy_arena_release(st->m0);
|
|
364
|
+
st->m0 = NULL;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/* ===== WHOLE_BUFFER function form (rb_ensure-protected) ===== */
|
|
369
|
+
|
|
370
|
+
typedef struct {
|
|
371
|
+
CArray *ca;
|
|
372
|
+
int writable;
|
|
373
|
+
ca_with_buffer_body_fn body_fn;
|
|
374
|
+
void *user_data;
|
|
375
|
+
} ca_with_buffer_ctx_t;
|
|
376
|
+
|
|
377
|
+
static VALUE
|
|
378
|
+
ca_with_buffer_body_trampoline (VALUE ctx_val)
|
|
379
|
+
{
|
|
380
|
+
ca_with_buffer_ctx_t *ctx = (ca_with_buffer_ctx_t *) ctx_val;
|
|
381
|
+
ctx->body_fn(ctx->user_data, ctx->ca->ptr, ctx->ca->elements);
|
|
382
|
+
return Qnil;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
static VALUE
|
|
386
|
+
ca_with_buffer_ensure_trampoline (VALUE ctx_val)
|
|
387
|
+
{
|
|
388
|
+
ca_with_buffer_ctx_t *ctx = (ca_with_buffer_ctx_t *) ctx_val;
|
|
389
|
+
if (ctx->writable) ca_sync(ctx->ca);
|
|
390
|
+
ca_detach(ctx->ca);
|
|
391
|
+
return Qnil;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
void
|
|
395
|
+
rb_ca_call_with_buffer (VALUE r_ca, int writable,
|
|
396
|
+
ca_with_buffer_body_fn body, void *user_data)
|
|
397
|
+
{
|
|
398
|
+
ca_with_buffer_ctx_t ctx;
|
|
399
|
+
TypedData_Get_Struct(r_ca, CArray, &carray_data_type, ctx.ca);
|
|
400
|
+
/* CAREFUL: attach outside rb_ensure. If attach raises, we are not
|
|
401
|
+
* yet inside the ensure scope, so the ensure trampoline will not
|
|
402
|
+
* fire on a not-attached ca (which would try to detach and crash). */
|
|
403
|
+
ca_attach(ctx.ca);
|
|
404
|
+
ctx.writable = writable;
|
|
405
|
+
ctx.body_fn = body;
|
|
406
|
+
ctx.user_data = user_data;
|
|
407
|
+
rb_ensure(ca_with_buffer_body_trampoline, (VALUE) &ctx,
|
|
408
|
+
ca_with_buffer_ensure_trampoline, (VALUE) &ctx);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
void
|
|
412
|
+
ca_sweep_check_same_shape (CArray *ca_in, CArray *ca_out, const char *src_label)
|
|
413
|
+
{
|
|
414
|
+
int k;
|
|
415
|
+
const char *lbl = src_label ? src_label : "ca_sweep_check_same_shape";
|
|
416
|
+
if (ca_in->ndim != ca_out->ndim) {
|
|
417
|
+
rb_raise(rb_eRuntimeError,
|
|
418
|
+
"%s: shape mismatch (ndim %d vs %d)",
|
|
419
|
+
lbl, ca_in->ndim, ca_out->ndim);
|
|
420
|
+
}
|
|
421
|
+
for (k = 0; k < ca_in->ndim; k++) {
|
|
422
|
+
if (ca_in->dim[k] != ca_out->dim[k]) {
|
|
423
|
+
rb_raise(rb_eRuntimeError,
|
|
424
|
+
"%s: shape mismatch at dim[%d] (%lld vs %lld)",
|
|
425
|
+
lbl, k,
|
|
426
|
+
(long long) ca_in->dim[k],
|
|
427
|
+
(long long) ca_out->dim[k]);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|