carray 3.0.1 → 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/CHANGELOG.md +520 -0
- data/README.md +2 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_dispatch.c +33 -4
- data/ext/ca_axis_group.c +202 -96
- data/ext/ca_categorical_iterator.c +108 -54
- data/ext/ca_kernel_iterator.c +317 -51
- data/ext/ca_kernel_iterator.h +142 -35
- data/ext/ca_obj_array.c +62 -20
- data/ext/ca_obj_block.c +4 -4
- data/ext/ca_obj_const_string.c +85 -26
- data/ext/ca_obj_face.c +24 -0
- data/ext/ca_obj_face.h +15 -0
- data/ext/ca_obj_fixlen_string.c +18 -5
- data/ext/ca_obj_meld.c +123 -25
- data/ext/ca_obj_object.c +8 -0
- data/ext/ca_obj_select.c +49 -34
- data/ext/ca_obj_stack.c +3 -8
- data/ext/ca_obj_stride.c +72 -1
- data/ext/ca_obj_string.c +8 -4
- data/ext/ca_obj_window.c +8 -2
- data/ext/ca_op_ipower.c +1 -2
- data/ext/ca_rng_normal.h +42 -0
- data/ext/ca_rng_xoshiro256pp.h +105 -0
- data/ext/ca_sweep_engine.c +307 -143
- data/ext/ca_sweep_engine.h +26 -5
- data/ext/carray.h +21 -2
- data/ext/carray_access.c +32 -20
- data/ext/carray_address_basis.c +590 -0
- data/ext/carray_broadcast.c +3 -3
- data/ext/carray_call_cfunc.c +667 -483
- data/ext/carray_cast.c +115 -41
- data/ext/carray_copy.c +55 -30
- data/ext/carray_core.c +83 -3
- data/ext/carray_count.c +9 -10
- data/ext/carray_factorize.c +46 -25
- data/ext/carray_internal.h +17 -0
- data/ext/carray_kernels_reduce_aggregate.c +168 -0
- data/ext/carray_kernels_reduce_cumulative.c +270 -1
- data/ext/carray_kernels_reduce_extreme.c +554 -8
- data/ext/carray_kernels_scan.c +4 -4
- data/ext/carray_kernels_search.c +94 -14
- data/ext/carray_loop.c +7 -1
- data/ext/carray_mask.c +23 -8
- data/ext/carray_median_percentile.c +55 -0
- data/ext/carray_operator.c +4 -4
- data/ext/carray_order.c +1 -1
- data/ext/carray_random.c +384 -40
- data/ext/carray_slab.c +13 -0
- data/ext/carray_sort.c +20 -22
- data/ext/mk_call_cfunc.rb +103 -116
- data/ext/mkkernel.rb +297 -29
- data/ext/ruby_carray.c +10 -1
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +5 -3
- data/lib/carray/autoload_method_extension.rb +12 -0
- data/lib/carray/axis_group.rb +77 -0
- data/lib/carray/basics.rb +4 -0
- data/lib/carray/block_iterator.rb +92 -16
- data/lib/carray/categorical.rb +150 -33
- data/lib/carray/categorical_iterator.rb +207 -80
- data/lib/carray/const_string.rb +131 -27
- data/lib/carray/construct.rb +40 -0
- data/lib/carray/data_type_extension.rb +3 -0
- data/lib/carray/data_type_limits.rb +91 -0
- data/lib/carray/fixlen_string.rb +1 -1
- data/lib/carray/frame/csv_parser.rb +11 -4
- data/lib/carray/frame/frame.rb +81 -10
- data/lib/carray/frame/group.rb +36 -3
- data/lib/carray/frame/io.rb +67 -15
- data/lib/carray/frame/records.rb +18 -4
- data/lib/carray/frame/verbs.rb +14 -11
- data/lib/carray/inspect.rb +42 -9
- data/lib/carray/iterator.rb +143 -0
- data/lib/carray/lazy.rb +0 -37
- data/lib/carray/mask_gap_fill.rb +3 -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 +13 -2
- data/lib/carray/methods/locate_addr.rb +75 -2
- data/lib/carray/methods/mask_duplicates.rb +35 -1
- data/lib/carray/methods/nunique.rb +22 -1
- data/lib/carray/methods/repeat.rb +110 -0
- data/lib/carray/methods/unique.rb +41 -1
- data/lib/carray/rng.rb +86 -0
- data/lib/carray/slab_iterator.rb +58 -13
- data/lib/carray/string_operation_extension.rb +5 -1
- data/lib/carray/time.rb +18 -2
- data/lib/carray/window_iterator.rb +142 -20
- data/lib/carray.rb +2 -0
- data/yard-stubs/ca_obj_block.rb +2 -7
- data/yard-stubs/ca_obj_window.rb +10 -2
- data/yard-stubs/carray_access.rb +1 -1
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_core.rb +0 -80
- data/yard-stubs/carray_count.rb +7 -2
- data/yard-stubs/carray_lazy.rb +205 -0
- data/yard-stubs/carray_math.rb +1486 -3
- data/yard-stubs/carray_median_percentile.rb +16 -2
- data/yard-stubs/carray_order.rb +9 -69
- data/yard-stubs/carray_slab.rb +9 -7
- data/yard-stubs/carray_sort.rb +7 -5
- metadata +9 -1
data/ext/ca_sweep_engine.h
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* OUTPUT (fsync=='1') -> ca_attach + use ca->ptr (sync on release)
|
|
14
14
|
* INPUT (fsync=='0') alias-able -> ca_attach + use ca->ptr
|
|
15
15
|
* INPUT (fsync=='0') non-alias -> xmalloc + ca_xfer_all(GET)
|
|
16
|
-
* (2)
|
|
16
|
+
* (2) operand pairing (scalar collapse; arrays must agree in shape)
|
|
17
17
|
* (3) mask OR across INPUT operands -> m0 (xmalloc, NULL if none)
|
|
18
18
|
* (4) mask propagate to OUTPUT operands (overwrite output->mask)
|
|
19
19
|
* (5) caller runs the per-cell loop using base[] + stride[]
|
|
@@ -84,14 +84,20 @@ typedef struct ca_sweep_state {
|
|
|
84
84
|
ca_size_t chunk_n_max; /* max chunk size from ca_chunk_compute_n */
|
|
85
85
|
ca_size_t inner; /* product of dims except outermost (= row
|
|
86
86
|
size in elements for outer-axis chunking) */
|
|
87
|
-
int chunked_state; /* 0=pre-init, 1=active, 2=done
|
|
87
|
+
int chunked_state; /* 0=pre-init, 1=active, 2=done,
|
|
88
|
+
3=aborted (a read raised; resources
|
|
89
|
+
already given back) */
|
|
88
90
|
boolean8_t *mask_scratch; /* chunk-sized staging for the per-chunk
|
|
89
91
|
mask OR; NULL when no INPUT is masked */
|
|
90
92
|
} ca_sweep_state_t;
|
|
91
93
|
|
|
92
|
-
/* Validate fsync length, acquire per-op
|
|
93
|
-
*
|
|
94
|
-
* length mismatch,
|
|
94
|
+
/* Validate fsync length, pair the operands (shape), acquire per-op
|
|
95
|
+
* buffers, build mask m0, propagate mask to OUTPUTs. May raise: refusals
|
|
96
|
+
* (fsync length, shape mismatch, masked INPUT in a NO_MASK form) before
|
|
97
|
+
* anything is held, and a raising operand read after -- in which case
|
|
98
|
+
* everything acquired so far is detached / freed before the raise
|
|
99
|
+
* propagates, so the caller must not call release. The chunked path
|
|
100
|
+
* does the same for acquire_chunked and each ca_sweep_next_chunk. */
|
|
95
101
|
void ca_sweep_acquire (ca_sweep_state_t *st);
|
|
96
102
|
|
|
97
103
|
/* Reverse-order release: sync OUTPUTs, detach attached / xfree owned_buf,
|
|
@@ -99,6 +105,21 @@ void ca_sweep_acquire (ca_sweep_state_t *st);
|
|
|
99
105
|
* state without re-initializing the caller-owned arrays. */
|
|
100
106
|
void ca_sweep_release (ca_sweep_state_t *st);
|
|
101
107
|
|
|
108
|
+
/* Run walk(arg) -- the caller's loop over the acquired state -- and then
|
|
109
|
+
* release. If walk raises (a callback refusing a value), everything the
|
|
110
|
+
* engine holds is detached / freed without syncing before the raise
|
|
111
|
+
* propagates. Use in place of calling ca_sweep_release /
|
|
112
|
+
* ca_sweep_release_chunked yourself whenever the loop can raise. The
|
|
113
|
+
* chunked walk calls ca_sweep_next_chunk itself. */
|
|
114
|
+
void ca_sweep_run (ca_sweep_state_t *st, VALUE (*walk)(VALUE), VALUE arg);
|
|
115
|
+
void ca_sweep_run_chunked (ca_sweep_state_t *st, VALUE (*walk)(VALUE), VALUE arg);
|
|
116
|
+
|
|
117
|
+
/* Shape pairing shared with rb_ca_template_n: non-zero when a and b have
|
|
118
|
+
* the same ndim and dims; the refusal raises ArgumentError naming both
|
|
119
|
+
* shapes. */
|
|
120
|
+
int ca_sweep_same_shape (CArray *a, CArray *b);
|
|
121
|
+
NORETURN(void ca_sweep_refuse_shapes (CArray *a, CArray *b));
|
|
122
|
+
|
|
102
123
|
/* Strict full-shape equality check used by INOUT macros (AC5: silent-
|
|
103
124
|
* corruption seam prevention). Raises if ndim differs or any dim[k]
|
|
104
125
|
* differs. Returns void; raises on mismatch. */
|
data/ext/carray.h
CHANGED
|
@@ -922,7 +922,6 @@ extern const rb_data_type_t careduce_data_type;
|
|
|
922
922
|
extern const rb_data_type_t carefer_data_type;
|
|
923
923
|
extern const rb_data_type_t caselect_data_type;
|
|
924
924
|
extern const rb_data_type_t cashift_data_type;
|
|
925
|
-
extern const rb_data_type_t caunboundrepeat_data_type;
|
|
926
925
|
extern const rb_data_type_t cawindow_data_type;
|
|
927
926
|
|
|
928
927
|
extern const rb_data_type_t carray_mask_data_type;
|
|
@@ -933,7 +932,6 @@ extern const rb_data_type_t careduce_mask_data_type;
|
|
|
933
932
|
extern const rb_data_type_t carefer_mask_data_type;
|
|
934
933
|
extern const rb_data_type_t caselect_mask_data_type;
|
|
935
934
|
extern const rb_data_type_t cashift_mask_data_type;
|
|
936
|
-
extern const rb_data_type_t caunboundrepeat_mask_data_type;
|
|
937
935
|
extern const rb_data_type_t cawindow_mask_data_type;
|
|
938
936
|
|
|
939
937
|
/* -------------------------------------------------------------------- */
|
|
@@ -1476,6 +1474,27 @@ int ca_is_valid_index (void *ap, ca_size_t *idx);
|
|
|
1476
1474
|
|
|
1477
1475
|
/* API : allocate, attach, update, sync, detach */
|
|
1478
1476
|
|
|
1477
|
+
/* Attach lifecycle contract (R1-R5). Ownership-based, and NOT transitive.
|
|
1478
|
+
This block is the canonical statement of the contract; the other documents
|
|
1479
|
+
copy it. guides/devel/04_attach_lifecycle.md discusses it at length.
|
|
1480
|
+
|
|
1481
|
+
R1 (validity) ca_attach(x) makes x->ptr only valid. It says nothing
|
|
1482
|
+
about any other array.
|
|
1483
|
+
R2 (no transit) Attaching a child does not attach its parent. An
|
|
1484
|
+
implementation may do so as an internal optimisation;
|
|
1485
|
+
never rely on it.
|
|
1486
|
+
R3 (necessity) To touch ca->parent->ptr, call ca_attach(ca->parent)
|
|
1487
|
+
yourself.
|
|
1488
|
+
R4 (ordering) Attaching both parent and child: open parent -> child,
|
|
1489
|
+
close child -> parent, sync in attach order. Symmetric
|
|
1490
|
+
nesting stays correct when a view double-attaches
|
|
1491
|
+
internally (views carry an attach refcount; entities do
|
|
1492
|
+
not).
|
|
1493
|
+
R5 (traffic) Attach hands you a buffer, not a live array. Use x->ptr;
|
|
1494
|
+
a view derived from x composes past the buffer to the
|
|
1495
|
+
root.
|
|
1496
|
+
*/
|
|
1497
|
+
|
|
1479
1498
|
void ca_allocate (void *ap);
|
|
1480
1499
|
void ca_attach (void *ca);
|
|
1481
1500
|
void ca_update (void *ca);
|
data/ext/carray_access.c
CHANGED
|
@@ -19,7 +19,7 @@ static ID id_begin, id_end, id_excl_end;
|
|
|
19
19
|
#define RANGE_EXCL(r) (rb_funcall(r, id_excl_end, 0))
|
|
20
20
|
|
|
21
21
|
static ID id_to_ca;
|
|
22
|
-
static VALUE
|
|
22
|
+
static VALUE sym_perc, sym_under, sym_gt, sym_tilde;
|
|
23
23
|
static VALUE S_CAInfo;
|
|
24
24
|
|
|
25
25
|
VALUE
|
|
@@ -1089,11 +1089,8 @@ rb_ca_fetch_method (int argc, VALUE *argv, VALUE self)
|
|
|
1089
1089
|
already-a-Face case (some builders lift their own result) is handled
|
|
1090
1090
|
inside ca_wrapper_lift.
|
|
1091
1091
|
|
|
1092
|
-
Every CA_REG_* branch converges here, so this one line covers
|
|
1093
|
-
|
|
1094
|
-
whose shape stays open until an operand binds it, and a marker copies
|
|
1095
|
-
shape at construction. ca_wrapper_lift refuses that one, in one place,
|
|
1096
|
-
because `unbound_repeat` reaches it by a second route. */
|
|
1092
|
+
Every CA_REG_* branch converges here, so this one line covers every
|
|
1093
|
+
index form that returns a CArray. */
|
|
1097
1094
|
CA_WRAPPER_LIFT(obj, self, ca);
|
|
1098
1095
|
|
|
1099
1096
|
return obj;
|
|
@@ -1107,6 +1104,8 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1107
1104
|
{
|
|
1108
1105
|
int i;
|
|
1109
1106
|
int nclean = 0;
|
|
1107
|
+
int nscalar = 0;
|
|
1108
|
+
int nunder = 0;
|
|
1110
1109
|
VALUE clean[CA_RANK_MAX];
|
|
1111
1110
|
volatile VALUE base;
|
|
1112
1111
|
ca_size_t final_dims[CA_RANK_MAX];
|
|
@@ -1118,11 +1117,17 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1118
1117
|
/* Build clean argv (strip :_); reject disjoint sigils + rubber dim. */
|
|
1119
1118
|
for (i = 0; i < argc; i++) {
|
|
1120
1119
|
VALUE a = argv[i];
|
|
1121
|
-
if ( a == sym_under )
|
|
1122
|
-
|
|
1120
|
+
if ( a == sym_under ) {
|
|
1121
|
+
nunder++;
|
|
1122
|
+
continue;
|
|
1123
|
+
}
|
|
1124
|
+
if ( FIXNUM_P(a) || RB_TYPE_P(a, T_BIGNUM) ) {
|
|
1125
|
+
nscalar++;
|
|
1126
|
+
}
|
|
1127
|
+
if ( a == sym_gt || a == sym_perc
|
|
1123
1128
|
|| a == Qfalse || a == sym_tilde ) {
|
|
1124
1129
|
rb_raise(rb_eIndexError,
|
|
1125
|
-
"newaxis (:_) cannot be combined with :>,
|
|
1130
|
+
"newaxis (:_) cannot be combined with :>, :%%, "
|
|
1126
1131
|
"or rubber dim (false / :~)");
|
|
1127
1132
|
}
|
|
1128
1133
|
if ( nclean >= CA_RANK_MAX ) {
|
|
@@ -1140,18 +1145,26 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1140
1145
|
nclean, (int) ca->ndim);
|
|
1141
1146
|
}
|
|
1142
1147
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
if (
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1148
|
+
/* Every real axis indexed by a scalar: fetching `clean` would yield the
|
|
1149
|
+
element itself, and there would be nothing left to reshape. Ask for a
|
|
1150
|
+
length-1 block on each axis instead, so the base stays a CArray and the
|
|
1151
|
+
result is a view into self. The result carries exactly the axes :_ asked
|
|
1152
|
+
for, all of length 1 -- an operand that states rank nunder and one
|
|
1153
|
+
element, which is what the shape rules then hold it to. */
|
|
1154
|
+
if ( nscalar == nclean ) {
|
|
1155
|
+
VALUE blocks[CA_RANK_MAX];
|
|
1156
|
+
for (i = 0; i < nclean; i++) {
|
|
1157
|
+
blocks[i] = rb_assoc_new(clean[i], INT2FIX(1));
|
|
1158
|
+
}
|
|
1159
|
+
base = rb_ca_fetch_method(nclean, blocks, self);
|
|
1160
|
+
for (i = 0; i < nunder; i++) {
|
|
1161
|
+
dim_argv[i] = INT2FIX(1);
|
|
1162
|
+
}
|
|
1163
|
+
return rb_ca_reshape(nunder, dim_argv, base);
|
|
1153
1164
|
}
|
|
1154
1165
|
|
|
1166
|
+
base = rb_ca_fetch_method(nclean, clean, self);
|
|
1167
|
+
|
|
1155
1168
|
TypedData_Get_Struct(base, CArray, &carray_data_type, cb);
|
|
1156
1169
|
|
|
1157
1170
|
/* Reconstruct final shape: walk original argv. :_ -> size-1, scalar
|
|
@@ -2076,7 +2089,6 @@ Init_carray_access (void)
|
|
|
2076
2089
|
id_excl_end = rb_intern("exclude_end?");
|
|
2077
2090
|
|
|
2078
2091
|
id_to_ca = rb_intern("to_ca");
|
|
2079
|
-
sym_star = ID2SYM(rb_intern("*"));
|
|
2080
2092
|
sym_perc = ID2SYM(rb_intern("%"));
|
|
2081
2093
|
sym_under = ID2SYM(rb_intern("_"));
|
|
2082
2094
|
sym_gt = ID2SYM(rb_intern(">"));
|