carray 3.0.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/CHANGELOG.md +325 -3
- data/{NEWS.md → CHANGELOG.v1.md} +1 -1
- data/README.md +32 -32
- data/carray.gemspec +12 -8
- data/ext/ca_axis_group.c +55 -19
- data/ext/ca_binop_dispatch.c +5 -6
- data/ext/ca_binop_dispatch.h +0 -7
- data/ext/ca_categorical_iterator.c +13 -13
- data/ext/ca_for_each_element.h +6 -8
- data/ext/ca_group_iter.c +1 -1
- data/ext/ca_kernel_iterator.c +69 -23
- data/ext/ca_kernel_iterator.h +3 -10
- data/ext/ca_obj_bincmp.c +57 -27
- data/ext/ca_obj_binop.c +86 -30
- data/ext/ca_obj_const_string.c +3 -1
- data/ext/ca_obj_face.c +80 -0
- data/ext/ca_obj_face.h +33 -1
- data/ext/ca_obj_fake.c +11 -0
- data/ext/ca_obj_fixlen_string.c +3 -1
- data/ext/ca_obj_grid.c +11 -3
- data/ext/ca_obj_meld.c +13 -8
- data/ext/ca_obj_moncmp.c +33 -14
- data/ext/ca_obj_monop.c +19 -7
- data/ext/ca_obj_object.c +99 -4
- data/ext/ca_obj_record.c +3 -1
- data/ext/ca_obj_refer.c +30 -6
- data/ext/ca_obj_roll.c +13 -5
- data/ext/ca_obj_select_axis.c +16 -6
- data/ext/ca_obj_shift.c +3 -3
- data/ext/ca_obj_stride.c +106 -23
- data/ext/ca_obj_string.c +3 -1
- data/ext/ca_obj_tile.c +13 -5
- data/ext/ca_obj_time.c +3 -1
- data/ext/ca_obj_timedelta.c +3 -1
- data/ext/ca_obj_transpose.c +1 -1
- data/ext/ca_obj_triop.c +62 -23
- data/ext/ca_obj_window.c +86 -17
- data/ext/ca_op_cmplx64.h +123 -0
- data/ext/ca_op_ipower.c +0 -3
- data/ext/ca_sort_kernels.h +5 -5
- data/ext/ca_sweep_engine.c +78 -35
- data/ext/ca_sweep_engine.h +13 -4
- data/ext/ca_transform_common.c +7 -0
- data/ext/carray.h +127 -130
- data/ext/carray_access.c +56 -34
- data/ext/carray_bincount.c +8 -8
- data/ext/carray_broadcast.c +99 -6
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +1491 -0
- data/ext/carray_call_cfunc.h +153 -0
- data/ext/carray_cast.c +69 -31
- data/ext/carray_conversion.c +22 -22
- data/ext/carray_copy.c +12 -2
- data/ext/carray_core.c +57 -10
- data/ext/carray_count.c +1 -1
- data/ext/carray_element.c +7 -7
- data/ext/carray_factorize.c +28 -28
- data/ext/carray_hold.c +1 -1
- data/ext/carray_index_classifier.c +7 -21
- data/ext/carray_internal.h +19 -3
- data/ext/carray_kernels_bincmp.c +1 -0
- data/ext/carray_kernels_binop.c +320 -298
- data/ext/carray_kernels_init.c +1095 -0
- data/ext/carray_kernels_map.c +1 -0
- data/ext/carray_kernels_moncmp.c +1 -0
- data/ext/carray_kernels_monop.c +412 -411
- data/ext/carray_kernels_reduce_aggregate.c +88 -87
- data/ext/carray_kernels_reduce_boolean.c +1 -0
- data/ext/carray_kernels_reduce_cumulative.c +54 -53
- data/ext/carray_kernels_reduce_extreme.c +51 -50
- data/ext/carray_kernels_reduce_variance.c +1 -0
- data/ext/carray_kernels_scan.c +1 -0
- data/ext/carray_kernels_search.c +93 -92
- data/ext/carray_kernels_sort.c +1 -0
- data/ext/carray_kernels_triop.c +1 -0
- data/ext/carray_lazy.c +175 -5
- data/ext/carray_mask.c +6 -5
- data/ext/carray_median_percentile.c +1 -1
- data/ext/carray_memory_view.c +46 -21
- data/ext/carray_operator.c +46 -49
- data/ext/carray_partition.c +4 -4
- data/ext/carray_random.c +7 -7
- data/ext/carray_scatter.c +1 -1
- data/ext/carray_sort.c +3 -3
- data/ext/carray_sort_kernel.c +10 -10
- data/ext/carray_test.c +1 -1
- data/ext/extconf.rb +18 -0
- data/ext/mk_call_cfunc.rb +243 -52
- data/ext/mkkernel.rb +354 -100
- data/ext/ruby_carray.c +18 -16
- data/ext/version.h +4 -4
- data/lib/carray/autoload_carray.rb +19 -0
- data/lib/carray/autoload_method_extension.rb +2 -1
- data/lib/carray/axis_group.rb +7 -7
- data/lib/carray/basics.rb +59 -59
- data/lib/carray/bincount_nd.rb +12 -12
- data/lib/carray/block_iterator.rb +24 -14
- data/lib/carray/categorical.rb +4 -4
- data/lib/carray/categorical_iterator.rb +98 -76
- data/lib/carray/conditional.rb +14 -14
- data/lib/carray/construct.rb +21 -0
- data/lib/carray/core_extensions.rb +62 -5
- data/lib/carray/data_type_extension.rb +18 -1
- data/lib/carray/frame/concat.rb +3 -3
- data/lib/carray/frame/convert.rb +1 -1
- data/lib/carray/frame/frame.rb +4 -11
- data/lib/carray/frame/io.rb +159 -2
- data/lib/carray/frame/sort.rb +1 -1
- data/lib/carray/frame/verbs.rb +18 -1
- data/lib/carray/fuse_source.rb +123 -0
- data/lib/carray/fusion.rb +218 -0
- data/lib/carray/histogram.rb +16 -16
- data/lib/carray/inspect.rb +1 -7
- data/lib/carray/iterator.rb +4 -3
- data/lib/carray/lazy.rb +125 -73
- data/lib/carray/meld_reduce.rb +2 -2
- data/lib/carray/methods/align_addr.rb +1 -1
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/is_in.rb +12 -12
- data/lib/carray/methods/locate_addr.rb +6 -1
- data/lib/carray/methods/mask_duplicates.rb +1 -1
- data/lib/carray/methods/meshgrid.rb +4 -5
- data/lib/carray/methods/mode.rb +2 -2
- data/lib/carray/methods/nunique.rb +1 -1
- data/lib/carray/methods/snap.rb +7 -2
- data/lib/carray/methods/unique.rb +3 -3
- data/lib/carray/methods/value_counts.rb +2 -2
- data/lib/carray/runtime.rb +0 -19
- data/lib/carray/slab_iterator.rb +20 -7
- data/lib/carray/string_operation_extension.rb +5 -5
- data/lib/carray/time.rb +890 -491
- data/lib/carray/window_iterator.rb +285 -13
- data/lib/carray.rb +5 -5
- data/yard-stubs/ca_obj_array.rb +385 -0
- data/yard-stubs/ca_obj_bitarray.rb +38 -0
- data/yard-stubs/ca_obj_bitfield.rb +43 -0
- data/yard-stubs/ca_obj_block.rb +73 -0
- data/yard-stubs/ca_obj_byte_swap.rb +56 -0
- data/yard-stubs/ca_obj_fake.rb +31 -0
- data/yard-stubs/ca_obj_farray.rb +32 -0
- data/yard-stubs/ca_obj_field.rb +45 -0
- data/yard-stubs/ca_obj_grid.rb +35 -0
- data/yard-stubs/ca_obj_refer.rb +72 -0
- data/yard-stubs/ca_obj_roll.rb +45 -0
- data/yard-stubs/ca_obj_shift.rb +43 -0
- data/yard-stubs/ca_obj_stride.rb +181 -0
- data/yard-stubs/ca_obj_tile.rb +29 -0
- data/yard-stubs/ca_obj_transpose.rb +40 -0
- data/yard-stubs/ca_obj_window.rb +49 -0
- data/yard-stubs/carray_access.rb +131 -0
- data/yard-stubs/carray_attribute.rb +246 -0
- data/yard-stubs/carray_broadcast.rb +37 -0
- data/yard-stubs/carray_cast.rb +489 -0
- data/yard-stubs/carray_class.rb +65 -0
- data/yard-stubs/carray_conversion.rb +76 -0
- data/yard-stubs/carray_copy.rb +79 -0
- data/yard-stubs/carray_core.rb +114 -0
- data/yard-stubs/carray_count.rb +79 -0
- data/yard-stubs/carray_element.rb +108 -0
- data/yard-stubs/carray_generate.rb +66 -0
- data/yard-stubs/carray_lazy.rb +23 -0
- data/yard-stubs/carray_loop.rb +140 -0
- data/yard-stubs/carray_mask.rb +259 -0
- data/yard-stubs/carray_math.rb +132 -0
- data/yard-stubs/carray_mathfunc.rb +45 -0
- data/yard-stubs/carray_median_percentile.rb +89 -0
- data/yard-stubs/carray_memory_view.rb +163 -0
- data/yard-stubs/carray_order.rb +312 -0
- data/yard-stubs/carray_random.rb +89 -0
- data/yard-stubs/carray_scatter.rb +106 -0
- data/yard-stubs/carray_slab.rb +57 -0
- data/yard-stubs/carray_sort.rb +163 -0
- data/yard-stubs/carray_test.rb +85 -0
- data/yard-stubs/carray_undef.rb +64 -0
- data/yard-stubs/carray_utils.rb +97 -0
- data/yard-stubs/ruby_carray.rb +193 -0
- metadata +59 -10
- data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/carray_call_cfunc.h
CHANGED
|
@@ -16,6 +16,18 @@
|
|
|
16
16
|
#ifndef CARRAY_CALL_CFUNC_H
|
|
17
17
|
#define CARRAY_CALL_CFUNC_H
|
|
18
18
|
|
|
19
|
+
/* Chunk callback for the ca_call_cslab_N family. `base` and `stride` are
|
|
20
|
+
one entry per operand, in the order the operands were passed; `n` is the
|
|
21
|
+
number of cells in this chunk; `m0` is the chunk's slice of the mask,
|
|
22
|
+
one byte per cell, or NULL when no INPUT carried a mask. The arity does
|
|
23
|
+
not appear in the signature -- the operands arrive through `base` -- so
|
|
24
|
+
one typedef serves every arity. */
|
|
25
|
+
typedef void (*ca_cslab_t) (char **base, ca_size_t *stride, ca_size_t n,
|
|
26
|
+
const boolean8_t *m0);
|
|
27
|
+
|
|
28
|
+
typedef void (*ca_cslab_r_t) (char **base, ca_size_t *stride, ca_size_t n,
|
|
29
|
+
const boolean8_t *m0, void *userdata);
|
|
30
|
+
|
|
19
31
|
VALUE
|
|
20
32
|
ca_call_cfunc_1 (void (*func)(void *p0), const char *fsync,
|
|
21
33
|
VALUE rcx0);
|
|
@@ -157,4 +169,145 @@ ca_call_cfunc_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t
|
|
|
157
169
|
VALUE
|
|
158
170
|
ca_call_cfunc_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, void (*mathfunc)(void*, void*, void*, void*, void*, void*, void *userdata), volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
159
171
|
|
|
172
|
+
VALUE
|
|
173
|
+
ca_call_cslab_1 (ca_cslab_t func, const char *fsync,
|
|
174
|
+
VALUE rcx0);
|
|
175
|
+
|
|
176
|
+
VALUE
|
|
177
|
+
ca_call_cslab_2 (ca_cslab_t func, const char *fsync,
|
|
178
|
+
VALUE rcx0, VALUE rcx1);
|
|
179
|
+
|
|
180
|
+
VALUE
|
|
181
|
+
ca_call_cslab_3 (ca_cslab_t func, const char *fsync,
|
|
182
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2);
|
|
183
|
+
|
|
184
|
+
VALUE
|
|
185
|
+
ca_call_cslab_4 (ca_cslab_t func, const char *fsync,
|
|
186
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3);
|
|
187
|
+
|
|
188
|
+
VALUE
|
|
189
|
+
ca_call_cslab_5 (ca_cslab_t func, const char *fsync,
|
|
190
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4);
|
|
191
|
+
|
|
192
|
+
VALUE
|
|
193
|
+
ca_call_cslab_6 (ca_cslab_t func, const char *fsync,
|
|
194
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5);
|
|
195
|
+
|
|
196
|
+
VALUE
|
|
197
|
+
ca_call_cslab_7 (ca_cslab_t func, const char *fsync,
|
|
198
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6);
|
|
199
|
+
|
|
200
|
+
VALUE
|
|
201
|
+
ca_call_cslab_1_r (ca_cslab_r_t func, const char *fsync,
|
|
202
|
+
VALUE rcx0,
|
|
203
|
+
void *userdata);
|
|
204
|
+
|
|
205
|
+
VALUE
|
|
206
|
+
ca_call_cslab_2_r (ca_cslab_r_t func, const char *fsync,
|
|
207
|
+
VALUE rcx0, VALUE rcx1,
|
|
208
|
+
void *userdata);
|
|
209
|
+
|
|
210
|
+
VALUE
|
|
211
|
+
ca_call_cslab_3_r (ca_cslab_r_t func, const char *fsync,
|
|
212
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2,
|
|
213
|
+
void *userdata);
|
|
214
|
+
|
|
215
|
+
VALUE
|
|
216
|
+
ca_call_cslab_4_r (ca_cslab_r_t func, const char *fsync,
|
|
217
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3,
|
|
218
|
+
void *userdata);
|
|
219
|
+
|
|
220
|
+
VALUE
|
|
221
|
+
ca_call_cslab_5_r (ca_cslab_r_t func, const char *fsync,
|
|
222
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4,
|
|
223
|
+
void *userdata);
|
|
224
|
+
|
|
225
|
+
VALUE
|
|
226
|
+
ca_call_cslab_6_r (ca_cslab_r_t func, const char *fsync,
|
|
227
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5,
|
|
228
|
+
void *userdata);
|
|
229
|
+
|
|
230
|
+
VALUE
|
|
231
|
+
ca_call_cslab_7_r (ca_cslab_r_t func, const char *fsync,
|
|
232
|
+
VALUE rcx0, VALUE rcx1, VALUE rcx2, VALUE rcx3, VALUE rcx4, VALUE rcx5, VALUE rcx6,
|
|
233
|
+
void *userdata);
|
|
234
|
+
|
|
235
|
+
VALUE
|
|
236
|
+
ca_call_cslab_1_1 (int8_t dty, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
237
|
+
|
|
238
|
+
VALUE
|
|
239
|
+
ca_call_cslab_1_2 (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
240
|
+
|
|
241
|
+
VALUE
|
|
242
|
+
ca_call_cslab_1_3 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
243
|
+
|
|
244
|
+
VALUE
|
|
245
|
+
ca_call_cslab_1_4 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4);
|
|
246
|
+
|
|
247
|
+
VALUE
|
|
248
|
+
ca_call_cslab_1_5 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5);
|
|
249
|
+
|
|
250
|
+
VALUE
|
|
251
|
+
ca_call_cslab_1_6 (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6);
|
|
252
|
+
|
|
253
|
+
VALUE
|
|
254
|
+
ca_call_cslab_2_1 (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
255
|
+
|
|
256
|
+
VALUE
|
|
257
|
+
ca_call_cslab_2_2 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
258
|
+
|
|
259
|
+
VALUE
|
|
260
|
+
ca_call_cslab_2_3 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
261
|
+
|
|
262
|
+
VALUE
|
|
263
|
+
ca_call_cslab_2_4 (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4);
|
|
264
|
+
|
|
265
|
+
VALUE
|
|
266
|
+
ca_call_cslab_3_1 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_t slabfunc, volatile VALUE rx1);
|
|
267
|
+
|
|
268
|
+
VALUE
|
|
269
|
+
ca_call_cslab_3_2 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2);
|
|
270
|
+
|
|
271
|
+
VALUE
|
|
272
|
+
ca_call_cslab_3_3 (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3);
|
|
273
|
+
|
|
274
|
+
VALUE
|
|
275
|
+
ca_call_cslab_1_1_r (int8_t dty, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
276
|
+
|
|
277
|
+
VALUE
|
|
278
|
+
ca_call_cslab_1_2_r (int8_t dty, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
279
|
+
|
|
280
|
+
VALUE
|
|
281
|
+
ca_call_cslab_1_3_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
282
|
+
|
|
283
|
+
VALUE
|
|
284
|
+
ca_call_cslab_1_4_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata);
|
|
285
|
+
|
|
286
|
+
VALUE
|
|
287
|
+
ca_call_cslab_1_5_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, void *userdata);
|
|
288
|
+
|
|
289
|
+
VALUE
|
|
290
|
+
ca_call_cslab_1_6_r (int8_t dty, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, int8_t dtx5, int8_t dtx6, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, volatile VALUE rx5, volatile VALUE rx6, void *userdata);
|
|
291
|
+
|
|
292
|
+
VALUE
|
|
293
|
+
ca_call_cslab_2_1_r (int8_t dty1, int8_t dty2, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
294
|
+
|
|
295
|
+
VALUE
|
|
296
|
+
ca_call_cslab_2_2_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
297
|
+
|
|
298
|
+
VALUE
|
|
299
|
+
ca_call_cslab_2_3_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
300
|
+
|
|
301
|
+
VALUE
|
|
302
|
+
ca_call_cslab_2_4_r (int8_t dty1, int8_t dty2, int8_t dtx1, int8_t dtx2, int8_t dtx3, int8_t dtx4, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, volatile VALUE rx4, void *userdata);
|
|
303
|
+
|
|
304
|
+
VALUE
|
|
305
|
+
ca_call_cslab_3_1_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, ca_cslab_r_t slabfunc, volatile VALUE rx1, void *userdata);
|
|
306
|
+
|
|
307
|
+
VALUE
|
|
308
|
+
ca_call_cslab_3_2_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, void *userdata);
|
|
309
|
+
|
|
310
|
+
VALUE
|
|
311
|
+
ca_call_cslab_3_3_r (int8_t dty1, int8_t dty2, int8_t dty3, int8_t dtx1, int8_t dtx2, int8_t dtx3, ca_cslab_r_t slabfunc, volatile VALUE rx1, volatile VALUE rx2, volatile VALUE rx3, void *userdata);
|
|
312
|
+
|
|
160
313
|
#endif /* CARRAY_CALL_CFUNC_H */
|
data/ext/carray_cast.c
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Cast surface (3 layers):
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
of the target
|
|
7
|
-
`self`.
|
|
5
|
+
<type> `a.int32` etc., and the general `a.to_type(:int32)`.
|
|
6
|
+
Returns a fresh entity CArray of the target
|
|
7
|
+
data_type. Independent storage from `self`. (The
|
|
8
|
+
C functions are named rb_ca_to_<type>, but the
|
|
9
|
+
methods they register carry no `to_` prefix.)
|
|
8
10
|
|
|
9
11
|
as_<type> `a.as_int32` etc. Returns a writable CAMonOp view
|
|
10
12
|
that reinterprets `self` cell-by-cell at the target
|
|
@@ -773,16 +775,62 @@ extern VALUE rb_ca_monop_build (VALUE cary, uint16_t op_id);
|
|
|
773
775
|
/* Forward declaration: clip kernel (ext/carray_kernels.c, generated). */
|
|
774
776
|
extern VALUE rb_ca_clip (VALUE self, VALUE lo, VALUE hi);
|
|
775
777
|
|
|
778
|
+
/* Which surface asked for a type-adapt view. A Face's cells do not mean
|
|
779
|
+
their storage bytes and there is no view that decodes them, so each
|
|
780
|
+
caller says what it does instead of reinterpreting the storage. */
|
|
781
|
+
enum {
|
|
782
|
+
CA_ADAPT_VIEW, /* as_type: the values are behind #to_type */
|
|
783
|
+
CA_ADAPT_READONLY, /* wrap_readonly: the eager conversion is the answer */
|
|
784
|
+
CA_ADAPT_WRITABLE /* wrap_writable: writes have nowhere to land */
|
|
785
|
+
};
|
|
786
|
+
|
|
776
787
|
/* Routes a type-adapt view request to CAMonOp(cast_<dt>) when the
|
|
777
788
|
target is a plain numeric data_type (NOT CA_FIXLEN, NOT CA_OBJECT,
|
|
778
789
|
and `rtype` is not a Class). Falls back to CAFake
|
|
779
790
|
(`rb_ca_fake_type`) for CA_FIXLEN sizing, CA_OBJECT, and class-rtype
|
|
780
791
|
data_class overlay cases.
|
|
781
792
|
Called by rb_ca_as_type_internal, rb_ca_wrap_readonly, and
|
|
782
|
-
rb_ca_wrap_writable in this file.
|
|
793
|
+
rb_ca_wrap_writable in this file.
|
|
794
|
+
|
|
795
|
+
A Face whose surface is not its storage reaches neither: reinterpreting
|
|
796
|
+
the storage would hand back the bytes the surface exists to hide (the
|
|
797
|
+
serial instead of the time, the descriptor instead of the string).
|
|
798
|
+
wrap_readonly, which already returns entities for its non-CArray inputs,
|
|
799
|
+
answers with the eager conversion #to_type performs -- the surface values,
|
|
800
|
+
or the Face's own #to_numeric for a numeric target. as_type and
|
|
801
|
+
wrap_writable have no honest answer and say so. */
|
|
783
802
|
static VALUE
|
|
784
|
-
ca_type_adapt_view (VALUE obj, VALUE rtype, int8_t data_type)
|
|
803
|
+
ca_type_adapt_view (VALUE obj, VALUE rtype, int8_t data_type, int mode)
|
|
785
804
|
{
|
|
805
|
+
CArray *ca;
|
|
806
|
+
|
|
807
|
+
TypedData_Get_Struct(obj, CArray, &carray_data_type, ca);
|
|
808
|
+
|
|
809
|
+
/* Same split the eager cast makes: :object is the Face's surface for every
|
|
810
|
+
Face, and a NonNumeric Face (CA_FIXLEN surface) has no reading of its
|
|
811
|
+
storage as a number either. A Numeric Face falls through, because there
|
|
812
|
+
its surface *is* its storage and the ordinary cast below is right. */
|
|
813
|
+
if ( ca_is_face(ca) && ( data_type == CA_OBJECT
|
|
814
|
+
|| ca->data_type == CA_FIXLEN ) ) {
|
|
815
|
+
VALUE args[1];
|
|
816
|
+
switch ( mode ) {
|
|
817
|
+
case CA_ADAPT_READONLY:
|
|
818
|
+
args[0] = rtype;
|
|
819
|
+
return rb_ca_to_type_internal(1, args, obj);
|
|
820
|
+
case CA_ADAPT_WRITABLE:
|
|
821
|
+
rb_raise(rb_eTypeError,
|
|
822
|
+
"%s has no writable view in another data_type: the writes "
|
|
823
|
+
"would land on the storage its surface hides -- wrap "
|
|
824
|
+
"#parent to reach that storage",
|
|
825
|
+
rb_obj_classname(obj));
|
|
826
|
+
default:
|
|
827
|
+
rb_raise(rb_eTypeError,
|
|
828
|
+
"%s has no view of its values in another data_type: "
|
|
829
|
+
"#to_type gives the values, #parent the raw storage",
|
|
830
|
+
rb_obj_classname(obj));
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
786
834
|
if ( data_type != CA_FIXLEN
|
|
787
835
|
&& data_type != CA_OBJECT
|
|
788
836
|
&& TYPE(rtype) != T_CLASS ) {
|
|
@@ -815,7 +863,7 @@ rb_ca_as_type_internal (int argc, VALUE *argv, VALUE self)
|
|
|
815
863
|
/* Natural-width cast: dispatch via helper (CAMonOp for numeric,
|
|
816
864
|
CAFake for CA_FIXLEN sizing / CA_OBJECT / class-rtype). */
|
|
817
865
|
if ( bytes == (ca_size_t) ca_sizeof[data_type] ) {
|
|
818
|
-
obj = ca_type_adapt_view(self, rtype, data_type);
|
|
866
|
+
obj = ca_type_adapt_view(self, rtype, data_type, CA_ADAPT_VIEW);
|
|
819
867
|
return obj;
|
|
820
868
|
}
|
|
821
869
|
|
|
@@ -1075,7 +1123,7 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1075
1123
|
data_type = rb_ca_guess_type(rtype);
|
|
1076
1124
|
}
|
|
1077
1125
|
if ( ca->data_type != data_type ) {
|
|
1078
|
-
obj = ca_type_adapt_view(obj, rtype, data_type);
|
|
1126
|
+
obj = ca_type_adapt_view(obj, rtype, data_type, CA_ADAPT_WRITABLE);
|
|
1079
1127
|
}
|
|
1080
1128
|
}
|
|
1081
1129
|
else if ( NIL_P(obj) ) { /* obj == nil */
|
|
@@ -1113,7 +1161,8 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1113
1161
|
data_type = rb_ca_guess_type(rtype);
|
|
1114
1162
|
}
|
|
1115
1163
|
if ( ca->data_type != data_type ) {
|
|
1116
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1164
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1165
|
+
CA_ADAPT_WRITABLE);
|
|
1117
1166
|
}
|
|
1118
1167
|
}
|
|
1119
1168
|
else if ( rb_memory_view_available_p(obj) ) { /* MemoryView producer */
|
|
@@ -1130,7 +1179,8 @@ rb_ca_wrap_writable (VALUE arg, VALUE rtype)
|
|
|
1130
1179
|
data_type = rb_ca_guess_type(rtype);
|
|
1131
1180
|
}
|
|
1132
1181
|
if ( ca->data_type != data_type ) {
|
|
1133
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1182
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1183
|
+
CA_ADAPT_WRITABLE);
|
|
1134
1184
|
}
|
|
1135
1185
|
}
|
|
1136
1186
|
else {
|
|
@@ -1171,7 +1221,7 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1171
1221
|
data_type = rb_ca_guess_type(rtype);
|
|
1172
1222
|
}
|
|
1173
1223
|
if ( ca->data_type != data_type ) {
|
|
1174
|
-
obj = ca_type_adapt_view(obj, rtype, data_type);
|
|
1224
|
+
obj = ca_type_adapt_view(obj, rtype, data_type, CA_ADAPT_READONLY);
|
|
1175
1225
|
}
|
|
1176
1226
|
}
|
|
1177
1227
|
else if ( rb_obj_is_kind_of(obj, rb_cNumeric) ) { /* number */
|
|
@@ -1193,7 +1243,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1193
1243
|
data_type = rb_ca_guess_type(rtype);
|
|
1194
1244
|
}
|
|
1195
1245
|
if ( ca->data_type != data_type ) {
|
|
1196
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1246
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1247
|
+
CA_ADAPT_READONLY);
|
|
1197
1248
|
}
|
|
1198
1249
|
}
|
|
1199
1250
|
else if ( TYPE(obj) == T_STRING ) { /* string */
|
|
@@ -1234,7 +1285,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1234
1285
|
data_type = rb_ca_guess_type(rtype);
|
|
1235
1286
|
}
|
|
1236
1287
|
if ( ca->data_type != data_type ) {
|
|
1237
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1288
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1289
|
+
CA_ADAPT_READONLY);
|
|
1238
1290
|
}
|
|
1239
1291
|
}
|
|
1240
1292
|
else if ( rb_memory_view_available_p(obj) ) { /* MemoryView producer */
|
|
@@ -1247,7 +1299,8 @@ rb_ca_wrap_readonly (VALUE arg, VALUE rtype)
|
|
|
1247
1299
|
data_type = rb_ca_guess_type(rtype);
|
|
1248
1300
|
}
|
|
1249
1301
|
if ( ca->data_type != data_type ) {
|
|
1250
|
-
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type
|
|
1302
|
+
obj = ca_type_adapt_view(obj, INT2NUM(data_type), data_type,
|
|
1303
|
+
CA_ADAPT_READONLY);
|
|
1251
1304
|
}
|
|
1252
1305
|
}
|
|
1253
1306
|
else { /* object */
|
|
@@ -1400,16 +1453,6 @@ rb_ca_cast_self_or_other (volatile VALUE *self, volatile VALUE *other)
|
|
|
1400
1453
|
TypedData_Get_Struct(*self, CArray, &carray_data_type, ca);
|
|
1401
1454
|
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1402
1455
|
|
|
1403
|
-
if ( ca->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1404
|
-
*self = ca_ubrep_bind_with(*self, *other);
|
|
1405
|
-
TypedData_Get_Struct(*self, CArray, &carray_data_type, ca);
|
|
1406
|
-
}
|
|
1407
|
-
|
|
1408
|
-
if ( cb->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1409
|
-
*other = ca_ubrep_bind_with(*other, *self);
|
|
1410
|
-
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1411
|
-
}
|
|
1412
|
-
|
|
1413
1456
|
/* Implicit size-1 broadcasting (case A only). No-op if either side
|
|
1414
1457
|
is scalar, ndim differs, or shapes are already equal. If shapes
|
|
1415
1458
|
are incompatible (neither side is 1 nor equal on some axis), also
|
|
@@ -1806,11 +1849,6 @@ rb_ca_cast_other (VALUE *self, volatile VALUE *other)
|
|
|
1806
1849
|
|
|
1807
1850
|
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1808
1851
|
|
|
1809
|
-
if ( cb->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
|
|
1810
|
-
*other = ca_ubrep_bind_with(*other, *self);
|
|
1811
|
-
TypedData_Get_Struct(*other, CArray, &carray_data_type, cb);
|
|
1812
|
-
}
|
|
1813
|
-
|
|
1814
1852
|
test1 = ca_cast_table[cb->data_type][ca->data_type];
|
|
1815
1853
|
|
|
1816
1854
|
if ( test1 == 0 ) {
|
|
@@ -1845,8 +1883,8 @@ rb_ca_cast_with (VALUE self, VALUE other)
|
|
|
1845
1883
|
}
|
|
1846
1884
|
|
|
1847
1885
|
/* -----------------------------------------------------------------------
|
|
1848
|
-
clip_<
|
|
1849
|
-
range, then cast. Sugar for `clip(lo, hi).as_<
|
|
1886
|
+
clip_<type> family — clip into the target data type's representable
|
|
1887
|
+
range, then cast. Sugar for `clip(lo, hi).as_<type>`.
|
|
1850
1888
|
----------------------------------------------------------------------- */
|
|
1851
1889
|
|
|
1852
1890
|
#define CLIP_CAST_FUNC(name, lo_expr, hi_expr, cast_func) \
|
|
@@ -1873,7 +1911,7 @@ CLIP_CAST_FUNC(clip_uint32, INT2NUM(0), UINT2NUM(429496729
|
|
|
1873
1911
|
an overflowing float source (e.g. 1e20) to 2^64 and the subsequent cast to
|
|
1874
1912
|
uint64 wraps around to 0. For floating-point sources we take a saturating
|
|
1875
1913
|
path: compare in float space against 2^64 (which IS representable) and
|
|
1876
|
-
saturate to UINT64_MAX above it and 0 below zero. Other source
|
|
1914
|
+
saturate to UINT64_MAX above it and 0 below zero. Other source data types use
|
|
1877
1915
|
the plain clip-then-cast path. */
|
|
1878
1916
|
static VALUE
|
|
1879
1917
|
rb_ca_clip_uint64 (VALUE self)
|
data/ext/carray_conversion.c
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
Siblings:
|
|
8
8
|
carray_copy.c — CArray-to-CArray copy / template family
|
|
9
9
|
carray_element.c — element-level fetch/store (rb_ca_ptr2obj / obj2ptr)
|
|
10
|
-
carray_cast_func.c —
|
|
10
|
+
carray_cast_func.c — data type cast table used by rb_ca_ptr2obj
|
|
11
11
|
|
|
12
12
|
---------------------------------------------------------------------------- */
|
|
13
13
|
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
#include "ruby/io.h"
|
|
17
17
|
|
|
18
18
|
/* to_a dispatch:
|
|
19
|
-
numeric / boolean
|
|
20
|
-
(
|
|
19
|
+
numeric / boolean data type + entity or attach-able view -> fast path
|
|
20
|
+
(data type-direct leaf loop over the attached contig buffer)
|
|
21
21
|
CA_OBJECT / CA_FIXLEN -> universal
|
|
22
22
|
(rb_ca_fetch_index per cell; ptr is VALUE or byte string, not
|
|
23
23
|
directly castable through the leaf switch)
|
|
24
24
|
|
|
25
25
|
Masked cells materialise as CA_UNDEF on both paths. */
|
|
26
26
|
|
|
27
|
-
/* Leaf macro:
|
|
27
|
+
/* Leaf macro: data type-specialized inner loop. Produces `n` VALUE objects
|
|
28
28
|
from a contig ptr base + element width, storing into `dst` (Ruby Array). */
|
|
29
29
|
#define TO_A_LEAF_LOOP(T, TO_VALUE) do { \
|
|
30
30
|
const T *src = (const T *) base; \
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
|
|
43
43
|
#define TO_A_DISPATCH_LEAF(LOOP) do { \
|
|
44
44
|
ca_size_t li; \
|
|
45
|
-
switch (
|
|
45
|
+
switch ( data_type ) { \
|
|
46
46
|
case CA_FLOAT64: LOOP(double, rb_float_new); break; \
|
|
47
47
|
case CA_FLOAT32: LOOP(float, rb_float_new); break; \
|
|
48
48
|
case CA_INT64: LOOP(int64_t, LL2NUM); break; \
|
|
@@ -67,13 +67,13 @@
|
|
|
67
67
|
} \
|
|
68
68
|
break; \
|
|
69
69
|
default: \
|
|
70
|
-
rb_bug("to_a fast path: unexpected
|
|
70
|
+
rb_bug("to_a fast path: unexpected data type %d", data_type); \
|
|
71
71
|
} \
|
|
72
72
|
} while (0)
|
|
73
73
|
|
|
74
74
|
#define TO_A_DISPATCH_LEAF_MASKED(LOOP) do { \
|
|
75
75
|
ca_size_t li; \
|
|
76
|
-
switch (
|
|
76
|
+
switch ( data_type ) { \
|
|
77
77
|
case CA_FLOAT64: LOOP(double, rb_float_new); break; \
|
|
78
78
|
case CA_FLOAT32: LOOP(float, rb_float_new); break; \
|
|
79
79
|
case CA_INT64: LOOP(int64_t, LL2NUM); break; \
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
} \
|
|
96
96
|
break; \
|
|
97
97
|
default: \
|
|
98
|
-
rb_bug("to_a fast path masked: unexpected
|
|
98
|
+
rb_bug("to_a fast path masked: unexpected data type %d", data_type); \
|
|
99
99
|
} \
|
|
100
100
|
} while (0)
|
|
101
101
|
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
static void
|
|
106
106
|
to_a_fast_recurse (CArray *ca, int32_t level, const char *base,
|
|
107
107
|
const boolean8_t *mask_base, VALUE dst,
|
|
108
|
-
int
|
|
108
|
+
int data_type, ca_size_t bytes, int has_mask)
|
|
109
109
|
{
|
|
110
110
|
ca_size_t i, n, slab_elements, slab_bytes;
|
|
111
111
|
|
|
@@ -135,7 +135,7 @@ to_a_fast_recurse (CArray *ca, int32_t level, const char *base,
|
|
|
135
135
|
to_a_fast_recurse(ca, level + 1,
|
|
136
136
|
base + i * slab_bytes,
|
|
137
137
|
has_mask ? mask_base + i * slab_elements : NULL,
|
|
138
|
-
child,
|
|
138
|
+
child, data_type, bytes, has_mask);
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -172,8 +172,8 @@ rb_ca_to_a_loop_universal (VALUE self, int32_t level, ca_size_t *idx, VALUE ary)
|
|
|
172
172
|
* ndim-1 nesting: shape [2, 3] -> 2-element Array of 3-element Arrays.
|
|
173
173
|
* Masked cells become CA_UNDEF; the mask itself is not preserved on the
|
|
174
174
|
* result. ca_attach(self) supplies a contig row-major buffer for the
|
|
175
|
-
* fast path, so all view kinds land in the
|
|
176
|
-
* the
|
|
175
|
+
* fast path, so all view kinds land in the data type-direct leaf loop when
|
|
176
|
+
* the data type is numeric or boolean; CA_OBJECT / CA_FIXLEN fall through
|
|
177
177
|
* to the universal fetch_index walk. */
|
|
178
178
|
VALUE
|
|
179
179
|
rb_ca_to_a (VALUE self)
|
|
@@ -181,7 +181,7 @@ rb_ca_to_a (VALUE self)
|
|
|
181
181
|
volatile VALUE ary;
|
|
182
182
|
CArray *ca;
|
|
183
183
|
ca_size_t idx[CA_RANK_MAX];
|
|
184
|
-
int
|
|
184
|
+
int data_type, fast_eligible;
|
|
185
185
|
|
|
186
186
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
187
187
|
ary = rb_ca_is_empty(self) ? rb_ary_new() : rb_ary_new2(ca->dim[0]);
|
|
@@ -199,22 +199,22 @@ rb_ca_to_a (VALUE self)
|
|
|
199
199
|
numeric-storage Face -- CATimedelta serials instead of CATimedelta
|
|
200
200
|
Elements -- while ca[i] / each / to_type(:object) all decode. The
|
|
201
201
|
universal loop goes through rb_ca_fetch_addr, which decodes. */
|
|
202
|
-
|
|
202
|
+
data_type = ca->data_type;
|
|
203
203
|
fast_eligible = (ca->elements > 0)
|
|
204
204
|
&& ( ! ca_is_face(ca) )
|
|
205
|
-
&& (
|
|
206
|
-
||
|
|
207
|
-
||
|
|
208
|
-
||
|
|
209
|
-
||
|
|
210
|
-
||
|
|
205
|
+
&& (data_type == CA_FLOAT64 || data_type == CA_FLOAT32
|
|
206
|
+
|| data_type == CA_INT64 || data_type == CA_INT32
|
|
207
|
+
|| data_type == CA_INT16 || data_type == CA_INT8
|
|
208
|
+
|| data_type == CA_UINT64 || data_type == CA_UINT32
|
|
209
|
+
|| data_type == CA_UINT16 || data_type == CA_UINT8
|
|
210
|
+
|| data_type == CA_BOOLEAN);
|
|
211
211
|
|
|
212
212
|
if ( fast_eligible ) {
|
|
213
213
|
int has_mask = (ca->mask != NULL);
|
|
214
214
|
const boolean8_t *mask_base = has_mask
|
|
215
215
|
? (const boolean8_t *) ca->mask->ptr : NULL;
|
|
216
216
|
to_a_fast_recurse(ca, 0, ca->ptr, mask_base, ary,
|
|
217
|
-
|
|
217
|
+
data_type, ca->bytes, has_mask);
|
|
218
218
|
}
|
|
219
219
|
else if ( ca->elements > 0 ) {
|
|
220
220
|
rb_ca_to_a_loop_universal(self, 0, idx, ary);
|
|
@@ -229,7 +229,7 @@ rb_ca_to_a (VALUE self)
|
|
|
229
229
|
#undef TO_A_DISPATCH_LEAF_MASKED
|
|
230
230
|
|
|
231
231
|
/* CArray#convert(data_type=nil, bytes: nil) { |elem| ... } — map every cell
|
|
232
|
-
* through the block, into a new array whose
|
|
232
|
+
* through the block, into a new array whose data type is chosen by argv via
|
|
233
233
|
* CArray#template (shape is inherited from self).
|
|
234
234
|
*
|
|
235
235
|
* Masked cells skip the block; if the block returns CA_UNDEF, the
|
data/ext/carray_copy.c
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
#include "carray.h"
|
|
12
12
|
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
|
|
13
|
+
#include "carray_internal.h" /* ca_gc_hold_push / ca_gc_hold_pop_to */
|
|
13
14
|
#include <stdarg.h>
|
|
14
15
|
|
|
15
16
|
/* ------------------------------------------------------------------- */
|
|
@@ -57,9 +58,18 @@ VALUE
|
|
|
57
58
|
rb_ca_copy (VALUE self)
|
|
58
59
|
{
|
|
59
60
|
volatile VALUE obj;
|
|
60
|
-
CArray *ca;
|
|
61
|
+
CArray *ca, *co;
|
|
62
|
+
int guard = -1;
|
|
61
63
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
62
|
-
|
|
64
|
+
co = ca_copy(ca);
|
|
65
|
+
/* The copy holds VALUEs that so far exist only in co->ptr, and
|
|
66
|
+
ca_wrap_struct allocates. Keep them reachable until the wrapper
|
|
67
|
+
that owns them exists. */
|
|
68
|
+
if ( ca_is_object_type(co) ) {
|
|
69
|
+
guard = ca_gc_hold_push(co->ptr, co->elements);
|
|
70
|
+
}
|
|
71
|
+
obj = ca_wrap_struct(co);
|
|
72
|
+
ca_gc_hold_pop_to(guard);
|
|
63
73
|
CA_FACE_LIFT_IF_FACE(obj, self, ca);
|
|
64
74
|
return obj;
|
|
65
75
|
}
|
data/ext/carray_core.c
CHANGED
|
@@ -231,7 +231,6 @@ ca_cast_table2[CA_NTYPE][CA_NTYPE] = {
|
|
|
231
231
|
* CASelect
|
|
232
232
|
* CAObject
|
|
233
233
|
* CARepeat
|
|
234
|
-
* CAUnboundRepeat
|
|
235
234
|
*/
|
|
236
235
|
|
|
237
236
|
void
|
|
@@ -243,7 +242,6 @@ ca_init_obj_type (void)
|
|
|
243
242
|
extern ca_operation_function_t ca_select_func;
|
|
244
243
|
extern ca_operation_function_t ca_object_func;
|
|
245
244
|
extern ca_operation_function_t ca_stride_func;
|
|
246
|
-
extern ca_operation_function_t ca_ubrep_func;
|
|
247
245
|
|
|
248
246
|
/* CArray */
|
|
249
247
|
ca_func[CA_OBJ_ARRAY] = ca_array_func;
|
|
@@ -309,12 +307,6 @@ ca_init_obj_type (void)
|
|
|
309
307
|
ca_mask_class[CA_OBJ_REPEAT] = rb_cCARepeatMask;
|
|
310
308
|
ca_mask_typeddata[CA_OBJ_REPEAT] = &castride_mask_data_type;
|
|
311
309
|
|
|
312
|
-
/* CAUnboundRepeat */
|
|
313
|
-
ca_func[CA_OBJ_UNBOUND_REPEAT] = ca_ubrep_func;
|
|
314
|
-
ca_class[CA_OBJ_UNBOUND_REPEAT] = rb_cCAUnboundRepeat;
|
|
315
|
-
ca_typeddata[CA_OBJ_UNBOUND_REPEAT] = &caunboundrepeat_data_type;
|
|
316
|
-
ca_mask_class[CA_OBJ_UNBOUND_REPEAT] = rb_cCAUnboundRepeatMask;
|
|
317
|
-
ca_mask_typeddata[CA_OBJ_UNBOUND_REPEAT] = &caunboundrepeat_mask_data_type;
|
|
318
310
|
|
|
319
311
|
ca_obj_num = 9;
|
|
320
312
|
}
|
|
@@ -432,11 +424,22 @@ ca_attach_is_alias (void *ap)
|
|
|
432
424
|
{
|
|
433
425
|
CArray *ca = (CArray *) ap;
|
|
434
426
|
extern ca_operation_function_t ca_stride_func;
|
|
427
|
+
extern ca_operation_function_t ca_lazy_marker_func;
|
|
435
428
|
extern int ca_stride_is_contiguous (CAStride *ca);
|
|
436
429
|
extern int ca_stride_attach_aliases_root (CAStride *ca);
|
|
437
430
|
|
|
438
431
|
if ( ca == NULL ) return 0;
|
|
439
432
|
if ( ca_is_entity(ca) ) return 1;
|
|
433
|
+
|
|
434
|
+
/* CALazyMarker's attach is literally `ca->ptr = ca->parent->ptr` after
|
|
435
|
+
attaching the parent — it adds no layout of its own — so it aliases
|
|
436
|
+
exactly when its parent does. Without this a marker looks expensive
|
|
437
|
+
to every caller and views built on it fall onto materialising paths,
|
|
438
|
+
even though there is nothing between the marker and real memory. */
|
|
439
|
+
if ( ca_func[ca->obj_type].attach == ca_lazy_marker_func.attach ) {
|
|
440
|
+
return ca_attach_is_alias(((CAView *) ca)->parent);
|
|
441
|
+
}
|
|
442
|
+
|
|
440
443
|
/* CAStride family share ca_stride_func.attach (= ca_stride_func_attach).
|
|
441
444
|
The alias-attach fast path is taken iff composed strides are
|
|
442
445
|
row-major contiguous. ca_stride_is_contiguous checks the leaf
|
|
@@ -1399,6 +1402,30 @@ ca_xfer_strided_walk (char *src_base,
|
|
|
1399
1402
|
}
|
|
1400
1403
|
}
|
|
1401
1404
|
|
|
1405
|
+
/* See the comment on the prototype in carray.h. */
|
|
1406
|
+
int
|
|
1407
|
+
ca_xfer_stride_request_is_axis_box (void *ap, ca_size_t *starts,
|
|
1408
|
+
ca_size_t *counts, ca_size_t *strides)
|
|
1409
|
+
{
|
|
1410
|
+
CArray *ca = (CArray *) ap;
|
|
1411
|
+
ca_size_t native[CA_RANK_MAX];
|
|
1412
|
+
ca_size_t s = ca->bytes;
|
|
1413
|
+
int8_t ndim = ca->ndim, k;
|
|
1414
|
+
|
|
1415
|
+
for ( k = ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
|
|
1416
|
+
|
|
1417
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
1418
|
+
ca_size_t q;
|
|
1419
|
+
if ( counts[k] <= 1 ) continue; /* moves nothing */
|
|
1420
|
+
if ( strides[k] <= 0 ) return 0; /* zero / negative: not an axis walk */
|
|
1421
|
+
if ( strides[k] % native[k] != 0 ) return 0;
|
|
1422
|
+
q = strides[k] / native[k];
|
|
1423
|
+
if ( q < 1 ) return 0;
|
|
1424
|
+
if ( starts[k] + (counts[k] - 1) * q >= ca->dim[k] ) return 0; /* runs off axis k */
|
|
1425
|
+
}
|
|
1426
|
+
return 1;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1402
1429
|
static void
|
|
1403
1430
|
ca_xfer_stride_dispatch (CArray *ca, ca_size_t *starts, ca_size_t *counts,
|
|
1404
1431
|
ca_size_t *strides, void *data, int dir)
|
|
@@ -1532,10 +1559,12 @@ ca_xfer_all_body (VALUE arg)
|
|
|
1532
1559
|
return Qnil;
|
|
1533
1560
|
}
|
|
1534
1561
|
|
|
1562
|
+
/* `arg` carries the hold depth to unwind to, so nested ca_xfer_all calls
|
|
1563
|
+
each drop their own hold rather than the whole stack. */
|
|
1535
1564
|
static VALUE
|
|
1536
1565
|
ca_xfer_all_ensure (VALUE arg)
|
|
1537
1566
|
{
|
|
1538
|
-
(
|
|
1567
|
+
ca_gc_hold_pop_to(NUM2INT(arg));
|
|
1539
1568
|
ca_lazy_arena_exit();
|
|
1540
1569
|
return Qnil;
|
|
1541
1570
|
}
|
|
@@ -1545,6 +1574,7 @@ ca_xfer_all (void *ap, void *data, int dir)
|
|
|
1545
1574
|
{
|
|
1546
1575
|
CArray *ca = (CArray *) ap;
|
|
1547
1576
|
ca_xfer_all_args_t args;
|
|
1577
|
+
int guard = -1;
|
|
1548
1578
|
if ( ! ca_func[ca->obj_type].xfer_all ) {
|
|
1549
1579
|
rb_raise(rb_eRuntimeError,
|
|
1550
1580
|
"[BUG] xfer_all not defined for object type <%i>",
|
|
@@ -1562,8 +1592,25 @@ ca_xfer_all (void *ap, void *data, int dir)
|
|
|
1562
1592
|
next entry. */
|
|
1563
1593
|
ca_lazy_arena_enter();
|
|
1564
1594
|
args.ca = ca; args.data = data; args.dir = dir;
|
|
1595
|
+
|
|
1596
|
+
/* A CA_OBJECT cell is a VALUE, and this buffer belongs to no Ruby
|
|
1597
|
+
object yet -- it is the destination `copy` will hand out, or a
|
|
1598
|
+
view's own freshly allocated one. The object lane calls rb_funcall
|
|
1599
|
+
per cell, so a collection partway through would free what has been
|
|
1600
|
+
written so far. ca_xfer_all is the whole-view entry, so the window
|
|
1601
|
+
is exactly ca->elements contiguous cells: the one place where the
|
|
1602
|
+
extent is known without trusting a caller's strides. Sub-windows
|
|
1603
|
+
written by nested transfers land inside it. */
|
|
1604
|
+
if ( ca->data_type == CA_OBJECT && dir == CA_XFER_GET ) {
|
|
1605
|
+
if ( data != (void *) ca->ptr ) {
|
|
1606
|
+
VALUE *p = (VALUE *) data;
|
|
1607
|
+
ca_size_t i;
|
|
1608
|
+
for ( i = 0; i < ca->elements; i++ ) *p++ = Qnil;
|
|
1609
|
+
}
|
|
1610
|
+
guard = ca_gc_hold_push(data, ca->elements);
|
|
1611
|
+
}
|
|
1565
1612
|
rb_ensure(ca_xfer_all_body, (VALUE) &args,
|
|
1566
|
-
ca_xfer_all_ensure,
|
|
1613
|
+
ca_xfer_all_ensure, INT2NUM(guard));
|
|
1567
1614
|
}
|
|
1568
1615
|
|
|
1569
1616
|
/* ------------------------------------------------------------------- */
|
data/ext/carray_count.c
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
CArray#count dispatcher (= value-comparison family entry point).
|
|
4
4
|
Hand-routed because the dispatch decision depends on (self.data_type,
|
|
5
|
-
v's runtime class), which the per-
|
|
5
|
+
v's runtime class), which the per-type mkkernel kernels can't see;
|
|
6
6
|
the actual counting is delegated to the kernel-iterator helpers
|
|
7
7
|
listed below.
|
|
8
8
|
|