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_obj_bincmp.c
CHANGED
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
Dispatch by data_type:
|
|
12
12
|
numeric (i8..f64, +complex) -> ca_bincmp_<op>_<type> kernel
|
|
13
|
-
|
|
13
|
+
fixlen -> ca_bincmp_<op>_fixlen (memcmp)
|
|
14
|
+
object -> ca_bincmp_<op>_VALUE
|
|
14
15
|
|
|
15
16
|
CAREFUL: the binop in-place trick (= pull left into the output
|
|
16
17
|
buffer) is structurally unavailable here — the output is
|
|
@@ -33,7 +34,6 @@
|
|
|
33
34
|
|
|
34
35
|
extern VALUE ca_broadcast_view (VALUE src, int8_t ndim,
|
|
35
36
|
ca_size_t *target_dim);
|
|
36
|
-
extern VALUE ca_lazy_wrap_scalar (VALUE other, CArray *self_ca);
|
|
37
37
|
extern void *ca_lazy_arena_acquire (ca_size_t bytes);
|
|
38
38
|
extern void ca_lazy_arena_release (void *ptr);
|
|
39
39
|
|
|
@@ -78,6 +78,11 @@ typedef struct CABinCmp {
|
|
|
78
78
|
`eps` name is retained to keep the
|
|
79
79
|
`__eps__` Ruby accessor stable across
|
|
80
80
|
the dual purpose. */
|
|
81
|
+
int8_t sign_fix; /* 0, or the side (1 left, 2 right) of an
|
|
82
|
+
int64 operand compared with a uint64 one:
|
|
83
|
+
the kernel compares both as uint64 and
|
|
84
|
+
the cells where it is negative are
|
|
85
|
+
answered after */
|
|
81
86
|
CArray *operands[2]; /* {left, right}; what parents points at */
|
|
82
87
|
} CABinCmp;
|
|
83
88
|
|
|
@@ -143,6 +148,15 @@ ca_bincmp_setup (CABinCmp *ca, CArray *left, CArray *right, uint16_t op_id,
|
|
|
143
148
|
ca->right_is_scalar = ( right->elements == 1 && left->elements > 1 ) ? 1 : 0;
|
|
144
149
|
/* Builder has already cast both operands to common data_type. */
|
|
145
150
|
ca->common_dt = left->data_type;
|
|
151
|
+
ca->sign_fix = 0;
|
|
152
|
+
if ( left->data_type == CA_INT64 && right->data_type == CA_UINT64 ) {
|
|
153
|
+
ca->common_dt = CA_UINT64;
|
|
154
|
+
ca->sign_fix = 1;
|
|
155
|
+
}
|
|
156
|
+
else if ( left->data_type == CA_UINT64 && right->data_type == CA_INT64 ) {
|
|
157
|
+
ca->common_dt = CA_UINT64;
|
|
158
|
+
ca->sign_fix = 2;
|
|
159
|
+
}
|
|
146
160
|
ca->eps = eps;
|
|
147
161
|
ca->operands[0] = left;
|
|
148
162
|
ca->operands[1] = right;
|
|
@@ -223,25 +237,6 @@ ca_bincmp_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
|
223
237
|
ca_bincmp_func_xfer_stride(ca, starts, counts, strides, data, CA_XFER_GET);
|
|
224
238
|
}
|
|
225
239
|
|
|
226
|
-
static void
|
|
227
|
-
ca_bincmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
228
|
-
void *data, int dir)
|
|
229
|
-
{
|
|
230
|
-
CABinCmp *ca = (CABinCmp *) ap;
|
|
231
|
-
ca_size_t i;
|
|
232
|
-
char *out = (char *) data;
|
|
233
|
-
|
|
234
|
-
if ( dir != CA_XFER_GET ) {
|
|
235
|
-
rb_raise(rb_eRuntimeError, "CABinCmp is read-only (xfer_addrs PUT)");
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
for ( i = 0; i < n; i++ ) {
|
|
239
|
-
ca_size_t idx[CA_RANK_MAX];
|
|
240
|
-
ca_addr2index((CArray *)ca, addrs[i], idx);
|
|
241
|
-
ca_bincmp_func_xfer_index(ca, idx, out + i, CA_XFER_GET);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
240
|
/* Test / observability counters — bumped from the xfer_stride hot
|
|
246
241
|
path so specs can assert scratch acquisition and leaf in-place
|
|
247
242
|
hit rates without materialising the view. */
|
|
@@ -296,59 +291,37 @@ ca_bincmp_try_leaf_inplace (CArray *op, int8_t common_dt,
|
|
|
296
291
|
return 1;
|
|
297
292
|
}
|
|
298
293
|
|
|
294
|
+
/* Evaluate the cells a request names into `data` (packed, n cells). */
|
|
299
295
|
static void
|
|
300
|
-
|
|
301
|
-
ca_size_t *strides, void *data, int dir)
|
|
296
|
+
ca_bincmp_eval (CABinCmp *bc, const ca_lazy_req_t *req, void *data)
|
|
302
297
|
{
|
|
303
|
-
|
|
304
|
-
ca_size_t slab_n;
|
|
298
|
+
ca_size_t slab_n = req->n;
|
|
305
299
|
int8_t k;
|
|
306
300
|
void *left_scratch, *right_scratch;
|
|
307
|
-
ca_size_t
|
|
308
|
-
ca_size_t operand_strides[CA_RANK_MAX];
|
|
301
|
+
ca_size_t left_bytes, right_bytes;
|
|
309
302
|
ca_size_t right_step;
|
|
310
303
|
int is_contig;
|
|
311
304
|
int left_is_inplace = 0; /* skip release for leaf-opt path */
|
|
312
305
|
int right_is_inplace = 0;
|
|
313
306
|
|
|
314
|
-
if ( dir != CA_XFER_GET ) {
|
|
315
|
-
rb_raise(rb_eRuntimeError, "CABinCmp is read-only (xfer_stride PUT)");
|
|
316
|
-
}
|
|
317
307
|
ca_bincmp_materialise_call_count++;
|
|
318
308
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
/* An operand cell is operand_bytes wide where this view's is one byte
|
|
325
|
-
(CA_BOOLEAN), so the caller's strides cannot be handed to the operand
|
|
326
|
-
pull the way a binop hands them on -- they have to be restated at the
|
|
327
|
-
operand's cell size. strides[k] / bytes is the index step, which is
|
|
328
|
-
what the two spaces share.
|
|
309
|
+
/* An operand's own bytes, not ca_sizeof[common_dt]: a fixlen cell has no
|
|
310
|
+
width in ca_sizeof, and the two fixlen operands may differ in width. */
|
|
311
|
+
left_bytes = bc->parent->bytes;
|
|
312
|
+
right_bytes = bc->right->bytes;
|
|
329
313
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
{
|
|
335
|
-
ca_size_t native = bc->bytes;
|
|
336
|
-
is_contig = 1;
|
|
337
|
-
for ( k = bc->ndim - 1; k >= 0; k-- ) {
|
|
338
|
-
operand_strides[k] = strides[k] / bc->bytes * operand_bytes;
|
|
339
|
-
if ( strides[k] != native ) {
|
|
340
|
-
is_contig = 0;
|
|
341
|
-
}
|
|
342
|
-
native *= bc->dim[k];
|
|
343
|
-
}
|
|
344
|
-
}
|
|
314
|
+
/* The leaf in-place path reads an operand's own buffer, which holds the
|
|
315
|
+
wanted cells in the order the kernel reads them only for the row-major
|
|
316
|
+
slab that xfer_all and attach send. */
|
|
317
|
+
is_contig = ca_lazy_req_is_packed(req, bc);
|
|
345
318
|
|
|
346
319
|
/* === 1. pull LEFT (leaf in-place read or arena scratch) === */
|
|
347
320
|
{
|
|
348
321
|
char *left_inplace = NULL;
|
|
349
322
|
if ( is_contig &&
|
|
350
323
|
ca_bincmp_try_leaf_inplace(bc->parent, bc->common_dt,
|
|
351
|
-
starts, counts,
|
|
324
|
+
req->starts, req->counts, left_bytes,
|
|
352
325
|
&left_inplace) ) {
|
|
353
326
|
/* Leaf-opt path: use parent->ptr + byte_offset directly. */
|
|
354
327
|
left_scratch = left_inplace;
|
|
@@ -358,10 +331,9 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
358
331
|
else {
|
|
359
332
|
left_scratch = ( bc->common_dt == CA_OBJECT )
|
|
360
333
|
? ca_lazy_arena_acquire_object(slab_n)
|
|
361
|
-
: ca_lazy_arena_acquire(slab_n *
|
|
334
|
+
: ca_lazy_arena_acquire(slab_n * left_bytes);
|
|
362
335
|
ca_bincmp_scratch_acquire_count++;
|
|
363
|
-
|
|
364
|
-
CA_XFER_GET);
|
|
336
|
+
ca_lazy_req_pull(bc->parent, req, left_scratch, CA_XFER_GET);
|
|
365
337
|
}
|
|
366
338
|
}
|
|
367
339
|
|
|
@@ -378,7 +350,7 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
378
350
|
for ( k = 0; k < bc->right->ndim; k++ ) one_counts[k] = 1;
|
|
379
351
|
|
|
380
352
|
if ( ca_bincmp_try_leaf_inplace(bc->right, bc->common_dt,
|
|
381
|
-
one_starts, one_counts,
|
|
353
|
+
one_starts, one_counts, right_bytes,
|
|
382
354
|
&right_inplace) ) {
|
|
383
355
|
right_scratch = right_inplace;
|
|
384
356
|
right_is_inplace = 1;
|
|
@@ -386,10 +358,10 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
386
358
|
}
|
|
387
359
|
else {
|
|
388
360
|
ca_size_t one_strides[CA_RANK_MAX];
|
|
389
|
-
for ( k = 0; k < bc->right->ndim; k++ ) one_strides[k] =
|
|
361
|
+
for ( k = 0; k < bc->right->ndim; k++ ) one_strides[k] = right_bytes;
|
|
390
362
|
right_scratch = ( bc->common_dt == CA_OBJECT )
|
|
391
363
|
? ca_lazy_arena_acquire_object(1)
|
|
392
|
-
: ca_lazy_arena_acquire(
|
|
364
|
+
: ca_lazy_arena_acquire(right_bytes);
|
|
393
365
|
ca_bincmp_scratch_acquire_count++;
|
|
394
366
|
ca_xfer_stride(bc->right, one_starts, one_counts, one_strides,
|
|
395
367
|
right_scratch, CA_XFER_GET);
|
|
@@ -401,7 +373,7 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
401
373
|
char *right_inplace = NULL;
|
|
402
374
|
if ( is_contig &&
|
|
403
375
|
ca_bincmp_try_leaf_inplace(bc->right, bc->common_dt,
|
|
404
|
-
starts, counts,
|
|
376
|
+
req->starts, req->counts, right_bytes,
|
|
405
377
|
&right_inplace) ) {
|
|
406
378
|
right_scratch = right_inplace;
|
|
407
379
|
right_is_inplace = 1;
|
|
@@ -410,10 +382,9 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
410
382
|
else {
|
|
411
383
|
right_scratch = ( bc->common_dt == CA_OBJECT )
|
|
412
384
|
? ca_lazy_arena_acquire_object(slab_n)
|
|
413
|
-
: ca_lazy_arena_acquire(slab_n *
|
|
385
|
+
: ca_lazy_arena_acquire(slab_n * right_bytes);
|
|
414
386
|
ca_bincmp_scratch_acquire_count++;
|
|
415
|
-
|
|
416
|
-
CA_XFER_GET);
|
|
387
|
+
ca_lazy_req_pull(bc->right, req, right_scratch, CA_XFER_GET);
|
|
417
388
|
}
|
|
418
389
|
right_step = 1;
|
|
419
390
|
}
|
|
@@ -423,14 +394,16 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
423
394
|
* Kernel signature (ext/carray.h):
|
|
424
395
|
* fn(n, m, ptr1, b1, i1, ptr2, b2, i2, ptr3, b3, i3)
|
|
425
396
|
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
397
|
+
* The `b*` args are the cell widths. The typed kernels step by
|
|
398
|
+
* sizeof(T) and ignore them; the fixlen kernels step and compare by
|
|
399
|
+
* them.
|
|
429
400
|
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
401
|
+
* m=NULL (= SIMD fast path) except for object operands, whose cells
|
|
402
|
+
* call Ruby: those skip the masked cells, as the eager comparison
|
|
403
|
+
* does. The output mask comes from create_mask.
|
|
432
404
|
*/
|
|
433
405
|
{
|
|
406
|
+
boolean8_t *slab_mask = NULL;
|
|
434
407
|
ca_bincmp_func_t fn = ca_bincmp_kernel_lookup(bc->op_id, bc->common_dt);
|
|
435
408
|
if ( fn == NULL ) {
|
|
436
409
|
if ( ! right_is_inplace ) ca_lazy_arena_release(right_scratch);
|
|
@@ -439,17 +412,59 @@ ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
439
412
|
"CABinCmp: kernel not implemented (op_id=%u data_type=%d)",
|
|
440
413
|
(unsigned) bc->op_id, (int) bc->common_dt);
|
|
441
414
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
415
|
+
if ( bc->common_dt == CA_OBJECT ) {
|
|
416
|
+
slab_mask = ca_lazy_req_mask(req, 2, bc->operands);
|
|
417
|
+
}
|
|
418
|
+
fn(slab_n, slab_mask,
|
|
419
|
+
(char *) left_scratch, left_bytes, 1,
|
|
420
|
+
(char *) right_scratch, right_bytes, right_step,
|
|
421
|
+
(char *) data, 1, 1,
|
|
446
422
|
bc->eps); /* Runtime tolerance for IS_CLOSE / IS_EQUIV. */
|
|
423
|
+
if ( slab_mask ) ca_lazy_arena_release(slab_mask);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if ( bc->sign_fix ) {
|
|
427
|
+
const int64_t *sp = (const int64_t *)
|
|
428
|
+
( bc->sign_fix == 1 ? left_scratch : right_scratch );
|
|
429
|
+
ca_size_t step = ( bc->sign_fix == 1 ) ? 1 : right_step;
|
|
430
|
+
boolean8_t answer =
|
|
431
|
+
(boolean8_t) ca_bincmp_answer_when_negative(bc->op_id, bc->sign_fix);
|
|
432
|
+
ca_size_t i;
|
|
433
|
+
for ( i = 0; i < slab_n; i++ ) {
|
|
434
|
+
if ( sp[i * step] < 0 ) ((boolean8_t *) data)[i] = answer;
|
|
435
|
+
}
|
|
447
436
|
}
|
|
448
437
|
|
|
449
438
|
if ( ! right_is_inplace ) ca_lazy_arena_release(right_scratch);
|
|
450
439
|
if ( ! left_is_inplace ) ca_lazy_arena_release(left_scratch);
|
|
451
440
|
}
|
|
452
441
|
|
|
442
|
+
static void
|
|
443
|
+
ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
444
|
+
ca_size_t *strides, void *data, int dir)
|
|
445
|
+
{
|
|
446
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
447
|
+
ca_lazy_req_t req;
|
|
448
|
+
if ( dir != CA_XFER_GET ) {
|
|
449
|
+
rb_raise(rb_eRuntimeError, "CABinCmp is read-only (xfer_stride PUT)");
|
|
450
|
+
}
|
|
451
|
+
ca_lazy_req_region(&req, ap, starts, counts, strides);
|
|
452
|
+
ca_bincmp_eval((CABinCmp *) ap, &req, data);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/* An address list is evaluated in one pass, as a region is. */
|
|
456
|
+
static void
|
|
457
|
+
ca_bincmp_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
458
|
+
void *data, int dir)
|
|
459
|
+
{
|
|
460
|
+
ca_lazy_req_t req;
|
|
461
|
+
if ( dir != CA_XFER_GET ) {
|
|
462
|
+
rb_raise(rb_eRuntimeError, "CABinCmp is read-only (xfer_addrs PUT)");
|
|
463
|
+
}
|
|
464
|
+
ca_lazy_req_addrs(&req, n, addrs);
|
|
465
|
+
ca_bincmp_eval((CABinCmp *) ap, &req, data);
|
|
466
|
+
}
|
|
467
|
+
|
|
453
468
|
static void
|
|
454
469
|
ca_bincmp_func_xfer_all (void *ap, void *data, int dir)
|
|
455
470
|
{
|
|
@@ -513,45 +528,12 @@ ca_bincmp_func_fill_data (void *ap, void *ptr)
|
|
|
513
528
|
rb_raise(rb_eRuntimeError, "CABinCmp is read-only (fill_data)");
|
|
514
529
|
}
|
|
515
530
|
|
|
516
|
-
/* mask = left.mask | right.mask,
|
|
517
|
-
Mirrors CABinOp's create_mask policy. */
|
|
531
|
+
/* mask = left.mask | right.mask, computed on each read (CAMaskOfOperands). */
|
|
518
532
|
static void
|
|
519
533
|
ca_bincmp_func_create_mask (void *ap)
|
|
520
534
|
{
|
|
521
535
|
CABinCmp *bc = (CABinCmp *) ap;
|
|
522
|
-
CArray *
|
|
523
|
-
CArray *r = bc->right;
|
|
524
|
-
CArray *lm = NULL, *rm = NULL;
|
|
525
|
-
boolean8_t *dst;
|
|
526
|
-
ca_size_t i, n;
|
|
527
|
-
int has_l, has_r;
|
|
528
|
-
|
|
529
|
-
has_l = ca_has_mask(l);
|
|
530
|
-
has_r = ca_has_mask(r);
|
|
531
|
-
if ( ! has_l && ! has_r ) return;
|
|
532
|
-
|
|
533
|
-
if ( has_l ) lm = l->mask;
|
|
534
|
-
if ( has_r ) rm = r->mask;
|
|
535
|
-
|
|
536
|
-
bc->mask = (CArray *) carray_new(CA_BOOLEAN, bc->ndim, bc->dim, 0, NULL);
|
|
537
|
-
dst = (boolean8_t *) bc->mask->ptr;
|
|
538
|
-
n = bc->elements;
|
|
539
|
-
|
|
540
|
-
if ( has_l ) ca_attach(lm);
|
|
541
|
-
if ( has_r ) ca_attach(rm);
|
|
542
|
-
|
|
543
|
-
for ( i = 0; i < n; i++ ) {
|
|
544
|
-
boolean8_t a = has_l ? ((boolean8_t *) lm->ptr)[i] : 0;
|
|
545
|
-
boolean8_t b = 0;
|
|
546
|
-
if ( has_r ) {
|
|
547
|
-
ca_size_t ri = bc->right_is_scalar ? 0 : i;
|
|
548
|
-
b = ((boolean8_t *) rm->ptr)[ri];
|
|
549
|
-
}
|
|
550
|
-
dst[i] = (boolean8_t)( a | b );
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if ( has_l ) ca_detach(lm);
|
|
554
|
-
if ( has_r ) ca_detach(rm);
|
|
536
|
+
bc->mask = ca_lazy_operation_mask((CArray *) bc, CA_LAZY_MASK_OR);
|
|
555
537
|
}
|
|
556
538
|
|
|
557
539
|
ca_operation_function_t ca_bincmp_func = {
|
|
@@ -605,26 +587,58 @@ rb_ca_bincmp_new (VALUE l_cary, VALUE r_cary, uint16_t op_id, double eps)
|
|
|
605
587
|
return obj;
|
|
606
588
|
}
|
|
607
589
|
|
|
590
|
+
/* An operand taken to data type dt: a scalar by value, an array through a
|
|
591
|
+
cast view so the expression stays lazy. */
|
|
592
|
+
static VALUE
|
|
593
|
+
ca_bincmp_cast_operand (VALUE v, int8_t dt)
|
|
594
|
+
{
|
|
595
|
+
CArray *ca;
|
|
596
|
+
TypedData_Get_Struct(v, CArray, &carray_data_type, ca);
|
|
597
|
+
if ( ca->data_type == dt ) return v;
|
|
598
|
+
if ( rb_obj_is_cscalar(v) ) {
|
|
599
|
+
return rb_funcall(v, rb_intern("to_type"), 1, INT2NUM(dt));
|
|
600
|
+
}
|
|
601
|
+
return rb_funcall(rb_const_get(rb_cObject, rb_intern("CAMonOp")),
|
|
602
|
+
rb_intern("__build__"), 2,
|
|
603
|
+
v, INT2NUM(CA_MONOP_CAST_BASE + dt));
|
|
604
|
+
}
|
|
605
|
+
|
|
608
606
|
VALUE
|
|
609
607
|
rb_ca_bincmp_build (VALUE l_cary, VALUE r_cary, uint16_t op_id, double eps)
|
|
610
608
|
{
|
|
611
609
|
CArray *l, *r;
|
|
612
610
|
int8_t l_in_dt, r_in_dt;
|
|
611
|
+
int signed_side = 0;
|
|
613
612
|
volatile VALUE l_resolved, r_resolved;
|
|
614
613
|
|
|
615
614
|
l_resolved = collapse_marker(l_cary);
|
|
616
615
|
r_resolved = collapse_marker(r_cary);
|
|
617
616
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
617
|
+
switch ( ca_bincmp_integer_prepare(&l_resolved, &r_resolved, op_id,
|
|
618
|
+
&signed_side) ) {
|
|
619
|
+
case 1: return rb_ca_bincmp_build(l_resolved, l_resolved, CA_BINCMP_EQ, eps);
|
|
620
|
+
case 2: return rb_ca_bincmp_build(l_resolved, l_resolved, CA_BINCMP_NE, eps);
|
|
621
|
+
case 3:
|
|
622
|
+
/* The unsigned operand goes to uint64 and the signed one to int64;
|
|
623
|
+
ca_bincmp_setup reads that pair as a comparison to correct. */
|
|
624
|
+
l_resolved = ca_bincmp_cast_operand(l_resolved,
|
|
625
|
+
( signed_side == 1 ) ? CA_INT64 : CA_UINT64);
|
|
626
|
+
r_resolved = ca_bincmp_cast_operand(r_resolved,
|
|
627
|
+
( signed_side == 2 ) ? CA_INT64 : CA_UINT64);
|
|
628
|
+
break;
|
|
623
629
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
630
|
+
|
|
631
|
+
/* A scalar beside the array (a Ruby value or a CScalar) is wrapped and
|
|
632
|
+
promoted as the eager comparison does it. */
|
|
633
|
+
if ( ! rb_obj_is_carray(l_resolved) || ! rb_obj_is_carray(r_resolved) ||
|
|
634
|
+
rb_obj_is_cscalar(l_resolved) || rb_obj_is_cscalar(r_resolved) ) {
|
|
635
|
+
int l_scalar = ! rb_obj_is_carray(l_resolved) || rb_obj_is_cscalar(l_resolved);
|
|
636
|
+
int r_scalar = ! rb_obj_is_carray(r_resolved) || rb_obj_is_cscalar(r_resolved);
|
|
637
|
+
if ( ! signed_side ) {
|
|
638
|
+
rb_ca_cast_self_or_other(&l_resolved, &r_resolved);
|
|
639
|
+
}
|
|
640
|
+
l_resolved = ca_lazy_settle_scalar(l_resolved, l_scalar);
|
|
641
|
+
r_resolved = ca_lazy_settle_scalar(r_resolved, r_scalar);
|
|
628
642
|
}
|
|
629
643
|
|
|
630
644
|
TypedData_Get_Struct(l_resolved, CArray, &carray_data_type, l);
|
|
@@ -633,6 +647,10 @@ rb_ca_bincmp_build (VALUE l_cary, VALUE r_cary, uint16_t op_id, double eps)
|
|
|
633
647
|
/* Cast both operands to the common data_type. */
|
|
634
648
|
ca_bincmp_kernel_input_data_types(op_id, l->data_type, r->data_type,
|
|
635
649
|
&l_in_dt, &r_in_dt);
|
|
650
|
+
if ( signed_side ) {
|
|
651
|
+
l_in_dt = l->data_type;
|
|
652
|
+
r_in_dt = r->data_type;
|
|
653
|
+
}
|
|
636
654
|
|
|
637
655
|
if ( l_in_dt != l->data_type ) {
|
|
638
656
|
VALUE cast_op = INT2NUM(CA_MONOP_CAST_BASE + l_in_dt);
|
|
@@ -655,10 +673,10 @@ rb_ca_bincmp_build (VALUE l_cary, VALUE r_cary, uint16_t op_id, double eps)
|
|
|
655
673
|
TypedData_Get_Struct(r_resolved, CArray, &carray_data_type, r);
|
|
656
674
|
|
|
657
675
|
if ( l->elements != r->elements ) {
|
|
658
|
-
if ( r->elements == 1
|
|
676
|
+
if ( r->elements == 1 ) {
|
|
659
677
|
/* CScalar right: handled via right_is_scalar */
|
|
660
678
|
}
|
|
661
|
-
else if ( l->elements == 1
|
|
679
|
+
else if ( l->elements == 1 ) {
|
|
662
680
|
/* Comparison ops commute under negation (LT/GT/LE/GE flip to
|
|
663
681
|
their counterpart, EQ/NE are commutative), but here we
|
|
664
682
|
broadcast the left scalar up instead of swapping, so op_id
|
|
@@ -698,6 +716,17 @@ rb_ca_bincmp_s_build (int argc, VALUE *argv, VALUE klass)
|
|
|
698
716
|
return rb_ca_bincmp_build(l_cary, r_cary, op_id, eps);
|
|
699
717
|
}
|
|
700
718
|
|
|
719
|
+
/* Whether this node's kernel skips the cells its operands mask, rather
|
|
720
|
+
than computing them: object cells, which call Ruby. CArray::Fusion
|
|
721
|
+
reads it so a plan carries the same rule. */
|
|
722
|
+
static VALUE
|
|
723
|
+
rb_ca_bincmp_trapping (VALUE self)
|
|
724
|
+
{
|
|
725
|
+
CABinCmp *bc;
|
|
726
|
+
TypedData_Get_Struct(self, CABinCmp, &cabincmp_data_type, bc);
|
|
727
|
+
return ( bc->common_dt == CA_OBJECT ) ? Qtrue : Qfalse;
|
|
728
|
+
}
|
|
729
|
+
|
|
701
730
|
static VALUE
|
|
702
731
|
rb_ca_bincmp_op_id (VALUE self)
|
|
703
732
|
{
|
|
@@ -777,6 +806,7 @@ rb_ca_bincmp_initialize_copy (VALUE self, VALUE other)
|
|
|
777
806
|
{
|
|
778
807
|
CABinCmp *ca, *cs;
|
|
779
808
|
TypedData_Get_Struct(self, CABinCmp, &cabincmp_data_type, ca);
|
|
809
|
+
ca_check_uninitialized(ca);
|
|
780
810
|
TypedData_Get_Struct(other, CABinCmp, &cabincmp_data_type, cs);
|
|
781
811
|
if ( ca_func[CA_OBJ_BINCMP].pool_init ) {
|
|
782
812
|
ca_array_pool_alloc(ca, CA_OBJ_BINCMP, cs->parent->ndim);
|
|
@@ -820,6 +850,7 @@ Init_ca_obj_bincmp (void)
|
|
|
820
850
|
rb_ca_bincmp_s_build, -1);
|
|
821
851
|
|
|
822
852
|
rb_define_method(rb_cCABinCmp, "__op_id__", rb_ca_bincmp_op_id, 0);
|
|
853
|
+
rb_define_method(rb_cCABinCmp, "__trapping__", rb_ca_bincmp_trapping, 0);
|
|
823
854
|
rb_define_method(rb_cCABinCmp, "__bincmp_right__",
|
|
824
855
|
rb_ca_bincmp_right, 0);
|
|
825
856
|
rb_define_method(rb_cCABinCmp, "__eps__", rb_ca_bincmp_eps, 0);
|