carray 3.0.3 → 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 +264 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +1 -6
- data/ext/ca_axis_group.c +27 -27
- data/ext/ca_binop_dispatch.c +1 -29
- data/ext/ca_binop_dispatch.h +0 -1
- data/ext/ca_categorical_iterator.c +205 -134
- data/ext/ca_compare.c +7 -18
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1234 -1994
- data/ext/ca_kernel_iterator.h +391 -437
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +96 -39
- data/ext/ca_obj_bincmp.c +24 -21
- data/ext/ca_obj_binop.c +15 -26
- data/ext/ca_obj_bitarray.c +3 -2
- data/ext/ca_obj_bitfield.c +5 -6
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +5 -6
- data/ext/ca_obj_const_string.c +173 -19
- data/ext/ca_obj_face.c +238 -57
- data/ext/ca_obj_face.h +19 -0
- data/ext/ca_obj_fake.c +15 -29
- data/ext/ca_obj_farray.c +6 -3
- data/ext/ca_obj_field.c +17 -5
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +406 -132
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +67 -57
- data/ext/ca_obj_object.c +157 -51
- data/ext/ca_obj_record.c +12 -7
- data/ext/ca_obj_reduce.c +13 -8
- data/ext/ca_obj_refer.c +25 -27
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +6 -5
- data/ext/ca_obj_select.c +14 -9
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +11 -1
- data/ext/ca_obj_stack.c +179 -34
- data/ext/ca_obj_stride.c +162 -115
- data/ext/ca_obj_string.c +71 -4
- data/ext/ca_obj_tile.c +6 -5
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +5 -3
- data/ext/ca_obj_triop.c +23 -32
- data/ext/ca_obj_window.c +190 -26
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +181 -75
- data/ext/carray_access.c +184 -96
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +89 -6
- data/ext/carray_bincount.c +10 -8
- data/ext/carray_broadcast.c +13 -8
- data/ext/carray_build_flags.h +3 -0
- data/ext/carray_call_cfunc.c +108 -0
- data/ext/carray_cast.c +142 -24
- data/ext/carray_cast_func.rb +46 -6
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +16 -7
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +147 -55
- data/ext/carray_count.c +50 -20
- data/ext/carray_element.c +76 -33
- data/ext/carray_factorize.c +118 -64
- data/ext/carray_generate.c +191 -50
- data/ext/carray_histogram.c +62 -17
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +336 -29
- data/ext/carray_kernels_bincmp.c +4453 -0
- data/ext/carray_kernels_binop.c +11368 -0
- data/ext/carray_kernels_init.c +1734 -0
- data/ext/carray_kernels_moncmp.c +2104 -0
- data/ext/carray_kernels_monop.c +18369 -0
- data/ext/carray_kernels_reduce_aggregate.c +23818 -0
- data/ext/carray_kernels_reduce_boolean.c +406 -0
- data/ext/carray_kernels_reduce_cumulative.c +10086 -0
- data/ext/carray_kernels_reduce_extreme.c +17634 -0
- data/ext/carray_kernels_reduce_variance.c +3849 -0
- data/ext/carray_kernels_scan.c +4302 -0
- data/ext/carray_kernels_search.c +33829 -0
- data/ext/carray_kernels_sort.c +10906 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +292 -72
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +124 -47
- data/ext/carray_order.c +384 -76
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +67 -13
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +63 -38
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +91 -28
- data/ext/carray_sort.c +35 -35
- data/ext/carray_struct.c +19 -18
- data/ext/carray_test.c +26 -5
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +246 -45
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +198 -240
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +126 -22
- data/lib/carray/autoload_carray.rb +8 -31
- data/lib/carray/autoload_method_extension.rb +14 -5
- data/lib/carray/axis_group.rb +255 -106
- data/lib/carray/basics.rb +78 -10
- data/lib/carray/bincount_nd.rb +12 -2
- data/lib/carray/block_iterator.rb +126 -23
- data/lib/carray/boolean_reduce.rb +17 -17
- data/lib/carray/categorical.rb +165 -43
- data/lib/carray/categorical_iterator.rb +130 -27
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +14 -5
- 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/convert.rb +69 -0
- data/lib/carray/frame/csv_parser.rb +111 -17
- data/lib/carray/frame/describe.rb +3 -2
- data/lib/carray/frame/frame.rb +246 -21
- data/lib/carray/frame/group.rb +510 -95
- data/lib/carray/frame/io.rb +115 -28
- data/lib/carray/frame/join.rb +312 -51
- data/lib/carray/frame/records.rb +83 -7
- data/lib/carray/frame/reshape.rb +42 -35
- data/lib/carray/frame/sort.rb +7 -19
- data/lib/carray/frame/verbs.rb +188 -48
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +2 -0
- data/lib/carray/fuse_source.rb +11 -4
- data/lib/carray/fusion.rb +40 -16
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +31 -8
- data/lib/carray/iterator.rb +85 -7
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +182 -183
- data/lib/carray/mask_gap_fill.rb +63 -57
- data/lib/carray/meld_reduce.rb +12 -14
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +16 -0
- data/lib/carray/methods/bit_string.rb +1 -1
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +3 -1
- data/lib/carray/methods/gather_nd.rb +14 -5
- data/lib/carray/methods/insert_block.rb +2 -2
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +53 -36
- data/lib/carray/methods/join.rb +1 -6
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +47 -51
- data/lib/carray/methods/mode.rb +1 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/resize.rb +3 -3
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +3 -3
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +53 -8
- data/lib/carray/segment_iterator.rb +313 -82
- data/lib/carray/serialize.rb +24 -10
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +8 -1
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +19 -8
- data/lib/carray/time.rb +726 -104
- data/lib/carray/window_iterator.rb +122 -16
- data/lib/carray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +4 -0
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +2 -1
- data/yard-stubs/ca_obj_roll.rb +2 -2
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_cast.rb +10 -0
- data/yard-stubs/carray_conversion.rb +2 -1
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +26 -2
- data/yard-stubs/carray_math.rb +27 -1
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +29 -18
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +14 -9
- data/yard-stubs/carray_slab.rb +9 -2
- data/yard-stubs/carray_sort.rb +6 -5
- data/yard-stubs/carray_test.rb +5 -3
- metadata +25 -3
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/ext/ca_obj_window.c
CHANGED
|
@@ -268,10 +268,19 @@ ca_window_compose_fold (void *win_ap,
|
|
|
268
268
|
for the window-over-parent mapping (ca_window_compose_fold) and composes
|
|
269
269
|
f through it (ca_stride_compose_through). Declines (returns 0) when the
|
|
270
270
|
window is not interior-only, making the window the fold boundary. */
|
|
271
|
+
static void ca_window_mask_current (CAWindow *ca);
|
|
272
|
+
static int ca_window_mask_reads_standin (CAWindow *ca);
|
|
273
|
+
|
|
271
274
|
static int
|
|
272
275
|
ca_window_func_fold_stride (void *ap, ca_fold_t *f, void **next_parent)
|
|
273
276
|
{
|
|
274
277
|
CAWindow *w = (CAWindow *) ap;
|
|
278
|
+
ca_window_mask_current(w);
|
|
279
|
+
/* A write folded through to a stand-in would bypass the settle in this
|
|
280
|
+
window's write slots. */
|
|
281
|
+
if ( ca_window_mask_reads_standin(w) ) {
|
|
282
|
+
return 0;
|
|
283
|
+
}
|
|
275
284
|
ca_size_t synth_strides[CA_RANK_MAX];
|
|
276
285
|
ca_size_t synth_base;
|
|
277
286
|
ca_size_t *synth_dim;
|
|
@@ -329,6 +338,7 @@ ca_window_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
329
338
|
{
|
|
330
339
|
if ( ca_region_is_empty(((CArray *) ap)->ndim, counts) ) return;
|
|
331
340
|
CAWindow *w = (CAWindow *) ap;
|
|
341
|
+
ca_window_mask_current(w);
|
|
332
342
|
CArray *parent = w->parent;
|
|
333
343
|
int8_t ndim = w->ndim;
|
|
334
344
|
int8_t inner = ndim - 1;
|
|
@@ -369,6 +379,7 @@ ca_window_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
369
379
|
ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
|
|
370
380
|
for (k = 0; k < ndim; k++) base += starts[k] * wnative[k];
|
|
371
381
|
for (k = 0; k < ndim; k++) idx[k] = 0;
|
|
382
|
+
/* empty: the slot returns on an empty region at its entry */
|
|
372
383
|
while (1) {
|
|
373
384
|
ca_size_t woff = base, widx[CA_RANK_MAX];
|
|
374
385
|
for (k = 0; k < ndim; k++) woff += idx[k] * strides[k];
|
|
@@ -672,7 +683,6 @@ ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
672
683
|
ca_size_t *dim;
|
|
673
684
|
ca_size_t bytes, elements;
|
|
674
685
|
int i;
|
|
675
|
-
int any_mask;
|
|
676
686
|
|
|
677
687
|
data_type = parent->data_type;
|
|
678
688
|
ndim = parent->ndim;
|
|
@@ -688,6 +698,27 @@ ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
688
698
|
}
|
|
689
699
|
elements = ca_shape_elements(ndim, count, bytes);
|
|
690
700
|
|
|
701
|
+
/* Under "ruby" or "strict" an index outside the parent raises. The
|
|
702
|
+
parent's shape is fixed, so a window that reaches outside it would raise
|
|
703
|
+
on every whole read or write, and a write would have changed the cells
|
|
704
|
+
before the one that raised. It is refused here instead. */
|
|
705
|
+
for (i=0; i<ndim; i++) {
|
|
706
|
+
ca_size_t lo, hi, size = dim[i];
|
|
707
|
+
if ( count[i] == 0 ) {
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
lo = start[i];
|
|
711
|
+
hi = start[i] + count[i] - 1;
|
|
712
|
+
if ( bounds[i] == CA_BOUNDS_STRICT ) {
|
|
713
|
+
if ( lo < 0 ) ca_index_out_of_range(lo, size, "index");
|
|
714
|
+
if ( hi >= size ) ca_index_out_of_range(hi, size, "index");
|
|
715
|
+
}
|
|
716
|
+
else if ( bounds[i] == CA_BOUNDS_RUBY ) {
|
|
717
|
+
if ( lo < -size ) ca_index_out_of_range(lo, size, "index");
|
|
718
|
+
if ( hi >= size ) ca_index_out_of_range(hi, size, "index");
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
691
722
|
/* ca == NULL asks for the checks above only, so that a constructor can
|
|
692
723
|
run them before it allocates. */
|
|
693
724
|
if ( ca == NULL ) {
|
|
@@ -707,6 +738,8 @@ ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
707
738
|
ca->parent = parent;
|
|
708
739
|
ca->attach = 0;
|
|
709
740
|
ca->nosync = 0;
|
|
741
|
+
ca->mask_standin = NULL;
|
|
742
|
+
ca->mask_owner = NULL;
|
|
710
743
|
/* Pool path: bounds/start/count/size0/embed_* are already wired into
|
|
711
744
|
ca->_pool by ca_window_pool_init. Legacy path: ALLOC_N each. `fill`
|
|
712
745
|
is bytes-sized (not ndim) so it stays on its own ALLOC_N in both
|
|
@@ -747,19 +780,25 @@ ca_window_setup (CAWindow *ca, CArray *parent,
|
|
|
747
780
|
}
|
|
748
781
|
}
|
|
749
782
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
783
|
+
return 0;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/* A window with an axis of MASK bounds has a mask of its own. Making it
|
|
787
|
+
asks the parent for its mask, which can raise (a CAObject answers in
|
|
788
|
+
Ruby), so the constructor makes it after the setup under
|
|
789
|
+
ca_fill_or_free; see ca_view_inherit_mask. */
|
|
790
|
+
VALUE
|
|
791
|
+
ca_window_create_bounds_mask (VALUE view)
|
|
792
|
+
{
|
|
793
|
+
CAWindow *ca = (CAWindow *) view;
|
|
794
|
+
int8_t i;
|
|
795
|
+
for (i = 0; i < ca->ndim; i++) {
|
|
753
796
|
if ( ca->bounds[i] == CA_BOUNDS_MASK ) {
|
|
754
|
-
|
|
797
|
+
ca_create_mask((CArray *) ca);
|
|
755
798
|
break;
|
|
756
799
|
}
|
|
757
800
|
}
|
|
758
|
-
|
|
759
|
-
ca_create_mask(ca);
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
return 0;
|
|
801
|
+
return Qnil;
|
|
763
802
|
}
|
|
764
803
|
|
|
765
804
|
CAWindow *
|
|
@@ -770,6 +809,7 @@ ca_window_new (CArray *parent,
|
|
|
770
809
|
ca_window_setup(NULL, parent, start, count, bounds, fill);
|
|
771
810
|
ca = (CAWindow *) ca_array_alloc(CA_OBJ_WINDOW, parent->ndim);
|
|
772
811
|
ca_window_setup(ca, parent, start, count, bounds, fill);
|
|
812
|
+
ca_fill_or_free((CArray *) ca, ca_window_create_bounds_mask, (VALUE) ca);
|
|
773
813
|
return ca;
|
|
774
814
|
}
|
|
775
815
|
|
|
@@ -779,6 +819,7 @@ free_ca_window (void *ap)
|
|
|
779
819
|
CAWindow *ca = (CAWindow *) ap;
|
|
780
820
|
if ( ca != NULL ) {
|
|
781
821
|
ca_free(ca->mask);
|
|
822
|
+
ca_free(ca->mask_standin);
|
|
782
823
|
xfree(ca->fill); /* always separate (bytes-sized) */
|
|
783
824
|
if ( ca->_pool ) {
|
|
784
825
|
/* bounds/start/count/size0/embed_* all live in ca->_pool. */
|
|
@@ -818,7 +859,39 @@ static void *
|
|
|
818
859
|
ca_window_func_clone (void *ap)
|
|
819
860
|
{
|
|
820
861
|
CAWindow *ca = (CAWindow *) ap;
|
|
821
|
-
|
|
862
|
+
CAWindow *cp = ca_window_new(ca->parent, ca->start, ca->count, ca->bounds,
|
|
863
|
+
ca->fill);
|
|
864
|
+
cp->mask_owner = ca->mask_owner;
|
|
865
|
+
return cp;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/* A mask window over its owner's stand-in (ca_mask_standin_current): what
|
|
869
|
+
it reads from now on. */
|
|
870
|
+
static void
|
|
871
|
+
ca_window_mask_current (CAWindow *ca)
|
|
872
|
+
{
|
|
873
|
+
CAWindow *o = (CAWindow *) ca->mask_owner;
|
|
874
|
+
if ( o != NULL ) {
|
|
875
|
+
ca->parent = ca_mask_standin_current((CArray *) ca, ca->parent, o->parent,
|
|
876
|
+
o->mask_standin);
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
static int
|
|
881
|
+
ca_window_mask_reads_standin (CAWindow *ca)
|
|
882
|
+
{
|
|
883
|
+
CAWindow *o = (CAWindow *) ca->mask_owner;
|
|
884
|
+
return o != NULL && o->mask_standin != NULL && ca->parent == o->mask_standin;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/* After a write that may have put a true into the stand-in: it goes on to
|
|
888
|
+
the parent's mask. */
|
|
889
|
+
static void
|
|
890
|
+
ca_window_mask_settle (CAWindow *ca)
|
|
891
|
+
{
|
|
892
|
+
if ( ca_window_mask_reads_standin(ca) ) {
|
|
893
|
+
ca_mask_standin_settle(((CAWindow *) ca->mask_owner)->parent, ca->parent);
|
|
894
|
+
}
|
|
822
895
|
}
|
|
823
896
|
|
|
824
897
|
/* Per-cell access. GET and PUT share the bound-normalised index walk; an OOB
|
|
@@ -828,6 +901,7 @@ static void
|
|
|
828
901
|
ca_window_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
829
902
|
{
|
|
830
903
|
CAWindow *ca = (CAWindow *) ap;
|
|
904
|
+
ca_window_mask_current(ca);
|
|
831
905
|
ca_size_t *start = ca->start;
|
|
832
906
|
ca_size_t *size0 = ca->size0;
|
|
833
907
|
ca_size_t idx0[CA_RANK_MAX];
|
|
@@ -856,6 +930,7 @@ ca_window_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
856
930
|
void *data, int dir)
|
|
857
931
|
{
|
|
858
932
|
CAWindow *ca = (CAWindow *) ap;
|
|
933
|
+
ca_window_mask_current(ca);
|
|
859
934
|
ca_size_t *start = ca->start;
|
|
860
935
|
ca_size_t *size0 = ca->size0;
|
|
861
936
|
char *d = (char *) data;
|
|
@@ -1010,8 +1085,9 @@ static void
|
|
|
1010
1085
|
ca_window_func_allocate (void *ap)
|
|
1011
1086
|
{
|
|
1012
1087
|
CAWindow *ca = (CAWindow *) ap;
|
|
1088
|
+
ca_window_mask_current(ca);
|
|
1013
1089
|
if ( ca_window_owns_buffer(ca) ) {
|
|
1014
|
-
ca->ptr =
|
|
1090
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1015
1091
|
return;
|
|
1016
1092
|
}
|
|
1017
1093
|
ca_attach(ca->parent);
|
|
@@ -1019,7 +1095,7 @@ ca_window_func_allocate (void *ap)
|
|
|
1019
1095
|
ca->ptr = ca_window_alias_ptr(ca);
|
|
1020
1096
|
return;
|
|
1021
1097
|
}
|
|
1022
|
-
ca->ptr =
|
|
1098
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1023
1099
|
}
|
|
1024
1100
|
|
|
1025
1101
|
/* The engine paths below emit a per-axis descriptor (ca_window_describe_axes)
|
|
@@ -1034,6 +1110,7 @@ static void
|
|
|
1034
1110
|
ca_window_func_attach (void *ap)
|
|
1035
1111
|
{
|
|
1036
1112
|
CAWindow *ca = (CAWindow *) ap;
|
|
1113
|
+
ca_window_mask_current(ca);
|
|
1037
1114
|
if ( ca_window_owns_buffer(ca) ) {
|
|
1038
1115
|
ca_axis_view_attach_owned(ca);
|
|
1039
1116
|
return;
|
|
@@ -1049,8 +1126,7 @@ ca_window_func_attach (void *ap)
|
|
|
1049
1126
|
ca->ptr = ca_window_alias_ptr(ca);
|
|
1050
1127
|
} else if ( ca->embed_eligible ) {
|
|
1051
1128
|
/* Embed path: allocate, then 1 fill + 1 strided memcpy. */
|
|
1052
|
-
|
|
1053
|
-
ca->ptr = xmalloc(out_len > 0 ? out_len : 1);
|
|
1129
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1054
1130
|
ca_window_attach_embed(ca, ca->ptr);
|
|
1055
1131
|
} else {
|
|
1056
1132
|
/* Fallback: PERIODIC / REFLECT / NEAREST / RUBY / STRICT go through
|
|
@@ -1085,6 +1161,7 @@ ca_window_func_sync (void *ap)
|
|
|
1085
1161
|
ca->elements, ca->ptr);
|
|
1086
1162
|
}
|
|
1087
1163
|
ca_sync(ca->parent);
|
|
1164
|
+
ca_window_mask_settle(ca);
|
|
1088
1165
|
}
|
|
1089
1166
|
|
|
1090
1167
|
static void
|
|
@@ -1149,6 +1226,7 @@ static void
|
|
|
1149
1226
|
ca_window_func_xfer_all (void *ap, void *data, int dir)
|
|
1150
1227
|
{
|
|
1151
1228
|
CAWindow *ca = (CAWindow *) ap;
|
|
1229
|
+
ca_window_mask_current(ca);
|
|
1152
1230
|
if ( ca->parent->ptr ) {
|
|
1153
1231
|
ca_window_func_run_fast_path(ca, (char *) data, dir);
|
|
1154
1232
|
return;
|
|
@@ -1250,6 +1328,7 @@ static void
|
|
|
1250
1328
|
ca_window_func_fill_data (void *ap, void *ptr)
|
|
1251
1329
|
{
|
|
1252
1330
|
CAWindow *ca = (CAWindow *) ap;
|
|
1331
|
+
ca_window_mask_current(ca);
|
|
1253
1332
|
|
|
1254
1333
|
/* embed_eligible (= no PERIODIC/REFLECT) covers both interior-only
|
|
1255
1334
|
windows (embed_covers_all == 1) and OOB-bearing ones such as a CAShift
|
|
@@ -1334,12 +1413,26 @@ static void
|
|
|
1334
1413
|
ca_window_func_create_mask (void *ap)
|
|
1335
1414
|
{
|
|
1336
1415
|
CAWindow *ca = (CAWindow *) ap;
|
|
1416
|
+
CArray *pmask;
|
|
1337
1417
|
boolean8_t fill;
|
|
1338
1418
|
uint8_t mbounds[CA_RANK_MAX];
|
|
1339
1419
|
int8_t i;
|
|
1340
1420
|
int any_mask;
|
|
1341
1421
|
|
|
1342
|
-
|
|
1422
|
+
/* The mask lies over the parent's mask, or, while the parent has none,
|
|
1423
|
+
over an all-false stand-in this window holds: masking the
|
|
1424
|
+
out-of-bounds cells gives the parent no mask
|
|
1425
|
+
(ca_mask_standin_new). */
|
|
1426
|
+
if ( ca_has_mask(ca->parent) ) {
|
|
1427
|
+
ca_create_mask(ca->parent);
|
|
1428
|
+
pmask = ca->parent->mask;
|
|
1429
|
+
}
|
|
1430
|
+
else {
|
|
1431
|
+
if ( ca->mask_standin == NULL ) {
|
|
1432
|
+
ca->mask_standin = ca_mask_standin_new(ca->parent);
|
|
1433
|
+
}
|
|
1434
|
+
pmask = ca->mask_standin;
|
|
1435
|
+
}
|
|
1343
1436
|
|
|
1344
1437
|
/* Any MASK axis of the view becomes FILL in the mask sub-view, with the
|
|
1345
1438
|
mask cell forced to 1 (= "masked"). Other axes keep their policy. When
|
|
@@ -1358,14 +1451,76 @@ ca_window_func_create_mask (void *ap)
|
|
|
1358
1451
|
/* The mask has the view's own type, so CAShift (which shares this table)
|
|
1359
1452
|
gets a CAShiftMask. */
|
|
1360
1453
|
{
|
|
1454
|
+
/* check: the mask window copies its own window's checked ranges */
|
|
1361
1455
|
CAWindow *m = (CAWindow *) ca_array_alloc(ca->obj_type, ca->ndim);
|
|
1362
|
-
ca_window_setup(m, ca->
|
|
1363
|
-
|
|
1364
|
-
m->
|
|
1456
|
+
ca_window_setup(m, pmask, ca->start, ca->count, mbounds, (char*)&fill);
|
|
1457
|
+
m->obj_type = ca->obj_type;
|
|
1458
|
+
m->mask_owner = (CArray *) ca;
|
|
1459
|
+
if ( pmask == ca->mask_standin ) {
|
|
1460
|
+
/* writes inside an attach window reach the stand-in through the
|
|
1461
|
+
sync, where they can give way to the parent's mask */
|
|
1462
|
+
m->embed_alias_eligible = 0;
|
|
1463
|
+
}
|
|
1365
1464
|
ca->mask = (CArray *) m;
|
|
1366
1465
|
}
|
|
1367
1466
|
}
|
|
1368
1467
|
|
|
1468
|
+
/* The table's write slots: on the mask of a window still reading a
|
|
1469
|
+
stand-in, a write that may have put a true into it ends with the settle
|
|
1470
|
+
(ca_mask_standin_settle). */
|
|
1471
|
+
static void
|
|
1472
|
+
ca_window_put_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
1473
|
+
{
|
|
1474
|
+
ca_window_func_xfer_index(ap, idx, data, dir);
|
|
1475
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1476
|
+
&& ca_mask_any_true(data, 1) ) {
|
|
1477
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
static void
|
|
1482
|
+
ca_window_put_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data,
|
|
1483
|
+
int dir)
|
|
1484
|
+
{
|
|
1485
|
+
ca_window_func_xfer_addrs(ap, n, addrs, data, dir);
|
|
1486
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1487
|
+
&& ca_mask_any_true(data, n) ) {
|
|
1488
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
static void
|
|
1493
|
+
ca_window_put_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
1494
|
+
ca_size_t *strides, void *data, int dir)
|
|
1495
|
+
{
|
|
1496
|
+
ca_window_func_xfer_stride(ap, starts, counts, strides, data, dir);
|
|
1497
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1498
|
+
&& ca_mask_any_true(data,
|
|
1499
|
+
ca_shape_elements(((CArray *) ap)->ndim, counts, 1)) ) {
|
|
1500
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
static void
|
|
1505
|
+
ca_window_put_xfer_all (void *ap, void *data, int dir)
|
|
1506
|
+
{
|
|
1507
|
+
ca_window_func_xfer_all(ap, data, dir);
|
|
1508
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1509
|
+
&& ca_mask_any_true(data, ((CArray *) ap)->elements) ) {
|
|
1510
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
static void
|
|
1515
|
+
ca_window_put_fill_data (void *ap, void *ptr)
|
|
1516
|
+
{
|
|
1517
|
+
ca_window_func_fill_data(ap, ptr);
|
|
1518
|
+
if ( ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1519
|
+
&& ca_mask_any_true(ptr, 1) ) {
|
|
1520
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1369
1524
|
ca_operation_function_t ca_window_func = {
|
|
1370
1525
|
-1, /* CA_OBJ_WINDOW */
|
|
1371
1526
|
CA_VIEW_ARRAY,
|
|
@@ -1375,13 +1530,13 @@ ca_operation_function_t ca_window_func = {
|
|
|
1375
1530
|
ca_window_func_attach,
|
|
1376
1531
|
ca_window_func_sync,
|
|
1377
1532
|
ca_window_func_detach,
|
|
1378
|
-
|
|
1533
|
+
ca_window_put_fill_data,
|
|
1379
1534
|
ca_window_func_create_mask,
|
|
1380
|
-
|
|
1381
|
-
|
|
1535
|
+
ca_window_put_xfer_index,
|
|
1536
|
+
ca_window_put_xfer_addrs,
|
|
1382
1537
|
ca_window_func_fold_stride,
|
|
1383
|
-
|
|
1384
|
-
|
|
1538
|
+
ca_window_put_xfer_stride,
|
|
1539
|
+
ca_window_put_xfer_all,
|
|
1385
1540
|
};
|
|
1386
1541
|
|
|
1387
1542
|
/* ------------------------------------------------------------------- */
|
|
@@ -1401,6 +1556,7 @@ ca_window_describe_axes (void *ap, ca_axis_desc_t *out,
|
|
|
1401
1556
|
ca_size_t *out_parent_dims)
|
|
1402
1557
|
{
|
|
1403
1558
|
CAWindow *ca = (CAWindow *) ap;
|
|
1559
|
+
ca_window_mask_current(ca);
|
|
1404
1560
|
int8_t k;
|
|
1405
1561
|
for ( k = 0; k < ca->ndim; k++ ) {
|
|
1406
1562
|
out_parent_dims[k] = ca->parent->dim[k];
|
|
@@ -1502,9 +1658,13 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1502
1658
|
bounds = CA_BOUNDS_MASK;
|
|
1503
1659
|
}
|
|
1504
1660
|
else {
|
|
1505
|
-
|
|
1661
|
+
/* The fill is a value of the array (a String for a CAString, an
|
|
1662
|
+
instant for a time array): rb_ca_obj2ptr writes it as one cell of
|
|
1663
|
+
the storage, through the Face. */
|
|
1664
|
+
rcs = rb_cscalar_new(ca_strip_face(ca)->data_type, ca->bytes, NULL);
|
|
1506
1665
|
TypedData_Get_Struct(rcs, CScalar, &cscalar_data_type, cs);
|
|
1507
1666
|
fill = cs->ptr;
|
|
1667
|
+
rb_ca_obj2ptr(self, rfval, fill);
|
|
1508
1668
|
}
|
|
1509
1669
|
|
|
1510
1670
|
if ( ! NIL_P(rbounds) ) {
|
|
@@ -1593,6 +1753,10 @@ rb_ca_window_initialize_copy (VALUE self, VALUE other)
|
|
|
1593
1753
|
ca_array_pool_alloc(ca, CA_OBJ_WINDOW, cs->ndim);
|
|
1594
1754
|
}
|
|
1595
1755
|
ca_window_setup(ca, cs->parent, cs->start, cs->count, cs->bounds, cs->fill);
|
|
1756
|
+
ca_window_create_bounds_mask((VALUE) ca);
|
|
1757
|
+
/* a copy of a mask over a stand-in gives way to the parent's mask as
|
|
1758
|
+
the original does */
|
|
1759
|
+
ca->mask_owner = cs->mask_owner;
|
|
1596
1760
|
|
|
1597
1761
|
return self;
|
|
1598
1762
|
}
|
|
@@ -1809,7 +1973,7 @@ Init_ca_obj_window (void)
|
|
|
1809
1973
|
/* No `count` accessor: the per-axis window widths are what `shape`
|
|
1810
1974
|
already answers, and the name belongs to CArray#count. */
|
|
1811
1975
|
rb_define_method(rb_cCAWindow, "start", rb_cw_start, 0);
|
|
1812
|
-
rb_define_method(rb_cCAWindow, "
|
|
1976
|
+
rb_define_method(rb_cCAWindow, "__boundary_rule_of_each_axis__", rb_ca_window_axis_bounds, 0);
|
|
1813
1977
|
rb_define_method(rb_cCAWindow, "size0", rb_cw_size0, 0);
|
|
1814
1978
|
|
|
1815
1979
|
#ifdef CARRAY_DEV_BUILD
|
data/ext/ca_sweep_engine.c
CHANGED
|
@@ -42,9 +42,9 @@ ca_sweep_refuse_shapes (CArray *a, CArray *b)
|
|
|
42
42
|
volatile VALUE sa = ca_sweep_shape_str(a);
|
|
43
43
|
volatile VALUE sb = ca_sweep_shape_str(b);
|
|
44
44
|
rb_raise(rb_eArgError,
|
|
45
|
-
"shape mismatch between operands (%s and %s); a scalar pairs "
|
|
45
|
+
"%s: shape mismatch between operands (%s and %s); a scalar pairs "
|
|
46
46
|
"with any array, two arrays only when their shapes agree",
|
|
47
|
-
StringValueCStr(sa), StringValueCStr(sb));
|
|
47
|
+
ca_calling_method_name(), StringValueCStr(sa), StringValueCStr(sb));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
int
|
data/ext/caframe_csv_reader.c
CHANGED
|
@@ -39,6 +39,85 @@ ca_csv_at (const char *s, long n, long p, const char *t, long tlen)
|
|
|
39
39
|
return p + tlen <= n && memcmp(s + p, t, tlen) == 0;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/* The coderange of UTF-8 text, as rb_enc_str_coderange answers it: 7BIT,
|
|
43
|
+
VALID, or BROKEN for an invalid sequence (a stray continuation byte, an
|
|
44
|
+
overlong form, a surrogate, past U+10FFFF, or a sequence cut short).
|
|
45
|
+
Runs of ASCII are passed over 8 bytes at a time, which Ruby's scan does
|
|
46
|
+
not do once it has met a multibyte character. */
|
|
47
|
+
static int
|
|
48
|
+
ca_csv_utf8_coderange (const unsigned char *s, long n)
|
|
49
|
+
{
|
|
50
|
+
long i = 0;
|
|
51
|
+
int ascii = 1;
|
|
52
|
+
while ( i < n ) {
|
|
53
|
+
unsigned c, c1;
|
|
54
|
+
while ( i + 8 <= n ) {
|
|
55
|
+
uint64_t w;
|
|
56
|
+
memcpy(&w, s + i, 8);
|
|
57
|
+
if ( w & 0x8080808080808080ULL ) {
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
i += 8;
|
|
61
|
+
}
|
|
62
|
+
if ( i >= n ) {
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
c = s[i];
|
|
66
|
+
if ( c < 0x80 ) {
|
|
67
|
+
i += 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
ascii = 0;
|
|
71
|
+
if ( c < 0xC2 || c > 0xF4 ) {
|
|
72
|
+
return ENC_CODERANGE_BROKEN;
|
|
73
|
+
}
|
|
74
|
+
if ( c < 0xE0 ) {
|
|
75
|
+
if ( i + 1 >= n || ( s[i + 1] & 0xC0 ) != 0x80 ) {
|
|
76
|
+
return ENC_CODERANGE_BROKEN;
|
|
77
|
+
}
|
|
78
|
+
i += 2;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if ( i + 1 >= n ) {
|
|
82
|
+
return ENC_CODERANGE_BROKEN;
|
|
83
|
+
}
|
|
84
|
+
c1 = s[i + 1];
|
|
85
|
+
if ( ( c1 & 0xC0 ) != 0x80
|
|
86
|
+
|| ( c == 0xE0 && c1 < 0xA0 ) || ( c == 0xED && c1 > 0x9F )
|
|
87
|
+
|| ( c == 0xF0 && c1 < 0x90 ) || ( c == 0xF4 && c1 > 0x8F ) ) {
|
|
88
|
+
return ENC_CODERANGE_BROKEN;
|
|
89
|
+
}
|
|
90
|
+
if ( c < 0xF0 ) {
|
|
91
|
+
if ( i + 2 >= n || ( s[i + 2] & 0xC0 ) != 0x80 ) {
|
|
92
|
+
return ENC_CODERANGE_BROKEN;
|
|
93
|
+
}
|
|
94
|
+
i += 3;
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if ( i + 3 >= n || ( s[i + 2] & 0xC0 ) != 0x80 || ( s[i + 3] & 0xC0 ) != 0x80 ) {
|
|
98
|
+
return ENC_CODERANGE_BROKEN;
|
|
99
|
+
}
|
|
100
|
+
i += 4;
|
|
101
|
+
}
|
|
102
|
+
return ascii ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* The coderange of the text, computed here for UTF-8 and cached on the
|
|
106
|
+
String as Ruby would cache it, so the Ruby reader's later String#count on
|
|
107
|
+
the same chunk does not scan it again. */
|
|
108
|
+
static int
|
|
109
|
+
ca_csv_text_coderange (VALUE text, rb_encoding *enc)
|
|
110
|
+
{
|
|
111
|
+
int cr = ENC_CODERANGE(text);
|
|
112
|
+
if ( cr != ENC_CODERANGE_UNKNOWN || enc != rb_utf8_encoding() ) {
|
|
113
|
+
return rb_enc_str_coderange(text);
|
|
114
|
+
}
|
|
115
|
+
cr = ca_csv_utf8_coderange((const unsigned char *) RSTRING_PTR(text),
|
|
116
|
+
RSTRING_LEN(text));
|
|
117
|
+
ENC_CODERANGE_SET(text, cr);
|
|
118
|
+
return cr;
|
|
119
|
+
}
|
|
120
|
+
|
|
42
121
|
/* The end of the line content that starts at p: the position of its "\n",
|
|
43
122
|
or n; *next is where the following line starts. A "\r" before the "\n",
|
|
44
123
|
or at the end of the text, is not content. */
|
|
@@ -311,7 +390,7 @@ ca_csv_check_reader_args (VALUE text, VALUE vsep, VALUE vquote, VALUE vncol,
|
|
|
311
390
|
*ncol = NUM2LONG(vncol);
|
|
312
391
|
enc = rb_enc_get(text);
|
|
313
392
|
if ( ( enc != rb_utf8_encoding() && enc != rb_usascii_encoding() )
|
|
314
|
-
||
|
|
393
|
+
|| ca_csv_text_coderange(text, enc) == ENC_CODERANGE_BROKEN || *ncol < 0 ) {
|
|
315
394
|
return 0;
|
|
316
395
|
}
|
|
317
396
|
return RSTRING_LEN(vsep) >= 1 && RSTRING_LEN(vquote) >= 1;
|