carray 3.0.4 → 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 +438 -0
- data/README.md +1 -1
- data/carray.gemspec +3 -2
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_dispatch.c +19 -20
- data/ext/ca_axis_group.c +1 -1
- data/ext/ca_categorical_iterator.c +34 -27
- data/ext/ca_compare.c +4 -4
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_kernel_iterator.c +122 -237
- data/ext/ca_kernel_iterator.h +522 -337
- data/ext/ca_obj_array.c +69 -19
- data/ext/ca_obj_bincmp.c +10 -1
- data/ext/ca_obj_binop.c +11 -1
- data/ext/ca_obj_bitarray.c +5 -1
- data/ext/ca_obj_bitfield.c +60 -43
- data/ext/ca_obj_byte_swap.c +4 -1
- data/ext/ca_obj_const_string.c +15 -3
- data/ext/ca_obj_face.c +44 -1
- data/ext/ca_obj_fake.c +3 -1
- data/ext/ca_obj_field.c +13 -3
- data/ext/ca_obj_grid.c +219 -17
- data/ext/ca_obj_meld.c +69 -113
- data/ext/ca_obj_moncmp.c +9 -1
- data/ext/ca_obj_monop.c +86 -12
- data/ext/ca_obj_object.c +118 -32
- data/ext/ca_obj_record.c +3 -0
- data/ext/ca_obj_reduce.c +19 -1
- data/ext/ca_obj_refer.c +80 -26
- data/ext/ca_obj_remap.c +69 -10
- data/ext/ca_obj_roll.c +27 -6
- data/ext/ca_obj_select.c +38 -6
- data/ext/ca_obj_select_axis.c +1 -0
- data/ext/ca_obj_shift.c +32 -7
- data/ext/ca_obj_stack.c +311 -111
- data/ext/ca_obj_stride.c +159 -64
- data/ext/ca_obj_string.c +27 -2
- data/ext/ca_obj_tile.c +28 -7
- data/ext/ca_obj_transpose.c +8 -4
- data/ext/ca_obj_triop.c +12 -1
- data/ext/ca_obj_window.c +80 -50
- data/ext/ca_op_ipower.c +12 -12
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +35 -1
- data/ext/carray_access.c +43 -67
- data/ext/carray_address_basis.c +134 -0
- data/ext/carray_attribute.c +32 -0
- data/ext/carray_broadcast.c +3 -4
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_cast.c +251 -93
- data/ext/carray_cast_func.rb +56 -26
- data/ext/carray_conversion.c +11 -7
- data/ext/carray_core.c +814 -72
- data/ext/carray_count.c +6 -0
- data/ext/carray_element.c +22 -13
- data/ext/carray_factorize.c +20 -20
- data/ext/carray_generate.c +8 -2
- data/ext/carray_histogram.c +26 -4
- data/ext/carray_index_classifier.c +4 -4
- data/ext/carray_internal.h +159 -12
- data/ext/carray_kernels_bincmp.c +2174 -170
- data/ext/carray_kernels_binop.c +25653 -5487
- data/ext/carray_kernels_init.c +8 -8
- data/ext/carray_kernels_moncmp.c +96 -96
- data/ext/carray_kernels_monop.c +12253 -5235
- data/ext/carray_kernels_reduce_aggregate.c +6150 -2423
- data/ext/carray_kernels_reduce_boolean.c +1533 -15
- data/ext/carray_kernels_reduce_cumulative.c +2442 -882
- data/ext/carray_kernels_reduce_extreme.c +5658 -1661
- data/ext/carray_kernels_reduce_variance.c +2534 -402
- data/ext/carray_kernels_scan.c +368 -368
- data/ext/carray_kernels_search.c +4551 -604
- data/ext/carray_kernels_sort.c +659 -751
- data/ext/carray_kernels_triop.c +114 -114
- data/ext/carray_key_windows.c +4 -0
- data/ext/carray_lazy.c +47 -0
- data/ext/carray_loop.c +1 -1
- data/ext/carray_mask.c +175 -161
- data/ext/carray_median_percentile.c +4 -4
- data/ext/carray_memory_view.c +15 -9
- data/ext/carray_operator.c +152 -49
- data/ext/carray_order.c +230 -10
- data/ext/carray_random.c +22 -19
- data/ext/carray_scatter.c +24 -7
- data/ext/carray_slab.c +128 -29
- 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_test.c +74 -19
- data/ext/carray_time_text.c +6 -4
- data/ext/carray_utils.c +63 -21
- data/ext/extconf.rb +11 -0
- data/ext/mkkernel.rb +546 -199
- data/ext/ruby_carray.c +4 -1
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +42 -5
- 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 +28 -8
- data/lib/carray/block_iterator.rb +17 -3
- data/lib/carray/categorical.rb +35 -23
- data/lib/carray/categorical_iterator.rb +8 -8
- data/lib/carray/complex.rb +2 -2
- data/lib/carray/conditional.rb +3 -2
- 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 +48 -16
- data/lib/carray/frame/concat.rb +17 -3
- 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 +405 -85
- data/lib/carray/frame/group.rb +777 -64
- data/lib/carray/frame/io.rb +212 -72
- 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/fuse_source.rb +31 -2
- data/lib/carray/inspect.rb +7 -2
- data/lib/carray/iterator.rb +32 -0
- data/lib/carray/lazy.rb +52 -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/is_in.rb +8 -1
- data/lib/carray/methods/meshgrid.rb +3 -1
- data/lib/carray/runtime.rb +47 -8
- data/lib/carray/segment_iterator.rb +35 -16
- data/lib/carray/serialize.rb +53 -19
- data/lib/carray/stack.rb +33 -18
- 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 +112 -68
- data/lib/carray/window_iterator.rb +16 -4
- data/yard-stubs/ca_obj_array.rb +26 -1
- data/yard-stubs/ca_obj_transpose.rb +5 -4
- data/yard-stubs/carray_attribute.rb +3 -1
- data/yard-stubs/carray_cast.rb +10 -5
- data/yard-stubs/carray_conversion.rb +13 -3
- data/yard-stubs/carray_element.rb +7 -6
- data/yard-stubs/carray_mask.rb +28 -4
- data/yard-stubs/carray_math.rb +45 -20
- data/yard-stubs/carray_memory_view.rb +7 -0
- data/yard-stubs/carray_order.rb +100 -4
- data/yard-stubs/carray_scatter.rb +7 -5
- data/yard-stubs/carray_test.rb +7 -4
- metadata +18 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7012a2c73c33e52e9b5dd18d5fd0e7c02b4c741bb650a41cefbfea117449da2f
|
|
4
|
+
data.tar.gz: 5731ca96689f1d87d9c4e1e6a4764893eac0e39f8126f91695b2042581ae198f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e05efbfc29639882cc08753c9394400abb707df063025a7ae5bfed6c006979721d8b0030ae17a4eab1397c89c7c3803bf9fa2ec62fa7aa9d8c56e1adb38bd79
|
|
7
|
+
data.tar.gz: 21baa2d1fac6d2c45a1ed47b4235e9f1832beb4063e93491743470ac77805c266210139d7af834ca1d014ec410ae43191228679a72004c14af6c2fa91eb88eba
|
data/CHANGELOG.md
CHANGED
|
@@ -34,6 +34,444 @@ 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.6
|
|
38
|
+
|
|
39
|
+
- New: `CAFrame` answers the column reductions itself, as a frame of one
|
|
40
|
+
row (`df.mean`, `df.sum("rain", "temp")`), and the running values down
|
|
41
|
+
all its rows (`df.cumsum("rain")`, `order`), as a grouped frame does
|
|
42
|
+
down each group. `percentile(p, *names)` and `quantile` (a column per
|
|
43
|
+
quartile, `"rain_p0"` ... `"rain_p100"`) are added to the frame, groups
|
|
44
|
+
and windows.
|
|
45
|
+
|
|
46
|
+
- New: `CAFrame` row picks: `nlargest` / `nsmallest` (also on
|
|
47
|
+
`GroupedFrame`), `drop_masked` for the rows with no masked cell,
|
|
48
|
+
`GroupedFrame#head` / `#tail` for the first and last rows of each group,
|
|
49
|
+
and `filter` given a boolean selector directly (`df.filter(df["n"] > 3)`).
|
|
50
|
+
|
|
51
|
+
- New: `CAFrame#transform` computes columns with a block, keeping their
|
|
52
|
+
names and the index. `select`, `drop`, `transform` and `describe` pick
|
|
53
|
+
columns by a Range of names, a Regexp, a kind (`:float`, `:integer`,
|
|
54
|
+
`:complex`, `:timedelta`, ...) or a data type.
|
|
55
|
+
|
|
56
|
+
- New: `CAFrame#value_counts` (how many rows hold each value, as a
|
|
57
|
+
frame), `#strip_mask` (the masked cells filled, in a new frame), `#to_a`
|
|
58
|
+
(the rows as Arrays, masked cells `UNDEF`), `#shape`, `#empty?`, and
|
|
59
|
+
`GroupedFrame#each` and `#size`. `CAFrame#==` compares two frames by
|
|
60
|
+
their table: names, columns, index and row axis name.
|
|
61
|
+
|
|
62
|
+
- New: `CAFrame#lag` and `GroupedFrame#lag` take a distance of the key,
|
|
63
|
+
`before: "1 hour"` or `after:`, giving each row the value of the row at
|
|
64
|
+
exactly that distance (`UNDEF` where there is none). The key is the
|
|
65
|
+
index or the column `on:` names: a time, a duration or a number.
|
|
66
|
+
|
|
67
|
+
- New: `join` and `join_asof` take a key named differently on the two
|
|
68
|
+
sides, and `view: :full`, which gives every column of the result as a
|
|
69
|
+
view, with holes for the unmatched rows, so a write reaches either
|
|
70
|
+
frame.
|
|
71
|
+
|
|
72
|
+
- New: `df[name] = value` with a single value repeats it on every row.
|
|
73
|
+
`fill` takes several columns, an Array of names or a Hash of column =>
|
|
74
|
+
value; `rename` takes a block, can exchange two names, and renames the
|
|
75
|
+
index under its name. `sort_by_key` and `sort_by` take `descending:`.
|
|
76
|
+
|
|
77
|
+
- New: `CAFrame#set_column_attrs` gives columns their names and common
|
|
78
|
+
attributes; `CArray#attrs_symkey` and `CAFrame#attrs_symkey` return the
|
|
79
|
+
attributes with Symbol keys. `CAFrame#to_csv` takes `precision:`.
|
|
80
|
+
|
|
81
|
+
- New: `GroupedFrame#fill(name, :linear)` interpolates within each group.
|
|
82
|
+
On a frame, `:linear` reads an index that is not in order as one series
|
|
83
|
+
in index order.
|
|
84
|
+
|
|
85
|
+
- New: `melt` brings number columns of different types (an `int64` and a
|
|
86
|
+
`float64` column) to their common type, still as a view. A mixture no
|
|
87
|
+
type holds without changing a value (`int64` beside `uint64`), or one
|
|
88
|
+
with text or time, is refused; cast the columns first.
|
|
89
|
+
|
|
90
|
+
- New: `wsum` and `wmean` take weights shaped as the reduced axes, matched
|
|
91
|
+
in ascending axis order, besides a scalar and weights of the receiver's
|
|
92
|
+
shape.
|
|
93
|
+
|
|
94
|
+
- New (C extensions and carray-jit): `CArray::AddressBasis.sweep(function,
|
|
95
|
+
fsync, arrays, *parts)` runs a chunked element-wise sweep
|
|
96
|
+
(`ca_call_cslab_N_r`, arities 1 to 7) from Ruby, handing the slab
|
|
97
|
+
pointers to the parts' own String bytes. An `fsync` character other than
|
|
98
|
+
`0` or `1` is refused.
|
|
99
|
+
|
|
100
|
+
- Change: CArray requires Ruby 3.2 or later, up from 3.0. On an older
|
|
101
|
+
Ruby, `gem install carray` does not offer this release; install a
|
|
102
|
+
newer Ruby with a version manager such as rbenv or mise, or stay on
|
|
103
|
+
3.0.5.
|
|
104
|
+
|
|
105
|
+
- Change: CSV reading and writing are split by what they take.
|
|
106
|
+
`CAFrame.read_csv` and `#write_csv` take a path or an IO;
|
|
107
|
+
`CAFrame.from_csv` takes CSV text as a String and `#to_csv` returns it.
|
|
108
|
+
Code that gave `from_csv` a path or an IO calls `read_csv`, and
|
|
109
|
+
`to_csv(path)` becomes `write_csv(path)`. No aliases are kept.
|
|
110
|
+
|
|
111
|
+
- Change: `read_csv` and `from_csv` infer the column types by default
|
|
112
|
+
(`int64`, `float64`, `boolean`, `time`, otherwise text); `types:` names
|
|
113
|
+
some columns and the rest are still inferred. Pass `types: :string` to
|
|
114
|
+
read every column as text, as before. A column with a blank but present
|
|
115
|
+
value (a quoted `""`) stays text.
|
|
116
|
+
|
|
117
|
+
- Change: `CAFrame#set_index`, `#reset_index`, `#cast`, `#promote`,
|
|
118
|
+
`#parse_to_time` and `#to_time` return a new frame and leave the
|
|
119
|
+
receiver as it is (the two share their columns). Assign the result:
|
|
120
|
+
`df = df.set_index("time")`.
|
|
121
|
+
|
|
122
|
+
- Change: a `GroupedFrame` reduction given column names returns a frame of
|
|
123
|
+
those columns, one row per group, labelled as without names; it
|
|
124
|
+
returned the `CArray` (one name) or an `Array` of them. Take the column
|
|
125
|
+
(`grp.mean("temp")["temp"]`) or reduce the group iterator
|
|
126
|
+
(`grp["temp"].mean`) for the values alone.
|
|
127
|
+
|
|
128
|
+
- Change: a `GroupedFrame` or window value on the frame's rows given
|
|
129
|
+
several column names (`keep_rows: true`, the running values, `lag`,
|
|
130
|
+
`w.mean("a", "b")`) returns a frame of them on the frame's rows and
|
|
131
|
+
index, instead of an `Array`. One name still gives the `CArray`.
|
|
132
|
+
|
|
133
|
+
- Change: `CAFrame#filter` no longer takes `keep_masked:`, so every row
|
|
134
|
+
selection is a view. To keep the rows whose condition is undetermined,
|
|
135
|
+
say so in the selector: `df.filter(cond.is_masked)` or
|
|
136
|
+
`df.filter(cond.strip_mask(true))`.
|
|
137
|
+
|
|
138
|
+
- Change: `df[sel] = ...` refuses a Ruby Array as the row selector, as
|
|
139
|
+
`df[]` does; the column indexer would read `[0, 2]` as two rows from
|
|
140
|
+
row 0. Write `df[CA_INT64([0, 2])]` for rows 0 and 2.
|
|
141
|
+
|
|
142
|
+
- Change: a group key named in a `GroupedFrame` reduction, and the index's
|
|
143
|
+
name given to a verb that reads or changes columns (`df[...]`,
|
|
144
|
+
`select`, `fill`, `cast`, the reductions), raise and point at `size`
|
|
145
|
+
or `df.index`. A key argument (`group_by`, `sort_by_key`, `join(on:)`)
|
|
146
|
+
still names the index.
|
|
147
|
+
|
|
148
|
+
- Change: an `:inner` or `:right` `join` gives the other frame's columns
|
|
149
|
+
as views picked by row, not copies, so a write to them reaches that
|
|
150
|
+
frame. Call `copy` on the result to keep it apart.
|
|
151
|
+
|
|
152
|
+
- Change: a `CScalar` takes only `s[]` and `s[0]`, reading or writing its
|
|
153
|
+
one cell; any other index (`s[3]`, a range, `nil`, an index array)
|
|
154
|
+
raises. A view such as `s.refer(s.data_type, [1])` takes the usual
|
|
155
|
+
indexes.
|
|
156
|
+
|
|
157
|
+
- Change: `CArray.stack` and `CArray.meld` refuse a value array
|
|
158
|
+
(`a.value`) or a mask array (`a.mask`) as a part. Pass a copy
|
|
159
|
+
(`a.value.copy`), or `a.is_masked` for the mask's values.
|
|
160
|
+
|
|
161
|
+
- Change: `CArray#==` finds a NaN equal to a NaN, so an array holding NaN
|
|
162
|
+
equals its copy and the array read back from a file. The cell-by-cell
|
|
163
|
+
IEEE comparison is `eq`; `eql?` still compares bits.
|
|
164
|
+
|
|
165
|
+
- Change: `CARemap#mapper` returns a read-only array; writing it raises.
|
|
166
|
+
The index array given to `a[idx]` is not affected.
|
|
167
|
+
|
|
168
|
+
- Change: `Marshal.dump` of a `CAWrap` (from `CArray.wrap_memory_view`)
|
|
169
|
+
writes its values, and the load gives a plain array owning a copy of
|
|
170
|
+
them, as for a view of the wrap; it raised `TypeError`.
|
|
171
|
+
|
|
172
|
+
- Change: `as_type` returns a view also when the data type is the
|
|
173
|
+
receiver's own, and `CATime#to_unit` / `CATimedelta#to_unit` return a
|
|
174
|
+
new array when the unit does not change, so an attribute set on, or a
|
|
175
|
+
freeze of, the result does not reach the receiver.
|
|
176
|
+
|
|
177
|
+
- Change: `wmean` gives `UNDEF` where the weights sum to zero, on every
|
|
178
|
+
path; numeric arrays gave NaN or an infinity. A weight array with one
|
|
179
|
+
element is no longer read as a scalar: give a Ruby number or a
|
|
180
|
+
`CScalar`.
|
|
181
|
+
|
|
182
|
+
- Change: a computation over an object array that comes back into the
|
|
183
|
+
array (a cell holding the array, or a view of it) raises, as reading
|
|
184
|
+
such a cell does; it recursed until the process died. A lazy
|
|
185
|
+
expression over such an array (a cell holding `x + 1` for the array `x`)
|
|
186
|
+
raises the same way instead of overflowing the stack or not ending, and
|
|
187
|
+
so does `Marshal.dump` of an object view whose cells lead back to its
|
|
188
|
+
root.
|
|
189
|
+
|
|
190
|
+
- Change (CAObject authors): a `CAObject` without `create_mask` raises
|
|
191
|
+
`TypeError` when its `copy_data` writes `UNDEF`, as it does when a
|
|
192
|
+
fetcher answers `UNDEF`; the `UNDEF` was dropped and read as a value.
|
|
193
|
+
|
|
194
|
+
- Change (C extensions): `ca_install_obj_type` refuses an operation table
|
|
195
|
+
without `allocate`, `attach`, `sync` and `detach` slots;
|
|
196
|
+
`ca_iter_register_source_kind` refuses carray's own types; and the
|
|
197
|
+
kernel iterator's `FIBER_PAIR` forms refuse `CA_KERNEL_WRITE`.
|
|
198
|
+
|
|
199
|
+
- Fix: `require "carray"` works on Ruby 4.0; it raised
|
|
200
|
+
`Ractor::IsolationError` since 3.0.4.
|
|
201
|
+
|
|
202
|
+
- Fix: `CArray.fuse` works on Ruby 3.2 and 3.3. The gem now depends on
|
|
203
|
+
prism 1.0 or later, which `gem install` and Bundler bring in on Ruby
|
|
204
|
+
3.2, which ships none, and 3.3, whose own prism is too old; Ruby 3.4
|
|
205
|
+
and later already ship it.
|
|
206
|
+
|
|
207
|
+
- Fix: a block of a reshape over a strided view
|
|
208
|
+
(`a[1..2, 1..3].reshape(3, 2)[0..1, nil]`) read and wrote past the end
|
|
209
|
+
of a row, outside the buffer at the edges.
|
|
210
|
+
|
|
211
|
+
- Fix: a frozen object array shared between Ractors can be computed over
|
|
212
|
+
in several at once; it was refused as cyclic. A cell holding a view of
|
|
213
|
+
other cells of the same array is no longer refused.
|
|
214
|
+
|
|
215
|
+
- Fix: a record array (`CARecord`) exports through MemoryView from a
|
|
216
|
+
Ractor other than the main one; it raised `Ractor::IsolationError`.
|
|
217
|
+
|
|
218
|
+
- Fix: `Marshal.dump` of a view no longer writes its whole parent (a
|
|
219
|
+
one-cell view of a 100,000-cell array dumped about 400 KB), and an
|
|
220
|
+
array's mask marshals as a plain boolean array.
|
|
221
|
+
|
|
222
|
+
- Fix: an `each_slab` Enumerator stopped part way with `next` leaves no
|
|
223
|
+
array attached once its Fiber is collected.
|
|
224
|
+
|
|
225
|
+
- Fix: a window or block iterator reads its source afresh on each call;
|
|
226
|
+
after the source changed, a later reduction mixed new sums with old
|
|
227
|
+
counts.
|
|
228
|
+
|
|
229
|
+
- Fix: a frozen or read-only `CArray.meld` refuses writes through a meld
|
|
230
|
+
of it (`CArray.meld(m, m)` wrote into the frozen root).
|
|
231
|
+
|
|
232
|
+
- Fix: a write to a `CArray.stack` or `CArray.meld` whose parts share
|
|
233
|
+
cells (`CArray.meld(a, a)`) gives those cells the value, or the mask, of
|
|
234
|
+
the last part; `add!` could leave an earlier part's result, and a mask
|
|
235
|
+
write masked the cells of every part.
|
|
236
|
+
|
|
237
|
+
- Fix: a write to a `CArray.stack` or `CArray.meld` that one part refuses
|
|
238
|
+
(a value outside a part's data type) writes nothing; the parts before
|
|
239
|
+
it were written.
|
|
240
|
+
|
|
241
|
+
- Fix: `blocks(...).sort_addr` works when the source holds more than one
|
|
242
|
+
tile; it failed with `IndexError`.
|
|
243
|
+
|
|
244
|
+
- Fix: `elem_fetch` answers a boolean cell with `true` or `false` when given
|
|
245
|
+
an index array over a view, as `[]` does; it answered `0` or `1`.
|
|
246
|
+
|
|
247
|
+
- Fix: `CAFrame#fill(:linear)` leaves a row with no coordinate out of the
|
|
248
|
+
interpolation; it was filled with 0.
|
|
249
|
+
|
|
250
|
+
- Fix: `bin_to` and `histogram1d` put a value next to an edge in the bin
|
|
251
|
+
that edge bounds when the edges are nearly but not exactly equally
|
|
252
|
+
spaced.
|
|
253
|
+
|
|
254
|
+
- Fix: `float ** Integer` takes any exponent that fits 64 bits, eagerly
|
|
255
|
+
as lazily, and `x.lazy.pow(k)` answers as `x.pow(k)`. A lazy array
|
|
256
|
+
compared with `UNDEF` (`eq`, `ne`) answers as the eager one does.
|
|
257
|
+
|
|
258
|
+
- Fix: writing `UNDEF` through a widening `refer` (`r.refer(:float64,
|
|
259
|
+
...)`) no longer masks parent cells outside the written cells, and a
|
|
260
|
+
mask written onto a `CAObject` without mask hooks survives the next
|
|
261
|
+
read of its values.
|
|
262
|
+
|
|
263
|
+
- Fix: a masked cell that is not a String reads as `""` when a `CAString`
|
|
264
|
+
wraps a view, as it does over an entity.
|
|
265
|
+
|
|
266
|
+
- Fix (CASource authors): a source that leaves its `ptr` NULL at rest no
|
|
267
|
+
longer crashes `elem_*`, `dump_binary` to a File or `nlargest` over a
|
|
268
|
+
whole axis.
|
|
269
|
+
|
|
270
|
+
## 3.0.5
|
|
271
|
+
|
|
272
|
+
- New: `GroupedFrame#aggregate` takes a block instead of a spec. The block
|
|
273
|
+
is given the grouping once and returns a Hash of output name => a
|
|
274
|
+
CArray with one value per group, built from `g["col"]` iterators and
|
|
275
|
+
CArray arithmetic (`g["temp"].max - g["temp"].min`). `grp[array]`
|
|
276
|
+
groups any CArray with one entry per row, such as a value computed
|
|
277
|
+
from columns or a column with cells masked.
|
|
278
|
+
|
|
279
|
+
- New: a `CAFrame` grouped reduction takes a Hash of column name => value
|
|
280
|
+
as `fill_value:`, filling only the named columns. A single
|
|
281
|
+
`fill_value:` still goes to every column and has to suit each.
|
|
282
|
+
|
|
283
|
+
- New: `CArray.meld` brings pieces of different data types to a common
|
|
284
|
+
one, as `CArray.stack` does, and takes `data_type:`. `CAFrame.meld` and
|
|
285
|
+
a frame splice still refuse a column whose pieces differ in data type;
|
|
286
|
+
cast the column first, or use `concatenate`.
|
|
287
|
+
|
|
288
|
+
- New: `scatter_replace!` takes an object or fixed-length array, as
|
|
289
|
+
`put_nd` and `put_along_axis` do. The accumulating members
|
|
290
|
+
(`scatter_add!` and the others) still take numeric arrays only.
|
|
291
|
+
|
|
292
|
+
- New: `CAConstString#count` and `CACategorical#count` with no argument
|
|
293
|
+
count the cells that are not masked, as `CArray#count` does.
|
|
294
|
+
|
|
295
|
+
- New: `CAFixlenString` answers `minmax`, `cummax` and `cummin`, as
|
|
296
|
+
`CAString` does.
|
|
297
|
+
|
|
298
|
+
- New (C extensions): `carray.h` defines `ca_u_<type>` cell types and
|
|
299
|
+
`CA_U(type)`, of the same size and value as the plain types but with no
|
|
300
|
+
alignment requirement, for reading cells that need not be aligned (a
|
|
301
|
+
refer with a byte offset, a struct member, a wrapped buffer). The slab
|
|
302
|
+
macros in `ca_kernel_iterator.h` use them for their pointers.
|
|
303
|
+
|
|
304
|
+
- Change: `CACategorical#sort_addr` is renamed `group_addr`, the order of
|
|
305
|
+
the cells by category. `sort_addr` on a categorical now raises, as
|
|
306
|
+
`sort_index` does, since a categorical has no order of values.
|
|
307
|
+
|
|
308
|
+
- Change: a Face's `parent` (of a `CATime`, `CARecord`, ...) is a
|
|
309
|
+
read-only view of its storage. Write the storage of a time through
|
|
310
|
+
`CATime#ticks`.
|
|
311
|
+
|
|
312
|
+
- Change: an operator that cannot bring two data types together raises
|
|
313
|
+
`CArray::DataTypeError` instead of `TypeError`. `DataTypeError` is a
|
|
314
|
+
`TypeError`, so `rescue TypeError` still catches it.
|
|
315
|
+
|
|
316
|
+
- Change: a float cell with no integer of the target type -- an infinity,
|
|
317
|
+
or a value out of the type's range -- is now treated the way NaN
|
|
318
|
+
already was. `to_type` (`int32`, `as_int64`, ...) masks it to `UNDEF`;
|
|
319
|
+
storing it into an integer array raises `RangeError`
|
|
320
|
+
(`FloatDomainError` for an infinity). Before, it became whatever the
|
|
321
|
+
machine's C conversion gave, which differed between x86 and ARM.
|
|
322
|
+
`clip_int64` and the other `clip_<type>` methods saturate a float
|
|
323
|
+
source to the type's limits on every machine; integer `linspace` raises
|
|
324
|
+
`RangeError` for a span the type cannot hold.
|
|
325
|
+
|
|
326
|
+
- Change: a Ruby Array operand of a numeric or boolean array is read as
|
|
327
|
+
its cells: `a.eq([1, 5, 3])` compares cell by cell (it compared every
|
|
328
|
+
cell with the whole Array), and `a + [1, 2, 3]` adds (it raised).
|
|
329
|
+
Nested Arrays give the axes. An object array still takes an Array as
|
|
330
|
+
one value.
|
|
331
|
+
|
|
332
|
+
- Change: `window`'s `bounds:` is a policy named by a Symbol or String,
|
|
333
|
+
matched whole; an Integer and an abbreviation raise. A `fill_value:`
|
|
334
|
+
given with a policy that does not use it (`:nearest`, `:strict`, ...)
|
|
335
|
+
raises instead of being dropped.
|
|
336
|
+
|
|
337
|
+
- Change: a length, count, offset or shift given to a view
|
|
338
|
+
(`sliding_windows`, `block_view`, `tile`, `roll`, `shift`, `field`,
|
|
339
|
+
`diagonal`) must be an Integer; a Float raises `TypeError` instead of
|
|
340
|
+
being truncated. `transpose` reads its axes as the other axis arguments
|
|
341
|
+
are read: negative from the end, an Integer only.
|
|
342
|
+
|
|
343
|
+
- Change: `drop_axis` on an array whose every axis has size 1 keeps one
|
|
344
|
+
axis of size 1, and `reshape` with no axes raises.
|
|
345
|
+
|
|
346
|
+
- Change: in an index of one key per axis, an index array of more than
|
|
347
|
+
one axis on one axis raises `ArgumentError`; it was read flat. Pass
|
|
348
|
+
`idx.flatten` for the old reading.
|
|
349
|
+
|
|
350
|
+
- Change: `elem_fetch`, `elem_store` and the other `elem_*` methods read
|
|
351
|
+
an index as `[]` reads a key: a Float with no fraction is an index, a
|
|
352
|
+
Float with a fraction raises `IndexError`.
|
|
353
|
+
|
|
354
|
+
- Change: two string arrays of different kinds (`CAString`,
|
|
355
|
+
`CAFixlenString`, `CAConstString`) or of different widths compare by
|
|
356
|
+
their strings. A String query longer than a fixed-width cell matches
|
|
357
|
+
no cell in `eq`, `count`, `search`, `bsearch` and `is_in`; it was cut
|
|
358
|
+
to the cell's width.
|
|
359
|
+
|
|
360
|
+
- Change: `str_index` and `rindex` give `UNDEF` for a cell that does not
|
|
361
|
+
hold the substring; they raised for the whole array.
|
|
362
|
+
|
|
363
|
+
- Change: `bsearch` and `bsearch_addr` answer the first of several equal
|
|
364
|
+
cells.
|
|
365
|
+
|
|
366
|
+
- Change: `search` and `search_addr` raise `ArgumentError` for a negative
|
|
367
|
+
or NaN `eps`, which acted as an exact match.
|
|
368
|
+
|
|
369
|
+
- Change: `inherit_mask` and `inherit_mask_replace` raise `ArgumentError`
|
|
370
|
+
for a source whose number of cells differs from the receiver's (a
|
|
371
|
+
scalar source still applies to every cell).
|
|
372
|
+
|
|
373
|
+
- Change: a reduction's `fill_value:` that its result cannot hold raises
|
|
374
|
+
even when no cell needs it, and `fill` on an empty array checks its
|
|
375
|
+
value as an assignment does.
|
|
376
|
+
|
|
377
|
+
- Change: rounding a `:M` or `:Y` `CATime` to a calendar bucket
|
|
378
|
+
(`round(unit: :Y)`, `"3 months"`) measures the distance by the instant,
|
|
379
|
+
so it agrees with the same dates on `:D`.
|
|
380
|
+
|
|
381
|
+
- Change: a `CATime` reduction (`mean`, `median`, ...) sends a tie to the
|
|
382
|
+
later tick on both sides of 1970; before 1970 it went to the earlier
|
|
383
|
+
one.
|
|
384
|
+
|
|
385
|
+
- Change: a duration String added to or subtracted from a `CATime` is
|
|
386
|
+
one step of its own resolution, so `"15 minutes"` on a `"10 minutes"`
|
|
387
|
+
grid raises, as the same duration as a `CATimedelta` does. It was read
|
|
388
|
+
as fifteen one-minute steps and cut to the grid.
|
|
389
|
+
|
|
390
|
+
- Change: of `-0.0` and `0.0`, `pmax` gives `0.0` and `pmin` gives
|
|
391
|
+
`-0.0`, in either order and on every platform, as `maximum` and
|
|
392
|
+
`minimum` do. Which zero `min` and `max` answer is not specified.
|
|
393
|
+
|
|
394
|
+
- Change: a one-sided `clip` passes a NaN cell through, as a two-sided
|
|
395
|
+
`clip` does.
|
|
396
|
+
|
|
397
|
+
- Change: a categorical's `fill_value:` (of `shift`, `window`, `project`)
|
|
398
|
+
is a label; a `CAConstString` takes only `UNDEF` as a fill value.
|
|
399
|
+
|
|
400
|
+
- Change: a lazy operator with a Face operand (a categorical, a time, a
|
|
401
|
+
string array) answers as the eager operator does; it read the Face's
|
|
402
|
+
storage. `CAConstString#eq` with another array compares cell by cell.
|
|
403
|
+
|
|
404
|
+
- Change: a boolean member of a record (or `field(offset, :boolean)` of a
|
|
405
|
+
fixed-length array) raises `RangeError` when read as a byte that is not
|
|
406
|
+
0 or 1, instead of answering differently in each method.
|
|
407
|
+
|
|
408
|
+
- Change: unmasking a cell of a `CAString` that holds no String gives an
|
|
409
|
+
empty String.
|
|
410
|
+
|
|
411
|
+
- Change: `swap_bytes` keeps the attributes, as `refer` and `bitfield`
|
|
412
|
+
do. An array with no cells has no say in the attributes a `meld`,
|
|
413
|
+
`stack` or `concatenate` keeps.
|
|
414
|
+
|
|
415
|
+
- Change: `dim_view` keeps a Face, as `transpose` does.
|
|
416
|
+
|
|
417
|
+
- Change: `CArray.string(n)` without a block, and `CArray.string("ab")`,
|
|
418
|
+
raise; `fixlen_string` and `to_fixlen_string` raise for `bytes:` below 1.
|
|
419
|
+
`project` raises for a keyword argument, `paste` into a frozen array
|
|
420
|
+
raises `FrozenError`, and `CArray.result_type` refuses a MemoryView
|
|
421
|
+
operand whose format carray cannot read, as the operators do.
|
|
422
|
+
|
|
423
|
+
- Change: `CArray.sort_addr` with numeric keys is two to three times as fast, and
|
|
424
|
+
`nlargest` / `nsmallest` read each fiber once with a work area of a
|
|
425
|
+
few times n.
|
|
426
|
+
|
|
427
|
+
- Fix: x86-64 Linux. Inputs that reached an integer division by zero
|
|
428
|
+
inside the library stopped the process with SIGFPE there (on ARM they
|
|
429
|
+
were refused later or gave a wrong answer): a sum over a view with a
|
|
430
|
+
zero-length axis, `wsum` / `wmean` with 1-D weights over a zero-length
|
|
431
|
+
axis, a view of a stack of empty arrays, `window` with a step of 0, and
|
|
432
|
+
`wrap_readonly(String, CA_FIXLEN)`. Each now answers or raises
|
|
433
|
+
`ArgumentError`. The extension builds with GCC 14 without warnings.
|
|
434
|
+
|
|
435
|
+
- Fix: big-endian hosts. `bitfield` read 0 and lost writes, a struct's
|
|
436
|
+
bit members overwrote each other, and an element-wise operation applied
|
|
437
|
+
in place could give a wrong cell.
|
|
438
|
+
|
|
439
|
+
- Fix: `save` and `dump` with `endian: :little` or `:big` wrote the other
|
|
440
|
+
byte order. `load` reads the marker, so files written so far still load
|
|
441
|
+
correctly.
|
|
442
|
+
|
|
443
|
+
- Fix: running out of memory inside a kernel left a view attached, lost
|
|
444
|
+
the keywords of the call (`a.sum(axis: 1)` returned the total), or
|
|
445
|
+
leaked the array being built.
|
|
446
|
+
|
|
447
|
+
- Fix: an array with 16 axes (the maximum) given to `bitarray`, `field`,
|
|
448
|
+
a narrowing `refer` or a `:_` index wrote past an internal array.
|
|
449
|
+
|
|
450
|
+
- Fix: a lazy chain whose step narrows the cells (`a.lazy.abs` of a
|
|
451
|
+
complex array) overran the heap; `seq` on an empty object array wrote
|
|
452
|
+
past its end.
|
|
453
|
+
|
|
454
|
+
- Fix: a CAObject's copy and sync hooks: a view the hook kept of the
|
|
455
|
+
array it was lent, or the lent array's mask, pointed at freed memory
|
|
456
|
+
after the hook returned.
|
|
457
|
+
|
|
458
|
+
- Fix: `CArray.fuse` crashed when several Ractors ran a fuse block for the
|
|
459
|
+
first time at once.
|
|
460
|
+
|
|
461
|
+
- Fix: a grouped `variancep` / `stddevp` matches `CArray#variancep` to the
|
|
462
|
+
last bit.
|
|
463
|
+
|
|
464
|
+
- Fix: `count` with an array of values honours `keep_axis:`.
|
|
465
|
+
|
|
466
|
+
- Fix: `CARecord.wrap` of a record array wraps its storage, not the
|
|
467
|
+
record array.
|
|
468
|
+
|
|
469
|
+
- Fix: an unnamed struct's `order_by` survives `save` / `load` and
|
|
470
|
+
Marshal.
|
|
471
|
+
|
|
472
|
+
- Fix: `CAFrame.from_csv` and `cast(name => :time)` read a leap second
|
|
473
|
+
(`23:59:60`) as `CArray.time` does, into the next minute.
|
|
474
|
+
|
|
37
475
|
## 3.0.4
|
|
38
476
|
|
|
39
477
|
- New: `CAFrame#verify(rules)` judges every row against named rules (each
|
data/README.md
CHANGED
data/carray.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "carray"
|
|
3
|
-
s.version = "3.0.
|
|
3
|
+
s.version = "3.0.6"
|
|
4
4
|
s.authors = ["himotoyoshi"]
|
|
5
5
|
s.email = ["himotoyoshi@users.noreply.github.com"]
|
|
6
6
|
s.summary = "Multi-dimensional numerical array class for Ruby"
|
|
@@ -17,7 +17,8 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
s.homepage = "https://github.com/himotoyoshi/carray"
|
|
18
18
|
s.license = "MIT"
|
|
19
19
|
s.platform = Gem::Platform::RUBY
|
|
20
|
-
s.required_ruby_version = ">= 3.
|
|
20
|
+
s.required_ruby_version = ">= 3.2"
|
|
21
|
+
s.add_dependency "prism", ">= 1.0"
|
|
21
22
|
s.files = [
|
|
22
23
|
*Dir.glob("lib/**/*.rb"),
|
|
23
24
|
*Dir.glob("yard-stubs/**/*.rb"),
|
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++)
|
|
@@ -1108,6 +1101,12 @@ ca_axis_view_xfer_all (void *ap, ca_axis_view_fast_t fast, int region_ok,
|
|
|
1108
1101
|
if ( ca_attach_is_alias(parent) ) {
|
|
1109
1102
|
ca_attach(parent); /* window: an alias attach, cannot raise */
|
|
1110
1103
|
fast(ca, (char *) data, dir);
|
|
1104
|
+
/* An entity that keeps no buffer at rest (the mask of a CAObject, a
|
|
1105
|
+
CASource) attaches a copy, which only its sync writes back; for
|
|
1106
|
+
memory it lends, the sync does nothing. */
|
|
1107
|
+
if ( dir == CA_XFER_PUT ) {
|
|
1108
|
+
ca_sync(parent);
|
|
1109
|
+
}
|
|
1111
1110
|
ca_detach(parent);
|
|
1112
1111
|
return;
|
|
1113
1112
|
}
|
data/ext/ca_axis_group.c
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
(see the section comment above `rb_ca_axis_group_scan`).
|
|
26
26
|
|
|
27
27
|
Group codes outside [0, k) at any bundle mark the slab element unassigned
|
|
28
|
-
(skipped, contributing to no group) — mirrors
|
|
28
|
+
(skipped, contributing to no group) — mirrors bin_to OOB.
|
|
29
29
|
|
|
30
30
|
Float reductions carry the CArray ε-close contract: relative error bounded,
|
|
31
31
|
not bit-exact.
|