carray 3.0.5 → 3.0.6
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 +233 -0
- data/README.md +1 -1
- data/carray.gemspec +3 -2
- data/ext/ca_axis_dispatch.c +6 -0
- data/ext/ca_axis_group.c +1 -1
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.c +116 -231
- data/ext/ca_kernel_iterator.h +410 -254
- data/ext/ca_obj_bincmp.c +9 -1
- data/ext/ca_obj_binop.c +10 -1
- data/ext/ca_obj_bitfield.c +2 -0
- data/ext/ca_obj_byte_swap.c +2 -0
- data/ext/ca_obj_face.c +2 -0
- data/ext/ca_obj_fake.c +3 -1
- data/ext/ca_obj_grid.c +167 -12
- data/ext/ca_obj_meld.c +69 -113
- data/ext/ca_obj_moncmp.c +9 -1
- data/ext/ca_obj_monop.c +40 -2
- data/ext/ca_obj_object.c +54 -20
- data/ext/ca_obj_reduce.c +15 -1
- data/ext/ca_obj_refer.c +65 -20
- data/ext/ca_obj_remap.c +69 -10
- data/ext/ca_obj_roll.c +1 -0
- data/ext/ca_obj_select.c +4 -1
- data/ext/ca_obj_select_axis.c +1 -0
- data/ext/ca_obj_shift.c +1 -0
- data/ext/ca_obj_stack.c +310 -111
- data/ext/ca_obj_stride.c +131 -45
- data/ext/ca_obj_string.c +18 -2
- data/ext/ca_obj_tile.c +1 -0
- data/ext/ca_obj_triop.c +9 -1
- data/ext/ca_obj_window.c +1 -0
- data/ext/ca_op_ipower.c +8 -8
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +2 -1
- data/ext/carray_access.c +27 -64
- data/ext/carray_address_basis.c +134 -0
- data/ext/carray_attribute.c +8 -0
- data/ext/carray_broadcast.c +3 -4
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_cast.c +8 -11
- data/ext/carray_conversion.c +9 -5
- data/ext/carray_core.c +811 -72
- data/ext/carray_element.c +13 -9
- data/ext/carray_histogram.c +25 -3
- data/ext/carray_internal.h +147 -12
- data/ext/carray_kernels_bincmp.c +2007 -3
- data/ext/carray_kernels_binop.c +25365 -5199
- data/ext/carray_kernels_init.c +8 -8
- data/ext/carray_kernels_monop.c +10696 -3678
- data/ext/carray_kernels_reduce_aggregate.c +4429 -702
- data/ext/carray_kernels_reduce_boolean.c +1533 -15
- data/ext/carray_kernels_reduce_cumulative.c +1808 -248
- data/ext/carray_kernels_reduce_extreme.c +4508 -511
- data/ext/carray_kernels_reduce_variance.c +2284 -152
- data/ext/carray_kernels_scan.c +240 -240
- data/ext/carray_kernels_search.c +4211 -264
- data/ext/carray_kernels_sort.c +367 -450
- data/ext/carray_lazy.c +47 -0
- data/ext/carray_loop.c +1 -1
- data/ext/carray_mask.c +130 -139
- data/ext/carray_median_percentile.c +4 -4
- data/ext/carray_memory_view.c +13 -7
- data/ext/carray_operator.c +147 -44
- data/ext/carray_order.c +3 -2
- data/ext/carray_random.c +4 -1
- data/ext/carray_slab.c +97 -21
- data/ext/carray_sort.c +1 -1
- data/ext/carray_test.c +74 -19
- data/ext/carray_time_text.c +2 -2
- data/ext/extconf.rb +11 -0
- data/ext/mkkernel.rb +346 -94
- data/ext/ruby_carray.c +4 -1
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +25 -1
- data/lib/carray/autoload_carray.rb +3 -3
- data/lib/carray/autoload_method_extension.rb +5 -3
- data/lib/carray/axis_group.rb +13 -7
- data/lib/carray/basics.rb +1 -1
- data/lib/carray/block_iterator.rb +17 -3
- data/lib/carray/categorical.rb +6 -8
- data/lib/carray/categorical_iterator.rb +2 -2
- data/lib/carray/complex.rb +2 -2
- data/lib/carray/conditional.rb +3 -2
- data/lib/carray/frame/column_verbs.rb +45 -14
- data/lib/carray/frame/convert.rb +19 -0
- data/lib/carray/frame/csv_parser.rb +32 -32
- data/lib/carray/frame/describe.rb +4 -2
- data/lib/carray/frame/frame.rb +399 -78
- data/lib/carray/frame/group.rb +679 -53
- data/lib/carray/frame/io.rb +209 -71
- data/lib/carray/frame/join.rb +146 -37
- data/lib/carray/frame/records.rb +3 -3
- data/lib/carray/frame/reshape.rb +89 -11
- data/lib/carray/frame/sort.rb +57 -9
- data/lib/carray/frame/verbs.rb +384 -49
- data/lib/carray/frame/windows.rb +44 -6
- data/lib/carray/inspect.rb +7 -2
- data/lib/carray/iterator.rb +32 -0
- data/lib/carray/lazy.rb +17 -8
- data/lib/carray/mask_gap_fill.rb +37 -17
- data/lib/carray/meld_reduce.rb +1 -1
- data/lib/carray/methods/choose.rb +3 -2
- data/lib/carray/methods/meshgrid.rb +3 -1
- data/lib/carray/runtime.rb +47 -8
- data/lib/carray/segment_iterator.rb +23 -8
- data/lib/carray/serialize.rb +34 -17
- data/lib/carray/stack.rb +18 -6
- data/lib/carray/time.rb +5 -0
- data/lib/carray/window_iterator.rb +16 -4
- data/yard-stubs/ca_obj_array.rb +26 -1
- data/yard-stubs/carray_cast.rb +8 -5
- data/yard-stubs/carray_conversion.rb +8 -2
- data/yard-stubs/carray_mask.rb +20 -1
- data/yard-stubs/carray_math.rb +31 -16
- data/yard-stubs/carray_memory_view.rb +7 -0
- data/yard-stubs/carray_test.rb +7 -4
- metadata +18 -4
data/ext/ca_obj_bincmp.c
CHANGED
|
@@ -291,9 +291,11 @@ ca_bincmp_try_leaf_inplace (CArray *op, int8_t common_dt,
|
|
|
291
291
|
|
|
292
292
|
/* Evaluate the cells a request names into `data` (packed, n cells). */
|
|
293
293
|
static void
|
|
294
|
-
|
|
294
|
+
ca_bincmp_eval_cells (void *node, const ca_lazy_req_t *req, void *data, int dir)
|
|
295
295
|
{
|
|
296
|
+
CABinCmp *bc = (CABinCmp *) node;
|
|
296
297
|
ca_size_t slab_n = req->n;
|
|
298
|
+
(void) dir;
|
|
297
299
|
int8_t k;
|
|
298
300
|
void *left_scratch, *right_scratch;
|
|
299
301
|
ca_size_t left_bytes, right_bytes;
|
|
@@ -437,6 +439,12 @@ ca_bincmp_eval (CABinCmp *bc, const ca_lazy_req_t *req, void *data)
|
|
|
437
439
|
if ( ! left_is_inplace ) ca_lazy_arena_release(left_scratch);
|
|
438
440
|
}
|
|
439
441
|
|
|
442
|
+
static void
|
|
443
|
+
ca_bincmp_eval (CABinCmp *bc, const ca_lazy_req_t *req, void *data)
|
|
444
|
+
{
|
|
445
|
+
ca_lazy_eval_recorded(bc, 2, bc->operands, 0, NULL, ca_bincmp_eval_cells, req, data, CA_XFER_GET);
|
|
446
|
+
}
|
|
447
|
+
|
|
440
448
|
static void
|
|
441
449
|
ca_bincmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
442
450
|
ca_size_t *strides, void *data, int dir)
|
data/ext/ca_obj_binop.c
CHANGED
|
@@ -249,9 +249,11 @@ ca_size_t ca_binop_materialise_call_count = 0;
|
|
|
249
249
|
|
|
250
250
|
/* Evaluate the cells a request names into `data` (packed, n cells). */
|
|
251
251
|
static void
|
|
252
|
-
|
|
252
|
+
ca_binop_eval_cells (void *node, const ca_lazy_req_t *req, void *data, int dir)
|
|
253
253
|
{
|
|
254
|
+
CABinOp *bo = (CABinOp *) node;
|
|
254
255
|
ca_size_t slab_n = req->n;
|
|
256
|
+
(void) dir;
|
|
255
257
|
int8_t k;
|
|
256
258
|
void *scratch;
|
|
257
259
|
volatile VALUE holder;
|
|
@@ -350,6 +352,13 @@ ca_binop_eval (CABinOp *bo, const ca_lazy_req_t *req, void *data)
|
|
|
350
352
|
ca_lazy_arena_release(scratch);
|
|
351
353
|
}
|
|
352
354
|
|
|
355
|
+
static void
|
|
356
|
+
ca_binop_eval (CABinOp *bo, const ca_lazy_req_t *req, void *data)
|
|
357
|
+
{
|
|
358
|
+
ca_lazy_eval_recorded(bo, 2, bo->operands, 0, NULL, ca_binop_eval_cells,
|
|
359
|
+
req, data, CA_XFER_GET);
|
|
360
|
+
}
|
|
361
|
+
|
|
353
362
|
static void
|
|
354
363
|
ca_binop_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
355
364
|
ca_size_t *strides, void *data, int dir)
|
data/ext/ca_obj_bitfield.c
CHANGED
data/ext/ca_obj_byte_swap.c
CHANGED
|
@@ -491,7 +491,9 @@ ca_byte_swap_func_sync (void *ap)
|
|
|
491
491
|
ca_byte_swap_apply(ca, tmp);
|
|
492
492
|
memcpy(ca->parent->ptr, tmp, ca_length(ca));
|
|
493
493
|
ALLOCV_END(holder);
|
|
494
|
+
ca_view_pass_mask_to_parent(ca);
|
|
494
495
|
ca_sync(ca->parent);
|
|
496
|
+
ca_view_sync_mask_after_parent(ca);
|
|
495
497
|
}
|
|
496
498
|
|
|
497
499
|
static void
|
data/ext/ca_obj_face.c
CHANGED
data/ext/ca_obj_fake.c
CHANGED
|
@@ -310,12 +310,14 @@ ca_fake_func_sync (void *ap)
|
|
|
310
310
|
ca_update_mask(ca);
|
|
311
311
|
if ( ca->mask ) {
|
|
312
312
|
ca_cast_block_with_mask(ca->elements, ca, ca->ptr, ca->parent, ca->parent->ptr,
|
|
313
|
-
(boolean8_t *)ca->
|
|
313
|
+
(boolean8_t *)ca->mask->ptr);
|
|
314
314
|
}
|
|
315
315
|
else {
|
|
316
316
|
ca_cast_block(ca->elements, ca, ca->ptr, ca->parent, ca->parent->ptr);
|
|
317
317
|
}
|
|
318
|
+
ca_view_pass_mask_to_parent(ca);
|
|
318
319
|
ca_sync(ca->parent);
|
|
320
|
+
ca_view_sync_mask_after_parent(ca);
|
|
319
321
|
}
|
|
320
322
|
|
|
321
323
|
static void
|
data/ext/ca_obj_grid.c
CHANGED
|
@@ -490,11 +490,86 @@ cag_parent_addr (const CAGrid *ca, const ca_size_t *idx, ca_size_t *paddr)
|
|
|
490
490
|
return hole;
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
+
/* The parent addresses (paddrs, may be NULL) and the hole marks of every
|
|
494
|
+
view cell in address order: a walk over the outer axes with the
|
|
495
|
+
innermost axis a run, its indices and holes read off the axis. A 1-D
|
|
496
|
+
index axis is its own index and hole arrays. */
|
|
497
|
+
static void
|
|
498
|
+
cag_parent_addrs_whole (const CAGrid *ca, ca_size_t *paddrs, uint8_t *hole)
|
|
499
|
+
{
|
|
500
|
+
int8_t ndim = ca->ndim;
|
|
501
|
+
int8_t inner = ndim - 1;
|
|
502
|
+
const cag_axis_t *last = &ca->axes[inner];
|
|
503
|
+
ca_size_t count = last->count;
|
|
504
|
+
ca_size_t pdim = ca->parent->dim[inner];
|
|
505
|
+
ca_size_t idx[CA_RANK_MAX];
|
|
506
|
+
ca_size_t i = 0, j;
|
|
507
|
+
int8_t k;
|
|
508
|
+
|
|
509
|
+
if ( ndim == 1 && last->kind == CAG_AXIS_INDEX ) {
|
|
510
|
+
if ( paddrs ) {
|
|
511
|
+
memcpy(paddrs, last->indices, (size_t) count * sizeof(ca_size_t));
|
|
512
|
+
}
|
|
513
|
+
if ( last->holes ) {
|
|
514
|
+
memcpy(hole, last->holes, (size_t) count);
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
memset(hole, 0, (size_t) count);
|
|
518
|
+
}
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
if ( count == 0 || ca->elements == 0 ) {
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
for (k = 0; k < ndim; k++) {
|
|
525
|
+
idx[k] = 0;
|
|
526
|
+
}
|
|
527
|
+
/* empty: returned above when the view has no cell */
|
|
528
|
+
while ( 1 ) {
|
|
529
|
+
ca_size_t base = 0;
|
|
530
|
+
uint8_t outer_hole = 0;
|
|
531
|
+
for (k = 0; k < inner; k++) {
|
|
532
|
+
const cag_axis_t *ax = &ca->axes[k];
|
|
533
|
+
if ( ax->kind == CAG_AXIS_INDEX && ax->holes && ax->holes[idx[k]] ) {
|
|
534
|
+
outer_hole = 1;
|
|
535
|
+
}
|
|
536
|
+
base = base * ca->parent->dim[k] + cag_parent_index_for(ax, idx[k]);
|
|
537
|
+
}
|
|
538
|
+
base *= pdim;
|
|
539
|
+
if ( last->kind == CAG_AXIS_INDEX ) {
|
|
540
|
+
const ca_size_t *ix = last->indices;
|
|
541
|
+
const uint8_t *hx = last->holes;
|
|
542
|
+
for (j = 0; j < count; j++) {
|
|
543
|
+
if ( paddrs ) {
|
|
544
|
+
paddrs[i + j] = base + ix[j];
|
|
545
|
+
}
|
|
546
|
+
hole[i + j] = (uint8_t) (outer_hole | (hx ? hx[j] : 0));
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
for (j = 0; j < count; j++) {
|
|
551
|
+
if ( paddrs ) {
|
|
552
|
+
paddrs[i + j] = base + last->start + j * last->step;
|
|
553
|
+
}
|
|
554
|
+
hole[i + j] = outer_hole;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
i += count;
|
|
558
|
+
for (k = inner - 1; k >= 0; k--) {
|
|
559
|
+
if ( ++idx[k] < ca->dim[k] ) break;
|
|
560
|
+
idx[k] = 0;
|
|
561
|
+
}
|
|
562
|
+
if ( k < 0 ) break;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
493
566
|
/* The transfer of a grid with holes, for the view cells at addrs (NULL:
|
|
494
|
-
the whole view in order). The parent is asked
|
|
495
|
-
addresses. A GET reads every cell, a hole reading the
|
|
496
|
-
of its holed axes (in a mask grid it is then set true); a
|
|
497
|
-
the holes out.
|
|
567
|
+
the whole view in order, walked axis by axis). The parent is asked
|
|
568
|
+
for one batch of addresses. A GET reads every cell, a hole reading the
|
|
569
|
+
cell at index 0 of its holed axes (in a mask grid it is then set true); a
|
|
570
|
+
PUT leaves the holes out. A mask grid reading its owner's stand-in reads
|
|
571
|
+
nothing: the stand-in is all false at rest (a write to it is settled
|
|
572
|
+
into the parent's mask at once), so the holes are the whole answer. */
|
|
498
573
|
static void
|
|
499
574
|
ca_grid_holed_xfer (CAGrid *ca, ca_size_t n, const ca_size_t *addrs,
|
|
500
575
|
char *data, int dir)
|
|
@@ -511,11 +586,43 @@ ca_grid_holed_xfer (CAGrid *ca, ca_size_t n, const ca_size_t *addrs,
|
|
|
511
586
|
}
|
|
512
587
|
cag_mask_current(ca);
|
|
513
588
|
parent = ca->parent;
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
589
|
+
|
|
590
|
+
if ( dir == CA_XFER_GET && ca->holes_read_masked && ca->mask_owner != NULL
|
|
591
|
+
&& parent == ca->mask_owner->mask_standin ) {
|
|
592
|
+
if ( ! addrs ) {
|
|
593
|
+
cag_parent_addrs_whole(ca, NULL, (uint8_t *) data);
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
for (i = 0; i < n; i++) {
|
|
597
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
598
|
+
((boolean8_t *) data)[i] = (boolean8_t) cag_parent_addr(ca, idx, &m);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
if ( dir == CA_XFER_GET && ! addrs && ca->ndim == 1
|
|
605
|
+
&& ( parent->obj_type == CA_OBJ_ARRAY || parent->obj_type == CA_OBJ_ARRAY_WRAP
|
|
606
|
+
|| parent->obj_type == CA_OBJ_SCALAR ) ) {
|
|
607
|
+
/* A 1-D grid read whole from an array of its own: its index axis's
|
|
608
|
+
index and hole arrays are the batch as they are. Another parent's
|
|
609
|
+
transfer (a view, a CAObject's hook) takes a copy it may write on,
|
|
610
|
+
as a PUT does, which compacts the batch. */
|
|
611
|
+
paddrs = ca->axes[0].indices;
|
|
612
|
+
hole = ca->axes[0].holes;
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
paddrs = ALLOCV_N(ca_size_t, h_addr, n);
|
|
616
|
+
hole = ALLOCV_N(uint8_t, h_hole, n);
|
|
617
|
+
if ( ! addrs ) {
|
|
618
|
+
cag_parent_addrs_whole(ca, paddrs, hole);
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
for (i = 0; i < n; i++) {
|
|
622
|
+
ca_addr2index((CArray *) ca, addrs[i], idx);
|
|
623
|
+
hole[i] = (uint8_t) cag_parent_addr(ca, idx, &paddrs[i]);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
519
626
|
}
|
|
520
627
|
|
|
521
628
|
if ( dir == CA_XFER_GET ) {
|
|
@@ -712,6 +819,50 @@ ca_grid_func_fold_stride (void *ap, ca_fold_t *f, void **next_parent)
|
|
|
712
819
|
return 1;
|
|
713
820
|
}
|
|
714
821
|
|
|
822
|
+
/* A region of a grid with holes: its view addresses as one batch to the
|
|
823
|
+
holed transfer, or none when the region is the whole view in order. */
|
|
824
|
+
static void
|
|
825
|
+
cag_holed_xfer_stride (CAGrid *g, const ca_size_t *starts, const ca_size_t *counts,
|
|
826
|
+
const ca_size_t *strides, char *data, int dir)
|
|
827
|
+
{
|
|
828
|
+
int8_t ndim = g->ndim;
|
|
829
|
+
ca_size_t gnative[CA_RANK_MAX], idx[CA_RANK_MAX];
|
|
830
|
+
ca_size_t n = 1, i, s, base = 0;
|
|
831
|
+
ca_size_t *addrs;
|
|
832
|
+
volatile VALUE holder = 0;
|
|
833
|
+
int whole = 1;
|
|
834
|
+
int8_t k;
|
|
835
|
+
|
|
836
|
+
s = g->bytes;
|
|
837
|
+
for (k = ndim - 1; k >= 0; k--) { gnative[k] = s; s *= g->dim[k]; }
|
|
838
|
+
for (k = 0; k < ndim; k++) {
|
|
839
|
+
n *= counts[k];
|
|
840
|
+
base += starts[k] * gnative[k];
|
|
841
|
+
if ( starts[k] != 0 || counts[k] != g->dim[k] || strides[k] != gnative[k] ) {
|
|
842
|
+
whole = 0;
|
|
843
|
+
}
|
|
844
|
+
idx[k] = 0;
|
|
845
|
+
}
|
|
846
|
+
if ( whole ) {
|
|
847
|
+
ca_grid_holed_xfer(g, n, NULL, data, dir);
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
addrs = ALLOCV_N(ca_size_t, holder, n);
|
|
851
|
+
for (i = 0; i < n; i++) {
|
|
852
|
+
ca_size_t goff = base;
|
|
853
|
+
for (k = 0; k < ndim; k++) {
|
|
854
|
+
goff += idx[k] * strides[k];
|
|
855
|
+
}
|
|
856
|
+
addrs[i] = goff / g->bytes;
|
|
857
|
+
for (k = ndim - 1; k >= 0; k--) {
|
|
858
|
+
if ( ++idx[k] < counts[k] ) break;
|
|
859
|
+
idx[k] = 0;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
ca_grid_holed_xfer(g, n, addrs, data, dir);
|
|
863
|
+
ALLOCV_END(holder);
|
|
864
|
+
}
|
|
865
|
+
|
|
715
866
|
/* xfer_stride: structural region delivery when CAGrid is the (declining)
|
|
716
867
|
fold boundary -- a multi-element INDEX axis. Instead of materialising
|
|
717
868
|
the whole grid, deliver only the requested region using the per-axis
|
|
@@ -763,9 +914,12 @@ ca_grid_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
763
914
|
/* The request is over the view's addresses, so a transposed / flat request
|
|
764
915
|
is legal and must not be composed axis-by-axis; see
|
|
765
916
|
ca_xfer_stride_request_is_axis_box (carray.h). */
|
|
766
|
-
if ( cag_has_holes(g)
|
|
767
|
-
|
|
768
|
-
|
|
917
|
+
if ( cag_has_holes(g) ) {
|
|
918
|
+
cag_holed_xfer_stride(g, starts, counts, strides, d, dir);
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
if ( ! ca_xfer_stride_request_is_axis_box(g, starts, counts, strides) ) {
|
|
922
|
+
aligned = 0;
|
|
769
923
|
}
|
|
770
924
|
else {
|
|
771
925
|
for (k = 0; k < ndim; k++) {
|
|
@@ -1548,6 +1702,7 @@ Init_ca_obj_grid (void)
|
|
|
1548
1702
|
&cagrid_data_type,
|
|
1549
1703
|
rb_cCAGridMask,
|
|
1550
1704
|
&cagrid_mask_data_type, &ca_grid_func, sizeof(ca_grid_func));
|
|
1705
|
+
ca_register_cell_moving_view(CA_OBJ_GRID);
|
|
1551
1706
|
rb_define_const(rb_cObject, "CA_OBJ_GRID", INT2NUM(CA_OBJ_GRID));
|
|
1552
1707
|
|
|
1553
1708
|
rb_define_method(rb_cCArray, "grid", rb_ca_grid, -1);
|
data/ext/ca_obj_meld.c
CHANGED
|
@@ -686,7 +686,7 @@ ca_meld_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
686
686
|
structural = 0;
|
|
687
687
|
}
|
|
688
688
|
|
|
689
|
-
if ( ! structural || !
|
|
689
|
+
if ( ! structural || ! ca_fast_path(CA_SC_MELD_STRIDE_BOX) ) {
|
|
690
690
|
ca_meld_xfer_stride_per_cell(ca, starts, counts, strides, data, dir);
|
|
691
691
|
return;
|
|
692
692
|
}
|
|
@@ -702,16 +702,23 @@ ca_meld_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
702
702
|
/* xfer_all */
|
|
703
703
|
/* ------------------------------------------------------------------- */
|
|
704
704
|
|
|
705
|
-
/* A parent's cells, delivered (PUT).
|
|
706
|
-
buffer the parent's attach handed out, rather than through the
|
|
707
|
-
what is behind it: the sync of an
|
|
708
|
-
|
|
709
|
-
own sync would push the stale buffer back over the cells just written.
|
|
705
|
+
/* A parent's cells, delivered (PUT). A non-NULL sync_error writes them
|
|
706
|
+
into the buffer the parent's attach handed out, rather than through the
|
|
707
|
+
parent to what is behind it, and syncs the parent: the sync of an
|
|
708
|
+
attached meld. Writing past the buffer would leave it stale, and the parent's
|
|
709
|
+
own sync would push the stale buffer back over the cells just written.
|
|
710
|
+
A parent with no buffer out (a stand-in the trial of a write puts in
|
|
711
|
+
place, which is never attached) has nothing to go stale: the cells go
|
|
712
|
+
through it. */
|
|
710
713
|
static void
|
|
711
|
-
ca_meld_put_parent (CArray *p, char *src,
|
|
714
|
+
ca_meld_put_parent (CArray *p, char *src, volatile VALUE *sync_error)
|
|
712
715
|
{
|
|
713
|
-
if (
|
|
716
|
+
if ( sync_error != NULL && p->ptr != NULL ) {
|
|
717
|
+
/* Synced at once, before the next part is written: parts that share
|
|
718
|
+
cells then take the write of the last of them, as a write through
|
|
719
|
+
the parts does. */
|
|
714
720
|
memcpy(p->ptr, src, (size_t) (p->elements * p->bytes));
|
|
721
|
+
ca_sync_carry_on(p, sync_error);
|
|
715
722
|
}
|
|
716
723
|
else {
|
|
717
724
|
ca_xfer_all(p, src, CA_XFER_PUT);
|
|
@@ -720,7 +727,7 @@ ca_meld_put_parent (CArray *p, char *src, int into_buffers)
|
|
|
720
727
|
|
|
721
728
|
/* meld_axis == 0 best path: K contig xfer_all at prefix-sum offsets. */
|
|
722
729
|
static void
|
|
723
|
-
ca_meld_xfer_all_ma0 (CAMeld *ca, void *data, int dir,
|
|
730
|
+
ca_meld_xfer_all_ma0 (CAMeld *ca, void *data, int dir, volatile VALUE *sync_error)
|
|
724
731
|
{
|
|
725
732
|
ca_size_t tail_bytes = ca_meld_tail_elements(ca) * ca->bytes;
|
|
726
733
|
char *d = (char *) data;
|
|
@@ -728,7 +735,7 @@ ca_meld_xfer_all_ma0 (CAMeld *ca, void *data, int dir, int into_buffers)
|
|
|
728
735
|
for ( k = 0; k < ca->n_parents; k++ ) {
|
|
729
736
|
char *seg = d + ca->seg_offset[k] * tail_bytes;
|
|
730
737
|
if ( dir == CA_XFER_PUT ) {
|
|
731
|
-
ca_meld_put_parent(ca->parents[k], seg,
|
|
738
|
+
ca_meld_put_parent(ca->parents[k], seg, sync_error);
|
|
732
739
|
}
|
|
733
740
|
else {
|
|
734
741
|
ca_xfer_all(ca->parents[k], seg, dir);
|
|
@@ -750,7 +757,7 @@ ca_meld_xfer_all_ma0 (CAMeld *ca, void *data, int dir, int into_buffers)
|
|
|
750
757
|
chunked memcpy approaches memcpy bandwidth (eager parity target). */
|
|
751
758
|
static void
|
|
752
759
|
ca_meld_xfer_all_ma_internal (CAMeld *ca, void *data, int dir,
|
|
753
|
-
|
|
760
|
+
volatile VALUE *sync_error)
|
|
754
761
|
{
|
|
755
762
|
int8_t ma = ca->meld_axis;
|
|
756
763
|
int8_t ndim = ca->ndim;
|
|
@@ -780,6 +787,12 @@ ca_meld_xfer_all_ma_internal (CAMeld *ca, void *data, int dir,
|
|
|
780
787
|
ca_size_t voff;
|
|
781
788
|
int8_t i;
|
|
782
789
|
|
|
790
|
+
/* A parent with no cells moves nothing. The walks below copy one
|
|
791
|
+
chunk before they look at the outer extents, so a parent empty along
|
|
792
|
+
an outer axis would copy a chunk out of a 0-byte buffer. sync comes
|
|
793
|
+
here without the slot's own check on the view. */
|
|
794
|
+
if ( p->elements == 0 ) continue;
|
|
795
|
+
|
|
783
796
|
buf = ALLOCV_N(char, holder, slab_bytes);
|
|
784
797
|
|
|
785
798
|
if ( dir == CA_XFER_GET ) {
|
|
@@ -837,19 +850,19 @@ ca_meld_xfer_all_ma_internal (CAMeld *ca, void *data, int dir,
|
|
|
837
850
|
}
|
|
838
851
|
|
|
839
852
|
if ( dir == CA_XFER_PUT ) {
|
|
840
|
-
ca_meld_put_parent(p, buf,
|
|
853
|
+
ca_meld_put_parent(p, buf, sync_error);
|
|
841
854
|
}
|
|
842
855
|
ALLOCV_END(holder);
|
|
843
856
|
}
|
|
844
857
|
}
|
|
845
858
|
|
|
846
859
|
static void
|
|
847
|
-
ca_meld_xfer_parents (CAMeld *ca, void *data, int dir,
|
|
860
|
+
ca_meld_xfer_parents (CAMeld *ca, void *data, int dir, volatile VALUE *sync_error)
|
|
848
861
|
{
|
|
849
|
-
if ( ca->meld_axis == 0 &&
|
|
850
|
-
ca_meld_xfer_all_ma0(ca, data, dir,
|
|
862
|
+
if ( ca->meld_axis == 0 && ca_fast_path(CA_SC_MELD_PARENTS_AXIS0) ) {
|
|
863
|
+
ca_meld_xfer_all_ma0(ca, data, dir, sync_error);
|
|
851
864
|
} else {
|
|
852
|
-
ca_meld_xfer_all_ma_internal(ca, data, dir,
|
|
865
|
+
ca_meld_xfer_all_ma_internal(ca, data, dir, sync_error);
|
|
853
866
|
}
|
|
854
867
|
}
|
|
855
868
|
|
|
@@ -858,7 +871,7 @@ ca_meld_func_xfer_all (void *ap, void *data, int dir)
|
|
|
858
871
|
{
|
|
859
872
|
if ( ((CArray *) ap)->elements == 0 ) return;
|
|
860
873
|
ca_meld_mask_refresh((CAMeld *) ap);
|
|
861
|
-
ca_meld_xfer_parents((CAMeld *) ap, data, dir,
|
|
874
|
+
ca_meld_xfer_parents((CAMeld *) ap, data, dir, NULL);
|
|
862
875
|
}
|
|
863
876
|
|
|
864
877
|
/* ------------------------------------------------------------------- */
|
|
@@ -890,15 +903,19 @@ ca_meld_func_attach (void *ap)
|
|
|
890
903
|
ca_fill_or_detach(ca->n_parents, ca->parents, ca_meld_attach_owned, (VALUE) ca);
|
|
891
904
|
}
|
|
892
905
|
|
|
893
|
-
static void ca_meld_mask_refuse_sync (CAMeld *ca);
|
|
894
|
-
|
|
895
906
|
static void
|
|
896
907
|
ca_meld_func_sync (void *ap)
|
|
897
908
|
{
|
|
898
909
|
CAMeld *ca = (CAMeld *) ap;
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
910
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ca, t,
|
|
911
|
+
ca_meld_xfer_parents((CAMeld *) t, ca->ptr, CA_XFER_PUT, NULL));
|
|
912
|
+
{
|
|
913
|
+
volatile VALUE error = Qnil;
|
|
914
|
+
ca_meld_xfer_parents(ca, ca->ptr, CA_XFER_PUT, &error);
|
|
915
|
+
if ( ! NIL_P(error) ) {
|
|
916
|
+
rb_exc_raise(error);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
902
919
|
ca_meld_mask_settle(ca);
|
|
903
920
|
}
|
|
904
921
|
|
|
@@ -971,79 +988,21 @@ ca_meld_func_fold_stride (void *ap, ca_fold_t *f, void **next_parent)
|
|
|
971
988
|
/* ------------------------------------------------------------------- */
|
|
972
989
|
|
|
973
990
|
/* The table's write slots: after a write that may have put a true into a
|
|
974
|
-
stand-in, the true goes on to the parent's mask
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
(ca_multi_parent_mask_refuse_first), so that a write refused for a value
|
|
979
|
-
array or mask array part changes no other part. */
|
|
980
|
-
enum { CA_MELD_PUT_INDEX, CA_MELD_PUT_ADDRS, CA_MELD_PUT_STRIDE, CA_MELD_PUT_ALL,
|
|
981
|
-
CA_MELD_PUT_FILL, CA_MELD_PUT_SYNC, CA_MELD_PUT_FILL_ADDRS,
|
|
982
|
-
CA_MELD_PUT_FILL_STRIDE };
|
|
983
|
-
|
|
984
|
-
typedef struct {
|
|
985
|
-
int slot;
|
|
986
|
-
void *ap;
|
|
987
|
-
ca_size_t *idx;
|
|
988
|
-
ca_size_t n;
|
|
989
|
-
ca_size_t *addrs;
|
|
990
|
-
ca_size_t *starts;
|
|
991
|
-
ca_size_t *counts;
|
|
992
|
-
ca_size_t *strides;
|
|
993
|
-
void *data;
|
|
994
|
-
ca_size_t base;
|
|
995
|
-
int8_t ndim;
|
|
996
|
-
ca_size_t *steps;
|
|
997
|
-
} ca_meld_put_t;
|
|
998
|
-
|
|
999
|
-
static VALUE
|
|
1000
|
-
ca_meld_put_body (VALUE arg)
|
|
1001
|
-
{
|
|
1002
|
-
ca_meld_put_t *a = (ca_meld_put_t *) arg;
|
|
1003
|
-
switch ( a->slot ) {
|
|
1004
|
-
case CA_MELD_PUT_INDEX:
|
|
1005
|
-
ca_meld_func_xfer_index(a->ap, a->idx, a->data, CA_XFER_PUT); break;
|
|
1006
|
-
case CA_MELD_PUT_ADDRS:
|
|
1007
|
-
ca_meld_func_xfer_addrs(a->ap, a->n, a->addrs, a->data, CA_XFER_PUT); break;
|
|
1008
|
-
case CA_MELD_PUT_STRIDE:
|
|
1009
|
-
ca_meld_func_xfer_stride(a->ap, a->starts, a->counts, a->strides, a->data,
|
|
1010
|
-
CA_XFER_PUT); break;
|
|
1011
|
-
case CA_MELD_PUT_ALL:
|
|
1012
|
-
ca_meld_func_xfer_all(a->ap, a->data, CA_XFER_PUT); break;
|
|
1013
|
-
case CA_MELD_PUT_FILL:
|
|
1014
|
-
ca_meld_func_fill_data(a->ap, a->data); break;
|
|
1015
|
-
case CA_MELD_PUT_FILL_ADDRS:
|
|
1016
|
-
ca_fill_addrs_default(a->ap, a->n, a->addrs, a->data); break;
|
|
1017
|
-
case CA_MELD_PUT_FILL_STRIDE:
|
|
1018
|
-
ca_fill_stride_default(a->ap, a->base, a->ndim, a->counts, a->steps,
|
|
1019
|
-
a->data); break;
|
|
1020
|
-
case CA_MELD_PUT_SYNC:
|
|
1021
|
-
ca_meld_xfer_parents((CAMeld *) a->ap, ((CArray *) a->ap)->ptr, CA_XFER_PUT, 1);
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
return Qnil;
|
|
1025
|
-
}
|
|
1026
|
-
|
|
991
|
+
stand-in, the true goes on to the parent's mask (ca_mask_standin_settle).
|
|
992
|
+
Only the mask of a CAMeld has stand-ins. */
|
|
993
|
+
/* After a write of n cells of `data` to the mask of a CAMeld: a true
|
|
994
|
+
that went into a stand-in goes on to its parent's mask. */
|
|
1027
995
|
static void
|
|
1028
|
-
|
|
996
|
+
ca_meld_mask_adopt_before (void *ap, const void *data, ca_size_t n)
|
|
1029
997
|
{
|
|
1030
|
-
CAMeld *
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
998
|
+
CAMeld *ca = (CAMeld *) ap;
|
|
999
|
+
CAMeld *o = (CAMeld *) ca->mask_owner;
|
|
1000
|
+
if ( o != NULL && ca_mask_any_true(data, n) ) {
|
|
1001
|
+
ca_multi_parent_mask_adopt((CArray *) ca, o->parents, o->mask_standins,
|
|
1002
|
+
o->n_parents);
|
|
1035
1003
|
}
|
|
1036
1004
|
}
|
|
1037
1005
|
|
|
1038
|
-
static void
|
|
1039
|
-
ca_meld_mask_refuse_sync (CAMeld *ca)
|
|
1040
|
-
{
|
|
1041
|
-
ca_meld_put_t a = { CA_MELD_PUT_SYNC, ca, NULL, 0, NULL, NULL, NULL, NULL, NULL };
|
|
1042
|
-
ca_meld_mask_refuse_first(&a);
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
/* After a write of n cells of `data` to the mask of a CAMeld: a true
|
|
1046
|
-
that went into a stand-in goes on to its parent's mask. */
|
|
1047
1006
|
static void
|
|
1048
1007
|
ca_meld_mask_settle_after (CAMeld *ca, const void *data, ca_size_t n)
|
|
1049
1008
|
{
|
|
@@ -1055,10 +1014,7 @@ ca_meld_mask_settle_after (CAMeld *ca, const void *data, ca_size_t n)
|
|
|
1055
1014
|
static void
|
|
1056
1015
|
ca_meld_put_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
1057
1016
|
{
|
|
1058
|
-
if ( dir == CA_XFER_PUT )
|
|
1059
|
-
ca_meld_put_t a = { CA_MELD_PUT_INDEX, ap, idx, 0, NULL, NULL, NULL, NULL, data };
|
|
1060
|
-
ca_meld_mask_refuse_first(&a);
|
|
1061
|
-
}
|
|
1017
|
+
if ( dir == CA_XFER_PUT ) ca_meld_mask_adopt_before(ap, data, 1);
|
|
1062
1018
|
ca_meld_func_xfer_index(ap, idx, data, dir);
|
|
1063
1019
|
if ( dir == CA_XFER_PUT ) ca_meld_mask_settle_after((CAMeld *) ap, data, 1);
|
|
1064
1020
|
}
|
|
@@ -1068,8 +1024,9 @@ ca_meld_put_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data,
|
|
|
1068
1024
|
int dir)
|
|
1069
1025
|
{
|
|
1070
1026
|
if ( dir == CA_XFER_PUT ) {
|
|
1071
|
-
|
|
1072
|
-
|
|
1027
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t,
|
|
1028
|
+
ca_meld_func_xfer_addrs(t, n, addrs, data, dir));
|
|
1029
|
+
ca_meld_mask_adopt_before(ap, data, n);
|
|
1073
1030
|
}
|
|
1074
1031
|
ca_meld_func_xfer_addrs(ap, n, addrs, data, dir);
|
|
1075
1032
|
if ( dir == CA_XFER_PUT ) ca_meld_mask_settle_after((CAMeld *) ap, data, n);
|
|
@@ -1080,8 +1037,10 @@ ca_meld_put_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
1080
1037
|
ca_size_t *strides, void *data, int dir)
|
|
1081
1038
|
{
|
|
1082
1039
|
if ( dir == CA_XFER_PUT ) {
|
|
1083
|
-
|
|
1084
|
-
|
|
1040
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t,
|
|
1041
|
+
ca_meld_func_xfer_stride(t, starts, counts, strides, data, dir));
|
|
1042
|
+
ca_meld_mask_adopt_before(ap, data,
|
|
1043
|
+
ca_shape_elements(((CArray *) ap)->ndim, counts, 1));
|
|
1085
1044
|
}
|
|
1086
1045
|
ca_meld_func_xfer_stride(ap, starts, counts, strides, data, dir);
|
|
1087
1046
|
if ( dir == CA_XFER_PUT ) {
|
|
@@ -1094,8 +1053,8 @@ static void
|
|
|
1094
1053
|
ca_meld_put_xfer_all (void *ap, void *data, int dir)
|
|
1095
1054
|
{
|
|
1096
1055
|
if ( dir == CA_XFER_PUT ) {
|
|
1097
|
-
|
|
1098
|
-
|
|
1056
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t, ca_meld_func_xfer_all(t, data, dir));
|
|
1057
|
+
ca_meld_mask_adopt_before(ap, data, ((CArray *) ap)->elements);
|
|
1099
1058
|
}
|
|
1100
1059
|
ca_meld_func_xfer_all(ap, data, dir);
|
|
1101
1060
|
if ( dir == CA_XFER_PUT ) {
|
|
@@ -1106,23 +1065,17 @@ ca_meld_put_xfer_all (void *ap, void *data, int dir)
|
|
|
1106
1065
|
static void
|
|
1107
1066
|
ca_meld_put_fill_data (void *ap, void *ptr)
|
|
1108
1067
|
{
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
ca_meld_mask_refuse_first(&a);
|
|
1112
|
-
}
|
|
1068
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t, ca_meld_func_fill_data(t, ptr));
|
|
1069
|
+
ca_meld_mask_adopt_before(ap, ptr, 1);
|
|
1113
1070
|
ca_meld_func_fill_data(ap, ptr);
|
|
1114
1071
|
ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
|
|
1115
1072
|
}
|
|
1116
1073
|
|
|
1117
|
-
/* A fill of part of the mask goes cell by cell through xfer_index; run
|
|
1118
|
-
the whole of it against blank masks first, so that a cell refused late
|
|
1119
|
-
does not leave the cells before it written. */
|
|
1120
1074
|
static void
|
|
1121
1075
|
ca_meld_put_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
|
|
1122
1076
|
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
ca_meld_mask_refuse_first(&a);
|
|
1077
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t, ca_fill_addrs_default(t, n, addrs, ptr));
|
|
1078
|
+
ca_meld_mask_adopt_before(ap, ptr, 1);
|
|
1126
1079
|
ca_fill_addrs_default(ap, n, addrs, ptr);
|
|
1127
1080
|
ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
|
|
1128
1081
|
}
|
|
@@ -1131,9 +1084,9 @@ static void
|
|
|
1131
1084
|
ca_meld_put_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
1132
1085
|
ca_size_t *counts, ca_size_t *steps, void *ptr)
|
|
1133
1086
|
{
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1087
|
+
CA_MULTI_PARENT_VALUE_TRIAL(ap, t,
|
|
1088
|
+
ca_fill_stride_default(t, base, ndim, counts, steps, ptr));
|
|
1089
|
+
ca_meld_mask_adopt_before(ap, ptr, 1);
|
|
1137
1090
|
ca_fill_stride_default(ap, base, ndim, counts, steps, ptr);
|
|
1138
1091
|
ca_meld_mask_settle_after((CAMeld *) ap, ptr, 1);
|
|
1139
1092
|
}
|
|
@@ -1179,6 +1132,7 @@ rb_ca_meld_new (VALUE parents_ary, int8_t meld_axis)
|
|
|
1179
1132
|
VALUE p = rb_ary_entry(parents_ary, i);
|
|
1180
1133
|
rb_check_carray_object(p);
|
|
1181
1134
|
TypedData_Get_Struct(p, CArray, &carray_data_type, parents[i]);
|
|
1135
|
+
ca_multi_parent_check_part(parents[i], "meld");
|
|
1182
1136
|
}
|
|
1183
1137
|
ca = ca_meld_new((int32_t) n, parents, meld_axis);
|
|
1184
1138
|
obj = ca_wrap_struct(ca);
|
|
@@ -1244,6 +1198,7 @@ rb_ca_meld_initialize (int argc, VALUE *argv, VALUE self)
|
|
|
1244
1198
|
VALUE p = rb_ary_entry(list, i);
|
|
1245
1199
|
rb_check_carray_object(p);
|
|
1246
1200
|
TypedData_Get_Struct(p, CArray, &carray_data_type, parents[i]);
|
|
1201
|
+
ca_multi_parent_check_part(parents[i], "meld");
|
|
1247
1202
|
}
|
|
1248
1203
|
ca_meld_setup(ca, (int32_t) n, parents, meld_axis);
|
|
1249
1204
|
rb_ivar_set(self, id_parents, rb_ary_dup(list));
|
|
@@ -1339,6 +1294,7 @@ Init_ca_obj_meld (void)
|
|
|
1339
1294
|
&cameld_data_type,
|
|
1340
1295
|
rb_cCAMeldMask,
|
|
1341
1296
|
&cameld_mask_data_type, &ca_meld_func, sizeof(ca_meld_func));
|
|
1297
|
+
ca_register_cell_moving_view(CA_OBJ_MELD);
|
|
1342
1298
|
rb_define_const(rb_cObject, "CA_OBJ_MELD", INT2NUM(CA_OBJ_MELD));
|
|
1343
1299
|
|
|
1344
1300
|
id_parents = rb_intern("parents");
|
data/ext/ca_obj_moncmp.c
CHANGED
|
@@ -227,9 +227,11 @@ ca_moncmp_try_leaf_inplace (CArray *p,
|
|
|
227
227
|
|
|
228
228
|
/* Evaluate the cells a request names into `data` (packed, n cells). */
|
|
229
229
|
static void
|
|
230
|
-
|
|
230
|
+
ca_moncmp_eval_cells (void *node, const ca_lazy_req_t *req, void *data, int dir)
|
|
231
231
|
{
|
|
232
|
+
CAMonCmp *mc = (CAMonCmp *) node;
|
|
232
233
|
ca_size_t slab_n = req->n;
|
|
234
|
+
(void) dir;
|
|
233
235
|
void *scratch;
|
|
234
236
|
ca_size_t operand_bytes;
|
|
235
237
|
int is_contig;
|
|
@@ -295,6 +297,12 @@ ca_moncmp_eval (CAMonCmp *mc, const ca_lazy_req_t *req, void *data)
|
|
|
295
297
|
if ( ! scratch_is_inplace ) ca_lazy_arena_release(scratch);
|
|
296
298
|
}
|
|
297
299
|
|
|
300
|
+
static void
|
|
301
|
+
ca_moncmp_eval (CAMonCmp *mc, const ca_lazy_req_t *req, void *data)
|
|
302
|
+
{
|
|
303
|
+
ca_lazy_eval_recorded(mc, 1, &mc->parent, 0, NULL, ca_moncmp_eval_cells, req, data, CA_XFER_GET);
|
|
304
|
+
}
|
|
305
|
+
|
|
298
306
|
static void
|
|
299
307
|
ca_moncmp_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
300
308
|
ca_size_t *strides, void *data, int dir)
|