carray 3.0.3 → 3.0.5
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 +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- 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 +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- 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 +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -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 +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -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 +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -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 +105 -17
- 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 +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- 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 +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -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 +42 -6
- 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 +217 -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 +61 -37
- 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 +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- 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_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- 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/ca_obj_monop.c
CHANGED
|
@@ -222,6 +222,7 @@ ca_monop_setup (CAMonOp *ca, CArray *parent, uint16_t op_id)
|
|
|
222
222
|
CAMonOp *
|
|
223
223
|
ca_monop_new (CArray *parent, uint16_t op_id)
|
|
224
224
|
{
|
|
225
|
+
/* check: the setup checks nothing */
|
|
225
226
|
CAMonOp *ca = (CAMonOp *) ca_array_alloc(CA_OBJ_MONOP, parent->ndim);
|
|
226
227
|
ca_monop_setup(ca, parent, op_id);
|
|
227
228
|
return ca;
|
|
@@ -282,7 +283,7 @@ ca_monop_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
|
282
283
|
/* PUT: only writable-view op_ids accept writes (cast, or byte_swap
|
|
283
284
|
involution). */
|
|
284
285
|
if ( ! ca_monop_is_writable_view(ca->op_id) ) {
|
|
285
|
-
|
|
286
|
+
ca_refuse_read_only();
|
|
286
287
|
}
|
|
287
288
|
{
|
|
288
289
|
volatile VALUE holder;
|
|
@@ -337,16 +338,14 @@ ca_size_t ca_monop_materialise_call_count = 0;
|
|
|
337
338
|
#define CA_MAX_LAZY_DEPTH 256
|
|
338
339
|
#endif
|
|
339
340
|
|
|
340
|
-
/* Whether
|
|
341
|
-
|
|
342
|
-
and an integer reciprocal (zero raises). */
|
|
341
|
+
/* Whether a cast from `from` to `to` raises on a NaN cell: a float or
|
|
342
|
+
complex value has no integer for NaN. */
|
|
343
343
|
static int
|
|
344
|
-
|
|
344
|
+
ca_monop_cast_refuses_nan (int8_t from, int8_t to)
|
|
345
345
|
{
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
return ( op_id == CA_MONOP_RCP && dt >= CA_INT8 && dt <= CA_UINT64 );
|
|
346
|
+
int from_float = ( from == CA_FLOAT32 || from == CA_FLOAT64 ||
|
|
347
|
+
from == CA_CMPLX64 || from == CA_CMPLX128 );
|
|
348
|
+
return from_float && to >= CA_INT8 && to <= CA_UINT64;
|
|
350
349
|
}
|
|
351
350
|
|
|
352
351
|
/* Apply a single op in-place on `data` (src == dst, unit element stride).
|
|
@@ -371,12 +370,19 @@ apply_monop_in_place (uint16_t op_id, int8_t cur_dt,
|
|
|
371
370
|
fn(slab_n, mask, (char *) data, 1, (char *) data, 1);
|
|
372
371
|
}
|
|
373
372
|
|
|
374
|
-
/*
|
|
375
|
-
ca_cast_block
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
373
|
+
/* A zeroed CArray carrying only data_type and bytes, handed to
|
|
374
|
+
ca_cast_block in place of a real array. It is a whole CArray, not a
|
|
375
|
+
shorter struct cast to one: ca_cast_block reads data_type through a
|
|
376
|
+
CArray pointer, and a fixlen cast reads bytes as well. */
|
|
377
|
+
static CArray
|
|
378
|
+
ca_data_type_stub (int8_t data_type)
|
|
379
|
+
{
|
|
380
|
+
CArray stub;
|
|
381
|
+
memset(&stub, 0, sizeof(stub));
|
|
382
|
+
stub.data_type = data_type;
|
|
383
|
+
stub.bytes = ca_sizeof[data_type];
|
|
384
|
+
return stub;
|
|
385
|
+
}
|
|
380
386
|
|
|
381
387
|
/* Pull leaf into the output buffer. Three paths:
|
|
382
388
|
|
|
@@ -429,8 +435,8 @@ pull_leaf_with_optional_cast (CArray *leaf, uint16_t innermost_op,
|
|
|
429
435
|
if ( has_cast_at_leaf ) {
|
|
430
436
|
/* Path 2: cast scratch → data with output layout in target data_type. */
|
|
431
437
|
int8_t target_dt = (int8_t)(innermost_op - CA_MONOP_CAST_BASE);
|
|
432
|
-
|
|
433
|
-
|
|
438
|
+
CArray src_stub = ca_data_type_stub(leaf->data_type);
|
|
439
|
+
CArray dst_stub = ca_data_type_stub(target_dt);
|
|
434
440
|
ca_cast_block(slab_n, &src_stub, scratch, &dst_stub, data);
|
|
435
441
|
result_dt = target_dt;
|
|
436
442
|
} else {
|
|
@@ -476,7 +482,27 @@ ca_monop_eval (CAMonOp *mo, const ca_lazy_req_t *req, void *data, int dir)
|
|
|
476
482
|
v = ALLOCV_N(char, holder, n * parent_bytes);
|
|
477
483
|
if ( dir == CA_XFER_GET ) {
|
|
478
484
|
ca_lazy_req_pull(mo->parent, req, v, CA_XFER_GET);
|
|
479
|
-
if ( is_cast
|
|
485
|
+
if ( is_cast && ca_monop_cast_refuses_nan(mo->parent->data_type,
|
|
486
|
+
mo->data_type) ) {
|
|
487
|
+
/* The cast raises on a NaN cell it is asked to convert; a masked
|
|
488
|
+
cell (mask_invalid keeps the NaN under the mask) is skipped.
|
|
489
|
+
The mask is copied off the arena first so a raise leaves no
|
|
490
|
+
arena slot held. */
|
|
491
|
+
CArray *parent = mo->parent;
|
|
492
|
+
boolean8_t *arena_mask = ca_lazy_req_mask(req, 1, &parent);
|
|
493
|
+
boolean8_t *m = NULL;
|
|
494
|
+
volatile VALUE mholder = 0;
|
|
495
|
+
if ( arena_mask ) {
|
|
496
|
+
m = ALLOCV_N(boolean8_t, mholder, n);
|
|
497
|
+
memcpy(m, arena_mask, n);
|
|
498
|
+
ca_lazy_arena_release(arena_mask);
|
|
499
|
+
}
|
|
500
|
+
ca_cast_block_with_mask(n, mo->parent, v, (CArray *) mo, data, m);
|
|
501
|
+
if ( m ) {
|
|
502
|
+
ALLOCV_END(mholder);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else if ( is_cast ) {
|
|
480
506
|
ca_cast_block(n, mo->parent, v, (CArray *) mo, data);
|
|
481
507
|
}
|
|
482
508
|
else {
|
|
@@ -503,7 +529,7 @@ ca_monop_eval (CAMonOp *mo, const ca_lazy_req_t *req, void *data, int dir)
|
|
|
503
529
|
/* Writable-view op_id PUT/GET is handled above. Below: non-writable
|
|
504
530
|
monop/monfunc. PUT is read-only. */
|
|
505
531
|
if ( dir != CA_XFER_GET ) {
|
|
506
|
-
|
|
532
|
+
ca_refuse_read_only();
|
|
507
533
|
}
|
|
508
534
|
ca_monop_materialise_call_count++;
|
|
509
535
|
|
|
@@ -536,6 +562,30 @@ ca_monop_eval (CAMonOp *mo, const ca_lazy_req_t *req, void *data, int dir)
|
|
|
536
562
|
chain_apply_count = chain_len - 1;
|
|
537
563
|
}
|
|
538
564
|
|
|
565
|
+
/* The chain runs in place, so the buffer must hold slab_n cells of the
|
|
566
|
+
widest type along it: the leaf, or a step that widens before a later
|
|
567
|
+
one narrows (cmplx128.lazy.abs pulls 16-byte cells and answers 8-byte
|
|
568
|
+
ones). When that is wider than the output, run in a scratch and copy
|
|
569
|
+
the answer into `data` at the end. */
|
|
570
|
+
void *out = data;
|
|
571
|
+
void *work = NULL;
|
|
572
|
+
{
|
|
573
|
+
ca_size_t max_bytes = leaf->bytes;
|
|
574
|
+
int8_t dt = leaf->data_type;
|
|
575
|
+
for ( i = chain_len - 1; i >= 0; i-- ) {
|
|
576
|
+
dt = ca_monop_is_cast(op_chain[i])
|
|
577
|
+
? (int8_t)(op_chain[i] - CA_MONOP_CAST_BASE)
|
|
578
|
+
: ca_lazy_promote_monop(op_chain[i], dt);
|
|
579
|
+
if ( ca_sizeof[dt] > max_bytes ) max_bytes = ca_sizeof[dt];
|
|
580
|
+
}
|
|
581
|
+
if ( max_bytes > mo->bytes ) {
|
|
582
|
+
work = ( leaf->data_type == CA_OBJECT )
|
|
583
|
+
? ca_lazy_arena_acquire_object((slab_n * max_bytes + sizeof(VALUE) - 1) / sizeof(VALUE))
|
|
584
|
+
: ca_lazy_arena_acquire(slab_n * max_bytes);
|
|
585
|
+
data = work;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
539
589
|
/* === 2. pull leaf into output buffer (with optional cast) === */
|
|
540
590
|
cur_dt = pull_leaf_with_optional_cast(
|
|
541
591
|
leaf,
|
|
@@ -557,8 +607,8 @@ ca_monop_eval (CAMonOp *mo, const ca_lazy_req_t *req, void *data, int dir)
|
|
|
557
607
|
ca_size_t src_bytes = ca_sizeof[cur_dt];
|
|
558
608
|
ca_size_t total_bytes = slab_n * src_bytes;
|
|
559
609
|
void *scratch;
|
|
560
|
-
|
|
561
|
-
|
|
610
|
+
CArray src_stub = ca_data_type_stub(cur_dt);
|
|
611
|
+
CArray dst_stub = ca_data_type_stub(target_dt);
|
|
562
612
|
|
|
563
613
|
/* Copy current data → scratch (in src data_type), then cast scratch
|
|
564
614
|
→ data (in target data_type). Required because in-place cast
|
|
@@ -573,18 +623,22 @@ ca_monop_eval (CAMonOp *mo, const ca_lazy_req_t *req, void *data, int dir)
|
|
|
573
623
|
ca_lazy_arena_release(scratch);
|
|
574
624
|
cur_dt = target_dt;
|
|
575
625
|
} else {
|
|
576
|
-
if ( ! mask_taken &&
|
|
626
|
+
if ( ! mask_taken && ca_op_raises_on_cell(CA_OP_KIND_MONOP, op_id, cur_dt) ) {
|
|
577
627
|
slab_mask = ca_lazy_req_mask(req, 1, &leaf);
|
|
578
628
|
mask_taken = 1;
|
|
579
629
|
}
|
|
580
630
|
apply_monop_in_place(op_id, cur_dt, slab_n, data,
|
|
581
|
-
|
|
631
|
+
ca_op_raises_on_cell(CA_OP_KIND_MONOP, op_id, cur_dt) ? slab_mask : NULL);
|
|
582
632
|
cur_dt = ca_lazy_promote_monop(op_id, cur_dt);
|
|
583
633
|
}
|
|
584
634
|
}
|
|
585
635
|
if ( slab_mask ) {
|
|
586
636
|
ca_lazy_arena_release(slab_mask);
|
|
587
637
|
}
|
|
638
|
+
if ( work ) {
|
|
639
|
+
memcpy(out, work, slab_n * mo->bytes);
|
|
640
|
+
ca_lazy_arena_release(work);
|
|
641
|
+
}
|
|
588
642
|
}
|
|
589
643
|
|
|
590
644
|
static void
|
|
@@ -638,16 +692,7 @@ ca_monop_func_allocate (void *ap)
|
|
|
638
692
|
if ( ca_monop_is_writable_view(ca->op_id) ) {
|
|
639
693
|
ca_attach(ca->parent);
|
|
640
694
|
}
|
|
641
|
-
ca->ptr =
|
|
642
|
-
/* CA_OBJECT initialisation for GC safety. */
|
|
643
|
-
if ( ca->data_type == CA_OBJECT ) {
|
|
644
|
-
VALUE *p = (VALUE *) ca->ptr;
|
|
645
|
-
VALUE zero = SIZE2NUM(0);
|
|
646
|
-
ca_size_t i;
|
|
647
|
-
for ( i = 0; i < ca->elements; i++ ) {
|
|
648
|
-
*p++ = zero;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
695
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
651
696
|
}
|
|
652
697
|
|
|
653
698
|
static void
|
|
@@ -676,22 +721,19 @@ ca_monop_func_attach (void *ap)
|
|
|
676
721
|
Mirrors CAFake.attach. */
|
|
677
722
|
if ( ca_monop_is_writable_view(ca->op_id) ) {
|
|
678
723
|
ca_attach(ca->parent);
|
|
679
|
-
ca->ptr =
|
|
680
|
-
/* CA_OBJECT initialisation for GC safety (mirrors CAFake.allocate):
|
|
681
|
-
zero-init the VALUE cells before any potential GC can observe
|
|
682
|
-
them. */
|
|
683
|
-
if ( ca->data_type == CA_OBJECT ) {
|
|
684
|
-
VALUE *p = (VALUE *) ca->ptr;
|
|
685
|
-
VALUE zero = SIZE2NUM(0);
|
|
686
|
-
ca_size_t i;
|
|
687
|
-
for ( i = 0; i < ca->elements; i++ ) {
|
|
688
|
-
*p++ = zero;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
724
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
691
725
|
if ( ca_monop_is_cast(ca->op_id) ) {
|
|
692
|
-
/* Cast parent.ptr (parent data_type) → ca.ptr (cast target data_type).
|
|
693
|
-
|
|
694
|
-
|
|
726
|
+
/* Cast parent.ptr (parent data_type) → ca.ptr (cast target data_type).
|
|
727
|
+
A cast that raises on NaN skips the masked cells; the parent's
|
|
728
|
+
mask is attached with the parent. A raise here is undone by
|
|
729
|
+
ca_attach, which calls the detach slot once ca->ptr is set. */
|
|
730
|
+
boolean8_t *m = NULL;
|
|
731
|
+
if ( ca_monop_cast_refuses_nan(ca->parent->data_type, ca->data_type)
|
|
732
|
+
&& ca_has_mask(ca->parent) ) {
|
|
733
|
+
m = (boolean8_t *) ca->parent->mask->ptr;
|
|
734
|
+
}
|
|
735
|
+
ca_cast_block_with_mask(ca->elements, ca->parent, ca->parent->ptr,
|
|
736
|
+
(CArray *) ca, ca->ptr, m);
|
|
695
737
|
}
|
|
696
738
|
else {
|
|
697
739
|
/* byte_swap: memcpy parent.ptr → ca.ptr (same data_type same bytes),
|
|
@@ -702,19 +744,11 @@ ca_monop_func_attach (void *ap)
|
|
|
702
744
|
return;
|
|
703
745
|
}
|
|
704
746
|
|
|
705
|
-
ca->ptr =
|
|
747
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
706
748
|
|
|
707
749
|
s = ca->bytes;
|
|
708
750
|
for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
|
|
709
751
|
for ( k = 0; k < ca->ndim; k++ ) starts[k] = 0;
|
|
710
|
-
/* CA_OBJECT cells are VALUEs and this buffer is about to be marked as
|
|
711
|
-
soon as the view is, so it must not be handed to the GC as raw
|
|
712
|
-
xmalloc garbage. */
|
|
713
|
-
if ( ca->data_type == CA_OBJECT ) {
|
|
714
|
-
VALUE *p = (VALUE *) ca->ptr;
|
|
715
|
-
ca_size_t i;
|
|
716
|
-
for ( i = 0; i < ca->elements; i++ ) *p++ = Qnil;
|
|
717
|
-
}
|
|
718
752
|
ca_monop_func_xfer_stride(ca, starts, ca->dim, native, ca->ptr, CA_XFER_GET);
|
|
719
753
|
}
|
|
720
754
|
|
|
@@ -782,7 +816,7 @@ ca_monop_func_fill_data (void *ap, void *ptr)
|
|
|
782
816
|
data_type (= same bytes for byte_swap, reverse-cast for cast).
|
|
783
817
|
Non-writable monop/monfunc remains read-only. */
|
|
784
818
|
if ( ! ca_monop_is_writable_view(ca->op_id) ) {
|
|
785
|
-
|
|
819
|
+
ca_refuse_read_only();
|
|
786
820
|
}
|
|
787
821
|
{
|
|
788
822
|
int is_cast = ca_monop_is_cast(ca->op_id);
|
|
@@ -915,8 +949,9 @@ rb_ca_monop_build (VALUE cary, uint16_t op_id)
|
|
|
915
949
|
with no boolean kernel reads the 0/1 storage in int64. */
|
|
916
950
|
if ( parent_dt == CA_BOOLEAN && ! ca_monop_is_writable_view(op_id) ) {
|
|
917
951
|
if ( ca_monop_is_widening(op_id) ) {
|
|
918
|
-
|
|
919
|
-
|
|
952
|
+
/* the eager monop reads a boolean with no kernel as int64 (0/1), and
|
|
953
|
+
names that type in its refusal */
|
|
954
|
+
ca_op_refuse_unimplemented(cary, CA_INT64, rb_eCADataTypeError);
|
|
920
955
|
}
|
|
921
956
|
if ( ca_monop_kernel_lookup(op_id, CA_BOOLEAN) == ca_monop_not_implement ) {
|
|
922
957
|
target = rb_ca_monop_new(target, CA_MONOP_CAST_BASE + CA_INT64);
|
|
@@ -934,8 +969,13 @@ rb_ca_monop_build (VALUE cary, uint16_t op_id)
|
|
|
934
969
|
( ca_monop_kernel_lookup(op_id, kernel_in_dt) == ca_monop_not_implement ||
|
|
935
970
|
( parent_dt == CA_FIXLEN &&
|
|
936
971
|
ca_monop_kernel_lookup(op_id, CA_FIXLEN) == ca_monop_not_implement ) ) ) {
|
|
937
|
-
|
|
938
|
-
|
|
972
|
+
/* the eager monop takes an integer to float64 before it looks for the
|
|
973
|
+
kernel, and names the type it looked in */
|
|
974
|
+
ca_op_refuse_unimplemented(cary,
|
|
975
|
+
parent_dt == CA_FIXLEN ? CA_FIXLEN
|
|
976
|
+
: RTEST(rb_ca_is_integer_type(cary)) ? CA_FLOAT64
|
|
977
|
+
: kernel_in_dt,
|
|
978
|
+
rb_eCADataTypeError);
|
|
939
979
|
}
|
|
940
980
|
|
|
941
981
|
/* Insert cast node if the kernel wants a different input data_type. */
|
|
@@ -952,6 +992,7 @@ rb_ca_monop_build (VALUE cary, uint16_t op_id)
|
|
|
952
992
|
static VALUE
|
|
953
993
|
rb_ca_monop_s_build (VALUE klass, VALUE cary, VALUE op_id_val)
|
|
954
994
|
{
|
|
995
|
+
/* fits: an operation number from the library's own table */
|
|
955
996
|
uint16_t op_id = (uint16_t) NUM2UINT(op_id_val);
|
|
956
997
|
(void) klass;
|
|
957
998
|
return rb_ca_monop_build(cary, op_id);
|
|
@@ -976,7 +1017,7 @@ rb_ca_monop_trapping (VALUE self)
|
|
|
976
1017
|
CAMonOp *mo;
|
|
977
1018
|
TypedData_Get_Struct(self, CAMonOp, &camonop_data_type, mo);
|
|
978
1019
|
return ( ! ca_monop_is_cast(mo->op_id)
|
|
979
|
-
&&
|
|
1020
|
+
&& ca_op_raises_on_cell(CA_OP_KIND_MONOP, mo->op_id, mo->parent->data_type) )
|
|
980
1021
|
? Qtrue : Qfalse;
|
|
981
1022
|
}
|
|
982
1023
|
|
|
@@ -996,6 +1037,7 @@ rb_ca_monop_op_id (VALUE self)
|
|
|
996
1037
|
because in-place chain eval allocates no scratch; only attach (xfer_all
|
|
997
1038
|
→ output) and the parent's own xfer_stride alloc, neither of which we
|
|
998
1039
|
count here. */
|
|
1040
|
+
#ifdef CARRAY_DEV_BUILD
|
|
999
1041
|
static VALUE
|
|
1000
1042
|
rb_ca_monop_s_reset_scratch_counter (VALUE klass)
|
|
1001
1043
|
{
|
|
@@ -1021,6 +1063,7 @@ rb_ca_monop_s_materialise_count (VALUE klass)
|
|
|
1021
1063
|
{
|
|
1022
1064
|
return SIZE2NUM(ca_monop_materialise_call_count);
|
|
1023
1065
|
}
|
|
1066
|
+
#endif /* CARRAY_DEV_BUILD */
|
|
1024
1067
|
|
|
1025
1068
|
static VALUE
|
|
1026
1069
|
rb_ca_monop_s_allocate (VALUE klass)
|
|
@@ -1108,6 +1151,7 @@ Init_ca_obj_monop (void)
|
|
|
1108
1151
|
rb_define_const(rb_cCAMonOp, "OP_RAD_PI", INT2NUM(CA_MONOP_RAD_PI));
|
|
1109
1152
|
rb_define_const(rb_cCAMonOp, "OP_SIGN", INT2NUM(CA_MONOP_SIGN));
|
|
1110
1153
|
rb_define_const(rb_cCAMonOp, "OP_ARG_I", INT2NUM(CA_MONOP_ARG_I));
|
|
1154
|
+
rb_define_const(rb_cCAMonOp, "OP_BYTE_SWAP", INT2NUM(CA_MONOP_BYTE_SWAP));
|
|
1111
1155
|
rb_define_const(rb_cCAMonOp, "CAST_BASE", INT2NUM(CA_MONOP_CAST_BASE));
|
|
1112
1156
|
|
|
1113
1157
|
rb_define_alloc_func(rb_cCAMonOp, rb_ca_monop_s_allocate);
|
|
@@ -1119,10 +1163,10 @@ Init_ca_obj_monop (void)
|
|
|
1119
1163
|
rb_define_singleton_method(rb_cCAMonOp, "__build__",
|
|
1120
1164
|
rb_ca_monop_s_build, 2);
|
|
1121
1165
|
|
|
1122
|
-
/* Lazy-view predicate
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1166
|
+
/* Lazy-view predicate on CArray (covers CAMonOp and CALazyMarker).
|
|
1167
|
+
Protected: the lazy dispatch asks it of the other operands. */
|
|
1168
|
+
rb_define_protected_method(rb_cCArray, "lazy_view?",
|
|
1169
|
+
rb_ca_is_lazy_view_p, 0);
|
|
1126
1170
|
|
|
1127
1171
|
/* op_id accessor for inspect / dump_tree consumers in Ruby. */
|
|
1128
1172
|
rb_define_method(rb_cCAMonOp, "__op_id__",
|
|
@@ -1130,6 +1174,7 @@ Init_ca_obj_monop (void)
|
|
|
1130
1174
|
rb_define_method(rb_cCAMonOp, "__trapping__", rb_ca_monop_trapping, 0);
|
|
1131
1175
|
|
|
1132
1176
|
/* Test instrumentation (not user-facing API). */
|
|
1177
|
+
#ifdef CARRAY_DEV_BUILD
|
|
1133
1178
|
rb_define_singleton_method(rb_cCAMonOp, "__reset_scratch_counter__",
|
|
1134
1179
|
rb_ca_monop_s_reset_scratch_counter, 0);
|
|
1135
1180
|
rb_define_singleton_method(rb_cCAMonOp, "__scratch_count__",
|
|
@@ -1138,4 +1183,5 @@ Init_ca_obj_monop (void)
|
|
|
1138
1183
|
rb_ca_monop_s_reset_materialise_counter, 0);
|
|
1139
1184
|
rb_define_singleton_method(rb_cCAMonOp, "__materialise_count__",
|
|
1140
1185
|
rb_ca_monop_s_materialise_count, 0);
|
|
1186
|
+
#endif
|
|
1141
1187
|
}
|