carray 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +205 -0
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_dispatch.c +13 -20
- data/ext/ca_categorical_iterator.c +27 -20
- data/ext/ca_compare.c +4 -4
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_kernel_iterator.c +6 -6
- data/ext/ca_kernel_iterator.h +112 -83
- data/ext/ca_obj_array.c +69 -19
- data/ext/ca_obj_bincmp.c +1 -0
- data/ext/ca_obj_binop.c +1 -0
- data/ext/ca_obj_bitarray.c +5 -1
- data/ext/ca_obj_bitfield.c +58 -43
- data/ext/ca_obj_byte_swap.c +2 -1
- data/ext/ca_obj_const_string.c +15 -3
- data/ext/ca_obj_face.c +42 -1
- data/ext/ca_obj_field.c +13 -3
- data/ext/ca_obj_grid.c +52 -5
- data/ext/ca_obj_monop.c +46 -10
- data/ext/ca_obj_object.c +64 -12
- data/ext/ca_obj_record.c +3 -0
- data/ext/ca_obj_reduce.c +4 -0
- data/ext/ca_obj_refer.c +18 -9
- data/ext/ca_obj_roll.c +26 -6
- data/ext/ca_obj_select.c +34 -5
- data/ext/ca_obj_shift.c +31 -7
- data/ext/ca_obj_stack.c +1 -0
- data/ext/ca_obj_stride.c +28 -19
- data/ext/ca_obj_string.c +11 -2
- data/ext/ca_obj_tile.c +27 -7
- data/ext/ca_obj_transpose.c +8 -4
- data/ext/ca_obj_triop.c +3 -0
- data/ext/ca_obj_window.c +79 -50
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/carray.h +33 -0
- data/ext/carray_access.c +16 -3
- data/ext/carray_attribute.c +24 -0
- data/ext/carray_cast.c +243 -82
- data/ext/carray_cast_func.rb +56 -26
- data/ext/carray_conversion.c +2 -2
- data/ext/carray_core.c +3 -0
- data/ext/carray_count.c +6 -0
- data/ext/carray_element.c +9 -4
- data/ext/carray_factorize.c +20 -20
- data/ext/carray_generate.c +8 -2
- data/ext/carray_histogram.c +1 -1
- data/ext/carray_index_classifier.c +4 -4
- data/ext/carray_internal.h +12 -0
- data/ext/carray_kernels_bincmp.c +168 -168
- data/ext/carray_kernels_binop.c +900 -900
- data/ext/carray_kernels_init.c +4 -4
- data/ext/carray_kernels_moncmp.c +96 -96
- data/ext/carray_kernels_monop.c +1984 -1984
- data/ext/carray_kernels_reduce_aggregate.c +1733 -1733
- data/ext/carray_kernels_reduce_cumulative.c +642 -642
- data/ext/carray_kernels_reduce_extreme.c +1150 -1150
- data/ext/carray_kernels_reduce_variance.c +258 -258
- data/ext/carray_kernels_scan.c +128 -128
- data/ext/carray_kernels_search.c +340 -340
- data/ext/carray_kernels_sort.c +295 -304
- data/ext/carray_kernels_triop.c +114 -114
- data/ext/carray_key_windows.c +4 -0
- data/ext/carray_mask.c +45 -22
- data/ext/carray_memory_view.c +2 -2
- data/ext/carray_operator.c +5 -5
- data/ext/carray_order.c +227 -8
- data/ext/carray_random.c +18 -18
- data/ext/carray_scatter.c +24 -7
- data/ext/carray_slab.c +32 -9
- data/ext/carray_sort.c +224 -16
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +35 -43
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_utils.c +63 -21
- data/ext/mkkernel.rb +210 -115
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +17 -4
- data/lib/carray/basics.rb +27 -7
- data/lib/carray/categorical.rb +30 -16
- data/lib/carray/categorical_iterator.rb +6 -6
- data/lib/carray/const_string.rb +10 -0
- data/lib/carray/data_type_extension.rb +8 -1
- data/lib/carray/fixlen_string.rb +41 -2
- data/lib/carray/frame/column_verbs.rb +4 -3
- data/lib/carray/frame/concat.rb +17 -3
- data/lib/carray/frame/frame.rb +6 -7
- data/lib/carray/frame/group.rb +100 -13
- data/lib/carray/frame/io.rb +3 -1
- data/lib/carray/fuse_source.rb +31 -2
- data/lib/carray/lazy.rb +35 -0
- data/lib/carray/methods/is_in.rb +8 -1
- data/lib/carray/segment_iterator.rb +12 -8
- data/lib/carray/serialize.rb +19 -2
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +8 -0
- data/lib/carray/string_operation_extension.rb +13 -5
- data/lib/carray/struct_builder.rb +5 -3
- data/lib/carray/time.rb +107 -68
- data/yard-stubs/ca_obj_transpose.rb +5 -4
- data/yard-stubs/carray_attribute.rb +3 -1
- data/yard-stubs/carray_cast.rb +2 -0
- data/yard-stubs/carray_conversion.rb +5 -1
- data/yard-stubs/carray_element.rb +7 -6
- data/yard-stubs/carray_mask.rb +8 -3
- data/yard-stubs/carray_math.rb +14 -4
- data/yard-stubs/carray_order.rb +100 -4
- data/yard-stubs/carray_scatter.rb +7 -5
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ccd30e8ea5b53c3a2654a86a0ab7473b3073f7feffa7db7be0e5c9aef5bc17c8
|
|
4
|
+
data.tar.gz: ffcd91fe93ca10b4b12dbff035ffc25533699472b364482a59bf2aa635296032
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 53c08f4ccf6a4c25219cef4e8f27e7de9740dc8c69ee493ff8e3631c87499cd15ed121d5f7707bd1017f77e0309dc1be2628fa3611b9b3c979e0e075008842d6
|
|
7
|
+
data.tar.gz: 2200b047a456603d6274d9dfaf8f93c011ce1cc1eb457c454fa7f9cdc9c75ea4b96c9bbe1dab0b37710f8b872ac5e8b630db5c0dacae12a9012b1b34d4c7f1ec
|
data/CHANGELOG.md
CHANGED
|
@@ -34,6 +34,211 @@ and a newer one. The 1.x history, up to the 2.0.0 release, is in
|
|
|
34
34
|
neighbour ("as well", "the producer above") or leave unnamed the
|
|
35
35
|
method, class or keyword it is about. -->
|
|
36
36
|
|
|
37
|
+
## 3.0.5
|
|
38
|
+
|
|
39
|
+
- New: `GroupedFrame#aggregate` takes a block instead of a spec. The block
|
|
40
|
+
is given the grouping once and returns a Hash of output name => a
|
|
41
|
+
CArray with one value per group, built from `g["col"]` iterators and
|
|
42
|
+
CArray arithmetic (`g["temp"].max - g["temp"].min`). `grp[array]`
|
|
43
|
+
groups any CArray with one entry per row, such as a value computed
|
|
44
|
+
from columns or a column with cells masked.
|
|
45
|
+
|
|
46
|
+
- New: a `CAFrame` grouped reduction takes a Hash of column name => value
|
|
47
|
+
as `fill_value:`, filling only the named columns. A single
|
|
48
|
+
`fill_value:` still goes to every column and has to suit each.
|
|
49
|
+
|
|
50
|
+
- New: `CArray.meld` brings pieces of different data types to a common
|
|
51
|
+
one, as `CArray.stack` does, and takes `data_type:`. `CAFrame.meld` and
|
|
52
|
+
a frame splice still refuse a column whose pieces differ in data type;
|
|
53
|
+
cast the column first, or use `concatenate`.
|
|
54
|
+
|
|
55
|
+
- New: `scatter_replace!` takes an object or fixed-length array, as
|
|
56
|
+
`put_nd` and `put_along_axis` do. The accumulating members
|
|
57
|
+
(`scatter_add!` and the others) still take numeric arrays only.
|
|
58
|
+
|
|
59
|
+
- New: `CAConstString#count` and `CACategorical#count` with no argument
|
|
60
|
+
count the cells that are not masked, as `CArray#count` does.
|
|
61
|
+
|
|
62
|
+
- New: `CAFixlenString` answers `minmax`, `cummax` and `cummin`, as
|
|
63
|
+
`CAString` does.
|
|
64
|
+
|
|
65
|
+
- New (C extensions): `carray.h` defines `ca_u_<type>` cell types and
|
|
66
|
+
`CA_U(type)`, of the same size and value as the plain types but with no
|
|
67
|
+
alignment requirement, for reading cells that need not be aligned (a
|
|
68
|
+
refer with a byte offset, a struct member, a wrapped buffer). The slab
|
|
69
|
+
macros in `ca_kernel_iterator.h` use them for their pointers.
|
|
70
|
+
|
|
71
|
+
- Change: `CACategorical#sort_addr` is renamed `group_addr`, the order of
|
|
72
|
+
the cells by category. `sort_addr` on a categorical now raises, as
|
|
73
|
+
`sort_index` does, since a categorical has no order of values.
|
|
74
|
+
|
|
75
|
+
- Change: a Face's `parent` (of a `CATime`, `CARecord`, ...) is a
|
|
76
|
+
read-only view of its storage. Write the storage of a time through
|
|
77
|
+
`CATime#ticks`.
|
|
78
|
+
|
|
79
|
+
- Change: an operator that cannot bring two data types together raises
|
|
80
|
+
`CArray::DataTypeError` instead of `TypeError`. `DataTypeError` is a
|
|
81
|
+
`TypeError`, so `rescue TypeError` still catches it.
|
|
82
|
+
|
|
83
|
+
- Change: a float cell with no integer of the target type -- an infinity,
|
|
84
|
+
or a value out of the type's range -- is now treated the way NaN
|
|
85
|
+
already was. `to_type` (`int32`, `as_int64`, ...) masks it to `UNDEF`;
|
|
86
|
+
storing it into an integer array raises `RangeError`
|
|
87
|
+
(`FloatDomainError` for an infinity). Before, it became whatever the
|
|
88
|
+
machine's C conversion gave, which differed between x86 and ARM.
|
|
89
|
+
`clip_int64` and the other `clip_<type>` methods saturate a float
|
|
90
|
+
source to the type's limits on every machine; integer `linspace` raises
|
|
91
|
+
`RangeError` for a span the type cannot hold.
|
|
92
|
+
|
|
93
|
+
- Change: a Ruby Array operand of a numeric or boolean array is read as
|
|
94
|
+
its cells: `a.eq([1, 5, 3])` compares cell by cell (it compared every
|
|
95
|
+
cell with the whole Array), and `a + [1, 2, 3]` adds (it raised).
|
|
96
|
+
Nested Arrays give the axes. An object array still takes an Array as
|
|
97
|
+
one value.
|
|
98
|
+
|
|
99
|
+
- Change: `window`'s `bounds:` is a policy named by a Symbol or String,
|
|
100
|
+
matched whole; an Integer and an abbreviation raise. A `fill_value:`
|
|
101
|
+
given with a policy that does not use it (`:nearest`, `:strict`, ...)
|
|
102
|
+
raises instead of being dropped.
|
|
103
|
+
|
|
104
|
+
- Change: a length, count, offset or shift given to a view
|
|
105
|
+
(`sliding_windows`, `block_view`, `tile`, `roll`, `shift`, `field`,
|
|
106
|
+
`diagonal`) must be an Integer; a Float raises `TypeError` instead of
|
|
107
|
+
being truncated. `transpose` reads its axes as the other axis arguments
|
|
108
|
+
are read: negative from the end, an Integer only.
|
|
109
|
+
|
|
110
|
+
- Change: `drop_axis` on an array whose every axis has size 1 keeps one
|
|
111
|
+
axis of size 1, and `reshape` with no axes raises.
|
|
112
|
+
|
|
113
|
+
- Change: in an index of one key per axis, an index array of more than
|
|
114
|
+
one axis on one axis raises `ArgumentError`; it was read flat. Pass
|
|
115
|
+
`idx.flatten` for the old reading.
|
|
116
|
+
|
|
117
|
+
- Change: `elem_fetch`, `elem_store` and the other `elem_*` methods read
|
|
118
|
+
an index as `[]` reads a key: a Float with no fraction is an index, a
|
|
119
|
+
Float with a fraction raises `IndexError`.
|
|
120
|
+
|
|
121
|
+
- Change: two string arrays of different kinds (`CAString`,
|
|
122
|
+
`CAFixlenString`, `CAConstString`) or of different widths compare by
|
|
123
|
+
their strings. A String query longer than a fixed-width cell matches
|
|
124
|
+
no cell in `eq`, `count`, `search`, `bsearch` and `is_in`; it was cut
|
|
125
|
+
to the cell's width.
|
|
126
|
+
|
|
127
|
+
- Change: `str_index` and `rindex` give `UNDEF` for a cell that does not
|
|
128
|
+
hold the substring; they raised for the whole array.
|
|
129
|
+
|
|
130
|
+
- Change: `bsearch` and `bsearch_addr` answer the first of several equal
|
|
131
|
+
cells.
|
|
132
|
+
|
|
133
|
+
- Change: `search` and `search_addr` raise `ArgumentError` for a negative
|
|
134
|
+
or NaN `eps`, which acted as an exact match.
|
|
135
|
+
|
|
136
|
+
- Change: `inherit_mask` and `inherit_mask_replace` raise `ArgumentError`
|
|
137
|
+
for a source whose number of cells differs from the receiver's (a
|
|
138
|
+
scalar source still applies to every cell).
|
|
139
|
+
|
|
140
|
+
- Change: a reduction's `fill_value:` that its result cannot hold raises
|
|
141
|
+
even when no cell needs it, and `fill` on an empty array checks its
|
|
142
|
+
value as an assignment does.
|
|
143
|
+
|
|
144
|
+
- Change: rounding a `:M` or `:Y` `CATime` to a calendar bucket
|
|
145
|
+
(`round(unit: :Y)`, `"3 months"`) measures the distance by the instant,
|
|
146
|
+
so it agrees with the same dates on `:D`.
|
|
147
|
+
|
|
148
|
+
- Change: a `CATime` reduction (`mean`, `median`, ...) sends a tie to the
|
|
149
|
+
later tick on both sides of 1970; before 1970 it went to the earlier
|
|
150
|
+
one.
|
|
151
|
+
|
|
152
|
+
- Change: a duration String added to or subtracted from a `CATime` is
|
|
153
|
+
one step of its own resolution, so `"15 minutes"` on a `"10 minutes"`
|
|
154
|
+
grid raises, as the same duration as a `CATimedelta` does. It was read
|
|
155
|
+
as fifteen one-minute steps and cut to the grid.
|
|
156
|
+
|
|
157
|
+
- Change: of `-0.0` and `0.0`, `pmax` gives `0.0` and `pmin` gives
|
|
158
|
+
`-0.0`, in either order and on every platform, as `maximum` and
|
|
159
|
+
`minimum` do. Which zero `min` and `max` answer is not specified.
|
|
160
|
+
|
|
161
|
+
- Change: a one-sided `clip` passes a NaN cell through, as a two-sided
|
|
162
|
+
`clip` does.
|
|
163
|
+
|
|
164
|
+
- Change: a categorical's `fill_value:` (of `shift`, `window`, `project`)
|
|
165
|
+
is a label; a `CAConstString` takes only `UNDEF` as a fill value.
|
|
166
|
+
|
|
167
|
+
- Change: a lazy operator with a Face operand (a categorical, a time, a
|
|
168
|
+
string array) answers as the eager operator does; it read the Face's
|
|
169
|
+
storage. `CAConstString#eq` with another array compares cell by cell.
|
|
170
|
+
|
|
171
|
+
- Change: a boolean member of a record (or `field(offset, :boolean)` of a
|
|
172
|
+
fixed-length array) raises `RangeError` when read as a byte that is not
|
|
173
|
+
0 or 1, instead of answering differently in each method.
|
|
174
|
+
|
|
175
|
+
- Change: unmasking a cell of a `CAString` that holds no String gives an
|
|
176
|
+
empty String.
|
|
177
|
+
|
|
178
|
+
- Change: `swap_bytes` keeps the attributes, as `refer` and `bitfield`
|
|
179
|
+
do. An array with no cells has no say in the attributes a `meld`,
|
|
180
|
+
`stack` or `concatenate` keeps.
|
|
181
|
+
|
|
182
|
+
- Change: `dim_view` keeps a Face, as `transpose` does.
|
|
183
|
+
|
|
184
|
+
- Change: `CArray.string(n)` without a block, and `CArray.string("ab")`,
|
|
185
|
+
raise; `fixlen_string` and `to_fixlen_string` raise for `bytes:` below 1.
|
|
186
|
+
`project` raises for a keyword argument, `paste` into a frozen array
|
|
187
|
+
raises `FrozenError`, and `CArray.result_type` refuses a MemoryView
|
|
188
|
+
operand whose format carray cannot read, as the operators do.
|
|
189
|
+
|
|
190
|
+
- Change: `CArray.sort_addr` with numeric keys is two to three times as fast, and
|
|
191
|
+
`nlargest` / `nsmallest` read each fiber once with a work area of a
|
|
192
|
+
few times n.
|
|
193
|
+
|
|
194
|
+
- Fix: x86-64 Linux. Inputs that reached an integer division by zero
|
|
195
|
+
inside the library stopped the process with SIGFPE there (on ARM they
|
|
196
|
+
were refused later or gave a wrong answer): a sum over a view with a
|
|
197
|
+
zero-length axis, `wsum` / `wmean` with 1-D weights over a zero-length
|
|
198
|
+
axis, a view of a stack of empty arrays, `window` with a step of 0, and
|
|
199
|
+
`wrap_readonly(String, CA_FIXLEN)`. Each now answers or raises
|
|
200
|
+
`ArgumentError`. The extension builds with GCC 14 without warnings.
|
|
201
|
+
|
|
202
|
+
- Fix: big-endian hosts. `bitfield` read 0 and lost writes, a struct's
|
|
203
|
+
bit members overwrote each other, and an element-wise operation applied
|
|
204
|
+
in place could give a wrong cell.
|
|
205
|
+
|
|
206
|
+
- Fix: `save` and `dump` with `endian: :little` or `:big` wrote the other
|
|
207
|
+
byte order. `load` reads the marker, so files written so far still load
|
|
208
|
+
correctly.
|
|
209
|
+
|
|
210
|
+
- Fix: running out of memory inside a kernel left a view attached, lost
|
|
211
|
+
the keywords of the call (`a.sum(axis: 1)` returned the total), or
|
|
212
|
+
leaked the array being built.
|
|
213
|
+
|
|
214
|
+
- Fix: an array with 16 axes (the maximum) given to `bitarray`, `field`,
|
|
215
|
+
a narrowing `refer` or a `:_` index wrote past an internal array.
|
|
216
|
+
|
|
217
|
+
- Fix: a lazy chain whose step narrows the cells (`a.lazy.abs` of a
|
|
218
|
+
complex array) overran the heap; `seq` on an empty object array wrote
|
|
219
|
+
past its end.
|
|
220
|
+
|
|
221
|
+
- Fix: a CAObject's copy and sync hooks: a view the hook kept of the
|
|
222
|
+
array it was lent, or the lent array's mask, pointed at freed memory
|
|
223
|
+
after the hook returned.
|
|
224
|
+
|
|
225
|
+
- Fix: `CArray.fuse` crashed when several Ractors ran a fuse block for the
|
|
226
|
+
first time at once.
|
|
227
|
+
|
|
228
|
+
- Fix: a grouped `variancep` / `stddevp` matches `CArray#variancep` to the
|
|
229
|
+
last bit.
|
|
230
|
+
|
|
231
|
+
- Fix: `count` with an array of values honours `keep_axis:`.
|
|
232
|
+
|
|
233
|
+
- Fix: `CARecord.wrap` of a record array wraps its storage, not the
|
|
234
|
+
record array.
|
|
235
|
+
|
|
236
|
+
- Fix: an unnamed struct's `order_by` survives `save` / `load` and
|
|
237
|
+
Marshal.
|
|
238
|
+
|
|
239
|
+
- Fix: `CAFrame.from_csv` and `cast(name => :time)` read a leap second
|
|
240
|
+
(`23:59:60`) as `CArray.time` does, into the next minute.
|
|
241
|
+
|
|
37
242
|
## 3.0.4
|
|
38
243
|
|
|
39
244
|
- New: `CAFrame#verify(rules)` judges every row against named rules (each
|
data/carray.gemspec
CHANGED
data/ext/ca_array_pool.c
CHANGED
|
@@ -43,18 +43,42 @@
|
|
|
43
43
|
---------------------------------------------------------------------------- */
|
|
44
44
|
|
|
45
45
|
#include "carray.h"
|
|
46
|
+
#include "carray_internal.h"
|
|
46
47
|
#include <string.h>
|
|
47
48
|
|
|
48
49
|
/* Allocate struct + pool in one shot, then run pool_init.
|
|
49
50
|
*
|
|
50
51
|
* Called by per-class C `*_new` constructors. */
|
|
52
|
+
typedef struct {
|
|
53
|
+
CArray *ca;
|
|
54
|
+
int8_t obj_type;
|
|
55
|
+
int8_t ndim;
|
|
56
|
+
} ca_array_alloc_arg;
|
|
57
|
+
|
|
58
|
+
static VALUE
|
|
59
|
+
ca_array_alloc_pool (VALUE varg)
|
|
60
|
+
{
|
|
61
|
+
ca_array_alloc_arg *a = (ca_array_alloc_arg *) varg;
|
|
62
|
+
ca_array_pool_alloc(a->ca, a->obj_type, a->ndim);
|
|
63
|
+
return Qnil;
|
|
64
|
+
}
|
|
65
|
+
|
|
51
66
|
void *
|
|
52
67
|
ca_array_alloc (int8_t obj_type, int8_t ndim)
|
|
53
68
|
{
|
|
54
69
|
ca_operation_function_t *func = &ca_func[obj_type];
|
|
55
70
|
CArray *ca = xmalloc(func->struct_size);
|
|
71
|
+
ca_array_alloc_arg a;
|
|
56
72
|
memset(ca, 0, func->struct_size);
|
|
57
|
-
|
|
73
|
+
/* The type is set now so that a constructor whose setup raises can hand
|
|
74
|
+
the struct to ca_free, which dispatches on it. The setup sets it
|
|
75
|
+
again. */
|
|
76
|
+
ca->obj_type = obj_type;
|
|
77
|
+
/* The pool is a second allocation; when it fails, the struct goes too. */
|
|
78
|
+
a.ca = ca;
|
|
79
|
+
a.obj_type = obj_type;
|
|
80
|
+
a.ndim = ndim;
|
|
81
|
+
ca_fill_or_xfree(ca, ca_array_alloc_pool, (VALUE) &a);
|
|
58
82
|
return ca;
|
|
59
83
|
}
|
|
60
84
|
|
data/ext/ca_axis_dispatch.c
CHANGED
|
@@ -647,15 +647,15 @@ ca_axis_dispatch_percell_gather (CArray *parent,
|
|
|
647
647
|
break;
|
|
648
648
|
case 2:
|
|
649
649
|
for (j = 0; j < inner_count; j++)
|
|
650
|
-
|
|
650
|
+
__builtin_memcpy(row_dst + j*2, src + j*inner_step, 2);
|
|
651
651
|
break;
|
|
652
652
|
case 4:
|
|
653
653
|
for (j = 0; j < inner_count; j++)
|
|
654
|
-
|
|
654
|
+
__builtin_memcpy(row_dst + j*4, src + j*inner_step, 4);
|
|
655
655
|
break;
|
|
656
656
|
case 8:
|
|
657
657
|
for (j = 0; j < inner_count; j++)
|
|
658
|
-
|
|
658
|
+
__builtin_memcpy(row_dst + j*8, src + j*inner_step, 8);
|
|
659
659
|
break;
|
|
660
660
|
default:
|
|
661
661
|
for (j = 0; j < inner_count; j++)
|
|
@@ -672,18 +672,15 @@ ca_axis_dispatch_percell_gather (CArray *parent,
|
|
|
672
672
|
break;
|
|
673
673
|
case 2:
|
|
674
674
|
for (j = 0; j < inner_count; j++)
|
|
675
|
-
|
|
676
|
-
*(uint16_t *)(row_src_base + inner_indices[j]*inner_pstride);
|
|
675
|
+
__builtin_memcpy(row_dst + j*2, row_src_base + inner_indices[j]*inner_pstride, 2);
|
|
677
676
|
break;
|
|
678
677
|
case 4:
|
|
679
678
|
for (j = 0; j < inner_count; j++)
|
|
680
|
-
|
|
681
|
-
*(uint32_t *)(row_src_base + inner_indices[j]*inner_pstride);
|
|
679
|
+
__builtin_memcpy(row_dst + j*4, row_src_base + inner_indices[j]*inner_pstride, 4);
|
|
682
680
|
break;
|
|
683
681
|
case 8:
|
|
684
682
|
for (j = 0; j < inner_count; j++)
|
|
685
|
-
|
|
686
|
-
*(uint64_t *)(row_src_base + inner_indices[j]*inner_pstride);
|
|
683
|
+
__builtin_memcpy(row_dst + j*8, row_src_base + inner_indices[j]*inner_pstride, 8);
|
|
687
684
|
break;
|
|
688
685
|
default:
|
|
689
686
|
for (j = 0; j < inner_count; j++)
|
|
@@ -761,8 +758,7 @@ ca_axis_dispatch_gather (CArray *parent,
|
|
|
761
758
|
so clang lowers to NEON ldp/stp directly (no libc memcpy call). */
|
|
762
759
|
if ( sbytes == 8 ) {
|
|
763
760
|
for ( i = 0; i < n; i++ ) {
|
|
764
|
-
|
|
765
|
-
*(uint64_t *)(base + indices[i] * pstride);
|
|
761
|
+
__builtin_memcpy(out_buf + i*8, base + indices[i] * pstride, 8);
|
|
766
762
|
}
|
|
767
763
|
} else if ( sbytes == 16 ) {
|
|
768
764
|
for ( i = 0; i < n; i++ ) {
|
|
@@ -887,15 +883,15 @@ ca_axis_dispatch_percell_scatter (CArray *parent,
|
|
|
887
883
|
break;
|
|
888
884
|
case 2:
|
|
889
885
|
for (j = 0; j < inner_count; j++)
|
|
890
|
-
|
|
886
|
+
__builtin_memcpy(dst + j*inner_step, row_src + j*2, 2);
|
|
891
887
|
break;
|
|
892
888
|
case 4:
|
|
893
889
|
for (j = 0; j < inner_count; j++)
|
|
894
|
-
|
|
890
|
+
__builtin_memcpy(dst + j*inner_step, row_src + j*4, 4);
|
|
895
891
|
break;
|
|
896
892
|
case 8:
|
|
897
893
|
for (j = 0; j < inner_count; j++)
|
|
898
|
-
|
|
894
|
+
__builtin_memcpy(dst + j*inner_step, row_src + j*8, 8);
|
|
899
895
|
break;
|
|
900
896
|
default:
|
|
901
897
|
for (j = 0; j < inner_count; j++)
|
|
@@ -912,18 +908,15 @@ ca_axis_dispatch_percell_scatter (CArray *parent,
|
|
|
912
908
|
break;
|
|
913
909
|
case 2:
|
|
914
910
|
for (j = 0; j < inner_count; j++)
|
|
915
|
-
|
|
916
|
-
*(uint16_t *)(row_src + j*2);
|
|
911
|
+
__builtin_memcpy(row_dst_base + inner_indices[j]*inner_pstride, row_src + j*2, 2);
|
|
917
912
|
break;
|
|
918
913
|
case 4:
|
|
919
914
|
for (j = 0; j < inner_count; j++)
|
|
920
|
-
|
|
921
|
-
*(uint32_t *)(row_src + j*4);
|
|
915
|
+
__builtin_memcpy(row_dst_base + inner_indices[j]*inner_pstride, row_src + j*4, 4);
|
|
922
916
|
break;
|
|
923
917
|
case 8:
|
|
924
918
|
for (j = 0; j < inner_count; j++)
|
|
925
|
-
|
|
926
|
-
*(uint64_t *)(row_src + j*8);
|
|
919
|
+
__builtin_memcpy(row_dst_base + inner_indices[j]*inner_pstride, row_src + j*8, 8);
|
|
927
920
|
break;
|
|
928
921
|
default:
|
|
929
922
|
for (j = 0; j < inner_count; j++)
|
|
@@ -457,20 +457,23 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
457
457
|
|
|
458
458
|
/* ---------------------------------------------------------------------------
|
|
459
459
|
|
|
460
|
-
__reduceat_variance__ — centred two-pass
|
|
461
|
-
The means (from the cached moments: sum/count)
|
|
462
|
-
accumulates the per-segment centred sum of
|
|
463
|
-
Centred (not the one-pass
|
|
464
|
-
one-pass formula cancels
|
|
465
|
-
|
|
466
|
-
SS / (count-
|
|
467
|
-
|
|
468
|
-
|
|
460
|
+
__reduceat_variance__ — centred two-pass variance reduceat, sample (ddof=1)
|
|
461
|
+
or population (ddof=0). The means (from the cached moments: sum/count)
|
|
462
|
+
drive a second walk that accumulates the per-segment centred sum of
|
|
463
|
+
squares; variance = SS / (n - ddof). Centred (not the one-pass
|
|
464
|
+
sum-of-squares) so the ε-close contract holds — a one-pass formula cancels
|
|
465
|
+
catastrophically. Matches CArray#variance / #variancep per group: count
|
|
466
|
+
<= ddof (or 0) -> masked, otherwise SS / (count - ddof), divided once as
|
|
467
|
+
the core does.
|
|
468
|
+
|
|
469
|
+
Surface (private):
|
|
470
|
+
grouped.__reduceat_variance__(offsets, means, counts, out, ddof)
|
|
469
471
|
self = grouped (numeric value data type, may carry a mask)
|
|
470
472
|
offsets = int64[k] segment STARTS
|
|
471
473
|
means = float64[k] per-segment mean (ignored where count < 2)
|
|
472
474
|
counts = int64[k] per-segment present count
|
|
473
|
-
out = float64[k] output: variance; count
|
|
475
|
+
out = float64[k] output: variance; count <= ddof masked
|
|
476
|
+
ddof = 1 (sample) or 0 (population)
|
|
474
477
|
|
|
475
478
|
--------------------------------------------------------------------------- */
|
|
476
479
|
|
|
@@ -479,7 +482,7 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
479
482
|
const T *gp = (const T *) grouped->ptr; \
|
|
480
483
|
for ( c = 0; c < k; c++ ) { \
|
|
481
484
|
int64_t cnt = countp[c]; \
|
|
482
|
-
if ( cnt <
|
|
485
|
+
if ( cnt <= ddof || cnt < 1 ) { outp[c] = 0.0; outm[c] = 1; continue; } \
|
|
483
486
|
{ double mean = meanp[c], ss = 0.0; \
|
|
484
487
|
ca_size_t lo = (ca_size_t) offs[c]; \
|
|
485
488
|
ca_size_t hi = (c + 1 < k) ? (ca_size_t) offs[c+1] : n, j; \
|
|
@@ -494,14 +497,15 @@ rb_ca_reduceat_percentile (VALUE self, VALUE roffsets, VALUE rp, VALUE rout)
|
|
|
494
497
|
double d = (double) gp[j] - mean; ss += d * d; \
|
|
495
498
|
} \
|
|
496
499
|
} \
|
|
497
|
-
outp[c] = ss / (double) (cnt -
|
|
500
|
+
outp[c] = ss / (double) (cnt - ddof); } \
|
|
498
501
|
} \
|
|
499
502
|
} while (0)
|
|
500
503
|
|
|
501
504
|
static VALUE
|
|
502
505
|
rb_ca_reduceat_variance (VALUE self, VALUE roffsets, VALUE rmeans,
|
|
503
|
-
VALUE rcounts, VALUE rout)
|
|
506
|
+
VALUE rcounts, VALUE rout, VALUE rddof)
|
|
504
507
|
{
|
|
508
|
+
int64_t ddof = NUM2LL(rddof);
|
|
505
509
|
CArray *grouped, *offsets, *means, *counts, *out;
|
|
506
510
|
int64_t k, *offs, *countp;
|
|
507
511
|
ca_size_t n, c;
|
|
@@ -518,8 +522,9 @@ rb_ca_reduceat_variance (VALUE self, VALUE roffsets, VALUE rmeans,
|
|
|
518
522
|
n = grouped->elements;
|
|
519
523
|
if ( offsets->data_type != CA_INT64 || counts->data_type != CA_INT64 ||
|
|
520
524
|
means->data_type != CA_FLOAT64 || out->data_type != CA_FLOAT64 ||
|
|
521
|
-
means->elements != k || counts->elements != k || out->elements != k
|
|
522
|
-
|
|
525
|
+
means->elements != k || counts->elements != k || out->elements != k ||
|
|
526
|
+
( ddof != 0 && ddof != 1 ) ) {
|
|
527
|
+
rb_raise(rb_eArgError, "__reduceat_variance__: offsets/counts int64, means/out float64[k], ddof 0 or 1");
|
|
523
528
|
}
|
|
524
529
|
|
|
525
530
|
offs = (int64_t *) offsets->ptr;
|
|
@@ -1104,8 +1109,13 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
|
|
|
1104
1109
|
h->data_type);
|
|
1105
1110
|
}
|
|
1106
1111
|
|
|
1112
|
+
ca_detach(h);
|
|
1113
|
+
ca_detach(codes);
|
|
1114
|
+
|
|
1107
1115
|
/* Mask empty (count == 0) cells in mins/maxs: value slot is 0 but meaningless.
|
|
1108
|
-
Matches __reduceat_moments__ contract for empty segments.
|
|
1116
|
+
Matches __reduceat_moments__ contract for empty segments. After the
|
|
1117
|
+
detach: creating a mask allocates, and a raise must not leave h and
|
|
1118
|
+
codes attached. */
|
|
1109
1119
|
ca_create_mask(mins);
|
|
1110
1120
|
ca_create_mask(maxs);
|
|
1111
1121
|
minm = (boolean8_t *) mins->mask->ptr;
|
|
@@ -1113,9 +1123,6 @@ rb_ca_fiber_scatter_moments (VALUE self, VALUE rcodes, VALUE raxis, VALUE rk,
|
|
|
1113
1123
|
for ( cell = 0; cell < total; cell++ ) {
|
|
1114
1124
|
if ( countp[cell] == 0 ) { minm[cell] = 1; maxm[cell] = 1; }
|
|
1115
1125
|
}
|
|
1116
|
-
|
|
1117
|
-
ca_detach(h);
|
|
1118
|
-
ca_detach(codes);
|
|
1119
1126
|
return Qnil;
|
|
1120
1127
|
}
|
|
1121
1128
|
|
|
@@ -1481,7 +1488,7 @@ Init_ca_categorical_iterator (void)
|
|
|
1481
1488
|
rb_define_private_method(rb_cCArray, "__reduceat_percentile__",
|
|
1482
1489
|
rb_ca_reduceat_percentile, 3);
|
|
1483
1490
|
rb_define_private_method(rb_cCArray, "__reduceat_variance__",
|
|
1484
|
-
rb_ca_reduceat_variance,
|
|
1491
|
+
rb_ca_reduceat_variance, 5);
|
|
1485
1492
|
rb_define_private_method(rb_cCArray, "__reduceat_prod__",
|
|
1486
1493
|
rb_ca_reduceat_prod, 2);
|
|
1487
1494
|
rb_define_private_method(rb_cCArray, "__reduceat_argminmax__",
|
data/ext/ca_compare.c
CHANGED
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
static int \
|
|
22
22
|
elem_cmp_## type (const void *va, const void *vb) \
|
|
23
23
|
{ \
|
|
24
|
-
const type *a = (const type *) va;
|
|
25
|
-
const type *b = (const type *) vb;
|
|
24
|
+
const CA_U(type) *a = (const CA_U(type) *) va; \
|
|
25
|
+
const CA_U(type) *b = (const CA_U(type) *) vb; \
|
|
26
26
|
if ( *a > *b ) return 1; \
|
|
27
27
|
if ( *a < *b ) return -1; \
|
|
28
28
|
return 0; \
|
|
@@ -33,8 +33,8 @@ elem_cmp_## type (const void *va, const void *vb) \
|
|
|
33
33
|
static int \
|
|
34
34
|
elem_cmp_## type (const void *va, const void *vb) \
|
|
35
35
|
{ \
|
|
36
|
-
const type a = *(const type *) va;
|
|
37
|
-
const type b = *(const type *) vb;
|
|
36
|
+
const type a = *(const CA_U(type) *) va; \
|
|
37
|
+
const type b = *(const CA_U(type) *) vb; \
|
|
38
38
|
return CA_FLOAT_ORDER_CMP(a, b); \
|
|
39
39
|
}
|
|
40
40
|
|
data/ext/ca_composite_dispatch.c
CHANGED
|
@@ -32,29 +32,29 @@ ca_fill_typed (char *dst, const char *val, ca_size_t bytes, ca_size_t n)
|
|
|
32
32
|
break;
|
|
33
33
|
}
|
|
34
34
|
case 2: {
|
|
35
|
-
uint16_t v = *(const
|
|
36
|
-
|
|
35
|
+
uint16_t v = *(const ca_u_uint16_t *)val;
|
|
36
|
+
ca_u_uint16_t *p = (ca_u_uint16_t *)dst;
|
|
37
37
|
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
38
38
|
break;
|
|
39
39
|
}
|
|
40
40
|
case 4: {
|
|
41
|
-
uint32_t v = *(const
|
|
42
|
-
|
|
41
|
+
uint32_t v = *(const ca_u_uint32_t *)val;
|
|
42
|
+
ca_u_uint32_t *p = (ca_u_uint32_t *)dst;
|
|
43
43
|
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
44
44
|
break;
|
|
45
45
|
}
|
|
46
46
|
case 8: {
|
|
47
|
-
uint64_t v = *(const
|
|
48
|
-
|
|
47
|
+
uint64_t v = *(const ca_u_uint64_t *)val;
|
|
48
|
+
ca_u_uint64_t *p = (ca_u_uint64_t *)dst;
|
|
49
49
|
for ( i = 0; i < n; i++ ) p[i] = v;
|
|
50
50
|
break;
|
|
51
51
|
}
|
|
52
52
|
case 16: {
|
|
53
53
|
/* complex128 etc. Two uint64_t stores per element. Compiler
|
|
54
54
|
pairs them into a NEON 128-bit or SSE2 store. */
|
|
55
|
-
uint64_t v0 = ((const
|
|
56
|
-
uint64_t v1 = ((const
|
|
57
|
-
|
|
55
|
+
uint64_t v0 = ((const ca_u_uint64_t *)val)[0];
|
|
56
|
+
uint64_t v1 = ((const ca_u_uint64_t *)val)[1];
|
|
57
|
+
ca_u_uint64_t *p = (ca_u_uint64_t *)dst;
|
|
58
58
|
for ( i = 0; i < n; i++ ) {
|
|
59
59
|
p[2*i] = v0;
|
|
60
60
|
p[2*i + 1] = v1;
|
data/ext/ca_kernel_iterator.c
CHANGED
|
@@ -1964,20 +1964,20 @@ ca_iter_state_next_slab_axes_unprotected (ca_iter_state *st,
|
|
|
1964
1964
|
/* f64 / i64 hot path: store one cell per inner iter, compiler
|
|
1965
1965
|
can keep `src` in a vector reg and stream cleanly. */
|
|
1966
1966
|
for ( int32_t kk = 0; kk < K; kk++ ) {
|
|
1967
|
-
const
|
|
1967
|
+
const ca_u_uint64_t *src = (const ca_u_uint64_t *)
|
|
1968
1968
|
(pptrs[kk] + parent_off);
|
|
1969
|
-
|
|
1969
|
+
ca_u_uint64_t *dst = (ca_u_uint64_t *) (cache + (ca_size_t) kk * bytes);
|
|
1970
1970
|
for ( ca_size_t t = 0; t < want; t++ ) {
|
|
1971
|
-
*(
|
|
1971
|
+
*(ca_u_uint64_t *)((char *) dst + t * stride_t) = src[t];
|
|
1972
1972
|
}
|
|
1973
1973
|
}
|
|
1974
1974
|
} else if ( bytes == 4 ) {
|
|
1975
1975
|
for ( int32_t kk = 0; kk < K; kk++ ) {
|
|
1976
|
-
const
|
|
1976
|
+
const ca_u_uint32_t *src = (const ca_u_uint32_t *)
|
|
1977
1977
|
(pptrs[kk] + parent_off);
|
|
1978
|
-
|
|
1978
|
+
ca_u_uint32_t *dst = (ca_u_uint32_t *) (cache + (ca_size_t) kk * bytes);
|
|
1979
1979
|
for ( ca_size_t t = 0; t < want; t++ ) {
|
|
1980
|
-
*(
|
|
1980
|
+
*(ca_u_uint32_t *)((char *) dst + t * stride_t) = src[t];
|
|
1981
1981
|
}
|
|
1982
1982
|
}
|
|
1983
1983
|
} else {
|