carray 3.0.6 → 3.0.7
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 +110 -0
- data/README.md +24 -3
- data/carray.gemspec +1 -1
- data/ext/ca_axis_group.c +6 -6
- data/ext/ca_binop_dispatch.c +8 -0
- data/ext/ca_binop_dispatch.h +1 -0
- data/ext/ca_categorical_iterator.c +7 -7
- data/ext/ca_kernel_iterator.h +6 -4
- data/ext/ca_obj_array.c +4 -4
- data/ext/ca_obj_bincmp.c +19 -3
- data/ext/ca_obj_binop.c +36 -11
- data/ext/ca_obj_bitarray.c +2 -4
- data/ext/ca_obj_bitfield.c +86 -4
- data/ext/ca_obj_byte_swap.c +2 -4
- data/ext/ca_obj_const_string.c +422 -257
- data/ext/ca_obj_face.c +71 -33
- data/ext/ca_obj_fake.c +112 -13
- data/ext/ca_obj_farray.c +7 -1
- data/ext/ca_obj_fixlen_string.c +51 -17
- data/ext/ca_obj_grid.c +12 -7
- data/ext/ca_obj_meld.c +5 -5
- data/ext/ca_obj_monop.c +65 -39
- data/ext/ca_obj_object.c +9 -9
- data/ext/ca_obj_reduce.c +2 -4
- data/ext/ca_obj_refer.c +104 -10
- data/ext/ca_obj_repeat.c +1 -1
- data/ext/ca_obj_roll.c +2 -4
- data/ext/ca_obj_select.c +8 -6
- data/ext/ca_obj_select_axis.c +8 -6
- data/ext/ca_obj_stack.c +5 -5
- data/ext/ca_obj_stride.c +46 -8
- data/ext/ca_obj_string.c +2 -2
- data/ext/ca_obj_tile.c +2 -4
- data/ext/ca_obj_triop.c +15 -12
- data/ext/ca_obj_window.c +22 -15
- data/ext/ca_op_ipower.c +63 -15
- data/ext/ca_op_powi.h +6 -29
- data/ext/ca_sort_kernels.h +3 -0
- data/ext/ca_sweep_engine.c +90 -23
- data/ext/ca_sweep_engine.h +5 -6
- data/ext/caframe_csv_reader.c +1 -1
- data/ext/carray.h +3 -1
- data/ext/carray_access.c +98 -39
- data/ext/carray_address_basis.c +98 -24
- data/ext/carray_broadcast.c +2 -2
- data/ext/carray_call_cfunc.c +5 -8
- data/ext/carray_cast.c +311 -37
- data/ext/carray_cast_func.rb +37 -5
- data/ext/carray_conversion.c +56 -2
- data/ext/carray_copy.c +24 -0
- data/ext/carray_core.c +69 -6
- data/ext/carray_count.c +28 -9
- data/ext/carray_element.c +9 -3
- data/ext/carray_factorize.c +11 -11
- data/ext/carray_histogram.c +2 -2
- data/ext/carray_index_classifier.c +7 -5
- data/ext/carray_internal.h +94 -0
- data/ext/carray_kernels_binop.c +55 -55
- data/ext/carray_kernels_init.c +14 -14
- data/ext/carray_kernels_monop.c +90 -140
- data/ext/carray_lazy.c +16 -1
- data/ext/carray_loop.c +9 -2
- data/ext/carray_mask.c +118 -11
- data/ext/carray_median_percentile.c +13 -8
- data/ext/carray_memory_view.c +41 -22
- data/ext/carray_operator.c +72 -11
- data/ext/carray_order.c +52 -9
- data/ext/carray_partition.c +1 -1
- data/ext/carray_random.c +1 -1
- data/ext/carray_round.c +24 -1
- data/ext/carray_scatter.c +4 -0
- data/ext/carray_segment.c +1 -1
- data/ext/carray_slab.c +13 -4
- data/ext/carray_sort.c +6 -3
- data/ext/carray_sort_kernel.c +24 -0
- data/ext/carray_struct.c +21 -6
- data/ext/carray_test.c +85 -39
- data/ext/carray_time_text.c +6 -0
- data/ext/carray_utils.c +124 -54
- data/ext/mk_call_cfunc.rb +6 -11
- data/ext/mkkernel.rb +37 -27
- data/ext/version.h +4 -4
- data/lib/carray/axis_group.rb +9 -6
- data/lib/carray/basics.rb +26 -8
- data/lib/carray/bincount_nd.rb +8 -2
- data/lib/carray/block_iterator.rb +48 -21
- data/lib/carray/categorical.rb +21 -8
- data/lib/carray/categorical_iterator.rb +2 -1
- data/lib/carray/conditional.rb +52 -4
- data/lib/carray/const_string.rb +74 -0
- data/lib/carray/construct.rb +2 -2
- data/lib/carray/core_extensions.rb +19 -68
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/fixlen_string.rb +83 -1
- data/lib/carray/frame/column_verbs.rb +61 -6
- data/lib/carray/frame/concat.rb +50 -6
- data/lib/carray/frame/csv_parser.rb +13 -4
- data/lib/carray/frame/frame.rb +38 -6
- data/lib/carray/frame/group.rb +67 -40
- data/lib/carray/frame/io.rb +10 -5
- data/lib/carray/frame/join.rb +20 -6
- data/lib/carray/frame/records.rb +6 -4
- data/lib/carray/frame/reshape.rb +25 -5
- data/lib/carray/frame/verbs.rb +78 -25
- data/lib/carray/frame/windows.rb +30 -6
- data/lib/carray/fuse_source.rb +4 -2
- data/lib/carray/iterator.rb +8 -0
- data/lib/carray/key_windows.rb +10 -4
- data/lib/carray/lazy.rb +12 -17
- data/lib/carray/methods/bin.rb +3 -0
- data/lib/carray/methods/composition.rb +1 -1
- data/lib/carray/methods/factorize.rb +2 -0
- data/lib/carray/methods/gather_nd.rb +4 -1
- data/lib/carray/methods/is_in.rb +23 -3
- data/lib/carray/methods/locate_addr.rb +63 -12
- data/lib/carray/methods/repeat.rb +11 -1
- data/lib/carray/record_order.rb +35 -6
- data/lib/carray/runtime.rb +10 -0
- data/lib/carray/segment_iterator.rb +19 -16
- data/lib/carray/serialize.rb +22 -0
- data/lib/carray/slab_iterator.rb +1 -1
- data/lib/carray/stack.rb +3 -3
- data/lib/carray/string.rb +6 -6
- data/lib/carray/string_operation_extension.rb +25 -4
- data/lib/carray/struct_builder.rb +4 -1
- data/lib/carray/time.rb +190 -46
- data/lib/carray/window_iterator.rb +48 -12
- data/yard-stubs/ca_obj_bitfield.rb +4 -1
- data/yard-stubs/ca_obj_refer.rb +3 -0
- data/yard-stubs/ca_obj_window.rb +2 -1
- data/yard-stubs/carray_access.rb +4 -2
- data/yard-stubs/carray_cast.rb +6 -0
- data/yard-stubs/carray_count.rb +6 -3
- data/yard-stubs/carray_math.rb +5 -0
- data/yard-stubs/carray_order.rb +6 -0
- data/yard-stubs/carray_scatter.rb +2 -1
- data/yard-stubs/carray_test.rb +18 -5
- metadata +2 -2
data/ext/ca_obj_face.c
CHANGED
|
@@ -187,8 +187,22 @@ rb_ca_face_template (VALUE original_face, CArray *new_parent,
|
|
|
187
187
|
dst);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
/* A Face put on a fresh entity has nothing to be read-only for: the template
|
|
191
|
+
copied the flag of the Face it came from, which may be read-only only as
|
|
192
|
+
that view was. A Face that cannot hold a new value keeps it. */
|
|
193
|
+
static void
|
|
194
|
+
ca_face_fresh_entity_is_writable (volatile VALUE lifted, VALUE face)
|
|
195
|
+
{
|
|
196
|
+
CArray *lc;
|
|
197
|
+
TypedData_Get_Struct(lifted, CArray, &carray_data_type, lc);
|
|
198
|
+
if ( ca_test_flag(lc, CA_FLAG_READ_ONLY)
|
|
199
|
+
&& RTEST(rb_funcall(face, rb_intern("holds_new_values?"), 0)) ) {
|
|
200
|
+
ca_unset_flag(lc, CA_FLAG_READ_ONLY);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
190
204
|
VALUE
|
|
191
|
-
ca_face_relift_entity (VALUE face, VALUE result)
|
|
205
|
+
ca_face_relift_entity (VALUE face, volatile VALUE result)
|
|
192
206
|
{
|
|
193
207
|
static ID id_copy_state = 0;
|
|
194
208
|
CArray *rc, *lc;
|
|
@@ -197,6 +211,7 @@ ca_face_relift_entity (VALUE face, VALUE result)
|
|
|
197
211
|
TypedData_Get_Struct(result, CArray, &carray_data_type, rc);
|
|
198
212
|
lifted = rb_ca_face_template(face, rc, rc->dim);
|
|
199
213
|
rb_ca_set_parent(lifted, result);
|
|
214
|
+
ca_face_fresh_entity_is_writable(lifted, face);
|
|
200
215
|
if ( ca_has_mask(rc) ) {
|
|
201
216
|
/* The template starts without a mask. */
|
|
202
217
|
TypedData_Get_Struct(lifted, CArray, &carray_data_type, lc);
|
|
@@ -304,6 +319,9 @@ ca_face_lift (VALUE view, VALUE face_parent)
|
|
|
304
319
|
if ( ca_is_view(view_ca) ) {
|
|
305
320
|
rb_ca_set_lifted_from(lifted, face_parent);
|
|
306
321
|
}
|
|
322
|
+
else {
|
|
323
|
+
ca_face_fresh_entity_is_writable(lifted, face_parent);
|
|
324
|
+
}
|
|
307
325
|
|
|
308
326
|
/* Optional Ruby callback for ivar / state carry. Faces holding
|
|
309
327
|
semantic state in the struct tail (CATime / CATimedelta
|
|
@@ -358,7 +376,7 @@ ca_face_lift (VALUE view, VALUE face_parent)
|
|
|
358
376
|
* builder handed us a view whose parent is the marker, and leaving it
|
|
359
377
|
* there would stack a redundant marker in the middle. */
|
|
360
378
|
static VALUE
|
|
361
|
-
ca_lazy_marker_lift (VALUE view, VALUE marker)
|
|
379
|
+
ca_lazy_marker_lift (VALUE view, volatile VALUE marker)
|
|
362
380
|
{
|
|
363
381
|
CArray *view_ca, *mp;
|
|
364
382
|
extern VALUE rb_ca_lazy_marker_new (VALUE cary);
|
|
@@ -741,16 +759,16 @@ ca_face_refuse_order (const char *name, VALUE face, const char *verb)
|
|
|
741
759
|
const char *storage = ca_face_storage_method(face);
|
|
742
760
|
if ( storage ) {
|
|
743
761
|
rb_raise(rb_eArgError,
|
|
744
|
-
"%s: %
|
|
762
|
+
"%s: %"PRIsVALUE" is not orderable by storage (a cell encodes the value "
|
|
745
763
|
"rather than being it); %s its values instead -- %s -- or %s "
|
|
746
764
|
"its storage, which #%s gives",
|
|
747
|
-
name,
|
|
765
|
+
name, rb_obj_class(face), verb,
|
|
748
766
|
ca_face_conversion_hint(face), verb, storage);
|
|
749
767
|
}
|
|
750
768
|
rb_raise(rb_eArgError,
|
|
751
|
-
"%s: %
|
|
769
|
+
"%s: %"PRIsVALUE" is not orderable by storage (a cell encodes the value "
|
|
752
770
|
"rather than being it); %s its values instead -- %s",
|
|
753
|
-
name,
|
|
771
|
+
name, rb_obj_class(face), verb,
|
|
754
772
|
ca_face_conversion_hint(face));
|
|
755
773
|
}
|
|
756
774
|
|
|
@@ -808,17 +826,17 @@ ca_face_refuse_numeric (VALUE self, const char *name, VALUE eclass)
|
|
|
808
826
|
const char *storage = ca_face_storage_method(self);
|
|
809
827
|
if ( storage ) {
|
|
810
828
|
rb_raise(eclass,
|
|
811
|
-
"%s: %
|
|
829
|
+
"%s: %"PRIsVALUE" does not define it (a cell encodes the value rather "
|
|
812
830
|
"than being a number); compute on its values instead -- %s -- "
|
|
813
831
|
"or on its storage, which #%s gives",
|
|
814
|
-
name,
|
|
832
|
+
name, rb_obj_class(self), ca_face_conversion_hint(self),
|
|
815
833
|
storage);
|
|
816
834
|
}
|
|
817
835
|
}
|
|
818
836
|
rb_raise(eclass,
|
|
819
|
-
"%s: %
|
|
837
|
+
"%s: %"PRIsVALUE" does not define it (a cell encodes the value rather than "
|
|
820
838
|
"being a number); compute on its values instead -- %s",
|
|
821
|
-
name,
|
|
839
|
+
name, rb_obj_class(self), ca_face_conversion_hint(self));
|
|
822
840
|
}
|
|
823
841
|
|
|
824
842
|
VALUE
|
|
@@ -839,21 +857,21 @@ ca_face_operand_descend (VALUE operand, const char *name)
|
|
|
839
857
|
const char *storage = ca_face_storage_method(operand);
|
|
840
858
|
if ( storage ) {
|
|
841
859
|
rb_raise(rb_eArgError,
|
|
842
|
-
"%s: cannot take a %
|
|
860
|
+
"%s: cannot take a %"PRIsVALUE" operand: its storage is not its surface "
|
|
843
861
|
"(a cell encodes the value rather than being it), so comparing "
|
|
844
862
|
"the storage would compare the encoding. Convert the operand "
|
|
845
863
|
"to the receiver's space first -- %s -- or compare the storage "
|
|
846
864
|
"of both sides, which #%s gives",
|
|
847
|
-
name,
|
|
865
|
+
name, rb_obj_class(operand),
|
|
848
866
|
ca_face_conversion_hint(operand), storage);
|
|
849
867
|
}
|
|
850
868
|
}
|
|
851
869
|
rb_raise(rb_eArgError,
|
|
852
|
-
"%s: cannot take a %
|
|
870
|
+
"%s: cannot take a %"PRIsVALUE" operand: its storage is not its surface "
|
|
853
871
|
"(a cell encodes the value rather than being it), so comparing "
|
|
854
872
|
"the storage would compare the encoding. Convert the operand to "
|
|
855
873
|
"the receiver's space first -- %s",
|
|
856
|
-
name,
|
|
874
|
+
name, rb_obj_class(operand), ca_face_conversion_hint(operand));
|
|
857
875
|
return Qnil; /* not reached */
|
|
858
876
|
}
|
|
859
877
|
|
|
@@ -862,11 +880,12 @@ ca_face_operand_descend (VALUE operand, const char *name)
|
|
|
862
880
|
|
|
863
881
|
A Face equals only a Face of its own class. When the two share their
|
|
864
882
|
state (a time array's unit) and the storage holds the values in their
|
|
865
|
-
order, equal storage is equal values, so the
|
|
866
|
-
Otherwise `==` compares the values themselves (two
|
|
867
|
-
different units, two const strings over different pools,
|
|
868
|
-
categoricals with differently ordered labels
|
|
869
|
-
agree with #hash,
|
|
883
|
+
order, cell for cell at one width, equal storage is equal values, so the
|
|
884
|
+
storage is compared. Otherwise `==` compares the values themselves (two
|
|
885
|
+
time arrays of different units, two const strings over different pools,
|
|
886
|
+
two categoricals with differently ordered labels, two fixed-length
|
|
887
|
+
strings of different widths), and `eql?`, which has to agree with #hash,
|
|
888
|
+
answers false. */
|
|
870
889
|
int
|
|
871
890
|
ca_face_equal (VALUE va, VALUE vb, int strict)
|
|
872
891
|
{
|
|
@@ -889,7 +908,8 @@ ca_face_equal (VALUE va, VALUE vb, int strict)
|
|
|
889
908
|
}
|
|
890
909
|
}
|
|
891
910
|
if ( ca_face_state_compatible(va, a, vb, b)
|
|
892
|
-
&& ( strict || ca_test_flag(a, CA_FLAG_FACE_ORDERABLE_STORAGE)
|
|
911
|
+
&& ( strict || ( ca_test_flag(a, CA_FLAG_FACE_ORDERABLE_STORAGE)
|
|
912
|
+
&& a->bytes == b->bytes ) ) ) {
|
|
893
913
|
return strict ? ca_eql_storage(ca_strip_face(a), ca_strip_face(b))
|
|
894
914
|
: ca_equal(ca_strip_face(a), ca_strip_face(b));
|
|
895
915
|
}
|
|
@@ -959,8 +979,8 @@ ca_face_reconcile_operand (VALUE reference, VALUE operand, const char *name)
|
|
|
959
979
|
if ( ca_is_face(op) ) {
|
|
960
980
|
if ( op->obj_type != CA_OBJ_RECORD ) {
|
|
961
981
|
rb_raise(rb_eTypeError,
|
|
962
|
-
"%s: can not take a %
|
|
963
|
-
"%"PRIsVALUE, name,
|
|
982
|
+
"%s: can not take a %"PRIsVALUE" operand for a record array of "
|
|
983
|
+
"%"PRIsVALUE, name, rb_obj_class(operand),
|
|
964
984
|
rb_ca_data_class(reference));
|
|
965
985
|
}
|
|
966
986
|
if ( rb_ca_data_class(operand) != rb_ca_data_class(reference) ) {
|
|
@@ -987,16 +1007,16 @@ ca_face_reconcile_operand (VALUE reference, VALUE operand, const char *name)
|
|
|
987
1007
|
const char *storage = ca_face_storage_method(reference);
|
|
988
1008
|
if ( storage ) {
|
|
989
1009
|
rb_raise(rb_eArgError,
|
|
990
|
-
"%s: %
|
|
1010
|
+
"%s: %"PRIsVALUE" is not comparable by storage and has no to_comparable "
|
|
991
1011
|
"to bring the operand into its space; compare the storage of "
|
|
992
1012
|
"both sides, which #%s gives",
|
|
993
|
-
name,
|
|
1013
|
+
name, rb_obj_class(reference), storage);
|
|
994
1014
|
}
|
|
995
1015
|
}
|
|
996
1016
|
rb_raise(rb_eArgError,
|
|
997
|
-
"%s: %
|
|
1017
|
+
"%s: %"PRIsVALUE" is not comparable by storage and has no to_comparable "
|
|
998
1018
|
"to bring the operand into its space",
|
|
999
|
-
name,
|
|
1019
|
+
name, rb_obj_class(reference));
|
|
1000
1020
|
return Qnil; /* not reached */
|
|
1001
1021
|
}
|
|
1002
1022
|
|
|
@@ -1088,8 +1108,8 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
1088
1108
|
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
1089
1109
|
"different Face classes; convert them first to one Face "
|
|
1090
1110
|
"class or to no Face, or combine their storage (#%s gives "
|
|
1091
|
-
"the storage of a %
|
|
1092
|
-
who, storage,
|
|
1111
|
+
"the storage of a %"PRIsVALUE")",
|
|
1112
|
+
who, storage, rb_obj_class(face));
|
|
1093
1113
|
}
|
|
1094
1114
|
rb_raise(rb_eArgError,
|
|
1095
1115
|
"%s: cannot mix Face and non-Face arrays, or arrays of "
|
|
@@ -1099,10 +1119,10 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
1099
1119
|
}
|
|
1100
1120
|
if ( n > 1 && ! ca_face_state_portable(ref->obj_type, face_class) ) {
|
|
1101
1121
|
rb_raise(rb_eArgError,
|
|
1102
|
-
"%s: %
|
|
1122
|
+
"%s: %"PRIsVALUE" state is not portable across several arrays (each "
|
|
1103
1123
|
"keeps its values in storage of its own); convert them first "
|
|
1104
1124
|
"(%s)",
|
|
1105
|
-
who,
|
|
1125
|
+
who, face_class,
|
|
1106
1126
|
ca_face_conversion_hint(face));
|
|
1107
1127
|
}
|
|
1108
1128
|
for ( i = 1; i < n; i++ ) {
|
|
@@ -1111,8 +1131,8 @@ ca_face_list_class (VALUE list, const char *who)
|
|
|
1111
1131
|
TypedData_Get_Struct(p, CArray, &carray_data_type, ca);
|
|
1112
1132
|
if ( ! ca_face_state_compatible(rb_ary_entry(list, 0), ref, p, ca) ) {
|
|
1113
1133
|
rb_raise(rb_eArgError,
|
|
1114
|
-
"%s: Face state mismatch (the %
|
|
1115
|
-
"index 0)", who,
|
|
1134
|
+
"%s: Face state mismatch (the %"PRIsVALUE" at index %ld differs from "
|
|
1135
|
+
"index 0)", who, face_class, i);
|
|
1116
1136
|
}
|
|
1117
1137
|
}
|
|
1118
1138
|
return face_class;
|
|
@@ -1195,7 +1215,7 @@ rb_ca_reconcile_operand (VALUE self, VALUE operand, VALUE rname)
|
|
|
1195
1215
|
static VALUE
|
|
1196
1216
|
rb_ca_face_lift_method (VALUE self, VALUE face_parent)
|
|
1197
1217
|
{
|
|
1198
|
-
CArray *fp;
|
|
1218
|
+
CArray *fp, *vc, *storage;
|
|
1199
1219
|
if ( ! rb_obj_is_kind_of(face_parent, rb_cCArray) ) {
|
|
1200
1220
|
rb_raise(rb_eArgError, "face_lift: face_parent must be a CArray");
|
|
1201
1221
|
}
|
|
@@ -1203,6 +1223,24 @@ rb_ca_face_lift_method (VALUE self, VALUE face_parent)
|
|
|
1203
1223
|
if ( ! ca_is_face(fp) ) {
|
|
1204
1224
|
rb_raise(rb_eArgError, "face_lift: face_parent must be a Face instance");
|
|
1205
1225
|
}
|
|
1226
|
+
rb_check_carray_object(self);
|
|
1227
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, vc);
|
|
1228
|
+
/* A Face of the same class is already lifted (see ca_face_lift). */
|
|
1229
|
+
if ( ca_is_face(vc) && rb_obj_class(self) == rb_obj_class(face_parent) ) {
|
|
1230
|
+
return self;
|
|
1231
|
+
}
|
|
1232
|
+
storage = ca_strip_face(fp);
|
|
1233
|
+
/* A Face reads the cells under it as its own, so they must be held in
|
|
1234
|
+
its surface type or its storage type. A Face receiver is held in its
|
|
1235
|
+
surface type, and is checked the same way. */
|
|
1236
|
+
if ( ! ( vc->data_type == fp->data_type && vc->bytes == fp->bytes )
|
|
1237
|
+
&& ! ( vc->data_type == storage->data_type
|
|
1238
|
+
&& vc->bytes == storage->bytes ) ) {
|
|
1239
|
+
rb_raise(rb_eArgError,
|
|
1240
|
+
"face_lift: a %"PRIsVALUE" holds its cells as %s, not as %s",
|
|
1241
|
+
rb_obj_class(face_parent), ca_type_name[storage->data_type],
|
|
1242
|
+
ca_type_name[vc->data_type]);
|
|
1243
|
+
}
|
|
1206
1244
|
return ca_face_lift(self, face_parent);
|
|
1207
1245
|
}
|
|
1208
1246
|
|
data/ext/ca_obj_fake.c
CHANGED
|
@@ -154,6 +154,71 @@ ca_fake_func_clone (void *ap)
|
|
|
154
154
|
return ca_fake_new(ca->parent, ca->data_type, ca->bytes);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/* A read does not raise for a masked cell (ca_fake_cast_get), as attach
|
|
158
|
+
does not: the value under a mask is not defined, and converting it can
|
|
159
|
+
raise (NaN to an integer type). The view's cells are its parent's at the same
|
|
160
|
+
addresses, so the parent's mask is read for the same cells. The view's
|
|
161
|
+
own mask is not made here: once it exists, sync leaves masked cells
|
|
162
|
+
alone, and a read must not change what a later write does. */
|
|
163
|
+
static CArray *
|
|
164
|
+
ca_fake_read_mask (CAFake *ca)
|
|
165
|
+
{
|
|
166
|
+
if ( ca->mask ) {
|
|
167
|
+
return ca->mask;
|
|
168
|
+
}
|
|
169
|
+
if ( ca_has_mask(ca->parent) ) {
|
|
170
|
+
return ca->parent->mask;
|
|
171
|
+
}
|
|
172
|
+
return NULL;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/* Convert n cells read from the parent. A masked cell is converted as
|
|
176
|
+
well, so that the cell holds what the parent holds (a walk that sends
|
|
177
|
+
back only the cells a kernel changed compares against it), but a value
|
|
178
|
+
that cannot be converted (NaN to an integer) leaves zero bytes instead
|
|
179
|
+
of raising: the value under a mask is not defined. */
|
|
180
|
+
typedef struct {
|
|
181
|
+
CArray *src_ca, *dst_ca;
|
|
182
|
+
char *src, *dst;
|
|
183
|
+
} ca_fake_cell_ctx_t;
|
|
184
|
+
|
|
185
|
+
static VALUE
|
|
186
|
+
ca_fake_cast_cell (VALUE arg)
|
|
187
|
+
{
|
|
188
|
+
ca_fake_cell_ctx_t *c = (ca_fake_cell_ctx_t *) arg;
|
|
189
|
+
ca_ptr2ptr(c->src_ca, c->src, c->dst_ca, c->dst);
|
|
190
|
+
return Qnil;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
static void
|
|
194
|
+
ca_fake_cast_get (CAFake *ca, ca_size_t n, char *src, char *dst, boolean8_t *m)
|
|
195
|
+
{
|
|
196
|
+
CArray *parent = ca->parent;
|
|
197
|
+
ca_size_t i;
|
|
198
|
+
if ( ! m ) {
|
|
199
|
+
ca_cast_block(n, parent, src, (CArray *) ca, dst);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
ca_cast_block_skip_masked(n, parent, src, (CArray *) ca, dst, m);
|
|
203
|
+
for ( i = 0; i < n; i++ ) {
|
|
204
|
+
if ( m[i] ) {
|
|
205
|
+
ca_fake_cell_ctx_t c;
|
|
206
|
+
int state = 0;
|
|
207
|
+
c.src_ca = parent;
|
|
208
|
+
c.dst_ca = (CArray *) ca;
|
|
209
|
+
c.src = src + i * parent->bytes;
|
|
210
|
+
c.dst = dst + i * ca->bytes;
|
|
211
|
+
/* A masked cell that cannot be converted reads as zero bytes. */
|
|
212
|
+
/* protect: converts a masked cell; nothing is held */
|
|
213
|
+
rb_protect(ca_fake_cast_cell, (VALUE) &c, &state);
|
|
214
|
+
if ( state ) {
|
|
215
|
+
rb_set_errinfo(Qnil);
|
|
216
|
+
memset(c.dst, 0, ca->bytes);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
157
222
|
/* Per-cell GET/PUT via a parent-sized scratch cell — same code services
|
|
158
223
|
both directions, casting through the parent data_type. */
|
|
159
224
|
static void
|
|
@@ -161,10 +226,16 @@ ca_fake_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
|
|
|
161
226
|
{
|
|
162
227
|
CAFake *ca = (CAFake *) ap;
|
|
163
228
|
volatile VALUE holder;
|
|
164
|
-
char *v
|
|
229
|
+
char *v;
|
|
230
|
+
v = ALLOCV_N(char, holder, ca->parent->bytes);
|
|
165
231
|
if ( dir == CA_XFER_GET ) {
|
|
232
|
+
CArray *mask = ca_fake_read_mask(ca);
|
|
233
|
+
boolean8_t masked = 0;
|
|
234
|
+
if ( mask ) {
|
|
235
|
+
ca_fetch_index(mask, idx, &masked);
|
|
236
|
+
}
|
|
166
237
|
ca_fetch_index(ca->parent, idx, v);
|
|
167
|
-
|
|
238
|
+
ca_fake_cast_get(ca, 1, v, (char *) data, mask ? &masked : NULL);
|
|
168
239
|
}
|
|
169
240
|
else {
|
|
170
241
|
ca_ptr2ptr(ca, data, ca->parent, v);
|
|
@@ -184,10 +255,22 @@ ca_fake_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
|
|
|
184
255
|
CAFake *ca = (CAFake *) ap;
|
|
185
256
|
CArray *parent = ca->parent;
|
|
186
257
|
CArray *eff;
|
|
258
|
+
CArray *mask = ( dir == CA_XFER_GET ) ? ca_fake_read_mask(ca) : NULL;
|
|
187
259
|
ca_size_t base;
|
|
188
260
|
char *v;
|
|
189
261
|
volatile VALUE holder;
|
|
190
262
|
|
|
263
|
+
if ( mask ) {
|
|
264
|
+
volatile VALUE mholder;
|
|
265
|
+
boolean8_t *m = ALLOCV_N(boolean8_t, mholder, n + n * parent->bytes);
|
|
266
|
+
v = (char *) (m + n);
|
|
267
|
+
ca_xfer_addrs(mask, n, addrs, m, CA_XFER_GET);
|
|
268
|
+
ca_xfer_addrs(parent, n, addrs, v, CA_XFER_GET);
|
|
269
|
+
ca_fake_cast_get(ca, n, v, (char *) data, m);
|
|
270
|
+
ALLOCV_END(mholder);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
191
274
|
/* Sequential-run + live-ptr fast path: cast directly from
|
|
192
275
|
parent->ptr + base*pbytes to data, no intermediate scratch. */
|
|
193
276
|
eff = ca_resolve_attached_root_via_identity(parent);
|
|
@@ -251,6 +334,24 @@ ca_fake_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
|
|
|
251
334
|
int8_t k;
|
|
252
335
|
char *v;
|
|
253
336
|
volatile VALUE holder;
|
|
337
|
+
CArray *mask = ( dir == CA_XFER_GET ) ? ca_fake_read_mask(ca) : NULL;
|
|
338
|
+
|
|
339
|
+
if ( mask ) {
|
|
340
|
+
ca_size_t mstrides[CA_RANK_MAX];
|
|
341
|
+
boolean8_t *m;
|
|
342
|
+
for ( k = 0; k < ndim; k++ ) {
|
|
343
|
+
n *= counts[k];
|
|
344
|
+
pstrides[k] = strides[k] / ca->bytes * ca->parent->bytes;
|
|
345
|
+
mstrides[k] = strides[k] / ca->bytes;
|
|
346
|
+
}
|
|
347
|
+
m = ALLOCV_N(boolean8_t, holder, n + n * ca->parent->bytes);
|
|
348
|
+
v = (char *) (m + n);
|
|
349
|
+
ca_xfer_stride(mask, starts, counts, mstrides, m, CA_XFER_GET);
|
|
350
|
+
ca_xfer_stride(ca->parent, starts, counts, pstrides, v, CA_XFER_GET);
|
|
351
|
+
ca_fake_cast_get(ca, n, v, (char *) data, m);
|
|
352
|
+
ALLOCV_END(holder);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
254
355
|
|
|
255
356
|
/* Fast path: fused walk + cast for GET/PUT */
|
|
256
357
|
if ( ca_xfer_stride_transform_fused((CArray *)ca, ca->parent,
|
|
@@ -282,21 +383,19 @@ static void
|
|
|
282
383
|
ca_fake_func_allocate (void *ap)
|
|
283
384
|
{
|
|
284
385
|
CAFake *ca = (CAFake *) ap;
|
|
285
|
-
|
|
286
|
-
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
386
|
+
ca->ptr = ca_alloc_cells_then_attach((CArray *) ca, 1, &ca->parent);
|
|
287
387
|
}
|
|
288
388
|
|
|
289
389
|
static void
|
|
290
390
|
ca_fake_func_attach (void *ap)
|
|
291
391
|
{
|
|
292
392
|
CAFake *ca = (CAFake *) ap;
|
|
293
|
-
|
|
294
|
-
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
393
|
+
ca->ptr = ca_alloc_cells_then_attach((CArray *) ca, 1, &ca->parent);
|
|
295
394
|
|
|
296
395
|
if ( ca->parent->mask ) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
396
|
+
ca_cast_block_skip_masked(ca->elements, ca->parent, ca->parent->ptr,
|
|
397
|
+
ca, ca->ptr,
|
|
398
|
+
(boolean8_t*)ca->parent->mask->ptr);
|
|
300
399
|
}
|
|
301
400
|
else {
|
|
302
401
|
ca_cast_block(ca->elements, ca->parent, ca->parent->ptr, ca, ca->ptr);
|
|
@@ -309,8 +408,8 @@ ca_fake_func_sync (void *ap)
|
|
|
309
408
|
CAFake *ca = (CAFake *) ap;
|
|
310
409
|
ca_update_mask(ca);
|
|
311
410
|
if ( ca->mask ) {
|
|
312
|
-
|
|
313
|
-
|
|
411
|
+
ca_cast_block_skip_masked(ca->elements, ca, ca->ptr, ca->parent, ca->parent->ptr,
|
|
412
|
+
(boolean8_t *)ca->mask->ptr);
|
|
314
413
|
}
|
|
315
414
|
else {
|
|
316
415
|
ca_cast_block(ca->elements, ca, ca->ptr, ca->parent, ca->parent->ptr);
|
|
@@ -426,9 +525,9 @@ rb_ca_fake_new (VALUE cary, int8_t data_type, ca_size_t bytes)
|
|
|
426
525
|
Both ways down stay open and say which one they are. A Numeric Face
|
|
427
526
|
is not one of these: its surface is its storage. */
|
|
428
527
|
rb_raise(rb_eTypeError,
|
|
429
|
-
"%
|
|
528
|
+
"%"PRIsVALUE" has no view of its values in another data_type: "
|
|
430
529
|
"#to_type gives the values, #parent.fake the raw storage",
|
|
431
|
-
|
|
530
|
+
rb_obj_class(cary));
|
|
432
531
|
}
|
|
433
532
|
ca = ca_fake_new(parent, data_type, bytes);
|
|
434
533
|
obj = ca_wrap_struct(ca);
|
data/ext/ca_obj_farray.c
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
#include "carray.h"
|
|
10
10
|
#include "carray_internal.h" /* ca_view_inherit_mask */
|
|
11
|
+
#include "ca_obj_face.h" /* CA_WRAPPER_LIFT */
|
|
11
12
|
|
|
12
13
|
extern ca_operation_function_t ca_stride_func;
|
|
13
14
|
|
|
@@ -87,7 +88,12 @@ rb_ca_farray_new (VALUE cary)
|
|
|
87
88
|
VALUE
|
|
88
89
|
rb_ca_farray (VALUE self)
|
|
89
90
|
{
|
|
90
|
-
|
|
91
|
+
volatile VALUE obj = rb_ca_farray_new(self);
|
|
92
|
+
CArray *ca;
|
|
93
|
+
|
|
94
|
+
TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
|
|
95
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
96
|
+
return obj;
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
static VALUE
|
data/ext/ca_obj_fixlen_string.c
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
fixlen bytes as a struct via the data_class encode/decode hooks); here
|
|
11
11
|
the bytes are the string, fetched and stored by the native fixlen path.
|
|
12
12
|
|
|
13
|
-
The Face
|
|
14
|
-
chain and
|
|
13
|
+
The Face carries the CAFixlenString class and the encoding of the text
|
|
14
|
+
across the view chain, and organises the String method surface onto a
|
|
15
|
+
dedicated class.
|
|
15
16
|
Because the storage is CA_FIXLEN (portable), the Face wrap can be carried
|
|
16
17
|
across multi-parent constructions (CAStack / Marshal / MemoryView).
|
|
17
18
|
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
#include "carray.h"
|
|
24
25
|
#include "ca_obj_face.h"
|
|
25
26
|
#include "carray_internal.h"
|
|
27
|
+
#include <ruby/encoding.h>
|
|
26
28
|
|
|
27
29
|
typedef struct {
|
|
28
30
|
/* === CAView prefix === */
|
|
@@ -39,7 +41,8 @@ typedef struct {
|
|
|
39
41
|
CArray *parent;
|
|
40
42
|
uint32_t attach;
|
|
41
43
|
uint8_t nosync;
|
|
42
|
-
/* === Face tail ===
|
|
44
|
+
/* === Face tail === */
|
|
45
|
+
int encoding_id; /* rb_enc_to_index() value of the cells' text */
|
|
43
46
|
} CAFixlenString;
|
|
44
47
|
|
|
45
48
|
static size_t
|
|
@@ -83,7 +86,7 @@ static VALUE rb_cCAFixlenString;
|
|
|
83
86
|
/* ------------------------------------------------------------------- */
|
|
84
87
|
|
|
85
88
|
int
|
|
86
|
-
ca_fixlen_string_setup (CAFixlenString *ca, CArray *parent)
|
|
89
|
+
ca_fixlen_string_setup (CAFixlenString *ca, CArray *parent, int encoding_id)
|
|
87
90
|
{
|
|
88
91
|
if ( parent->data_type != CA_FIXLEN ) {
|
|
89
92
|
rb_raise(rb_eTypeError,
|
|
@@ -136,6 +139,7 @@ ca_fixlen_string_setup (CAFixlenString *ca, CArray *parent)
|
|
|
136
139
|
ca->parent = parent;
|
|
137
140
|
ca->attach = 0;
|
|
138
141
|
ca->nosync = 0;
|
|
142
|
+
ca->encoding_id = encoding_id;
|
|
139
143
|
|
|
140
144
|
|
|
141
145
|
if ( ca_is_scalar(parent) ) {
|
|
@@ -150,12 +154,12 @@ ca_fixlen_string_setup (CAFixlenString *ca, CArray *parent)
|
|
|
150
154
|
}
|
|
151
155
|
|
|
152
156
|
CAFixlenString *
|
|
153
|
-
ca_fixlen_string_new (CArray *parent)
|
|
157
|
+
ca_fixlen_string_new (CArray *parent, int encoding_id)
|
|
154
158
|
{
|
|
155
159
|
CAFixlenString *ca;
|
|
156
|
-
ca_fixlen_string_setup(NULL, parent);
|
|
160
|
+
ca_fixlen_string_setup(NULL, parent, encoding_id);
|
|
157
161
|
ca = (CAFixlenString *) ca_array_alloc(CA_OBJ_FIXLEN_STRING, parent->ndim);
|
|
158
|
-
ca_fixlen_string_setup(ca, parent);
|
|
162
|
+
ca_fixlen_string_setup(ca, parent, encoding_id);
|
|
159
163
|
ca_fill_or_free((CArray *) ca, ca_view_inherit_mask, (VALUE) ca);
|
|
160
164
|
return ca;
|
|
161
165
|
}
|
|
@@ -182,7 +186,7 @@ static void *
|
|
|
182
186
|
ca_fixlen_string_func_clone (void *ap)
|
|
183
187
|
{
|
|
184
188
|
CAFixlenString *ca = (CAFixlenString *) ap;
|
|
185
|
-
return ca_fixlen_string_new(ca->parent);
|
|
189
|
+
return ca_fixlen_string_new(ca->parent, ca->encoding_id);
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
static void
|
|
@@ -216,9 +220,10 @@ ca_operation_function_t ca_fixlen_string_func = {
|
|
|
216
220
|
|
|
217
221
|
/* ------------------------------------------------------------------- */
|
|
218
222
|
|
|
219
|
-
/* CAFixlenString.wrap(fixlen_array) — zero-copy Face wrap
|
|
223
|
+
/* CAFixlenString.wrap(fixlen_array, encoding: nil) — zero-copy Face wrap.
|
|
224
|
+
Without an encoding the cells are bytes that claim no text encoding. */
|
|
220
225
|
VALUE
|
|
221
|
-
rb_ca_fixlen_string_wrap (VALUE parent_val)
|
|
226
|
+
rb_ca_fixlen_string_wrap (VALUE parent_val, int encoding_id)
|
|
222
227
|
{
|
|
223
228
|
volatile VALUE obj;
|
|
224
229
|
CArray *parent;
|
|
@@ -227,17 +232,41 @@ rb_ca_fixlen_string_wrap (VALUE parent_val)
|
|
|
227
232
|
rb_check_carray_object(parent_val);
|
|
228
233
|
TypedData_Get_Struct(parent_val, CArray, &carray_data_type, parent);
|
|
229
234
|
|
|
230
|
-
ca = ca_fixlen_string_new(parent);
|
|
235
|
+
ca = ca_fixlen_string_new(parent, encoding_id);
|
|
231
236
|
obj = ca_wrap_struct(ca);
|
|
232
237
|
rb_ca_set_parent(obj, parent_val);
|
|
233
238
|
return obj;
|
|
234
239
|
}
|
|
235
240
|
|
|
236
241
|
static VALUE
|
|
237
|
-
rb_ca_fixlen_string_wrap_method (VALUE
|
|
242
|
+
rb_ca_fixlen_string_wrap_method (int argc, VALUE *argv, VALUE klass)
|
|
238
243
|
{
|
|
244
|
+
VALUE raw, ropt, renc = Qnil;
|
|
239
245
|
(void) klass;
|
|
240
|
-
|
|
246
|
+
rb_scan_args(argc, argv, "1:", &raw, &ropt);
|
|
247
|
+
rb_scan_options(ropt, "encoding", &renc);
|
|
248
|
+
return rb_ca_fixlen_string_wrap(raw, NIL_P(renc) ? rb_ascii8bit_encindex()
|
|
249
|
+
: rb_to_encoding_index(renc));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* The encoding of the text in the cells; BINARY when the cells claim none. */
|
|
253
|
+
static VALUE
|
|
254
|
+
rb_ca_fixlen_string_encoding (VALUE self)
|
|
255
|
+
{
|
|
256
|
+
CAFixlenString *ca;
|
|
257
|
+
TypedData_Get_Struct(self, CAFixlenString, &cafixlen_string_data_type, ca);
|
|
258
|
+
return rb_enc_from_encoding(rb_enc_from_index(ca->encoding_id));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* Arrays of two text encodings cannot be read as one column; cells that
|
|
262
|
+
claim no encoding go with either. */
|
|
263
|
+
static int
|
|
264
|
+
ca_fixlen_string_state_compatible (CArray *a, CArray *b)
|
|
265
|
+
{
|
|
266
|
+
int ea = ((CAFixlenString *) a)->encoding_id;
|
|
267
|
+
int eb = ((CAFixlenString *) b)->encoding_id;
|
|
268
|
+
int binary = rb_ascii8bit_encindex();
|
|
269
|
+
return ( ea == eb || ea == binary || eb == binary ) ? 1 : 0;
|
|
241
270
|
}
|
|
242
271
|
|
|
243
272
|
/* Per-cell scalar decode: strip trailing NUL padding from the raw K-byte
|
|
@@ -249,14 +278,15 @@ rb_ca_fixlen_string_wrap_method (VALUE klass, VALUE raw)
|
|
|
249
278
|
static VALUE
|
|
250
279
|
rb_ca_fixlen_string_storage_to_element (VALUE self, VALUE raw)
|
|
251
280
|
{
|
|
252
|
-
(void) self;
|
|
253
281
|
if ( TYPE(raw) == T_STRING ) {
|
|
282
|
+
CAFixlenString *ca;
|
|
254
283
|
const char *p = RSTRING_PTR(raw);
|
|
255
284
|
long n = RSTRING_LEN(raw);
|
|
256
285
|
while ( n > 0 && p[n - 1] == '\0' ) {
|
|
257
286
|
n--;
|
|
258
287
|
}
|
|
259
|
-
|
|
288
|
+
TypedData_Get_Struct(self, CAFixlenString, &cafixlen_string_data_type, ca);
|
|
289
|
+
return rb_enc_str_new(p, n, rb_enc_from_index(ca->encoding_id));
|
|
260
290
|
}
|
|
261
291
|
return raw;
|
|
262
292
|
}
|
|
@@ -279,7 +309,7 @@ rb_ca_fixlen_string_initialize_copy (VALUE self, VALUE other)
|
|
|
279
309
|
if ( ca_func[CA_OBJ_FIXLEN_STRING].pool_init ) {
|
|
280
310
|
ca_array_pool_alloc(ca, CA_OBJ_FIXLEN_STRING, cs->parent->ndim);
|
|
281
311
|
}
|
|
282
|
-
ca_fixlen_string_setup(ca, cs->parent);
|
|
312
|
+
ca_fixlen_string_setup(ca, cs->parent, cs->encoding_id);
|
|
283
313
|
ca_view_inherit_mask((VALUE) ca);
|
|
284
314
|
return self;
|
|
285
315
|
}
|
|
@@ -304,7 +334,9 @@ Init_ca_obj_fixlen_string (void)
|
|
|
304
334
|
rb_define_method(rb_cCAFixlenString, "initialize_copy",
|
|
305
335
|
rb_ca_fixlen_string_initialize_copy, 1);
|
|
306
336
|
rb_define_singleton_method(rb_cCAFixlenString, "wrap",
|
|
307
|
-
rb_ca_fixlen_string_wrap_method, 1);
|
|
337
|
+
rb_ca_fixlen_string_wrap_method, -1);
|
|
338
|
+
rb_define_method(rb_cCAFixlenString, "encoding",
|
|
339
|
+
rb_ca_fixlen_string_encoding, 0);
|
|
308
340
|
rb_define_method(rb_cCAFixlenString, "storage_to_element",
|
|
309
341
|
rb_ca_fixlen_string_storage_to_element, 1);
|
|
310
342
|
ca_face_register_storage_to_element(CA_OBJ_FIXLEN_STRING,
|
|
@@ -314,6 +346,8 @@ Init_ca_obj_fixlen_string (void)
|
|
|
314
346
|
or per-parent buffer), so the Face can be carried across multi-parent
|
|
315
347
|
constructions like CAStack. */
|
|
316
348
|
ca_face_register_state_portable(CA_OBJ_FIXLEN_STRING, 1);
|
|
349
|
+
ca_face_register_state_compatible(CA_OBJ_FIXLEN_STRING,
|
|
350
|
+
ca_fixlen_string_state_compatible);
|
|
317
351
|
|
|
318
352
|
/* The bytes are the strings: a MemoryView consumer reads them as "Ns". */
|
|
319
353
|
ca_face_register_memory_view(CA_OBJ_FIXLEN_STRING, 1);
|
data/ext/ca_obj_grid.c
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
#include "carray.h"
|
|
17
17
|
#include "carray_internal.h" /* ca_attach_window */
|
|
18
|
+
#include "ca_obj_face.h" /* CA_WRAPPER_LIFT */
|
|
18
19
|
|
|
19
20
|
/* Per-axis tagged kind. Each axis is either STRIDE (start/step/count,
|
|
20
21
|
no allocation) or INDEX (an owned ca_size_t index snapshot). A Range
|
|
@@ -1087,9 +1088,11 @@ ca_grid_func_allocate (void *ap)
|
|
|
1087
1088
|
{
|
|
1088
1089
|
CAGrid *ca = (CAGrid *) ap;
|
|
1089
1090
|
if ( ! cag_owns_buffer(ca) ) {
|
|
1090
|
-
|
|
1091
|
+
ca->ptr = ca_alloc_cells_then_attach((CArray *) ca, 1, &ca->parent);
|
|
1092
|
+
}
|
|
1093
|
+
else {
|
|
1094
|
+
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1091
1095
|
}
|
|
1092
|
-
ca->ptr = ca_alloc_cells((CArray *) ca);
|
|
1093
1096
|
}
|
|
1094
1097
|
|
|
1095
1098
|
static void
|
|
@@ -1104,10 +1107,10 @@ ca_grid_func_attach (void *ap)
|
|
|
1104
1107
|
return;
|
|
1105
1108
|
}
|
|
1106
1109
|
|
|
1107
|
-
|
|
1110
|
+
ca->ptr = ca_alloc_cells_then_attach((CArray *) ca, 1, &ca->parent);
|
|
1108
1111
|
ca_grid_describe_axes(ca, desc, pdims);
|
|
1109
|
-
|
|
1110
|
-
|
|
1112
|
+
ca_axis_dispatch_gather(ca->parent, pdims, desc, ca->ndim,
|
|
1113
|
+
ca->bytes, ca->elements, NULL, ca->ptr);
|
|
1111
1114
|
}
|
|
1112
1115
|
|
|
1113
1116
|
static void
|
|
@@ -1422,8 +1425,9 @@ rb_ca_grid (int argc, VALUE *argv, VALUE self)
|
|
|
1422
1425
|
extern int ca_csa_dispatch_bypass;
|
|
1423
1426
|
if ( ! ca_csa_dispatch_bypass && argc > 0 && TYPE(argv[0]) == T_DATA ) {
|
|
1424
1427
|
if ( rb_ca_select_axis_eligible_p(argc, argv, self) ) {
|
|
1425
|
-
|
|
1426
|
-
|
|
1428
|
+
obj = rb_ca_select_axis(argc, argv, self);
|
|
1429
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
1430
|
+
return ca_grid_drop_scalar_axes(obj, argc, argv);
|
|
1427
1431
|
}
|
|
1428
1432
|
}
|
|
1429
1433
|
|
|
@@ -1492,6 +1496,7 @@ rb_ca_grid (int argc, VALUE *argv, VALUE self)
|
|
|
1492
1496
|
(VALUE) &c);
|
|
1493
1497
|
}
|
|
1494
1498
|
|
|
1499
|
+
CA_WRAPPER_LIFT(obj, self, ca);
|
|
1495
1500
|
return ca_grid_drop_scalar_axes(obj, argc, argv);
|
|
1496
1501
|
}
|
|
1497
1502
|
|