carray 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -25
  3. data/CHANGELOG.md +16 -0
  4. data/LICENSE +1 -1
  5. data/NEWS.md +3 -0
  6. data/README.md +128 -44
  7. data/carray.gemspec +22 -24
  8. data/ext/ca_array_pool.c +91 -0
  9. data/ext/ca_axis_descriptor.h +186 -0
  10. data/ext/ca_axis_dispatch.c +924 -0
  11. data/ext/ca_axis_group.c +1208 -0
  12. data/ext/ca_bincmp_dispatch.c +76 -0
  13. data/ext/ca_bincmp_dispatch.h +85 -0
  14. data/ext/ca_binop_dispatch.c +125 -0
  15. data/ext/ca_binop_dispatch.h +159 -0
  16. data/ext/ca_categorical_iterator.c +1375 -0
  17. data/ext/ca_compare.c +94 -0
  18. data/ext/ca_compare.h +26 -0
  19. data/ext/ca_composite_dispatch.c +414 -0
  20. data/ext/ca_composite_dispatch.h +116 -0
  21. data/ext/ca_for_buffer.h +96 -0
  22. data/ext/ca_for_each_element.h +241 -0
  23. data/ext/ca_group_iter.c +304 -0
  24. data/ext/ca_iter_substrate.h +325 -0
  25. data/ext/ca_kernel_iterator.c +4321 -0
  26. data/ext/ca_kernel_iterator.h +2603 -0
  27. data/ext/ca_moncmp_dispatch.c +37 -0
  28. data/ext/ca_moncmp_dispatch.h +62 -0
  29. data/ext/ca_monop_dispatch.c +200 -0
  30. data/ext/ca_monop_dispatch.h +235 -0
  31. data/ext/ca_obj_array.c +355 -359
  32. data/ext/ca_obj_bincmp.c +809 -0
  33. data/ext/ca_obj_binop.c +892 -0
  34. data/ext/ca_obj_bitarray.c +369 -164
  35. data/ext/ca_obj_bitfield.c +294 -234
  36. data/ext/ca_obj_block.c +189 -711
  37. data/ext/ca_obj_byte_swap.c +766 -0
  38. data/ext/ca_obj_const_string.c +965 -0
  39. data/ext/ca_obj_face.c +670 -0
  40. data/ext/ca_obj_face.h +247 -0
  41. data/ext/ca_obj_fake.c +228 -100
  42. data/ext/ca_obj_farray.c +54 -441
  43. data/ext/ca_obj_field.c +82 -529
  44. data/ext/ca_obj_fixlen_string.c +306 -0
  45. data/ext/ca_obj_grid.c +858 -440
  46. data/ext/ca_obj_meld.c +1034 -0
  47. data/ext/ca_obj_moncmp.c +569 -0
  48. data/ext/ca_obj_monop.c +1111 -0
  49. data/ext/ca_obj_object.c +774 -298
  50. data/ext/ca_obj_record.c +468 -0
  51. data/ext/ca_obj_reduce.c +97 -82
  52. data/ext/ca_obj_refer.c +569 -459
  53. data/ext/ca_obj_remap.c +475 -0
  54. data/ext/ca_obj_repeat.c +92 -477
  55. data/ext/ca_obj_roll.c +616 -0
  56. data/ext/ca_obj_select.c +344 -296
  57. data/ext/ca_obj_select_axis.c +1296 -0
  58. data/ext/ca_obj_shift.c +230 -792
  59. data/ext/ca_obj_source.c +78 -0
  60. data/ext/ca_obj_stack.c +1173 -0
  61. data/ext/ca_obj_stride.c +2501 -0
  62. data/ext/ca_obj_string.c +268 -0
  63. data/ext/ca_obj_tile.c +614 -0
  64. data/ext/ca_obj_time.c +546 -0
  65. data/ext/ca_obj_timedelta.c +435 -0
  66. data/ext/ca_obj_transpose.c +62 -516
  67. data/ext/ca_obj_triop.c +746 -0
  68. data/ext/ca_obj_unbound_repeat.c +208 -241
  69. data/ext/ca_obj_window.c +1131 -563
  70. data/ext/ca_op_byte_swap.c +175 -0
  71. data/ext/ca_op_ipower.c +319 -0
  72. data/ext/ca_op_powi.h +88 -0
  73. data/ext/ca_sort_kernels.h +132 -0
  74. data/ext/ca_sweep_engine.c +430 -0
  75. data/ext/ca_sweep_engine.h +157 -0
  76. data/ext/ca_transform_common.c +228 -0
  77. data/ext/ca_triop_dispatch.c +55 -0
  78. data/ext/ca_triop_dispatch.h +62 -0
  79. data/ext/carray.h +795 -402
  80. data/ext/carray_access.c +831 -711
  81. data/ext/carray_attribute.c +98 -330
  82. data/ext/carray_bincount.c +255 -0
  83. data/ext/carray_broadcast.c +283 -0
  84. data/ext/carray_call_cfunc.c +1360 -828
  85. data/ext/carray_call_cfunc.h +160 -0
  86. data/ext/carray_cast.c +1212 -301
  87. data/ext/carray_cast_func.rb +81 -40
  88. data/ext/carray_class.c +53 -63
  89. data/ext/carray_config.h +28 -0
  90. data/ext/carray_conversion.c +350 -346
  91. data/ext/carray_copy.c +156 -268
  92. data/ext/carray_core.c +1342 -199
  93. data/ext/carray_count.c +312 -0
  94. data/ext/carray_data_type.c +43 -19
  95. data/ext/carray_element.c +585 -213
  96. data/ext/carray_factorize.c +2542 -0
  97. data/ext/carray_generate.c +230 -559
  98. data/ext/carray_histogram.c +490 -0
  99. data/ext/carray_hold.c +228 -0
  100. data/ext/carray_index_classifier.c +1035 -0
  101. data/ext/carray_index_classifier.h +27 -0
  102. data/ext/carray_internal.h +120 -0
  103. data/ext/carray_kernels_bincmp.c +4445 -0
  104. data/ext/carray_kernels_binop.c +10979 -0
  105. data/ext/carray_kernels_init.c +36 -0
  106. data/ext/carray_kernels_map.c +3466 -0
  107. data/ext/carray_kernels_moncmp.c +2096 -0
  108. data/ext/carray_kernels_monop.c +18312 -0
  109. data/ext/carray_kernels_reduce_aggregate.c +25836 -0
  110. data/ext/carray_kernels_reduce_boolean.c +329 -0
  111. data/ext/carray_kernels_reduce_cumulative.c +14592 -0
  112. data/ext/carray_kernels_reduce_extreme.c +16947 -0
  113. data/ext/carray_kernels_reduce_variance.c +3909 -0
  114. data/ext/carray_kernels_scan.c +3692 -0
  115. data/ext/carray_kernels_search.c +32137 -0
  116. data/ext/carray_kernels_sort.c +10625 -0
  117. data/ext/carray_kernels_triop.c +1391 -0
  118. data/ext/carray_lazy.c +567 -0
  119. data/ext/carray_loop.c +88 -200
  120. data/ext/carray_mask.c +848 -154
  121. data/ext/carray_math_kernel.h +120 -0
  122. data/ext/carray_mathfunc.c +10 -241
  123. data/ext/carray_median_percentile.c +1257 -0
  124. data/ext/carray_memory_view.c +1625 -0
  125. data/ext/carray_operator.c +1526 -318
  126. data/ext/carray_order.c +664 -1394
  127. data/ext/carray_partition.c +416 -0
  128. data/ext/carray_random.c +518 -0
  129. data/ext/carray_scatter.c +357 -0
  130. data/ext/carray_slab.c +1219 -0
  131. data/ext/carray_slab.h +84 -0
  132. data/ext/carray_sort.c +829 -0
  133. data/ext/carray_sort_kernel.c +620 -0
  134. data/ext/carray_struct.c +695 -0
  135. data/ext/carray_test.c +343 -229
  136. data/ext/carray_undef.c +34 -17
  137. data/ext/carray_utils.c +175 -74
  138. data/ext/extconf.rb +216 -55
  139. data/ext/mk_call_cfunc.rb +480 -0
  140. data/ext/mkkernel.rb +8842 -0
  141. data/ext/ruby_carray.c +202 -101
  142. data/ext/version.h +4 -14
  143. data/ext/version.rb +5 -13
  144. data/lib/carray/arrow_tensor.rb +401 -0
  145. data/lib/carray/attribute.rb +166 -0
  146. data/lib/carray/autoload_carray.rb +220 -0
  147. data/lib/carray/autoload_method_extension.rb +44 -0
  148. data/lib/carray/axis_group.rb +711 -0
  149. data/lib/carray/basics.rb +481 -0
  150. data/lib/carray/bincount_nd.rb +358 -0
  151. data/lib/carray/block_iterator.rb +604 -0
  152. data/lib/carray/boolean_reduce.rb +109 -0
  153. data/lib/carray/categorical.rb +561 -0
  154. data/lib/carray/categorical_iterator.rb +1062 -0
  155. data/lib/carray/complex.rb +150 -0
  156. data/lib/carray/conditional.rb +216 -0
  157. data/lib/carray/const_string.rb +228 -0
  158. data/lib/carray/construct.rb +139 -328
  159. data/lib/carray/core_extensions.rb +240 -0
  160. data/lib/carray/data_type_extension.rb +233 -0
  161. data/lib/carray/fixlen_string.rb +95 -0
  162. data/lib/carray/frame/concat.rb +132 -0
  163. data/lib/carray/frame/convert.rb +95 -0
  164. data/lib/carray/frame/csv_parser.rb +211 -0
  165. data/lib/carray/frame/frame.rb +649 -0
  166. data/lib/carray/frame/group.rb +186 -0
  167. data/lib/carray/frame/io.rb +164 -0
  168. data/lib/carray/frame/join.rb +248 -0
  169. data/lib/carray/frame/records.rb +99 -0
  170. data/lib/carray/frame/sort.rb +113 -0
  171. data/lib/carray/frame/verbs.rb +299 -0
  172. data/lib/carray/frame.rb +16 -0
  173. data/lib/carray/histogram.rb +512 -0
  174. data/lib/carray/inspect.rb +37 -20
  175. data/lib/carray/iterator.rb +57 -349
  176. data/lib/carray/lazy.rb +889 -0
  177. data/lib/carray/mask_gap_fill.rb +200 -0
  178. data/lib/carray/math.rb +78 -342
  179. data/lib/carray/meld_reduce.rb +289 -0
  180. data/lib/carray/methods/align_addr.rb +116 -0
  181. data/lib/carray/methods/bin.rb +128 -0
  182. data/lib/carray/methods/bincount.rb +87 -0
  183. data/lib/carray/methods/bit_string.rb +92 -0
  184. data/lib/carray/methods/broadcast.rb +63 -0
  185. data/lib/carray/methods/choose.rb +39 -0
  186. data/lib/carray/methods/composition.rb +280 -0
  187. data/lib/carray/methods/gather_nd.rb +206 -0
  188. data/lib/carray/methods/index.rb +39 -0
  189. data/lib/carray/methods/insert_block.rb +99 -0
  190. data/lib/carray/methods/is_in.rb +141 -0
  191. data/lib/carray/methods/join.rb +90 -0
  192. data/lib/carray/methods/locate_addr.rb +47 -0
  193. data/lib/carray/methods/mask_duplicates.rb +41 -0
  194. data/lib/carray/methods/meshgrid.rb +91 -0
  195. data/lib/carray/methods/mode.rb +126 -0
  196. data/lib/carray/methods/nunique.rb +46 -0
  197. data/lib/carray/methods/resize.rb +56 -0
  198. data/lib/carray/methods/snap.rb +156 -0
  199. data/lib/carray/methods/string_format.rb +57 -0
  200. data/lib/carray/methods/unique.rb +47 -0
  201. data/lib/carray/methods/value_counts.rb +71 -0
  202. data/lib/carray/mkmf.rb +124 -101
  203. data/lib/carray/runtime.rb +108 -0
  204. data/lib/carray/serialize.rb +478 -167
  205. data/lib/carray/slab_iterator.rb +292 -0
  206. data/lib/carray/stack.rb +291 -0
  207. data/lib/carray/string.rb +56 -180
  208. data/lib/carray/string_operation_extension.rb +289 -0
  209. data/lib/carray/struct.rb +335 -323
  210. data/lib/carray/struct_builder.rb +697 -0
  211. data/lib/carray/table.rb +41 -2
  212. data/lib/carray/time.rb +2255 -38
  213. data/lib/carray/window_iterator.rb +655 -0
  214. data/lib/carray.rb +55 -57
  215. metadata +163 -130
  216. data/Rakefile +0 -51
  217. data/TODO.md +0 -18
  218. data/ext/ca_iter_block.c +0 -257
  219. data/ext/ca_iter_dimension.c +0 -299
  220. data/ext/ca_iter_window.c +0 -214
  221. data/ext/ca_obj_mapping.c +0 -644
  222. data/ext/carray_iterator.c +0 -641
  223. data/ext/carray_math.rb +0 -850
  224. data/ext/carray_numeric.c +0 -259
  225. data/ext/carray_sort_addr.c +0 -254
  226. data/ext/carray_stat.c +0 -2100
  227. data/ext/carray_stat_proc.rb +0 -1999
  228. data/ext/mkmath.rb +0 -741
  229. data/ext/ruby_ccomplex.c +0 -509
  230. data/ext/ruby_float_func.c +0 -86
  231. data/lib/carray/array.rb +0 -8
  232. data/lib/carray/autoload/autoload_base.rb +0 -19
  233. data/lib/carray/autoload/autoload_gem_cairo.rb +0 -9
  234. data/lib/carray/autoload/autoload_gem_ffi.rb +0 -9
  235. data/lib/carray/autoload/autoload_gem_gnuplot.rb +0 -2
  236. data/lib/carray/autoload/autoload_gem_io_csv.rb +0 -14
  237. data/lib/carray/autoload/autoload_gem_io_pg.rb +0 -6
  238. data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +0 -12
  239. data/lib/carray/autoload/autoload_gem_narray.rb +0 -10
  240. data/lib/carray/autoload/autoload_gem_numo_narray.rb +0 -15
  241. data/lib/carray/autoload/autoload_gem_opencv.rb +0 -16
  242. data/lib/carray/autoload/autoload_gem_random.rb +0 -8
  243. data/lib/carray/autoload/autoload_gem_rmagick.rb +0 -23
  244. data/lib/carray/autoload/autoload_gem_zimg.rb +0 -3
  245. data/lib/carray/autoload/autoload_io_imagemagick.rb +0 -6
  246. data/lib/carray/autoload/autoload_math_histogram.rb +0 -5
  247. data/lib/carray/autoload/autoload_math_recurrence.rb +0 -6
  248. data/lib/carray/autoload/autoload_object_iterator.rb +0 -1
  249. data/lib/carray/autoload/autoload_object_link.rb +0 -1
  250. data/lib/carray/autoload/autoload_object_pack.rb +0 -2
  251. data/lib/carray/autoload.rb +0 -141
  252. data/lib/carray/basic.rb +0 -191
  253. data/lib/carray/broadcast.rb +0 -101
  254. data/lib/carray/compose.rb +0 -315
  255. data/lib/carray/convert.rb +0 -115
  256. data/lib/carray/info.rb +0 -110
  257. data/lib/carray/io/imagemagick.rb +0 -235
  258. data/lib/carray/mask.rb +0 -102
  259. data/lib/carray/math/histogram.rb +0 -177
  260. data/lib/carray/math/recurrence.rb +0 -93
  261. data/lib/carray/object/ca_obj_iterator.rb +0 -50
  262. data/lib/carray/object/ca_obj_link.rb +0 -50
  263. data/lib/carray/object/ca_obj_pack.rb +0 -99
  264. data/lib/carray/obsolete.rb +0 -256
  265. data/lib/carray/ordering.rb +0 -181
  266. data/lib/carray/testing.rb +0 -51
  267. data/lib/carray/transform.rb +0 -109
  268. data/misc/Methods.ja.md +0 -182
  269. data/misc/NOTE +0 -51
  270. data/spec/Classes/CABitfield_spec.rb +0 -58
  271. data/spec/Classes/CABlockIterator_spec.rb +0 -114
  272. data/spec/Classes/CABlock_spec.rb +0 -205
  273. data/spec/Classes/CAField_spec.rb +0 -39
  274. data/spec/Classes/CAGrid_spec.rb +0 -75
  275. data/spec/Classes/CAMap_spec.rb +0 -0
  276. data/spec/Classes/CAMapping_spec.rb +0 -105
  277. data/spec/Classes/CAObject_attribute_spec.rb +0 -33
  278. data/spec/Classes/CAObject_spec.rb +0 -33
  279. data/spec/Classes/CARefer_spec.rb +0 -93
  280. data/spec/Classes/CARepeat_spec.rb +0 -65
  281. data/spec/Classes/CASelect_spec.rb +0 -22
  282. data/spec/Classes/CAShift_spec.rb +0 -16
  283. data/spec/Classes/CAStruct_spec.rb +0 -71
  284. data/spec/Classes/CATranspose_spec.rb +0 -60
  285. data/spec/Classes/CAUnboudRepeat_spec.rb +0 -102
  286. data/spec/Classes/CAWindow_spec.rb +0 -54
  287. data/spec/Classes/CAWrap_spec.rb +0 -8
  288. data/spec/Classes/CArray_spec.rb +0 -184
  289. data/spec/Classes/CScalar_spec.rb +0 -55
  290. data/spec/Classes/ex1.rb +0 -46
  291. data/spec/Features/feature_130_spec.rb +0 -19
  292. data/spec/Features/feature_attributes_spec.rb +0 -280
  293. data/spec/Features/feature_boolean_spec.rb +0 -98
  294. data/spec/Features/feature_broadcast.rb +0 -116
  295. data/spec/Features/feature_cast_function.rb +0 -19
  296. data/spec/Features/feature_cast_spec.rb +0 -33
  297. data/spec/Features/feature_class_spec.rb +0 -84
  298. data/spec/Features/feature_complex_spec.rb +0 -42
  299. data/spec/Features/feature_composite_spec.rb +0 -124
  300. data/spec/Features/feature_convert_spec.rb +0 -46
  301. data/spec/Features/feature_copy_spec.rb +0 -123
  302. data/spec/Features/feature_creation_spec.rb +0 -84
  303. data/spec/Features/feature_element_spec.rb +0 -144
  304. data/spec/Features/feature_extream_spec.rb +0 -54
  305. data/spec/Features/feature_generate_spec.rb +0 -74
  306. data/spec/Features/feature_index_spec.rb +0 -69
  307. data/spec/Features/feature_mask_spec.rb +0 -580
  308. data/spec/Features/feature_math_spec.rb +0 -97
  309. data/spec/Features/feature_order_spec.rb +0 -146
  310. data/spec/Features/feature_ref_store_spec.rb +0 -209
  311. data/spec/Features/feature_serialization_spec.rb +0 -125
  312. data/spec/Features/feature_stat_spec.rb +0 -397
  313. data/spec/Features/feature_virtual_spec.rb +0 -48
  314. data/spec/Features/method_eq_spec.rb +0 -81
  315. data/spec/Features/method_is_nan_spec.rb +0 -12
  316. data/spec/Features/method_map_spec.rb +0 -54
  317. data/spec/Features/method_max_with.rb +0 -20
  318. data/spec/Features/method_min_with.rb +0 -19
  319. data/spec/Features/method_ne_spec.rb +0 -18
  320. data/spec/Features/method_project_spec.rb +0 -188
  321. data/spec/Features/method_ref_spec.rb +0 -27
  322. data/spec/Features/method_round_spec.rb +0 -11
  323. data/spec/Features/method_s_linspace_spec.rb +0 -48
  324. data/spec/Features/method_s_span_spec.rb +0 -14
  325. data/spec/Features/method_seq_spec.rb +0 -47
  326. data/spec/Features/method_sort_with.rb +0 -43
  327. data/spec/Features/method_sorted_with.rb +0 -29
  328. data/spec/Features/method_span_spec.rb +0 -42
  329. data/spec/Features/method_wrap_readonly_spec.rb +0 -43
  330. data/spec/UnitTest/test_CAVirtual.rb +0 -214
  331. data/spec/spec_all.rb +0 -10
  332. data/utils/ca_ase.rb +0 -21
  333. data/utils/ca_methods.rb +0 -15
  334. data/utils/cast_checker.rb +0 -30
  335. data/utils/convert_test.rb +0 -73
  336. data/utils/extract_yard.rb +0 -22
  337. data/utils/guess_shape.rb +0 -76
  338. data/utils/monkey_patch_methods.rb +0 -62
  339. data/utils/remove_resource_fork.sh +0 -5
data/ext/carray_copy.c CHANGED
@@ -1,28 +1,37 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- carray_copy.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
3
+ Duplication and template allocation: `copy` (always-copy entity),
4
+ `to_ca` (entity self / view materialise sentinel), and `template`
5
+ (same-shape blank result, optionally retyped or block-initialised).
6
+ Sibling of carray_generate.c (factory builders) and carray_access.c
7
+ (`store_all` broadcast path used by the 0-arity template block).
8
8
 
9
9
  ---------------------------------------------------------------------------- */
10
10
 
11
11
  #include "carray.h"
12
+ #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
12
13
  #include <stdarg.h>
13
14
 
14
15
  /* ------------------------------------------------------------------- */
15
16
 
17
+ /* Allocates a fresh entity (or scalar) of the same shape, data_type,
18
+ * and bytes as `ca`, copies the element payload, and reproduces the
19
+ * mask state. Always copies even when `ca` is an entity; for view
20
+ * sources the data path goes through `ca_copy_data`, otherwise a flat
21
+ * memcpy of `ca_length(ca)` bytes.
22
+ *
23
+ * Backs `CArray#copy` and is also reachable as a C-level utility from
24
+ * other ext files that need an owned snapshot. */
16
25
  CArray *
17
26
  ca_copy (void *ap)
18
27
  {
19
28
  CArray *ca = (CArray *) ap;
20
29
  CArray *co;
21
30
 
22
- if ( ca_is_scalar(ca) ) { /* create scalar without mask */
31
+ if ( ca_is_scalar(ca) ) {
23
32
  co = (CArray *) cscalar_new(ca->data_type, ca->bytes, 0);
24
33
  }
25
- else { /* create array without mask */
34
+ else {
26
35
  co = carray_new(ca->data_type, ca->ndim, ca->dim, ca->bytes, 0);
27
36
  }
28
37
 
@@ -41,11 +50,9 @@ ca_copy (void *ap)
41
50
  return co;
42
51
  }
43
52
 
44
- /* @overload to_ca
45
-
46
- (Copy) Creates CArray object from `self` with same contents includes mask state.
47
- */
48
-
53
+ /* Ruby entry for `CArray#copy`. Wraps `ca_copy` and, when `self` is a
54
+ * Face (e.g. CARecord), lifts the wrapped result so the derived class
55
+ * identity is preserved on the copy. */
49
56
  VALUE
50
57
  rb_ca_copy (VALUE self)
51
58
  {
@@ -53,57 +60,129 @@ rb_ca_copy (VALUE self)
53
60
  CArray *ca;
54
61
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
55
62
  obj = ca_wrap_struct(ca_copy(ca));
56
- rb_ca_data_type_inherit(obj, self);
63
+ CA_FACE_LIFT_IF_FACE(obj, self, ca);
57
64
  return obj;
58
65
  }
59
66
 
67
+ /* Reads the `writable:` keyword every `to_ca` implementation accepts.
68
+ * Returns non-zero when the caller demands a result whose writes reach
69
+ * the source, so a `to_ca` that can only hand back a copy must refuse
70
+ * instead of returning one silently.
71
+ *
72
+ * Exported for `to_ca` implementations written in C, in this tree and
73
+ * in ext gems; the Ruby-side equivalent is a `writable: false` keyword
74
+ * on the method definition. */
75
+ int
76
+ ca_to_ca_writable_arg (int argc, VALUE *argv)
77
+ {
78
+ VALUE opts;
79
+ ID kw_ids[1];
80
+ VALUE kw_vals[1];
81
+
82
+ rb_scan_args(argc, argv, "0:", &opts);
83
+ if ( NIL_P(opts) ) {
84
+ return 0;
85
+ }
86
+ kw_ids[0] = rb_intern("writable");
87
+ rb_get_kwargs(opts, kw_ids, 0, 1, kw_vals);
88
+ return ( kw_vals[0] == Qundef ) ? 0 : RTEST(kw_vals[0]);
89
+ }
90
+
91
+ /* Refusal an implementation raises when `writable: true` was asked of a
92
+ * `to_ca` that only ever produces a detached copy. */
93
+ void
94
+ ca_to_ca_refuse_writable (VALUE self)
95
+ {
96
+ volatile VALUE inspect = rb_inspect(CLASS_OF(self));
97
+ rb_raise(rb_eRuntimeError,
98
+ "%s#to_ca can only return a copy; it can't satisfy `writable: true'",
99
+ StringValuePtr(inspect));
100
+ }
101
+
102
+ /* Ruby entry for `CArray#to_ca`. Returns `self` unchanged — for any
103
+ * CArray (entity or data view) the receiver is already a CArray.
104
+ *
105
+ * `writable: true` states that the caller is going to write through the
106
+ * result into the source. `self` shares its storage by construction, so
107
+ * the only way to fail here is a read-only receiver.
108
+ *
109
+ * Other classes override `to_ca` for their own semantics: a Ruby
110
+ * `Array` builds a new CArray, and lazy views (CAMonOp / CABinOp /
111
+ * CAMonCmp / CABinCmp / CALazyMarker) force evaluation into a fresh
112
+ * entity; both are copies and so refuse `writable: true`. When an
113
+ * independent owned copy is required, callers use `copy`. */
114
+ VALUE
115
+ rb_ca_to_ca (int argc, VALUE *argv, VALUE self)
116
+ {
117
+ if ( ca_to_ca_writable_arg(argc, argv) ) {
118
+ CArray *ca;
119
+ TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
120
+ if ( ca_is_readonly(ca) ) {
121
+ rb_raise(rb_eRuntimeError, "can't modify read-only carray");
122
+ }
123
+ }
124
+ return self;
125
+ }
126
+
60
127
  /* ------------------------------------------------------------------- */
61
128
 
129
+ /* Allocates a fresh entity (or scalar) with the same shape,
130
+ * data_type, and bytes as `ca`, without a mask and with the payload
131
+ * left uninitialised. Used by ext code that is about to overwrite
132
+ * every element (e.g. kernel outputs, casts, element-wise results). */
62
133
  CArray *
63
134
  ca_template (void *ap)
64
135
  {
65
136
  CArray *ca = (CArray *) ap;
66
- if ( ca_is_scalar(ca) ) { /* create scalar without mask */
137
+ if ( ca_is_scalar(ca) ) {
67
138
  return (CArray*) cscalar_new(ca->data_type, ca->bytes, NULL);
68
139
  }
69
- else { /* create array without mask */
140
+ else {
70
141
  return carray_new(ca->data_type, ca->ndim, ca->dim, ca->bytes, NULL);
71
142
  }
72
143
  }
73
144
 
145
+ /* Variant of `ca_template` that zero-fills the payload (entity path
146
+ * uses `carray_new_safe`). Used when the caller may leave some cells
147
+ * untouched and needs a defined initial value. */
74
148
  CArray *
75
149
  ca_template_safe (void *ap)
76
150
  {
77
151
  CArray *ca = (CArray *) ap;
78
- if ( ca_is_scalar(ca) ) { /* create scalar without mask */
152
+ if ( ca_is_scalar(ca) ) {
79
153
  return (CArray*) cscalar_new(ca->data_type, ca->bytes, NULL);
80
154
  }
81
- else { /* create array filled with 0, without mask */
155
+ else {
82
156
  return carray_new_safe(ca->data_type, ca->ndim, ca->dim, ca->bytes, NULL);
83
157
  }
84
158
  }
85
159
 
160
+ /* `ca_template_safe` with an explicit target `data_type` / `bytes`
161
+ * (i.e. shape is taken from `ca` but the element type is overridden).
162
+ * The `bytes` argument is required for fixlen, ignored for numeric
163
+ * data types. */
86
164
  CArray *
87
165
  ca_template_safe2 (void *ap, int8_t data_type, ca_size_t bytes)
88
166
  {
89
167
  CArray *ca = (CArray *) ap;
90
168
  CA_CHECK_DATA_TYPE(data_type);
91
- if ( ca_is_scalar(ca) ) { /* create scalar without mask */
169
+ if ( ca_is_scalar(ca) ) {
92
170
  return (CArray*) cscalar_new(data_type, bytes, NULL);
93
171
  }
94
- else { /* create array filled with 0, without mask */
172
+ else {
95
173
  return carray_new_safe(data_type, ca->ndim, ca->dim, bytes, NULL);
96
174
  }
97
175
  }
98
176
 
99
- /* @overload template(data_type=self.data_type, bytes: 0)
100
-
101
- (Copy) Returns CArray object with same dimension with `self`
102
- The data type of the new carray object can be specified by `data_type`.
103
- For fixlen data type, the option `:bytes` is used to specified the
104
- data length.
105
- */
106
-
177
+ /* Ruby entry for `CArray#template`. Allocates a same-shape blank
178
+ * result, retypes it when `data_type` is given, and optionally runs a
179
+ * block initialiser:
180
+ * - block arity == 0: evaluate once, broadcast via `rb_ca_store_all`
181
+ * (scalar-fill fast path, the dominant idiom)
182
+ * - block arity != 0: per-cell walk yielding the multi-dimensional
183
+ * subscript as individual integer arguments
184
+ * The arity dispatch matches `CArray.new` (ca_obj_array.c) so the two
185
+ * factories behave the same for block-driven initialisation. */
107
186
  static VALUE
108
187
  rb_ca_template_method (int argc, VALUE *argv, VALUE self)
109
188
  {
@@ -118,25 +197,53 @@ rb_ca_template_method (int argc, VALUE *argv, VALUE self)
118
197
 
119
198
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
120
199
 
121
- if ( NIL_P(rtype) ) { /* data_type not given */
200
+ if ( NIL_P(rtype) ) {
122
201
  co = ca_template_safe(ca);
123
202
  obj = ca_wrap_struct(co);
124
- rb_ca_data_type_inherit(obj, self);
125
203
  }
126
204
  else {
127
205
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
128
206
  co = ca_template_safe2(ca, data_type, bytes);
129
207
  obj = ca_wrap_struct(co);
130
- rb_ca_data_type_import(obj, rtype);
131
208
  }
132
209
 
133
- if ( rb_block_given_p() ) { /* block given */
134
- volatile VALUE rval = rb_yield_values(0);
135
- if ( rval != self ) {
136
- rb_ca_store_all(obj, rval);
210
+ if ( rb_block_given_p() ) {
211
+ if ( rb_proc_arity(rb_block_proc()) == 0 ) {
212
+ volatile VALUE rval = rb_yield_values2(0, NULL);
213
+ if ( rval != self ) {
214
+ rb_ca_store_all(obj, rval);
215
+ }
216
+ }
217
+ else {
218
+ CArray *co;
219
+ TypedData_Get_Struct(obj, CArray, &carray_data_type, co);
220
+ if ( co->ndim > 0 ) {
221
+ ca_size_t idx[CA_RANK_MAX];
222
+ volatile VALUE ridx = rb_ary_new2(co->ndim);
223
+ ca_attach(co);
224
+ rb_ca_index_walk(obj, co, 0, idx, ridx, CA_LOOP_STORE);
225
+ ca_sync(co);
226
+ ca_detach(co);
227
+ }
228
+ else {
229
+ volatile VALUE rval = rb_yield_values2(0, NULL);
230
+ rb_ca_store_addr(obj, 0, rval);
231
+ }
137
232
  }
138
233
  }
139
234
 
235
+ /* Preserve the Face identity only for a same-type template (no explicit
236
+ * retype). A retype (template(:boolean)) is a different-typed buffer and
237
+ * must not be re-wrapped as the Face. A same-type template of a Face with
238
+ * a valid blank form (CARecord carries its data_class through the struct
239
+ * tail; identity Faces alias same-type storage) is lifted so the class is
240
+ * preserved. A Face with no valid blank form (CAConstString's content-
241
+ * defined offset+buffer) overrides `template` in Ruby to return a plain
242
+ * array instead of a broken same-class shell. */
243
+ if ( NIL_P(rtype) ) {
244
+ CA_FACE_LIFT_IF_FACE(obj, self, ca);
245
+ }
246
+
140
247
  return obj;
141
248
  }
142
249
 
@@ -155,6 +262,10 @@ rb_ca_template_with_type (VALUE self, VALUE rtype, VALUE rbytes)
155
262
  return rb_ca_template_method(2, args, self);
156
263
  }
157
264
 
265
+ /* Picks the largest-shape CArray among `n` variadic CArray arguments
266
+ * and returns `template(largest)`. Used by `carray_call_cfunc.c` to
267
+ * size the output of vectorised scalar C-function calls, where the
268
+ * inputs may be a mix of scalars and arrays. */
158
269
  VALUE
159
270
  rb_ca_template_n (int n, ...)
160
271
  {
@@ -194,244 +305,21 @@ rb_ca_template_n (int n, ...)
194
305
  }
195
306
 
196
307
  /* ------------------------------------------------------------------- */
197
-
198
- static void
199
- ca_paste_loop (CArray *ca, ca_size_t *offset, ca_size_t *offset0,
200
- ca_size_t *size, CArray *cs,
201
- int32_t level, ca_size_t *idx, ca_size_t *idx0)
202
- {
203
- ca_size_t i;
204
- if ( level == ca->ndim - 1 ) {
205
- idx[level] = offset[level];
206
- idx0[level] = offset0[level];
207
- memcpy(ca_ptr_at_index(ca, idx), ca_ptr_at_index(cs, idx0), size[level]*ca->bytes);
208
- if ( ca->mask ) {
209
- memset(ca_ptr_at_index(ca->mask, idx), 0, size[level]*sizeof(boolean8_t));
210
- }
211
- }
212
- else {
213
- for (i=0; i<size[level]; i++) {
214
- idx[level] = offset[level] + i;
215
- idx0[level] = offset0[level] + i;
216
- ca_paste_loop(ca, offset, offset0, size, cs, level+1, idx, idx0);
217
- }
218
- }
219
- }
220
-
221
- /* ------------------------------------------------------------------- */
222
-
223
- void
224
- ca_paste (void *ap, ca_size_t *offset, void *sp)
225
- {
226
- CArray *ca = (CArray *) ap;
227
- CArray *cs = (CArray *) sp;
228
- ca_size_t size[CA_RANK_MAX];
229
- ca_size_t offset0[CA_RANK_MAX];
230
- ca_size_t idx[CA_RANK_MAX];
231
- ca_size_t idx0[CA_RANK_MAX];
232
- int8_t i;
233
-
234
- ca_check_same_data_type(ca, cs);
235
- ca_check_same_ndim(ca, cs);
236
-
237
- for (i=0; i<ca->ndim; i++) {
238
- if ( offset[i] >= 0 ) {
239
- if ( ca->dim[i] <= cs->dim[i] + offset[i] ) {
240
- size[i] = ca->dim[i] - offset[i];
241
- }
242
- else {
243
- size[i] = cs->dim[i];
244
- }
245
- offset0[i] = 0;
246
- }
247
- else {
248
- if ( ca->dim[i] <= cs->dim[i] + offset[i] ) {
249
- size[i] = ca->dim[i];
250
- }
251
- else {
252
- size[i] = cs->dim[i] + offset[i];
253
- }
254
- offset0[i] = -offset[i];
255
- offset[i] = 0;
256
- }
257
- }
258
-
259
- for (i=0; i<ca->ndim; i++) {
260
- CA_CHECK_INDEX(offset[i], ca->dim[i]);
261
- }
262
-
263
- if ( ca_has_mask(cs) ) {
264
- ca_create_mask(ca);
265
- }
266
-
267
- ca_attach_n(2, ca, cs);
268
-
269
- ca_paste_loop(ca, offset, offset0, size, cs, 0, idx, idx0);
270
-
271
- if ( ca_has_mask(cs) ) {
272
- ca_paste_loop(ca->mask, offset, offset0, size, cs->mask, 0, idx, idx0);
273
- }
274
-
275
- ca_sync(ca);
276
- ca_detach_n(2, ca, cs);
277
- }
278
-
279
- /* @overload paste (idx, ary)
280
- (Copy) Pastes `ary` to `self` at the index `idx`.
281
- `idx` should be Array object with the length same as `self.ndim`.
282
- `ary` should have same shape with `self`.
283
- */
284
-
285
- static VALUE
286
- rb_ca_paste (VALUE self, VALUE roffset, VALUE rsrc)
287
- {
288
- CArray *ca, *cs;
289
- ca_size_t offset[CA_RANK_MAX];
290
- int i;
291
-
292
- rb_ca_modify(self);
293
-
294
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
295
-
296
- Check_Type(roffset, T_ARRAY);
297
-
298
- if ( RARRAY_LEN(roffset) != ca->ndim ) {
299
- rb_raise(rb_eArgError,
300
- "# of arguments should equal to the ndim");
301
- }
302
-
303
- for (i=0; i<ca->ndim; i++) {
304
- offset[i] = NUM2SIZE(rb_ary_entry(roffset,i));
305
- }
306
-
307
- cs = ca_wrap_readonly(rsrc, ca->data_type);
308
-
309
- ca_paste(ca, offset, cs);
310
-
311
- return self;
312
- }
313
-
314
-
315
- static void
316
- ca_clip_loop (CArray *ca, ca_size_t *offset, ca_size_t *offset0,
317
- ca_size_t *size, CArray *cs,
318
- int32_t level, ca_size_t *idx, ca_size_t *idx0)
319
- {
320
- ca_size_t i;
321
- if ( level == ca->ndim - 1 ) {
322
- idx[level] = offset[level];
323
- idx0[level] = offset0[level];
324
- memcpy(ca_ptr_at_index(cs, idx0), ca_ptr_at_index(ca, idx), size[level]*ca->bytes);
325
- }
326
- else {
327
- for (i=0; i<size[level]; i++) {
328
- idx[level] = offset[level] + i;
329
- idx0[level] = offset0[level] + i;
330
- ca_clip_loop(ca, offset, offset0, size, cs, level+1, idx, idx0);
331
- }
332
- }
333
- }
334
-
335
- /* ------------------------------------------------------------------- */
336
-
337
- void
338
- ca_clip (void *ap, ca_size_t *offset, void *sp)
339
- {
340
- CArray *ca = (CArray *) ap;
341
- CArray *cs = (CArray *) sp;
342
- ca_size_t size[CA_RANK_MAX];
343
- ca_size_t offset0[CA_RANK_MAX];
344
- ca_size_t idx[CA_RANK_MAX];
345
- ca_size_t idx0[CA_RANK_MAX];
346
- int i;
347
-
348
- ca_check_same_data_type(ca, cs);
349
- ca_check_same_ndim(ca, cs);
350
-
351
- for (i=0; i<ca->ndim; i++) {
352
- if ( offset[i] >= 0 ) {
353
- if ( ca->dim[i] <= cs->dim[i] + offset[i] ) {
354
- size[i] = ca->dim[i] - offset[i];
355
- }
356
- else {
357
- size[i] = cs->dim[i];
358
- }
359
- offset0[i] = 0;
360
- }
361
- else {
362
- if ( ca->dim[i] <= cs->dim[i] + offset[i] ) {
363
- size[i] = ca->dim[i];
364
- }
365
- else {
366
- size[i] = cs->dim[i] + offset[i];
367
- }
368
- offset0[i] = -offset[i];
369
- offset[i] = 0;
370
- }
371
- }
372
-
373
- for (i=0; i<ca->ndim; i++) {
374
- CA_CHECK_INDEX(offset[i], ca->dim[i]);
375
- }
376
-
377
- if ( ca_has_mask(cs) ) {
378
- ca_create_mask(ca);
379
- }
380
-
381
- ca_attach_n(2, ca, cs);
382
-
383
- ca_clip_loop(ca, offset, offset0, size, cs, 0, idx, idx0);
384
-
385
- if ( ca_has_mask(cs) ) {
386
- ca_clip_loop(ca->mask, offset, offset0, size, cs->mask, 0, idx, idx0);
387
- }
388
-
389
- ca_sync(ca);
390
- ca_detach_n(2, ca, cs);
391
- }
392
-
393
- /* @overload clip (idx, ary)
394
- (copy) Clips the data at `idx` from `self` to `ary`.
395
- */
396
-
397
- static VALUE
398
- rb_ca_clip (VALUE self, VALUE roffset, VALUE rsrc)
399
- {
400
- CArray *ca, *cs;
401
- ca_size_t offset[CA_RANK_MAX];
402
- int i;
403
-
404
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
405
-
406
- Check_Type(roffset, T_ARRAY);
407
-
408
- if ( RARRAY_LEN(roffset) != ca->ndim ) {
409
- rb_raise(rb_eArgError,
410
- "# of arguments should equal to the ndim");
411
- }
412
-
413
- for (i=0; i<ca->ndim; i++) {
414
- offset[i] = NUM2SIZE(rb_ary_entry(roffset, i));
415
- }
416
-
417
- cs = ca_wrap_writable(rsrc, ca->data_type);
418
-
419
- ca_clip(ca, offset, cs);
420
-
421
- return rsrc;
422
- }
308
+ /* [MOVED] sub-region copy `crop(offset, dst)` / `paste(offset, src)`
309
+ * -> lib/extras/crop_paste.rb (Ruby wrappers over CAWindow,
310
+ * opt-in via `require "extras/crop_paste"`, not autoloaded).
311
+ *
312
+ * The names `clip` / `clip!` now mean value clamp (clamp to a min/max
313
+ * range) and live in ext/carray_generate.c. The old `clip` argument
314
+ * order was reversed in the sub-region API, so the moved entry is
315
+ * renamed to `crop`; `paste` keeps its name. */
423
316
 
424
317
  /* ------------------------------------------------------------------- */
425
318
 
426
319
  void
427
- Init_carray_copy ()
320
+ Init_carray_copy (void)
428
321
  {
429
- /* CArray duplication, conversion */
430
-
431
- rb_define_method(rb_cCArray, "to_ca", rb_ca_copy, 0);
322
+ rb_define_method(rb_cCArray, "to_ca", rb_ca_to_ca, -1);
323
+ rb_define_method(rb_cCArray, "copy", rb_ca_copy, 0);
432
324
  rb_define_method(rb_cCArray, "template", rb_ca_template_method, -1);
433
-
434
- rb_define_method(rb_cCArray, "clip", rb_ca_clip, 2);
435
- rb_define_method(rb_cCArray, "paste", rb_ca_paste, 2);
436
325
  }
437
-