carray 3.0.2 → 3.0.4
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 +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/ca_obj_bitfield.c
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
---------------------------------------------------------------------------- */
|
|
13
13
|
|
|
14
14
|
#include "carray.h"
|
|
15
|
+
#include "carray_internal.h"
|
|
15
16
|
|
|
16
17
|
typedef struct {
|
|
17
18
|
int16_t obj_type;
|
|
@@ -32,6 +33,8 @@ typedef struct {
|
|
|
32
33
|
ca_size_t bit_offset;
|
|
33
34
|
uint64_t bit_mask;
|
|
34
35
|
ca_size_t bit_start; /* original offset before endian adjustment */
|
|
36
|
+
ca_size_t bit_length; /* width of the field in bits */
|
|
37
|
+
int8_t sign_extend; /* the field is read as a signed integer */
|
|
35
38
|
} CABitfield;
|
|
36
39
|
|
|
37
40
|
static size_t
|
|
@@ -73,20 +76,6 @@ static int8_t CA_OBJ_BITFIELD;
|
|
|
73
76
|
|
|
74
77
|
static VALUE rb_cCABitfield;
|
|
75
78
|
|
|
76
|
-
static ca_size_t
|
|
77
|
-
bitfield_bitlen (uint64_t bit_mask, ca_size_t bytes)
|
|
78
|
-
{
|
|
79
|
-
ca_size_t bitsize = bytes * 8;
|
|
80
|
-
ca_size_t count = 0;
|
|
81
|
-
ca_size_t i;
|
|
82
|
-
for (i=0; i<bitsize; i++) {
|
|
83
|
-
if ( ( bit_mask >> i ) & 1 ) {
|
|
84
|
-
count++;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return count;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
79
|
/* Generic per-cell fetch: load up to 8 bytes from src starting at
|
|
91
80
|
byte_offset, mask with bit_mask, shift down by bit_offset, and
|
|
92
81
|
write the low `dwrite` bytes of the result to dst.
|
|
@@ -100,8 +89,10 @@ static void
|
|
|
100
89
|
bitfield_fetch(char *dst, ca_size_t dbytes,
|
|
101
90
|
char *src, ca_size_t sbytes,
|
|
102
91
|
ca_size_t byte_offset, ca_size_t bit_offset, uint64_t bit_mask,
|
|
92
|
+
ca_size_t bit_length, int sign_extend,
|
|
103
93
|
ca_size_t elements)
|
|
104
94
|
{
|
|
95
|
+
uint64_t sign = ( sign_extend && bit_length < 64 ) ? ( 1ULL << ( bit_length - 1 ) ) : 0;
|
|
105
96
|
ca_size_t k;
|
|
106
97
|
ca_size_t span = sbytes - byte_offset;
|
|
107
98
|
if (span > 8) span = 8;
|
|
@@ -110,6 +101,9 @@ bitfield_fetch(char *dst, ca_size_t dbytes,
|
|
|
110
101
|
uint64_t tmp = 0;
|
|
111
102
|
memcpy(&tmp, src + k * sbytes + byte_offset, (size_t) span);
|
|
112
103
|
uint64_t result = (tmp & bit_mask) >> bit_offset;
|
|
104
|
+
if ( result & sign ) {
|
|
105
|
+
result |= ~( ( sign << 1 ) - 1 ); /* the field's top bit is its sign */
|
|
106
|
+
}
|
|
113
107
|
memcpy(dst + k * dbytes, &result, (size_t) dwrite);
|
|
114
108
|
}
|
|
115
109
|
}
|
|
@@ -142,12 +136,14 @@ bitfield_store(char *src, ca_size_t sbytes,
|
|
|
142
136
|
|
|
143
137
|
/* ------------------------------------------------------------------- */
|
|
144
138
|
|
|
139
|
+
/* `data_type` is the integer type the field is read as, or CA_NONE for
|
|
140
|
+
the narrowest unsigned type that holds it (boolean for one bit). A
|
|
141
|
+
signed type reads the field's top bit as its sign. */
|
|
145
142
|
int
|
|
146
143
|
ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
147
|
-
ca_size_t offset, ca_size_t bitlen)
|
|
144
|
+
ca_size_t offset, ca_size_t bitlen, int8_t data_type)
|
|
148
145
|
{
|
|
149
146
|
int8_t ndim;
|
|
150
|
-
int8_t data_type;
|
|
151
147
|
ca_size_t bytes = 0, elements;
|
|
152
148
|
ca_size_t bitsize;
|
|
153
149
|
ca_size_t byte_offset;
|
|
@@ -163,11 +159,37 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
163
159
|
rb_raise(rb_eIndexError, "invalid bit length specified for bit field");
|
|
164
160
|
}
|
|
165
161
|
|
|
166
|
-
if ( offset + bitlen -1 >= bitsize ) {
|
|
162
|
+
if ( offset < 0 || offset + bitlen -1 >= bitsize ) {
|
|
167
163
|
rb_raise(rb_eIndexError, "invalid offset for bit field");
|
|
168
164
|
}
|
|
169
165
|
|
|
170
|
-
|
|
166
|
+
/* The bits of an object cell are a reference: writing them would leave
|
|
167
|
+
the cell pointing nowhere. A complex cell is refused as bitarray
|
|
168
|
+
refuses it. */
|
|
169
|
+
if ( ca_is_object_type(parent) || ca_is_complex_type(parent) ) {
|
|
170
|
+
rb_raise(rb_eCADataTypeError, "invalid data_type for bitfield");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* A field is read with one 8-byte load from the byte it starts in. */
|
|
174
|
+
if ( offset % 8 + bitlen > 64 ) {
|
|
175
|
+
rb_raise(rb_eIndexError,
|
|
176
|
+
"a bit field of %lld bits at bit %lld spans more than 8 bytes",
|
|
177
|
+
(long long) bitlen, (long long) offset);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if ( data_type != CA_NONE ) {
|
|
181
|
+
switch ( data_type ) {
|
|
182
|
+
case CA_BOOLEAN:
|
|
183
|
+
case CA_INT8: case CA_UINT8: case CA_INT16: case CA_UINT16:
|
|
184
|
+
case CA_INT32: case CA_UINT32: case CA_INT64: case CA_UINT64:
|
|
185
|
+
break;
|
|
186
|
+
default:
|
|
187
|
+
rb_raise(rb_eCADataTypeError,
|
|
188
|
+
"a bit field is read as an integer type, not <%s>",
|
|
189
|
+
ca_type_name[data_type]);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else if ( bitlen == 1 ) {
|
|
171
193
|
data_type = CA_BOOLEAN;
|
|
172
194
|
}
|
|
173
195
|
else if ( bitlen <= 8 ) {
|
|
@@ -183,18 +205,20 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
183
205
|
data_type = CA_UINT64;
|
|
184
206
|
}
|
|
185
207
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if ( bitlen > bytes * 8 ) {
|
|
189
|
-
rb_raise(rb_eArgError, "invalid bit length for specified data_type");
|
|
190
|
-
}
|
|
208
|
+
CA_CHECK_BYTES_GIVEN(data_type, bytes);
|
|
191
209
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
210
|
+
if ( bitlen > bytes * 8 ||
|
|
211
|
+
( ( data_type == CA_BOOLEAN ) && ( bitlen > 1 ) ) ) {
|
|
212
|
+
rb_raise(rb_eArgError, "a bit field of %lld bits does not fit <%s>",
|
|
213
|
+
(long long) bitlen, ca_type_name[data_type]);
|
|
194
214
|
}
|
|
195
215
|
|
|
196
216
|
if ( ca_endian == CA_BIG_ENDIAN ) {
|
|
197
|
-
|
|
217
|
+
/* The window is placed by the narrowest width that holds the field,
|
|
218
|
+
not by the type it is read as, which may be wider. */
|
|
219
|
+
ca_size_t window = ( bitlen <= 8 ) ? 1 : ( bitlen <= 16 ) ? 2 :
|
|
220
|
+
( bitlen <= 32 ) ? 4 : 8;
|
|
221
|
+
byte_offset = parent->bytes - offset/8 - window;
|
|
198
222
|
bit_offset = offset % 8;
|
|
199
223
|
bit_mask = 0;
|
|
200
224
|
for (i=0; i<bitlen; i++) {
|
|
@@ -217,6 +241,12 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
217
241
|
}
|
|
218
242
|
}
|
|
219
243
|
|
|
244
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
245
|
+
run them before it allocates. */
|
|
246
|
+
if ( ca == NULL ) {
|
|
247
|
+
return 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
220
250
|
ca->obj_type = CA_OBJ_BITFIELD;
|
|
221
251
|
ca->data_type = data_type;
|
|
222
252
|
ca->flags = 0;
|
|
@@ -237,21 +267,25 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
237
267
|
ca->bit_offset = bit_offset;
|
|
238
268
|
ca->bit_mask = bit_mask;
|
|
239
269
|
ca->bit_start = offset; /* preserve original offset for clone/copy */
|
|
270
|
+
ca->bit_length = bitlen;
|
|
271
|
+
ca->sign_extend = ( data_type == CA_INT8 || data_type == CA_INT16 ||
|
|
272
|
+
data_type == CA_INT32 || data_type == CA_INT64 );
|
|
240
273
|
|
|
241
274
|
memcpy(ca->dim, parent->dim, ndim * sizeof(ca_size_t));
|
|
242
275
|
|
|
243
|
-
if ( ca_has_mask(parent) ) {
|
|
244
|
-
ca_create_mask(ca);
|
|
245
|
-
}
|
|
246
276
|
|
|
247
277
|
return 0;
|
|
248
278
|
}
|
|
249
279
|
|
|
250
280
|
CABitfield *
|
|
251
|
-
ca_bitfield_new (CArray *parent, ca_size_t offset, ca_size_t bitlen
|
|
281
|
+
ca_bitfield_new (CArray *parent, ca_size_t offset, ca_size_t bitlen,
|
|
282
|
+
int8_t data_type)
|
|
252
283
|
{
|
|
253
|
-
CABitfield *ca
|
|
254
|
-
ca_bitfield_setup(
|
|
284
|
+
CABitfield *ca;
|
|
285
|
+
ca_bitfield_setup(NULL, parent, offset, bitlen, data_type);
|
|
286
|
+
ca = (CABitfield *) ca_array_alloc(CA_OBJ_BITFIELD, parent->ndim);
|
|
287
|
+
ca_bitfield_setup(ca, parent, offset, bitlen, data_type);
|
|
288
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
255
289
|
return ca;
|
|
256
290
|
}
|
|
257
291
|
|
|
@@ -281,9 +315,8 @@ static void *
|
|
|
281
315
|
ca_bitfield_func_clone (void *ap)
|
|
282
316
|
{
|
|
283
317
|
CABitfield *ca = (CABitfield *) ap;
|
|
284
|
-
return ca_bitfield_new(ca->parent,
|
|
285
|
-
ca->
|
|
286
|
-
bitfield_bitlen(ca->bit_mask, ca->bytes));
|
|
318
|
+
return ca_bitfield_new(ca->parent, ca->bit_start, ca->bit_length,
|
|
319
|
+
ca->data_type);
|
|
287
320
|
}
|
|
288
321
|
|
|
289
322
|
/* Per-cell get/put: fetch the parent cell into a scratch buffer,
|
|
@@ -293,19 +326,21 @@ static void
|
|
|
293
326
|
ca_bitfield_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
294
327
|
{
|
|
295
328
|
CABitfield *ca = (CABitfield *) ap;
|
|
296
|
-
|
|
329
|
+
volatile VALUE holder;
|
|
330
|
+
char *v = ALLOCV_N(char, holder, ca->parent->bytes);
|
|
297
331
|
ca_fetch_index(ca->parent, idx, v);
|
|
298
332
|
if ( dir == CA_XFER_GET ) {
|
|
299
333
|
memset(data, 0, ca->bytes);
|
|
300
334
|
bitfield_fetch(data, ca->bytes, v, ca->parent->bytes,
|
|
301
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
335
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
336
|
+
ca->bit_length, ca->sign_extend, 1);
|
|
302
337
|
}
|
|
303
338
|
else {
|
|
304
339
|
bitfield_store(data, ca->bytes, v, ca->parent->bytes,
|
|
305
340
|
ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
|
|
306
341
|
ca_store_index(ca->parent, idx, v);
|
|
307
342
|
}
|
|
308
|
-
|
|
343
|
+
ALLOCV_END(holder);
|
|
309
344
|
}
|
|
310
345
|
|
|
311
346
|
/* Batched gather / scatter. CABitfield is a 1:1 view (each parent
|
|
@@ -342,7 +377,8 @@ ca_bitfield_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
342
377
|
directly from the attached parent. */
|
|
343
378
|
memset(d, 0, n * ca->bytes);
|
|
344
379
|
bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
345
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
380
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
381
|
+
ca->bit_length, ca->sign_extend, n);
|
|
346
382
|
} else {
|
|
347
383
|
/* Bulk RMW directly against parent memory (bitfield_store
|
|
348
384
|
preserves non-field bits). */
|
|
@@ -359,7 +395,8 @@ ca_bitfield_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
359
395
|
for (i = 0; i < n; i++) {
|
|
360
396
|
memset(d + i * ca->bytes, 0, ca->bytes);
|
|
361
397
|
bitfield_fetch(d + i * ca->bytes, ca->bytes, v + i * pbytes, pbytes,
|
|
362
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
398
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
399
|
+
ca->bit_length, ca->sign_extend, 1);
|
|
363
400
|
}
|
|
364
401
|
}
|
|
365
402
|
else {
|
|
@@ -382,6 +419,7 @@ static void
|
|
|
382
419
|
ca_bitfield_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
383
420
|
ca_size_t *strides, void *data, int dir)
|
|
384
421
|
{
|
|
422
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
385
423
|
CABitfield *ca = (CABitfield *) ap;
|
|
386
424
|
int8_t ndim = ca->ndim;
|
|
387
425
|
ca_size_t native[CA_RANK_MAX], idx[CA_RANK_MAX];
|
|
@@ -412,7 +450,7 @@ ca_bitfield_func_allocate (void *ap)
|
|
|
412
450
|
{
|
|
413
451
|
CABitfield *ca = (CABitfield *) ap;
|
|
414
452
|
ca_attach(ca->parent);
|
|
415
|
-
ca->ptr =
|
|
453
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
416
454
|
}
|
|
417
455
|
|
|
418
456
|
static void
|
|
@@ -420,7 +458,7 @@ ca_bitfield_func_attach (void *ap)
|
|
|
420
458
|
{
|
|
421
459
|
CABitfield *ca = (CABitfield *) ap;
|
|
422
460
|
ca_attach(ca->parent);
|
|
423
|
-
ca->ptr =
|
|
461
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
424
462
|
ca_bitfield_attach(ca);
|
|
425
463
|
}
|
|
426
464
|
|
|
@@ -467,7 +505,8 @@ ca_bitfield_func_xfer_all (void *ap, void *data, int dir)
|
|
|
467
505
|
if ( dir == CA_XFER_GET ) {
|
|
468
506
|
memset(d, 0, n * ca->bytes);
|
|
469
507
|
bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
470
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
508
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
509
|
+
ca->bit_length, ca->sign_extend, n);
|
|
471
510
|
} else {
|
|
472
511
|
bitfield_store(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
473
512
|
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
@@ -491,7 +530,8 @@ ca_bitfield_func_xfer_all (void *ap, void *data, int dir)
|
|
|
491
530
|
ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_GET);
|
|
492
531
|
memset(d, 0, n * ca->bytes);
|
|
493
532
|
bitfield_fetch(d, ca->bytes, scratch, pbytes,
|
|
494
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
533
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
534
|
+
ca->bit_length, ca->sign_extend, n);
|
|
495
535
|
} else {
|
|
496
536
|
/* CAREFUL: gather parent into scratch before splicing so the
|
|
497
537
|
non-field bits are preserved across the RMW. */
|
|
@@ -510,8 +550,7 @@ ca_bitfield_func_fill_data (void *ap, void *ptr)
|
|
|
510
550
|
CABitfield *ca = (CABitfield *) ap;
|
|
511
551
|
ca_attach(ca->parent);
|
|
512
552
|
ca_bitfield_fill(ca, ptr);
|
|
513
|
-
|
|
514
|
-
ca_detach(ca->parent);
|
|
553
|
+
ca_sync_detach(ca->parent);
|
|
515
554
|
}
|
|
516
555
|
|
|
517
556
|
|
|
@@ -542,20 +581,6 @@ ca_bitfield_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
|
542
581
|
ca_fill_stride_via_addrs(ap, base, ndim, counts, steps, ptr);
|
|
543
582
|
}
|
|
544
583
|
|
|
545
|
-
static void
|
|
546
|
-
ca_bitfield_func_create_mask (void *ap)
|
|
547
|
-
{
|
|
548
|
-
CABitfield *ca = (CABitfield *) ap;
|
|
549
|
-
|
|
550
|
-
ca_update_mask(ca->parent);
|
|
551
|
-
if ( ! ca->parent->mask ) {
|
|
552
|
-
ca_create_mask(ca->parent);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
ca->mask = (CArray *) ca_refer_new(ca->parent->mask,
|
|
556
|
-
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
557
|
-
}
|
|
558
|
-
|
|
559
584
|
ca_operation_function_t ca_bitfield_func = {
|
|
560
585
|
-1, /* CA_OBJ_BITFIELD */
|
|
561
586
|
CA_VIEW_ARRAY,
|
|
@@ -566,7 +591,7 @@ ca_operation_function_t ca_bitfield_func = {
|
|
|
566
591
|
ca_bitfield_func_sync,
|
|
567
592
|
ca_bitfield_func_detach,
|
|
568
593
|
ca_bitfield_func_fill_data,
|
|
569
|
-
|
|
594
|
+
ca_view_func_create_mask,
|
|
570
595
|
ca_bitfield_func_xfer_index,
|
|
571
596
|
ca_bitfield_func_xfer_addrs,
|
|
572
597
|
NULL, /* fold_stride: never fold — per-cell bit transform */
|
|
@@ -583,7 +608,8 @@ ca_bitfield_attach (CABitfield *ca)
|
|
|
583
608
|
{
|
|
584
609
|
memset(ca->ptr, 0, ca_length(ca));
|
|
585
610
|
bitfield_fetch(ca->ptr, ca->bytes, ca->parent->ptr, ca->parent->bytes,
|
|
586
|
-
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
611
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask,
|
|
612
|
+
ca->bit_length, ca->sign_extend, ca->elements);
|
|
587
613
|
}
|
|
588
614
|
|
|
589
615
|
static void
|
|
@@ -614,14 +640,15 @@ ca_bitfield_fill (CABitfield *ca, char *ptr)
|
|
|
614
640
|
/* ------------------------------------------------------------------- */
|
|
615
641
|
|
|
616
642
|
VALUE
|
|
617
|
-
rb_ca_bitfield_new (VALUE cary, ca_size_t offset, ca_size_t bitlen
|
|
643
|
+
rb_ca_bitfield_new (VALUE cary, ca_size_t offset, ca_size_t bitlen,
|
|
644
|
+
int8_t data_type)
|
|
618
645
|
{
|
|
619
646
|
volatile VALUE obj;
|
|
620
647
|
CArray *parent;
|
|
621
648
|
CABitfield *ca;
|
|
622
649
|
rb_check_carray_object(cary);
|
|
623
650
|
TypedData_Get_Struct(cary, CArray, &carray_data_type, parent);
|
|
624
|
-
ca = ca_bitfield_new(parent, offset, bitlen);
|
|
651
|
+
ca = ca_bitfield_new(parent, offset, bitlen, data_type);
|
|
625
652
|
obj = ca_wrap_struct(ca);
|
|
626
653
|
rb_ca_set_parent(obj, cary);
|
|
627
654
|
return obj;
|
|
@@ -641,6 +668,9 @@ rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
|
|
|
641
668
|
|
|
642
669
|
if ( TYPE(rrange) == T_FIXNUM ) {
|
|
643
670
|
offset = NUM2INT(rrange);
|
|
671
|
+
if ( offset < 0 ) {
|
|
672
|
+
offset += ca->bytes * 8;
|
|
673
|
+
}
|
|
644
674
|
bitlen = 1;
|
|
645
675
|
}
|
|
646
676
|
else {
|
|
@@ -651,7 +681,8 @@ rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
|
|
|
651
681
|
}
|
|
652
682
|
}
|
|
653
683
|
|
|
654
|
-
return rb_ca_bitfield_new(self, offset, bitlen
|
|
684
|
+
return rb_ca_bitfield_new(self, offset, bitlen,
|
|
685
|
+
NIL_P(rtype) ? CA_NONE : rb_ca_guess_type(rtype));
|
|
655
686
|
}
|
|
656
687
|
|
|
657
688
|
static VALUE
|
|
@@ -667,14 +698,15 @@ rb_ca_bitfield_initialize_copy (VALUE self, VALUE other)
|
|
|
667
698
|
CABitfield *ca, *cs;
|
|
668
699
|
|
|
669
700
|
TypedData_Get_Struct(self, CABitfield, &cabitfield_data_type, ca);
|
|
701
|
+
ca_check_uninitialized(ca);
|
|
670
702
|
TypedData_Get_Struct(other, CABitfield, &cabitfield_data_type, cs);
|
|
671
703
|
|
|
672
704
|
if ( ca_func[CA_OBJ_BITFIELD].pool_init ) {
|
|
673
705
|
ca_array_pool_alloc(ca, CA_OBJ_BITFIELD, cs->parent->ndim);
|
|
674
706
|
}
|
|
675
|
-
ca_bitfield_setup(ca, cs->parent,
|
|
676
|
-
cs->
|
|
677
|
-
|
|
707
|
+
ca_bitfield_setup(ca, cs->parent, cs->bit_start, cs->bit_length,
|
|
708
|
+
cs->data_type);
|
|
709
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
678
710
|
|
|
679
711
|
return self;
|
|
680
712
|
}
|
data/ext/ca_obj_block.c
CHANGED
|
@@ -124,6 +124,12 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
128
|
+
run them before it allocates. */
|
|
129
|
+
if ( ca == NULL ) {
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
|
|
127
133
|
/* strides[k] = step[k] * Pi_{j>k} size0[j] * parent->bytes */
|
|
128
134
|
suffix = parent->bytes;
|
|
129
135
|
for (i = ndim - 1; i >= 0; i--) {
|
|
@@ -141,10 +147,9 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
|
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
/*
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
ca_block_func_create_mask reads those tail fields.
|
|
150
|
+
/* The CABlock tail (offset / start / step / count / size0) is filled
|
|
151
|
+
here; ca_block_func_create_mask reads it when the constructor takes
|
|
152
|
+
the parent's mask (ca_view_inherit_mask) after this setup.
|
|
148
153
|
|
|
149
154
|
Pool path: start/step/count/size0 already point into _pool (wired
|
|
150
155
|
by ca_block_pool_init); only memcpy the values. Non-pool path:
|
|
@@ -161,10 +166,10 @@ ca_block_setup (CABlock *ca, CArray *parent, int8_t ndim, ca_size_t *dim,
|
|
|
161
166
|
memcpy(ca->count, count, ndim * sizeof(ca_size_t));
|
|
162
167
|
memcpy(ca->size0, dim, ndim * sizeof(ca_size_t));
|
|
163
168
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
169
|
+
ca_stride_setup_view((CAStride *) ca, CA_OBJ_BLOCK, parent,
|
|
170
|
+
parent->data_type, parent->bytes,
|
|
171
|
+
ndim, count, strides,
|
|
172
|
+
base_offset_elements * parent->bytes);
|
|
168
173
|
|
|
169
174
|
return 0;
|
|
170
175
|
}
|
|
@@ -174,8 +179,11 @@ ca_block_new (CArray *parent, int8_t ndim, ca_size_t *dim,
|
|
|
174
179
|
ca_size_t *start, ca_size_t *step, ca_size_t *count,
|
|
175
180
|
ca_size_t offset)
|
|
176
181
|
{
|
|
177
|
-
CABlock *ca
|
|
182
|
+
CABlock *ca;
|
|
183
|
+
ca_block_setup(NULL, parent, ndim, dim, start, step, count, offset);
|
|
184
|
+
ca = (CABlock *) ca_array_alloc(CA_OBJ_BLOCK, ndim);
|
|
178
185
|
ca_block_setup(ca, parent, ndim, dim, start, step, count, offset);
|
|
186
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
179
187
|
return ca;
|
|
180
188
|
}
|
|
181
189
|
|
|
@@ -254,6 +262,7 @@ rb_cb_initialize_copy (VALUE self, VALUE other)
|
|
|
254
262
|
{
|
|
255
263
|
CABlock *ca, *cs;
|
|
256
264
|
TypedData_Get_Struct(self, CABlock, &cablock_data_type, ca);
|
|
265
|
+
ca_check_uninitialized(ca);
|
|
257
266
|
TypedData_Get_Struct(other, CABlock, &cablock_data_type, cs);
|
|
258
267
|
/* `self` was created by rb_cb_s_allocate (TypedData_Make_Struct) with
|
|
259
268
|
ca->_pool == NULL. Wire up the pool before ca_block_setup so the
|
|
@@ -264,6 +273,7 @@ rb_cb_initialize_copy (VALUE self, VALUE other)
|
|
|
264
273
|
}
|
|
265
274
|
ca_block_setup(ca, cs->parent, cs->ndim, cs->size0,
|
|
266
275
|
cs->start, cs->step, cs->count, cs->offset);
|
|
276
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
267
277
|
rb_ca_set_parent(self, rb_ca_parent(other));
|
|
268
278
|
return self;
|
|
269
279
|
}
|
data/ext/ca_obj_byte_swap.c
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
---------------------------------------------------------------------------- */
|
|
14
14
|
|
|
15
15
|
#include "carray.h"
|
|
16
|
+
#include "carray_internal.h"
|
|
16
17
|
#include "ca_iter_substrate.h" /* ca_xfer_stride_transform_fused */
|
|
17
18
|
#include "ca_monop_dispatch.h" /* CA_MONOP_BYTE_SWAP dispatch id */
|
|
18
19
|
#include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE for CARecord parent */
|
|
@@ -192,12 +193,18 @@ VALUE rb_cCAByteSwap;
|
|
|
192
193
|
int
|
|
193
194
|
ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
|
|
194
195
|
{
|
|
195
|
-
|
|
196
|
+
CA_CHECK_DATA_TYPE_GIVEN(parent->data_type);
|
|
196
197
|
|
|
197
198
|
if ( parent->data_type == CA_OBJECT ) {
|
|
198
199
|
rb_raise(rb_eCADataTypeError, "object array can't be byte-swapped");
|
|
199
200
|
}
|
|
200
201
|
|
|
202
|
+
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
203
|
+
run them before it allocates. */
|
|
204
|
+
if ( ca == NULL ) {
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
|
|
201
208
|
ca->obj_type = CA_OBJ_BYTE_SWAP;
|
|
202
209
|
ca->data_type = parent->data_type;
|
|
203
210
|
ca->flags = 0;
|
|
@@ -216,9 +223,6 @@ ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
|
|
|
216
223
|
ca->nosync = 0;
|
|
217
224
|
ca->data_class = data_class; /* Qnil if parent has no data_class */
|
|
218
225
|
|
|
219
|
-
if ( ca_has_mask(parent) ) {
|
|
220
|
-
ca_create_mask(ca);
|
|
221
|
-
}
|
|
222
226
|
if ( ca_is_scalar(parent) ) {
|
|
223
227
|
ca_set_flag(ca, CA_FLAG_SCALAR);
|
|
224
228
|
}
|
|
@@ -229,8 +233,11 @@ ca_byte_swap_setup (CAByteSwap *ca, CArray *parent, VALUE data_class)
|
|
|
229
233
|
CAByteSwap *
|
|
230
234
|
ca_byte_swap_new (CArray *parent, VALUE data_class)
|
|
231
235
|
{
|
|
232
|
-
CAByteSwap *ca
|
|
236
|
+
CAByteSwap *ca;
|
|
237
|
+
ca_byte_swap_setup(NULL, parent, data_class);
|
|
238
|
+
ca = (CAByteSwap *) ca_array_alloc(CA_OBJ_BYTE_SWAP, parent->ndim);
|
|
233
239
|
ca_byte_swap_setup(ca, parent, data_class);
|
|
240
|
+
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
234
241
|
return ca;
|
|
235
242
|
}
|
|
236
243
|
|
|
@@ -319,12 +326,12 @@ ca_byte_swap_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
|
319
326
|
ca_byte_swap_apply_one(ca, (char *) data);
|
|
320
327
|
}
|
|
321
328
|
else {
|
|
322
|
-
|
|
323
|
-
char *buf = (
|
|
329
|
+
volatile VALUE holder;
|
|
330
|
+
char *buf = ALLOCV_N(char, holder, ca->bytes);
|
|
324
331
|
memcpy(buf, data, ca->bytes);
|
|
325
332
|
ca_byte_swap_apply_one(ca, buf);
|
|
326
333
|
ca_store_index(ca->parent, idx, buf);
|
|
327
|
-
|
|
334
|
+
ALLOCV_END(holder);
|
|
328
335
|
}
|
|
329
336
|
}
|
|
330
337
|
|
|
@@ -405,6 +412,7 @@ static void
|
|
|
405
412
|
ca_byte_swap_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
406
413
|
ca_size_t *strides, void *data, int dir)
|
|
407
414
|
{
|
|
415
|
+
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
408
416
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
409
417
|
char *d = (char *) data;
|
|
410
418
|
int is_struct = ( ca->data_type == CA_FIXLEN && RTEST(ca->data_class) );
|
|
@@ -454,7 +462,7 @@ ca_byte_swap_func_allocate (void *ap)
|
|
|
454
462
|
{
|
|
455
463
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
456
464
|
ca_attach(ca->parent);
|
|
457
|
-
ca->ptr =
|
|
465
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
458
466
|
}
|
|
459
467
|
|
|
460
468
|
static void
|
|
@@ -462,7 +470,7 @@ ca_byte_swap_func_attach (void *ap)
|
|
|
462
470
|
{
|
|
463
471
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
464
472
|
ca_attach(ca->parent);
|
|
465
|
-
ca->ptr =
|
|
473
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
466
474
|
memcpy(ca->ptr, ca->parent->ptr, ca_length(ca));
|
|
467
475
|
ca_byte_swap_apply(ca, ca->ptr);
|
|
468
476
|
}
|
|
@@ -471,10 +479,17 @@ static void
|
|
|
471
479
|
ca_byte_swap_func_sync (void *ap)
|
|
472
480
|
{
|
|
473
481
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
474
|
-
/* Swap is involutive, so applying it once to the view buffer
|
|
475
|
-
restores the parent byte order
|
|
476
|
-
|
|
477
|
-
|
|
482
|
+
/* Swap is involutive, so applying it once to a copy of the view buffer
|
|
483
|
+
restores the parent byte order. Not the view buffer in place: the
|
|
484
|
+
window stays open after a sync, and a second sync (a stack holding
|
|
485
|
+
this view twice) would swap it again. The swap of a record calls
|
|
486
|
+
Ruby, so it runs on the copy and reaches the parent only whole. */
|
|
487
|
+
volatile VALUE holder;
|
|
488
|
+
char *tmp = ALLOCV_N(char, holder, ca_length(ca));
|
|
489
|
+
memcpy(tmp, ca->ptr, ca_length(ca));
|
|
490
|
+
ca_byte_swap_apply(ca, tmp);
|
|
491
|
+
memcpy(ca->parent->ptr, tmp, ca_length(ca));
|
|
492
|
+
ALLOCV_END(holder);
|
|
478
493
|
ca_sync(ca->parent);
|
|
479
494
|
}
|
|
480
495
|
|
|
@@ -509,8 +524,8 @@ static void
|
|
|
509
524
|
ca_byte_swap_func_fill_data (void *ap, void *ptr)
|
|
510
525
|
{
|
|
511
526
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
512
|
-
|
|
513
|
-
char *buf = (
|
|
527
|
+
volatile VALUE holder;
|
|
528
|
+
char *buf = ALLOCV_N(char, holder, ca->bytes);
|
|
514
529
|
memcpy(buf, ptr, ca->bytes);
|
|
515
530
|
if ( !ca_byte_swap_apply_one(ca, buf) ) {
|
|
516
531
|
/* Bare CA_FIXLEN fill: broadcast the raw bytes into the view
|
|
@@ -523,13 +538,12 @@ ca_byte_swap_func_fill_data (void *ap, void *ptr)
|
|
|
523
538
|
memcpy(ca->ptr + i * ca->bytes, ptr, ca->bytes);
|
|
524
539
|
}
|
|
525
540
|
}
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if ( buf != v ) xfree(buf);
|
|
541
|
+
ca_sync_detach(ca);
|
|
542
|
+
ALLOCV_END(holder);
|
|
529
543
|
return;
|
|
530
544
|
}
|
|
531
545
|
ca_fill(ca->parent, buf);
|
|
532
|
-
|
|
546
|
+
ALLOCV_END(holder);
|
|
533
547
|
}
|
|
534
548
|
|
|
535
549
|
/* fill_data with a region. Swapping is per value, not per cell, so the one
|
|
@@ -543,8 +557,8 @@ ca_byte_swap_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
|
543
557
|
ca_size_t *counts, ca_size_t *steps, void *ptr)
|
|
544
558
|
{
|
|
545
559
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
546
|
-
|
|
547
|
-
char *buf = (
|
|
560
|
+
volatile VALUE holder;
|
|
561
|
+
char *buf = ALLOCV_N(char, holder, ca->bytes);
|
|
548
562
|
memcpy(buf, ptr, ca->bytes);
|
|
549
563
|
if ( ca_byte_swap_apply_one(ca, buf) ) {
|
|
550
564
|
ca_fill_stride(ca->parent, base, ndim, counts, steps, buf);
|
|
@@ -552,7 +566,7 @@ ca_byte_swap_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
|
552
566
|
else {
|
|
553
567
|
ca_fill_stride_default(ca, base, ndim, counts, steps, ptr);
|
|
554
568
|
}
|
|
555
|
-
|
|
569
|
+
ALLOCV_END(holder);
|
|
556
570
|
}
|
|
557
571
|
|
|
558
572
|
static void
|
|
@@ -560,8 +574,8 @@ ca_byte_swap_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
560
574
|
void *ptr)
|
|
561
575
|
{
|
|
562
576
|
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
563
|
-
|
|
564
|
-
char *buf = (
|
|
577
|
+
volatile VALUE holder;
|
|
578
|
+
char *buf = ALLOCV_N(char, holder, ca->bytes);
|
|
565
579
|
memcpy(buf, ptr, ca->bytes);
|
|
566
580
|
if ( ca_byte_swap_apply_one(ca, buf) ) {
|
|
567
581
|
ca_fill_addrs(ca->parent, n, addrs, buf);
|
|
@@ -569,23 +583,7 @@ ca_byte_swap_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
569
583
|
else {
|
|
570
584
|
ca_fill_addrs_default(ca, n, addrs, ptr);
|
|
571
585
|
}
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
static void
|
|
576
|
-
ca_byte_swap_func_create_mask (void *ap)
|
|
577
|
-
{
|
|
578
|
-
CAByteSwap *ca = (CAByteSwap *) ap;
|
|
579
|
-
ca_update_mask(ca->parent);
|
|
580
|
-
if ( ! ca->parent->mask ) {
|
|
581
|
-
ca_create_mask(ca->parent);
|
|
582
|
-
}
|
|
583
|
-
/* Mask is byte-wide (boolean), so the swap is a no-op for the
|
|
584
|
-
mask itself. Share the parent's mask via a CARefer to keep the
|
|
585
|
-
two in lockstep. */
|
|
586
|
-
ca->mask =
|
|
587
|
-
(CArray *) ca_refer_new(ca->parent->mask,
|
|
588
|
-
CA_BOOLEAN, ca->ndim, ca->dim, 0, 0);
|
|
586
|
+
ALLOCV_END(holder);
|
|
589
587
|
}
|
|
590
588
|
|
|
591
589
|
ca_operation_function_t ca_byte_swap_func = {
|
|
@@ -598,7 +596,7 @@ ca_operation_function_t ca_byte_swap_func = {
|
|
|
598
596
|
ca_byte_swap_func_sync,
|
|
599
597
|
ca_byte_swap_func_detach,
|
|
600
598
|
ca_byte_swap_func_fill_data,
|
|
601
|
-
|
|
599
|
+
ca_view_func_create_mask,
|
|
602
600
|
ca_byte_swap_func_xfer_index,
|
|
603
601
|
ca_byte_swap_func_xfer_addrs,
|
|
604
602
|
NULL, /* fold_stride: never fold — value-conversion boundary */
|
|
@@ -658,11 +656,13 @@ rb_ca_byte_swap_initialize_copy (VALUE self, VALUE other)
|
|
|
658
656
|
{
|
|
659
657
|
CAByteSwap *ca, *cs;
|
|
660
658
|
TypedData_Get_Struct(self, CAByteSwap, &cabyteswap_data_type, ca);
|
|
659
|
+
ca_check_uninitialized(ca);
|
|
661
660
|
TypedData_Get_Struct(other, CAByteSwap, &cabyteswap_data_type, cs);
|
|
662
661
|
if ( ca_func[CA_OBJ_BYTE_SWAP].pool_init ) {
|
|
663
662
|
ca_array_pool_alloc(ca, CA_OBJ_BYTE_SWAP, cs->parent->ndim);
|
|
664
663
|
}
|
|
665
664
|
ca_byte_swap_setup(ca, cs->parent, cs->data_class);
|
|
665
|
+
ca_view_inherit_mask((VALUE) ca);
|
|
666
666
|
return self;
|
|
667
667
|
}
|
|
668
668
|
|
|
@@ -732,10 +732,9 @@ rb_ca_swap_bytes_bang (VALUE self)
|
|
|
732
732
|
}
|
|
733
733
|
|
|
734
734
|
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
735
|
-
ca_attach(ca);
|
|
735
|
+
ca_attach(ca); /* window: nothing raises inside */
|
|
736
736
|
ca_byte_swap_buffer(ca->data_type, ca->bytes, ca->elements, ca->ptr);
|
|
737
|
-
|
|
738
|
-
ca_detach(ca);
|
|
737
|
+
ca_sync_detach(ca);
|
|
739
738
|
return self;
|
|
740
739
|
}
|
|
741
740
|
|