carray 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +205 -0
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_dispatch.c +13 -20
- data/ext/ca_categorical_iterator.c +27 -20
- data/ext/ca_compare.c +4 -4
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_kernel_iterator.c +6 -6
- data/ext/ca_kernel_iterator.h +112 -83
- data/ext/ca_obj_array.c +69 -19
- data/ext/ca_obj_bincmp.c +1 -0
- data/ext/ca_obj_binop.c +1 -0
- data/ext/ca_obj_bitarray.c +5 -1
- data/ext/ca_obj_bitfield.c +58 -43
- data/ext/ca_obj_byte_swap.c +2 -1
- data/ext/ca_obj_const_string.c +15 -3
- data/ext/ca_obj_face.c +42 -1
- data/ext/ca_obj_field.c +13 -3
- data/ext/ca_obj_grid.c +52 -5
- data/ext/ca_obj_monop.c +46 -10
- data/ext/ca_obj_object.c +64 -12
- data/ext/ca_obj_record.c +3 -0
- data/ext/ca_obj_reduce.c +4 -0
- data/ext/ca_obj_refer.c +18 -9
- data/ext/ca_obj_roll.c +26 -6
- data/ext/ca_obj_select.c +34 -5
- data/ext/ca_obj_shift.c +31 -7
- data/ext/ca_obj_stack.c +1 -0
- data/ext/ca_obj_stride.c +28 -19
- data/ext/ca_obj_string.c +11 -2
- data/ext/ca_obj_tile.c +27 -7
- data/ext/ca_obj_transpose.c +8 -4
- data/ext/ca_obj_triop.c +3 -0
- data/ext/ca_obj_window.c +79 -50
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/carray.h +33 -0
- data/ext/carray_access.c +16 -3
- data/ext/carray_attribute.c +24 -0
- data/ext/carray_cast.c +243 -82
- data/ext/carray_cast_func.rb +56 -26
- data/ext/carray_conversion.c +2 -2
- data/ext/carray_core.c +3 -0
- data/ext/carray_count.c +6 -0
- data/ext/carray_element.c +9 -4
- data/ext/carray_factorize.c +20 -20
- data/ext/carray_generate.c +8 -2
- data/ext/carray_histogram.c +1 -1
- data/ext/carray_index_classifier.c +4 -4
- data/ext/carray_internal.h +12 -0
- data/ext/carray_kernels_bincmp.c +168 -168
- data/ext/carray_kernels_binop.c +900 -900
- data/ext/carray_kernels_init.c +4 -4
- data/ext/carray_kernels_moncmp.c +96 -96
- data/ext/carray_kernels_monop.c +1984 -1984
- data/ext/carray_kernels_reduce_aggregate.c +1733 -1733
- data/ext/carray_kernels_reduce_cumulative.c +642 -642
- data/ext/carray_kernels_reduce_extreme.c +1150 -1150
- data/ext/carray_kernels_reduce_variance.c +258 -258
- data/ext/carray_kernels_scan.c +128 -128
- data/ext/carray_kernels_search.c +340 -340
- data/ext/carray_kernels_sort.c +295 -304
- data/ext/carray_kernels_triop.c +114 -114
- data/ext/carray_key_windows.c +4 -0
- data/ext/carray_mask.c +45 -22
- data/ext/carray_memory_view.c +2 -2
- data/ext/carray_operator.c +5 -5
- data/ext/carray_order.c +227 -8
- data/ext/carray_random.c +18 -18
- data/ext/carray_scatter.c +24 -7
- data/ext/carray_slab.c +32 -9
- data/ext/carray_sort.c +224 -16
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +35 -43
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_utils.c +63 -21
- data/ext/mkkernel.rb +210 -115
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +17 -4
- data/lib/carray/basics.rb +27 -7
- data/lib/carray/categorical.rb +30 -16
- data/lib/carray/categorical_iterator.rb +6 -6
- data/lib/carray/const_string.rb +10 -0
- data/lib/carray/data_type_extension.rb +8 -1
- data/lib/carray/fixlen_string.rb +41 -2
- data/lib/carray/frame/column_verbs.rb +4 -3
- data/lib/carray/frame/concat.rb +17 -3
- data/lib/carray/frame/frame.rb +6 -7
- data/lib/carray/frame/group.rb +100 -13
- data/lib/carray/frame/io.rb +3 -1
- data/lib/carray/fuse_source.rb +31 -2
- data/lib/carray/lazy.rb +35 -0
- data/lib/carray/methods/is_in.rb +8 -1
- data/lib/carray/segment_iterator.rb +12 -8
- data/lib/carray/serialize.rb +19 -2
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +8 -0
- data/lib/carray/string_operation_extension.rb +13 -5
- data/lib/carray/struct_builder.rb +5 -3
- data/lib/carray/time.rb +107 -68
- data/yard-stubs/ca_obj_transpose.rb +5 -4
- data/yard-stubs/carray_attribute.rb +3 -1
- data/yard-stubs/carray_cast.rb +2 -0
- data/yard-stubs/carray_conversion.rb +5 -1
- data/yard-stubs/carray_element.rb +7 -6
- data/yard-stubs/carray_mask.rb +8 -3
- data/yard-stubs/carray_math.rb +14 -4
- data/yard-stubs/carray_order.rb +100 -4
- data/yard-stubs/carray_scatter.rb +7 -5
- metadata +1 -1
data/ext/ca_obj_tile.c
CHANGED
|
@@ -108,6 +108,8 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
|
|
|
108
108
|
ca->parent = parent;
|
|
109
109
|
ca->attach = 0;
|
|
110
110
|
ca->nosync = 0;
|
|
111
|
+
ca->reps = NULL; /* set before either allocation can raise */
|
|
112
|
+
ca->dim = NULL;
|
|
111
113
|
ca->reps = ALLOC_N(ca_size_t, ndim);
|
|
112
114
|
ca->dim = ALLOC_N(ca_size_t, ndim);
|
|
113
115
|
|
|
@@ -120,15 +122,33 @@ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
|
|
|
120
122
|
return 0;
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
typedef struct {
|
|
126
|
+
CATile *ca;
|
|
127
|
+
CArray *parent;
|
|
128
|
+
ca_size_t *reps;
|
|
129
|
+
} ca_tile_new_arg;
|
|
130
|
+
|
|
131
|
+
static VALUE
|
|
132
|
+
ca_tile_new_setup (VALUE varg)
|
|
133
|
+
{
|
|
134
|
+
ca_tile_new_arg *a = (ca_tile_new_arg *) varg;
|
|
135
|
+
ca_tile_setup(a->ca, a->parent, a->reps);
|
|
136
|
+
return Qnil;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* The setup allocates reps and dim after the struct: when either fails,
|
|
140
|
+
the struct goes too. */
|
|
123
141
|
CATile *
|
|
124
142
|
ca_tile_new (CArray *parent, ca_size_t *reps)
|
|
125
143
|
{
|
|
126
|
-
|
|
144
|
+
ca_tile_new_arg a;
|
|
127
145
|
ca_tile_setup(NULL, parent, reps);
|
|
128
|
-
ca
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
146
|
+
a.ca = ALLOC(CATile);
|
|
147
|
+
a.parent = parent;
|
|
148
|
+
a.reps = reps;
|
|
149
|
+
ca_fill_or_free((CArray *) a.ca, ca_tile_new_setup, (VALUE) &a);
|
|
150
|
+
ca_fill_or_free((CArray *) a.ca, ca_view_inherit_mask, (VALUE) a.ca);
|
|
151
|
+
return a.ca;
|
|
132
152
|
}
|
|
133
153
|
|
|
134
154
|
static void
|
|
@@ -548,7 +568,7 @@ rb_ca_tile (int argc, VALUE *argv, VALUE self)
|
|
|
548
568
|
len, ca->ndim);
|
|
549
569
|
}
|
|
550
570
|
for ( i = 0; i < ca->ndim; i++ ) {
|
|
551
|
-
reps[i] =
|
|
571
|
+
reps[i] = ca_integer_arg(rb_ary_entry(ary, i), "a repeat count", NULL);
|
|
552
572
|
}
|
|
553
573
|
}
|
|
554
574
|
else {
|
|
@@ -559,7 +579,7 @@ rb_ca_tile (int argc, VALUE *argv, VALUE self)
|
|
|
559
579
|
ca->ndim, argc);
|
|
560
580
|
}
|
|
561
581
|
for ( i = 0; i < ca->ndim; i++ ) {
|
|
562
|
-
reps[i] =
|
|
582
|
+
reps[i] = ca_integer_arg(argv[i], "a repeat count", NULL);
|
|
563
583
|
}
|
|
564
584
|
}
|
|
565
585
|
|
data/ext/ca_obj_transpose.c
CHANGED
|
@@ -42,8 +42,8 @@ ca_trans_setup (CAStride *ca, CArray *parent, ca_size_t *imap)
|
|
|
42
42
|
"specified %i-th dimension number out of range", i);
|
|
43
43
|
}
|
|
44
44
|
if (map[idim] != -1) {
|
|
45
|
-
rb_raise(rb_eArgError,
|
|
46
|
-
|
|
45
|
+
rb_raise(rb_eArgError, "%s: axis %" PRId64 " is given twice",
|
|
46
|
+
ca_calling_method_name(), (int64_t) idim);
|
|
47
47
|
}
|
|
48
48
|
map[idim] = i;
|
|
49
49
|
newdim[i] = dim0[idim];
|
|
@@ -120,10 +120,14 @@ rb_ca_trans (int argc, VALUE *argv, VALUE self)
|
|
|
120
120
|
for (i = 0; i < ca->ndim; i++) imap[i] = ca->ndim - i - 1;
|
|
121
121
|
}
|
|
122
122
|
else if (argc == ca->ndim) {
|
|
123
|
-
|
|
123
|
+
/* Each axis read as every axis argument is: negative from the end. */
|
|
124
|
+
for (i = 0; i < ca->ndim; i++) {
|
|
125
|
+
imap[i] = ca_normalize_axis_arg(argv[i], ca->ndim, NULL);
|
|
126
|
+
}
|
|
124
127
|
}
|
|
125
128
|
else {
|
|
126
|
-
rb_raise(rb_eArgError, "
|
|
129
|
+
rb_raise(rb_eArgError, "%s: %d axes given for ndim %d",
|
|
130
|
+
ca_calling_method_name(), argc, (int) ca->ndim);
|
|
127
131
|
}
|
|
128
132
|
|
|
129
133
|
obj = rb_ca_trans_new(self, imap);
|
data/ext/ca_obj_triop.c
CHANGED
|
@@ -542,6 +542,9 @@ rb_ca_triop_build (VALUE cary1, VALUE cary2, VALUE cary3, uint16_t op_id)
|
|
|
542
542
|
r3 = ca_lazy_settle_scalar(r3, r3_scalar);
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
+
ca_refuse_without_common_type(r1, r2);
|
|
546
|
+
ca_refuse_without_common_type(r1, r3);
|
|
547
|
+
ca_refuse_without_common_type(r2, r3);
|
|
545
548
|
TypedData_Get_Struct(r1, CArray, &carray_data_type, op1);
|
|
546
549
|
TypedData_Get_Struct(r2, CArray, &carray_data_type, op2);
|
|
547
550
|
TypedData_Get_Struct(r3, CArray, &carray_data_type, op3);
|
data/ext/ca_obj_window.c
CHANGED
|
@@ -801,16 +801,40 @@ ca_window_create_bounds_mask (VALUE view)
|
|
|
801
801
|
return Qnil;
|
|
802
802
|
}
|
|
803
803
|
|
|
804
|
+
typedef struct {
|
|
805
|
+
CAWindow *ca;
|
|
806
|
+
CArray *parent;
|
|
807
|
+
ca_size_t *start;
|
|
808
|
+
ca_size_t *count;
|
|
809
|
+
uint8_t *bounds;
|
|
810
|
+
char *fill;
|
|
811
|
+
} ca_window_new_arg;
|
|
812
|
+
|
|
813
|
+
static VALUE
|
|
814
|
+
ca_window_new_setup (VALUE varg)
|
|
815
|
+
{
|
|
816
|
+
ca_window_new_arg *a = (ca_window_new_arg *) varg;
|
|
817
|
+
ca_window_setup(a->ca, a->parent, a->start, a->count, a->bounds, a->fill);
|
|
818
|
+
return Qnil;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/* The setup allocates the fill value after the struct and its pool: when
|
|
822
|
+
that fails, the struct goes too. */
|
|
804
823
|
CAWindow *
|
|
805
824
|
ca_window_new (CArray *parent,
|
|
806
825
|
ca_size_t *start, ca_size_t *count, uint8_t *bounds, char *fill)
|
|
807
826
|
{
|
|
808
|
-
|
|
827
|
+
ca_window_new_arg a;
|
|
809
828
|
ca_window_setup(NULL, parent, start, count, bounds, fill);
|
|
810
|
-
ca
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
829
|
+
a.ca = (CAWindow *) ca_array_alloc(CA_OBJ_WINDOW, parent->ndim);
|
|
830
|
+
a.parent = parent;
|
|
831
|
+
a.start = start;
|
|
832
|
+
a.count = count;
|
|
833
|
+
a.bounds = bounds;
|
|
834
|
+
a.fill = fill;
|
|
835
|
+
ca_fill_or_free((CArray *) a.ca, ca_window_new_setup, (VALUE) &a);
|
|
836
|
+
ca_fill_or_free((CArray *) a.ca, ca_window_create_bounds_mask, (VALUE) a.ca);
|
|
837
|
+
return a.ca;
|
|
814
838
|
}
|
|
815
839
|
|
|
816
840
|
static void
|
|
@@ -1674,51 +1698,56 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1674
1698
|
if ( SYMBOL_P(rbounds) ) {
|
|
1675
1699
|
rbounds = rb_sym2str(rbounds);
|
|
1676
1700
|
}
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1701
|
+
if ( ! RB_TYPE_P(rbounds, T_STRING) ) {
|
|
1702
|
+
rb_raise(rb_eTypeError,
|
|
1703
|
+
"window: bounds: must be a Symbol or a String (got %s)",
|
|
1704
|
+
rb_obj_classname(rbounds));
|
|
1705
|
+
}
|
|
1706
|
+
cbounds = StringValueCStr(rbounds);
|
|
1707
|
+
if ( ! strcmp(cbounds, "ruby") ) {
|
|
1708
|
+
bounds = CA_BOUNDS_RUBY;
|
|
1709
|
+
}
|
|
1710
|
+
else if ( ! strcmp(cbounds, "strict") ) {
|
|
1711
|
+
bounds = CA_BOUNDS_STRICT;
|
|
1712
|
+
}
|
|
1713
|
+
else if ( ! strcmp(cbounds, "nearest") ) {
|
|
1714
|
+
bounds = CA_BOUNDS_NEAREST;
|
|
1715
|
+
}
|
|
1716
|
+
else if ( ! strcmp(cbounds, "periodic") ) {
|
|
1717
|
+
rb_raise(rb_eArgError,
|
|
1718
|
+
"bounds=>'periodic' removed in 3.0; "
|
|
1719
|
+
"use CArray#roll(...) for cyclic shift "
|
|
1720
|
+
"(returns a CARoll view)");
|
|
1721
|
+
}
|
|
1722
|
+
else if ( ! strcmp(cbounds, "reflect") ) {
|
|
1723
|
+
rb_raise(rb_eArgError,
|
|
1724
|
+
"bounds=>'reflect' removed in 3.0; "
|
|
1725
|
+
"there is no view-based alternative");
|
|
1726
|
+
}
|
|
1727
|
+
else if ( ! strcmp(cbounds, "mask") ) {
|
|
1728
|
+
rb_warn("CAWindow option :bounds=>\"mask\" will be obsolete");
|
|
1729
|
+
rb_warn("use ca.window(..., fill_value: UNDEF)");
|
|
1730
|
+
bounds = CA_BOUNDS_MASK;
|
|
1731
|
+
}
|
|
1732
|
+
else if ( ! strcmp(cbounds, "fill") ) {
|
|
1733
|
+
bounds = ( rfval == CA_UNDEF ) ? CA_BOUNDS_MASK : CA_BOUNDS_FILL;
|
|
1734
|
+
}
|
|
1735
|
+
else {
|
|
1736
|
+
rb_raise(rb_eArgError,
|
|
1737
|
+
"window: unknown bounds: '%s'", cbounds);
|
|
1738
|
+
}
|
|
1739
|
+
/* A fill value says what the cells outside the array are; the other
|
|
1740
|
+
policies say something else about them. */
|
|
1741
|
+
if ( rfval != CA_UNSPECIFIED
|
|
1742
|
+
&& bounds != CA_BOUNDS_FILL && bounds != CA_BOUNDS_MASK ) {
|
|
1743
|
+
rb_raise(rb_eArgError,
|
|
1744
|
+
"window: fill_value: is for bounds: :fill, not :%s", cbounds);
|
|
1745
|
+
}
|
|
1746
|
+
if ( rfval != CA_UNSPECIFIED && rfval != CA_UNDEF
|
|
1747
|
+
&& bounds == CA_BOUNDS_MASK ) {
|
|
1748
|
+
rb_raise(rb_eArgError,
|
|
1749
|
+
"window: fill_value: %+"PRIsVALUE" conflicts with bounds: :mask "
|
|
1750
|
+
"(use fill_value: UNDEF to mask the cells outside)", rfval);
|
|
1722
1751
|
}
|
|
1723
1752
|
}
|
|
1724
1753
|
|
data/ext/ca_op_ipower.c
CHANGED
|
@@ -112,7 +112,7 @@ static void
|
|
|
112
112
|
ca_ipower_float32_t (ca_size_t n, boolean8_t *m,
|
|
113
113
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
114
114
|
{
|
|
115
|
-
|
|
115
|
+
ca_u_float32_t *p1 = (ca_u_float32_t *) ptr1, *p2 = (ca_u_float32_t *) ptr2;
|
|
116
116
|
if ( m ) {
|
|
117
117
|
while (n--) {
|
|
118
118
|
if ( ! *m++ ) { *p2 = op_powi_float32_t(*p1, ipow); }
|
|
@@ -127,7 +127,7 @@ static void
|
|
|
127
127
|
ca_ipower_float64_t (ca_size_t n, boolean8_t *m,
|
|
128
128
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
129
129
|
{
|
|
130
|
-
|
|
130
|
+
ca_u_float64_t *p1 = (ca_u_float64_t *) ptr1, *p2 = (ca_u_float64_t *) ptr2;
|
|
131
131
|
if ( m ) {
|
|
132
132
|
while (n--) {
|
|
133
133
|
if ( ! *m++ ) { *p2 = op_powi_float64_t(*p1, ipow); }
|
|
@@ -142,7 +142,7 @@ static void
|
|
|
142
142
|
ca_ipower_cmplx64_t (ca_size_t n, boolean8_t *m,
|
|
143
143
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
144
144
|
{
|
|
145
|
-
|
|
145
|
+
ca_u_cmplx64_t *p1 = (ca_u_cmplx64_t *) ptr1, *p2 = (ca_u_cmplx64_t *) ptr2;
|
|
146
146
|
if ( m ) {
|
|
147
147
|
while (n--) {
|
|
148
148
|
if ( ! *m++ ) { *p2 = op_powi_cmplx64_t(*p1, ipow); }
|
|
@@ -157,7 +157,7 @@ static void
|
|
|
157
157
|
ca_ipower_cmplx128_t (ca_size_t n, boolean8_t *m,
|
|
158
158
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
159
159
|
{
|
|
160
|
-
|
|
160
|
+
ca_u_cmplx128_t *p1 = (ca_u_cmplx128_t *) ptr1, *p2 = (ca_u_cmplx128_t *) ptr2;
|
|
161
161
|
if ( m ) {
|
|
162
162
|
while (n--) {
|
|
163
163
|
if ( ! *m++ ) { *p2 = op_powi_cmplx128_t(*p1, ipow); }
|
data/ext/ca_sort_kernels.h
CHANGED
|
@@ -62,11 +62,14 @@ void ca_sort_merge_f64 (double *a, double *aux, ca_size_t n);
|
|
|
62
62
|
ca_size_t ca_partition_nan_f32 (float32_t *a, ca_size_t n);
|
|
63
63
|
ca_size_t ca_partition_nan_f64 (double *a, ca_size_t n);
|
|
64
64
|
|
|
65
|
-
/*
|
|
65
|
+
/* Pair variant of NaN pre-partition for float argsort kernels. scratch
|
|
66
|
+
holds n pairs; its contents on return are unspecified. */
|
|
66
67
|
struct ca_pair_f32;
|
|
67
68
|
struct ca_pair_f64;
|
|
68
|
-
ca_size_t ca_partition_nan_pair_f32 (struct ca_pair_f32 *a, ca_size_t n
|
|
69
|
-
|
|
69
|
+
ca_size_t ca_partition_nan_pair_f32 (struct ca_pair_f32 *a, ca_size_t n,
|
|
70
|
+
struct ca_pair_f32 *scratch);
|
|
71
|
+
ca_size_t ca_partition_nan_pair_f64 (struct ca_pair_f64 *a, ca_size_t n,
|
|
72
|
+
struct ca_pair_f64 *scratch);
|
|
70
73
|
|
|
71
74
|
/* P.9: value-level quickselect for partition_copy.
|
|
72
75
|
Reorders a[0..n) so that a[kth] is exact + left/right regions
|
data/ext/carray.h
CHANGED
|
@@ -173,6 +173,39 @@ typedef int8_t boolean8_t;
|
|
|
173
173
|
#define CA_ALIGN_CMPLX128 offsetof(struct { char c; cmplx128_t x; }, x)
|
|
174
174
|
#define CA_ALIGN_OBJECT offsetof(struct { char c; VALUE x; }, x)
|
|
175
175
|
|
|
176
|
+
/* Cell types that may sit at any byte. A view's cells need not be aligned
|
|
177
|
+
to their size: a struct member at offset 1, a refer with a byte offset,
|
|
178
|
+
a wrapped external buffer. Reading a cell through a plain `double *`
|
|
179
|
+
there is undefined (x86 vector code may assume the alignment), so a
|
|
180
|
+
kernel reads and writes cells through these. Same size and value as the
|
|
181
|
+
plain type; only the alignment the compiler may assume is 1. */
|
|
182
|
+
#if defined(__GNUC__) || defined(__clang__)
|
|
183
|
+
# define CA_UNALIGNED __attribute__((aligned(1)))
|
|
184
|
+
#else
|
|
185
|
+
# define CA_UNALIGNED
|
|
186
|
+
#endif
|
|
187
|
+
typedef boolean8_t ca_u_boolean8_t;
|
|
188
|
+
typedef int8_t ca_u_int8_t;
|
|
189
|
+
typedef uint8_t ca_u_uint8_t;
|
|
190
|
+
typedef int16_t ca_u_int16_t CA_UNALIGNED;
|
|
191
|
+
typedef uint16_t ca_u_uint16_t CA_UNALIGNED;
|
|
192
|
+
typedef int32_t ca_u_int32_t CA_UNALIGNED;
|
|
193
|
+
typedef uint32_t ca_u_uint32_t CA_UNALIGNED;
|
|
194
|
+
typedef int64_t ca_u_int64_t CA_UNALIGNED;
|
|
195
|
+
typedef uint64_t ca_u_uint64_t CA_UNALIGNED;
|
|
196
|
+
typedef float32_t ca_u_float32_t CA_UNALIGNED;
|
|
197
|
+
typedef float64_t ca_u_float64_t CA_UNALIGNED;
|
|
198
|
+
typedef cmplx64_t ca_u_cmplx64_t CA_UNALIGNED;
|
|
199
|
+
typedef cmplx128_t ca_u_cmplx128_t CA_UNALIGNED;
|
|
200
|
+
typedef VALUE ca_u_VALUE CA_UNALIGNED;
|
|
201
|
+
|
|
202
|
+
typedef ca_u_float32_t ca_u_float;
|
|
203
|
+
typedef ca_u_float64_t ca_u_double;
|
|
204
|
+
|
|
205
|
+
/* CA_U(float64_t) is ca_u_float64_t (and CA_U(double) ca_u_double): for a
|
|
206
|
+
macro that takes the cell type. */
|
|
207
|
+
#define CA_U(type) ca_u_##type
|
|
208
|
+
|
|
176
209
|
/* -------------------------------------------------------------------- */
|
|
177
210
|
|
|
178
211
|
#define CA_OBJ_TYPE_MAX 256
|
data/ext/carray_access.c
CHANGED
|
@@ -193,6 +193,14 @@ rb_ca_fill (VALUE self, VALUE rval)
|
|
|
193
193
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
194
194
|
|
|
195
195
|
if ( ca_is_empty(ca) ) {
|
|
196
|
+
/* No cell to fill, but a value no cell could hold is refused, as an
|
|
197
|
+
assignment to the empty array refuses it. */
|
|
198
|
+
if ( rval != CA_UNDEF && ca->bytes > 0 ) {
|
|
199
|
+
volatile VALUE holder;
|
|
200
|
+
char *fval = ALLOCV_N(char, holder, ca->bytes);
|
|
201
|
+
rb_ca_obj2ptr(self, rval, fval);
|
|
202
|
+
ALLOCV_END(holder);
|
|
203
|
+
}
|
|
196
204
|
return self; /* empty = no-op fill; return self for chaining */
|
|
197
205
|
}
|
|
198
206
|
|
|
@@ -884,9 +892,9 @@ rb_ca_index_restruct_block (int16_t *ndimp, ca_size_t *shrink, ca_size_t *dim,
|
|
|
884
892
|
|
|
885
893
|
offset = 0;
|
|
886
894
|
|
|
887
|
-
if ( idx[0] == -1 ) {
|
|
888
|
-
j =
|
|
889
|
-
|
|
895
|
+
if ( ndim0 > 0 && idx[0] == -1 ) {
|
|
896
|
+
/* j = the number of leading axes collapsed by a scalar index */
|
|
897
|
+
for (j=1; j<ndim0 && idx[j] == -1; j++) {
|
|
890
898
|
;
|
|
891
899
|
}
|
|
892
900
|
|
|
@@ -1365,6 +1373,7 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1365
1373
|
element, which is what the shape rules then hold it to. */
|
|
1366
1374
|
if ( nscalar == nclean ) {
|
|
1367
1375
|
VALUE blocks[CA_RANK_MAX];
|
|
1376
|
+
ca_check_rank_fits(nunder, NULL); /* the result has the :_ axes only */
|
|
1368
1377
|
for (i = 0; i < nclean; i++) {
|
|
1369
1378
|
blocks[i] = rb_assoc_new(clean[i], INT2FIX(1));
|
|
1370
1379
|
}
|
|
@@ -1379,6 +1388,10 @@ rb_ca_fetch_newaxis (int argc, VALUE *argv, VALUE self, CArray *ca)
|
|
|
1379
1388
|
|
|
1380
1389
|
TypedData_Get_Struct(base, CArray, &carray_data_type, cb);
|
|
1381
1390
|
|
|
1391
|
+
/* The result has the base's axes and one for each :_, before any is
|
|
1392
|
+
written into final_dims. */
|
|
1393
|
+
ca_check_rank_fits((long) nunder + cb->ndim, NULL);
|
|
1394
|
+
|
|
1382
1395
|
/* Reconstruct final shape: walk original argv. :_ -> size-1, scalar
|
|
1383
1396
|
(Integer) -> dropped (skip), else -> base.dim[cursor]. A key gives one
|
|
1384
1397
|
axis, except an integer CArray read alone (a mapping), which gives as
|
data/ext/carray_attribute.c
CHANGED
|
@@ -520,10 +520,34 @@ rb_ca_inherit_attr (VALUE dst, VALUE src)
|
|
|
520
520
|
it up after this (an ivar, a lift that moves it onto another parent), and
|
|
521
521
|
writes through it are refused by ca_is_readonly, which walks to the
|
|
522
522
|
frozen root and finds CA_FLAG_READ_ONLY there. */
|
|
523
|
+
static void
|
|
524
|
+
ca_note_view_of_lent (CArray *p)
|
|
525
|
+
{
|
|
526
|
+
if ( ca_test_flag(p, CA_FLAG_LENT) ) {
|
|
527
|
+
ca_set_flag(p, CA_FLAG_LENT_VIEWED);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
523
531
|
VALUE
|
|
524
532
|
rb_ca_set_parent (VALUE self, VALUE obj)
|
|
525
533
|
{
|
|
526
534
|
rb_ivar_set(self, id_parent, obj);
|
|
535
|
+
/* A view of an array lent to a CAObject hook outlives the hook: tell the
|
|
536
|
+
array, so that it keeps its cells when the hook returns. A view of
|
|
537
|
+
several arrays names one here and holds the rest in parents[]. */
|
|
538
|
+
if ( rb_obj_is_carray(obj) ) {
|
|
539
|
+
ca_note_view_of_lent((CArray *) DATA_PTR(obj));
|
|
540
|
+
}
|
|
541
|
+
if ( rb_obj_is_carray(self) ) {
|
|
542
|
+
CArray *ca = (CArray *) DATA_PTR(self);
|
|
543
|
+
if ( ca_test_flag(ca, CA_FLAG_MULTI_PARENTS) ) {
|
|
544
|
+
CAMultiParent *mp = (CAMultiParent *) ca;
|
|
545
|
+
int32_t k;
|
|
546
|
+
for ( k = 0; k < mp->n_parents; k++ ) {
|
|
547
|
+
ca_note_view_of_lent(mp->parents[k]);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
527
551
|
return obj;
|
|
528
552
|
}
|
|
529
553
|
|