carray 3.0.3 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +469 -0
- data/README.md +3 -2
- data/carray.gemspec +1 -1
- data/ext/ca_array_pool.c +25 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +14 -26
- 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 +231 -153
- data/ext/ca_compare.c +9 -20
- data/ext/ca_composite_dispatch.c +9 -9
- data/ext/ca_group_iter.c +16 -17
- data/ext/ca_kernel_iterator.c +1240 -2000
- data/ext/ca_kernel_iterator.h +502 -519
- data/ext/ca_monop_dispatch.c +82 -59
- data/ext/ca_monop_dispatch.h +1 -0
- data/ext/ca_obj_array.c +152 -45
- data/ext/ca_obj_bincmp.c +25 -21
- data/ext/ca_obj_binop.c +16 -26
- data/ext/ca_obj_bitarray.c +8 -3
- data/ext/ca_obj_bitfield.c +63 -49
- data/ext/ca_obj_block.c +18 -9
- data/ext/ca_obj_byte_swap.c +7 -7
- data/ext/ca_obj_const_string.c +188 -22
- data/ext/ca_obj_face.c +280 -58
- 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 +30 -8
- data/ext/ca_obj_fixlen_string.c +2 -3
- data/ext/ca_obj_grid.c +455 -134
- data/ext/ca_obj_meld.c +172 -34
- data/ext/ca_obj_moncmp.c +23 -8
- data/ext/ca_obj_monop.c +113 -67
- data/ext/ca_obj_object.c +210 -52
- data/ext/ca_obj_record.c +15 -7
- data/ext/ca_obj_reduce.c +17 -8
- data/ext/ca_obj_refer.c +42 -35
- data/ext/ca_obj_remap.c +30 -9
- data/ext/ca_obj_repeat.c +9 -10
- data/ext/ca_obj_roll.c +31 -10
- data/ext/ca_obj_select.c +48 -14
- data/ext/ca_obj_select_axis.c +15 -47
- data/ext/ca_obj_shift.c +41 -7
- data/ext/ca_obj_stack.c +180 -34
- data/ext/ca_obj_stride.c +190 -134
- data/ext/ca_obj_string.c +80 -4
- data/ext/ca_obj_tile.c +32 -11
- data/ext/ca_obj_time.c +22 -6
- data/ext/ca_obj_timedelta.c +22 -6
- data/ext/ca_obj_transpose.c +13 -7
- data/ext/ca_obj_triop.c +26 -32
- data/ext/ca_obj_window.c +267 -74
- data/ext/ca_op_ipower.c +4 -4
- data/ext/ca_sort_kernels.h +6 -3
- data/ext/ca_sweep_engine.c +2 -2
- data/ext/caframe_csv_reader.c +80 -1
- data/ext/carray.h +214 -75
- data/ext/carray_access.c +200 -99
- data/ext/carray_address_basis.c +343 -87
- data/ext/carray_attribute.c +113 -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 +375 -96
- data/ext/carray_cast_func.rb +90 -20
- data/ext/carray_class.c +4 -3
- data/ext/carray_config.h +28 -0
- data/ext/carray_conversion.c +18 -9
- data/ext/carray_copy.c +51 -14
- data/ext/carray_core.c +150 -55
- data/ext/carray_count.c +56 -20
- data/ext/carray_element.c +81 -33
- data/ext/carray_factorize.c +138 -84
- data/ext/carray_generate.c +199 -52
- data/ext/carray_histogram.c +63 -18
- data/ext/carray_hold.c +12 -15
- data/ext/carray_index_classifier.c +388 -176
- data/ext/carray_internal.h +348 -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 +10897 -0
- data/ext/carray_kernels_triop.c +1864 -0
- data/ext/carray_key_windows.c +220 -0
- data/ext/carray_lazy.c +170 -111
- data/ext/carray_mask.c +337 -94
- data/ext/carray_median_percentile.c +82 -28
- data/ext/carray_memory_view.c +669 -561
- data/ext/carray_operator.c +129 -52
- data/ext/carray_order.c +604 -77
- data/ext/carray_partition.c +28 -27
- data/ext/carray_random.c +85 -31
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +87 -45
- data/ext/carray_segment.c +3 -3
- data/ext/carray_slab.c +123 -37
- data/ext/carray_sort.c +259 -51
- data/ext/carray_sort_kernel.c +5 -7
- data/ext/carray_struct.c +54 -61
- data/ext/carray_test.c +26 -5
- data/ext/carray_time_text.c +4 -2
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +309 -66
- data/ext/mk_call_cfunc.rb +19 -2
- data/ext/mkkernel.rb +403 -350
- data/ext/ruby_carray.c +10 -4
- data/ext/version.h +4 -4
- data/lib/carray/attribute.rb +139 -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 +105 -17
- 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 +195 -59
- data/lib/carray/categorical_iterator.rb +132 -29
- data/lib/carray/complex.rb +5 -5
- data/lib/carray/conditional.rb +67 -18
- data/lib/carray/const_string.rb +24 -5
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +9 -1
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +48 -3
- data/lib/carray/frame/column_verbs.rb +71 -0
- data/lib/carray/frame/concat.rb +17 -3
- 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 +252 -28
- data/lib/carray/frame/group.rb +603 -101
- data/lib/carray/frame/io.rb +117 -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 +42 -6
- 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 +217 -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 +61 -37
- 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 +323 -88
- data/lib/carray/serialize.rb +45 -14
- data/lib/carray/slab_iterator.rb +50 -0
- data/lib/carray/stack.rb +15 -12
- data/lib/carray/string.rb +113 -5
- data/lib/carray/string_operation_extension.rb +21 -6
- data/lib/carray/struct.rb +9 -21
- data/lib/carray/struct_builder.rb +24 -11
- data/lib/carray/time.rb +819 -158
- 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_transpose.rb +5 -4
- data/yard-stubs/ca_obj_window.rb +8 -3
- data/yard-stubs/carray_access.rb +6 -1
- data/yard-stubs/carray_attribute.rb +3 -6
- data/yard-stubs/carray_cast.rb +12 -0
- data/yard-stubs/carray_conversion.rb +7 -2
- data/yard-stubs/carray_copy.rb +4 -2
- data/yard-stubs/carray_count.rb +4 -4
- data/yard-stubs/carray_element.rb +17 -10
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_mask.rb +32 -3
- data/yard-stubs/carray_math.rb +41 -5
- data/yard-stubs/carray_median_percentile.rb +5 -2
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +129 -22
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +17 -10
- 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,30 +780,61 @@ 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
|
-
|
|
760
|
-
}
|
|
801
|
+
return Qnil;
|
|
802
|
+
}
|
|
761
803
|
|
|
762
|
-
|
|
804
|
+
typedef struct {
|
|
805
|
+
CAWindow *ca;
|
|
806
|
+
CArray *parent;
|
|
807
|
+
ca_size_t *start;
|
|
808
|
+
ca_size_t *count;
|
|
809
|
+
uint8_t *bounds;
|
|
810
|
+
char *fill;
|
|
811
|
+
} ca_window_new_arg;
|
|
812
|
+
|
|
813
|
+
static VALUE
|
|
814
|
+
ca_window_new_setup (VALUE varg)
|
|
815
|
+
{
|
|
816
|
+
ca_window_new_arg *a = (ca_window_new_arg *) varg;
|
|
817
|
+
ca_window_setup(a->ca, a->parent, a->start, a->count, a->bounds, a->fill);
|
|
818
|
+
return Qnil;
|
|
763
819
|
}
|
|
764
820
|
|
|
821
|
+
/* The setup allocates the fill value after the struct and its pool: when
|
|
822
|
+
that fails, the struct goes too. */
|
|
765
823
|
CAWindow *
|
|
766
824
|
ca_window_new (CArray *parent,
|
|
767
825
|
ca_size_t *start, ca_size_t *count, uint8_t *bounds, char *fill)
|
|
768
826
|
{
|
|
769
|
-
|
|
827
|
+
ca_window_new_arg a;
|
|
770
828
|
ca_window_setup(NULL, parent, start, count, bounds, fill);
|
|
771
|
-
ca
|
|
772
|
-
|
|
773
|
-
|
|
829
|
+
a.ca = (CAWindow *) ca_array_alloc(CA_OBJ_WINDOW, parent->ndim);
|
|
830
|
+
a.parent = parent;
|
|
831
|
+
a.start = start;
|
|
832
|
+
a.count = count;
|
|
833
|
+
a.bounds = bounds;
|
|
834
|
+
a.fill = fill;
|
|
835
|
+
ca_fill_or_free((CArray *) a.ca, ca_window_new_setup, (VALUE) &a);
|
|
836
|
+
ca_fill_or_free((CArray *) a.ca, ca_window_create_bounds_mask, (VALUE) a.ca);
|
|
837
|
+
return a.ca;
|
|
774
838
|
}
|
|
775
839
|
|
|
776
840
|
static void
|
|
@@ -779,6 +843,7 @@ free_ca_window (void *ap)
|
|
|
779
843
|
CAWindow *ca = (CAWindow *) ap;
|
|
780
844
|
if ( ca != NULL ) {
|
|
781
845
|
ca_free(ca->mask);
|
|
846
|
+
ca_free(ca->mask_standin);
|
|
782
847
|
xfree(ca->fill); /* always separate (bytes-sized) */
|
|
783
848
|
if ( ca->_pool ) {
|
|
784
849
|
/* bounds/start/count/size0/embed_* all live in ca->_pool. */
|
|
@@ -818,7 +883,39 @@ static void *
|
|
|
818
883
|
ca_window_func_clone (void *ap)
|
|
819
884
|
{
|
|
820
885
|
CAWindow *ca = (CAWindow *) ap;
|
|
821
|
-
|
|
886
|
+
CAWindow *cp = ca_window_new(ca->parent, ca->start, ca->count, ca->bounds,
|
|
887
|
+
ca->fill);
|
|
888
|
+
cp->mask_owner = ca->mask_owner;
|
|
889
|
+
return cp;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/* A mask window over its owner's stand-in (ca_mask_standin_current): what
|
|
893
|
+
it reads from now on. */
|
|
894
|
+
static void
|
|
895
|
+
ca_window_mask_current (CAWindow *ca)
|
|
896
|
+
{
|
|
897
|
+
CAWindow *o = (CAWindow *) ca->mask_owner;
|
|
898
|
+
if ( o != NULL ) {
|
|
899
|
+
ca->parent = ca_mask_standin_current((CArray *) ca, ca->parent, o->parent,
|
|
900
|
+
o->mask_standin);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
static int
|
|
905
|
+
ca_window_mask_reads_standin (CAWindow *ca)
|
|
906
|
+
{
|
|
907
|
+
CAWindow *o = (CAWindow *) ca->mask_owner;
|
|
908
|
+
return o != NULL && o->mask_standin != NULL && ca->parent == o->mask_standin;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/* After a write that may have put a true into the stand-in: it goes on to
|
|
912
|
+
the parent's mask. */
|
|
913
|
+
static void
|
|
914
|
+
ca_window_mask_settle (CAWindow *ca)
|
|
915
|
+
{
|
|
916
|
+
if ( ca_window_mask_reads_standin(ca) ) {
|
|
917
|
+
ca_mask_standin_settle(((CAWindow *) ca->mask_owner)->parent, ca->parent);
|
|
918
|
+
}
|
|
822
919
|
}
|
|
823
920
|
|
|
824
921
|
/* Per-cell access. GET and PUT share the bound-normalised index walk; an OOB
|
|
@@ -828,6 +925,7 @@ static void
|
|
|
828
925
|
ca_window_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
829
926
|
{
|
|
830
927
|
CAWindow *ca = (CAWindow *) ap;
|
|
928
|
+
ca_window_mask_current(ca);
|
|
831
929
|
ca_size_t *start = ca->start;
|
|
832
930
|
ca_size_t *size0 = ca->size0;
|
|
833
931
|
ca_size_t idx0[CA_RANK_MAX];
|
|
@@ -856,6 +954,7 @@ ca_window_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
856
954
|
void *data, int dir)
|
|
857
955
|
{
|
|
858
956
|
CAWindow *ca = (CAWindow *) ap;
|
|
957
|
+
ca_window_mask_current(ca);
|
|
859
958
|
ca_size_t *start = ca->start;
|
|
860
959
|
ca_size_t *size0 = ca->size0;
|
|
861
960
|
char *d = (char *) data;
|
|
@@ -1010,8 +1109,9 @@ static void
|
|
|
1010
1109
|
ca_window_func_allocate (void *ap)
|
|
1011
1110
|
{
|
|
1012
1111
|
CAWindow *ca = (CAWindow *) ap;
|
|
1112
|
+
ca_window_mask_current(ca);
|
|
1013
1113
|
if ( ca_window_owns_buffer(ca) ) {
|
|
1014
|
-
ca->ptr =
|
|
1114
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1015
1115
|
return;
|
|
1016
1116
|
}
|
|
1017
1117
|
ca_attach(ca->parent);
|
|
@@ -1019,7 +1119,7 @@ ca_window_func_allocate (void *ap)
|
|
|
1019
1119
|
ca->ptr = ca_window_alias_ptr(ca);
|
|
1020
1120
|
return;
|
|
1021
1121
|
}
|
|
1022
|
-
ca->ptr =
|
|
1122
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1023
1123
|
}
|
|
1024
1124
|
|
|
1025
1125
|
/* The engine paths below emit a per-axis descriptor (ca_window_describe_axes)
|
|
@@ -1034,6 +1134,7 @@ static void
|
|
|
1034
1134
|
ca_window_func_attach (void *ap)
|
|
1035
1135
|
{
|
|
1036
1136
|
CAWindow *ca = (CAWindow *) ap;
|
|
1137
|
+
ca_window_mask_current(ca);
|
|
1037
1138
|
if ( ca_window_owns_buffer(ca) ) {
|
|
1038
1139
|
ca_axis_view_attach_owned(ca);
|
|
1039
1140
|
return;
|
|
@@ -1049,8 +1150,7 @@ ca_window_func_attach (void *ap)
|
|
|
1049
1150
|
ca->ptr = ca_window_alias_ptr(ca);
|
|
1050
1151
|
} else if ( ca->embed_eligible ) {
|
|
1051
1152
|
/* Embed path: allocate, then 1 fill + 1 strided memcpy. */
|
|
1052
|
-
|
|
1053
|
-
ca->ptr = xmalloc(out_len > 0 ? out_len : 1);
|
|
1153
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1054
1154
|
ca_window_attach_embed(ca, ca->ptr);
|
|
1055
1155
|
} else {
|
|
1056
1156
|
/* Fallback: PERIODIC / REFLECT / NEAREST / RUBY / STRICT go through
|
|
@@ -1085,6 +1185,7 @@ ca_window_func_sync (void *ap)
|
|
|
1085
1185
|
ca->elements, ca->ptr);
|
|
1086
1186
|
}
|
|
1087
1187
|
ca_sync(ca->parent);
|
|
1188
|
+
ca_window_mask_settle(ca);
|
|
1088
1189
|
}
|
|
1089
1190
|
|
|
1090
1191
|
static void
|
|
@@ -1149,6 +1250,7 @@ static void
|
|
|
1149
1250
|
ca_window_func_xfer_all (void *ap, void *data, int dir)
|
|
1150
1251
|
{
|
|
1151
1252
|
CAWindow *ca = (CAWindow *) ap;
|
|
1253
|
+
ca_window_mask_current(ca);
|
|
1152
1254
|
if ( ca->parent->ptr ) {
|
|
1153
1255
|
ca_window_func_run_fast_path(ca, (char *) data, dir);
|
|
1154
1256
|
return;
|
|
@@ -1250,6 +1352,7 @@ static void
|
|
|
1250
1352
|
ca_window_func_fill_data (void *ap, void *ptr)
|
|
1251
1353
|
{
|
|
1252
1354
|
CAWindow *ca = (CAWindow *) ap;
|
|
1355
|
+
ca_window_mask_current(ca);
|
|
1253
1356
|
|
|
1254
1357
|
/* embed_eligible (= no PERIODIC/REFLECT) covers both interior-only
|
|
1255
1358
|
windows (embed_covers_all == 1) and OOB-bearing ones such as a CAShift
|
|
@@ -1334,12 +1437,26 @@ static void
|
|
|
1334
1437
|
ca_window_func_create_mask (void *ap)
|
|
1335
1438
|
{
|
|
1336
1439
|
CAWindow *ca = (CAWindow *) ap;
|
|
1440
|
+
CArray *pmask;
|
|
1337
1441
|
boolean8_t fill;
|
|
1338
1442
|
uint8_t mbounds[CA_RANK_MAX];
|
|
1339
1443
|
int8_t i;
|
|
1340
1444
|
int any_mask;
|
|
1341
1445
|
|
|
1342
|
-
|
|
1446
|
+
/* The mask lies over the parent's mask, or, while the parent has none,
|
|
1447
|
+
over an all-false stand-in this window holds: masking the
|
|
1448
|
+
out-of-bounds cells gives the parent no mask
|
|
1449
|
+
(ca_mask_standin_new). */
|
|
1450
|
+
if ( ca_has_mask(ca->parent) ) {
|
|
1451
|
+
ca_create_mask(ca->parent);
|
|
1452
|
+
pmask = ca->parent->mask;
|
|
1453
|
+
}
|
|
1454
|
+
else {
|
|
1455
|
+
if ( ca->mask_standin == NULL ) {
|
|
1456
|
+
ca->mask_standin = ca_mask_standin_new(ca->parent);
|
|
1457
|
+
}
|
|
1458
|
+
pmask = ca->mask_standin;
|
|
1459
|
+
}
|
|
1343
1460
|
|
|
1344
1461
|
/* Any MASK axis of the view becomes FILL in the mask sub-view, with the
|
|
1345
1462
|
mask cell forced to 1 (= "masked"). Other axes keep their policy. When
|
|
@@ -1358,14 +1475,76 @@ ca_window_func_create_mask (void *ap)
|
|
|
1358
1475
|
/* The mask has the view's own type, so CAShift (which shares this table)
|
|
1359
1476
|
gets a CAShiftMask. */
|
|
1360
1477
|
{
|
|
1478
|
+
/* check: the mask window copies its own window's checked ranges */
|
|
1361
1479
|
CAWindow *m = (CAWindow *) ca_array_alloc(ca->obj_type, ca->ndim);
|
|
1362
|
-
ca_window_setup(m, ca->
|
|
1363
|
-
|
|
1364
|
-
m->
|
|
1480
|
+
ca_window_setup(m, pmask, ca->start, ca->count, mbounds, (char*)&fill);
|
|
1481
|
+
m->obj_type = ca->obj_type;
|
|
1482
|
+
m->mask_owner = (CArray *) ca;
|
|
1483
|
+
if ( pmask == ca->mask_standin ) {
|
|
1484
|
+
/* writes inside an attach window reach the stand-in through the
|
|
1485
|
+
sync, where they can give way to the parent's mask */
|
|
1486
|
+
m->embed_alias_eligible = 0;
|
|
1487
|
+
}
|
|
1365
1488
|
ca->mask = (CArray *) m;
|
|
1366
1489
|
}
|
|
1367
1490
|
}
|
|
1368
1491
|
|
|
1492
|
+
/* The table's write slots: on the mask of a window still reading a
|
|
1493
|
+
stand-in, a write that may have put a true into it ends with the settle
|
|
1494
|
+
(ca_mask_standin_settle). */
|
|
1495
|
+
static void
|
|
1496
|
+
ca_window_put_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
1497
|
+
{
|
|
1498
|
+
ca_window_func_xfer_index(ap, idx, data, dir);
|
|
1499
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1500
|
+
&& ca_mask_any_true(data, 1) ) {
|
|
1501
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
static void
|
|
1506
|
+
ca_window_put_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *data,
|
|
1507
|
+
int dir)
|
|
1508
|
+
{
|
|
1509
|
+
ca_window_func_xfer_addrs(ap, n, addrs, data, dir);
|
|
1510
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1511
|
+
&& ca_mask_any_true(data, n) ) {
|
|
1512
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1513
|
+
}
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
static void
|
|
1517
|
+
ca_window_put_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
1518
|
+
ca_size_t *strides, void *data, int dir)
|
|
1519
|
+
{
|
|
1520
|
+
ca_window_func_xfer_stride(ap, starts, counts, strides, data, dir);
|
|
1521
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1522
|
+
&& ca_mask_any_true(data,
|
|
1523
|
+
ca_shape_elements(((CArray *) ap)->ndim, counts, 1)) ) {
|
|
1524
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
static void
|
|
1529
|
+
ca_window_put_xfer_all (void *ap, void *data, int dir)
|
|
1530
|
+
{
|
|
1531
|
+
ca_window_func_xfer_all(ap, data, dir);
|
|
1532
|
+
if ( dir == CA_XFER_PUT && ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1533
|
+
&& ca_mask_any_true(data, ((CArray *) ap)->elements) ) {
|
|
1534
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
static void
|
|
1539
|
+
ca_window_put_fill_data (void *ap, void *ptr)
|
|
1540
|
+
{
|
|
1541
|
+
ca_window_func_fill_data(ap, ptr);
|
|
1542
|
+
if ( ca_window_mask_reads_standin((CAWindow *) ap)
|
|
1543
|
+
&& ca_mask_any_true(ptr, 1) ) {
|
|
1544
|
+
ca_window_mask_settle((CAWindow *) ap);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1369
1548
|
ca_operation_function_t ca_window_func = {
|
|
1370
1549
|
-1, /* CA_OBJ_WINDOW */
|
|
1371
1550
|
CA_VIEW_ARRAY,
|
|
@@ -1375,13 +1554,13 @@ ca_operation_function_t ca_window_func = {
|
|
|
1375
1554
|
ca_window_func_attach,
|
|
1376
1555
|
ca_window_func_sync,
|
|
1377
1556
|
ca_window_func_detach,
|
|
1378
|
-
|
|
1557
|
+
ca_window_put_fill_data,
|
|
1379
1558
|
ca_window_func_create_mask,
|
|
1380
|
-
|
|
1381
|
-
|
|
1559
|
+
ca_window_put_xfer_index,
|
|
1560
|
+
ca_window_put_xfer_addrs,
|
|
1382
1561
|
ca_window_func_fold_stride,
|
|
1383
|
-
|
|
1384
|
-
|
|
1562
|
+
ca_window_put_xfer_stride,
|
|
1563
|
+
ca_window_put_xfer_all,
|
|
1385
1564
|
};
|
|
1386
1565
|
|
|
1387
1566
|
/* ------------------------------------------------------------------- */
|
|
@@ -1401,6 +1580,7 @@ ca_window_describe_axes (void *ap, ca_axis_desc_t *out,
|
|
|
1401
1580
|
ca_size_t *out_parent_dims)
|
|
1402
1581
|
{
|
|
1403
1582
|
CAWindow *ca = (CAWindow *) ap;
|
|
1583
|
+
ca_window_mask_current(ca);
|
|
1404
1584
|
int8_t k;
|
|
1405
1585
|
for ( k = 0; k < ca->ndim; k++ ) {
|
|
1406
1586
|
out_parent_dims[k] = ca->parent->dim[k];
|
|
@@ -1502,9 +1682,13 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1502
1682
|
bounds = CA_BOUNDS_MASK;
|
|
1503
1683
|
}
|
|
1504
1684
|
else {
|
|
1505
|
-
|
|
1685
|
+
/* The fill is a value of the array (a String for a CAString, an
|
|
1686
|
+
instant for a time array): rb_ca_obj2ptr writes it as one cell of
|
|
1687
|
+
the storage, through the Face. */
|
|
1688
|
+
rcs = rb_cscalar_new(ca_strip_face(ca)->data_type, ca->bytes, NULL);
|
|
1506
1689
|
TypedData_Get_Struct(rcs, CScalar, &cscalar_data_type, cs);
|
|
1507
1690
|
fill = cs->ptr;
|
|
1691
|
+
rb_ca_obj2ptr(self, rfval, fill);
|
|
1508
1692
|
}
|
|
1509
1693
|
|
|
1510
1694
|
if ( ! NIL_P(rbounds) ) {
|
|
@@ -1514,51 +1698,56 @@ rb_ca_window (int argc, VALUE *argv, VALUE self)
|
|
|
1514
1698
|
if ( SYMBOL_P(rbounds) ) {
|
|
1515
1699
|
rbounds = rb_sym2str(rbounds);
|
|
1516
1700
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1701
|
+
if ( ! RB_TYPE_P(rbounds, T_STRING) ) {
|
|
1702
|
+
rb_raise(rb_eTypeError,
|
|
1703
|
+
"window: bounds: must be a Symbol or a String (got %s)",
|
|
1704
|
+
rb_obj_classname(rbounds));
|
|
1705
|
+
}
|
|
1706
|
+
cbounds = StringValueCStr(rbounds);
|
|
1707
|
+
if ( ! strcmp(cbounds, "ruby") ) {
|
|
1708
|
+
bounds = CA_BOUNDS_RUBY;
|
|
1709
|
+
}
|
|
1710
|
+
else if ( ! strcmp(cbounds, "strict") ) {
|
|
1711
|
+
bounds = CA_BOUNDS_STRICT;
|
|
1712
|
+
}
|
|
1713
|
+
else if ( ! strcmp(cbounds, "nearest") ) {
|
|
1714
|
+
bounds = CA_BOUNDS_NEAREST;
|
|
1715
|
+
}
|
|
1716
|
+
else if ( ! strcmp(cbounds, "periodic") ) {
|
|
1717
|
+
rb_raise(rb_eArgError,
|
|
1718
|
+
"bounds=>'periodic' removed in 3.0; "
|
|
1719
|
+
"use CArray#roll(...) for cyclic shift "
|
|
1720
|
+
"(returns a CARoll view)");
|
|
1721
|
+
}
|
|
1722
|
+
else if ( ! strcmp(cbounds, "reflect") ) {
|
|
1723
|
+
rb_raise(rb_eArgError,
|
|
1724
|
+
"bounds=>'reflect' removed in 3.0; "
|
|
1725
|
+
"there is no view-based alternative");
|
|
1726
|
+
}
|
|
1727
|
+
else if ( ! strcmp(cbounds, "mask") ) {
|
|
1728
|
+
rb_warn("CAWindow option :bounds=>\"mask\" will be obsolete");
|
|
1729
|
+
rb_warn("use ca.window(..., fill_value: UNDEF)");
|
|
1730
|
+
bounds = CA_BOUNDS_MASK;
|
|
1731
|
+
}
|
|
1732
|
+
else if ( ! strcmp(cbounds, "fill") ) {
|
|
1733
|
+
bounds = ( rfval == CA_UNDEF ) ? CA_BOUNDS_MASK : CA_BOUNDS_FILL;
|
|
1734
|
+
}
|
|
1735
|
+
else {
|
|
1736
|
+
rb_raise(rb_eArgError,
|
|
1737
|
+
"window: unknown bounds: '%s'", cbounds);
|
|
1738
|
+
}
|
|
1739
|
+
/* A fill value says what the cells outside the array are; the other
|
|
1740
|
+
policies say something else about them. */
|
|
1741
|
+
if ( rfval != CA_UNSPECIFIED
|
|
1742
|
+
&& bounds != CA_BOUNDS_FILL && bounds != CA_BOUNDS_MASK ) {
|
|
1743
|
+
rb_raise(rb_eArgError,
|
|
1744
|
+
"window: fill_value: is for bounds: :fill, not :%s", cbounds);
|
|
1745
|
+
}
|
|
1746
|
+
if ( rfval != CA_UNSPECIFIED && rfval != CA_UNDEF
|
|
1747
|
+
&& bounds == CA_BOUNDS_MASK ) {
|
|
1748
|
+
rb_raise(rb_eArgError,
|
|
1749
|
+
"window: fill_value: %+"PRIsVALUE" conflicts with bounds: :mask "
|
|
1750
|
+
"(use fill_value: UNDEF to mask the cells outside)", rfval);
|
|
1562
1751
|
}
|
|
1563
1752
|
}
|
|
1564
1753
|
|
|
@@ -1593,6 +1782,10 @@ rb_ca_window_initialize_copy (VALUE self, VALUE other)
|
|
|
1593
1782
|
ca_array_pool_alloc(ca, CA_OBJ_WINDOW, cs->ndim);
|
|
1594
1783
|
}
|
|
1595
1784
|
ca_window_setup(ca, cs->parent, cs->start, cs->count, cs->bounds, cs->fill);
|
|
1785
|
+
ca_window_create_bounds_mask((VALUE) ca);
|
|
1786
|
+
/* a copy of a mask over a stand-in gives way to the parent's mask as
|
|
1787
|
+
the original does */
|
|
1788
|
+
ca->mask_owner = cs->mask_owner;
|
|
1596
1789
|
|
|
1597
1790
|
return self;
|
|
1598
1791
|
}
|
|
@@ -1809,7 +2002,7 @@ Init_ca_obj_window (void)
|
|
|
1809
2002
|
/* No `count` accessor: the per-axis window widths are what `shape`
|
|
1810
2003
|
already answers, and the name belongs to CArray#count. */
|
|
1811
2004
|
rb_define_method(rb_cCAWindow, "start", rb_cw_start, 0);
|
|
1812
|
-
rb_define_method(rb_cCAWindow, "
|
|
2005
|
+
rb_define_method(rb_cCAWindow, "__boundary_rule_of_each_axis__", rb_ca_window_axis_bounds, 0);
|
|
1813
2006
|
rb_define_method(rb_cCAWindow, "size0", rb_cw_size0, 0);
|
|
1814
2007
|
|
|
1815
2008
|
#ifdef CARRAY_DEV_BUILD
|
data/ext/ca_op_ipower.c
CHANGED
|
@@ -112,7 +112,7 @@ static void
|
|
|
112
112
|
ca_ipower_float32_t (ca_size_t n, boolean8_t *m,
|
|
113
113
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
114
114
|
{
|
|
115
|
-
|
|
115
|
+
ca_u_float32_t *p1 = (ca_u_float32_t *) ptr1, *p2 = (ca_u_float32_t *) ptr2;
|
|
116
116
|
if ( m ) {
|
|
117
117
|
while (n--) {
|
|
118
118
|
if ( ! *m++ ) { *p2 = op_powi_float32_t(*p1, ipow); }
|
|
@@ -127,7 +127,7 @@ static void
|
|
|
127
127
|
ca_ipower_float64_t (ca_size_t n, boolean8_t *m,
|
|
128
128
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
129
129
|
{
|
|
130
|
-
|
|
130
|
+
ca_u_float64_t *p1 = (ca_u_float64_t *) ptr1, *p2 = (ca_u_float64_t *) ptr2;
|
|
131
131
|
if ( m ) {
|
|
132
132
|
while (n--) {
|
|
133
133
|
if ( ! *m++ ) { *p2 = op_powi_float64_t(*p1, ipow); }
|
|
@@ -142,7 +142,7 @@ static void
|
|
|
142
142
|
ca_ipower_cmplx64_t (ca_size_t n, boolean8_t *m,
|
|
143
143
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
144
144
|
{
|
|
145
|
-
|
|
145
|
+
ca_u_cmplx64_t *p1 = (ca_u_cmplx64_t *) ptr1, *p2 = (ca_u_cmplx64_t *) ptr2;
|
|
146
146
|
if ( m ) {
|
|
147
147
|
while (n--) {
|
|
148
148
|
if ( ! *m++ ) { *p2 = op_powi_cmplx64_t(*p1, ipow); }
|
|
@@ -157,7 +157,7 @@ static void
|
|
|
157
157
|
ca_ipower_cmplx128_t (ca_size_t n, boolean8_t *m,
|
|
158
158
|
char *ptr1, int32_t ipow, char *ptr2)
|
|
159
159
|
{
|
|
160
|
-
|
|
160
|
+
ca_u_cmplx128_t *p1 = (ca_u_cmplx128_t *) ptr1, *p2 = (ca_u_cmplx128_t *) ptr2;
|
|
161
161
|
if ( m ) {
|
|
162
162
|
while (n--) {
|
|
163
163
|
if ( ! *m++ ) { *p2 = op_powi_cmplx128_t(*p1, ipow); }
|
data/ext/ca_sort_kernels.h
CHANGED
|
@@ -62,11 +62,14 @@ void ca_sort_merge_f64 (double *a, double *aux, ca_size_t n);
|
|
|
62
62
|
ca_size_t ca_partition_nan_f32 (float32_t *a, ca_size_t n);
|
|
63
63
|
ca_size_t ca_partition_nan_f64 (double *a, ca_size_t n);
|
|
64
64
|
|
|
65
|
-
/*
|
|
65
|
+
/* Pair variant of NaN pre-partition for float argsort kernels. scratch
|
|
66
|
+
holds n pairs; its contents on return are unspecified. */
|
|
66
67
|
struct ca_pair_f32;
|
|
67
68
|
struct ca_pair_f64;
|
|
68
|
-
ca_size_t ca_partition_nan_pair_f32 (struct ca_pair_f32 *a, ca_size_t n
|
|
69
|
-
|
|
69
|
+
ca_size_t ca_partition_nan_pair_f32 (struct ca_pair_f32 *a, ca_size_t n,
|
|
70
|
+
struct ca_pair_f32 *scratch);
|
|
71
|
+
ca_size_t ca_partition_nan_pair_f64 (struct ca_pair_f64 *a, ca_size_t n,
|
|
72
|
+
struct ca_pair_f64 *scratch);
|
|
70
73
|
|
|
71
74
|
/* P.9: value-level quickselect for partition_copy.
|
|
72
75
|
Reorders a[0..n) so that a[kth] is exact + left/right regions
|
data/ext/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
|