carray 3.0.3 → 3.0.4
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 +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +78 -10
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +11 -4
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +182 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +53 -36
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/carray_operator.c
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
#include "carray.h"
|
|
14
14
|
#include "carray_internal.h" /* ca_lazy_arena_* */
|
|
15
|
-
#include "ca_binop_dispatch.h" /*
|
|
15
|
+
#include "ca_binop_dispatch.h" /* ca_binop_op_id_of_table */
|
|
16
|
+
#include "ca_monop_dispatch.h" /* ca_monop_op_id_of_table */
|
|
16
17
|
|
|
17
18
|
/* Operand scratch for a chunked / gathered kernel run.
|
|
18
19
|
|
|
@@ -31,19 +32,17 @@ ca_op_acquire_operand_scratch (CArray *ca, ca_size_t n_elements)
|
|
|
31
32
|
|
|
32
33
|
#include "ca_obj_face.h" /* ca_face_reconcile_comparison (comparison Face gate) */
|
|
33
34
|
|
|
34
|
-
/* A kernel table with no entry for the
|
|
35
|
-
method and the type, or the Face, rather than
|
|
36
|
-
stub, which knows neither.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
static void
|
|
41
|
-
ca_op_refuse_unimplemented (VALUE operand, CArray *ca, VALUE eclass)
|
|
35
|
+
/* A kernel table with no entry for `data_type`, the type the operator
|
|
36
|
+
would run in. Name the method and the type, or the Face, rather than
|
|
37
|
+
leave it to the table's stub, which knows neither. The eager operators
|
|
38
|
+
and the lazy builders refuse through here, so the two say the same. */
|
|
39
|
+
void
|
|
40
|
+
ca_op_refuse_unimplemented (VALUE operand, int8_t data_type, VALUE eclass)
|
|
42
41
|
{
|
|
43
42
|
const char *name = ca_calling_method_name();
|
|
44
43
|
ca_face_refuse_numeric(operand, name, eclass);
|
|
45
44
|
rb_raise(eclass, "%s: not defined for data_type %s",
|
|
46
|
-
name, ca_type_name[
|
|
45
|
+
name, ca_type_name[data_type]);
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
VALUE rb_mCAMath;
|
|
@@ -276,10 +275,11 @@ ca_chunked_run (ca_chunked_run_t *run)
|
|
|
276
275
|
/* ---- Kernels that can raise -----------------------------------------
|
|
277
276
|
|
|
278
277
|
An operator kernel runs with its alias operands attached. Most kernels
|
|
279
|
-
cannot raise and are called directly.
|
|
278
|
+
cannot raise and are called directly. Two kinds can:
|
|
280
279
|
|
|
281
|
-
-
|
|
282
|
-
|
|
280
|
+
- a kernel that can raise on a cell (ca_op_raises_on_cell: an object
|
|
281
|
+
lane, which calls Ruby for every cell; an integer division, remainder
|
|
282
|
+
or reciprocal by zero; an integer power of zero to a negative power)
|
|
283
283
|
- a data type the operator has no kernel for (the not_implement slot)
|
|
284
284
|
|
|
285
285
|
Those run through ca_op_guarded, which releases the operands the call
|
|
@@ -293,41 +293,71 @@ ca_op_is_integer (int8_t dt)
|
|
|
293
293
|
return ( dt >= CA_INT8 && dt <= CA_UINT64 );
|
|
294
294
|
}
|
|
295
295
|
|
|
296
|
+
int
|
|
297
|
+
ca_op_raises_on_cell (int kind, int op_id, int8_t dt)
|
|
298
|
+
{
|
|
299
|
+
if ( dt == CA_OBJECT ) {
|
|
300
|
+
return 1;
|
|
301
|
+
}
|
|
302
|
+
if ( ! ca_op_is_integer(dt) ) {
|
|
303
|
+
return 0;
|
|
304
|
+
}
|
|
305
|
+
switch ( kind ) {
|
|
306
|
+
case CA_OP_KIND_MONOP:
|
|
307
|
+
return op_id == CA_MONOP_RCP;
|
|
308
|
+
case CA_OP_KIND_BINOP:
|
|
309
|
+
switch ( op_id ) {
|
|
310
|
+
case CA_BINOP_DIV:
|
|
311
|
+
case CA_BINOP_MOD:
|
|
312
|
+
case CA_BINOP_QUO:
|
|
313
|
+
case CA_BINOP_FMOD:
|
|
314
|
+
case CA_BINOP_RCP_MUL:
|
|
315
|
+
case CA_BINOP_POW:
|
|
316
|
+
case CA_BINOP_IPOWER:
|
|
317
|
+
return 1;
|
|
318
|
+
default:
|
|
319
|
+
return 0;
|
|
320
|
+
}
|
|
321
|
+
default:
|
|
322
|
+
return 0;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* The eager forms: a kernel that can raise on a cell
|
|
327
|
+
(ca_op_raises_on_cell), or a data type the operator has no kernel for. */
|
|
296
328
|
static int
|
|
297
329
|
ca_monop_may_raise (ca_monop_func_t func[], int8_t dt)
|
|
298
330
|
{
|
|
299
|
-
return dt ==
|
|
300
|
-
|| func
|
|
301
|
-
|| ( func == ca_monop_rcp && ca_op_is_integer(dt) );
|
|
331
|
+
return func[dt] == ca_monop_not_implement
|
|
332
|
+
|| ca_op_raises_on_cell(CA_OP_KIND_MONOP, ca_monop_op_id_of_table(func), dt);
|
|
302
333
|
}
|
|
303
334
|
|
|
304
|
-
/* Which ops raise on a cell is ca_binop_is_trapping's list, the one the
|
|
305
|
-
lazy views skip masked cells by. */
|
|
306
335
|
static int
|
|
307
336
|
ca_binop_may_raise (ca_binop_func_t func[], int8_t dt)
|
|
308
337
|
{
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
op_id = ca_binop_op_id_of_table(func);
|
|
312
|
-
return op_id >= 0 && ca_binop_is_trapping((uint16_t) op_id, dt);
|
|
338
|
+
return func[dt] == ca_binop_not_implement
|
|
339
|
+
|| ca_op_raises_on_cell(CA_OP_KIND_BINOP, ca_binop_op_id_of_table(func), dt);
|
|
313
340
|
}
|
|
314
341
|
|
|
315
342
|
static int
|
|
316
343
|
ca_triop_may_raise (ca_triop_func_t func[], int8_t dt)
|
|
317
344
|
{
|
|
318
|
-
return
|
|
345
|
+
return func[dt] == ca_triop_not_implement
|
|
346
|
+
|| ca_op_raises_on_cell(CA_OP_KIND_TRIOP, -1, dt);
|
|
319
347
|
}
|
|
320
348
|
|
|
321
349
|
static int
|
|
322
350
|
ca_moncmp_may_raise (ca_moncmp_func_t func[], int8_t dt)
|
|
323
351
|
{
|
|
324
|
-
return
|
|
352
|
+
return func[dt] == ca_moncmp_not_implement
|
|
353
|
+
|| ca_op_raises_on_cell(CA_OP_KIND_MONCMP, -1, dt);
|
|
325
354
|
}
|
|
326
355
|
|
|
327
356
|
static int
|
|
328
357
|
ca_bincmp_may_raise (ca_bincmp_func_t func[], int8_t dt)
|
|
329
358
|
{
|
|
330
|
-
return
|
|
359
|
+
return func[dt] == ca_bincmp_not_implement
|
|
360
|
+
|| ca_op_raises_on_cell(CA_OP_KIND_BINCMP, -1, dt);
|
|
331
361
|
}
|
|
332
362
|
|
|
333
363
|
/* One kernel call, packed so that it can run under rb_ensure. */
|
|
@@ -456,6 +486,7 @@ ca_op_guard_release (VALUE varg)
|
|
|
456
486
|
}
|
|
457
487
|
if ( g->mode[k] == 'w' ) {
|
|
458
488
|
int tag = 0;
|
|
489
|
+
/* protect: a sync that raises is dropped so that every held array is detached */
|
|
459
490
|
rb_protect(ca_op_guard_sync, (VALUE) ca, &tag);
|
|
460
491
|
rb_set_errinfo(Qnil);
|
|
461
492
|
}
|
|
@@ -495,11 +526,16 @@ ca_mask_overlay_or_body (VALUE arg)
|
|
|
495
526
|
{
|
|
496
527
|
ca_mask_overlay_or_t *o = (ca_mask_overlay_or_t *) arg;
|
|
497
528
|
boolean8_t *ms;
|
|
529
|
+
/* Locals, not o->ma / o->elements: a store through a boolean8_t may alias
|
|
530
|
+
*o, so reading them through o reloads both every iteration and keeps
|
|
531
|
+
the loop from vectorizing. */
|
|
532
|
+
boolean8_t *ma = o->ma;
|
|
533
|
+
ca_size_t elements = o->elements;
|
|
498
534
|
ca_size_t j;
|
|
499
|
-
o->scratch = ca_lazy_arena_acquire(
|
|
535
|
+
o->scratch = ca_lazy_arena_acquire(elements);
|
|
500
536
|
ms = (boolean8_t *) o->scratch;
|
|
501
537
|
ca_xfer_all(o->mask, o->scratch, CA_XFER_GET);
|
|
502
|
-
for ( j = 0; j <
|
|
538
|
+
for ( j = 0; j < elements; j++ ) ma[j] |= ms[j];
|
|
503
539
|
return Qnil;
|
|
504
540
|
}
|
|
505
541
|
|
|
@@ -515,9 +551,10 @@ ca_mask_overlay_or_body (VALUE arg)
|
|
|
515
551
|
Memory peak: one mask scratch at a time (= elements bytes, 1 B/cell),
|
|
516
552
|
released between operands.
|
|
517
553
|
|
|
518
|
-
CAREFUL:
|
|
519
|
-
|
|
520
|
-
|
|
554
|
+
CAREFUL: ca_out's mask is written through ca_out->mask->ptr, so ca_out
|
|
555
|
+
is an entity (a fresh one from ca_template_safe) or an attached view.
|
|
556
|
+
Each operand other than a scalar has ca_out's number of elements
|
|
557
|
+
(ArgumentError otherwise); at most 8 operands.
|
|
521
558
|
|
|
522
559
|
This gathers the full mask once; a per-chunk mask gather inside the
|
|
523
560
|
chunked branch is a possible future optimisation. */
|
|
@@ -534,10 +571,22 @@ ca_mask_overlay_safe (CArray *ca_out, int n, ...)
|
|
|
534
571
|
va_start(ap, n);
|
|
535
572
|
for ( i = 0; i < n; i++ ) {
|
|
536
573
|
slist[i] = va_arg(ap, CArray *);
|
|
537
|
-
if ( slist[i] && ca_has_mask(slist[i]) ) any_mask = 1;
|
|
538
574
|
}
|
|
539
575
|
va_end(ap);
|
|
540
576
|
|
|
577
|
+
/* An array operand's mask is gathered over ca_out's cells. */
|
|
578
|
+
for ( i = 0; i < n; i++ ) {
|
|
579
|
+
CArray *cs = slist[i];
|
|
580
|
+
if ( cs && ! ca_is_scalar(cs) && cs->elements != ca_out->elements ) {
|
|
581
|
+
rb_raise(rb_eArgError,
|
|
582
|
+
"mask operand has %lld elements, the output %lld",
|
|
583
|
+
(long long) cs->elements, (long long) ca_out->elements);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
for ( i = 0; i < n; i++ ) {
|
|
587
|
+
if ( slist[i] && ca_has_mask(slist[i]) ) any_mask = 1;
|
|
588
|
+
}
|
|
589
|
+
|
|
541
590
|
if ( ! any_mask ) return;
|
|
542
591
|
|
|
543
592
|
ca_update_mask(ca_out);
|
|
@@ -609,17 +658,12 @@ ca_mask_overlay_attached (CArray *out, int n,
|
|
|
609
658
|
CArray *s0, CArray *s1, CArray *s2)
|
|
610
659
|
{
|
|
611
660
|
ca_overlay_args_t a;
|
|
612
|
-
int tag = 0;
|
|
613
661
|
a.out = out;
|
|
614
662
|
a.n = n;
|
|
615
663
|
a.src[0] = s0;
|
|
616
664
|
a.src[1] = s1;
|
|
617
665
|
a.src[2] = s2;
|
|
618
|
-
|
|
619
|
-
if ( tag ) {
|
|
620
|
-
ca_detach(out);
|
|
621
|
-
rb_jump_tag(tag);
|
|
622
|
-
}
|
|
666
|
+
ca_fill_or_detach(1, &out, ca_overlay_attached_body, (VALUE) &a);
|
|
623
667
|
}
|
|
624
668
|
|
|
625
669
|
/* Monop driver. ca1 is input-only (the driver does not attach it); ca2
|
|
@@ -642,7 +686,7 @@ rb_ca_call_monop (VALUE self, ca_monop_func_t func[])
|
|
|
642
686
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca1);
|
|
643
687
|
}
|
|
644
688
|
if ( func[ca1->data_type] == ca_monop_not_implement ) {
|
|
645
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
689
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
646
690
|
}
|
|
647
691
|
|
|
648
692
|
ca2 = ca_has_mask(ca1) ? ca_template_safe(ca1) : ca_template(ca1);
|
|
@@ -650,6 +694,10 @@ rb_ca_call_monop (VALUE self, ca_monop_func_t func[])
|
|
|
650
694
|
|
|
651
695
|
ca_mask_overlay_safe(ca2, 1, ca1);
|
|
652
696
|
|
|
697
|
+
/* No cell to compute: the strided walks below hand the kernel a first
|
|
698
|
+
row before they look at the outer counts. */
|
|
699
|
+
if ( ca2->elements == 0 ) return out;
|
|
700
|
+
|
|
653
701
|
if ( ca_attach_is_alias(ca1) ) {
|
|
654
702
|
ca_monop_call_t k;
|
|
655
703
|
k.f = func[ca1->data_type];
|
|
@@ -724,6 +772,7 @@ rb_ca_call_monop (VALUE self, ca_monop_func_t func[])
|
|
|
724
772
|
ca2->ptr, 1);
|
|
725
773
|
}
|
|
726
774
|
else {
|
|
775
|
+
/* empty: the function returns on a result with no cells, above */
|
|
727
776
|
while ( 1 ) {
|
|
728
777
|
ca_size_t off1 = e1_base;
|
|
729
778
|
for ( k = 0; k < ndim - 1; k++ ) {
|
|
@@ -763,6 +812,8 @@ rb_ca_call_monop (VALUE self, ca_monop_func_t func[])
|
|
|
763
812
|
}
|
|
764
813
|
}
|
|
765
814
|
|
|
815
|
+
/* the INT64 view of a boolean operand is reached only through ca1 */
|
|
816
|
+
RB_GC_GUARD(self);
|
|
766
817
|
return out;
|
|
767
818
|
}
|
|
768
819
|
|
|
@@ -775,7 +826,7 @@ rb_ca_call_monop_bang (VALUE self, ca_monop_func_t func[])
|
|
|
775
826
|
|
|
776
827
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca1);
|
|
777
828
|
if ( func[ca1->data_type] == ca_monop_not_implement ) {
|
|
778
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
829
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
779
830
|
}
|
|
780
831
|
|
|
781
832
|
ca_attach(ca1); /* window: the kernel runs through ca_op_guarded when it can raise */
|
|
@@ -815,7 +866,7 @@ rb_ca_call_monop_typed (VALUE self, ca_monop_func_t func[],
|
|
|
815
866
|
|
|
816
867
|
out_dt = out_data_types[ca1->data_type];
|
|
817
868
|
if ( out_dt < 0 ) {
|
|
818
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
869
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
819
870
|
}
|
|
820
871
|
|
|
821
872
|
/* Allocate output with the per-op output data_type. Same shape as input. */
|
|
@@ -825,6 +876,10 @@ rb_ca_call_monop_typed (VALUE self, ca_monop_func_t func[],
|
|
|
825
876
|
/* Same fast/slow pattern as rb_ca_call_monop. ca1 input-only, ca2 output. */
|
|
826
877
|
ca_mask_overlay_safe(ca2, 1, ca1);
|
|
827
878
|
|
|
879
|
+
/* No cell to compute: the strided walks below hand the kernel a first
|
|
880
|
+
row before they look at the outer counts. */
|
|
881
|
+
if ( ca2->elements == 0 ) return out;
|
|
882
|
+
|
|
828
883
|
if ( ca_attach_is_alias(ca1) ) {
|
|
829
884
|
ca_monop_call_t k;
|
|
830
885
|
k.f = func[ca1->data_type];
|
|
@@ -895,6 +950,7 @@ rb_ca_call_monop_typed (VALUE self, ca_monop_func_t func[],
|
|
|
895
950
|
ca2->ptr, 1);
|
|
896
951
|
}
|
|
897
952
|
else {
|
|
953
|
+
/* empty: the function returns on a result with no cells, above */
|
|
898
954
|
while ( 1 ) {
|
|
899
955
|
ca_size_t off1 = e1_base;
|
|
900
956
|
for ( k = 0; k < ndim - 1; k++ ) {
|
|
@@ -1165,7 +1221,7 @@ rb_ca_call_binop (volatile VALUE self, volatile VALUE other,
|
|
|
1165
1221
|
TypedData_Get_Struct(other, CArray, &carray_data_type, ca2);
|
|
1166
1222
|
}
|
|
1167
1223
|
if ( func[ca1->data_type] == ca_binop_not_implement ) {
|
|
1168
|
-
ca_op_refuse_unimplemented(ca_is_face(ca1) ? self : other, ca1,
|
|
1224
|
+
ca_op_refuse_unimplemented(ca_is_face(ca1) ? self : other, ca1->data_type,
|
|
1169
1225
|
rb_eCADataTypeError);
|
|
1170
1226
|
}
|
|
1171
1227
|
|
|
@@ -1210,6 +1266,10 @@ rb_ca_call_binop (volatile VALUE self, volatile VALUE other,
|
|
|
1210
1266
|
input-only operand does not raise. */
|
|
1211
1267
|
ca_mask_overlay_safe(ca3, 2, ca1, ca2);
|
|
1212
1268
|
|
|
1269
|
+
/* No cell to compute: the strided walks below hand the kernel a first
|
|
1270
|
+
row before they look at the outer counts. */
|
|
1271
|
+
if ( ca3->elements == 0 ) return out;
|
|
1272
|
+
|
|
1213
1273
|
/* path decision: alias-attachable both → fast path */
|
|
1214
1274
|
fast_path = ca_attach_is_alias(ca1) && ca_attach_is_alias(ca2);
|
|
1215
1275
|
|
|
@@ -1291,7 +1351,7 @@ rb_ca_call_binop (volatile VALUE self, volatile VALUE other,
|
|
|
1291
1351
|
Output ca3 is contig entity; per-row output offset = row_idx *
|
|
1292
1352
|
inner_count. The use_chunked / ALLOCV blocks below remain as a
|
|
1293
1353
|
fallback (dead on the success path) but fire for views outside the
|
|
1294
|
-
CAStride+entity family (CASelect /
|
|
1354
|
+
CAStride+entity family (CASelect / CAGrid / CAReduce
|
|
1295
1355
|
etc.). */
|
|
1296
1356
|
if ( i1 == 1 && i2 == 1 && nonalias_arrays >= 1 ) {
|
|
1297
1357
|
extern ca_operation_function_t ca_stride_func;
|
|
@@ -1380,6 +1440,7 @@ rb_ca_call_binop (volatile VALUE self, volatile VALUE other,
|
|
|
1380
1440
|
ca3->ptr, i3);
|
|
1381
1441
|
}
|
|
1382
1442
|
else {
|
|
1443
|
+
/* empty: the function returns on a result with no cells, above */
|
|
1383
1444
|
while ( 1 ) {
|
|
1384
1445
|
ca_size_t off1 = e1_base, off2 = e2_base;
|
|
1385
1446
|
for ( k = 0; k < ndim - 1; k++ ) {
|
|
@@ -1519,7 +1580,7 @@ rb_ca_call_binop_bang (VALUE self, VALUE other, ca_binop_func_t func[])
|
|
|
1519
1580
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca1);
|
|
1520
1581
|
TypedData_Get_Struct(other, CArray, &carray_data_type, ca2);
|
|
1521
1582
|
if ( func[ca1->data_type] == ca_binop_not_implement ) {
|
|
1522
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
1583
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
1523
1584
|
}
|
|
1524
1585
|
|
|
1525
1586
|
self_is_scalar = RTEST(rb_obj_is_cscalar(self));
|
|
@@ -1589,6 +1650,8 @@ rb_ca_call_binop_bang (VALUE self, VALUE other, ca_binop_func_t func[])
|
|
|
1589
1650
|
|
|
1590
1651
|
ca_sync_detach(ca1);
|
|
1591
1652
|
|
|
1653
|
+
/* a cast or broadcast view of other is reached only through ca2 */
|
|
1654
|
+
RB_GC_GUARD(other);
|
|
1592
1655
|
return self;
|
|
1593
1656
|
}
|
|
1594
1657
|
|
|
@@ -1732,7 +1795,7 @@ rb_ca_call_triop (VALUE self, VALUE other2, VALUE other3,
|
|
|
1732
1795
|
if ( func[ca1->data_type] == ca_triop_not_implement ) {
|
|
1733
1796
|
ca_op_refuse_unimplemented(ca_is_face(ca1) ? self
|
|
1734
1797
|
: ca_is_face(ca2) ? other2 : other3,
|
|
1735
|
-
ca1, rb_eCADataTypeError);
|
|
1798
|
+
ca1->data_type, rb_eCADataTypeError);
|
|
1736
1799
|
}
|
|
1737
1800
|
|
|
1738
1801
|
/* Element-count check: all non-scalar operands must agree. */
|
|
@@ -1855,6 +1918,10 @@ rb_ca_call_triop (VALUE self, VALUE other2, VALUE other3,
|
|
|
1855
1918
|
}
|
|
1856
1919
|
}
|
|
1857
1920
|
|
|
1921
|
+
/* the INT64 views of a boolean triop are reached only through ca1..ca3 */
|
|
1922
|
+
RB_GC_GUARD(self);
|
|
1923
|
+
RB_GC_GUARD(other2);
|
|
1924
|
+
RB_GC_GUARD(other3);
|
|
1858
1925
|
return out;
|
|
1859
1926
|
}
|
|
1860
1927
|
|
|
@@ -1883,7 +1950,7 @@ rb_ca_call_triop_bang (VALUE self, VALUE other2, VALUE other3,
|
|
|
1883
1950
|
TypedData_Get_Struct(other2, CArray, &carray_data_type, ca2);
|
|
1884
1951
|
TypedData_Get_Struct(other3, CArray, &carray_data_type, ca3);
|
|
1885
1952
|
if ( func[ca1->data_type] == ca_triop_not_implement ) {
|
|
1886
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
1953
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
1887
1954
|
}
|
|
1888
1955
|
|
|
1889
1956
|
/* self is the write target, so the destination rule applies to each
|
|
@@ -2018,6 +2085,10 @@ rb_ca_call_triop_bang (VALUE self, VALUE other2, VALUE other3,
|
|
|
2018
2085
|
|
|
2019
2086
|
ca_sync_detach(ca1);
|
|
2020
2087
|
|
|
2088
|
+
/* cast or broadcast views of the operands are reached only through
|
|
2089
|
+
ca2 and ca3 */
|
|
2090
|
+
RB_GC_GUARD(other2);
|
|
2091
|
+
RB_GC_GUARD(other3);
|
|
2021
2092
|
return self;
|
|
2022
2093
|
}
|
|
2023
2094
|
|
|
@@ -2031,7 +2102,7 @@ rb_ca_call_moncmp (VALUE self, ca_moncmp_func_t func[])
|
|
|
2031
2102
|
|
|
2032
2103
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca1);
|
|
2033
2104
|
if ( func[ca1->data_type] == ca_moncmp_not_implement ) {
|
|
2034
|
-
ca_op_refuse_unimplemented(self, ca1, rb_eCADataTypeError);
|
|
2105
|
+
ca_op_refuse_unimplemented(self, ca1->data_type, rb_eCADataTypeError);
|
|
2035
2106
|
}
|
|
2036
2107
|
|
|
2037
2108
|
if ( ca_is_scalar(ca1) ) {
|
|
@@ -2045,6 +2116,9 @@ rb_ca_call_moncmp (VALUE self, ca_moncmp_func_t func[])
|
|
|
2045
2116
|
|
|
2046
2117
|
ca_mask_overlay_safe(ca2, 1, ca1);
|
|
2047
2118
|
|
|
2119
|
+
/* No cell to compute, as in the operators above. */
|
|
2120
|
+
if ( ca2->elements == 0 ) return out;
|
|
2121
|
+
|
|
2048
2122
|
/* The kernel's masked branch skips masked cells, so they would keep the
|
|
2049
2123
|
uninitialised data from rb_carray_new. Zero the output when a mask is
|
|
2050
2124
|
present so masked cells read as 0 (matching binop's ca_template_safe
|
|
@@ -2302,7 +2376,7 @@ rb_ca_call_bincmp (volatile VALUE self, volatile VALUE other,
|
|
|
2302
2376
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca1);
|
|
2303
2377
|
TypedData_Get_Struct(other, CArray, &carray_data_type, ca2);
|
|
2304
2378
|
if ( func[ca1->data_type] == ca_bincmp_not_implement ) {
|
|
2305
|
-
ca_op_refuse_unimplemented(ca_is_face(ca1) ? self : other, ca1,
|
|
2379
|
+
ca_op_refuse_unimplemented(ca_is_face(ca1) ? self : other, ca1->data_type,
|
|
2306
2380
|
rb_eTypeError);
|
|
2307
2381
|
}
|
|
2308
2382
|
|
|
@@ -2338,6 +2412,9 @@ rb_ca_call_bincmp (volatile VALUE self, volatile VALUE other,
|
|
|
2338
2412
|
|
|
2339
2413
|
ca_mask_overlay_safe(ca3, 2, ca1, ca2);
|
|
2340
2414
|
|
|
2415
|
+
/* No cell to compute, as in the operators above. */
|
|
2416
|
+
if ( ca3->elements == 0 ) return out;
|
|
2417
|
+
|
|
2341
2418
|
/* The kernel's masked branch skips masked cells, so they would keep the
|
|
2342
2419
|
uninitialised data from rb_carray_new. Zero the output when a mask is
|
|
2343
2420
|
present so masked cells read as 0 (matching binop's ca_template_safe
|