carray 3.0.5 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +233 -0
- data/README.md +1 -1
- data/carray.gemspec +3 -2
- data/ext/ca_axis_dispatch.c +6 -0
- data/ext/ca_axis_group.c +1 -1
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.c +116 -231
- data/ext/ca_kernel_iterator.h +410 -254
- data/ext/ca_obj_bincmp.c +9 -1
- data/ext/ca_obj_binop.c +10 -1
- data/ext/ca_obj_bitfield.c +2 -0
- data/ext/ca_obj_byte_swap.c +2 -0
- data/ext/ca_obj_face.c +2 -0
- data/ext/ca_obj_fake.c +3 -1
- data/ext/ca_obj_grid.c +167 -12
- data/ext/ca_obj_meld.c +69 -113
- data/ext/ca_obj_moncmp.c +9 -1
- data/ext/ca_obj_monop.c +40 -2
- data/ext/ca_obj_object.c +54 -20
- data/ext/ca_obj_reduce.c +15 -1
- data/ext/ca_obj_refer.c +65 -20
- data/ext/ca_obj_remap.c +69 -10
- data/ext/ca_obj_roll.c +1 -0
- data/ext/ca_obj_select.c +4 -1
- data/ext/ca_obj_select_axis.c +1 -0
- data/ext/ca_obj_shift.c +1 -0
- data/ext/ca_obj_stack.c +310 -111
- data/ext/ca_obj_stride.c +131 -45
- data/ext/ca_obj_string.c +18 -2
- data/ext/ca_obj_tile.c +1 -0
- data/ext/ca_obj_triop.c +9 -1
- data/ext/ca_obj_window.c +1 -0
- data/ext/ca_op_ipower.c +8 -8
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +2 -1
- data/ext/carray_access.c +27 -64
- data/ext/carray_address_basis.c +134 -0
- data/ext/carray_attribute.c +8 -0
- data/ext/carray_broadcast.c +3 -4
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_cast.c +8 -11
- data/ext/carray_conversion.c +9 -5
- data/ext/carray_core.c +811 -72
- data/ext/carray_element.c +13 -9
- data/ext/carray_histogram.c +25 -3
- data/ext/carray_internal.h +147 -12
- data/ext/carray_kernels_bincmp.c +2007 -3
- data/ext/carray_kernels_binop.c +25365 -5199
- data/ext/carray_kernels_init.c +8 -8
- data/ext/carray_kernels_monop.c +10696 -3678
- data/ext/carray_kernels_reduce_aggregate.c +4429 -702
- data/ext/carray_kernels_reduce_boolean.c +1533 -15
- data/ext/carray_kernels_reduce_cumulative.c +1808 -248
- data/ext/carray_kernels_reduce_extreme.c +4508 -511
- data/ext/carray_kernels_reduce_variance.c +2284 -152
- data/ext/carray_kernels_scan.c +240 -240
- data/ext/carray_kernels_search.c +4211 -264
- data/ext/carray_kernels_sort.c +367 -450
- data/ext/carray_lazy.c +47 -0
- data/ext/carray_loop.c +1 -1
- data/ext/carray_mask.c +130 -139
- data/ext/carray_median_percentile.c +4 -4
- data/ext/carray_memory_view.c +13 -7
- data/ext/carray_operator.c +147 -44
- data/ext/carray_order.c +3 -2
- data/ext/carray_random.c +4 -1
- data/ext/carray_slab.c +97 -21
- data/ext/carray_sort.c +1 -1
- data/ext/carray_test.c +74 -19
- data/ext/carray_time_text.c +2 -2
- data/ext/extconf.rb +11 -0
- data/ext/mkkernel.rb +346 -94
- data/ext/ruby_carray.c +4 -1
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +25 -1
- data/lib/carray/autoload_carray.rb +3 -3
- data/lib/carray/autoload_method_extension.rb +5 -3
- data/lib/carray/axis_group.rb +13 -7
- data/lib/carray/basics.rb +1 -1
- data/lib/carray/block_iterator.rb +17 -3
- data/lib/carray/categorical.rb +6 -8
- data/lib/carray/categorical_iterator.rb +2 -2
- data/lib/carray/complex.rb +2 -2
- data/lib/carray/conditional.rb +3 -2
- data/lib/carray/frame/column_verbs.rb +45 -14
- data/lib/carray/frame/convert.rb +19 -0
- data/lib/carray/frame/csv_parser.rb +32 -32
- data/lib/carray/frame/describe.rb +4 -2
- data/lib/carray/frame/frame.rb +399 -78
- data/lib/carray/frame/group.rb +679 -53
- data/lib/carray/frame/io.rb +209 -71
- data/lib/carray/frame/join.rb +146 -37
- data/lib/carray/frame/records.rb +3 -3
- data/lib/carray/frame/reshape.rb +89 -11
- data/lib/carray/frame/sort.rb +57 -9
- data/lib/carray/frame/verbs.rb +384 -49
- data/lib/carray/frame/windows.rb +44 -6
- data/lib/carray/inspect.rb +7 -2
- data/lib/carray/iterator.rb +32 -0
- data/lib/carray/lazy.rb +17 -8
- data/lib/carray/mask_gap_fill.rb +37 -17
- data/lib/carray/meld_reduce.rb +1 -1
- data/lib/carray/methods/choose.rb +3 -2
- data/lib/carray/methods/meshgrid.rb +3 -1
- data/lib/carray/runtime.rb +47 -8
- data/lib/carray/segment_iterator.rb +23 -8
- data/lib/carray/serialize.rb +34 -17
- data/lib/carray/stack.rb +18 -6
- data/lib/carray/time.rb +5 -0
- data/lib/carray/window_iterator.rb +16 -4
- data/yard-stubs/ca_obj_array.rb +26 -1
- data/yard-stubs/carray_cast.rb +8 -5
- data/yard-stubs/carray_conversion.rb +8 -2
- data/yard-stubs/carray_mask.rb +20 -1
- data/yard-stubs/carray_math.rb +31 -16
- data/yard-stubs/carray_memory_view.rb +7 -0
- data/yard-stubs/carray_test.rb +7 -4
- metadata +18 -4
data/ext/carray_test.c
CHANGED
|
@@ -274,10 +274,23 @@ eql_## type (const char *a, const char *b, ca_size_t bytes) \
|
|
|
274
274
|
return ( *(const type*)a == *(const type*)b ); \
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
/* == compares contents: a NaN equals a NaN (whatever its payload), as the
|
|
278
|
+
same array read back or copied holds the same NaN; -0.0 equals 0.0 as
|
|
279
|
+
values do. eql? stays bitwise. */
|
|
280
|
+
static int
|
|
281
|
+
ca_object_cells_equal (VALUE x, VALUE y)
|
|
282
|
+
{
|
|
283
|
+
if ( RB_FLOAT_TYPE_P(x) && RB_FLOAT_TYPE_P(y) &&
|
|
284
|
+
isnan(RFLOAT_VALUE(x)) && isnan(RFLOAT_VALUE(y)) ) {
|
|
285
|
+
return 1;
|
|
286
|
+
}
|
|
287
|
+
return RTEST(rb_funcall(x, id_equal, 1, y)) ? 1 : 0;
|
|
288
|
+
}
|
|
289
|
+
|
|
277
290
|
static int
|
|
278
291
|
eql_VALUE (const char *a, const char *b, ca_size_t bytes)
|
|
279
292
|
{
|
|
280
|
-
return
|
|
293
|
+
return ca_object_cells_equal(*(const VALUE*)a, *(const VALUE*)b);
|
|
281
294
|
}
|
|
282
295
|
|
|
283
296
|
static int
|
|
@@ -295,10 +308,28 @@ eql_type(int32_t)
|
|
|
295
308
|
eql_type(uint32_t)
|
|
296
309
|
eql_type(int64_t)
|
|
297
310
|
eql_type(uint64_t)
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
311
|
+
#define eql_float(type) \
|
|
312
|
+
static int \
|
|
313
|
+
eql_## type (const char *a, const char *b, ca_size_t bytes) \
|
|
314
|
+
{ \
|
|
315
|
+
type x = *(const type*)a, y = *(const type*)b; \
|
|
316
|
+
return ( x == y ) || ( isnan(x) && isnan(y) ); \
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#define eql_cmplx(type, part) \
|
|
320
|
+
static int \
|
|
321
|
+
eql_## type (const char *a, const char *b, ca_size_t bytes) \
|
|
322
|
+
{ \
|
|
323
|
+
type x = *(const type*)a, y = *(const type*)b; \
|
|
324
|
+
part xr = creal(x), xi = cimag(x), yr = creal(y), yi = cimag(y); \
|
|
325
|
+
return ( ( xr == yr ) || ( isnan(xr) && isnan(yr) ) ) && \
|
|
326
|
+
( ( xi == yi ) || ( isnan(xi) && isnan(yi) ) ); \
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
eql_float(float32_t)
|
|
330
|
+
eql_float(float64_t)
|
|
331
|
+
eql_cmplx(cmplx64_t, float)
|
|
332
|
+
eql_cmplx(cmplx128_t, double)
|
|
302
333
|
|
|
303
334
|
/* Placeholder for CA_FLOAT128 / CA_CMPLX256 slots (ca_valid[12] =
|
|
304
335
|
ca_valid[15] = 0, so never invoked). */
|
|
@@ -371,8 +402,8 @@ ca_compare_body (VALUE arg)
|
|
|
371
402
|
comparison is bitwise (= NaN.eql?(NaN) yields true since their bit
|
|
372
403
|
patterns match), so memcmp gives the right semantics. For non-strict
|
|
373
404
|
(==) of numeric data_types, type-equality is byte-equality EXCEPT for
|
|
374
|
-
floats where -0.0 == +0.0 (different bit pattern, same value) and
|
|
375
|
-
NaN
|
|
405
|
+
floats where -0.0 == +0.0 (different bit pattern, same value) and any
|
|
406
|
+
NaN equals any NaN (payloads may differ) -- so we must keep the
|
|
376
407
|
per-element comparator there.
|
|
377
408
|
|
|
378
409
|
Integer / bool / fixlen data_types are byte-exact, so memcmp matches both
|
|
@@ -380,13 +411,14 @@ ca_compare_body (VALUE arg)
|
|
|
380
411
|
the comparator. */
|
|
381
412
|
if ( ! masked_a && ! masked_b ) {
|
|
382
413
|
if ( is_object ) {
|
|
383
|
-
ID id = strict ? id_eql : id_equal;
|
|
384
414
|
VALUE *va = (VALUE *) pa;
|
|
385
415
|
VALUE *vb = (VALUE *) pb;
|
|
386
416
|
for (i=0; i<ca->elements; i++) {
|
|
387
417
|
volatile VALUE x = va[i];
|
|
388
418
|
volatile VALUE y = vb[i];
|
|
389
|
-
|
|
419
|
+
int eq = strict ? RTEST(rb_funcall(x, id_eql, 1, y))
|
|
420
|
+
: ca_object_cells_equal(x, y);
|
|
421
|
+
if ( ! eq ) {
|
|
390
422
|
flag = 0;
|
|
391
423
|
break;
|
|
392
424
|
}
|
|
@@ -427,8 +459,8 @@ ca_compare_body (VALUE arg)
|
|
|
427
459
|
if ( is_object ) {
|
|
428
460
|
volatile VALUE x = *(VALUE *) pa;
|
|
429
461
|
volatile VALUE y = *(VALUE *) pb;
|
|
430
|
-
|
|
431
|
-
|
|
462
|
+
eq = strict ? RTEST(rb_funcall(x, id_eql, 1, y))
|
|
463
|
+
: ca_object_cells_equal(x, y);
|
|
432
464
|
}
|
|
433
465
|
else if ( strict
|
|
434
466
|
|| ca->data_type <= CA_UINT64
|
|
@@ -451,6 +483,19 @@ ca_compare_body (VALUE arg)
|
|
|
451
483
|
return Qnil;
|
|
452
484
|
}
|
|
453
485
|
|
|
486
|
+
typedef struct {
|
|
487
|
+
CArray **list;
|
|
488
|
+
ca_compare_ctx_t *c;
|
|
489
|
+
} ca_compare_run_t;
|
|
490
|
+
|
|
491
|
+
static VALUE
|
|
492
|
+
ca_compare_run (VALUE arg)
|
|
493
|
+
{
|
|
494
|
+
ca_compare_run_t *r = (ca_compare_run_t *) arg;
|
|
495
|
+
ca_attach_window(2, r->list, "rr", ca_compare_body, (VALUE) r->c);
|
|
496
|
+
return Qnil;
|
|
497
|
+
}
|
|
498
|
+
|
|
454
499
|
/* ca_compare_common(a, b, strict) — shared body of ca_equal (==) and
|
|
455
500
|
* ca_eql_strict (eql?). Returns 1 if arrays match under the selected
|
|
456
501
|
* semantics, else 0.
|
|
@@ -461,7 +506,7 @@ ca_compare_body (VALUE arg)
|
|
|
461
506
|
* four masked/unmasked combinations.
|
|
462
507
|
*
|
|
463
508
|
* The only difference is the per-element comparator:
|
|
464
|
-
* == : ca_eql[data_type] (
|
|
509
|
+
* == : ca_eql[data_type] (by value: NaN equals NaN, -0.0 equals 0.0)
|
|
465
510
|
* eql?: memcmp for numeric, rb_funcall(:eql?) for CA_OBJECT
|
|
466
511
|
*
|
|
467
512
|
* The unmasked-unmasked branch takes a bulk memcmp or per-cell
|
|
@@ -503,8 +548,14 @@ ca_compare_common (void *ap, void *bp, int strict)
|
|
|
503
548
|
c.flag = 1;
|
|
504
549
|
list[0] = ca;
|
|
505
550
|
list[1] = cb;
|
|
506
|
-
/* The object lane calls #== / #eql? with both arrays attached
|
|
507
|
-
|
|
551
|
+
/* The object lane calls #== / #eql? with both arrays attached, and
|
|
552
|
+
recorded as compared over (ca_computing_run), so a cell holding one
|
|
553
|
+
of them is refused as cyclic rather than compared again without
|
|
554
|
+
end. */
|
|
555
|
+
ca_compare_run_t r;
|
|
556
|
+
r.list = list;
|
|
557
|
+
r.c = &c;
|
|
558
|
+
ca_computing_run(2, list, ca_compare_run, (VALUE) &r);
|
|
508
559
|
return c.flag;
|
|
509
560
|
}
|
|
510
561
|
}
|
|
@@ -522,9 +573,10 @@ ca_eql_storage (void *ap, void *bp)
|
|
|
522
573
|
}
|
|
523
574
|
|
|
524
575
|
/* CArray#==(other) — elementwise equality returning true / false.
|
|
525
|
-
* data_class, data_type, shape, and mask state must all match
|
|
526
|
-
*
|
|
527
|
-
*
|
|
576
|
+
* data_class, data_type, shape, and mask state must all match. It asks
|
|
577
|
+
* whether the contents are the same, so a NaN equals a NaN and -0.0
|
|
578
|
+
* equals 0.0; the IEEE comparison of each element is #eq. Non-CArray
|
|
579
|
+
* other returns false. */
|
|
528
580
|
static VALUE
|
|
529
581
|
rb_ca_equal (VALUE self, VALUE other)
|
|
530
582
|
{
|
|
@@ -795,7 +847,8 @@ without_read_only_ensure (VALUE arg)
|
|
|
795
847
|
* the bridge owns.
|
|
796
848
|
*
|
|
797
849
|
* Mechanics: clears CA_FLAG_READ_ONLY on self and on its mask for the
|
|
798
|
-
* duration of the block
|
|
850
|
+
* duration of the block, except on a mask that is a wrap: that mask borrows
|
|
851
|
+
* its bits from a producer (wrap_memory_view's mask:), which set the flag; rb_ensure restores both on normal return AND on
|
|
799
852
|
* raise, setting the flag on whatever mask self has by then. (A read-only
|
|
800
853
|
* array's mask carries the flag once CArray#mask has handed it out.) Frozen
|
|
801
854
|
* objects still raise FrozenError. Does not walk parent chains.
|
|
@@ -822,7 +875,9 @@ rb_ca_without_read_only_flag (VALUE self)
|
|
|
822
875
|
s.was_readonly = ca_test_flag(ca, CA_FLAG_READ_ONLY);
|
|
823
876
|
if (s.was_readonly) {
|
|
824
877
|
ca_unset_flag(ca, CA_FLAG_READ_ONLY);
|
|
825
|
-
|
|
878
|
+
/* A mask that is a wrap borrows its bits (the mask: of
|
|
879
|
+
wrap_memory_view); its flag is the lender's and stays. */
|
|
880
|
+
if (ca->mask && ca->mask->obj_type != CA_OBJ_ARRAY_WRAP) {
|
|
826
881
|
ca_unset_flag(ca->mask, CA_FLAG_READ_ONLY);
|
|
827
882
|
}
|
|
828
883
|
}
|
data/ext/carray_time_text.c
CHANGED
|
@@ -383,7 +383,7 @@ rb_ca_parse_time_text (int argc, VALUE *argv, VALUE self)
|
|
|
383
383
|
if ( ca->data_type != CA_OBJECT ) {
|
|
384
384
|
rb_raise(rb_eArgError, "time text reading needs an object array");
|
|
385
385
|
}
|
|
386
|
-
if ( ! ca_is_entity(ca) ) {
|
|
386
|
+
if ( ! ca_is_entity(ca) || ! ca->ptr ) {
|
|
387
387
|
src = rb_ca_copy(src);
|
|
388
388
|
TypedData_Get_Struct(src, CArray, &carray_data_type, ca);
|
|
389
389
|
}
|
|
@@ -1077,7 +1077,7 @@ rb_ca_strptime_fields (VALUE self, VALUE rformat, VALUE rstrict)
|
|
|
1077
1077
|
if ( ca->data_type != CA_OBJECT ) {
|
|
1078
1078
|
rb_raise(rb_eArgError, "strptime reading needs an object array");
|
|
1079
1079
|
}
|
|
1080
|
-
if ( ! ca_is_entity(ca) ) {
|
|
1080
|
+
if ( ! ca_is_entity(ca) || ! ca->ptr ) {
|
|
1081
1081
|
src = rb_ca_copy(src);
|
|
1082
1082
|
TypedData_Get_Struct(src, CArray, &carray_data_type, ca);
|
|
1083
1083
|
}
|
data/ext/extconf.rb
CHANGED
|
@@ -118,6 +118,17 @@ if try_compile("int main(void) { return 0; }", "-fwrapv")
|
|
|
118
118
|
$carray_build_flags << "-fwrapv"
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
# --- math functions do not set errno (`-fno-math-errno`)
|
|
122
|
+
#
|
|
123
|
+
# Nothing in carray reads errno after a math call. With errno kept, GCC
|
|
124
|
+
# must call sqrt() for every cell instead of using the vector square root,
|
|
125
|
+
# so `sqrt` ran 2-4x slower than it could. The values do not change.
|
|
126
|
+
# Apple clang already defaults to this.
|
|
127
|
+
if try_compile("int main(void) { return 0; }", "-fno-math-errno")
|
|
128
|
+
$CFLAGS += " -fno-math-errno"
|
|
129
|
+
$carray_build_flags << "-fno-math-errno"
|
|
130
|
+
end
|
|
131
|
+
|
|
121
132
|
# --- probe for `-fopenmp-simd` (SL.1.0, PROPOSAL_REDUCTION_SIMD_LICENSE)
|
|
122
133
|
#
|
|
123
134
|
# `-fopenmp-simd` enables `#pragma omp simd` (and its `reduction(+:acc)`
|