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,357 @@
|
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
|
2
|
+
|
|
3
|
+
scatter_*! family (per-position mutation primitives): scatter_add /
|
|
4
|
+
sub / mul / min / max in-place, docs in yard-stubs/carray_scatter.rb.
|
|
5
|
+
|
|
6
|
+
Shared contract (load-bearing across all five methods):
|
|
7
|
+
addrs CArray or Ruby Array; coerced to ca_size_t, OOB raises IndexError
|
|
8
|
+
vals CArray of length(addrs) OR Numeric scalar (broadcast)
|
|
9
|
+
duplicates unbuffered (sequential) — collisions accumulate
|
|
10
|
+
mask pair skipped when any of addrs[i] / vals[i] / self[addrs[i]] is masked
|
|
11
|
+
cast vals silently cast to self.data_type
|
|
12
|
+
dtype arithmetic (add / sub / mul / min / max): numeric only
|
|
13
|
+
(boolean / object / fixlen → CADataTypeError; the bang
|
|
14
|
+
cannot widen self, same rationale as fma! / fms!)
|
|
15
|
+
replace: numeric or boolean (assignment, no widening)
|
|
16
|
+
|
|
17
|
+
--------------------------------------------------------------------------- */
|
|
18
|
+
|
|
19
|
+
#include "carray.h"
|
|
20
|
+
|
|
21
|
+
/* ---------- common kernel macros ----------
|
|
22
|
+
|
|
23
|
+
Scalar broadcast path: `vs` already cast to T at entry.
|
|
24
|
+
Vector path: `r[i]` already in self.data_type (silent cast via wrap).
|
|
25
|
+
|
|
26
|
+
APPLY(qp, v) := one of:
|
|
27
|
+
OP_ADD *(qp) += (v)
|
|
28
|
+
OP_SUB *(qp) -= (v)
|
|
29
|
+
OP_MIN_FLT if ((v) < *(qp) || *(qp) != *(qp)) *(qp) = (v) (fmin policy)
|
|
30
|
+
OP_MAX_FLT if ((v) > *(qp) || *(qp) != *(qp)) *(qp) = (v)
|
|
31
|
+
OP_MIN_INT if ((v) < *(qp)) *(qp) = (v)
|
|
32
|
+
OP_MAX_INT if ((v) > *(qp)) *(qp) = (v)
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
#define OP_ADD(qp, v) (*(qp) += (v))
|
|
36
|
+
#define OP_SUB(qp, v) (*(qp) -= (v))
|
|
37
|
+
#define OP_MUL(qp, v) (*(qp) *= (v))
|
|
38
|
+
#define OP_REPLACE(qp, v) (*(qp) = (v))
|
|
39
|
+
#define OP_MIN_FLT(qp, v) do { if ((v) < *(qp) || *(qp) != *(qp)) *(qp) = (v); } while (0)
|
|
40
|
+
#define OP_MAX_FLT(qp, v) do { if ((v) > *(qp) || *(qp) != *(qp)) *(qp) = (v); } while (0)
|
|
41
|
+
#define OP_MIN_INT(qp, v) do { if ((v) < *(qp)) *(qp) = (v); } while (0)
|
|
42
|
+
#define OP_MAX_INT(qp, v) do { if ((v) > *(qp)) *(qp) = (v); } while (0)
|
|
43
|
+
|
|
44
|
+
#define LOOP_SCALAR(T, APPLY) do { \
|
|
45
|
+
T *q = (T *) ca->ptr; \
|
|
46
|
+
T vs = (T) (v_is_float ? (double)vd : (double)vl); \
|
|
47
|
+
if ( mself ) { \
|
|
48
|
+
for (i = 0; i < n; i++) { \
|
|
49
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
50
|
+
addr = p[i]; \
|
|
51
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
52
|
+
if ( mself[addr] ) continue; \
|
|
53
|
+
APPLY(q + addr, vs); \
|
|
54
|
+
} \
|
|
55
|
+
} \
|
|
56
|
+
else { \
|
|
57
|
+
for (i = 0; i < n; i++) { \
|
|
58
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
59
|
+
addr = p[i]; \
|
|
60
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
61
|
+
APPLY(q + addr, vs); \
|
|
62
|
+
} \
|
|
63
|
+
} \
|
|
64
|
+
} while (0)
|
|
65
|
+
|
|
66
|
+
#define LOOP_VEC(T, APPLY) do { \
|
|
67
|
+
T *q = (T *) ca->ptr; \
|
|
68
|
+
T *r = (T *) cv->ptr; \
|
|
69
|
+
if ( mself ) { \
|
|
70
|
+
for (i = 0; i < n; i++) { \
|
|
71
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
72
|
+
if ( mvals && mvals[i] ) continue; \
|
|
73
|
+
addr = p[i]; \
|
|
74
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
75
|
+
if ( mself[addr] ) continue; \
|
|
76
|
+
APPLY(q + addr, r[i]); \
|
|
77
|
+
} \
|
|
78
|
+
} \
|
|
79
|
+
else { \
|
|
80
|
+
for (i = 0; i < n; i++) { \
|
|
81
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
82
|
+
if ( mvals && mvals[i] ) continue; \
|
|
83
|
+
addr = p[i]; \
|
|
84
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
85
|
+
APPLY(q + addr, r[i]); \
|
|
86
|
+
} \
|
|
87
|
+
} \
|
|
88
|
+
} while (0)
|
|
89
|
+
|
|
90
|
+
/* REPLACE variant: last-write semantics. Differs from the accumulate
|
|
91
|
+
family on mask handling:
|
|
92
|
+
- target's prior mask is NOT a skip signal; the write overwrites
|
|
93
|
+
both value and mask (indexer contract, `self[addrs] = vals`).
|
|
94
|
+
- masked vals[i] flips target to masked (writes UNDEF); valid
|
|
95
|
+
vals[i] writes value and clears the target's mask bit.
|
|
96
|
+
Scalar vals is always valid (Fixnum / Float), so scalar path just
|
|
97
|
+
writes and clears target mask. */
|
|
98
|
+
|
|
99
|
+
#define LOOP_SCALAR_REPLACE(T) do { \
|
|
100
|
+
T *q = (T *) ca->ptr; \
|
|
101
|
+
T vs = (T) (v_is_float ? (double)vd : (double)vl); \
|
|
102
|
+
for (i = 0; i < n; i++) { \
|
|
103
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
104
|
+
addr = p[i]; \
|
|
105
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
106
|
+
q[addr] = vs; \
|
|
107
|
+
if ( mself ) mself[addr] = 0; \
|
|
108
|
+
} \
|
|
109
|
+
} while (0)
|
|
110
|
+
|
|
111
|
+
#define LOOP_VEC_REPLACE(T) do { \
|
|
112
|
+
T *q = (T *) ca->ptr; \
|
|
113
|
+
T *r = (T *) cv->ptr; \
|
|
114
|
+
for (i = 0; i < n; i++) { \
|
|
115
|
+
if ( maddrs && maddrs[i] ) continue; \
|
|
116
|
+
addr = p[i]; \
|
|
117
|
+
CA_CHECK_INDEX(addr, elements); \
|
|
118
|
+
if ( mvals && mvals[i] ) { \
|
|
119
|
+
if ( mself ) mself[addr] = 1; \
|
|
120
|
+
} else { \
|
|
121
|
+
q[addr] = r[i]; \
|
|
122
|
+
if ( mself ) mself[addr] = 0; \
|
|
123
|
+
} \
|
|
124
|
+
} \
|
|
125
|
+
} while (0)
|
|
126
|
+
|
|
127
|
+
#define DISPATCH_NUMERIC_REPLACE() do { \
|
|
128
|
+
switch ( ca->data_type ) { \
|
|
129
|
+
case CA_BOOLEAN: if (vals_scalar) LOOP_SCALAR_REPLACE(uint8_t); else LOOP_VEC_REPLACE(uint8_t); break; \
|
|
130
|
+
case CA_FLOAT64: if (vals_scalar) LOOP_SCALAR_REPLACE(double); else LOOP_VEC_REPLACE(double); break; \
|
|
131
|
+
case CA_FLOAT32: if (vals_scalar) LOOP_SCALAR_REPLACE(float); else LOOP_VEC_REPLACE(float); break; \
|
|
132
|
+
case CA_INT64: if (vals_scalar) LOOP_SCALAR_REPLACE(int64_t); else LOOP_VEC_REPLACE(int64_t); break; \
|
|
133
|
+
case CA_INT32: if (vals_scalar) LOOP_SCALAR_REPLACE(int32_t); else LOOP_VEC_REPLACE(int32_t); break; \
|
|
134
|
+
case CA_INT16: if (vals_scalar) LOOP_SCALAR_REPLACE(int16_t); else LOOP_VEC_REPLACE(int16_t); break; \
|
|
135
|
+
case CA_INT8: if (vals_scalar) LOOP_SCALAR_REPLACE(int8_t); else LOOP_VEC_REPLACE(int8_t); break; \
|
|
136
|
+
case CA_UINT64: if (vals_scalar) LOOP_SCALAR_REPLACE(uint64_t); else LOOP_VEC_REPLACE(uint64_t); break; \
|
|
137
|
+
case CA_UINT32: if (vals_scalar) LOOP_SCALAR_REPLACE(uint32_t); else LOOP_VEC_REPLACE(uint32_t); break; \
|
|
138
|
+
case CA_UINT16: if (vals_scalar) LOOP_SCALAR_REPLACE(uint16_t); else LOOP_VEC_REPLACE(uint16_t); break; \
|
|
139
|
+
case CA_UINT8: if (vals_scalar) LOOP_SCALAR_REPLACE(uint8_t); else LOOP_VEC_REPLACE(uint8_t); break; \
|
|
140
|
+
default: \
|
|
141
|
+
rb_bug("carray_scatter: unsupported data_type %d after numeric check", ca->data_type); \
|
|
142
|
+
} \
|
|
143
|
+
} while (0)
|
|
144
|
+
|
|
145
|
+
#define DISPATCH_NUMERIC(APPLY_INT, APPLY_FLT) do { \
|
|
146
|
+
switch ( ca->data_type ) { \
|
|
147
|
+
case CA_FLOAT64: if (vals_scalar) LOOP_SCALAR(double, APPLY_FLT); else LOOP_VEC(double, APPLY_FLT); break; \
|
|
148
|
+
case CA_FLOAT32: if (vals_scalar) LOOP_SCALAR(float, APPLY_FLT); else LOOP_VEC(float, APPLY_FLT); break; \
|
|
149
|
+
case CA_INT64: if (vals_scalar) LOOP_SCALAR(int64_t, APPLY_INT); else LOOP_VEC(int64_t, APPLY_INT); break; \
|
|
150
|
+
case CA_INT32: if (vals_scalar) LOOP_SCALAR(int32_t, APPLY_INT); else LOOP_VEC(int32_t, APPLY_INT); break; \
|
|
151
|
+
case CA_INT16: if (vals_scalar) LOOP_SCALAR(int16_t, APPLY_INT); else LOOP_VEC(int16_t, APPLY_INT); break; \
|
|
152
|
+
case CA_INT8: if (vals_scalar) LOOP_SCALAR(int8_t, APPLY_INT); else LOOP_VEC(int8_t, APPLY_INT); break; \
|
|
153
|
+
case CA_UINT64: if (vals_scalar) LOOP_SCALAR(uint64_t, APPLY_INT); else LOOP_VEC(uint64_t, APPLY_INT); break; \
|
|
154
|
+
case CA_UINT32: if (vals_scalar) LOOP_SCALAR(uint32_t, APPLY_INT); else LOOP_VEC(uint32_t, APPLY_INT); break; \
|
|
155
|
+
case CA_UINT16: if (vals_scalar) LOOP_SCALAR(uint16_t, APPLY_INT); else LOOP_VEC(uint16_t, APPLY_INT); break; \
|
|
156
|
+
case CA_UINT8: if (vals_scalar) LOOP_SCALAR(uint8_t, APPLY_INT); else LOOP_VEC(uint8_t, APPLY_INT); break; \
|
|
157
|
+
default: \
|
|
158
|
+
/* numeric check passed before dispatch; complex types fall through to bug */ \
|
|
159
|
+
rb_bug("carray_scatter: unsupported data_type %d after numeric check", ca->data_type); \
|
|
160
|
+
} \
|
|
161
|
+
} while (0)
|
|
162
|
+
|
|
163
|
+
/* Setup boilerplate: parse args, wrap addrs/vals, attach.
|
|
164
|
+
|
|
165
|
+
Outputs into caller's locals:
|
|
166
|
+
ca, ci, cv (CArray*), n, elements (ca_size_t),
|
|
167
|
+
p, maddrs, mvals, mself (pointers),
|
|
168
|
+
vals_scalar (int), v_is_float (int), vd (double), vl (long).
|
|
169
|
+
|
|
170
|
+
Caller must `ca_sync(ca); ca_detach_n(...);` after kernel.
|
|
171
|
+
*/
|
|
172
|
+
/* Body shared by arithmetic and replace setups. Caller precondition:
|
|
173
|
+
the data_type gate has already run (arithmetic = numeric only, replace
|
|
174
|
+
= numeric or boolean). For the replace variant, `true` / `false`
|
|
175
|
+
scalars are accepted as vals (bridged as vl = 1 / 0). */
|
|
176
|
+
#define AT_SETUP_BODY(name, allow_bool_scalar) \
|
|
177
|
+
raddrs = rb_ca_wrap_readonly(raddrs, INT2NUM(CA_SIZE)); \
|
|
178
|
+
TypedData_Get_Struct(raddrs, CArray, &carray_data_type, ci); \
|
|
179
|
+
n = ci->elements; \
|
|
180
|
+
if ( n == 0 ) return self; \
|
|
181
|
+
vals_scalar = (RB_FLOAT_TYPE_P(rvals) || FIXNUM_P(rvals) \
|
|
182
|
+
|| ((allow_bool_scalar) && (rvals == Qtrue || rvals == Qfalse))); \
|
|
183
|
+
if ( vals_scalar ) { \
|
|
184
|
+
if ( RB_FLOAT_TYPE_P(rvals) ) { vd = RFLOAT_VALUE(rvals); v_is_float = 1; } \
|
|
185
|
+
else if ( FIXNUM_P(rvals) ) { vl = FIX2LONG(rvals); v_is_float = 0; } \
|
|
186
|
+
else { vl = (rvals == Qtrue) ? 1 : 0; v_is_float = 0; } \
|
|
187
|
+
} \
|
|
188
|
+
else { \
|
|
189
|
+
rvals = rb_ca_wrap_readonly(rvals, INT2NUM(ca->data_type)); \
|
|
190
|
+
TypedData_Get_Struct(rvals, CArray, &carray_data_type, cv); \
|
|
191
|
+
if ( cv->elements != n ) { \
|
|
192
|
+
rb_raise(rb_eArgError, \
|
|
193
|
+
name ": vals length (%lld) doesn't match addrs length (%lld)", \
|
|
194
|
+
(long long)cv->elements, (long long)n); \
|
|
195
|
+
} \
|
|
196
|
+
} \
|
|
197
|
+
if ( vals_scalar ) ca_attach_n(2, ca, ci); \
|
|
198
|
+
else ca_attach_n(3, ca, ci, cv); \
|
|
199
|
+
p = (ca_size_t *) ci->ptr; \
|
|
200
|
+
maddrs = ci->mask ? (boolean8_t *) ci->mask->ptr : NULL; \
|
|
201
|
+
mvals = (cv && cv->mask) ? (boolean8_t *) cv->mask->ptr : NULL; \
|
|
202
|
+
mself = ca->mask ? (boolean8_t *) ca->mask->ptr : NULL; \
|
|
203
|
+
elements = ca->elements;
|
|
204
|
+
|
|
205
|
+
#define AT_SETUP_OR_RETURN(name) \
|
|
206
|
+
CArray *ca, *ci, *cv = NULL; \
|
|
207
|
+
ca_size_t i, n, addr, elements; \
|
|
208
|
+
ca_size_t *p; \
|
|
209
|
+
boolean8_t *maddrs, *mvals = NULL, *mself; \
|
|
210
|
+
int vals_scalar, v_is_float = 0; \
|
|
211
|
+
double vd = 0.0; long vl = 0; \
|
|
212
|
+
rb_ca_modify(self); \
|
|
213
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca); \
|
|
214
|
+
if ( ! ca_is_numeric_type(ca) ) { \
|
|
215
|
+
rb_raise(rb_eCADataTypeError, name " requires a numeric array"); \
|
|
216
|
+
} \
|
|
217
|
+
AT_SETUP_BODY(name, 0)
|
|
218
|
+
|
|
219
|
+
/* replace variant: accepts boolean self (assignment, no widening) and
|
|
220
|
+
Ruby true / false as scalar vals. */
|
|
221
|
+
#define AT_SETUP_OR_RETURN_REPLACE(name) \
|
|
222
|
+
CArray *ca, *ci, *cv = NULL; \
|
|
223
|
+
ca_size_t i, n, addr, elements; \
|
|
224
|
+
ca_size_t *p; \
|
|
225
|
+
boolean8_t *maddrs, *mvals = NULL, *mself; \
|
|
226
|
+
int vals_scalar, v_is_float = 0; \
|
|
227
|
+
double vd = 0.0; long vl = 0; \
|
|
228
|
+
rb_ca_modify(self); \
|
|
229
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca); \
|
|
230
|
+
if ( ! ca_is_numeric_type(ca) && ca->data_type != CA_BOOLEAN ) { \
|
|
231
|
+
rb_raise(rb_eCADataTypeError, \
|
|
232
|
+
name " requires a numeric or boolean array"); \
|
|
233
|
+
} \
|
|
234
|
+
AT_SETUP_BODY(name, 1)
|
|
235
|
+
|
|
236
|
+
#define AT_TEARDOWN() do { \
|
|
237
|
+
ca_sync(ca); \
|
|
238
|
+
if ( vals_scalar ) ca_detach_n(2, ca, ci); \
|
|
239
|
+
else ca_detach_n(3, ca, ci, cv); \
|
|
240
|
+
} while (0)
|
|
241
|
+
|
|
242
|
+
/* --------------------------------------------------------------- */
|
|
243
|
+
|
|
244
|
+
/* CArray#scatter_add!(addrs, vals) — for each i, self[addrs[i]] +=
|
|
245
|
+
* vals[i] (or += vals when scalar). Duplicate addrs accumulate
|
|
246
|
+
* (unbuffered), unlike self[addrs] += vals which is last-wins. */
|
|
247
|
+
static VALUE
|
|
248
|
+
rb_ca_scatter_add_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
249
|
+
{
|
|
250
|
+
AT_SETUP_OR_RETURN("scatter_add!");
|
|
251
|
+
DISPATCH_NUMERIC(OP_ADD, OP_ADD);
|
|
252
|
+
AT_TEARDOWN();
|
|
253
|
+
return self;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* --------------------------------------------------------------- */
|
|
257
|
+
|
|
258
|
+
/* CArray#scatter_sub!(addrs, vals) — for each i, self[addrs[i]] -=
|
|
259
|
+
* vals[i]. Same mask/cast/bounds policy as scatter_add!. */
|
|
260
|
+
static VALUE
|
|
261
|
+
rb_ca_scatter_sub_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
262
|
+
{
|
|
263
|
+
AT_SETUP_OR_RETURN("scatter_sub!");
|
|
264
|
+
DISPATCH_NUMERIC(OP_SUB, OP_SUB);
|
|
265
|
+
AT_TEARDOWN();
|
|
266
|
+
return self;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* --------------------------------------------------------------- */
|
|
270
|
+
|
|
271
|
+
/* CArray#scatter_mul!(addrs, vals) — for each i, self[addrs[i]] *=
|
|
272
|
+
* vals[i]. NaN/inf follow standard C arithmetic (no fmin-style
|
|
273
|
+
* missing-value rule); integer overflow wraps. Otherwise identical
|
|
274
|
+
* to scatter_add! (mask / cast / bounds). */
|
|
275
|
+
static VALUE
|
|
276
|
+
rb_ca_scatter_mul_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
277
|
+
{
|
|
278
|
+
AT_SETUP_OR_RETURN("scatter_mul!");
|
|
279
|
+
DISPATCH_NUMERIC(OP_MUL, OP_MUL);
|
|
280
|
+
AT_TEARDOWN();
|
|
281
|
+
return self;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/* --------------------------------------------------------------- */
|
|
285
|
+
|
|
286
|
+
/* CArray#scatter_min!(addrs, vals) — for each i, self[addrs[i]] =
|
|
287
|
+
* min(self[addrs[i]], vals[i]). Float types follow the fmin rule
|
|
288
|
+
* (NaN is treated as missing). Same mask/cast/bounds policy as
|
|
289
|
+
* scatter_add!. */
|
|
290
|
+
static VALUE
|
|
291
|
+
rb_ca_scatter_min_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
292
|
+
{
|
|
293
|
+
AT_SETUP_OR_RETURN("scatter_min!");
|
|
294
|
+
DISPATCH_NUMERIC(OP_MIN_INT, OP_MIN_FLT);
|
|
295
|
+
AT_TEARDOWN();
|
|
296
|
+
return self;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* --------------------------------------------------------------- */
|
|
300
|
+
|
|
301
|
+
/* CArray#scatter_max!(addrs, vals) — for each i, self[addrs[i]] =
|
|
302
|
+
* max(self[addrs[i]], vals[i]). Float types follow the fmax rule.
|
|
303
|
+
* Otherwise identical to scatter_add!. */
|
|
304
|
+
static VALUE
|
|
305
|
+
rb_ca_scatter_max_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
306
|
+
{
|
|
307
|
+
AT_SETUP_OR_RETURN("scatter_max!");
|
|
308
|
+
DISPATCH_NUMERIC(OP_MAX_INT, OP_MAX_FLT);
|
|
309
|
+
AT_TEARDOWN();
|
|
310
|
+
return self;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* --------------------------------------------------------------- */
|
|
314
|
+
|
|
315
|
+
/* CArray#scatter_replace!(addrs, vals) — for each i, self[addrs[i]] =
|
|
316
|
+
* vals[i] (or = vals when scalar). Semantically equivalent to
|
|
317
|
+
* self[addrs] = vals (last-write-wins on duplicate addrs) but bypasses
|
|
318
|
+
* the CAGrid view chain (snapshot copy of addrs + view alloc + store_all
|
|
319
|
+
* dispatch). Mask policy follows the indexer contract: target's prior
|
|
320
|
+
* mask is overwritten (masked vals[i] flips target to masked, valid
|
|
321
|
+
* vals[i] clears target's mask). */
|
|
322
|
+
static VALUE
|
|
323
|
+
rb_ca_scatter_replace_bang (VALUE self, VALUE raddrs, VALUE rvals)
|
|
324
|
+
{
|
|
325
|
+
/* Pre-scan: if vals is a masked CArray and self isn't yet masked,
|
|
326
|
+
promote self so the kernel can flip target cells to masked (indexer
|
|
327
|
+
`self[addrs] = vals` establishes self.mask lazily the same way). */
|
|
328
|
+
if ( ! (RB_FLOAT_TYPE_P(rvals) || FIXNUM_P(rvals))
|
|
329
|
+
&& rb_obj_is_carray(rvals) ) {
|
|
330
|
+
CArray *cv_pre;
|
|
331
|
+
TypedData_Get_Struct(rvals, CArray, &carray_data_type, cv_pre);
|
|
332
|
+
if ( ca_has_mask(cv_pre) ) {
|
|
333
|
+
CArray *ca_pre;
|
|
334
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca_pre);
|
|
335
|
+
if ( ! ca_has_mask(ca_pre) ) {
|
|
336
|
+
ca_create_mask(ca_pre);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
AT_SETUP_OR_RETURN_REPLACE("scatter_replace!");
|
|
341
|
+
DISPATCH_NUMERIC_REPLACE();
|
|
342
|
+
AT_TEARDOWN();
|
|
343
|
+
return self;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* --------------------------------------------------------------- */
|
|
347
|
+
|
|
348
|
+
void
|
|
349
|
+
Init_carray_scatter (void)
|
|
350
|
+
{
|
|
351
|
+
rb_define_method(rb_cCArray, "scatter_add!", rb_ca_scatter_add_bang, 2);
|
|
352
|
+
rb_define_method(rb_cCArray, "scatter_sub!", rb_ca_scatter_sub_bang, 2);
|
|
353
|
+
rb_define_method(rb_cCArray, "scatter_mul!", rb_ca_scatter_mul_bang, 2);
|
|
354
|
+
rb_define_method(rb_cCArray, "scatter_min!", rb_ca_scatter_min_bang, 2);
|
|
355
|
+
rb_define_method(rb_cCArray, "scatter_max!", rb_ca_scatter_max_bang, 2);
|
|
356
|
+
rb_define_method(rb_cCArray, "scatter_replace!", rb_ca_scatter_replace_bang, 2);
|
|
357
|
+
}
|