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_kernel_iterator.c
CHANGED
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
|
|
32
32
|
A route added for speed is a shortcut, tagged next to its code with
|
|
33
33
|
"Shortcut NAME" and a fixed set of fields; each one is switched off by
|
|
34
|
-
|
|
34
|
+
ca_fast_path(CA_SC_name): by its name in CARRAY_SHORTCUTS_OFF, or with
|
|
35
|
+
the others by CARRAY_GENERAL_PATH=1 (carray_internal.h).
|
|
35
36
|
|
|
36
37
|
---------------------------------------------------------------------------- */
|
|
37
38
|
|
|
@@ -43,7 +44,6 @@
|
|
|
43
44
|
|
|
44
45
|
#include <assert.h>
|
|
45
46
|
#include <string.h>
|
|
46
|
-
#include <ruby/ractor.h>
|
|
47
47
|
|
|
48
48
|
/* Private flags bit, kept in ca_iter_state.flags like
|
|
49
49
|
CA_ITER_FLAG_WALK_MAY_RAISE below: src is a copy the walk owns (see
|
|
@@ -52,69 +52,7 @@
|
|
|
52
52
|
|
|
53
53
|
/* Data scratch. A scratch of object cells holds VALUEs no Ruby object
|
|
54
54
|
owns while the kernel calls Ruby for each cell, so it is filled with
|
|
55
|
-
Qnil and held for the GC until finish releases it.
|
|
56
|
-
|
|
57
|
-
One large scratch is kept when a walk frees it and handed to the next
|
|
58
|
-
walk that fits in it: a fresh allocation of that size costs the page
|
|
59
|
-
faults of touching it, which for a reduction is several times the
|
|
60
|
-
reduction itself. The kept buffer is owned by nobody, and a walk that
|
|
61
|
-
takes it owns it alone until it frees it again. Each Ractor keeps its
|
|
62
|
-
own (ractor-local storage), since walks in different Ractors run at
|
|
63
|
-
the same time.
|
|
64
|
-
|
|
65
|
-
Shortcut KEEP_SCRATCH (name tag; docs/internal/KernelIteratorEngine.md
|
|
66
|
-
section 3.4 has the table of all shortcuts).
|
|
67
|
-
Layer data: where a scratch comes from. The walk is unchanged.
|
|
68
|
-
Speeds up walks with a scratch of 1 MiB or more, run one after
|
|
69
|
-
another.
|
|
70
|
-
Why no difference measured on macOS (a per-axis sum of a
|
|
71
|
-
2000x2000 fake view); the page faults it
|
|
72
|
-
avoids are expected to cost more on Linux (unmeasured).
|
|
73
|
-
Enters ki_data_alloc: bytes >= KI_KEEP_MIN and a kept buffer
|
|
74
|
-
that fits; ki_data_free: KI_KEEP_MIN <= bytes <=
|
|
75
|
-
KI_KEEP_MAX.
|
|
76
|
-
Promises 4 (a kept buffer has no owner, so no exit can leave it
|
|
77
|
-
held); 7 (object cells are cleared and held either way).
|
|
78
|
-
Switch ca_fast_paths_enabled(): off, every scratch is fresh.
|
|
79
|
-
Checked by test_iter_ractor_scratch.rb; the buffer count in
|
|
80
|
-
test_iter_delivery_detectors.rb. */
|
|
81
|
-
|
|
82
|
-
#define KI_KEEP_MIN ((ca_size_t) 1 << 20)
|
|
83
|
-
#define KI_KEEP_MAX ((ca_size_t) 64 << 20)
|
|
84
|
-
|
|
85
|
-
typedef struct {
|
|
86
|
-
void *p;
|
|
87
|
-
ca_size_t bytes;
|
|
88
|
-
} ki_kept_t;
|
|
89
|
-
|
|
90
|
-
static rb_ractor_local_key_t ki_kept_key;
|
|
91
|
-
|
|
92
|
-
static void
|
|
93
|
-
ki_kept_free (void *ptr)
|
|
94
|
-
{
|
|
95
|
-
ki_kept_t *k = (ki_kept_t *) ptr;
|
|
96
|
-
if ( k ) {
|
|
97
|
-
if ( k->p ) ruby_xfree(k->p);
|
|
98
|
-
ruby_xfree(k);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
static const struct rb_ractor_local_storage_type ki_kept_type = {
|
|
103
|
-
NULL, ki_kept_free
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
static ki_kept_t *
|
|
107
|
-
ki_kept_slot (void)
|
|
108
|
-
{
|
|
109
|
-
ki_kept_t *k = (ki_kept_t *) rb_ractor_local_storage_ptr(ki_kept_key);
|
|
110
|
-
if ( k == NULL ) {
|
|
111
|
-
k = ALLOC(ki_kept_t);
|
|
112
|
-
k->p = NULL;
|
|
113
|
-
k->bytes = 0;
|
|
114
|
-
rb_ractor_local_storage_ptr_set(ki_kept_key, k);
|
|
115
|
-
}
|
|
116
|
-
return k;
|
|
117
|
-
}
|
|
55
|
+
Qnil and held for the GC until finish releases it. */
|
|
118
56
|
|
|
119
57
|
/* Development build: the number of buffers ki_data_alloc has handed out
|
|
120
58
|
that ki_data_free has not taken back (CArray.__iter_buffers__). A walk
|
|
@@ -131,19 +69,9 @@ static long ki_buffers_out = 0;
|
|
|
131
69
|
static void *
|
|
132
70
|
ki_data_alloc (int8_t data_type, ca_size_t bytes)
|
|
133
71
|
{
|
|
134
|
-
void *p
|
|
72
|
+
void *p;
|
|
135
73
|
KI_BUFFERS_OUT(1);
|
|
136
|
-
|
|
137
|
-
ki_kept_t *k = ki_kept_slot();
|
|
138
|
-
if ( k->p && bytes <= k->bytes ) {
|
|
139
|
-
p = k->p;
|
|
140
|
-
k->p = NULL;
|
|
141
|
-
k->bytes = 0;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if ( p == NULL ) {
|
|
145
|
-
p = xmalloc(bytes > 0 ? bytes : 1);
|
|
146
|
-
}
|
|
74
|
+
p = xmalloc(bytes > 0 ? bytes : 1);
|
|
147
75
|
if ( data_type == CA_OBJECT ) {
|
|
148
76
|
ca_size_t n = bytes / (ca_size_t) sizeof(VALUE);
|
|
149
77
|
ca_object_cells_clear(p, n);
|
|
@@ -152,24 +80,11 @@ ki_data_alloc (int8_t data_type, ca_size_t bytes)
|
|
|
152
80
|
return p;
|
|
153
81
|
}
|
|
154
82
|
|
|
155
|
-
/* `bytes` is the size p was allocated with (0 when unknown: never kept). */
|
|
156
83
|
static void
|
|
157
|
-
ki_data_free (void *p
|
|
84
|
+
ki_data_free (void *p)
|
|
158
85
|
{
|
|
159
86
|
KI_BUFFERS_OUT(-1);
|
|
160
87
|
ca_gc_release_buffer(p);
|
|
161
|
-
if ( bytes >= KI_KEEP_MIN && bytes <= KI_KEEP_MAX && ca_fast_paths_enabled() ) {
|
|
162
|
-
ki_kept_t *k = ki_kept_slot();
|
|
163
|
-
if ( bytes > k->bytes ) {
|
|
164
|
-
void *old = k->p;
|
|
165
|
-
k->p = p;
|
|
166
|
-
k->bytes = bytes;
|
|
167
|
-
if ( old ) {
|
|
168
|
-
xfree(old);
|
|
169
|
-
}
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
88
|
xfree(p);
|
|
174
89
|
}
|
|
175
90
|
|
|
@@ -197,7 +112,7 @@ extern ca_operation_function_t ca_window_func;
|
|
|
197
112
|
engine gathers its cells into a scratch buffer of its own through the
|
|
198
113
|
view's transfer (ki_gather_view = ca_xfer_all GET) and, on a WRITE
|
|
199
114
|
walk, sends back the cells the kernel changed (ki_scratch_push_changed
|
|
200
|
-
= ca_xfer_addrs
|
|
115
|
+
= ca_xfer_addrs). The
|
|
201
116
|
view's attach / sync slots are not called. Cast / byte swap / bit
|
|
202
117
|
unpack / reduction views: */
|
|
203
118
|
extern ca_operation_function_t ca_fake_func;
|
|
@@ -272,6 +187,14 @@ ca_iter_register_source_kind (int obj_type, uint8_t kind)
|
|
|
272
187
|
"ca_iter_register_source_kind: obj_type %d out of range",
|
|
273
188
|
obj_type);
|
|
274
189
|
}
|
|
190
|
+
/* carray's own types are classified from their operation tables; a
|
|
191
|
+
registration would only move one of them onto the transfer walk, for
|
|
192
|
+
every array in the process. */
|
|
193
|
+
if ( obj_type < ca_obj_num_builtin ) {
|
|
194
|
+
rb_raise(rb_eArgError,
|
|
195
|
+
"ca_iter_register_source_kind: obj_type %d is one of carray's "
|
|
196
|
+
"own", obj_type);
|
|
197
|
+
}
|
|
275
198
|
if ( kind != CA_ITER_SRC_ATTACH ) {
|
|
276
199
|
rb_raise(rb_eArgError,
|
|
277
200
|
"ca_iter_register_source_kind: only CA_ITER_SRC_ATTACH (%d) "
|
|
@@ -497,10 +420,10 @@ ca_iter_build_rowmajor_strides (ca_size_t *strides,
|
|
|
497
420
|
/* ---- PER_FIBER_FUSED: which views take it ----------------------------- */
|
|
498
421
|
|
|
499
422
|
/* A src_kind branch, then a check of the view's operation table, then of
|
|
500
|
-
the fiber axis's stride. Returns nonzero for
|
|
423
|
+
the fiber axis's stride. Returns nonzero for a read of
|
|
501
424
|
CAFake / CAByteSwap / a single-cast CAMonOp under SRC_ATTACH when the
|
|
502
|
-
fiber is contiguous in the parent,
|
|
503
|
-
|
|
425
|
+
fiber is contiguous in the parent (that is, the fiber runs along the
|
|
426
|
+
innermost axis); zero for a write walk and for every other view.
|
|
504
427
|
|
|
505
428
|
The fiber_axis_stride argument is the effective byte stride of the
|
|
506
429
|
fiber axis on the view (= what next_slab_axes would yield as
|
|
@@ -508,10 +431,10 @@ ca_iter_build_rowmajor_strides (ca_size_t *strides,
|
|
|
508
431
|
a contiguous run of the parent's memory, which is what lets the view's
|
|
509
432
|
region transfer deliver it in one pass.
|
|
510
433
|
|
|
511
|
-
Called from
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
CA_ITER_ALIAS_PER_FIBER_FUSED
|
|
434
|
+
Called from one place, the SRC_ATTACH branch of ki_choose_l2_route,
|
|
435
|
+
with src_kind = CA_ITER_SRC_ATTACH. When it returns nonzero the route
|
|
436
|
+
is KI_L2_FIBER_FUSED: the whole view is not gathered and alias_mode is
|
|
437
|
+
CA_ITER_ALIAS_PER_FIBER_FUSED. */
|
|
515
438
|
static int
|
|
516
439
|
ca_iter_should_per_fiber_fused (CArray *src,
|
|
517
440
|
int src_kind,
|
|
@@ -543,19 +466,6 @@ ca_iter_should_per_fiber_fused (CArray *src,
|
|
|
543
466
|
}
|
|
544
467
|
}
|
|
545
468
|
|
|
546
|
-
/* CAShift / CAWindow: the view's region transfer fills out-of-bounds
|
|
547
|
-
cells itself, so a fiber can be fetched in one call instead of a
|
|
548
|
-
per-slab or whole-view gather (SRC_DESCRIPTOR). A view that can
|
|
549
|
-
lend the parent's memory (SRC_DESCRIPTOR_L2_ALIASABLE, an interior
|
|
550
|
-
CAWindow) is already read in place; fetching it fiber by fiber was
|
|
551
|
-
measured slower (0.35-0.82x), so only SRC_DESCRIPTOR takes it. */
|
|
552
|
-
if ( src_kind == CA_ITER_SRC_DESCRIPTOR ) {
|
|
553
|
-
/* CAWindow and CAShift share ca_window_func.attach. */
|
|
554
|
-
if ( attach == ca_window_func.attach ) {
|
|
555
|
-
return 1;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
469
|
/* Not taken by the other views, each measured slower fiber by fiber:
|
|
560
470
|
CASelectAxis / CAGrid / CASelect (1.25-4.7x), whose descriptor
|
|
561
471
|
engine already gathers the whole view in one batched pass and has no
|
|
@@ -645,9 +555,9 @@ ca_iter_strip_storage_wrapper (CArray *src)
|
|
|
645
555
|
return src;
|
|
646
556
|
}
|
|
647
557
|
|
|
648
|
-
/* Raise unless a and b have the same shape. The INOUT and
|
|
649
|
-
macros call it before opening either walk, so a refusal leaves
|
|
650
|
-
to close. */
|
|
558
|
+
/* Raise unless a and b have the same shape. The INOUT, SLAB_INOUT and
|
|
559
|
+
PAIR macros call it before opening either walk, so a refusal leaves
|
|
560
|
+
nothing to close. */
|
|
651
561
|
int
|
|
652
562
|
ca_iter_check_same_shape (struct _CArray *a, struct _CArray *b)
|
|
653
563
|
{
|
|
@@ -817,19 +727,7 @@ ki_scratch_push_changed (ca_iter_state *st)
|
|
|
817
727
|
}
|
|
818
728
|
}
|
|
819
729
|
|
|
820
|
-
|
|
821
|
-
Layer write-back.
|
|
822
|
-
Speeds up a whole-view write walk that changed every cell: one
|
|
823
|
-
ca_xfer_all PUT instead of a list of all the addresses.
|
|
824
|
-
Why about 5% on a whole write of a fake view of 1M cells.
|
|
825
|
-
Enters whole && n_changed == n.
|
|
826
|
-
Promises 3 (the same cells go back; the list would hold them all).
|
|
827
|
-
Switch ca_fast_paths_enabled(): off, the address list.
|
|
828
|
-
Checked by the write rows of the delivery matrix (L1 / L2 whole). */
|
|
829
|
-
if ( whole && n_changed == n && ca_fast_paths_enabled() ) {
|
|
830
|
-
ca_xfer_all(src, now, CA_XFER_PUT);
|
|
831
|
-
}
|
|
832
|
-
else if ( n_changed > 0 ) {
|
|
730
|
+
if ( n_changed > 0 ) {
|
|
833
731
|
ca_xfer_addrs(src, n_changed, addrs, vals, CA_XFER_PUT);
|
|
834
732
|
}
|
|
835
733
|
ALLOCV_END(h_vals);
|
|
@@ -1027,8 +925,8 @@ ca_iter_state_init_l1_unprotected (ca_iter_state *st,
|
|
|
1027
925
|
state is assembled in one place and init_l2 has one way out. */
|
|
1028
926
|
|
|
1029
927
|
typedef enum {
|
|
1030
|
-
KI_L2_FIBER_FUSED, /* PER_FIBER_FUSED: a
|
|
1031
|
-
|
|
928
|
+
KI_L2_FIBER_FUSED, /* PER_FIBER_FUSED: a read of a conversion view's
|
|
929
|
+
innermost fiber */
|
|
1032
930
|
KI_L2_PER_SLAB, /* descriptor view, read, a slab axis INDEX or SHIFT:
|
|
1033
931
|
one slab gathered at a time (PER_SLAB / _HOIST) */
|
|
1034
932
|
KI_L2_DESC_WHOLE, /* descriptor view, read: the whole view gathered by
|
|
@@ -1135,33 +1033,6 @@ ki_choose_l2_route (CArray *src, int8_t *axes, int8_t naxes, uint32_t flags,
|
|
|
1135
1033
|
|
|
1136
1034
|
if ( plan->src_kind == CA_ITER_SRC_DESCRIPTOR
|
|
1137
1035
|
|| plan->src_kind == CA_ITER_SRC_DESCRIPTOR_L2_ALIASABLE ) {
|
|
1138
|
-
/* Shortcut PER_FIBER_FUSED (CAWindow / CAShift).
|
|
1139
|
-
Layer all three, per fiber: each fiber is fetched with the
|
|
1140
|
-
view's ca_xfer_stride (which fills out-of-bounds
|
|
1141
|
-
cells itself) and put back the same way.
|
|
1142
|
-
Speeds up a fiber walk of a CAWindow / CAShift whose innermost
|
|
1143
|
-
axis is SHIFT.
|
|
1144
|
-
Why none measured: about 8% slower than the descriptor
|
|
1145
|
-
route on a sort of a 2000x2000 shift view.
|
|
1146
|
-
Enters CA_KERNEL_FIBER_CONTIG, one slab axis, the view's
|
|
1147
|
-
own rank, and ca_iter_should_per_fiber_fused. An
|
|
1148
|
-
outer-only SHIFT arrives as L2_ALIASABLE and never
|
|
1149
|
-
reaches this hook.
|
|
1150
|
-
Promises 1 (the fiber scratch is contiguous), 2 (the mask is
|
|
1151
|
-
fetched into the fiber mask scratch), 3 (ca_xfer_stride
|
|
1152
|
-
PUT of a fiber that neither converts nor repeats a
|
|
1153
|
-
cell), 4 (CA_ITER_FLAG_WALK_MAY_RAISE).
|
|
1154
|
-
Switch ca_fast_paths_enabled(): off, the descriptor route.
|
|
1155
|
-
Checked by the fiber rows of the "shift" view in the delivery
|
|
1156
|
-
matrix. */
|
|
1157
|
-
if ( (flags & CA_KERNEL_FIBER_CONTIG) && naxes == 1
|
|
1158
|
-
&& plan->ndesc == src->ndim && ca_fast_paths_enabled()
|
|
1159
|
-
&& ca_iter_should_per_fiber_fused(src, plan->src_kind, axes[0],
|
|
1160
|
-
row_bytes[axes[0]], flags) ) {
|
|
1161
|
-
plan->route = KI_L2_FIBER_FUSED;
|
|
1162
|
-
return CA_ITER_OK;
|
|
1163
|
-
}
|
|
1164
|
-
|
|
1165
1036
|
/* The rank check guards a descriptor whose rank differs from the
|
|
1166
1037
|
view's (it would not expose the axis partition slab_axes names).
|
|
1167
1038
|
Every describe_axes in the engine reports the view's rank, so the
|
|
@@ -1190,19 +1061,21 @@ ki_choose_l2_route (CArray *src, int8_t *axes, int8_t naxes, uint32_t flags,
|
|
|
1190
1061
|
Layer data; the fiber layer (ki_fiber_contig_*) sits on top.
|
|
1191
1062
|
Speeds up read walks of a CAWindow / CAShift whose slab has a
|
|
1192
1063
|
SHIFT axis and not the innermost axis.
|
|
1193
|
-
Why
|
|
1194
|
-
|
|
1064
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
1065
|
+
M2 Max / a Xeon 6369P, 2026-10-26: 1.5x / 1.1x on a
|
|
1066
|
+
median along axis 0 of a 2000x2000 shift view, 3.1x /
|
|
1067
|
+
2.2x on a sum along axis 0 of a window.
|
|
1195
1068
|
Enters a non-stride slab axis, no INDEX slab axis, the
|
|
1196
1069
|
innermost axis outside the slab, a read walk.
|
|
1197
1070
|
Promises 2 and 6 (the mask is copied by ki_take_mask_copy, and
|
|
1198
1071
|
only when the view has one).
|
|
1199
|
-
Switch
|
|
1072
|
+
Switch ca_fast_path(): off, the per-slab gather.
|
|
1200
1073
|
Checked by the slab-axis rows of the "shift" and "window" views
|
|
1201
1074
|
in the delivery matrix. */
|
|
1202
1075
|
int whole_view = slab_has_non_stride && ! slab_has_index
|
|
1203
1076
|
&& ! in_slab[src->ndim - 1]
|
|
1204
1077
|
&& ! ( flags & CA_KERNEL_WRITE )
|
|
1205
|
-
&&
|
|
1078
|
+
&& ca_fast_path(CA_SC_SHIFT_WHOLE_VIEW);
|
|
1206
1079
|
|
|
1207
1080
|
/* The descriptor engine's gathers (per slab and whole view) read
|
|
1208
1081
|
only. A write takes the transfer walk instead: the view is
|
|
@@ -1234,19 +1107,20 @@ ki_choose_l2_route (CArray *src, int8_t *axes, int8_t naxes, uint32_t flags,
|
|
|
1234
1107
|
parents through a tile cache.
|
|
1235
1108
|
Speeds up read walks of an unmasked CAStack whose one slab axis
|
|
1236
1109
|
is the stack axis.
|
|
1237
|
-
Why
|
|
1238
|
-
|
|
1110
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
1111
|
+
M2 Max / a Xeon 6369P, 2026-10-26: 1.2x / 1.3x on a mean
|
|
1112
|
+
along the stack axis of 4 parents of 500x2000.
|
|
1239
1113
|
Enters a CAStack, no mask, a read walk, one slab axis that is
|
|
1240
1114
|
k_axis.
|
|
1241
1115
|
Promises 1 (the slab is contiguous), 6 (no mask exists to touch).
|
|
1242
|
-
Switch
|
|
1116
|
+
Switch ca_fast_path(): off, the transfer walk.
|
|
1243
1117
|
Checked by the slab-axis and fiber rows of the stack parent along
|
|
1244
1118
|
axis 0 in the delivery matrix. */
|
|
1245
1119
|
if ( ca_func[src->obj_type].attach == ca_stack_func.attach
|
|
1246
1120
|
&& !ca_has_mask(src)
|
|
1247
1121
|
&& !(flags & CA_KERNEL_WRITE)
|
|
1248
1122
|
&& naxes == 1 && axes[0] == ((CAStack *) src)->k_axis
|
|
1249
|
-
&&
|
|
1123
|
+
&& ca_fast_path(CA_SC_STACK) ) {
|
|
1250
1124
|
plan->route = KI_L2_STACK;
|
|
1251
1125
|
return CA_ITER_OK;
|
|
1252
1126
|
}
|
|
@@ -1255,19 +1129,22 @@ ki_choose_l2_route (CArray *src, int8_t *axes, int8_t naxes, uint32_t flags,
|
|
|
1255
1129
|
Speeds up read walks of a CAStack whose stack axis is an outer
|
|
1256
1130
|
axis: each slab is cut from the one parent the outer
|
|
1257
1131
|
index picks, without gathering the stack.
|
|
1258
|
-
Why
|
|
1259
|
-
|
|
1132
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
1133
|
+
M2 Max / a Xeon 6369P, 2026-10-26: 1.0x / 1.0x on a mean
|
|
1134
|
+
along axis 1 of 4 parents of 500x2000, which the
|
|
1135
|
+
generated loop interchange answers first (3.5x / 3.8x
|
|
1136
|
+
with that off too); 1.1x / 1.2x on a median along axis 2.
|
|
1260
1137
|
Enters a CAStack, a read walk, the stack axis outside the slab.
|
|
1261
1138
|
Promises 2 (the parents' masks are copied), 6 (masks are read
|
|
1262
1139
|
only when a parent has one), 8 (alias_ptr stays NULL,
|
|
1263
1140
|
so no slab is lent as a window).
|
|
1264
|
-
Switch
|
|
1141
|
+
Switch ca_fast_path(): off, the transfer walk.
|
|
1265
1142
|
Checked by the slab-axis, fiber and two-slab-axes rows of the
|
|
1266
1143
|
stack parent along axes 1 and 2 in the delivery matrix. */
|
|
1267
1144
|
if ( ca_func[src->obj_type].attach == ca_stack_func.attach
|
|
1268
1145
|
&& !(flags & CA_KERNEL_WRITE)
|
|
1269
1146
|
&& naxes >= 1 && !in_slab[((CAStack *) src)->k_axis]
|
|
1270
|
-
&&
|
|
1147
|
+
&& ca_fast_path(CA_SC_STACK_OUTER_K) ) {
|
|
1271
1148
|
plan->route = KI_L2_STACK_OUTER_K;
|
|
1272
1149
|
return CA_ITER_OK;
|
|
1273
1150
|
}
|
|
@@ -1277,17 +1154,20 @@ ki_choose_l2_route (CArray *src, int8_t *axes, int8_t naxes, uint32_t flags,
|
|
|
1277
1154
|
gathering the whole view.
|
|
1278
1155
|
Speeds up a read of a fiber of a fake or byte-swap view, or of a
|
|
1279
1156
|
lazy monop that only casts, along its innermost axis.
|
|
1280
|
-
Why
|
|
1281
|
-
|
|
1157
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
1158
|
+
M2 Max / a Xeon 6369P, 2026-10-26: 1.0x / 1.1x on a sort
|
|
1159
|
+
and 1.05x / 1.2x on a median along the last axis of a
|
|
1160
|
+
2000x2000 fake view.
|
|
1282
1161
|
Enters CA_KERNEL_FIBER_CONTIG, one slab axis, a read walk, and
|
|
1283
1162
|
ca_iter_should_per_fiber_fused.
|
|
1284
|
-
Promises 1
|
|
1285
|
-
|
|
1286
|
-
|
|
1163
|
+
Promises 1 (the fiber is fetched packed), 2 (its mask is fetched
|
|
1164
|
+
the same way into fiber_mask_scratch) and 4. A write
|
|
1165
|
+
takes the transfer walk (promise 3).
|
|
1166
|
+
Switch ca_fast_path(): off, the transfer walk.
|
|
1287
1167
|
Checked by the fiber rows of the fake parent in the delivery
|
|
1288
1168
|
matrix. */
|
|
1289
1169
|
if ( (flags & CA_KERNEL_FIBER_CONTIG) && naxes == 1
|
|
1290
|
-
&&
|
|
1170
|
+
&& ca_fast_path(CA_SC_FIBER_FUSED_CONVERSION)
|
|
1291
1171
|
&& ca_iter_should_per_fiber_fused(src, CA_ITER_SRC_ATTACH, axes[0],
|
|
1292
1172
|
row_bytes[axes[0]], flags) ) {
|
|
1293
1173
|
plan->route = KI_L2_FIBER_FUSED;
|
|
@@ -1588,16 +1468,19 @@ ki_open_l2 (ca_iter_state *st, CArray *src, ca_slab_policy_t policy,
|
|
|
1588
1468
|
and with no SHIFT axis in the view: the outer and
|
|
1589
1469
|
non-innermost slab offsets are hoisted and the inner
|
|
1590
1470
|
run is copied with memcpy.
|
|
1591
|
-
Why
|
|
1471
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
1472
|
+
M2 Max, 2026-10-26: 1.6x on a mean over two slab axes of
|
|
1473
|
+
a 400x200x200 array with rows selected. Not taken with
|
|
1474
|
+
one slab axis.
|
|
1592
1475
|
Enters at least one slab axis, the innermost slab axis
|
|
1593
1476
|
STRIDE, no SHIFT axis.
|
|
1594
1477
|
Promises 2 and 6 (the mask is copied by ki_take_mask_copy, and
|
|
1595
1478
|
only when the view has one).
|
|
1596
|
-
Switch
|
|
1479
|
+
Switch ca_fast_path(): off, the PER_SLAB gather.
|
|
1597
1480
|
Checked by the two-slab-axes rows of the grid parent in the
|
|
1598
1481
|
delivery matrix. */
|
|
1599
1482
|
ca_size_t slab_bytes = st->slab_elements * src->bytes;
|
|
1600
|
-
int hoist = (st->slab_ndim > 0) &&
|
|
1483
|
+
int hoist = (st->slab_ndim > 0) && ca_fast_path(CA_SC_PER_SLAB_HOIST)
|
|
1601
1484
|
&& plan->descs[st->slab_axes_buf[st->slab_ndim - 1]].kind
|
|
1602
1485
|
== CA_AXIS_KIND_STRIDE;
|
|
1603
1486
|
for ( k = 0; hoist && k < src->ndim; k++ ) {
|
|
@@ -1745,7 +1628,7 @@ ki_fiber_contig_data (ca_iter_state *st, char *data, ca_size_t step)
|
|
|
1745
1628
|
return data;
|
|
1746
1629
|
}
|
|
1747
1630
|
if ( st->fiber_data_scratch_cap < need ) {
|
|
1748
|
-
if ( st->fiber_data_scratch ) ki_data_free(st->fiber_data_scratch
|
|
1631
|
+
if ( st->fiber_data_scratch ) ki_data_free(st->fiber_data_scratch);
|
|
1749
1632
|
st->fiber_data_scratch = (char *) ki_data_alloc(st->src->data_type, need);
|
|
1750
1633
|
st->fiber_data_scratch_cap = need;
|
|
1751
1634
|
}
|
|
@@ -2108,15 +1991,9 @@ ca_iter_state_next_slab_axes_unprotected (ca_iter_state *st,
|
|
|
2108
1991
|
/* PER_FIBER_FUSED: there is no whole-view buffer to alias from. Build
|
|
2109
1992
|
the fiber region from outer_idx + fiber_axis and call
|
|
2110
1993
|
ca_xfer_stride(src, ..., GET) directly into fiber_data_scratch; the
|
|
2111
|
-
view's region transfer (
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
last_data_off carries the fiber region's outer footprint so
|
|
2116
|
-
sync_slab can reconstruct the same region for WRITE PUT. Encode
|
|
2117
|
-
it as the linear outer_idx position scaled by fiber_axis stride
|
|
2118
|
-
equivalence; for PER_FIBER_FUSED sync_slab reads outer_idx state
|
|
2119
|
-
directly rather than data_off so the value is informational. */
|
|
1994
|
+
view's region transfer (the conversion for a fake, byte-swap or
|
|
1995
|
+
single-cast lazy view) delivers it in one pass. The route is read
|
|
1996
|
+
only, so nothing is put back; last_data_off is not used. */
|
|
2120
1997
|
if ( st->alias_mode == CA_ITER_ALIAS_PER_FIBER_FUSED ) {
|
|
2121
1998
|
ca_size_t fiber_n = st->slab_dims[0];
|
|
2122
1999
|
ca_size_t need = fiber_n * st->bytes;
|
|
@@ -2126,16 +2003,13 @@ ca_iter_state_next_slab_axes_unprotected (ca_iter_state *st,
|
|
|
2126
2003
|
ca_size_t counts[CA_RANK_MAX];
|
|
2127
2004
|
|
|
2128
2005
|
if ( st->fiber_data_scratch_cap < need ) {
|
|
2129
|
-
if ( st->fiber_data_scratch ) ki_data_free(st->fiber_data_scratch
|
|
2006
|
+
if ( st->fiber_data_scratch ) ki_data_free(st->fiber_data_scratch);
|
|
2130
2007
|
st->fiber_data_scratch = (char *) ki_data_alloc(st->src->data_type, need);
|
|
2131
2008
|
st->fiber_data_scratch_cap = need;
|
|
2132
2009
|
}
|
|
2133
2010
|
|
|
2134
2011
|
/* Build fiber region: fiber_axis spans the full fiber, all other
|
|
2135
|
-
axes pinned to outer_idx position (count=1).
|
|
2136
|
-
state so sync_slab can rebuild the same region for WRITE PUT
|
|
2137
|
-
(= captured BEFORE the outer_idx advance below, the same hazard as
|
|
2138
|
-
last_data_off; see sync_slab). */
|
|
2012
|
+
axes pinned to outer_idx position (count=1). */
|
|
2139
2013
|
{
|
|
2140
2014
|
int8_t op = 0;
|
|
2141
2015
|
for ( int8_t k = 0; k < nd; k++ ) {
|
|
@@ -2147,7 +2021,6 @@ ca_iter_state_next_slab_axes_unprotected (ca_iter_state *st,
|
|
|
2147
2021
|
counts[k] = 1;
|
|
2148
2022
|
op++;
|
|
2149
2023
|
}
|
|
2150
|
-
st->fiber_region_starts[k] = starts[k];
|
|
2151
2024
|
}
|
|
2152
2025
|
}
|
|
2153
2026
|
|
|
@@ -2276,27 +2149,6 @@ ca_iter_state_sync_slab_unprotected (ca_iter_state *st)
|
|
|
2276
2149
|
* instead of reusing -- separate phase, separate design.
|
|
2277
2150
|
* ====================================================================== */
|
|
2278
2151
|
|
|
2279
|
-
/* PER_FIBER_FUSED write: the author
|
|
2280
|
-
wrote into fiber_data_scratch and there is no whole-view buffer
|
|
2281
|
-
to xfer_all PUT. Rebuild the same fiber region from cached
|
|
2282
|
-
fiber_region_starts[] (= captured pre-advance in next_slab_axes,
|
|
2283
|
-
the same hazard as last_data_off) and call ca_xfer_stride(src, ...,
|
|
2284
|
-
PUT), which puts the fiber back through the view's region transfer
|
|
2285
|
-
in one pass. */
|
|
2286
|
-
if ( st->alias_mode == CA_ITER_ALIAS_PER_FIBER_FUSED ) {
|
|
2287
|
-
ca_size_t fiber_n = st->slab_dims[0];
|
|
2288
|
-
int8_t nd = st->ndim;
|
|
2289
|
-
ca_size_t counts[CA_RANK_MAX];
|
|
2290
|
-
for ( int8_t k = 0; k < nd; k++ ) {
|
|
2291
|
-
counts[k] = (k == st->fiber_axis) ? fiber_n : 1;
|
|
2292
|
-
}
|
|
2293
|
-
ca_xfer_stride(st->src, st->fiber_region_starts, counts,
|
|
2294
|
-
st->fiber_native_strides,
|
|
2295
|
-
st->fiber_data_scratch, CA_XFER_PUT);
|
|
2296
|
-
st->write_dirty = 0;
|
|
2297
|
-
return;
|
|
2298
|
-
}
|
|
2299
|
-
|
|
2300
2152
|
/* Per-fiber gather path scatter.
|
|
2301
2153
|
When next_slab_axes gathered the fiber into fiber_data_scratch
|
|
2302
2154
|
(= naxes==1 + slab_strides[0] != bytes), scatter it back to the
|
|
@@ -2358,9 +2210,9 @@ ca_iter_state_sync_slab_unprotected (ca_iter_state *st)
|
|
|
2358
2210
|
static VALUE ca_iter_finish_sync (VALUE arg);
|
|
2359
2211
|
|
|
2360
2212
|
static VALUE
|
|
2361
|
-
|
|
2213
|
+
ki_sync_detach (VALUE ca)
|
|
2362
2214
|
{
|
|
2363
|
-
ca_sync_detach((CArray *)
|
|
2215
|
+
ca_sync_detach((CArray *) ca);
|
|
2364
2216
|
return Qnil;
|
|
2365
2217
|
}
|
|
2366
2218
|
|
|
@@ -2389,7 +2241,7 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2389
2241
|
at init. ca_detach, or ca_sync_detach on a WRITE walk.
|
|
2390
2242
|
- else (alias paths): src was attached at init, detach. */
|
|
2391
2243
|
if ( st->scratch_ptr ) {
|
|
2392
|
-
ki_data_free(st->scratch_ptr
|
|
2244
|
+
ki_data_free(st->scratch_ptr);
|
|
2393
2245
|
st->scratch_ptr = NULL;
|
|
2394
2246
|
st->scratch_cap = 0;
|
|
2395
2247
|
}
|
|
@@ -2399,7 +2251,7 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2399
2251
|
}
|
|
2400
2252
|
/* The per-fiber scratch. */
|
|
2401
2253
|
if ( st->fiber_data_scratch ) {
|
|
2402
|
-
ki_data_free(st->fiber_data_scratch
|
|
2254
|
+
ki_data_free(st->fiber_data_scratch);
|
|
2403
2255
|
st->fiber_data_scratch = NULL;
|
|
2404
2256
|
st->fiber_data_scratch_cap = 0;
|
|
2405
2257
|
}
|
|
@@ -2422,7 +2274,7 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2422
2274
|
}
|
|
2423
2275
|
/* The STACK tile cache. */
|
|
2424
2276
|
if ( st->stack_tile_cache ) {
|
|
2425
|
-
ki_data_free(st->stack_tile_cache
|
|
2277
|
+
ki_data_free(st->stack_tile_cache);
|
|
2426
2278
|
st->stack_tile_cache = NULL;
|
|
2427
2279
|
st->stack_tile_cap = 0;
|
|
2428
2280
|
st->stack_tile_pos = 0;
|
|
@@ -2461,7 +2313,7 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2461
2313
|
block, a view lending no memory) gave a buffer of its own. */
|
|
2462
2314
|
if ( write ) {
|
|
2463
2315
|
/* protect: frees the iterator's own copy before the raise passes on */
|
|
2464
|
-
rb_protect(
|
|
2316
|
+
rb_protect(ki_sync_detach, (VALUE) root, &tag);
|
|
2465
2317
|
}
|
|
2466
2318
|
else {
|
|
2467
2319
|
ca_detach(root);
|
|
@@ -2471,8 +2323,15 @@ ca_iter_state_finish (ca_iter_state *st)
|
|
|
2471
2323
|
/* alias path (CONTIG/STRIDED for CAStride family): we attached
|
|
2472
2324
|
src directly at init, so detach it here. A SRC_ATTACH walk owns
|
|
2473
2325
|
its own scratch (alias_mode = NONE, freed above) and attached
|
|
2474
|
-
nothing to detach.
|
|
2475
|
-
|
|
2326
|
+
nothing to detach. A write walk syncs first: an entity whose
|
|
2327
|
+
attach hands out a copy (a cold one such as a CAObject mask)
|
|
2328
|
+
keeps what was written only through its sync slot. */
|
|
2329
|
+
if ( write ) {
|
|
2330
|
+
rb_protect(ki_sync_detach, (VALUE) src, &tag);
|
|
2331
|
+
}
|
|
2332
|
+
else {
|
|
2333
|
+
ca_detach(src);
|
|
2334
|
+
}
|
|
2476
2335
|
}
|
|
2477
2336
|
if ( own ) {
|
|
2478
2337
|
if ( ca_is_object_type(own) ) {
|
|
@@ -2554,18 +2413,20 @@ typedef struct {
|
|
|
2554
2413
|
Layer the exits (promise 4): which walks run next_slab /
|
|
2555
2414
|
sync_slab under rb_protect.
|
|
2556
2415
|
Speeds up walks that cannot raise there: they skip rb_protect.
|
|
2557
|
-
Why
|
|
2416
|
+
Why measured switched off alone (CARRAY_SHORTCUTS_OFF) on an
|
|
2417
|
+
M2 Max / a Xeon 6369P, 2026-10-26: 1.55x / 1.4x on a
|
|
2418
|
+
per-axis sum over 200k short fibers.
|
|
2558
2419
|
Enters the route is not PER_FIBER_FUSED and the walk does not
|
|
2559
2420
|
write back out of scratch.
|
|
2560
2421
|
Promises 4 (a walk left out cannot raise between init and finish).
|
|
2561
|
-
Switch
|
|
2422
|
+
Switch ca_fast_path(): off, every walk is protected.
|
|
2562
2423
|
Checked by test_iter_raise_cleanup.rb; the raise rows of
|
|
2563
2424
|
test_iter_delivery_detectors.rb. */
|
|
2564
2425
|
static void
|
|
2565
2426
|
ca_iter_mark_walk_may_raise (ca_iter_state *st)
|
|
2566
2427
|
{
|
|
2567
2428
|
if ( st == NULL ) return;
|
|
2568
|
-
if ( !
|
|
2429
|
+
if ( ! ca_fast_path(CA_SC_PROTECT_ONLY_MAY_RAISE) ) {
|
|
2569
2430
|
/* the general path protects every walk */
|
|
2570
2431
|
st->flags |= CA_ITER_FLAG_WALK_MAY_RAISE;
|
|
2571
2432
|
return;
|
|
@@ -2578,8 +2439,8 @@ ca_iter_mark_walk_may_raise (ca_iter_state *st)
|
|
|
2578
2439
|
&& (st->scratch_ptr != NULL
|
|
2579
2440
|
|| st->src_kind == CA_ITER_SRC_ATTACH) ) {
|
|
2580
2441
|
/* writes back out of iterator-owned scratch, through the source's
|
|
2581
|
-
transfer (ki_scratch_push_changed:
|
|
2582
|
-
|
|
2442
|
+
transfer (ki_scratch_push_changed: the changed cells by
|
|
2443
|
+
ca_xfer_addrs PUT). A write into aliased memory needs no
|
|
2583
2444
|
push-back at all: sync_slab returns at once. */
|
|
2584
2445
|
st->flags |= CA_ITER_FLAG_WALK_MAY_RAISE;
|
|
2585
2446
|
}
|
|
@@ -2919,6 +2780,32 @@ ca_iter_ensure (int32_t n, ca_iter_state *states,
|
|
|
2919
2780
|
return rb_ensure(body, arg, ca_iter_ensure_close, (VALUE) &e);
|
|
2920
2781
|
}
|
|
2921
2782
|
|
|
2783
|
+
/* ca_iter_ensure over the object array ca, recorded as being computed
|
|
2784
|
+
over (ca_computing_run) for the length of the body. The record is taken
|
|
2785
|
+
inside the ensure, so a refusal closes the states as a raise from the
|
|
2786
|
+
body does. */
|
|
2787
|
+
typedef struct {
|
|
2788
|
+
CArray *ca;
|
|
2789
|
+
VALUE (*body)(VALUE);
|
|
2790
|
+
VALUE arg;
|
|
2791
|
+
} ca_iter_computing_t;
|
|
2792
|
+
|
|
2793
|
+
static VALUE
|
|
2794
|
+
ca_iter_computing_body (VALUE arg)
|
|
2795
|
+
{
|
|
2796
|
+
ca_iter_computing_t *c = (ca_iter_computing_t *) arg;
|
|
2797
|
+
return ca_computing_run(1, &c->ca, c->body, c->arg);
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
VALUE
|
|
2801
|
+
ca_iter_ensure_computing (CArray *ca, int32_t n, ca_iter_state *states,
|
|
2802
|
+
VALUE (*body)(VALUE), VALUE arg)
|
|
2803
|
+
{
|
|
2804
|
+
ca_iter_computing_t c;
|
|
2805
|
+
c.ca = ca; c.body = body; c.arg = arg;
|
|
2806
|
+
return ca_iter_ensure(n, states, ca_iter_computing_body, (VALUE) &c);
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2922
2809
|
#ifdef CARRAY_DEV_BUILD
|
|
2923
2810
|
/* ============================================================
|
|
2924
2811
|
* smoke surface (dev-only, stripped in release)
|
|
@@ -3729,7 +3616,7 @@ rb_t1_smoke_remap_read_strided (VALUE klass, VALUE vref, VALUE vidx)
|
|
|
3729
3616
|
|
|
3730
3617
|
/* WRITE smoke: fill view's slab buffer with `val` (float64), let
|
|
3731
3618
|
sync_slab send the changed cells back to ref through the view
|
|
3732
|
-
(ki_scratch_push_changed: ca_xfer_addrs
|
|
3619
|
+
(ki_scratch_push_changed: ca_xfer_addrs PUT). */
|
|
3733
3620
|
static VALUE
|
|
3734
3621
|
rb_t1_smoke_remap_write_fill_f64 (VALUE klass, VALUE vref, VALUE vidx,
|
|
3735
3622
|
VALUE vval)
|
|
@@ -4223,8 +4110,6 @@ rb_ki_buffers_out (VALUE klass)
|
|
|
4223
4110
|
void
|
|
4224
4111
|
Init_ca_kernel_iterator (void)
|
|
4225
4112
|
{
|
|
4226
|
-
ki_kept_key = rb_ractor_local_storage_ptr_newkey(&ki_kept_type);
|
|
4227
|
-
|
|
4228
4113
|
#ifdef CARRAY_DEV_BUILD
|
|
4229
4114
|
/* ==== smoke surface registrations (dev-only, stripped in release) ====
|
|
4230
4115
|
* All `t1_smoke_*`, `caf_smoke_*`,
|