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.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +469 -0
  3. data/README.md +3 -2
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_descriptor.h +27 -24
  7. data/ext/ca_axis_dispatch.c +14 -26
  8. data/ext/ca_axis_group.c +27 -27
  9. data/ext/ca_binop_dispatch.c +1 -29
  10. data/ext/ca_binop_dispatch.h +0 -1
  11. data/ext/ca_categorical_iterator.c +231 -153
  12. data/ext/ca_compare.c +9 -20
  13. data/ext/ca_composite_dispatch.c +9 -9
  14. data/ext/ca_group_iter.c +16 -17
  15. data/ext/ca_kernel_iterator.c +1240 -2000
  16. data/ext/ca_kernel_iterator.h +502 -519
  17. data/ext/ca_monop_dispatch.c +82 -59
  18. data/ext/ca_monop_dispatch.h +1 -0
  19. data/ext/ca_obj_array.c +152 -45
  20. data/ext/ca_obj_bincmp.c +25 -21
  21. data/ext/ca_obj_binop.c +16 -26
  22. data/ext/ca_obj_bitarray.c +8 -3
  23. data/ext/ca_obj_bitfield.c +63 -49
  24. data/ext/ca_obj_block.c +18 -9
  25. data/ext/ca_obj_byte_swap.c +7 -7
  26. data/ext/ca_obj_const_string.c +188 -22
  27. data/ext/ca_obj_face.c +280 -58
  28. data/ext/ca_obj_face.h +19 -0
  29. data/ext/ca_obj_fake.c +15 -29
  30. data/ext/ca_obj_farray.c +6 -3
  31. data/ext/ca_obj_field.c +30 -8
  32. data/ext/ca_obj_fixlen_string.c +2 -3
  33. data/ext/ca_obj_grid.c +455 -134
  34. data/ext/ca_obj_meld.c +172 -34
  35. data/ext/ca_obj_moncmp.c +23 -8
  36. data/ext/ca_obj_monop.c +113 -67
  37. data/ext/ca_obj_object.c +210 -52
  38. data/ext/ca_obj_record.c +15 -7
  39. data/ext/ca_obj_reduce.c +17 -8
  40. data/ext/ca_obj_refer.c +42 -35
  41. data/ext/ca_obj_remap.c +30 -9
  42. data/ext/ca_obj_repeat.c +9 -10
  43. data/ext/ca_obj_roll.c +31 -10
  44. data/ext/ca_obj_select.c +48 -14
  45. data/ext/ca_obj_select_axis.c +15 -47
  46. data/ext/ca_obj_shift.c +41 -7
  47. data/ext/ca_obj_stack.c +180 -34
  48. data/ext/ca_obj_stride.c +190 -134
  49. data/ext/ca_obj_string.c +80 -4
  50. data/ext/ca_obj_tile.c +32 -11
  51. data/ext/ca_obj_time.c +22 -6
  52. data/ext/ca_obj_timedelta.c +22 -6
  53. data/ext/ca_obj_transpose.c +13 -7
  54. data/ext/ca_obj_triop.c +26 -32
  55. data/ext/ca_obj_window.c +267 -74
  56. data/ext/ca_op_ipower.c +4 -4
  57. data/ext/ca_sort_kernels.h +6 -3
  58. data/ext/ca_sweep_engine.c +2 -2
  59. data/ext/caframe_csv_reader.c +80 -1
  60. data/ext/carray.h +214 -75
  61. data/ext/carray_access.c +200 -99
  62. data/ext/carray_address_basis.c +343 -87
  63. data/ext/carray_attribute.c +113 -6
  64. data/ext/carray_bincount.c +10 -8
  65. data/ext/carray_broadcast.c +13 -8
  66. data/ext/carray_build_flags.h +3 -0
  67. data/ext/carray_call_cfunc.c +108 -0
  68. data/ext/carray_cast.c +375 -96
  69. data/ext/carray_cast_func.rb +90 -20
  70. data/ext/carray_class.c +4 -3
  71. data/ext/carray_config.h +28 -0
  72. data/ext/carray_conversion.c +18 -9
  73. data/ext/carray_copy.c +51 -14
  74. data/ext/carray_core.c +150 -55
  75. data/ext/carray_count.c +56 -20
  76. data/ext/carray_element.c +81 -33
  77. data/ext/carray_factorize.c +138 -84
  78. data/ext/carray_generate.c +199 -52
  79. data/ext/carray_histogram.c +63 -18
  80. data/ext/carray_hold.c +12 -15
  81. data/ext/carray_index_classifier.c +388 -176
  82. data/ext/carray_internal.h +348 -29
  83. data/ext/carray_kernels_bincmp.c +4453 -0
  84. data/ext/carray_kernels_binop.c +11368 -0
  85. data/ext/carray_kernels_init.c +1734 -0
  86. data/ext/carray_kernels_moncmp.c +2104 -0
  87. data/ext/carray_kernels_monop.c +18369 -0
  88. data/ext/carray_kernels_reduce_aggregate.c +23818 -0
  89. data/ext/carray_kernels_reduce_boolean.c +406 -0
  90. data/ext/carray_kernels_reduce_cumulative.c +10086 -0
  91. data/ext/carray_kernels_reduce_extreme.c +17634 -0
  92. data/ext/carray_kernels_reduce_variance.c +3849 -0
  93. data/ext/carray_kernels_scan.c +4302 -0
  94. data/ext/carray_kernels_search.c +33829 -0
  95. data/ext/carray_kernels_sort.c +10897 -0
  96. data/ext/carray_kernels_triop.c +1864 -0
  97. data/ext/carray_key_windows.c +220 -0
  98. data/ext/carray_lazy.c +170 -111
  99. data/ext/carray_mask.c +337 -94
  100. data/ext/carray_median_percentile.c +82 -28
  101. data/ext/carray_memory_view.c +669 -561
  102. data/ext/carray_operator.c +129 -52
  103. data/ext/carray_order.c +604 -77
  104. data/ext/carray_partition.c +28 -27
  105. data/ext/carray_random.c +85 -31
  106. data/ext/carray_round.c +273 -0
  107. data/ext/carray_scatter.c +87 -45
  108. data/ext/carray_segment.c +3 -3
  109. data/ext/carray_slab.c +123 -37
  110. data/ext/carray_sort.c +259 -51
  111. data/ext/carray_sort_kernel.c +5 -7
  112. data/ext/carray_struct.c +54 -61
  113. data/ext/carray_test.c +26 -5
  114. data/ext/carray_time_text.c +4 -2
  115. data/ext/carray_undef.c +4 -0
  116. data/ext/carray_utils.c +309 -66
  117. data/ext/mk_call_cfunc.rb +19 -2
  118. data/ext/mkkernel.rb +403 -350
  119. data/ext/ruby_carray.c +10 -4
  120. data/ext/version.h +4 -4
  121. data/lib/carray/attribute.rb +139 -22
  122. data/lib/carray/autoload_carray.rb +8 -31
  123. data/lib/carray/autoload_method_extension.rb +14 -5
  124. data/lib/carray/axis_group.rb +255 -106
  125. data/lib/carray/basics.rb +105 -17
  126. data/lib/carray/bincount_nd.rb +12 -2
  127. data/lib/carray/block_iterator.rb +126 -23
  128. data/lib/carray/boolean_reduce.rb +17 -17
  129. data/lib/carray/categorical.rb +195 -59
  130. data/lib/carray/categorical_iterator.rb +132 -29
  131. data/lib/carray/complex.rb +5 -5
  132. data/lib/carray/conditional.rb +67 -18
  133. data/lib/carray/const_string.rb +24 -5
  134. data/lib/carray/construct.rb +15 -11
  135. data/lib/carray/data_type_extension.rb +9 -1
  136. data/lib/carray/distance_limit.rb +77 -0
  137. data/lib/carray/fixlen_string.rb +48 -3
  138. data/lib/carray/frame/column_verbs.rb +71 -0
  139. data/lib/carray/frame/concat.rb +17 -3
  140. data/lib/carray/frame/convert.rb +69 -0
  141. data/lib/carray/frame/csv_parser.rb +111 -17
  142. data/lib/carray/frame/describe.rb +3 -2
  143. data/lib/carray/frame/frame.rb +252 -28
  144. data/lib/carray/frame/group.rb +603 -101
  145. data/lib/carray/frame/io.rb +117 -28
  146. data/lib/carray/frame/join.rb +312 -51
  147. data/lib/carray/frame/records.rb +83 -7
  148. data/lib/carray/frame/reshape.rb +42 -35
  149. data/lib/carray/frame/sort.rb +7 -19
  150. data/lib/carray/frame/verbs.rb +188 -48
  151. data/lib/carray/frame/windows.rb +117 -0
  152. data/lib/carray/frame.rb +2 -0
  153. data/lib/carray/fuse_source.rb +42 -6
  154. data/lib/carray/fusion.rb +40 -16
  155. data/lib/carray/histogram.rb +6 -1
  156. data/lib/carray/inspect.rb +31 -8
  157. data/lib/carray/iterator.rb +85 -7
  158. data/lib/carray/key_windows.rb +620 -0
  159. data/lib/carray/lazy.rb +217 -183
  160. data/lib/carray/mask_gap_fill.rb +63 -57
  161. data/lib/carray/meld_reduce.rb +12 -14
  162. data/lib/carray/methods/bin.rb +26 -18
  163. data/lib/carray/methods/bincount.rb +16 -0
  164. data/lib/carray/methods/bit_string.rb +1 -1
  165. data/lib/carray/methods/choose.rb +16 -3
  166. data/lib/carray/methods/composition.rb +3 -1
  167. data/lib/carray/methods/gather_nd.rb +14 -5
  168. data/lib/carray/methods/insert_block.rb +2 -2
  169. data/lib/carray/methods/is_between.rb +59 -0
  170. data/lib/carray/methods/is_in.rb +61 -37
  171. data/lib/carray/methods/join.rb +1 -6
  172. data/lib/carray/methods/lag.rb +49 -0
  173. data/lib/carray/methods/locate_addr.rb +47 -51
  174. data/lib/carray/methods/mode.rb +1 -1
  175. data/lib/carray/methods/nunique.rb +11 -6
  176. data/lib/carray/methods/resize.rb +3 -3
  177. data/lib/carray/methods/value_counts.rb +4 -11
  178. data/lib/carray/record_order.rb +3 -3
  179. data/lib/carray/rng.rb +3 -0
  180. data/lib/carray/runtime.rb +53 -8
  181. data/lib/carray/segment_iterator.rb +323 -88
  182. data/lib/carray/serialize.rb +45 -14
  183. data/lib/carray/slab_iterator.rb +50 -0
  184. data/lib/carray/stack.rb +15 -12
  185. data/lib/carray/string.rb +113 -5
  186. data/lib/carray/string_operation_extension.rb +21 -6
  187. data/lib/carray/struct.rb +9 -21
  188. data/lib/carray/struct_builder.rb +24 -11
  189. data/lib/carray/time.rb +819 -158
  190. data/lib/carray/window_iterator.rb +122 -16
  191. data/lib/carray.rb +7 -0
  192. data/yard-stubs/ca_obj_bitfield.rb +1 -1
  193. data/yard-stubs/ca_obj_field.rb +4 -0
  194. data/yard-stubs/ca_obj_grid.rb +21 -10
  195. data/yard-stubs/ca_obj_refer.rb +2 -1
  196. data/yard-stubs/ca_obj_roll.rb +2 -2
  197. data/yard-stubs/ca_obj_shift.rb +5 -1
  198. data/yard-stubs/ca_obj_tile.rb +1 -1
  199. data/yard-stubs/ca_obj_transpose.rb +5 -4
  200. data/yard-stubs/ca_obj_window.rb +8 -3
  201. data/yard-stubs/carray_access.rb +6 -1
  202. data/yard-stubs/carray_attribute.rb +3 -6
  203. data/yard-stubs/carray_cast.rb +12 -0
  204. data/yard-stubs/carray_conversion.rb +7 -2
  205. data/yard-stubs/carray_copy.rb +4 -2
  206. data/yard-stubs/carray_count.rb +4 -4
  207. data/yard-stubs/carray_element.rb +17 -10
  208. data/yard-stubs/carray_generate.rb +21 -1
  209. data/yard-stubs/carray_mask.rb +32 -3
  210. data/yard-stubs/carray_math.rb +41 -5
  211. data/yard-stubs/carray_median_percentile.rb +5 -2
  212. data/yard-stubs/carray_memory_view.rb +40 -23
  213. data/yard-stubs/carray_order.rb +129 -22
  214. data/yard-stubs/carray_random.rb +13 -4
  215. data/yard-stubs/carray_scatter.rb +17 -10
  216. data/yard-stubs/carray_slab.rb +9 -2
  217. data/yard-stubs/carray_sort.rb +6 -5
  218. data/yard-stubs/carray_test.rb +5 -3
  219. metadata +25 -3
  220. data/lib/carray/arrow_tensor.rb +0 -401
  221. data/lib/carray/table.rb +0 -108
@@ -45,67 +45,67 @@
45
45
  /* op_id -> kernel table lookup */
46
46
  /* ------------------------------------------------------------------- */
47
47
 
48
- /* Returns the kernel for the given input data_type. Returns NULL for
49
- cast ops (op_id >= CA_MONOP_CAST_BASE) and unknown op_ids; cast is
50
- handled specially in xfer_stride via ca_cast_block. */
51
- ca_monop_func_t
52
- ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type)
48
+ /* The kernel table of an op, or NULL for cast ops (op_id >=
49
+ CA_MONOP_CAST_BASE) and unknown op_ids; cast is handled specially in
50
+ xfer_stride via ca_cast_block. */
51
+ static ca_monop_func_t *
52
+ ca_monop_table_of (uint16_t op_id)
53
53
  {
54
54
  switch (op_id) {
55
- case CA_MONOP_ZERO: return ca_monop_zero[in_data_type];
56
- case CA_MONOP_ONE: return ca_monop_one[in_data_type];
57
- case CA_MONOP_FRAC: return ca_monop_frac[in_data_type];
58
- case CA_MONOP_NEG: return ca_monop_neg[in_data_type];
59
- case CA_MONOP_BIT_NEG: return ca_monop_bit_neg[in_data_type];
60
- case CA_MONOP_ABS_I: return ca_monop_abs_i[in_data_type];
61
- case CA_MONOP_CONJ: return ca_monop_conj[in_data_type];
62
- case CA_MONOP_NOT: return ca_monop_not[in_data_type];
63
-
64
- case CA_MONOP_CEIL: return ca_monop_ceil[in_data_type];
65
- case CA_MONOP_FLOOR: return ca_monop_floor[in_data_type];
66
- case CA_MONOP_ROUND: return ca_monop_round[in_data_type];
67
- case CA_MONOP_RCP: return ca_monop_rcp[in_data_type];
68
-
69
- case CA_MONOP_RAD: return ca_monop_rad[in_data_type];
70
- case CA_MONOP_DEG: return ca_monop_deg[in_data_type];
71
- case CA_MONOP_SQRT: return ca_monop_sqrt[in_data_type];
72
- case CA_MONOP_EXP: return ca_monop_exp[in_data_type];
73
- case CA_MONOP_EXP2: return ca_monop_exp2[in_data_type];
74
- case CA_MONOP_EXP10: return ca_monop_exp10[in_data_type];
75
- case CA_MONOP_LOG: return ca_monop_log[in_data_type];
76
- case CA_MONOP_LOG10: return ca_monop_log10[in_data_type];
77
- case CA_MONOP_LOG2: return ca_monop_log2[in_data_type];
78
- case CA_MONOP_LOGB: return ca_monop_logb[in_data_type];
79
- case CA_MONOP_SIN: return ca_monop_sin[in_data_type];
80
- case CA_MONOP_COS: return ca_monop_cos[in_data_type];
81
- case CA_MONOP_TAN: return ca_monop_tan[in_data_type];
82
- case CA_MONOP_ASIN: return ca_monop_asin[in_data_type];
83
- case CA_MONOP_ACOS: return ca_monop_acos[in_data_type];
84
- case CA_MONOP_ATAN: return ca_monop_atan[in_data_type];
85
- case CA_MONOP_SINH: return ca_monop_sinh[in_data_type];
86
- case CA_MONOP_COSH: return ca_monop_cosh[in_data_type];
87
- case CA_MONOP_TANH: return ca_monop_tanh[in_data_type];
88
- case CA_MONOP_ASINH: return ca_monop_asinh[in_data_type];
89
- case CA_MONOP_ACOSH: return ca_monop_acosh[in_data_type];
90
- case CA_MONOP_ATANH: return ca_monop_atanh[in_data_type];
91
-
92
- case CA_MONOP_BYTE_SWAP: return ca_monop_byte_swap[in_data_type];
93
-
94
- case CA_MONOP_IMAG_I: return ca_monop_imag_i[in_data_type];
95
-
96
- case CA_MONOP_EXPM1: return ca_monop_expm1 [in_data_type];
97
- case CA_MONOP_LOG1P: return ca_monop_log1p [in_data_type];
98
- case CA_MONOP_RSQRT: return ca_monop_rsqrt [in_data_type];
99
- case CA_MONOP_TRUNC: return ca_monop_trunc [in_data_type];
100
- case CA_MONOP_SQUARE: return ca_monop_square[in_data_type];
101
-
102
- case CA_MONOP_DEG_360: return ca_monop_deg_360[in_data_type];
103
- case CA_MONOP_DEG_180: return ca_monop_deg_180[in_data_type];
104
- case CA_MONOP_RAD_2PI: return ca_monop_rad_2pi[in_data_type];
105
- case CA_MONOP_RAD_PI: return ca_monop_rad_pi [in_data_type];
106
-
107
- case CA_MONOP_SIGN: return ca_monop_sign [in_data_type];
108
- case CA_MONOP_ARG_I: return ca_monop_arg_i [in_data_type];
55
+ case CA_MONOP_ZERO: return ca_monop_zero;
56
+ case CA_MONOP_ONE: return ca_monop_one;
57
+ case CA_MONOP_FRAC: return ca_monop_frac;
58
+ case CA_MONOP_NEG: return ca_monop_neg;
59
+ case CA_MONOP_BIT_NEG: return ca_monop_bit_neg;
60
+ case CA_MONOP_ABS_I: return ca_monop_abs_i;
61
+ case CA_MONOP_CONJ: return ca_monop_conj;
62
+ case CA_MONOP_NOT: return ca_monop_not;
63
+
64
+ case CA_MONOP_CEIL: return ca_monop_ceil;
65
+ case CA_MONOP_FLOOR: return ca_monop_floor;
66
+ case CA_MONOP_ROUND: return ca_monop_round;
67
+ case CA_MONOP_RCP: return ca_monop_rcp;
68
+
69
+ case CA_MONOP_RAD: return ca_monop_rad;
70
+ case CA_MONOP_DEG: return ca_monop_deg;
71
+ case CA_MONOP_SQRT: return ca_monop_sqrt;
72
+ case CA_MONOP_EXP: return ca_monop_exp;
73
+ case CA_MONOP_EXP2: return ca_monop_exp2;
74
+ case CA_MONOP_EXP10: return ca_monop_exp10;
75
+ case CA_MONOP_LOG: return ca_monop_log;
76
+ case CA_MONOP_LOG10: return ca_monop_log10;
77
+ case CA_MONOP_LOG2: return ca_monop_log2;
78
+ case CA_MONOP_LOGB: return ca_monop_logb;
79
+ case CA_MONOP_SIN: return ca_monop_sin;
80
+ case CA_MONOP_COS: return ca_monop_cos;
81
+ case CA_MONOP_TAN: return ca_monop_tan;
82
+ case CA_MONOP_ASIN: return ca_monop_asin;
83
+ case CA_MONOP_ACOS: return ca_monop_acos;
84
+ case CA_MONOP_ATAN: return ca_monop_atan;
85
+ case CA_MONOP_SINH: return ca_monop_sinh;
86
+ case CA_MONOP_COSH: return ca_monop_cosh;
87
+ case CA_MONOP_TANH: return ca_monop_tanh;
88
+ case CA_MONOP_ASINH: return ca_monop_asinh;
89
+ case CA_MONOP_ACOSH: return ca_monop_acosh;
90
+ case CA_MONOP_ATANH: return ca_monop_atanh;
91
+
92
+ case CA_MONOP_BYTE_SWAP: return ca_monop_byte_swap;
93
+
94
+ case CA_MONOP_IMAG_I: return ca_monop_imag_i;
95
+
96
+ case CA_MONOP_EXPM1: return ca_monop_expm1;
97
+ case CA_MONOP_LOG1P: return ca_monop_log1p;
98
+ case CA_MONOP_RSQRT: return ca_monop_rsqrt;
99
+ case CA_MONOP_TRUNC: return ca_monop_trunc;
100
+ case CA_MONOP_SQUARE: return ca_monop_square;
101
+
102
+ case CA_MONOP_DEG_360: return ca_monop_deg_360;
103
+ case CA_MONOP_DEG_180: return ca_monop_deg_180;
104
+ case CA_MONOP_RAD_2PI: return ca_monop_rad_2pi;
105
+ case CA_MONOP_RAD_PI: return ca_monop_rad_pi;
106
+
107
+ case CA_MONOP_SIGN: return ca_monop_sign;
108
+ case CA_MONOP_ARG_I: return ca_monop_arg_i;
109
109
 
110
110
  default:
111
111
  /* Cast ops or unknown — caller handles cast specially. */
@@ -113,6 +113,29 @@ ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type)
113
113
  }
114
114
  }
115
115
 
116
+ /* Returns the kernel for the given input data_type. Returns NULL for
117
+ cast ops and unknown op_ids. */
118
+ ca_monop_func_t
119
+ ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type)
120
+ {
121
+ ca_monop_func_t *table = ca_monop_table_of(op_id);
122
+ return table ? table[in_data_type] : NULL;
123
+ }
124
+
125
+ /* The op id whose kernel table is `table`, or -1 for a table no op id
126
+ names. */
127
+ int
128
+ ca_monop_op_id_of_table (ca_monop_func_t table[])
129
+ {
130
+ int op_id;
131
+ for ( op_id = 0; op_id < CA_MONOP_CAST_BASE; op_id++ ) {
132
+ if ( ca_monop_table_of((uint16_t) op_id) == table ) return op_id;
133
+ }
134
+ return -1;
135
+ }
136
+
137
+
138
+
116
139
  /* ------------------------------------------------------------------- */
117
140
  /* op category predicates */
118
141
  /* ------------------------------------------------------------------- */
@@ -190,6 +190,7 @@ extern ca_monop_func_t ca_monop_arg_i [CA_NTYPE];
190
190
  /* Look up the per-data_type kernel for a normal monop op_id. Returns NULL
191
191
  for cast op_ids (caller handles cast via ca_cast_block). */
192
192
  ca_monop_func_t ca_monop_kernel_lookup (uint16_t op_id, int8_t in_data_type);
193
+ int ca_monop_op_id_of_table (ca_monop_func_t table[]);
193
194
 
194
195
  /* Returns true iff op_id encodes a cast operation. */
195
196
  int ca_monop_is_cast (uint16_t op_id);
data/ext/ca_obj_array.c CHANGED
@@ -61,7 +61,10 @@ const rb_data_type_t carray_data_type = {
61
61
  .dsize = ca_dsize,
62
62
  .dcompact = NULL
63
63
  },
64
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
64
+ /* A frozen entity is shared between Ractors: reading it writes nothing
65
+ to its struct (an entity takes no attach count), so each Ractor makes
66
+ its own views of it. */
67
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE,
65
68
  };
66
69
 
67
70
  const rb_data_type_t cawrap_data_type = {
@@ -85,7 +88,10 @@ const rb_data_type_t cscalar_data_type = {
85
88
  .dsize = ca_dsize,
86
89
  .dcompact = NULL
87
90
  },
88
- .flags = RUBY_TYPED_FREE_IMMEDIATELY
91
+ /* A frozen entity is shared between Ractors: reading it writes nothing
92
+ to its struct (an entity takes no attach count), so each Ractor makes
93
+ its own views of it. */
94
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE
89
95
  };
90
96
 
91
97
  const rb_data_type_t caview_data_type = {
@@ -138,14 +144,13 @@ carray_setup_i (CArray *ca,
138
144
  CArray *mask, int allocate, int use_calloc, char *adopt_ptr)
139
145
  {
140
146
  ca_size_t elements;
141
- int8_t i;
142
147
  ca_size_t k;
143
148
 
144
149
  /* check arguments */
145
- CA_CHECK_DATA_TYPE(data_type);
146
- CA_CHECK_RANK(ndim);
147
- CA_CHECK_DIM(ndim, dim);
148
- CA_CHECK_BYTES(data_type, bytes);
150
+ CA_CHECK_DATA_TYPE_GIVEN(data_type);
151
+ CA_CHECK_RANK_GIVEN(ndim);
152
+ CA_CHECK_DIM_GIVEN(ndim, dim);
153
+ CA_CHECK_BYTES_GIVEN(data_type, bytes);
149
154
 
150
155
  elements = ca_shape_elements(ndim, dim, bytes);
151
156
 
@@ -190,16 +195,14 @@ carray_setup_i (CArray *ca,
190
195
 
191
196
  /* allocate memory for entity */
192
197
  if ( use_calloc ) {
193
- /* ca->ptr = ALLOC_N(char, elements * bytes); */
194
- ca->ptr = xmalloc(elements * bytes);
198
+ ca->ptr = xmalloc(elements * bytes); /* cells: set to 0 below */
195
199
  MEMZERO(ca->ptr, char, elements * bytes);
196
200
  }
197
201
  else {
198
- /* ca->ptr = ALLOC_N(char, elements * bytes); */
199
- ca->ptr = xmalloc(elements * bytes);
202
+ ca->ptr = xmalloc(elements * bytes); /* cells: set to 0 below */
200
203
  }
201
204
 
202
- /* initialize elements with Qnil for CA_OBJECT data_type */
205
+ /* an object array starts with every cell 0 */
203
206
  if ( allocate && data_type == CA_OBJECT ) {
204
207
  volatile VALUE zero = SIZE2NUM(0);
205
208
  VALUE *p = (VALUE *) ca->ptr;
@@ -215,6 +218,7 @@ carray_setup_i (CArray *ca,
215
218
 
216
219
  ca->mask = NULL;
217
220
  if ( mask ) {
221
+ /* mask: only initialize_copy passes one, on a struct Ruby owns */
218
222
  ca_setup_mask(ca, mask);
219
223
  }
220
224
 
@@ -243,9 +247,12 @@ ca_wrap_setup (CArray *ca,
243
247
  int ret;
244
248
 
245
249
  ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
246
- if ( (!ptr) && (ca->elements != 0) ) {
250
+ if ( (!ptr) && ca_shape_elements(ndim, dim, bytes) != 0 ) {
247
251
  rb_raise(rb_eRuntimeError, "wrapping NULL pointer with an non-empty array");
248
252
  }
253
+ if ( ca == NULL ) { /* checks only */
254
+ return ret;
255
+ }
249
256
  ca->ptr = ptr;
250
257
  return ret;
251
258
  }
@@ -258,30 +265,83 @@ ca_wrap_setup_null (CArray *ca,
258
265
  int ret;
259
266
 
260
267
  ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
261
- ca->ptr = NULL;
268
+ if ( ca != NULL ) {
269
+ ca->ptr = NULL;
270
+ }
262
271
  return ret;
263
272
  }
264
273
 
274
+ static VALUE
275
+ carray_new_copy_mask (VALUE arg)
276
+ {
277
+ void **a = (void **) arg;
278
+ ca_setup_mask((CArray *) a[0], (CArray *) a[1]);
279
+ return Qnil;
280
+ }
281
+
282
+ /* Reading the mask to copy can call Ruby (a CAObject's mask hooks) and
283
+ raise, while the new array belongs to no Ruby object yet. The array is
284
+ built without it, and the mask is copied in under ca_fill_or_free. */
285
+ static CArray *
286
+ carray_new_with_mask (CArray *ca, CArray *mask)
287
+ {
288
+ if ( mask ) {
289
+ void *a[2];
290
+ a[0] = ca;
291
+ a[1] = mask;
292
+ ca_fill_or_free(ca, carray_new_copy_mask, (VALUE) a);
293
+ }
294
+ return ca;
295
+ }
296
+
297
+ typedef struct {
298
+ CArray *ca;
299
+ int8_t data_type;
300
+ int8_t ndim;
301
+ ca_size_t *dim;
302
+ ca_size_t bytes;
303
+ int use_calloc;
304
+ } carray_new_arg;
305
+
306
+ static VALUE
307
+ carray_new_setup (VALUE varg)
308
+ {
309
+ carray_new_arg *a = (carray_new_arg *) varg;
310
+ carray_setup_i(a->ca, a->data_type, a->ndim, a->dim, a->bytes, NULL,
311
+ 1, a->use_calloc, NULL);
312
+ return Qnil;
313
+ }
314
+
315
+ /* The setup allocates the cells, after the struct: when that fails, the
316
+ struct goes too. */
317
+ static CArray *
318
+ carray_new_i (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
319
+ CArray *mask, int use_calloc)
320
+ {
321
+ carray_new_arg a;
322
+ carray_setup_i(NULL, data_type, ndim, dim, bytes, NULL, 1, use_calloc, NULL);
323
+ a.ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
324
+ a.data_type = data_type;
325
+ a.ndim = ndim;
326
+ a.dim = dim;
327
+ a.bytes = bytes;
328
+ a.use_calloc = use_calloc;
329
+ ca_fill_or_free(a.ca, carray_new_setup, (VALUE) &a);
330
+ return carray_new_with_mask(a.ca, mask);
331
+ }
332
+
265
333
  CArray *
266
334
  carray_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
267
335
  CArray *mask)
268
336
  {
269
- CArray *ca;
270
- carray_setup(NULL, data_type, ndim, dim, bytes, mask);
271
- ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
272
- carray_setup(ca, data_type, ndim, dim, bytes, mask);
273
- return ca;
337
+ return carray_new_i(data_type, ndim, dim, bytes, mask, 0);
274
338
  }
275
339
 
276
340
  CArray *
277
341
  carray_new_safe (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
278
342
  CArray *mask)
279
343
  {
280
- CArray *ca;
281
- carray_safe_setup(NULL, data_type, ndim, dim, bytes, mask);
282
- ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
283
- carray_safe_setup(ca, data_type, ndim, dim, bytes, mask);
284
- return ca;
344
+ return carray_new_i(data_type, ndim, dim, bytes, mask, 1);
285
345
  }
286
346
 
287
347
  /* Create an entity that adopts a caller-provided data buffer instead of
@@ -297,6 +357,7 @@ carray_new_adopt (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes
297
357
  if ( ! ptr ) {
298
358
  rb_raise(rb_eRuntimeError, "carray_new_adopt: NULL data pointer");
299
359
  }
360
+ carray_setup_i(NULL, data_type, ndim, dim, bytes, NULL, 0, 0, ptr);
300
361
  ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
301
362
  carray_setup_i(ca, data_type, ndim, dim, bytes, NULL, 0, 0, ptr);
302
363
  return ca;
@@ -306,18 +367,22 @@ CAWrap *
306
367
  ca_wrap_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
307
368
  CArray *mask, char *ptr)
308
369
  {
309
- CAWrap *ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
310
- ca_wrap_setup(ca, data_type, ndim, dim, bytes, mask, ptr);
311
- return ca;
370
+ CAWrap *ca;
371
+ ca_wrap_setup(NULL, data_type, ndim, dim, bytes, NULL, ptr);
372
+ ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
373
+ ca_wrap_setup(ca, data_type, ndim, dim, bytes, NULL, ptr);
374
+ return (CAWrap *) carray_new_with_mask((CArray *) ca, mask);
312
375
  }
313
376
 
314
377
  CAWrap *
315
378
  ca_wrap_new_null (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
316
379
  CArray *mask)
317
380
  {
318
- CAWrap *ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
319
- ca_wrap_setup_null(ca, data_type, ndim, dim, bytes, mask);
320
- return ca;
381
+ CAWrap *ca;
382
+ ca_wrap_setup_null(NULL, data_type, ndim, dim, bytes, NULL);
383
+ ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
384
+ ca_wrap_setup_null(ca, data_type, ndim, dim, bytes, NULL);
385
+ return (CAWrap *) carray_new_with_mask((CArray *) ca, mask);
321
386
  }
322
387
 
323
388
  void
@@ -360,8 +425,14 @@ static int
360
425
  cscalar_setup (CScalar *ca,
361
426
  int8_t data_type, ca_size_t bytes, CArray *mask)
362
427
  {
363
- CA_CHECK_DATA_TYPE(data_type);
364
- CA_CHECK_BYTES(data_type, bytes);
428
+ CA_CHECK_DATA_TYPE_GIVEN(data_type);
429
+ CA_CHECK_BYTES_GIVEN(data_type, bytes);
430
+
431
+ /* ca == NULL asks for the checks above only, so that a constructor can
432
+ run them before it allocates. */
433
+ if ( ca == NULL ) {
434
+ return 0;
435
+ }
365
436
 
366
437
  ca->obj_type = CA_OBJ_SCALAR;
367
438
  ca->data_type = data_type;
@@ -370,7 +441,7 @@ cscalar_setup (CScalar *ca,
370
441
  ca->bytes = bytes;
371
442
  ca->elements = 1;
372
443
  ca->dim = &(ca->_dim);
373
- ca->ptr = xmalloc(bytes);
444
+ ca->ptr = xmalloc(bytes); /* cells: the one cell is set to 0 below */
374
445
  ca->mask = NULL;
375
446
 
376
447
  ca->dim[0] = 1;
@@ -383,6 +454,7 @@ cscalar_setup (CScalar *ca,
383
454
  }
384
455
 
385
456
  if ( mask ) {
457
+ /* mask: the constructors pass none (carray_new_with_mask copies it) */
386
458
  ca_setup_mask((CArray *)ca, mask);
387
459
  }
388
460
 
@@ -395,12 +467,40 @@ cscalar_setup (CScalar *ca,
395
467
  * constructs a CScalar struct without initialization
396
468
  */
397
469
 
470
+ typedef struct {
471
+ CScalar *ca;
472
+ int8_t data_type;
473
+ ca_size_t bytes;
474
+ } cscalar_new_arg;
475
+
476
+ static VALUE
477
+ cscalar_new_setup (VALUE varg)
478
+ {
479
+ cscalar_new_arg *a = (cscalar_new_arg *) varg;
480
+ cscalar_setup(a->ca, a->data_type, a->bytes, NULL);
481
+ return Qnil;
482
+ }
483
+
484
+ /* The setup allocates the cell after the struct: when that fails, the
485
+ struct goes too. It goes by xfree, not ca_free, because its ptr was
486
+ never set. */
487
+ static CScalar *
488
+ cscalar_new_i (int8_t data_type, ca_size_t bytes)
489
+ {
490
+ cscalar_new_arg a;
491
+ cscalar_setup(NULL, data_type, bytes, NULL);
492
+ a.ca = ALLOC(CScalar);
493
+ a.data_type = data_type;
494
+ a.bytes = bytes;
495
+ ca_fill_or_xfree(a.ca, cscalar_new_setup, (VALUE) &a);
496
+ return a.ca;
497
+ }
498
+
398
499
  CScalar *
399
500
  cscalar_new (int8_t data_type, ca_size_t bytes, CArray *mask)
400
501
  {
401
- CScalar *ca = ALLOC(CScalar);
402
- cscalar_setup(ca, data_type, bytes, mask);
403
- return ca;
502
+ CScalar *ca = cscalar_new_i(data_type, bytes);
503
+ return (CScalar *) carray_new_with_mask((CArray *) ca, mask);
404
504
  }
405
505
 
406
506
  /*
@@ -410,8 +510,7 @@ cscalar_new (int8_t data_type, ca_size_t bytes, CArray *mask)
410
510
  CScalar *
411
511
  cscalar_new2 (int8_t data_type, ca_size_t bytes, char *val)
412
512
  {
413
- CScalar *ca = ALLOC(CScalar);
414
- cscalar_setup(ca, data_type, bytes, NULL);
513
+ CScalar *ca = cscalar_new_i(data_type, bytes);
415
514
  memcpy(ca->ptr, val, ca->bytes);
416
515
  return ca;
417
516
  }
@@ -591,6 +690,7 @@ ca_fill_stride_buffer (char *dst, ca_size_t bytes, ca_size_t base, int8_t ndim,
591
690
  outer_ndim = ndim - 1;
592
691
 
593
692
  for ( k = 0; k < outer_ndim; k++ ) idx[k] = 0;
693
+ /* empty: the function returns on an empty region at its entry */
594
694
  while ( 1 ) {
595
695
  ca_size_t addr = base;
596
696
  char *p;
@@ -824,7 +924,7 @@ rb_ca_s_allocate (VALUE klass)
824
924
  }
825
925
 
826
926
  /* Reads the (data_type, dim, bytes: nil) argument list that CArray.new
827
- and CArray.__empty__ share. The two differ only in whether the buffer
927
+ and CArray.empty_of_data_type share. The two differ only in whether the buffer
828
928
  is filled, so the rule for reading their arguments -- the optional
829
929
  bytes for a fixlen, the refusal of a Class, the guess of the data type,
830
930
  the demand that dim be an Array -- is written once here. */
@@ -855,7 +955,7 @@ ca_scan_construct_args (int argc, VALUE *argv, int8_t *data_type,
855
955
  rb_ca_guess_type_and_bytes(rtype, rbytes, data_type, bytes);
856
956
 
857
957
  Check_Type(rdim, T_ARRAY);
858
- CA_CHECK_RANK(RARRAY_LEN(rdim)); /* before dim[] is filled */
958
+ CA_CHECK_RANK_GIVEN(RARRAY_LEN(rdim)); /* before dim[] is filled */
859
959
  *ndim = RARRAY_LEN(rdim);
860
960
  for (i=0; i<*ndim; i++) {
861
961
  dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
@@ -907,8 +1007,13 @@ rb_ca_initialize (int argc, VALUE *argv, VALUE self)
907
1007
  with the multi-dimensional subscript yielded as individual
908
1008
  integer arguments, so |i|, |i,j|, |i,j,k| all work uniformly
909
1009
  across ranks. Block forms that want the whole subscript as
910
- an Array should write |*idx|. */
911
- if ( rb_proc_arity(rb_block_proc()) == 0 ) {
1010
+ an Array should write |*idx|.
1011
+ An array of no cells calls neither, as Array.new(0) { ... } does
1012
+ not. */
1013
+ if ( ca->elements == 0 ) {
1014
+ ;
1015
+ }
1016
+ else if ( rb_proc_arity(rb_block_proc()) == 0 ) {
912
1017
  volatile VALUE rval = rb_yield_values2(0, NULL);
913
1018
  rb_ca_store_all(self, rval);
914
1019
  }
@@ -1160,6 +1265,7 @@ rb_ca_initialize_dup (VALUE self, VALUE other)
1160
1265
  {
1161
1266
  rb_call_super(1, &other);
1162
1267
  ca_dup_keep_state(self, other);
1268
+ rb_ca_own_attr(self);
1163
1269
  return self;
1164
1270
  }
1165
1271
 
@@ -1177,6 +1283,7 @@ rb_ca_initialize_clone (int argc, VALUE *argv, VALUE self)
1177
1283
  rb_call_super_kw(argc, argv, RB_PASS_CALLED_KEYWORDS);
1178
1284
  rb_scan_args(argc, argv, "1:", &orig, &opts);
1179
1285
  ca_dup_keep_state(self, orig);
1286
+ rb_ca_own_attr(self);
1180
1287
 
1181
1288
  if ( ! NIL_P(opts) ) {
1182
1289
  vfreeze = rb_hash_lookup2(opts, ID2SYM(rb_intern("freeze")), Qnil);
@@ -1246,7 +1353,7 @@ rb_ca_s_wrap (int argc, VALUE *argv, VALUE self)
1246
1353
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
1247
1354
 
1248
1355
  Check_Type(rdim, T_ARRAY);
1249
- CA_CHECK_RANK(RARRAY_LEN(rdim)); /* before dim[] is filled */
1356
+ CA_CHECK_RANK_GIVEN(RARRAY_LEN(rdim)); /* before dim[] is filled */
1250
1357
  ndim = RARRAY_LEN(rdim);
1251
1358
  for (i=0; i<ndim; i++) {
1252
1359
  dim[i] = NUM2SIZE(rb_ary_entry(rdim, i));
@@ -1552,7 +1659,7 @@ rb_ca_s_alloc_uninit (VALUE klass, VALUE rtype, VALUE rshape)
1552
1659
  int8_t i;
1553
1660
  rb_ca_guess_type_and_bytes(rtype, Qnil, &data_type, &bytes);
1554
1661
  Check_Type(rshape, T_ARRAY);
1555
- CA_CHECK_RANK(RARRAY_LEN(rshape)); /* before dim[] is filled */
1662
+ CA_CHECK_RANK_GIVEN(RARRAY_LEN(rshape)); /* before dim[] is filled */
1556
1663
  ndim = (int8_t) RARRAY_LEN(rshape);
1557
1664
  for (i = 0; i < ndim; i++) dim[i] = NUM2SIZE(rb_ary_entry(rshape, i));
1558
1665
  return rb_carray_new(data_type, ndim, dim, bytes, NULL);
@@ -1596,7 +1703,7 @@ Init_ca_obj_array (void)
1596
1703
  rb_define_method(rb_cCArray, "initialize", rb_ca_initialize, -1);
1597
1704
  rb_define_singleton_method(rb_cCArray, "__alloc_uninit__",
1598
1705
  rb_ca_s_alloc_uninit, 2);
1599
- rb_define_singleton_method(rb_cCArray, "__empty__", rb_ca_s_empty, -1);
1706
+ rb_define_private_method(rb_singleton_class(rb_cCArray), "empty_of_data_type", rb_ca_s_empty, -1);
1600
1707
 
1601
1708
  rb_define_singleton_method(rb_cCArray, "fixlen", rb_ca_s_fixlen, -1);
1602
1709
  rb_define_singleton_method(rb_cCArray, "boolean", rb_ca_s_boolean, -1);