carray 3.0.2 → 3.0.3
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/CHANGELOG.md +304 -0
- data/README.md +3 -4
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +225 -0
- data/ext/ca_axis_group.c +177 -99
- data/ext/ca_binop_dispatch.c +54 -32
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +66 -71
- data/ext/ca_compare.c +8 -2
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +27 -11
- data/ext/ca_kernel_iterator.c +663 -214
- data/ext/ca_kernel_iterator.h +231 -167
- data/ext/ca_monop_dispatch.c +4 -4
- data/ext/ca_monop_dispatch.h +4 -0
- data/ext/ca_obj_array.c +132 -22
- data/ext/ca_obj_bincmp.c +152 -121
- data/ext/ca_obj_binop.c +107 -210
- data/ext/ca_obj_bitarray.c +37 -24
- data/ext/ca_obj_bitfield.c +95 -62
- data/ext/ca_obj_block.c +1 -0
- data/ext/ca_obj_byte_swap.c +40 -40
- data/ext/ca_obj_const_string.c +96 -25
- data/ext/ca_obj_face.c +406 -64
- data/ext/ca_obj_face.h +92 -47
- data/ext/ca_obj_fake.c +21 -50
- data/ext/ca_obj_farray.c +1 -0
- data/ext/ca_obj_field.c +16 -3
- data/ext/ca_obj_fixlen_string.c +21 -21
- data/ext/ca_obj_grid.c +181 -124
- data/ext/ca_obj_meld.c +189 -107
- data/ext/ca_obj_moncmp.c +61 -61
- data/ext/ca_obj_monop.c +125 -107
- data/ext/ca_obj_object.c +543 -233
- data/ext/ca_obj_record.c +51 -16
- data/ext/ca_obj_reduce.c +5 -8
- data/ext/ca_obj_refer.c +117 -33
- data/ext/ca_obj_remap.c +57 -17
- data/ext/ca_obj_repeat.c +21 -5
- data/ext/ca_obj_roll.c +115 -11
- data/ext/ca_obj_select.c +47 -49
- data/ext/ca_obj_select_axis.c +58 -60
- data/ext/ca_obj_shift.c +22 -102
- data/ext/ca_obj_stack.c +223 -118
- data/ext/ca_obj_stride.c +195 -34
- data/ext/ca_obj_string.c +17 -18
- data/ext/ca_obj_tile.c +32 -16
- data/ext/ca_obj_time.c +23 -25
- data/ext/ca_obj_timedelta.c +21 -23
- data/ext/ca_obj_transpose.c +12 -3
- data/ext/ca_obj_triop.c +110 -117
- data/ext/ca_obj_window.c +149 -27
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +102 -79
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +463 -0
- data/ext/carray.h +70 -27
- data/ext/carray_access.c +455 -211
- data/ext/carray_address_basis.c +177 -36
- data/ext/carray_attribute.c +45 -3
- data/ext/carray_bincount.c +32 -2
- data/ext/carray_broadcast.c +46 -14
- data/ext/carray_call_cfunc.c +0 -28
- data/ext/carray_cast.c +1444 -209
- data/ext/carray_cast_func.rb +34 -21
- data/ext/carray_conversion.c +197 -73
- data/ext/carray_copy.c +32 -11
- data/ext/carray_core.c +514 -122
- data/ext/carray_count.c +140 -87
- data/ext/carray_element.c +18 -27
- data/ext/carray_factorize.c +569 -277
- data/ext/carray_generate.c +76 -40
- data/ext/carray_histogram.c +152 -94
- data/ext/carray_hold.c +2 -1
- data/ext/carray_index_classifier.c +63 -96
- data/ext/carray_internal.h +385 -3
- data/ext/carray_lazy.c +834 -79
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +682 -316
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +221 -76
- data/ext/carray_memory_view.c +254 -248
- data/ext/carray_operator.c +1089 -359
- data/ext/carray_order.c +133 -69
- data/ext/carray_partition.c +102 -56
- data/ext/carray_random.c +273 -239
- data/ext/carray_scatter.c +308 -65
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +170 -70
- data/ext/carray_sort.c +215 -218
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +99 -21
- data/ext/carray_test.c +167 -64
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_utils.c +363 -98
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +0 -2
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1076 -846
- data/ext/ruby_carray.c +7 -1
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +39 -0
- data/lib/carray/autoload_carray.rb +19 -0
- data/lib/carray/autoload_method_extension.rb +6 -0
- data/lib/carray/axis_group.rb +174 -26
- data/lib/carray/basics.rb +91 -25
- data/lib/carray/bincount_nd.rb +6 -0
- data/lib/carray/block_iterator.rb +118 -48
- data/lib/carray/boolean_reduce.rb +21 -29
- data/lib/carray/categorical.rb +94 -26
- data/lib/carray/categorical_iterator.rb +333 -826
- data/lib/carray/complex.rb +36 -29
- data/lib/carray/conditional.rb +94 -7
- data/lib/carray/const_string.rb +46 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +13 -7
- data/lib/carray/frame/csv_parser.rb +589 -82
- data/lib/carray/frame/describe.rb +79 -0
- data/lib/carray/frame/frame.rb +124 -25
- data/lib/carray/frame/group.rb +189 -63
- data/lib/carray/frame/io.rb +412 -72
- data/lib/carray/frame/join.rb +134 -46
- data/lib/carray/frame/records.rb +37 -16
- data/lib/carray/frame/reshape.rb +448 -0
- data/lib/carray/frame/sort.rb +26 -2
- data/lib/carray/frame/verbs.rb +715 -48
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +111 -2
- data/lib/carray/fusion.rb +229 -38
- data/lib/carray/inspect.rb +29 -11
- data/lib/carray/iterator.rb +14 -2
- data/lib/carray/lazy.rb +54 -30
- data/lib/carray/mask_gap_fill.rb +66 -52
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +40 -7
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bincount.rb +2 -2
- data/lib/carray/methods/bit_string.rb +14 -3
- data/lib/carray/methods/composition.rb +16 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +13 -2
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_in.rb +117 -4
- data/lib/carray/methods/join.rb +1 -1
- data/lib/carray/methods/locate_addr.rb +177 -36
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/runtime.rb +14 -11
- data/lib/carray/segment_iterator.rb +990 -0
- data/lib/carray/serialize.rb +197 -27
- data/lib/carray/slab_iterator.rb +51 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string_operation_extension.rb +4 -3
- data/lib/carray/struct.rb +142 -51
- data/lib/carray/struct_builder.rb +110 -14
- data/lib/carray/table.rb +2 -2
- data/lib/carray/time.rb +517 -103
- data/lib/carray/window_iterator.rb +127 -72
- data/lib/carray.rb +2 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +1 -1
- data/yard-stubs/ca_obj_refer.rb +3 -3
- data/yard-stubs/ca_obj_roll.rb +0 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +1 -2
- data/yard-stubs/carray_access.rb +5 -4
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +78 -43
- data/yard-stubs/carray_conversion.rb +13 -1
- data/yard-stubs/carray_copy.rb +8 -3
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +34 -10
- data/yard-stubs/carray_math.rb +25 -13
- data/yard-stubs/carray_median_percentile.rb +10 -6
- data/yard-stubs/carray_order.rb +34 -13
- data/yard-stubs/carray_scatter.rb +10 -3
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +2 -1
- data/yard-stubs/carray_sort.rb +43 -3
- data/yard-stubs/carray_test.rb +10 -0
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +11 -19
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_build_flags.h +0 -3
- data/ext/carray_config.h +0 -28
- data/ext/carray_kernels_bincmp.c +0 -4446
- data/ext/carray_kernels_binop.c +0 -11001
- data/ext/carray_kernels_init.c +0 -1131
- data/ext/carray_kernels_map.c +0 -3467
- data/ext/carray_kernels_moncmp.c +0 -2097
- data/ext/carray_kernels_monop.c +0 -18313
- data/ext/carray_kernels_reduce_aggregate.c +0 -26005
- data/ext/carray_kernels_reduce_boolean.c +0 -330
- data/ext/carray_kernels_reduce_cumulative.c +0 -14862
- data/ext/carray_kernels_reduce_extreme.c +0 -17494
- data/ext/carray_kernels_reduce_variance.c +0 -3910
- data/ext/carray_kernels_scan.c +0 -3693
- data/ext/carray_kernels_search.c +0 -32218
- data/ext/carray_kernels_sort.c +0 -10626
- data/ext/carray_kernels_triop.c +0 -1392
data/ext/ca_axis_group.c
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
--------------------------------------------------------------------------- */
|
|
34
34
|
|
|
35
35
|
#include "carray.h"
|
|
36
|
+
#include "carray_internal.h" /* CA_EXTREMUM_REPLACES, ca_obj_extremum_replaces */
|
|
36
37
|
#include "ca_kernel_iterator.h"
|
|
37
38
|
#include <math.h>
|
|
38
39
|
|
|
@@ -64,8 +65,8 @@ group_op_code (VALUE vop)
|
|
|
64
65
|
else if ( id == rb_intern("max_addr") ) return GR_MAXADDR;
|
|
65
66
|
else if ( id == rb_intern("all") ) return GR_ALL;
|
|
66
67
|
else if ( id == rb_intern("any") ) return GR_ANY;
|
|
67
|
-
rb_raise(rb_eArgError, "axis_group_reduce: unsupported op :%
|
|
68
|
-
|
|
68
|
+
rb_raise(rb_eArgError, "axis_group_reduce: unsupported op :%"PRIsVALUE,
|
|
69
|
+
rb_id2str(id));
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
/* ---- per-slab-element composite-code walk, templated on the load type ----
|
|
@@ -206,16 +207,16 @@ group_op_code (VALUE vop)
|
|
|
206
207
|
only while nothing else has landed, the first number displaces it, and a
|
|
207
208
|
group of nothing but NaN answers NaN (for a position, UNDEF). `v` is the
|
|
208
209
|
widened load, so testing it for NaN is the same question for every source
|
|
209
|
-
type and costs an integer body nothing.
|
|
210
|
-
|
|
210
|
+
type and costs an integer body nothing. The replacement test is the
|
|
211
|
+
shared CA_EXTREMUM_REPLACES; the first member is taken whatever it is.
|
|
212
|
+
seen_num[] says whether a number has landed (the positions read it);
|
|
213
|
+
cnt[] says whether anything has. */
|
|
211
214
|
#define GMINMAX(T, A, CMP) \
|
|
212
215
|
do { \
|
|
213
216
|
A *acc = (A *) co->ptr; \
|
|
214
217
|
A av = (A) rv; \
|
|
215
|
-
if (
|
|
216
|
-
|
|
217
|
-
else if ( av CMP acc[o] ) acc[o] = av; \
|
|
218
|
-
} else if ( cnt[o] == 0 ) acc[o] = av; \
|
|
218
|
+
if ( cnt[o] == 0 || CA_EXTREMUM_REPLACES(av, acc[o], CMP) ) acc[o] = av; \
|
|
219
|
+
if ( v == v ) seen_num[o] = 1; \
|
|
219
220
|
cnt[o] += 1; \
|
|
220
221
|
} while (0)
|
|
221
222
|
|
|
@@ -310,7 +311,7 @@ group_op_code (VALUE vop)
|
|
|
310
311
|
Empty / all-masked groups follow the CArray zero-contribution contract: an
|
|
311
312
|
identity-bearing op returns its identity (sum 0, prod 1, count 0, all true,
|
|
312
313
|
any false), a ratio / extremum returns UNDEF. Sample variance / stddev:
|
|
313
|
-
n
|
|
314
|
+
n < 2 UNDEF, n >= 2 the formula.
|
|
314
315
|
*/
|
|
315
316
|
static VALUE
|
|
316
317
|
rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
@@ -321,7 +322,7 @@ rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
321
322
|
GetCArray(self, src);
|
|
322
323
|
|
|
323
324
|
if ( src->ndim <= 0 ) {
|
|
324
|
-
rb_raise(
|
|
325
|
+
rb_raise(rb_eArgError, "axis_group_reduce: scalar source");
|
|
325
326
|
}
|
|
326
327
|
|
|
327
328
|
/* --- group (slab) axes --- */
|
|
@@ -393,9 +394,7 @@ rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
393
394
|
size_t nbytes = (size_t) bundle_ca[bi]->elements * sizeof(int32_t);
|
|
394
395
|
VALUE vbuf = rb_str_tmp_new((long) nbytes);
|
|
395
396
|
rb_ary_push((VALUE) keep, vbuf);
|
|
396
|
-
|
|
397
|
-
memcpy(RSTRING_PTR(vbuf), bundle_ca[bi]->ptr, nbytes);
|
|
398
|
-
ca_detach(bundle_ca[bi]);
|
|
397
|
+
ca_copy_data(bundle_ca[bi], RSTRING_PTR(vbuf));
|
|
399
398
|
bundle_codes[bi] = (int32_t *) RSTRING_PTR(vbuf);
|
|
400
399
|
}
|
|
401
400
|
|
|
@@ -477,9 +476,9 @@ rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
477
476
|
case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
|
|
478
477
|
case CA_FLOAT32: case CA_FLOAT64: break;
|
|
479
478
|
default:
|
|
480
|
-
rb_raise(
|
|
481
|
-
"
|
|
482
|
-
src->data_type);
|
|
479
|
+
rb_raise(rb_eCADataTypeError,
|
|
480
|
+
"axis_group: %"PRIsVALUE" over a group is not supported for data type %s",
|
|
481
|
+
rb_sym2str(vop), ca_type_name[src->data_type]);
|
|
483
482
|
}
|
|
484
483
|
|
|
485
484
|
/* output data type per op */
|
|
@@ -618,8 +617,8 @@ rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
618
617
|
/* Empty / all-masked groups follow the same zero-contribution contract as
|
|
619
618
|
CArray reductions (ERI, matching the categorical sibling): an identity-
|
|
620
619
|
bearing op returns its identity (sum 0, prod 1, count 0, all true, any
|
|
621
|
-
false), a ratio / extremum returns UNDEF. Sample variance/stddev: n
|
|
622
|
-
UNDEF
|
|
620
|
+
false), a ratio / extremum returns UNDEF. Sample variance/stddev: n<2
|
|
621
|
+
UNDEF (n-1 is zero), n>=2 the formula. */
|
|
623
622
|
if ( op == GR_COUNT ) {
|
|
624
623
|
int64_t *out = (int64_t *) co->ptr;
|
|
625
624
|
for ( ca_size_t o = 0; o < nout; o++ ) out[o] = (int64_t) cnt[o];
|
|
@@ -664,8 +663,7 @@ rb_ca_axis_group_reduce (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
664
663
|
break;
|
|
665
664
|
case GR_VARIANCE:
|
|
666
665
|
case GR_STDDEV:
|
|
667
|
-
if ( cnt[o]
|
|
668
|
-
else if ( cnt[o] == 1 ) { out[o] = 0.0; } /* n=1 contract */
|
|
666
|
+
if ( cnt[o] < 2 ) { out[o] = 0.0; MARK_UNDEF(o); }
|
|
669
667
|
else { double var = sumsq[o] / ( (double) cnt[o] - 1.0 );
|
|
670
668
|
out[o] = ( op == GR_STDDEV ) ? sqrt(var) : var; }
|
|
671
669
|
break;
|
|
@@ -854,7 +852,9 @@ group_scan_build_plan (ca_iter_state *st, boolean8_t *m,
|
|
|
854
852
|
emits its own value: a per-group `seen` byte initialises the accumulator
|
|
855
853
|
lazily on first hit — no sentinel like HUGE_VAL, which an integer data type could
|
|
856
854
|
not represent. CMP is > for max, < for min: a later member replaces the
|
|
857
|
-
running extremum when
|
|
855
|
+
running extremum when CA_EXTREMUM_REPLACES (a NaN never does, and a
|
|
856
|
+
number displaces a leading NaN, as the core cummax / cummin and the
|
|
857
|
+
reduce twins above do). A cell masked within its group holds the
|
|
858
858
|
current extremum once a member has been seen (output NOT masked, like sum);
|
|
859
859
|
before any member the extremum is undefined so the cell stays UNDEF (the
|
|
860
860
|
CArray reduction contract: empty max/min has no value — deliberately NOT the
|
|
@@ -895,7 +895,9 @@ group_scan_build_plan (ca_iter_state *st, boolean8_t *m,
|
|
|
895
895
|
} \
|
|
896
896
|
T rv = *(T *)(p + sw_doff[e]); \
|
|
897
897
|
if ( ! seen[code] ) { acce[code] = rv; seen[code] = 1; } \
|
|
898
|
-
else if ( rv
|
|
898
|
+
else if ( CA_EXTREMUM_REPLACES(rv, acce[code], CMP) ) { \
|
|
899
|
+
acce[code] = rv; \
|
|
900
|
+
} \
|
|
899
901
|
outp[addr] = acce[code]; \
|
|
900
902
|
} \
|
|
901
903
|
} \
|
|
@@ -933,19 +935,19 @@ group_scan_build_plan (ca_iter_state *st, boolean8_t *m,
|
|
|
933
935
|
both unmasked (matching core object cumsum / cumprod); cummax / cummin hold
|
|
934
936
|
the running VALUE only once a member has been seen and stay UNDEF before that
|
|
935
937
|
(no identity for arbitrary objects). GW_SKIP (excluded) stays UNDEF. accn /
|
|
936
|
-
seen are reset at each band; acco carries the running VALUE.
|
|
938
|
+
seen are reset at each band; acco carries the running VALUE.
|
|
939
|
+
Expanded only in group_scan_object_body, whose walk state is c->st. */
|
|
937
940
|
#define GROUP_SCAN_OBJECT_WALK(EMIT, HOLD) \
|
|
938
941
|
do { \
|
|
939
|
-
ca_iter_state st; \
|
|
940
942
|
char *p; \
|
|
941
943
|
boolean8_t *m; \
|
|
942
944
|
ca_size_t b = 0; \
|
|
943
945
|
int ready = 0; \
|
|
944
|
-
CA_FOR_EACH_SLAB(st, ca, axes, (int8_t) ngroup, CA_KERNEL_READ, p, m) {
|
|
945
|
-
ca_size_t SE = st.slab_elements;
|
|
946
|
+
CA_FOR_EACH_SLAB(c->st, ca, axes, (int8_t) ngroup, CA_KERNEL_READ, p, m) {\
|
|
947
|
+
ca_size_t SE = c->st.slab_elements; \
|
|
946
948
|
if ( SE > 0 ) { \
|
|
947
949
|
if ( ! ready ) { \
|
|
948
|
-
group_scan_build_plan(&st, m, n_bundles, bundle_codes, bundle_k
|
|
950
|
+
group_scan_build_plan(&c->st, m, n_bundles, bundle_codes, bundle_k,\
|
|
949
951
|
bundle_placeval, bundle_nconsumed, \
|
|
950
952
|
bundle_slot, bundle_cstride, ngroup, \
|
|
951
953
|
grstride, sw_code, sw_doff, sw_moff, sw_addr);\
|
|
@@ -970,6 +972,137 @@ group_scan_build_plan (ca_iter_state *st, boolean8_t *m,
|
|
|
970
972
|
} \
|
|
971
973
|
} while (0)
|
|
972
974
|
|
|
975
|
+
/* Marks output cell o UNDEF, creating the output mask on first use. Used
|
|
976
|
+
by the scan walks, in functions that hold the output as `co` and the mask
|
|
977
|
+
pointer as `omask`. */
|
|
978
|
+
#define MARK_OUT_UNDEF(o) do { \
|
|
979
|
+
if ( ! omask ) { \
|
|
980
|
+
ca_create_mask(co); \
|
|
981
|
+
omask = (boolean8_t *) co->mask->ptr; \
|
|
982
|
+
} \
|
|
983
|
+
omask[o] = 1; \
|
|
984
|
+
} while (0)
|
|
985
|
+
|
|
986
|
+
/* The CA_OBJECT lane of __axis_group_scan__. Every cell calls into Ruby,
|
|
987
|
+
so the walk can raise part way; its state lives in the caller's frame, in
|
|
988
|
+
c->st, and ca_iter_ensure finishes it however this body leaves. The
|
|
989
|
+
buffers are ALLOCV-backed, so the unwind collects them. */
|
|
990
|
+
typedef struct {
|
|
991
|
+
ca_iter_state st;
|
|
992
|
+
CArray *ca;
|
|
993
|
+
CArray *co;
|
|
994
|
+
int op;
|
|
995
|
+
int8_t *axes;
|
|
996
|
+
long ngroup;
|
|
997
|
+
int n_bundles;
|
|
998
|
+
int32_t **bundle_codes;
|
|
999
|
+
ca_size_t *bundle_k;
|
|
1000
|
+
ca_size_t *bundle_placeval;
|
|
1001
|
+
int *bundle_nconsumed;
|
|
1002
|
+
int (*bundle_slot)[CA_RANK_MAX];
|
|
1003
|
+
ca_size_t (*bundle_cstride)[CA_RANK_MAX];
|
|
1004
|
+
ca_size_t *grstride;
|
|
1005
|
+
ca_size_t *band_addr;
|
|
1006
|
+
ca_size_t K_total;
|
|
1007
|
+
ca_size_t *sw_code;
|
|
1008
|
+
ca_size_t *sw_doff;
|
|
1009
|
+
ca_size_t *sw_moff;
|
|
1010
|
+
ca_size_t *sw_addr;
|
|
1011
|
+
ca_size_t *accn;
|
|
1012
|
+
char *seen;
|
|
1013
|
+
VALUE *acco;
|
|
1014
|
+
} group_scan_object_t;
|
|
1015
|
+
|
|
1016
|
+
static VALUE
|
|
1017
|
+
group_scan_object_body (VALUE arg)
|
|
1018
|
+
{
|
|
1019
|
+
group_scan_object_t *c = (group_scan_object_t *) arg;
|
|
1020
|
+
CArray *ca = c->ca;
|
|
1021
|
+
CArray *co = c->co;
|
|
1022
|
+
int op = c->op;
|
|
1023
|
+
int8_t *axes = c->axes;
|
|
1024
|
+
long ngroup = c->ngroup;
|
|
1025
|
+
int n_bundles = c->n_bundles;
|
|
1026
|
+
int32_t **bundle_codes = c->bundle_codes;
|
|
1027
|
+
ca_size_t *bundle_k = c->bundle_k;
|
|
1028
|
+
ca_size_t *bundle_placeval = c->bundle_placeval;
|
|
1029
|
+
int *bundle_nconsumed = c->bundle_nconsumed;
|
|
1030
|
+
int (*bundle_slot)[CA_RANK_MAX] = c->bundle_slot;
|
|
1031
|
+
ca_size_t (*bundle_cstride)[CA_RANK_MAX] = c->bundle_cstride;
|
|
1032
|
+
ca_size_t *grstride = c->grstride;
|
|
1033
|
+
ca_size_t *band_addr = c->band_addr;
|
|
1034
|
+
ca_size_t K_total = c->K_total;
|
|
1035
|
+
ca_size_t *sw_code = c->sw_code;
|
|
1036
|
+
ca_size_t *sw_doff = c->sw_doff;
|
|
1037
|
+
ca_size_t *sw_moff = c->sw_moff;
|
|
1038
|
+
ca_size_t *sw_addr = c->sw_addr;
|
|
1039
|
+
ca_size_t *accn = c->accn;
|
|
1040
|
+
char *seen = c->seen;
|
|
1041
|
+
VALUE *acco = c->acco;
|
|
1042
|
+
boolean8_t *omask = NULL;
|
|
1043
|
+
|
|
1044
|
+
if ( op == GS_CUMCOUNT ) { /* int64 1-based running count */
|
|
1045
|
+
int64_t *outi = (int64_t *) co->ptr;
|
|
1046
|
+
GROUP_SCAN_OBJECT_WALK(
|
|
1047
|
+
accn[code] += 1; outi[addr] = (int64_t) accn[code];,
|
|
1048
|
+
outi[addr] = (int64_t) accn[code];
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
else { /* object running VALUE */
|
|
1052
|
+
VALUE *outo = (VALUE *) co->ptr;
|
|
1053
|
+
switch ( op ) {
|
|
1054
|
+
case GS_CUMSUM:
|
|
1055
|
+
/* Identity 0 (matching the core object cumsum): a group's acc is lazily
|
|
1056
|
+
seeded to 0 (Fixnum, so 0 + ev promotes to ev's class), so a cell
|
|
1057
|
+
masked before any present member holds 0 unmasked and an all-masked
|
|
1058
|
+
group yields 0 everywhere. seen doubles as the per-band init flag. */
|
|
1059
|
+
GROUP_SCAN_OBJECT_WALK(
|
|
1060
|
+
if ( ! seen[code] ) { acco[code] = INT2FIX(0); seen[code] = 1; }
|
|
1061
|
+
acco[code] = rb_funcall(acco[code], rb_intern("+"), 1, ev);
|
|
1062
|
+
outo[addr] = acco[code];,
|
|
1063
|
+
if ( ! seen[code] ) { acco[code] = INT2FIX(0); seen[code] = 1; }
|
|
1064
|
+
outo[addr] = acco[code];
|
|
1065
|
+
);
|
|
1066
|
+
break;
|
|
1067
|
+
case GS_CUMPROD:
|
|
1068
|
+
/* Identity 1, same lazy-init as cumsum. */
|
|
1069
|
+
GROUP_SCAN_OBJECT_WALK(
|
|
1070
|
+
if ( ! seen[code] ) { acco[code] = INT2FIX(1); seen[code] = 1; }
|
|
1071
|
+
acco[code] = rb_funcall(acco[code], rb_intern("*"), 1, ev);
|
|
1072
|
+
outo[addr] = acco[code];,
|
|
1073
|
+
if ( ! seen[code] ) { acco[code] = INT2FIX(1); seen[code] = 1; }
|
|
1074
|
+
outo[addr] = acco[code];
|
|
1075
|
+
);
|
|
1076
|
+
break;
|
|
1077
|
+
case GS_CUMMAX:
|
|
1078
|
+
/* No identity: seed from the first member, hold only once seen; a cell
|
|
1079
|
+
masked before any member stays UNDEF (empty-max contract). */
|
|
1080
|
+
GROUP_SCAN_OBJECT_WALK(
|
|
1081
|
+
if ( ! seen[code] ) { acco[code] = ev; seen[code] = 1; }
|
|
1082
|
+
else if ( ca_obj_extremum_replaces(ev, acco[code], rb_intern(">")) ) {
|
|
1083
|
+
acco[code] = ev;
|
|
1084
|
+
}
|
|
1085
|
+
outo[addr] = acco[code];,
|
|
1086
|
+
if ( seen[code] ) { outo[addr] = acco[code]; }
|
|
1087
|
+
else { MARK_OUT_UNDEF(addr); }
|
|
1088
|
+
);
|
|
1089
|
+
break;
|
|
1090
|
+
case GS_CUMMIN:
|
|
1091
|
+
GROUP_SCAN_OBJECT_WALK(
|
|
1092
|
+
if ( ! seen[code] ) { acco[code] = ev; seen[code] = 1; }
|
|
1093
|
+
else if ( ca_obj_extremum_replaces(ev, acco[code], rb_intern("<")) ) {
|
|
1094
|
+
acco[code] = ev;
|
|
1095
|
+
}
|
|
1096
|
+
outo[addr] = acco[code];,
|
|
1097
|
+
if ( seen[code] ) { outo[addr] = acco[code]; }
|
|
1098
|
+
else { MARK_OUT_UNDEF(addr); }
|
|
1099
|
+
);
|
|
1100
|
+
break;
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
return Qnil;
|
|
1104
|
+
}
|
|
1105
|
+
|
|
973
1106
|
static int
|
|
974
1107
|
group_scan_op_code (VALUE vop)
|
|
975
1108
|
{
|
|
@@ -979,7 +1112,7 @@ group_scan_op_code (VALUE vop)
|
|
|
979
1112
|
else if ( id == rb_intern("cummax") ) return GS_CUMMAX;
|
|
980
1113
|
else if ( id == rb_intern("cummin") ) return GS_CUMMIN;
|
|
981
1114
|
else if ( id == rb_intern("cumprod") ) return GS_CUMPROD;
|
|
982
|
-
rb_raise(rb_eArgError, "axis_group_scan: unsupported op :%
|
|
1115
|
+
rb_raise(rb_eArgError, "axis_group_scan: unsupported op :%"PRIsVALUE, rb_id2str(id));
|
|
983
1116
|
}
|
|
984
1117
|
|
|
985
1118
|
/* __axis_group_scan__(group_axes, bundles, op) — group-keyed segment scan of
|
|
@@ -1022,7 +1155,7 @@ rb_ca_axis_group_scan (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
1022
1155
|
GetCArray(self, src);
|
|
1023
1156
|
|
|
1024
1157
|
if ( src->ndim <= 0 ) {
|
|
1025
|
-
rb_raise(
|
|
1158
|
+
rb_raise(rb_eArgError, "axis_group_scan: scalar source");
|
|
1026
1159
|
}
|
|
1027
1160
|
|
|
1028
1161
|
/* --- group (slab) axes (same validation as reduce) --- */
|
|
@@ -1096,9 +1229,7 @@ rb_ca_axis_group_scan (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
1096
1229
|
size_t nbytes = (size_t) bundle_ca[bi]->elements * sizeof(int32_t);
|
|
1097
1230
|
VALUE vbuf = rb_str_tmp_new((long) nbytes);
|
|
1098
1231
|
rb_ary_push((VALUE) keep, vbuf);
|
|
1099
|
-
|
|
1100
|
-
memcpy(RSTRING_PTR(vbuf), bundle_ca[bi]->ptr, nbytes);
|
|
1101
|
-
ca_detach(bundle_ca[bi]);
|
|
1232
|
+
ca_copy_data(bundle_ca[bi], RSTRING_PTR(vbuf));
|
|
1102
1233
|
bundle_codes[bi] = (int32_t *) RSTRING_PTR(vbuf);
|
|
1103
1234
|
}
|
|
1104
1235
|
|
|
@@ -1160,7 +1291,7 @@ rb_ca_axis_group_scan (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
1160
1291
|
case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
|
|
1161
1292
|
case CA_FLOAT32: case CA_FLOAT64: case CA_OBJECT: break;
|
|
1162
1293
|
default:
|
|
1163
|
-
rb_raise(
|
|
1294
|
+
rb_raise(rb_eCADataTypeError,
|
|
1164
1295
|
"axis_group_scan: unsupported source data_type %d",
|
|
1165
1296
|
src->data_type);
|
|
1166
1297
|
}
|
|
@@ -1232,75 +1363,23 @@ rb_ca_axis_group_scan (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
1232
1363
|
double acc_init = ( op == GS_CUMPROD ) ? 1.0 : 0.0;
|
|
1233
1364
|
|
|
1234
1365
|
boolean8_t *omask = NULL;
|
|
1235
|
-
#define MARK_OUT_UNDEF(o) do { \
|
|
1236
|
-
if ( ! omask ) { \
|
|
1237
|
-
ca_create_mask(co); \
|
|
1238
|
-
omask = (boolean8_t *) co->mask->ptr; \
|
|
1239
|
-
} \
|
|
1240
|
-
omask[o] = 1; \
|
|
1241
|
-
} while (0)
|
|
1242
1366
|
|
|
1243
1367
|
if ( src->data_type == CA_OBJECT ) {
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
GROUP_SCAN_OBJECT_WALK(
|
|
1247
|
-
accn[code] += 1; outi[addr] = (int64_t) accn[code];,
|
|
1248
|
-
outi[addr] = (int64_t) accn[code];
|
|
1249
|
-
);
|
|
1250
|
-
}
|
|
1251
|
-
else { /* object running VALUE */
|
|
1252
|
-
VALUE *outo = (VALUE *) co->ptr;
|
|
1368
|
+
group_scan_object_t c;
|
|
1369
|
+
if ( op != GS_CUMCOUNT ) {
|
|
1253
1370
|
acco = ALLOCV_N(VALUE, h_acco, K_total);
|
|
1254
|
-
switch ( op ) {
|
|
1255
|
-
case GS_CUMSUM:
|
|
1256
|
-
/* Identity 0 (matching the core object cumsum): a group's acc is lazily
|
|
1257
|
-
seeded to 0 (Fixnum, so 0 + ev promotes to ev's class), so a cell
|
|
1258
|
-
masked before any present member holds 0 unmasked and an all-masked
|
|
1259
|
-
group yields 0 everywhere. seen doubles as the per-band init flag. */
|
|
1260
|
-
GROUP_SCAN_OBJECT_WALK(
|
|
1261
|
-
if ( ! seen[code] ) { acco[code] = INT2FIX(0); seen[code] = 1; }
|
|
1262
|
-
acco[code] = rb_funcall(acco[code], rb_intern("+"), 1, ev);
|
|
1263
|
-
outo[addr] = acco[code];,
|
|
1264
|
-
if ( ! seen[code] ) { acco[code] = INT2FIX(0); seen[code] = 1; }
|
|
1265
|
-
outo[addr] = acco[code];
|
|
1266
|
-
);
|
|
1267
|
-
break;
|
|
1268
|
-
case GS_CUMPROD:
|
|
1269
|
-
/* Identity 1, same lazy-init as cumsum. */
|
|
1270
|
-
GROUP_SCAN_OBJECT_WALK(
|
|
1271
|
-
if ( ! seen[code] ) { acco[code] = INT2FIX(1); seen[code] = 1; }
|
|
1272
|
-
acco[code] = rb_funcall(acco[code], rb_intern("*"), 1, ev);
|
|
1273
|
-
outo[addr] = acco[code];,
|
|
1274
|
-
if ( ! seen[code] ) { acco[code] = INT2FIX(1); seen[code] = 1; }
|
|
1275
|
-
outo[addr] = acco[code];
|
|
1276
|
-
);
|
|
1277
|
-
break;
|
|
1278
|
-
case GS_CUMMAX:
|
|
1279
|
-
/* No identity: seed from the first member, hold only once seen; a cell
|
|
1280
|
-
masked before any member stays UNDEF (empty-max contract). */
|
|
1281
|
-
GROUP_SCAN_OBJECT_WALK(
|
|
1282
|
-
if ( ! seen[code] ) { acco[code] = ev; seen[code] = 1; }
|
|
1283
|
-
else if ( NUM2INT(rb_funcall(ev, rb_intern("<=>"), 1, acco[code])) > 0 ) {
|
|
1284
|
-
acco[code] = ev;
|
|
1285
|
-
}
|
|
1286
|
-
outo[addr] = acco[code];,
|
|
1287
|
-
if ( seen[code] ) { outo[addr] = acco[code]; }
|
|
1288
|
-
else { MARK_OUT_UNDEF(addr); }
|
|
1289
|
-
);
|
|
1290
|
-
break;
|
|
1291
|
-
case GS_CUMMIN:
|
|
1292
|
-
GROUP_SCAN_OBJECT_WALK(
|
|
1293
|
-
if ( ! seen[code] ) { acco[code] = ev; seen[code] = 1; }
|
|
1294
|
-
else if ( NUM2INT(rb_funcall(ev, rb_intern("<=>"), 1, acco[code])) < 0 ) {
|
|
1295
|
-
acco[code] = ev;
|
|
1296
|
-
}
|
|
1297
|
-
outo[addr] = acco[code];,
|
|
1298
|
-
if ( seen[code] ) { outo[addr] = acco[code]; }
|
|
1299
|
-
else { MARK_OUT_UNDEF(addr); }
|
|
1300
|
-
);
|
|
1301
|
-
break;
|
|
1302
|
-
}
|
|
1303
1371
|
}
|
|
1372
|
+
c.ca = ca; c.co = co; c.op = op;
|
|
1373
|
+
c.axes = axes; c.ngroup = ngroup;
|
|
1374
|
+
c.n_bundles = n_bundles; c.bundle_codes = bundle_codes;
|
|
1375
|
+
c.bundle_k = bundle_k; c.bundle_placeval = bundle_placeval;
|
|
1376
|
+
c.bundle_nconsumed = bundle_nconsumed;
|
|
1377
|
+
c.bundle_slot = bundle_slot; c.bundle_cstride = bundle_cstride;
|
|
1378
|
+
c.grstride = grstride; c.band_addr = band_addr; c.K_total = K_total;
|
|
1379
|
+
c.sw_code = sw_code; c.sw_doff = sw_doff;
|
|
1380
|
+
c.sw_moff = sw_moff; c.sw_addr = sw_addr;
|
|
1381
|
+
c.accn = accn; c.seen = seen; c.acco = acco;
|
|
1382
|
+
ca_iter_ensure(1, &c.st, group_scan_object_body, (VALUE) &c);
|
|
1304
1383
|
}
|
|
1305
1384
|
else { /* native data type dispatch */
|
|
1306
1385
|
switch ( op ) {
|
|
@@ -1330,7 +1409,6 @@ rb_ca_axis_group_scan (VALUE self, VALUE vgaxes, VALUE vbundles, VALUE vop)
|
|
|
1330
1409
|
break;
|
|
1331
1410
|
}
|
|
1332
1411
|
}
|
|
1333
|
-
#undef MARK_OUT_UNDEF
|
|
1334
1412
|
|
|
1335
1413
|
ALLOCV_END(h_band2); ALLOCV_END(h_code); ALLOCV_END(h_doff);
|
|
1336
1414
|
ALLOCV_END(h_moff); ALLOCV_END(h_addr); ALLOCV_END(h_accd);
|
data/ext/ca_binop_dispatch.c
CHANGED
|
@@ -27,39 +27,56 @@
|
|
|
27
27
|
/* vv kernel lookup */
|
|
28
28
|
/* ------------------------------------------------------------------- */
|
|
29
29
|
|
|
30
|
+
/* The kernel table of each op id. The eager operators hold the tables
|
|
31
|
+
themselves; ca_binop_op_id_of_table maps one back to its op id, so that
|
|
32
|
+
both ask ca_binop_is_trapping the same question. */
|
|
33
|
+
static ca_binop_func_t * const ca_binop_tables[CA_BINOP_COUNT] = {
|
|
34
|
+
[CA_BINOP_ADD] = ca_binop_add,
|
|
35
|
+
[CA_BINOP_SUB] = ca_binop_sub,
|
|
36
|
+
[CA_BINOP_MUL] = ca_binop_mul,
|
|
37
|
+
[CA_BINOP_DIV] = ca_binop_div,
|
|
38
|
+
[CA_BINOP_POW] = ca_binop_power,
|
|
39
|
+
[CA_BINOP_BIT_AND] = ca_binop_bit_and_i,
|
|
40
|
+
[CA_BINOP_BIT_OR] = ca_binop_bit_or_i,
|
|
41
|
+
[CA_BINOP_BIT_XOR] = ca_binop_bit_xor_i,
|
|
42
|
+
[CA_BINOP_BIT_LSHIFT]= ca_binop_bit_lshift,
|
|
43
|
+
[CA_BINOP_BIT_RSHIFT]= ca_binop_bit_rshift,
|
|
44
|
+
[CA_BINOP_MOD] = ca_binop_mod,
|
|
45
|
+
[CA_BINOP_QUO] = ca_binop_quo_i,
|
|
46
|
+
[CA_BINOP_RCP_MUL] = ca_binop_rcp_mul,
|
|
47
|
+
[CA_BINOP_IPOWER] = ca_binop_ipower,
|
|
48
|
+
[CA_BINOP_COPYSIGN] = ca_binop_copysign,
|
|
49
|
+
[CA_BINOP_LOGADDEXP] = ca_binop_logaddexp,
|
|
50
|
+
[CA_BINOP_NEXTAFTER] = ca_binop_nextafter,
|
|
51
|
+
[CA_BINOP_FMOD] = ca_binop_fmod,
|
|
52
|
+
[CA_BINOP_ATAN2] = ca_binop_atan2,
|
|
53
|
+
[CA_BINOP_HYPOT] = ca_binop_hypot,
|
|
54
|
+
[CA_BINOP_PMAX] = ca_binop_pmax,
|
|
55
|
+
[CA_BINOP_PMIN] = ca_binop_pmin,
|
|
56
|
+
[CA_BINOP_MAXIMUM] = ca_binop_maximum,
|
|
57
|
+
[CA_BINOP_MINIMUM] = ca_binop_minimum,
|
|
58
|
+
[CA_BINOP_AND] = ca_binop_and,
|
|
59
|
+
[CA_BINOP_OR] = ca_binop_or,
|
|
60
|
+
[CA_BINOP_XOR] = ca_binop_xor,
|
|
61
|
+
};
|
|
62
|
+
|
|
30
63
|
ca_binop_func_t
|
|
31
64
|
ca_binop_kernel_lookup_vv (uint16_t op_id, int8_t common_dt)
|
|
32
65
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
case CA_BINOP_QUO: return ca_binop_quo_i [common_dt];
|
|
46
|
-
case CA_BINOP_RCP_MUL: return ca_binop_rcp_mul [common_dt];
|
|
47
|
-
case CA_BINOP_IPOWER: return ca_binop_ipower [common_dt];
|
|
48
|
-
case CA_BINOP_COPYSIGN: return ca_binop_copysign [common_dt];
|
|
49
|
-
case CA_BINOP_LOGADDEXP: return ca_binop_logaddexp [common_dt];
|
|
50
|
-
case CA_BINOP_NEXTAFTER: return ca_binop_nextafter [common_dt];
|
|
51
|
-
case CA_BINOP_FMOD: return ca_binop_fmod [common_dt];
|
|
52
|
-
case CA_BINOP_ATAN2: return ca_binop_atan2 [common_dt];
|
|
53
|
-
case CA_BINOP_HYPOT: return ca_binop_hypot [common_dt];
|
|
54
|
-
case CA_BINOP_PMAX: return ca_binop_pmax [common_dt];
|
|
55
|
-
case CA_BINOP_PMIN: return ca_binop_pmin [common_dt];
|
|
56
|
-
case CA_BINOP_MAXIMUM: return ca_binop_maximum [common_dt];
|
|
57
|
-
case CA_BINOP_MINIMUM: return ca_binop_minimum [common_dt];
|
|
58
|
-
case CA_BINOP_AND: return ca_binop_and [common_dt];
|
|
59
|
-
case CA_BINOP_OR: return ca_binop_or [common_dt];
|
|
60
|
-
case CA_BINOP_XOR: return ca_binop_xor [common_dt];
|
|
61
|
-
default: return NULL;
|
|
66
|
+
if ( op_id >= CA_BINOP_COUNT || ! ca_binop_tables[op_id] ) return NULL;
|
|
67
|
+
return ca_binop_tables[op_id][common_dt];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* The op id whose kernel table is `table`, or -1 for a table no op id
|
|
71
|
+
names. */
|
|
72
|
+
int
|
|
73
|
+
ca_binop_op_id_of_table (ca_binop_func_t table[])
|
|
74
|
+
{
|
|
75
|
+
int op_id;
|
|
76
|
+
for ( op_id = 0; op_id < CA_BINOP_COUNT; op_id++ ) {
|
|
77
|
+
if ( ca_binop_tables[op_id] == table ) return op_id;
|
|
62
78
|
}
|
|
79
|
+
return -1;
|
|
63
80
|
}
|
|
64
81
|
|
|
65
82
|
/* ------------------------------------------------------------------- */
|
|
@@ -106,10 +123,12 @@ ca_binop_kernel_input_data_types (uint16_t op_id, int8_t l_dt, int8_t r_dt,
|
|
|
106
123
|
int
|
|
107
124
|
ca_binop_is_trapping (uint16_t op_id, int8_t common_dt)
|
|
108
125
|
{
|
|
109
|
-
/*
|
|
110
|
-
DIV
|
|
111
|
-
|
|
126
|
+
/* An object cell calls Ruby, which can raise for any op. Integer
|
|
127
|
+
DIV / MOD / QUO / FMOD / RCP_MUL raise on a zero divisor, and POW /
|
|
128
|
+
IPOWER on zero to a negative power. Float division returns NaN/Inf
|
|
129
|
+
and does not trap. */
|
|
112
130
|
int is_integer = ( common_dt >= CA_INT8 && common_dt <= CA_UINT64 );
|
|
131
|
+
if ( common_dt == CA_OBJECT ) return 1;
|
|
113
132
|
if ( ! is_integer ) return 0;
|
|
114
133
|
|
|
115
134
|
switch (op_id) {
|
|
@@ -117,6 +136,9 @@ ca_binop_is_trapping (uint16_t op_id, int8_t common_dt)
|
|
|
117
136
|
case CA_BINOP_MOD:
|
|
118
137
|
case CA_BINOP_QUO:
|
|
119
138
|
case CA_BINOP_FMOD:
|
|
139
|
+
case CA_BINOP_RCP_MUL:
|
|
140
|
+
case CA_BINOP_POW:
|
|
141
|
+
case CA_BINOP_IPOWER:
|
|
120
142
|
return 1;
|
|
121
143
|
default:
|
|
122
144
|
return 0;
|
data/ext/ca_binop_dispatch.h
CHANGED
|
@@ -148,5 +148,6 @@ void ca_binop_kernel_input_data_types (uint16_t op_id, int8_t l_dt, int8_t r_dt,
|
|
|
148
148
|
a slab mask to the kernel so masked cells are skipped (otherwise
|
|
149
149
|
masked-zero divisors crash with SIGFPE). See §3.4 rev3. */
|
|
150
150
|
int ca_binop_is_trapping (uint16_t op_id, int8_t common_dt);
|
|
151
|
+
int ca_binop_op_id_of_table (ca_binop_func_t table[]);
|
|
151
152
|
|
|
152
153
|
#endif /* CA_BINOP_DISPATCH_H */
|