carray 3.0.0 → 3.0.2
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/.yardopts +2 -1
- data/CHANGELOG.md +845 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +33 -33
- data/carray.gemspec +12 -8
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +256 -114
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +121 -67
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +386 -74
- data/ext/ca_kernel_iterator.h +145 -45
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +88 -27
- data/ext/ca_obj_face.c +104 -0
- data/ext/ca_obj_face.h +48 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +21 -6
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +125 -22
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +107 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +178 -24
- data/ext/ca_obj_string.c +11 -5
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +94 -19
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +1 -5
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +362 -155
- data/ext/ca_sweep_engine.h +39 -9
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +148 -132
- data/ext/carray_access.c +83 -49
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +102 -9
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +2010 -335
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +184 -72
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +67 -32
- data/ext/carray_core.c +140 -13
- data/ext/carray_count.c +10 -11
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +72 -51
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +36 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +256 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +324 -54
- data/ext/carray_kernels_reduce_extreme.c +605 -58
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +5 -4
- data/ext/carray_kernels_search.c +187 -106
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +29 -13
- data/ext/carray_median_percentile.c +56 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +50 -53
- data/ext/carray_order.c +1 -1
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +391 -47
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +22 -24
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +323 -145
- data/ext/mkkernel.rb +651 -129
- data/ext/ruby_carray.c +28 -17
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +24 -3
- data/lib/carray/autoload_method_extension.rb +14 -1
- data/lib/carray/axis_group.rb +84 -7
- data/lib/carray/basics.rb +63 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +111 -25
- data/lib/carray/categorical.rb +154 -37
- data/lib/carray/categorical_iterator.rb +300 -151
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +61 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +21 -1
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +85 -21
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +224 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +32 -12
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +43 -16
- data/lib/carray/iterator.rb +147 -3
- data/lib/carray/lazy.rb +88 -73
- data/lib/carray/mask_gap_fill.rb +3 -1
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/discovery_along.rb +74 -0
- data/lib/carray/methods/factorize.rb +50 -0
- data/lib/carray/methods/is_in.rb +25 -14
- data/lib/carray/methods/locate_addr.rb +81 -3
- data/lib/carray/methods/mask_duplicates.rb +36 -2
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +23 -2
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +44 -4
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +77 -19
- data/lib/carray/string_operation_extension.rb +10 -6
- data/lib/carray/time.rb +906 -491
- data/lib/carray/window_iterator.rb +421 -27
- data/lib/carray.rb +7 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +68 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +57 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +34 -0
- data/yard-stubs/carray_count.rb +84 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +228 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +1615 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +103 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +252 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +59 -0
- data/yard-stubs/carray_sort.rb +165 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +67 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/ca_kernel_iterator.c
CHANGED
|
@@ -186,9 +186,7 @@ ca_iter_classify_source (CArray *src)
|
|
|
186
186
|
if ( attach == ca_window_func.attach ) return CA_ITER_SRC_DESCRIPTOR; /* + CAShift */
|
|
187
187
|
|
|
188
188
|
/* Step 9: SRC_ATTACH 5 view. Each view-specific attach materialises
|
|
189
|
-
src->ptr via per-element transform; kernel sees a flat contig slab.
|
|
190
|
-
CAUnboundRepeat shares ca_stride_func.attach so it was already
|
|
191
|
-
classified as SRC_CASTRIDE above (prep doc §2.6). */
|
|
189
|
+
src->ptr via per-element transform; kernel sees a flat contig slab. */
|
|
192
190
|
if ( attach == ca_fake_func.attach ) return CA_ITER_SRC_ATTACH;
|
|
193
191
|
if ( attach == ca_byte_swap_func.attach ) return CA_ITER_SRC_ATTACH;
|
|
194
192
|
if ( attach == ca_bitfield_func.attach ) return CA_ITER_SRC_ATTACH;
|
|
@@ -526,18 +524,97 @@ ca_iter_validate_inputs (ca_iter_state *st,
|
|
|
526
524
|
return CA_ITER_OK;
|
|
527
525
|
}
|
|
528
526
|
|
|
527
|
+
/* Storage-identical wrapper strip for the kernel-compute entry.
|
|
528
|
+
|
|
529
|
+
A Face layers a semantic identifier and a CALazyMarker layers "read this
|
|
530
|
+
as the leaf of a lazy chain"; neither changes the storage, so routing and
|
|
531
|
+
alias decisions belong to what they wrap. ca_strip_face answers this for
|
|
532
|
+
Face alone and is read that way in ~60 other places, so the marker is
|
|
533
|
+
added here rather than inside it.
|
|
534
|
+
|
|
535
|
+
The marker is NOT classified as a source in its own right. Routing it to
|
|
536
|
+
CA_ITER_SRC_ATTACH would work but would allocate elements * bytes and pull
|
|
537
|
+
the whole array through ca_xfer_all first -- a.lazy.sum(axis: 0) would copy
|
|
538
|
+
what a.sum(axis: 0) aliases. Descending instead lets the parent be
|
|
539
|
+
classified on its own merits, which costs nothing.
|
|
540
|
+
|
|
541
|
+
Unlike Face, nothing re-wraps the result: a reduction over a lazy marker
|
|
542
|
+
yields a plain entity, not a lazy view.
|
|
543
|
+
|
|
544
|
+
CAREFUL: a marker carries CA_FLAG_READ_ONLY and its parent usually does
|
|
545
|
+
not, so the WRITE rejection has to happen against the wrapper. The caller
|
|
546
|
+
does that before stripping. */
|
|
547
|
+
static CArray *
|
|
548
|
+
ca_iter_strip_storage_wrapper (CArray *src)
|
|
549
|
+
{
|
|
550
|
+
while ( src && ( ca_is_face(src) || ca_is_lazy_marker(src) ) ) {
|
|
551
|
+
src = ((CAView *) src)->parent;
|
|
552
|
+
}
|
|
553
|
+
return src;
|
|
554
|
+
}
|
|
555
|
+
|
|
529
556
|
int
|
|
530
|
-
|
|
557
|
+
ca_iter_check_init (int rc)
|
|
558
|
+
{
|
|
559
|
+
const char *why;
|
|
560
|
+
|
|
561
|
+
if ( rc == CA_ITER_OK ) return rc;
|
|
562
|
+
|
|
563
|
+
switch ( rc ) {
|
|
564
|
+
case CA_ITER_ERR_NOT_CHEAP:
|
|
565
|
+
why = "the source cannot be read without materialising it";
|
|
566
|
+
break;
|
|
567
|
+
case CA_ITER_ERR_POLICY:
|
|
568
|
+
why = "the slab policy or the axes given do not apply to this source";
|
|
569
|
+
break;
|
|
570
|
+
case CA_ITER_ERR_FLAGS:
|
|
571
|
+
why = "this flag combination is not supported for this source";
|
|
572
|
+
break;
|
|
573
|
+
case CA_ITER_ERR_READONLY:
|
|
574
|
+
why = "the array is read-only and the kernel asked to write";
|
|
575
|
+
break;
|
|
576
|
+
case CA_ITER_ERR_MASK:
|
|
577
|
+
why = "the source carries a mask";
|
|
578
|
+
break;
|
|
579
|
+
case CA_ITER_ERR_MASK_NOT_ALLOWED:
|
|
580
|
+
why = "the kernel declared CA_KERNEL_NO_MASK and the source carries a mask";
|
|
581
|
+
break;
|
|
582
|
+
default:
|
|
583
|
+
why = "the request was refused";
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
rb_raise(rb_eRuntimeError, "kernel iterator: %s (rc=%d)", why, rc);
|
|
587
|
+
return rc; /* not reached */
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
static int
|
|
591
|
+
ca_iter_state_init_l1_unprotected (ca_iter_state *st,
|
|
531
592
|
struct _CArray *src,
|
|
532
593
|
ca_slab_policy_t policy,
|
|
533
594
|
int8_t *axes,
|
|
534
595
|
int8_t naxes,
|
|
535
596
|
uint32_t flags)
|
|
536
597
|
{
|
|
537
|
-
/*
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
598
|
+
/* Leave the state defined before anything can return. Every error
|
|
599
|
+
return below hands control back to a caller that may not look at the
|
|
600
|
+
code, so what it is left holding has to be a state that iterates zero
|
|
601
|
+
times rather than whatever its stack frame happened to contain. */
|
|
602
|
+
if ( st == NULL ) return CA_ITER_ERR_FLAGS;
|
|
603
|
+
memset(st, 0, sizeof(*st));
|
|
604
|
+
|
|
605
|
+
/* PROPOSAL_CAFACE_PHASE_2 F.2.6 + PROPOSAL_LAZY_MARKER_LIFT Phase 0:
|
|
606
|
+
storage-identical wrapper strip at entry (= same rationale as init_l2
|
|
607
|
+
below). Strip before validate_inputs.
|
|
608
|
+
|
|
609
|
+
The WRITE rejection is taken against the wrapper, not what it wraps: a
|
|
610
|
+
CALazyMarker is read-only while its parent is not, and stripping first
|
|
611
|
+
would let a destructive kernel through to the parent. validate_inputs
|
|
612
|
+
re-checks the stripped source, which is harmless. */
|
|
613
|
+
if ( (flags & CA_KERNEL_WRITE) && ca_is_readonly(src) ) {
|
|
614
|
+
return CA_ITER_ERR_READONLY;
|
|
615
|
+
}
|
|
616
|
+
if ( ca_is_face(src) || ca_is_lazy_marker(src) ) {
|
|
617
|
+
src = ca_iter_strip_storage_wrapper(src);
|
|
541
618
|
}
|
|
542
619
|
|
|
543
620
|
int rc = ca_iter_validate_inputs(st, src, policy, flags);
|
|
@@ -550,7 +627,6 @@ ca_iter_state_init_l1 (ca_iter_state *st,
|
|
|
550
627
|
|
|
551
628
|
uint8_t src_kind = ca_iter_classify_source(src);
|
|
552
629
|
|
|
553
|
-
memset(st, 0, sizeof(*st));
|
|
554
630
|
st->src = src;
|
|
555
631
|
st->src_kind = src_kind;
|
|
556
632
|
st->level = 1;
|
|
@@ -704,24 +780,42 @@ ca_iter_state_init_l1 (ca_iter_state *st,
|
|
|
704
780
|
return CA_ITER_OK;
|
|
705
781
|
}
|
|
706
782
|
|
|
707
|
-
int
|
|
708
|
-
|
|
783
|
+
static int
|
|
784
|
+
ca_iter_state_init_l2_unprotected (ca_iter_state *st,
|
|
709
785
|
struct _CArray *src,
|
|
710
786
|
ca_slab_policy_t policy,
|
|
711
787
|
int8_t *axes,
|
|
712
788
|
int8_t naxes,
|
|
713
789
|
uint32_t flags)
|
|
714
790
|
{
|
|
715
|
-
/*
|
|
716
|
-
|
|
717
|
-
so
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
791
|
+
/* Leave the state defined before anything can return. Every error
|
|
792
|
+
return below hands control back to a caller that may not look at the
|
|
793
|
+
code, so what it is left holding has to be a state that iterates zero
|
|
794
|
+
times rather than whatever its stack frame happened to contain. */
|
|
795
|
+
if ( st == NULL ) return CA_ITER_ERR_FLAGS;
|
|
796
|
+
memset(st, 0, sizeof(*st));
|
|
797
|
+
|
|
798
|
+
/* PROPOSAL_CAFACE_PHASE_2 F.2.6 (= MEMO §3.5 kernel_iterator entry strip)
|
|
799
|
+
+ PROPOSAL_LAZY_MARKER_LIFT Phase 0.
|
|
800
|
+
|
|
801
|
+
A Face only layers a semantic identifier and a CALazyMarker only layers
|
|
802
|
+
"leaf of a lazy chain"; storage is identical to the parent either way, so
|
|
803
|
+
strip at the kernel-compute entry and descend. Routing and alias
|
|
804
|
+
decisions belong to the parent. Strip before validate_inputs —
|
|
805
|
+
classify_source rejects both as knows-no.
|
|
806
|
+
|
|
807
|
+
The Face identifier is re-wrapped onto the result by the caller's lift
|
|
808
|
+
hook (= primary operators / reductions / etc.). The marker is not:
|
|
809
|
+
a reduction over a lazy marker yields a plain entity.
|
|
810
|
+
|
|
811
|
+
WRITE is rejected against the wrapper, before the strip — a marker is
|
|
812
|
+
read-only while its parent is not. validate_inputs re-checks the
|
|
813
|
+
stripped source, which is harmless. */
|
|
814
|
+
if ( (flags & CA_KERNEL_WRITE) && ca_is_readonly(src) ) {
|
|
815
|
+
return CA_ITER_ERR_READONLY;
|
|
816
|
+
}
|
|
817
|
+
if ( ca_is_face(src) || ca_is_lazy_marker(src) ) {
|
|
818
|
+
src = ca_iter_strip_storage_wrapper(src);
|
|
725
819
|
}
|
|
726
820
|
|
|
727
821
|
int rc = ca_iter_validate_inputs(st, src, policy, flags);
|
|
@@ -781,7 +875,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
781
875
|
if ( ca_iter_should_per_fiber_fused(src, src_kind, fiber_ax,
|
|
782
876
|
row_byte_strides[fiber_ax],
|
|
783
877
|
flags) ) {
|
|
784
|
-
memset(st, 0, sizeof(*st));
|
|
785
878
|
st->src = src;
|
|
786
879
|
st->src_kind = src_kind;
|
|
787
880
|
st->level = 2;
|
|
@@ -875,7 +968,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
875
968
|
return CA_ITER_ERR_FLAGS;
|
|
876
969
|
}
|
|
877
970
|
|
|
878
|
-
memset(st, 0, sizeof(*st));
|
|
879
971
|
st->src = src;
|
|
880
972
|
st->src_kind = CA_ITER_SRC_DESCRIPTOR;
|
|
881
973
|
st->level = 2;
|
|
@@ -1028,8 +1120,8 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1028
1120
|
}
|
|
1029
1121
|
/* slab is all-STRIDE: fall through to B.1.5 / Phase B paths. */
|
|
1030
1122
|
/* Phase B.1.5: outer SHIFT axis → materialise downgrade. Alias
|
|
1031
|
-
can't deliver OOB cells (= need fill_value),
|
|
1032
|
-
|
|
1123
|
+
can't deliver OOB cells (= need fill_value), and the view-family
|
|
1124
|
+
surface prioritises delivering the cells over avoiding a copy, so
|
|
1033
1125
|
we materialise the entire view into a row-major scratch
|
|
1034
1126
|
buffer via ca_axis_dispatch_attach (= same engine as the
|
|
1035
1127
|
existing SRC_DESCRIPTOR L2 NONE path), then walk it with
|
|
@@ -1044,7 +1136,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1044
1136
|
}
|
|
1045
1137
|
|
|
1046
1138
|
if ( outer_has_shift ) {
|
|
1047
|
-
memset(st, 0, sizeof(*st));
|
|
1048
1139
|
st->src = src;
|
|
1049
1140
|
st->src_kind = CA_ITER_SRC_DESCRIPTOR;
|
|
1050
1141
|
st->level = 2;
|
|
@@ -1138,7 +1229,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1138
1229
|
return CA_ITER_OK;
|
|
1139
1230
|
}
|
|
1140
1231
|
|
|
1141
|
-
memset(st, 0, sizeof(*st));
|
|
1142
1232
|
st->src = src;
|
|
1143
1233
|
st->src_kind = CA_ITER_SRC_DESCRIPTOR; /* Phase B alias path */
|
|
1144
1234
|
st->level = 2;
|
|
@@ -1286,7 +1376,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1286
1376
|
in_slab[ax] = 1;
|
|
1287
1377
|
}
|
|
1288
1378
|
|
|
1289
|
-
memset(st, 0, sizeof(*st));
|
|
1290
1379
|
st->src = src;
|
|
1291
1380
|
st->src_kind = CA_ITER_SRC_ATTACH;
|
|
1292
1381
|
st->level = 2;
|
|
@@ -1339,6 +1428,7 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1339
1428
|
k_axis..N-2]; either way outer_idx[m] = parent axis m). */
|
|
1340
1429
|
if ( ca_func[src->obj_type].attach == ca_stack_func.attach
|
|
1341
1430
|
&& !ca_has_mask(src)
|
|
1431
|
+
&& !(flags & CA_KERNEL_WRITE)
|
|
1342
1432
|
&& naxes == 1 && axes[0] == ((CAStack *) src)->k_axis ) {
|
|
1343
1433
|
CAStack *stack = (CAStack *) src;
|
|
1344
1434
|
int8_t parent_ndim = src->ndim - 1;
|
|
@@ -1454,6 +1544,7 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1454
1544
|
s - 1); only the K stack axis (s == k_axis) has no parent
|
|
1455
1545
|
counterpart. */
|
|
1456
1546
|
if ( ca_func[src->obj_type].attach == ca_stack_func.attach
|
|
1547
|
+
&& !(flags & CA_KERNEL_WRITE)
|
|
1457
1548
|
&& naxes >= 1 && !in_slab[((CAStack *) src)->k_axis] ) {
|
|
1458
1549
|
CAStack *stack = (CAStack *) src;
|
|
1459
1550
|
int8_t k_axis = stack->k_axis;
|
|
@@ -1674,7 +1765,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1674
1765
|
/ CATile / CARoll). Same shape as L1 SRC_ATTACH: iterator-owns
|
|
1675
1766
|
scratch + xfer_all GET/PUT. Yield as one 1-D strided slab. */
|
|
1676
1767
|
if ( src_kind == CA_ITER_SRC_ATTACH ) {
|
|
1677
|
-
memset(st, 0, sizeof(*st));
|
|
1678
1768
|
st->src = src;
|
|
1679
1769
|
st->src_kind = CA_ITER_SRC_ATTACH;
|
|
1680
1770
|
st->level = 2;
|
|
@@ -1726,7 +1816,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1726
1816
|
int8_t nd = raw_ndim;
|
|
1727
1817
|
int8_t k;
|
|
1728
1818
|
|
|
1729
|
-
memset(st, 0, sizeof(*st));
|
|
1730
1819
|
st->src = src;
|
|
1731
1820
|
st->src_kind = CA_ITER_SRC_DESCRIPTOR_L2_ALIASABLE;
|
|
1732
1821
|
st->level = 2;
|
|
@@ -1804,9 +1893,9 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1804
1893
|
return CA_ITER_OK;
|
|
1805
1894
|
}
|
|
1806
1895
|
|
|
1807
|
-
/* Sub-step 5.3: L2 dispatch over descriptor sources.
|
|
1808
|
-
|
|
1809
|
-
|
|
1896
|
+
/* Sub-step 5.3: L2 dispatch over descriptor sources. The view-family
|
|
1897
|
+
surface prioritises delivering the cells over avoiding a copy: always
|
|
1898
|
+
materialise into a
|
|
1810
1899
|
scratch buffer via ca_axis_dispatch_attach and yield a single
|
|
1811
1900
|
strided slab (stride = bytes). CASelect/CAMapping always reach
|
|
1812
1901
|
here, CSA/CAGrid/CAWindow/CAShift when INDEX/SHIFT axes are
|
|
@@ -1817,7 +1906,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1817
1906
|
/* raw_descs / raw_pdims / raw_ndim were populated by route_source
|
|
1818
1907
|
above so we skip the local describe_axes call. Kept locals
|
|
1819
1908
|
named raw_* to match the original code. */
|
|
1820
|
-
memset(st, 0, sizeof(*st));
|
|
1821
1909
|
st->src = src;
|
|
1822
1910
|
st->src_kind = CA_ITER_SRC_DESCRIPTOR;
|
|
1823
1911
|
st->level = 2;
|
|
@@ -1891,7 +1979,6 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
1891
1979
|
}
|
|
1892
1980
|
|
|
1893
1981
|
/* === CAStride / entity L2 path === */
|
|
1894
|
-
memset(st, 0, sizeof(*st));
|
|
1895
1982
|
st->src = src;
|
|
1896
1983
|
st->src_kind = CA_ITER_SRC_CASTRIDE;
|
|
1897
1984
|
st->level = 2;
|
|
@@ -2092,8 +2179,8 @@ ca_iter_state_init_l2 (ca_iter_state *st,
|
|
|
2092
2179
|
return CA_ITER_OK;
|
|
2093
2180
|
}
|
|
2094
2181
|
|
|
2095
|
-
int
|
|
2096
|
-
|
|
2182
|
+
static int
|
|
2183
|
+
ca_iter_state_next_slab_unprotected (ca_iter_state *st,
|
|
2097
2184
|
char **out_ptr,
|
|
2098
2185
|
boolean8_t **out_mask,
|
|
2099
2186
|
ca_size_t *out_n)
|
|
@@ -2115,8 +2202,8 @@ ca_iter_state_next_slab (ca_iter_state *st,
|
|
|
2115
2202
|
return 1;
|
|
2116
2203
|
}
|
|
2117
2204
|
|
|
2118
|
-
int
|
|
2119
|
-
|
|
2205
|
+
static int
|
|
2206
|
+
ca_iter_state_next_slab_strided_unprotected (ca_iter_state *st,
|
|
2120
2207
|
char **out_ptr,
|
|
2121
2208
|
boolean8_t **out_mask,
|
|
2122
2209
|
ca_size_t *out_n,
|
|
@@ -2184,8 +2271,8 @@ ca_iter_state_next_slab_strided (ca_iter_state *st,
|
|
|
2184
2271
|
return 1;
|
|
2185
2272
|
}
|
|
2186
2273
|
|
|
2187
|
-
int
|
|
2188
|
-
|
|
2274
|
+
static int
|
|
2275
|
+
ca_iter_state_next_slab_axes_unprotected (ca_iter_state *st,
|
|
2189
2276
|
char **out_ptr,
|
|
2190
2277
|
boolean8_t **out_mask)
|
|
2191
2278
|
{
|
|
@@ -2695,38 +2782,22 @@ ca_iter_state_next_slab_axes (ca_iter_state *st,
|
|
|
2695
2782
|
return 1;
|
|
2696
2783
|
}
|
|
2697
2784
|
|
|
2698
|
-
void
|
|
2699
|
-
|
|
2785
|
+
static void
|
|
2786
|
+
ca_iter_state_sync_slab_unprotected (ca_iter_state *st)
|
|
2700
2787
|
{
|
|
2701
2788
|
/* READ walk: nothing to sync. */
|
|
2702
2789
|
if ( st == NULL || !(st->flags & CA_KERNEL_WRITE) ) return;
|
|
2703
2790
|
|
|
2704
|
-
/*
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2791
|
+
/* Neither stack mode can be reached with WRITE set: both are declined
|
|
2792
|
+
at init, which sends a write destination down the generic SRC_ATTACH
|
|
2793
|
+
path instead. They cannot serve a write themselves -- ALIAS_STACK
|
|
2794
|
+
hands out a tile cache that finish frees, and STACK_OUTER_K aliases
|
|
2795
|
+
parents[k]->ptr, which is the attach buffer rather than the parent's
|
|
2796
|
+
own memory whenever the parent is a view. Scattering per parent
|
|
2797
|
+
would let the fast paths carry writes too; until then this branch is
|
|
2798
|
+
just the assertion that they are not asked to. */
|
|
2710
2799
|
if ( st->alias_mode == CA_ITER_ALIAS_STACK
|
|
2711
2800
|
|| st->alias_mode == CA_ITER_ALIAS_STACK_OUTER_K ) {
|
|
2712
|
-
/* STACK_OUTER_K (P.2 Case A) is READ-only scope: slabs are direct
|
|
2713
|
-
aliases into parents[k]->ptr, kernel WRITE would scatter into
|
|
2714
|
-
parent memory which is out of scope (see proposal R1). Skip
|
|
2715
|
-
sync. */
|
|
2716
|
-
st->write_dirty = 0;
|
|
2717
|
-
return;
|
|
2718
|
-
}
|
|
2719
|
-
|
|
2720
|
-
/* SRC_ATTACH path (step 9 + 2026-05-31 refactor): kernel wrote into
|
|
2721
|
-
iterator-owned scratch (= scratch_ptr). Push back via xfer_all PUT
|
|
2722
|
-
which routes through the view's xfer_all slot -- handles CAFake
|
|
2723
|
-
(cast back), CAByteSwap (swap back), CABitfield/CABitarray (bit
|
|
2724
|
-
pack back), CAReduce (broadcast across reduce window). Inherits
|
|
2725
|
-
transform-fused / partial materialise / etc. automatically. */
|
|
2726
|
-
if ( st->src_kind == CA_ITER_SRC_ATTACH ) {
|
|
2727
|
-
if ( st->src->elements > 0 ) {
|
|
2728
|
-
ca_xfer_all(st->src, st->scratch_ptr, CA_XFER_PUT);
|
|
2729
|
-
}
|
|
2730
2801
|
st->write_dirty = 0;
|
|
2731
2802
|
return;
|
|
2732
2803
|
}
|
|
@@ -2805,12 +2876,32 @@ ca_iter_state_sync_slab (ca_iter_state *st)
|
|
|
2805
2876
|
ca_stride_scatter_run(dst, st->fiber_data_scratch,
|
|
2806
2877
|
bytes, n, data_step);
|
|
2807
2878
|
}
|
|
2808
|
-
/* Fall through
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2879
|
+
/* Fall through. The gather above is not specific to a src_kind --
|
|
2880
|
+
it fires for any source whose fiber is not innermost-contig -- so
|
|
2881
|
+
for SRC_ATTACH this has just written the fiber back into the
|
|
2882
|
+
whole-view scratch, and the push-back below carries it to the
|
|
2883
|
+
source. For the alias paths scratch_ptr is NULL and the switch
|
|
2884
|
+
below early-returns. */
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
/* SRC_ATTACH path (step 9 + 2026-05-31 refactor): kernel wrote into
|
|
2888
|
+
iterator-owned scratch (= scratch_ptr). Push back via xfer_all PUT
|
|
2889
|
+
which routes through the view's xfer_all slot -- handles CAFake
|
|
2890
|
+
(cast back), CAByteSwap (swap back), CABitfield/CABitarray (bit
|
|
2891
|
+
pack back), CAReduce (broadcast across reduce window). Inherits
|
|
2892
|
+
transform-fused / partial materialise / etc. automatically.
|
|
2893
|
+
|
|
2894
|
+
This has to stay below the two per-fiber blocks: consulting
|
|
2895
|
+
src_kind first would push back the whole-view buffer while the
|
|
2896
|
+
fiber the author actually wrote sat unscattered in
|
|
2897
|
+
fiber_data_scratch, and would push back a NULL one for
|
|
2898
|
+
PER_FIBER_FUSED, which owns no whole-view buffer at all. */
|
|
2899
|
+
if ( st->src_kind == CA_ITER_SRC_ATTACH ) {
|
|
2900
|
+
if ( st->src->elements > 0 ) {
|
|
2901
|
+
ca_xfer_all(st->src, st->scratch_ptr, CA_XFER_PUT);
|
|
2902
|
+
}
|
|
2903
|
+
st->write_dirty = 0;
|
|
2904
|
+
return;
|
|
2814
2905
|
}
|
|
2815
2906
|
|
|
2816
2907
|
/* alias path: kernel wrote through alias_ptr into parent directly
|
|
@@ -2949,6 +3040,228 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2949
3040
|
st->alias_ptr = NULL;
|
|
2950
3041
|
}
|
|
2951
3042
|
|
|
3043
|
+
/* ---- Raise-safe entry points ----------------------------------------
|
|
3044
|
+
*
|
|
3045
|
+
* A walk reads its source, and a source that converts as it is read (a
|
|
3046
|
+
* lazy view over an object array, say) raises when it meets a cell it
|
|
3047
|
+
* cannot convert. The caller's loop then never reaches
|
|
3048
|
+
* ca_iter_state_finish -- the block macros put it in the `for`
|
|
3049
|
+
* increment, which a raise jumps over, and it is past the raise in
|
|
3050
|
+
* hand-written walks too. So the walk finishes itself on the way out.
|
|
3051
|
+
*
|
|
3052
|
+
* Every entry point that can raise is called through rb_protect here,
|
|
3053
|
+
* and ca_iter_state_finish is idempotent (it clears st->src), so the
|
|
3054
|
+
* caller's own finish after an ordinary walk stays correct.
|
|
3055
|
+
*
|
|
3056
|
+
* Not covered: a kernel body that raises. It runs in the caller's
|
|
3057
|
+
* frame, between two calls of these functions, where the engine has no
|
|
3058
|
+
* hold on it. An object-lane kernel calling back into Ruby is the case
|
|
3059
|
+
* to watch.
|
|
3060
|
+
*
|
|
3061
|
+
* init runs protected always -- once per walk, next to a materialise.
|
|
3062
|
+
* next_slab / sync_slab are called once per slab, in walks whose whole
|
|
3063
|
+
* per-fiber cost can be a few nanoseconds, so they are protected only
|
|
3064
|
+
* when this walk can raise at all: when it gathers each fiber through
|
|
3065
|
+
* the source's own transfer slots, or when it writes scratch back
|
|
3066
|
+
* through them. Every other shape hands out pointers into memory that
|
|
3067
|
+
* init already materialised, and moves it with memcpy. */
|
|
3068
|
+
|
|
3069
|
+
/* Private flags bit, kept in ca_iter_state.flags rather than a field of
|
|
3070
|
+
its own: the state is stack-allocated by ext authors through the block
|
|
3071
|
+
macros, so growing it would overrun states built against an older
|
|
3072
|
+
header. */
|
|
3073
|
+
#define CA_ITER_FLAG_WALK_MAY_RAISE 0x80000000u
|
|
3074
|
+
|
|
3075
|
+
typedef struct {
|
|
3076
|
+
ca_iter_state *st;
|
|
3077
|
+
CArray *src;
|
|
3078
|
+
ca_slab_policy_t policy;
|
|
3079
|
+
int8_t *axes;
|
|
3080
|
+
int8_t naxes;
|
|
3081
|
+
uint32_t flags;
|
|
3082
|
+
char **out_ptr;
|
|
3083
|
+
boolean8_t **out_mask;
|
|
3084
|
+
ca_size_t *out_n;
|
|
3085
|
+
ca_size_t *out_stride_bytes;
|
|
3086
|
+
int rc;
|
|
3087
|
+
} ca_iter_call_t;
|
|
3088
|
+
|
|
3089
|
+
/* Whether next_slab / sync_slab on this walk need the protection. */
|
|
3090
|
+
static void
|
|
3091
|
+
ca_iter_mark_walk_may_raise (ca_iter_state *st)
|
|
3092
|
+
{
|
|
3093
|
+
if ( st == NULL ) return;
|
|
3094
|
+
if ( st->alias_mode == CA_ITER_ALIAS_PER_FIBER_FUSED ) {
|
|
3095
|
+
/* gathers each fiber through the source's xfer_stride slot */
|
|
3096
|
+
st->flags |= CA_ITER_FLAG_WALK_MAY_RAISE;
|
|
3097
|
+
}
|
|
3098
|
+
else if ( (st->flags & CA_KERNEL_WRITE)
|
|
3099
|
+
&& (st->scratch_ptr != NULL
|
|
3100
|
+
|| st->src_kind == CA_ITER_SRC_ATTACH) ) {
|
|
3101
|
+
/* writes back out of iterator-owned scratch, through the source's
|
|
3102
|
+
xfer_all / sync_data slot. A write into aliased memory needs no
|
|
3103
|
+
push-back at all: sync_slab returns at once. */
|
|
3104
|
+
st->flags |= CA_ITER_FLAG_WALK_MAY_RAISE;
|
|
3105
|
+
}
|
|
3106
|
+
}
|
|
3107
|
+
|
|
3108
|
+
static void
|
|
3109
|
+
ca_iter_protect (ca_iter_state *st, VALUE (*body)(VALUE), VALUE arg)
|
|
3110
|
+
{
|
|
3111
|
+
int tag = 0;
|
|
3112
|
+
rb_protect(body, arg, &tag);
|
|
3113
|
+
if ( tag ) {
|
|
3114
|
+
ca_iter_state_finish(st);
|
|
3115
|
+
rb_jump_tag(tag);
|
|
3116
|
+
}
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3119
|
+
static VALUE
|
|
3120
|
+
ca_iter_call_init_l1 (VALUE arg)
|
|
3121
|
+
{
|
|
3122
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3123
|
+
c->rc = ca_iter_state_init_l1_unprotected(c->st, c->src, c->policy,
|
|
3124
|
+
c->axes, c->naxes, c->flags);
|
|
3125
|
+
return Qnil;
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
static VALUE
|
|
3129
|
+
ca_iter_call_init_l2 (VALUE arg)
|
|
3130
|
+
{
|
|
3131
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3132
|
+
c->rc = ca_iter_state_init_l2_unprotected(c->st, c->src, c->policy,
|
|
3133
|
+
c->axes, c->naxes, c->flags);
|
|
3134
|
+
return Qnil;
|
|
3135
|
+
}
|
|
3136
|
+
|
|
3137
|
+
static VALUE
|
|
3138
|
+
ca_iter_call_next_slab (VALUE arg)
|
|
3139
|
+
{
|
|
3140
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3141
|
+
c->rc = ca_iter_state_next_slab_unprotected(c->st, c->out_ptr,
|
|
3142
|
+
c->out_mask, c->out_n);
|
|
3143
|
+
return Qnil;
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
static VALUE
|
|
3147
|
+
ca_iter_call_next_slab_strided (VALUE arg)
|
|
3148
|
+
{
|
|
3149
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3150
|
+
c->rc = ca_iter_state_next_slab_strided_unprotected(c->st, c->out_ptr,
|
|
3151
|
+
c->out_mask, c->out_n,
|
|
3152
|
+
c->out_stride_bytes);
|
|
3153
|
+
return Qnil;
|
|
3154
|
+
}
|
|
3155
|
+
|
|
3156
|
+
static VALUE
|
|
3157
|
+
ca_iter_call_next_slab_axes (VALUE arg)
|
|
3158
|
+
{
|
|
3159
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3160
|
+
c->rc = ca_iter_state_next_slab_axes_unprotected(c->st, c->out_ptr,
|
|
3161
|
+
c->out_mask);
|
|
3162
|
+
return Qnil;
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
static VALUE
|
|
3166
|
+
ca_iter_call_sync_slab (VALUE arg)
|
|
3167
|
+
{
|
|
3168
|
+
ca_iter_call_t *c = (ca_iter_call_t *) arg;
|
|
3169
|
+
ca_iter_state_sync_slab_unprotected(c->st);
|
|
3170
|
+
return Qnil;
|
|
3171
|
+
}
|
|
3172
|
+
|
|
3173
|
+
int
|
|
3174
|
+
ca_iter_state_init_l1 (ca_iter_state *st,
|
|
3175
|
+
struct _CArray *src,
|
|
3176
|
+
ca_slab_policy_t policy,
|
|
3177
|
+
int8_t *axes,
|
|
3178
|
+
int8_t naxes,
|
|
3179
|
+
uint32_t flags)
|
|
3180
|
+
{
|
|
3181
|
+
ca_iter_call_t c;
|
|
3182
|
+
c.st = st; c.src = src; c.policy = policy;
|
|
3183
|
+
c.axes = axes; c.naxes = naxes; c.flags = flags; c.rc = CA_ITER_OK;
|
|
3184
|
+
ca_iter_protect(st, ca_iter_call_init_l1, (VALUE) &c);
|
|
3185
|
+
if ( c.rc == CA_ITER_OK ) ca_iter_mark_walk_may_raise(st);
|
|
3186
|
+
return c.rc;
|
|
3187
|
+
}
|
|
3188
|
+
|
|
3189
|
+
int
|
|
3190
|
+
ca_iter_state_init_l2 (ca_iter_state *st,
|
|
3191
|
+
struct _CArray *src,
|
|
3192
|
+
ca_slab_policy_t policy,
|
|
3193
|
+
int8_t *axes,
|
|
3194
|
+
int8_t naxes,
|
|
3195
|
+
uint32_t flags)
|
|
3196
|
+
{
|
|
3197
|
+
ca_iter_call_t c;
|
|
3198
|
+
c.st = st; c.src = src; c.policy = policy;
|
|
3199
|
+
c.axes = axes; c.naxes = naxes; c.flags = flags; c.rc = CA_ITER_OK;
|
|
3200
|
+
ca_iter_protect(st, ca_iter_call_init_l2, (VALUE) &c);
|
|
3201
|
+
if ( c.rc == CA_ITER_OK ) ca_iter_mark_walk_may_raise(st);
|
|
3202
|
+
return c.rc;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
int
|
|
3206
|
+
ca_iter_state_next_slab (ca_iter_state *st,
|
|
3207
|
+
char **out_ptr,
|
|
3208
|
+
boolean8_t **out_mask,
|
|
3209
|
+
ca_size_t *out_n)
|
|
3210
|
+
{
|
|
3211
|
+
ca_iter_call_t c;
|
|
3212
|
+
if ( st == NULL || !(st->flags & CA_ITER_FLAG_WALK_MAY_RAISE) ) {
|
|
3213
|
+
return ca_iter_state_next_slab_unprotected(st, out_ptr, out_mask, out_n);
|
|
3214
|
+
}
|
|
3215
|
+
c.st = st; c.out_ptr = out_ptr; c.out_mask = out_mask; c.out_n = out_n;
|
|
3216
|
+
c.rc = 0;
|
|
3217
|
+
ca_iter_protect(st, ca_iter_call_next_slab, (VALUE) &c);
|
|
3218
|
+
return c.rc;
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
int
|
|
3222
|
+
ca_iter_state_next_slab_strided (ca_iter_state *st,
|
|
3223
|
+
char **out_ptr,
|
|
3224
|
+
boolean8_t **out_mask,
|
|
3225
|
+
ca_size_t *out_n,
|
|
3226
|
+
ca_size_t *out_stride_bytes)
|
|
3227
|
+
{
|
|
3228
|
+
ca_iter_call_t c;
|
|
3229
|
+
if ( st == NULL || !(st->flags & CA_ITER_FLAG_WALK_MAY_RAISE) ) {
|
|
3230
|
+
return ca_iter_state_next_slab_strided_unprotected(st, out_ptr, out_mask,
|
|
3231
|
+
out_n, out_stride_bytes);
|
|
3232
|
+
}
|
|
3233
|
+
c.st = st; c.out_ptr = out_ptr; c.out_mask = out_mask; c.out_n = out_n;
|
|
3234
|
+
c.out_stride_bytes = out_stride_bytes; c.rc = 0;
|
|
3235
|
+
ca_iter_protect(st, ca_iter_call_next_slab_strided, (VALUE) &c);
|
|
3236
|
+
return c.rc;
|
|
3237
|
+
}
|
|
3238
|
+
|
|
3239
|
+
int
|
|
3240
|
+
ca_iter_state_next_slab_axes (ca_iter_state *st,
|
|
3241
|
+
char **out_ptr,
|
|
3242
|
+
boolean8_t **out_mask)
|
|
3243
|
+
{
|
|
3244
|
+
ca_iter_call_t c;
|
|
3245
|
+
if ( st == NULL || !(st->flags & CA_ITER_FLAG_WALK_MAY_RAISE) ) {
|
|
3246
|
+
return ca_iter_state_next_slab_axes_unprotected(st, out_ptr, out_mask);
|
|
3247
|
+
}
|
|
3248
|
+
c.st = st; c.out_ptr = out_ptr; c.out_mask = out_mask; c.rc = 0;
|
|
3249
|
+
ca_iter_protect(st, ca_iter_call_next_slab_axes, (VALUE) &c);
|
|
3250
|
+
return c.rc;
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
void
|
|
3254
|
+
ca_iter_state_sync_slab (ca_iter_state *st)
|
|
3255
|
+
{
|
|
3256
|
+
ca_iter_call_t c;
|
|
3257
|
+
if ( st == NULL || !(st->flags & CA_ITER_FLAG_WALK_MAY_RAISE) ) {
|
|
3258
|
+
ca_iter_state_sync_slab_unprotected(st);
|
|
3259
|
+
return;
|
|
3260
|
+
}
|
|
3261
|
+
c.st = st;
|
|
3262
|
+
ca_iter_protect(st, ca_iter_call_sync_slab, (VALUE) &c);
|
|
3263
|
+
}
|
|
3264
|
+
|
|
2952
3265
|
#ifdef CARRAY_DEV_BUILD
|
|
2953
3266
|
/* ============================================================
|
|
2954
3267
|
* smoke surface (dev-only, stripped in release)
|
|
@@ -4316,6 +4629,5 @@ Init_ca_kernel_iterator (void)
|
|
|
4316
4629
|
rb_define_const(rb_cCArray, "T1_ITER_ALIAS_CONTIG", INT2NUM(CA_ITER_ALIAS_CONTIG));
|
|
4317
4630
|
rb_define_const(rb_cCArray, "T1_ITER_ALIAS_STRIDED", INT2NUM(CA_ITER_ALIAS_STRIDED));
|
|
4318
4631
|
rb_define_const(rb_cCArray, "T1_ITER_ALIAS_ATTACH", INT2NUM(CA_ITER_ALIAS_ATTACH));
|
|
4319
|
-
rb_define_const(rb_cCArray, "T1_ITER_ERR_UNBOUND_SHAPE", INT2NUM(CA_ITER_ERR_UNBOUND_SHAPE));
|
|
4320
4632
|
#endif /* CARRAY_DEV_BUILD */
|
|
4321
4633
|
}
|