carray 2.0.0 → 3.0.0
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 +5 -25
- data/CHANGELOG.md +16 -0
- data/LICENSE +1 -1
- data/NEWS.md +3 -0
- data/README.md +128 -44
- data/carray.gemspec +22 -24
- data/ext/ca_array_pool.c +91 -0
- data/ext/ca_axis_descriptor.h +186 -0
- data/ext/ca_axis_dispatch.c +924 -0
- data/ext/ca_axis_group.c +1208 -0
- data/ext/ca_bincmp_dispatch.c +76 -0
- data/ext/ca_bincmp_dispatch.h +85 -0
- data/ext/ca_binop_dispatch.c +125 -0
- data/ext/ca_binop_dispatch.h +159 -0
- data/ext/ca_categorical_iterator.c +1375 -0
- data/ext/ca_compare.c +94 -0
- data/ext/ca_compare.h +26 -0
- data/ext/ca_composite_dispatch.c +414 -0
- data/ext/ca_composite_dispatch.h +116 -0
- data/ext/ca_for_buffer.h +96 -0
- data/ext/ca_for_each_element.h +241 -0
- data/ext/ca_group_iter.c +304 -0
- data/ext/ca_iter_substrate.h +325 -0
- data/ext/ca_kernel_iterator.c +4321 -0
- data/ext/ca_kernel_iterator.h +2603 -0
- data/ext/ca_moncmp_dispatch.c +37 -0
- data/ext/ca_moncmp_dispatch.h +62 -0
- data/ext/ca_monop_dispatch.c +200 -0
- data/ext/ca_monop_dispatch.h +235 -0
- data/ext/ca_obj_array.c +355 -359
- data/ext/ca_obj_bincmp.c +809 -0
- data/ext/ca_obj_binop.c +892 -0
- data/ext/ca_obj_bitarray.c +369 -164
- data/ext/ca_obj_bitfield.c +294 -234
- data/ext/ca_obj_block.c +189 -711
- data/ext/ca_obj_byte_swap.c +766 -0
- data/ext/ca_obj_const_string.c +965 -0
- data/ext/ca_obj_face.c +670 -0
- data/ext/ca_obj_face.h +247 -0
- data/ext/ca_obj_fake.c +228 -100
- data/ext/ca_obj_farray.c +54 -441
- data/ext/ca_obj_field.c +82 -529
- data/ext/ca_obj_fixlen_string.c +306 -0
- data/ext/ca_obj_grid.c +858 -440
- data/ext/ca_obj_meld.c +1034 -0
- data/ext/ca_obj_moncmp.c +569 -0
- data/ext/ca_obj_monop.c +1111 -0
- data/ext/ca_obj_object.c +774 -298
- data/ext/ca_obj_record.c +468 -0
- data/ext/ca_obj_reduce.c +97 -82
- data/ext/ca_obj_refer.c +569 -459
- data/ext/ca_obj_remap.c +475 -0
- data/ext/ca_obj_repeat.c +92 -477
- data/ext/ca_obj_roll.c +616 -0
- data/ext/ca_obj_select.c +344 -296
- data/ext/ca_obj_select_axis.c +1296 -0
- data/ext/ca_obj_shift.c +230 -792
- data/ext/ca_obj_source.c +78 -0
- data/ext/ca_obj_stack.c +1173 -0
- data/ext/ca_obj_stride.c +2501 -0
- data/ext/ca_obj_string.c +268 -0
- data/ext/ca_obj_tile.c +614 -0
- data/ext/ca_obj_time.c +546 -0
- data/ext/ca_obj_timedelta.c +435 -0
- data/ext/ca_obj_transpose.c +62 -516
- data/ext/ca_obj_triop.c +746 -0
- data/ext/ca_obj_unbound_repeat.c +208 -241
- data/ext/ca_obj_window.c +1131 -563
- data/ext/ca_op_byte_swap.c +175 -0
- data/ext/ca_op_ipower.c +319 -0
- data/ext/ca_op_powi.h +88 -0
- data/ext/ca_sort_kernels.h +132 -0
- data/ext/ca_sweep_engine.c +430 -0
- data/ext/ca_sweep_engine.h +157 -0
- data/ext/ca_transform_common.c +228 -0
- data/ext/ca_triop_dispatch.c +55 -0
- data/ext/ca_triop_dispatch.h +62 -0
- data/ext/carray.h +795 -402
- data/ext/carray_access.c +831 -711
- data/ext/carray_attribute.c +98 -330
- data/ext/carray_bincount.c +255 -0
- data/ext/carray_broadcast.c +283 -0
- data/ext/carray_call_cfunc.c +1360 -828
- data/ext/carray_call_cfunc.h +160 -0
- data/ext/carray_cast.c +1212 -301
- data/ext/carray_cast_func.rb +81 -40
- data/ext/carray_class.c +53 -63
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +350 -346
- data/ext/carray_copy.c +156 -268
- data/ext/carray_core.c +1342 -199
- data/ext/carray_count.c +312 -0
- data/ext/carray_data_type.c +43 -19
- data/ext/carray_element.c +585 -213
- data/ext/carray_factorize.c +2542 -0
- data/ext/carray_generate.c +230 -559
- data/ext/carray_histogram.c +490 -0
- data/ext/carray_hold.c +228 -0
- data/ext/carray_index_classifier.c +1035 -0
- data/ext/carray_index_classifier.h +27 -0
- data/ext/carray_internal.h +120 -0
- data/ext/carray_kernels_bincmp.c +4445 -0
- data/ext/carray_kernels_binop.c +10979 -0
- data/ext/carray_kernels_init.c +36 -0
- data/ext/carray_kernels_map.c +3466 -0
- data/ext/carray_kernels_moncmp.c +2096 -0
- data/ext/carray_kernels_monop.c +18312 -0
- data/ext/carray_kernels_reduce_aggregate.c +25836 -0
- data/ext/carray_kernels_reduce_boolean.c +329 -0
- data/ext/carray_kernels_reduce_cumulative.c +14592 -0
- data/ext/carray_kernels_reduce_extreme.c +16947 -0
- data/ext/carray_kernels_reduce_variance.c +3909 -0
- data/ext/carray_kernels_scan.c +3692 -0
- data/ext/carray_kernels_search.c +32137 -0
- data/ext/carray_kernels_sort.c +10625 -0
- data/ext/carray_kernels_triop.c +1391 -0
- data/ext/carray_lazy.c +567 -0
- data/ext/carray_loop.c +88 -200
- data/ext/carray_mask.c +848 -154
- data/ext/carray_math_kernel.h +120 -0
- data/ext/carray_mathfunc.c +10 -241
- data/ext/carray_median_percentile.c +1257 -0
- data/ext/carray_memory_view.c +1625 -0
- data/ext/carray_operator.c +1526 -318
- data/ext/carray_order.c +664 -1394
- data/ext/carray_partition.c +416 -0
- data/ext/carray_random.c +518 -0
- data/ext/carray_scatter.c +357 -0
- data/ext/carray_slab.c +1219 -0
- data/ext/carray_slab.h +84 -0
- data/ext/carray_sort.c +829 -0
- data/ext/carray_sort_kernel.c +620 -0
- data/ext/carray_struct.c +695 -0
- data/ext/carray_test.c +343 -229
- data/ext/carray_undef.c +34 -17
- data/ext/carray_utils.c +175 -74
- data/ext/extconf.rb +216 -55
- data/ext/mk_call_cfunc.rb +480 -0
- data/ext/mkkernel.rb +8842 -0
- data/ext/ruby_carray.c +202 -101
- data/ext/version.h +4 -14
- data/ext/version.rb +5 -13
- data/lib/carray/arrow_tensor.rb +401 -0
- data/lib/carray/attribute.rb +166 -0
- data/lib/carray/autoload_carray.rb +220 -0
- data/lib/carray/autoload_method_extension.rb +44 -0
- data/lib/carray/axis_group.rb +711 -0
- data/lib/carray/basics.rb +481 -0
- data/lib/carray/bincount_nd.rb +358 -0
- data/lib/carray/block_iterator.rb +604 -0
- data/lib/carray/boolean_reduce.rb +109 -0
- data/lib/carray/categorical.rb +561 -0
- data/lib/carray/categorical_iterator.rb +1062 -0
- data/lib/carray/complex.rb +150 -0
- data/lib/carray/conditional.rb +216 -0
- data/lib/carray/const_string.rb +228 -0
- data/lib/carray/construct.rb +139 -328
- data/lib/carray/core_extensions.rb +240 -0
- data/lib/carray/data_type_extension.rb +233 -0
- data/lib/carray/fixlen_string.rb +95 -0
- data/lib/carray/frame/concat.rb +132 -0
- data/lib/carray/frame/convert.rb +95 -0
- data/lib/carray/frame/csv_parser.rb +211 -0
- data/lib/carray/frame/frame.rb +649 -0
- data/lib/carray/frame/group.rb +186 -0
- data/lib/carray/frame/io.rb +164 -0
- data/lib/carray/frame/join.rb +248 -0
- data/lib/carray/frame/records.rb +99 -0
- data/lib/carray/frame/sort.rb +113 -0
- data/lib/carray/frame/verbs.rb +299 -0
- data/lib/carray/frame.rb +16 -0
- data/lib/carray/histogram.rb +512 -0
- data/lib/carray/inspect.rb +37 -20
- data/lib/carray/iterator.rb +57 -349
- data/lib/carray/lazy.rb +889 -0
- data/lib/carray/mask_gap_fill.rb +200 -0
- data/lib/carray/math.rb +78 -342
- data/lib/carray/meld_reduce.rb +289 -0
- data/lib/carray/methods/align_addr.rb +116 -0
- data/lib/carray/methods/bin.rb +128 -0
- data/lib/carray/methods/bincount.rb +87 -0
- data/lib/carray/methods/bit_string.rb +92 -0
- data/lib/carray/methods/broadcast.rb +63 -0
- data/lib/carray/methods/choose.rb +39 -0
- data/lib/carray/methods/composition.rb +280 -0
- data/lib/carray/methods/gather_nd.rb +206 -0
- data/lib/carray/methods/index.rb +39 -0
- data/lib/carray/methods/insert_block.rb +99 -0
- data/lib/carray/methods/is_in.rb +141 -0
- data/lib/carray/methods/join.rb +90 -0
- data/lib/carray/methods/locate_addr.rb +47 -0
- data/lib/carray/methods/mask_duplicates.rb +41 -0
- data/lib/carray/methods/meshgrid.rb +91 -0
- data/lib/carray/methods/mode.rb +126 -0
- data/lib/carray/methods/nunique.rb +46 -0
- data/lib/carray/methods/resize.rb +56 -0
- data/lib/carray/methods/snap.rb +156 -0
- data/lib/carray/methods/string_format.rb +57 -0
- data/lib/carray/methods/unique.rb +47 -0
- data/lib/carray/methods/value_counts.rb +71 -0
- data/lib/carray/mkmf.rb +124 -101
- data/lib/carray/runtime.rb +108 -0
- data/lib/carray/serialize.rb +478 -167
- data/lib/carray/slab_iterator.rb +292 -0
- data/lib/carray/stack.rb +291 -0
- data/lib/carray/string.rb +56 -180
- data/lib/carray/string_operation_extension.rb +289 -0
- data/lib/carray/struct.rb +335 -323
- data/lib/carray/struct_builder.rb +697 -0
- data/lib/carray/table.rb +41 -2
- data/lib/carray/time.rb +2255 -38
- data/lib/carray/window_iterator.rb +655 -0
- data/lib/carray.rb +55 -57
- metadata +163 -130
- data/Rakefile +0 -51
- data/TODO.md +0 -18
- data/ext/ca_iter_block.c +0 -257
- data/ext/ca_iter_dimension.c +0 -299
- data/ext/ca_iter_window.c +0 -214
- data/ext/ca_obj_mapping.c +0 -644
- data/ext/carray_iterator.c +0 -641
- data/ext/carray_math.rb +0 -850
- data/ext/carray_numeric.c +0 -259
- data/ext/carray_sort_addr.c +0 -254
- data/ext/carray_stat.c +0 -2100
- data/ext/carray_stat_proc.rb +0 -1999
- data/ext/mkmath.rb +0 -741
- data/ext/ruby_ccomplex.c +0 -509
- data/ext/ruby_float_func.c +0 -86
- data/lib/carray/array.rb +0 -8
- data/lib/carray/autoload/autoload_base.rb +0 -19
- data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
- data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
- data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
- data/lib/carray/autoload/autoload_gem_random.rb +0 -8
- data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
- data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
- data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
- data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
- data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
- data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
- data/lib/carray/autoload/autoload_object_link.rb +0 -1
- data/lib/carray/autoload/autoload_object_pack.rb +0 -2
- data/lib/carray/autoload.rb +0 -141
- data/lib/carray/basic.rb +0 -191
- data/lib/carray/broadcast.rb +0 -101
- data/lib/carray/compose.rb +0 -315
- data/lib/carray/convert.rb +0 -115
- data/lib/carray/info.rb +0 -110
- data/lib/carray/io/imagemagick.rb +0 -235
- data/lib/carray/mask.rb +0 -102
- data/lib/carray/math/histogram.rb +0 -177
- data/lib/carray/math/recurrence.rb +0 -93
- data/lib/carray/object/ca_obj_iterator.rb +0 -50
- data/lib/carray/object/ca_obj_link.rb +0 -50
- data/lib/carray/object/ca_obj_pack.rb +0 -99
- data/lib/carray/obsolete.rb +0 -256
- data/lib/carray/ordering.rb +0 -181
- data/lib/carray/testing.rb +0 -51
- data/lib/carray/transform.rb +0 -109
- data/misc/Methods.ja.md +0 -182
- data/misc/NOTE +0 -51
- data/spec/Classes/CABitfield_spec.rb +0 -58
- data/spec/Classes/CABlockIterator_spec.rb +0 -114
- data/spec/Classes/CABlock_spec.rb +0 -205
- data/spec/Classes/CAField_spec.rb +0 -39
- data/spec/Classes/CAGrid_spec.rb +0 -75
- data/spec/Classes/CAMap_spec.rb +0 -0
- data/spec/Classes/CAMapping_spec.rb +0 -105
- data/spec/Classes/CAObject_attribute_spec.rb +0 -33
- data/spec/Classes/CAObject_spec.rb +0 -33
- data/spec/Classes/CARefer_spec.rb +0 -93
- data/spec/Classes/CARepeat_spec.rb +0 -65
- data/spec/Classes/CASelect_spec.rb +0 -22
- data/spec/Classes/CAShift_spec.rb +0 -16
- data/spec/Classes/CAStruct_spec.rb +0 -71
- data/spec/Classes/CATranspose_spec.rb +0 -60
- data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
- data/spec/Classes/CAWindow_spec.rb +0 -54
- data/spec/Classes/CAWrap_spec.rb +0 -8
- data/spec/Classes/CArray_spec.rb +0 -184
- data/spec/Classes/CScalar_spec.rb +0 -55
- data/spec/Classes/ex1.rb +0 -46
- data/spec/Features/feature_130_spec.rb +0 -19
- data/spec/Features/feature_attributes_spec.rb +0 -280
- data/spec/Features/feature_boolean_spec.rb +0 -98
- data/spec/Features/feature_broadcast.rb +0 -116
- data/spec/Features/feature_cast_function.rb +0 -19
- data/spec/Features/feature_cast_spec.rb +0 -33
- data/spec/Features/feature_class_spec.rb +0 -84
- data/spec/Features/feature_complex_spec.rb +0 -42
- data/spec/Features/feature_composite_spec.rb +0 -124
- data/spec/Features/feature_convert_spec.rb +0 -46
- data/spec/Features/feature_copy_spec.rb +0 -123
- data/spec/Features/feature_creation_spec.rb +0 -84
- data/spec/Features/feature_element_spec.rb +0 -144
- data/spec/Features/feature_extream_spec.rb +0 -54
- data/spec/Features/feature_generate_spec.rb +0 -74
- data/spec/Features/feature_index_spec.rb +0 -69
- data/spec/Features/feature_mask_spec.rb +0 -580
- data/spec/Features/feature_math_spec.rb +0 -97
- data/spec/Features/feature_order_spec.rb +0 -146
- data/spec/Features/feature_ref_store_spec.rb +0 -209
- data/spec/Features/feature_serialization_spec.rb +0 -125
- data/spec/Features/feature_stat_spec.rb +0 -397
- data/spec/Features/feature_virtual_spec.rb +0 -48
- data/spec/Features/method_eq_spec.rb +0 -81
- data/spec/Features/method_is_nan_spec.rb +0 -12
- data/spec/Features/method_map_spec.rb +0 -54
- data/spec/Features/method_max_with.rb +0 -20
- data/spec/Features/method_min_with.rb +0 -19
- data/spec/Features/method_ne_spec.rb +0 -18
- data/spec/Features/method_project_spec.rb +0 -188
- data/spec/Features/method_ref_spec.rb +0 -27
- data/spec/Features/method_round_spec.rb +0 -11
- data/spec/Features/method_s_linspace_spec.rb +0 -48
- data/spec/Features/method_s_span_spec.rb +0 -14
- data/spec/Features/method_seq_spec.rb +0 -47
- data/spec/Features/method_sort_with.rb +0 -43
- data/spec/Features/method_sorted_with.rb +0 -29
- data/spec/Features/method_span_spec.rb +0 -42
- data/spec/Features/method_wrap_readonly_spec.rb +0 -43
- data/spec/UnitTest/test_CAVirtual.rb +0 -214
- data/spec/spec_all.rb +0 -10
- data/utils/ca_ase.rb +0 -21
- data/utils/ca_methods.rb +0 -15
- data/utils/cast_checker.rb +0 -30
- data/utils/convert_test.rb +0 -73
- data/utils/extract_yard.rb +0 -22
- data/utils/guess_shape.rb +0 -76
- data/utils/monkey_patch_methods.rb +0 -62
- data/utils/remove_resource_fork.sh +0 -5
data/ext/ca_obj_bitfield.c
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/* ---------------------------------------------------------------------------
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CABitfield view: extract a contiguous bit field from each parent
|
|
4
|
+
cell, exposing it as an unsigned-integer (or boolean, when
|
|
5
|
+
bitlen == 1) CArray of the same shape as the parent.
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
Byte-straddling fields are handled by loading up to 8 bytes from
|
|
8
|
+
the parent starting at `byte_offset`, masking with `bit_mask`, and
|
|
9
|
+
shifting by `bit_offset`. Big-endian hosts adjust byte_offset /
|
|
10
|
+
bit_offset so the field selection is invariant to host byte order.
|
|
8
11
|
|
|
9
12
|
---------------------------------------------------------------------------- */
|
|
10
13
|
|
|
@@ -20,6 +23,7 @@ typedef struct {
|
|
|
20
23
|
ca_size_t *dim;
|
|
21
24
|
char *ptr;
|
|
22
25
|
CArray *mask;
|
|
26
|
+
char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
|
|
23
27
|
CArray *parent;
|
|
24
28
|
uint32_t attach;
|
|
25
29
|
uint8_t nosync;
|
|
@@ -27,15 +31,39 @@ typedef struct {
|
|
|
27
31
|
ca_size_t byte_offset;
|
|
28
32
|
ca_size_t bit_offset;
|
|
29
33
|
uint64_t bit_mask;
|
|
34
|
+
ca_size_t bit_start; /* original offset before endian adjustment */
|
|
30
35
|
} CABitfield;
|
|
31
36
|
|
|
37
|
+
static size_t
|
|
38
|
+
ca_bitfield_dsize (const void *ap)
|
|
39
|
+
{
|
|
40
|
+
const CABitfield *ca = (const CABitfield *) ap;
|
|
41
|
+
return sizeof(CABitfield) + ca->ndim * sizeof(ca_size_t);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Pool framework hooks: single ndim-sized tail (dim) in the _pool
|
|
45
|
+
buffer. See ca_array_pool.c for the shared alloc/free discipline. */
|
|
46
|
+
static size_t
|
|
47
|
+
ca_bitfield_pool_bytes (int8_t ndim)
|
|
48
|
+
{
|
|
49
|
+
ca_size_t n = (ndim > 0) ? ndim : 1;
|
|
50
|
+
return (size_t) n * sizeof(ca_size_t);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static void
|
|
54
|
+
ca_bitfield_pool_init (void *ap, int8_t ndim)
|
|
55
|
+
{
|
|
56
|
+
CABitfield *ca = (CABitfield *) ap;
|
|
57
|
+
ca->dim = (ca_size_t *) ca->_pool;
|
|
58
|
+
}
|
|
59
|
+
|
|
32
60
|
const rb_data_type_t cabitfield_data_type = {
|
|
33
|
-
.parent = &
|
|
61
|
+
.parent = &caview_data_type,
|
|
34
62
|
.wrap_struct_name = "CABitfield",
|
|
35
63
|
.function = {
|
|
36
64
|
.dmark = ca_mark,
|
|
37
65
|
.dfree = ca_free,
|
|
38
|
-
.dsize =
|
|
66
|
+
.dsize = ca_bitfield_dsize,
|
|
39
67
|
.dcompact = NULL
|
|
40
68
|
},
|
|
41
69
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
@@ -45,11 +73,6 @@ static int8_t CA_OBJ_BITFIELD;
|
|
|
45
73
|
|
|
46
74
|
static VALUE rb_cCABitfield;
|
|
47
75
|
|
|
48
|
-
/* yard:
|
|
49
|
-
class CABitField < CAVirtual # :nodoc:
|
|
50
|
-
end
|
|
51
|
-
*/
|
|
52
|
-
|
|
53
76
|
static ca_size_t
|
|
54
77
|
bitfield_bitlen (uint64_t bit_mask, ca_size_t bytes)
|
|
55
78
|
{
|
|
@@ -64,153 +87,55 @@ bitfield_bitlen (uint64_t bit_mask, ca_size_t bytes)
|
|
|
64
87
|
return count;
|
|
65
88
|
}
|
|
66
89
|
|
|
90
|
+
/* Generic per-cell fetch: load up to 8 bytes from src starting at
|
|
91
|
+
byte_offset, mask with bit_mask, shift down by bit_offset, and
|
|
92
|
+
write the low `dwrite` bytes of the result to dst.
|
|
93
|
+
*
|
|
94
|
+
* CAREFUL: the read goes through a uint64 with dynamic `span` /
|
|
95
|
+
* `dwrite` deliberately, so that a byte-straddling field (e.g. an
|
|
96
|
+
* 8-bit field starting at bit 4 of a 2-byte parent) sees the full
|
|
97
|
+
* bit_mask. A dbytes-typed cast would silently truncate bit_mask
|
|
98
|
+
* to `1 << (dbytes * 8)`, dropping the upper bits of the field. */
|
|
67
99
|
static void
|
|
68
|
-
bitfield_fetch(char *dst, ca_size_t dbytes,
|
|
100
|
+
bitfield_fetch(char *dst, ca_size_t dbytes,
|
|
69
101
|
char *src, ca_size_t sbytes,
|
|
70
102
|
ca_size_t byte_offset, ca_size_t bit_offset, uint64_t bit_mask,
|
|
71
103
|
ca_size_t elements)
|
|
72
104
|
{
|
|
73
105
|
ca_size_t k;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
#pragma omp parallel for private(r)
|
|
83
|
-
#endif
|
|
84
|
-
for (k=0; k<elements; k++) {
|
|
85
|
-
r = (uint8_t *) (p+k*sbytes);
|
|
86
|
-
*(q+k) = (( *r & mask ) >> bit_offset);
|
|
87
|
-
}
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
case 2: {
|
|
91
|
-
char *p;
|
|
92
|
-
uint16_t *q, *r;
|
|
93
|
-
uint16_t mask = (uint16_t) bit_mask;
|
|
94
|
-
p = src + byte_offset;
|
|
95
|
-
q = (uint16_t *) dst;
|
|
96
|
-
#ifdef _OPENMP
|
|
97
|
-
#pragma omp parallel for private(r)
|
|
98
|
-
#endif
|
|
99
|
-
for (k=0; k<elements; k++) {
|
|
100
|
-
r = (uint16_t *) (p+k*sbytes);
|
|
101
|
-
*(q+k) = (( *r & mask ) >> bit_offset);
|
|
102
|
-
}
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
case 4: {
|
|
106
|
-
char *p;
|
|
107
|
-
uint32_t *q, *r;
|
|
108
|
-
uint32_t mask = (uint32_t) bit_mask;
|
|
109
|
-
p = src + byte_offset;
|
|
110
|
-
q = (uint32_t *) dst;
|
|
111
|
-
#ifdef _OPENMP
|
|
112
|
-
#pragma omp parallel for private(r)
|
|
113
|
-
#endif
|
|
114
|
-
for (k=0; k<elements; k++) {
|
|
115
|
-
r = (uint32_t *) (p+k*sbytes);
|
|
116
|
-
*(q+k) = (( *r & mask ) >> bit_offset);
|
|
117
|
-
}
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
case 8: {
|
|
121
|
-
char *p;
|
|
122
|
-
uint64_t *q, *r;
|
|
123
|
-
uint64_t mask = (uint64_t) bit_mask;
|
|
124
|
-
p = src + byte_offset;
|
|
125
|
-
q = (uint64_t *) dst;
|
|
126
|
-
#ifdef _OPENMP
|
|
127
|
-
#pragma omp parallel for private(r)
|
|
128
|
-
#endif
|
|
129
|
-
for (k=0; k<elements; k++) {
|
|
130
|
-
r = (uint64_t *) (p+k*sbytes);
|
|
131
|
-
*(q+k) = (( *r & mask ) >> bit_offset);
|
|
132
|
-
}
|
|
133
|
-
break;
|
|
134
|
-
}
|
|
135
|
-
default:
|
|
136
|
-
rb_raise(rb_eRuntimeError, "[BUG]");
|
|
106
|
+
ca_size_t span = sbytes - byte_offset;
|
|
107
|
+
if (span > 8) span = 8;
|
|
108
|
+
ca_size_t dwrite = (dbytes > 8) ? 8 : dbytes;
|
|
109
|
+
for (k = 0; k < elements; k++) {
|
|
110
|
+
uint64_t tmp = 0;
|
|
111
|
+
memcpy(&tmp, src + k * sbytes + byte_offset, (size_t) span);
|
|
112
|
+
uint64_t result = (tmp & bit_mask) >> bit_offset;
|
|
113
|
+
memcpy(dst + k * dbytes, &result, (size_t) dwrite);
|
|
137
114
|
}
|
|
138
115
|
}
|
|
139
116
|
|
|
140
117
|
static void
|
|
141
118
|
bitfield_store(char *src, ca_size_t sbytes,
|
|
142
|
-
char *dst, ca_size_t dbytes,
|
|
119
|
+
char *dst, ca_size_t dbytes,
|
|
143
120
|
ca_size_t byte_offset, ca_size_t bit_offset, uint64_t bit_mask,
|
|
144
121
|
ca_size_t elements)
|
|
145
122
|
{
|
|
123
|
+
/* Mirror of bitfield_fetch with scatter direction: reads sbytes
|
|
124
|
+
from src, reads dbytes of dst starting at byte_offset, masks
|
|
125
|
+
the field bits in, writes back. The uint64 read/write span
|
|
126
|
+
preserves bit_mask for byte-straddling fields (see
|
|
127
|
+
bitfield_fetch CAREFUL). */
|
|
146
128
|
ca_size_t k;
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
for (k=0; k<elements; k++) {
|
|
158
|
-
r = p + k;
|
|
159
|
-
*(uint8_t*)(q+k*dbytes) =
|
|
160
|
-
( ((*(uint8_t*)(q+k*dbytes)) & ~mask) | ((*r << bit_offset) & mask) );
|
|
161
|
-
}
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
case 2: {
|
|
165
|
-
char *q;
|
|
166
|
-
uint16_t *p, *r;
|
|
167
|
-
uint16_t mask = (uint16_t) bit_mask;
|
|
168
|
-
p = (uint16_t *) src;
|
|
169
|
-
q = dst + byte_offset;
|
|
170
|
-
#ifdef _OPENMP
|
|
171
|
-
#pragma omp parallel for private(r)
|
|
172
|
-
#endif
|
|
173
|
-
for (k=0; k<elements; k++) {
|
|
174
|
-
r = p + k;
|
|
175
|
-
*(uint16_t*)(q+k*dbytes) =
|
|
176
|
-
( ((*(uint16_t*)(q+k*dbytes)) & ~mask) | ((*r << bit_offset) & mask) );
|
|
177
|
-
}
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
|
-
case 4: {
|
|
181
|
-
char *q;
|
|
182
|
-
uint32_t *p, *r;
|
|
183
|
-
uint32_t mask = (uint32_t) bit_mask;
|
|
184
|
-
p = (uint32_t *) src;
|
|
185
|
-
q = dst + byte_offset;
|
|
186
|
-
#ifdef _OPENMP
|
|
187
|
-
#pragma omp parallel for private(r)
|
|
188
|
-
#endif
|
|
189
|
-
for (k=0; k<elements; k++) {
|
|
190
|
-
r = p + k;
|
|
191
|
-
*(uint32_t*)(q+k*dbytes) =
|
|
192
|
-
( ((*(uint32_t*)(q+k*dbytes)) & ~mask) | ((*r << bit_offset) & mask) );
|
|
193
|
-
}
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
case 8: {
|
|
197
|
-
char *q;
|
|
198
|
-
uint64_t *p, *r;
|
|
199
|
-
uint64_t mask = (uint64_t) bit_mask;
|
|
200
|
-
p = (uint64_t *) src;
|
|
201
|
-
q = dst + byte_offset;
|
|
202
|
-
#ifdef _OPENMP
|
|
203
|
-
#pragma omp parallel for private(r)
|
|
204
|
-
#endif
|
|
205
|
-
for (k=0; k<elements; k++) {
|
|
206
|
-
r = p + k;
|
|
207
|
-
*(uint64_t*)(q+k*dbytes) =
|
|
208
|
-
( ((*(uint64_t*)(q+k*dbytes)) & ~mask) | ((*r << bit_offset) & mask) );
|
|
209
|
-
}
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
default:
|
|
213
|
-
rb_raise(rb_eRuntimeError, "[BUG]");
|
|
129
|
+
ca_size_t span = dbytes - byte_offset;
|
|
130
|
+
if (span > 8) span = 8;
|
|
131
|
+
ca_size_t sread = (sbytes > 8) ? 8 : sbytes;
|
|
132
|
+
for (k = 0; k < elements; k++) {
|
|
133
|
+
uint64_t srcv = 0;
|
|
134
|
+
memcpy(&srcv, src + k * sbytes, (size_t) sread);
|
|
135
|
+
uint64_t tmp = 0;
|
|
136
|
+
memcpy(&tmp, dst + k * dbytes + byte_offset, (size_t) span);
|
|
137
|
+
tmp = (tmp & ~bit_mask) | ((srcv << bit_offset) & bit_mask);
|
|
138
|
+
memcpy(dst + k * dbytes + byte_offset, &tmp, (size_t) span);
|
|
214
139
|
}
|
|
215
140
|
}
|
|
216
141
|
|
|
@@ -230,14 +155,6 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
230
155
|
uint64_t bit_mask;
|
|
231
156
|
ca_size_t i;
|
|
232
157
|
|
|
233
|
-
/* check arguments */
|
|
234
|
-
|
|
235
|
-
/*
|
|
236
|
-
if ( ! ca_is_integer_type(parent) && ! ca_is_float_type(ca) ) {
|
|
237
|
-
rb_raise(rb_eCADataTypeError, "invalid data_type for bitfield");
|
|
238
|
-
}
|
|
239
|
-
*/
|
|
240
|
-
|
|
241
158
|
ndim = parent->ndim;
|
|
242
159
|
bitsize = parent->bytes * 8;
|
|
243
160
|
elements = parent->elements;
|
|
@@ -281,7 +198,7 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
281
198
|
bit_offset = offset % 8;
|
|
282
199
|
bit_mask = 0;
|
|
283
200
|
for (i=0; i<bitlen; i++) {
|
|
284
|
-
bit_mask +=
|
|
201
|
+
bit_mask += 1ULL << ( bit_offset + i );
|
|
285
202
|
}
|
|
286
203
|
if ( byte_offset < 0 ) {
|
|
287
204
|
for (i=0; i<-byte_offset; i++) {
|
|
@@ -296,7 +213,7 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
296
213
|
bit_offset = offset % 8;
|
|
297
214
|
bit_mask = 0;
|
|
298
215
|
for (i=0; i<bitlen; i++) {
|
|
299
|
-
bit_mask +=
|
|
216
|
+
bit_mask += 1ULL << ( bit_offset + i );
|
|
300
217
|
}
|
|
301
218
|
}
|
|
302
219
|
|
|
@@ -308,7 +225,9 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
308
225
|
ca->elements = elements;
|
|
309
226
|
ca->ptr = NULL;
|
|
310
227
|
ca->mask = NULL;
|
|
311
|
-
ca->
|
|
228
|
+
if ( ! ca->_pool ) {
|
|
229
|
+
ca->dim = ALLOC_N(ca_size_t, ndim);
|
|
230
|
+
}
|
|
312
231
|
|
|
313
232
|
ca->parent = parent;
|
|
314
233
|
ca->attach = 0;
|
|
@@ -317,6 +236,7 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
317
236
|
ca->byte_offset = byte_offset;
|
|
318
237
|
ca->bit_offset = bit_offset;
|
|
319
238
|
ca->bit_mask = bit_mask;
|
|
239
|
+
ca->bit_start = offset; /* preserve original offset for clone/copy */
|
|
320
240
|
|
|
321
241
|
memcpy(ca->dim, parent->dim, ndim * sizeof(ca_size_t));
|
|
322
242
|
|
|
@@ -330,7 +250,7 @@ ca_bitfield_setup (CABitfield *ca, CArray *parent,
|
|
|
330
250
|
CABitfield *
|
|
331
251
|
ca_bitfield_new (CArray *parent, ca_size_t offset, ca_size_t bitlen)
|
|
332
252
|
{
|
|
333
|
-
CABitfield *ca =
|
|
253
|
+
CABitfield *ca = (CABitfield *) ca_array_alloc(CA_OBJ_BITFIELD, parent->ndim);
|
|
334
254
|
ca_bitfield_setup(ca, parent, offset, bitlen);
|
|
335
255
|
return ca;
|
|
336
256
|
}
|
|
@@ -341,8 +261,13 @@ free_ca_bitfield (void *ap)
|
|
|
341
261
|
CABitfield *ca = (CABitfield *) ap;
|
|
342
262
|
if ( ca != NULL ) {
|
|
343
263
|
ca_free(ca->mask);
|
|
344
|
-
|
|
345
|
-
|
|
264
|
+
if ( ca->_pool ) {
|
|
265
|
+
ca_array_free(ca); /* dim lives in _pool */
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
xfree(ca->dim);
|
|
269
|
+
xfree(ca);
|
|
270
|
+
}
|
|
346
271
|
}
|
|
347
272
|
}
|
|
348
273
|
|
|
@@ -356,59 +281,130 @@ static void *
|
|
|
356
281
|
ca_bitfield_func_clone (void *ap)
|
|
357
282
|
{
|
|
358
283
|
CABitfield *ca = (CABitfield *) ap;
|
|
359
|
-
return ca_bitfield_new(ca->parent,
|
|
360
|
-
|
|
284
|
+
return ca_bitfield_new(ca->parent,
|
|
285
|
+
ca->bit_start,
|
|
361
286
|
bitfield_bitlen(ca->bit_mask, ca->bytes));
|
|
362
287
|
}
|
|
363
288
|
|
|
364
|
-
|
|
365
|
-
|
|
289
|
+
/* Per-cell get/put: fetch the parent cell into a scratch buffer,
|
|
290
|
+
then extract or splice the bit field with bitfield_fetch /
|
|
291
|
+
bitfield_store on a single element. */
|
|
292
|
+
static void
|
|
293
|
+
ca_bitfield_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
366
294
|
{
|
|
367
295
|
CABitfield *ca = (CABitfield *) ap;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
296
|
+
char *v = xmalloc(ca->parent->bytes);
|
|
297
|
+
ca_fetch_index(ca->parent, idx, v);
|
|
298
|
+
if ( dir == CA_XFER_GET ) {
|
|
299
|
+
memset(data, 0, ca->bytes);
|
|
300
|
+
bitfield_fetch(data, ca->bytes, v, ca->parent->bytes,
|
|
301
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
|
|
371
302
|
}
|
|
372
303
|
else {
|
|
373
|
-
|
|
304
|
+
bitfield_store(data, ca->bytes, v, ca->parent->bytes,
|
|
305
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
|
|
306
|
+
ca_store_index(ca->parent, idx, v);
|
|
374
307
|
}
|
|
308
|
+
xfree(v);
|
|
375
309
|
}
|
|
376
310
|
|
|
377
|
-
|
|
378
|
-
|
|
311
|
+
/* Batched gather / scatter. CABitfield is a 1:1 view (each parent
|
|
312
|
+
cell carries exactly one field position) so the incoming view
|
|
313
|
+
addresses are also parent addresses. GET gathers parent cells in
|
|
314
|
+
one call then extracts bits; PUT reads, splices field bits, then
|
|
315
|
+
writes back. Each cell touches its own bits, so there is no
|
|
316
|
+
shared-cell hazard between concurrent scatters.
|
|
317
|
+
|
|
318
|
+
Fast path: when `addrs` covers the whole view sequentially and
|
|
319
|
+
the effective attached parent (via identity compose-fold) is
|
|
320
|
+
live, drive bitfield_fetch / bitfield_store directly against
|
|
321
|
+
parent->ptr — no scratch, no double xfer_addrs round-trip. */
|
|
322
|
+
static void
|
|
323
|
+
ca_bitfield_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
324
|
+
void *data, int dir)
|
|
379
325
|
{
|
|
380
326
|
CABitfield *ca = (CABitfield *) ap;
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
327
|
+
CArray *parent = ca->parent;
|
|
328
|
+
char *d = (char *) data;
|
|
329
|
+
ca_size_t pbytes = parent->bytes;
|
|
330
|
+
ca_size_t i, base;
|
|
331
|
+
char *v;
|
|
332
|
+
volatile VALUE holder;
|
|
333
|
+
|
|
334
|
+
if ( n == ca->elements
|
|
335
|
+
&& ca_xfer_addrs_is_sequential_run(n, addrs, &base) && base == 0 ) {
|
|
336
|
+
CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
|
|
337
|
+
if ( eff_parent->ptr
|
|
338
|
+
&& eff_parent->elements == parent->elements
|
|
339
|
+
&& eff_parent->bytes == parent->bytes ) {
|
|
340
|
+
if ( dir == CA_XFER_GET ) {
|
|
341
|
+
/* Zero the output buffer, then bulk-extract n field values
|
|
342
|
+
directly from the attached parent. */
|
|
343
|
+
memset(d, 0, n * ca->bytes);
|
|
344
|
+
bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
345
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
346
|
+
} else {
|
|
347
|
+
/* Bulk RMW directly against parent memory (bitfield_store
|
|
348
|
+
preserves non-field bits). */
|
|
349
|
+
bitfield_store(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
350
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
v = ALLOCV_N(char, holder, n * pbytes);
|
|
357
|
+
if ( dir == CA_XFER_GET ) {
|
|
358
|
+
ca_xfer_addrs(parent, n, addrs, v, CA_XFER_GET);
|
|
359
|
+
for (i = 0; i < n; i++) {
|
|
360
|
+
memset(d + i * ca->bytes, 0, ca->bytes);
|
|
361
|
+
bitfield_fetch(d + i * ca->bytes, ca->bytes, v + i * pbytes, pbytes,
|
|
362
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
|
|
363
|
+
}
|
|
384
364
|
}
|
|
385
365
|
else {
|
|
386
|
-
|
|
366
|
+
ca_xfer_addrs(parent, n, addrs, v, CA_XFER_GET); /* RMW: read first */
|
|
367
|
+
for (i = 0; i < n; i++) {
|
|
368
|
+
bitfield_store(d + i * ca->bytes, ca->bytes, v + i * pbytes, pbytes,
|
|
369
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, 1);
|
|
370
|
+
}
|
|
371
|
+
ca_xfer_addrs(parent, n, addrs, v, CA_XFER_PUT);
|
|
387
372
|
}
|
|
373
|
+
ALLOCV_END(holder);
|
|
388
374
|
}
|
|
389
375
|
|
|
376
|
+
/* CABitfield is a per-cell bit transform with no axis structure to
|
|
377
|
+
preserve, so the incoming region reduces to a flat address list
|
|
378
|
+
over the view. We materialise that list from starts / counts /
|
|
379
|
+
strides and delegate to the view's own xfer_addrs, which handles
|
|
380
|
+
the gather + bit RMW + batched parent delivery. */
|
|
390
381
|
static void
|
|
391
|
-
|
|
382
|
+
ca_bitfield_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
383
|
+
ca_size_t *strides, void *data, int dir)
|
|
392
384
|
{
|
|
393
385
|
CABitfield *ca = (CABitfield *) ap;
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
386
|
+
int8_t ndim = ca->ndim;
|
|
387
|
+
ca_size_t native[CA_RANK_MAX], idx[CA_RANK_MAX];
|
|
388
|
+
ca_size_t *vaddrs;
|
|
389
|
+
ca_size_t base = 0, n = 1, i, s;
|
|
390
|
+
int8_t k;
|
|
391
|
+
volatile VALUE holder;
|
|
392
|
+
|
|
393
|
+
s = ca->bytes;
|
|
394
|
+
for (k = ndim - 1; k >= 0; k--) { native[k] = s; s *= ca->dim[k]; }
|
|
395
|
+
for (k = 0; k < ndim; k++) { base += starts[k] * native[k]; n *= counts[k]; }
|
|
396
|
+
|
|
397
|
+
vaddrs = ALLOCV_N(ca_size_t, holder, n);
|
|
398
|
+
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
399
|
+
for (i = 0; i < n; i++) {
|
|
400
|
+
ca_size_t off = base;
|
|
401
|
+
for (k = 0; k < ndim; k++) off += idx[k] * strides[k];
|
|
402
|
+
vaddrs[i] = off / ca->bytes;
|
|
403
|
+
k = ndim - 1;
|
|
404
|
+
while (k >= 0) { if (++idx[k] < counts[k]) break; idx[k] = 0; k--; }
|
|
405
|
+
}
|
|
406
|
+
ca_xfer_addrs(ca, n, vaddrs, data, dir);
|
|
407
|
+
ALLOCV_END(holder);
|
|
412
408
|
}
|
|
413
409
|
|
|
414
410
|
static void
|
|
@@ -416,18 +412,15 @@ ca_bitfield_func_allocate (void *ap)
|
|
|
416
412
|
{
|
|
417
413
|
CABitfield *ca = (CABitfield *) ap;
|
|
418
414
|
ca_attach(ca->parent);
|
|
419
|
-
|
|
420
|
-
ca->ptr = malloc_with_check(ca_length(ca));
|
|
415
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
421
416
|
}
|
|
422
417
|
|
|
423
418
|
static void
|
|
424
419
|
ca_bitfield_func_attach (void *ap)
|
|
425
420
|
{
|
|
426
|
-
void ca_bitfield_attach (CABitfield *cb);
|
|
427
421
|
CABitfield *ca = (CABitfield *) ap;
|
|
428
422
|
ca_attach(ca->parent);
|
|
429
|
-
|
|
430
|
-
ca->ptr = malloc_with_check(ca_length(ca));
|
|
423
|
+
ca->ptr = xmalloc(ca_length(ca));
|
|
431
424
|
ca_bitfield_attach(ca);
|
|
432
425
|
}
|
|
433
426
|
|
|
@@ -443,44 +436,110 @@ static void
|
|
|
443
436
|
ca_bitfield_func_detach (void *ap)
|
|
444
437
|
{
|
|
445
438
|
CABitfield *ca = (CABitfield *) ap;
|
|
446
|
-
|
|
439
|
+
xfree(ca->ptr);
|
|
447
440
|
ca->ptr = NULL;
|
|
448
441
|
ca_detach(ca->parent);
|
|
449
442
|
}
|
|
450
443
|
|
|
444
|
+
/* Whole-view transfer. Fast path: drive bitfield_fetch /
|
|
445
|
+
bitfield_store directly against the effective attached parent
|
|
446
|
+
(via identity compose-fold), bypassing the addrs[] allocation
|
|
447
|
+
and sequential-run scan that xfer_addrs would perform.
|
|
448
|
+
|
|
449
|
+
Cold parent falls back to a scratch 2-pass (gather parent into a
|
|
450
|
+
local buffer via xfer_stride, apply the bitfield primitive, and
|
|
451
|
+
for PUT scatter the buffer back). Deliberately does not call
|
|
452
|
+
ca_attach(parent) — that would re-introduce the silent transitive
|
|
453
|
+
attach the fast path exists to avoid. */
|
|
451
454
|
static void
|
|
452
|
-
|
|
455
|
+
ca_bitfield_func_xfer_all (void *ap, void *data, int dir)
|
|
453
456
|
{
|
|
454
457
|
CABitfield *ca = (CABitfield *) ap;
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
458
|
+
CArray *parent = ca->parent;
|
|
459
|
+
ca_size_t pbytes = parent->bytes;
|
|
460
|
+
ca_size_t n = ca->elements;
|
|
461
|
+
char *d = (char *) data;
|
|
462
|
+
CArray *eff_parent = ca_resolve_attached_root_via_identity(parent);
|
|
463
|
+
|
|
464
|
+
if ( eff_parent->ptr
|
|
465
|
+
&& eff_parent->elements == parent->elements
|
|
466
|
+
&& eff_parent->bytes == parent->bytes ) {
|
|
467
|
+
if ( dir == CA_XFER_GET ) {
|
|
468
|
+
memset(d, 0, n * ca->bytes);
|
|
469
|
+
bitfield_fetch(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
470
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
471
|
+
} else {
|
|
472
|
+
bitfield_store(d, ca->bytes, eff_parent->ptr, pbytes,
|
|
473
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
474
|
+
}
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* Cold-parent fallback: materialise into scratch via xfer_stride
|
|
479
|
+
(no ca_attach(parent)), apply the bitfield primitive, and for
|
|
480
|
+
PUT scatter back. */
|
|
481
|
+
{
|
|
482
|
+
volatile VALUE holder;
|
|
483
|
+
char *scratch = ALLOCV_N(char, holder, parent->elements * pbytes);
|
|
484
|
+
ca_size_t pstarts[CA_RANK_MAX];
|
|
485
|
+
ca_size_t pnative[CA_RANK_MAX];
|
|
486
|
+
ca_size_t s = pbytes;
|
|
487
|
+
int8_t k;
|
|
488
|
+
for ( k = parent->ndim - 1; k >= 0; k-- ) { pnative[k] = s; s *= parent->dim[k]; }
|
|
489
|
+
for ( k = 0; k < parent->ndim; k++ ) pstarts[k] = 0;
|
|
490
|
+
if ( dir == CA_XFER_GET ) {
|
|
491
|
+
ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_GET);
|
|
492
|
+
memset(d, 0, n * ca->bytes);
|
|
493
|
+
bitfield_fetch(d, ca->bytes, scratch, pbytes,
|
|
494
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
495
|
+
} else {
|
|
496
|
+
/* CAREFUL: gather parent into scratch before splicing so the
|
|
497
|
+
non-field bits are preserved across the RMW. */
|
|
498
|
+
ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_GET);
|
|
499
|
+
bitfield_store(d, ca->bytes, scratch, pbytes,
|
|
500
|
+
ca->byte_offset, ca->bit_offset, ca->bit_mask, n);
|
|
501
|
+
ca_xfer_stride(parent, pstarts, parent->dim, pnative, scratch, CA_XFER_PUT);
|
|
502
|
+
}
|
|
503
|
+
ALLOCV_END(holder);
|
|
504
|
+
}
|
|
461
505
|
}
|
|
462
506
|
|
|
463
507
|
static void
|
|
464
|
-
|
|
508
|
+
ca_bitfield_func_fill_data (void *ap, void *ptr)
|
|
465
509
|
{
|
|
466
510
|
CABitfield *ca = (CABitfield *) ap;
|
|
467
|
-
char *ptr0 = ca->ptr;
|
|
468
511
|
ca_attach(ca->parent);
|
|
469
|
-
ca
|
|
470
|
-
ca_bitfield_sync(ca);
|
|
471
|
-
ca->ptr = ptr0;
|
|
512
|
+
ca_bitfield_fill(ca, ptr);
|
|
472
513
|
ca_sync(ca->parent);
|
|
473
514
|
ca_detach(ca->parent);
|
|
474
515
|
}
|
|
475
516
|
|
|
517
|
+
|
|
518
|
+
/* A fill here is a read-modify-write: the cell also carries bits this view
|
|
519
|
+
does not own, so there is nothing to hand down as a region. The batched
|
|
520
|
+
address slot already reads and writes a run in one call each; broadcasting
|
|
521
|
+
the value into it is all that is left, and it saves the descent that a
|
|
522
|
+
per-cell walk would pay for every cell. */
|
|
476
523
|
static void
|
|
477
|
-
|
|
524
|
+
ca_bitfield_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
|
|
478
525
|
{
|
|
479
526
|
CABitfield *ca = (CABitfield *) ap;
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
527
|
+
volatile VALUE holder;
|
|
528
|
+
char *buf = ALLOCV_N(char, holder, (size_t) n * ca->bytes);
|
|
529
|
+
ca_size_t i;
|
|
530
|
+
|
|
531
|
+
for ( i = 0; i < n; i++ ) {
|
|
532
|
+
memcpy(buf + i * ca->bytes, ptr, ca->bytes);
|
|
533
|
+
}
|
|
534
|
+
ca_bitfield_func_xfer_addrs(ca, n, addrs, buf, CA_XFER_PUT);
|
|
535
|
+
ALLOCV_END(holder);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
static void
|
|
539
|
+
ca_bitfield_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
|
|
540
|
+
ca_size_t *counts, ca_size_t *steps, void *ptr)
|
|
541
|
+
{
|
|
542
|
+
ca_fill_stride_via_addrs(ap, base, ndim, counts, steps, ptr);
|
|
484
543
|
}
|
|
485
544
|
|
|
486
545
|
static void
|
|
@@ -499,23 +558,22 @@ ca_bitfield_func_create_mask (void *ap)
|
|
|
499
558
|
|
|
500
559
|
ca_operation_function_t ca_bitfield_func = {
|
|
501
560
|
-1, /* CA_OBJ_BITFIELD */
|
|
502
|
-
|
|
561
|
+
CA_VIEW_ARRAY,
|
|
503
562
|
free_ca_bitfield,
|
|
504
563
|
ca_bitfield_func_clone,
|
|
505
|
-
ca_bitfield_func_ptr_at_addr,
|
|
506
|
-
ca_bitfield_func_ptr_at_index,
|
|
507
|
-
NULL,
|
|
508
|
-
ca_bitfield_func_fetch_index,
|
|
509
|
-
NULL,
|
|
510
|
-
ca_bitfield_func_store_index,
|
|
511
564
|
ca_bitfield_func_allocate,
|
|
512
565
|
ca_bitfield_func_attach,
|
|
513
566
|
ca_bitfield_func_sync,
|
|
514
567
|
ca_bitfield_func_detach,
|
|
515
|
-
ca_bitfield_func_copy_data,
|
|
516
|
-
ca_bitfield_func_sync_data,
|
|
517
568
|
ca_bitfield_func_fill_data,
|
|
518
569
|
ca_bitfield_func_create_mask,
|
|
570
|
+
ca_bitfield_func_xfer_index,
|
|
571
|
+
ca_bitfield_func_xfer_addrs,
|
|
572
|
+
NULL, /* fold_stride: never fold — per-cell bit transform */
|
|
573
|
+
ca_bitfield_func_xfer_stride,
|
|
574
|
+
ca_bitfield_func_xfer_all,
|
|
575
|
+
.fill_addrs = ca_bitfield_func_fill_addrs,
|
|
576
|
+
.fill_stride = ca_bitfield_func_fill_stride,
|
|
519
577
|
};
|
|
520
578
|
|
|
521
579
|
/* ------------------------------------------------------------------- */
|
|
@@ -569,11 +627,6 @@ rb_ca_bitfield_new (VALUE cary, ca_size_t offset, ca_size_t bitlen)
|
|
|
569
627
|
return obj;
|
|
570
628
|
}
|
|
571
629
|
|
|
572
|
-
/* @overload bitfield (range, type)
|
|
573
|
-
|
|
574
|
-
[TBD]
|
|
575
|
-
*/
|
|
576
|
-
|
|
577
630
|
VALUE
|
|
578
631
|
rb_ca_bitfield (int argc, VALUE *argv, VALUE self)
|
|
579
632
|
{
|
|
@@ -616,22 +669,29 @@ rb_ca_bitfield_initialize_copy (VALUE self, VALUE other)
|
|
|
616
669
|
TypedData_Get_Struct(self, CABitfield, &cabitfield_data_type, ca);
|
|
617
670
|
TypedData_Get_Struct(other, CABitfield, &cabitfield_data_type, cs);
|
|
618
671
|
|
|
619
|
-
|
|
620
|
-
|
|
672
|
+
if ( ca_func[CA_OBJ_BITFIELD].pool_init ) {
|
|
673
|
+
ca_array_pool_alloc(ca, CA_OBJ_BITFIELD, cs->parent->ndim);
|
|
674
|
+
}
|
|
675
|
+
ca_bitfield_setup(ca, cs->parent,
|
|
676
|
+
cs->bit_start,
|
|
621
677
|
bitfield_bitlen(cs->bit_mask, cs->bytes));
|
|
622
678
|
|
|
623
679
|
return self;
|
|
624
680
|
}
|
|
625
681
|
|
|
626
682
|
void
|
|
627
|
-
Init_ca_obj_bitfield ()
|
|
683
|
+
Init_ca_obj_bitfield (void)
|
|
628
684
|
{
|
|
629
|
-
rb_cCABitfield = rb_define_class("CABitfield",
|
|
685
|
+
rb_cCABitfield = rb_define_class("CABitfield", rb_cCAView);
|
|
686
|
+
|
|
687
|
+
ca_bitfield_func.struct_size = sizeof(CABitfield);
|
|
688
|
+
ca_bitfield_func.pool_bytes = ca_bitfield_pool_bytes;
|
|
689
|
+
ca_bitfield_func.pool_init = ca_bitfield_pool_init;
|
|
630
690
|
|
|
631
|
-
CA_OBJ_BITFIELD = ca_install_obj_type(rb_cCABitfield,
|
|
632
|
-
&cabitfield_data_type,
|
|
691
|
+
CA_OBJ_BITFIELD = ca_install_obj_type(rb_cCABitfield,
|
|
692
|
+
&cabitfield_data_type,
|
|
633
693
|
rb_cCArrayMask,
|
|
634
|
-
&
|
|
694
|
+
&carray_mask_data_type, &ca_bitfield_func, sizeof(ca_bitfield_func));
|
|
635
695
|
rb_define_const(rb_cObject, "CA_OBJ_BITFIELD", INT2NUM(CA_OBJ_BITFIELD));
|
|
636
696
|
|
|
637
697
|
rb_define_method(rb_cCArray, "bitfield", rb_ca_bitfield, -1);
|