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/ca_obj_array.c CHANGED
@@ -1,27 +1,63 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- ca_obj_array.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
3
+ The concrete entity implementations: CArray (owns its buffer), CScalar
4
+ (single-cell, dim inline), and CAWrap (wraps external memory, does not
5
+ own it). Holds their TypedData descriptors, the entity ca_func table,
6
+ allocation / setup, CArray.new, and the typed factory constructors
7
+ (CArray.int32(...) etc.).
8
8
 
9
9
  ---------------------------------------------------------------------------- */
10
10
 
11
11
  #include "carray.h"
12
- #if RUBY_VERSION_CODE < 190
13
- #include "rubysig.h"
14
- #endif
15
12
 
16
13
  /* -------------------------------------------------------------------- */
17
14
 
15
+ static size_t
16
+ ca_dsize (const void *ap)
17
+ {
18
+ const CArray *ca = (const CArray *) ap;
19
+ size_t size;
20
+
21
+ if ( ca == NULL ) return 0;
22
+
23
+ /* struct size (approximate for view subtypes) */
24
+ switch ( ca->obj_type ) {
25
+ case CA_OBJ_ARRAY:
26
+ case CA_OBJ_ARRAY_WRAP:
27
+ size = sizeof(CArray);
28
+ size += ca->ndim * sizeof(ca_size_t);
29
+ break;
30
+ case CA_OBJ_SCALAR:
31
+ size = sizeof(CScalar);
32
+ /* CScalar: dim points to _dim inside struct, no separate allocation */
33
+ size += ca->bytes; /* ptr: 1 element */
34
+ break;
35
+ default:
36
+ /* CAView and its subtypes (CARefer, CABlock, etc.)
37
+ Use sizeof(CAView) as a lower bound; actual subtypes may be
38
+ larger, but the exact size varies by obj_type. */
39
+ size = sizeof(CAView);
40
+ size += ca->ndim * sizeof(ca_size_t);
41
+ break;
42
+ }
43
+
44
+ /* data buffer (only for entity arrays that own their ptr) */
45
+ if ( ca->ptr != NULL && ca->obj_type != CA_OBJ_ARRAY_WRAP ) {
46
+ size += (size_t)ca->elements * (size_t)ca->bytes;
47
+ }
48
+
49
+ /* Note: mask memory is accounted for by the mask's own dsize */
50
+
51
+ return size;
52
+ }
53
+
18
54
  const rb_data_type_t carray_data_type = {
19
55
  .parent = NULL,
20
56
  .wrap_struct_name = "CArray",
21
57
  .function = {
22
58
  .dmark = ca_mark,
23
59
  .dfree = ca_free,
24
- .dsize = NULL,
60
+ .dsize = ca_dsize,
25
61
  .dcompact = NULL
26
62
  },
27
63
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
@@ -33,7 +69,7 @@ const rb_data_type_t cawrap_data_type = {
33
69
  .function = {
34
70
  .dmark = ca_mark,
35
71
  .dfree = ca_free,
36
- .dsize = NULL,
72
+ .dsize = ca_dsize,
37
73
  .dcompact = NULL
38
74
  },
39
75
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -45,19 +81,19 @@ const rb_data_type_t cscalar_data_type = {
45
81
  .function = {
46
82
  .dmark = ca_mark,
47
83
  .dfree = ca_free,
48
- .dsize = NULL,
84
+ .dsize = ca_dsize,
49
85
  .dcompact = NULL
50
86
  },
51
87
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
52
88
  };
53
89
 
54
- const rb_data_type_t cavirtual_data_type = {
90
+ const rb_data_type_t caview_data_type = {
55
91
  .parent = &carray_data_type,
56
- .wrap_struct_name = "CAVirtual",
92
+ .wrap_struct_name = "CAView",
57
93
  .function = {
58
94
  .dmark = ca_mark,
59
95
  .dfree = ca_free,
60
- .dsize = NULL,
96
+ .dsize = ca_dsize,
61
97
  .dcompact = NULL
62
98
  },
63
99
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -69,7 +105,7 @@ const rb_data_type_t carray_mask_data_type = {
69
105
  .function = {
70
106
  .dmark = NULL,
71
107
  .dfree = ca_free_nop,
72
- .dsize = NULL,
108
+ .dsize = ca_dsize,
73
109
  .dcompact = NULL
74
110
  },
75
111
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
@@ -77,90 +113,9 @@ const rb_data_type_t carray_mask_data_type = {
77
113
 
78
114
  /* ------------------------------------------------------------------- */
79
115
 
80
- VALUE rb_cCArray, rb_cCAWrap, rb_cCScalar, rb_cCAVirtual;
116
+ VALUE rb_cCArray, rb_cCAWrap, rb_cCScalar, rb_cCAView;
81
117
  VALUE rb_cCArrayMask;
82
118
 
83
- /* yard:
84
- class CArray
85
- end
86
- class CAWrap < CArray # :nodoc:
87
- end
88
- class CScalar < CArray
89
- end
90
- class CAVirtual < CArray # :nodoc:
91
- end
92
- */
93
-
94
- /* ------------------------------------------------------------------- */
95
-
96
- /* Monitering newly allocated memory size to do gc at appropreate timing */
97
- /* This GC technique is based on NArray library. */
98
-
99
- /* monitoring memory usage */
100
-
101
- double ca_mem_usage = 0.0;
102
- double ca_mem_count = 0.0;
103
-
104
- /* Threshold for forced garbage collection and its default value */
105
- double ca_gc_interval;
106
- const double ca_default_gc_interval = 100.0; /* 100MB */
107
-
108
- #define MB (1024*1024)
109
-
110
- static void
111
- ca_check_mem_count()
112
- {
113
- VALUE is_gc_disabled = rb_gc_enable();
114
- if ( is_gc_disabled ) {
115
- rb_gc_disable();
116
- return;
117
- }
118
- else if ( ca_mem_count > (ca_gc_interval * MB) ) {
119
- rb_gc();
120
- ca_mem_count = 0;
121
- }
122
- }
123
-
124
- /* @private gc_interval
125
-
126
- Returns the threshold of incremented memory (MB) used by carray object
127
- until start GC.
128
- */
129
- static VALUE
130
- rb_ca_get_gc_interval (VALUE self)
131
- {
132
- return rb_float_new(ca_gc_interval);
133
- }
134
-
135
- /* @private gc_interval= (val)
136
-
137
- Sets the threshold of incremented memory (MB) used by carray object
138
- until start GC.
139
- */
140
- static VALUE
141
- rb_ca_set_gc_interval (VALUE self, VALUE rth)
142
- {
143
- double th = NUM2INT(rth);
144
- if ( th <= 0 ) {
145
- th = 0;
146
- }
147
- ca_gc_interval = th;
148
- return rb_float_new(ca_gc_interval);
149
- }
150
-
151
- /* @private reset_gc_inverval
152
-
153
- Reset the counter for the GC start when the incremented memory
154
- get larger than `CArray.gc_interval`.
155
- */
156
- static VALUE
157
- rb_ca_reset_gc_interval (VALUE self)
158
- {
159
- ca_gc_interval = ca_default_gc_interval;
160
- return rb_float_new(ca_gc_interval);
161
- }
162
-
163
-
164
119
  /* ------------------------------------------------------------------- */
165
120
 
166
121
  /*
@@ -179,7 +134,7 @@ rb_ca_reset_gc_interval (VALUE self)
179
134
  static int
180
135
  carray_setup_i (CArray *ca,
181
136
  int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
182
- CArray *mask, int allocate, int use_calloc)
137
+ CArray *mask, int allocate, int use_calloc, char *adopt_ptr)
183
138
  {
184
139
  ca_size_t elements;
185
140
  double length;
@@ -192,11 +147,9 @@ carray_setup_i (CArray *ca,
192
147
  CA_CHECK_DIM(ndim, dim);
193
148
  CA_CHECK_BYTES(data_type, bytes);
194
149
 
195
- /* calculate total number of elements */
196
- elements = 1;
150
+ /* calculate total byte length using double to detect overflow */
197
151
  length = bytes;
198
152
  for (i=0; i<ndim; i++) {
199
- elements *= dim[i];
200
153
  length *= dim[i];
201
154
  }
202
155
 
@@ -204,8 +157,24 @@ carray_setup_i (CArray *ca,
204
157
  rb_raise(rb_eRuntimeError, "too large byte length");
205
158
  }
206
159
 
160
+ /* calculate total number of elements (safe after length check above) */
161
+ elements = 1;
162
+ for (i=0; i<ndim; i++) {
163
+ elements *= dim[i];
164
+ }
165
+
166
+ /* An adopted buffer produces an owning entity (CA_OBJ_ARRAY), not a
167
+ wrap: free_carray xfree()s ca->ptr, so the caller's buffer must be
168
+ ruby_xmalloc()'d and its ownership transfers here. A raw buffer
169
+ cannot be adopted as CA_OBJECT (ca_mark would walk uninitialised
170
+ VALUEs). */
171
+ if ( adopt_ptr && data_type == CA_OBJECT ) {
172
+ rb_raise(rb_eRuntimeError,
173
+ "cannot adopt a raw buffer as a CA_OBJECT array");
174
+ }
175
+
207
176
  /* set values to the struct members */
208
- if ( allocate ) {
177
+ if ( allocate || adopt_ptr ) {
209
178
  ca->obj_type = CA_OBJ_ARRAY;
210
179
  }
211
180
  else {
@@ -217,25 +186,27 @@ carray_setup_i (CArray *ca,
217
186
  ca->ndim = ndim;
218
187
  ca->bytes = bytes;
219
188
  ca->elements = elements;
220
- ca->dim = ALLOC_N(ca_size_t, ndim);
189
+ if ( ! ca->_pool ) {
190
+ ca->dim = ALLOC_N(ca_size_t, ndim);
191
+ }
221
192
  memcpy(ca->dim, dim, ndim*sizeof(ca_size_t));
222
193
 
223
- if ( allocate ) { /* allocate == true */
194
+ if ( adopt_ptr ) { /* adopt: take ownership of buffer */
195
+ ca->ptr = adopt_ptr;
196
+ }
197
+ else if ( allocate ) { /* allocate == true */
224
198
 
225
199
  /* allocate memory for entity */
226
200
  if ( use_calloc ) {
227
201
  /* ca->ptr = ALLOC_N(char, elements * bytes); */
228
- ca->ptr = malloc_with_check(elements * bytes);
202
+ ca->ptr = xmalloc(elements * bytes);
229
203
  MEMZERO(ca->ptr, char, elements * bytes);
230
204
  }
231
205
  else {
232
206
  /* ca->ptr = ALLOC_N(char, elements * bytes); */
233
- ca->ptr = malloc_with_check(elements * bytes);
207
+ ca->ptr = xmalloc(elements * bytes);
234
208
  }
235
209
 
236
- ca_mem_count += (double)(ca_length(ca));
237
- ca_mem_usage += (double)(ca_length(ca));
238
-
239
210
  /* initialize elements with Qnil for CA_OBJECT data_type */
240
211
  if ( allocate && data_type == CA_OBJECT ) {
241
212
  volatile VALUE zero = SIZE2NUM(0);
@@ -255,8 +226,6 @@ carray_setup_i (CArray *ca,
255
226
  ca_setup_mask(ca, mask);
256
227
  }
257
228
 
258
- ca_check_mem_count();
259
-
260
229
  return 0;
261
230
  }
262
231
 
@@ -264,14 +233,14 @@ int
264
233
  carray_setup (CArray *ca,
265
234
  int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes, CArray *mask)
266
235
  {
267
- return carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 1, 0);
236
+ return carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 1, 0, NULL);
268
237
  }
269
238
 
270
239
  int
271
240
  carray_safe_setup (CArray *ca,
272
241
  int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes, CArray *mask)
273
242
  {
274
- return carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 1, 1);
243
+ return carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 1, 1, NULL);
275
244
  }
276
245
 
277
246
  int
@@ -281,7 +250,7 @@ ca_wrap_setup (CArray *ca,
281
250
  {
282
251
  int ret;
283
252
 
284
- ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0);
253
+ ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
285
254
  if ( (!ptr) && (ca->elements != 0) ) {
286
255
  rb_raise(rb_eRuntimeError, "wrapping NULL pointer with an non-empty array");
287
256
  }
@@ -296,7 +265,7 @@ ca_wrap_setup_null (CArray *ca,
296
265
  {
297
266
  int ret;
298
267
 
299
- ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0);
268
+ ret = carray_setup_i(ca, data_type, ndim, dim, bytes, mask, 0, 0, NULL);
300
269
  ca->ptr = NULL;
301
270
  return ret;
302
271
  }
@@ -305,7 +274,7 @@ CArray *
305
274
  carray_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
306
275
  CArray *mask)
307
276
  {
308
- CArray *ca = ALLOC(CArray);
277
+ CArray *ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
309
278
  carray_setup(ca, data_type, ndim, dim, bytes, mask);
310
279
  return ca;
311
280
  }
@@ -314,16 +283,34 @@ CArray *
314
283
  carray_new_safe (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
315
284
  CArray *mask)
316
285
  {
317
- CArray *ca = ALLOC(CArray);
286
+ CArray *ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
318
287
  carray_safe_setup(ca, data_type, ndim, dim, bytes, mask);
319
288
  return ca;
320
289
  }
321
290
 
291
+ /* Create an entity that adopts a caller-provided data buffer instead of
292
+ allocating its own. Ownership transfers: the buffer must be
293
+ ruby_xmalloc()'d and at least elements*bytes long, and is freed with
294
+ xfree() when the array is collected. data_type must not be CA_OBJECT
295
+ (a raw buffer holds no valid VALUEs for the GC to mark). */
296
+ CArray *
297
+ carray_new_adopt (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
298
+ char *ptr)
299
+ {
300
+ CArray *ca;
301
+ if ( ! ptr ) {
302
+ rb_raise(rb_eRuntimeError, "carray_new_adopt: NULL data pointer");
303
+ }
304
+ ca = (CArray *) ca_array_alloc(CA_OBJ_ARRAY, ndim);
305
+ carray_setup_i(ca, data_type, ndim, dim, bytes, NULL, 0, 0, ptr);
306
+ return ca;
307
+ }
308
+
322
309
  CAWrap *
323
310
  ca_wrap_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
324
311
  CArray *mask, char *ptr)
325
312
  {
326
- CAWrap *ca = ALLOC(CAWrap);
313
+ CAWrap *ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
327
314
  ca_wrap_setup(ca, data_type, ndim, dim, bytes, mask, ptr);
328
315
  return ca;
329
316
  }
@@ -332,7 +319,7 @@ CAWrap *
332
319
  ca_wrap_new_null (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
333
320
  CArray *mask)
334
321
  {
335
- CAWrap *ca = ALLOC(CAWrap);
322
+ CAWrap *ca = (CAWrap *) ca_array_alloc(CA_OBJ_ARRAY_WRAP, ndim);
336
323
  ca_wrap_setup_null(ca, data_type, ndim, dim, bytes, mask);
337
324
  return ca;
338
325
  }
@@ -342,11 +329,15 @@ free_carray (void *ap)
342
329
  {
343
330
  CArray *ca = (CArray *) ap;
344
331
  if ( ca != NULL ) {
345
- ca_mem_usage -= (double)(ca_length(ca));
346
332
  ca_free(ca->mask);
347
- free(ca->ptr);
348
- xfree(ca->dim);
349
- xfree(ca);
333
+ xfree(ca->ptr); /* entity owns its data buffer */
334
+ if ( ca->_pool ) {
335
+ ca_array_free(ca); /* dim lives in _pool */
336
+ }
337
+ else {
338
+ xfree(ca->dim);
339
+ xfree(ca);
340
+ }
350
341
  }
351
342
  }
352
343
 
@@ -355,10 +346,15 @@ free_ca_wrap (void *ap)
355
346
  {
356
347
  CArray *ca = (CArray *) ap;
357
348
  if ( ca != NULL ) {
358
- /* free(ca->ptr); */ /* don't free ca->ptr for CAWrap */
349
+ /* don't free ca->ptr for CAWrap (borrowed external memory) */
359
350
  ca_free(ca->mask);
360
- xfree(ca->dim);
361
- xfree(ca);
351
+ if ( ca->_pool ) {
352
+ ca_array_free(ca); /* dim lives in _pool */
353
+ }
354
+ else {
355
+ xfree(ca->dim);
356
+ xfree(ca);
357
+ }
362
358
  }
363
359
  }
364
360
 
@@ -383,8 +379,6 @@ cscalar_setup (CScalar *ca,
383
379
 
384
380
  ca->dim[0] = 1;
385
381
 
386
- ca_mem_usage += (double)(ca->bytes);
387
-
388
382
  if ( data_type == CA_OBJECT ) {
389
383
  *((VALUE*) ca->ptr) = SIZE2NUM(0);
390
384
  }
@@ -435,8 +429,7 @@ free_cscalar (void *ap)
435
429
  {
436
430
  CScalar *ca = (CScalar *) ap;
437
431
  if ( ca != NULL ) {
438
- ca_mem_usage -= (double)(ca->bytes);
439
- free(ca->ptr);
432
+ xfree(ca->ptr);
440
433
  ca_free(ca->mask);
441
434
  xfree(ca);
442
435
  }
@@ -454,67 +447,43 @@ ca_array_func_clone (void *ap)
454
447
  return co;
455
448
  }
456
449
 
457
- char *
458
- ca_array_func_ptr_at_addr (void *ap, ca_size_t addr)
459
- {
460
- CArray *ca = (CArray *) ap;
461
- return ca->ptr + ca->bytes * addr;
462
- }
463
-
464
- char *
465
- ca_array_func_ptr_at_index (void *ap, ca_size_t *idx)
466
- {
467
- CArray *ca = (CArray *) ap;
468
- ca_size_t *dim = ca->dim;
469
- int8_t i;
470
- ca_size_t n;
471
- n = idx[0]; /* n = idx[0]*dim[1]*dim[2]*...*dim[ndim-1] */
472
- for (i=1; i<ca->ndim; i++) { /* + idx[1]*dim[1]*dim[2]*...*dim[ndim-1] */
473
- n = dim[i]*n+idx[i]; /* ... + idx[ndim-2]*dim[1] + idx[ndim-1] */
474
- }
475
- return ca->ptr + ca->bytes * n;
476
- }
477
-
478
- void
479
- ca_array_func_fetch_addr (void *ap, ca_size_t addr, void *ptr)
480
- {
481
- CArray *ca = (CArray *) ap;
482
- memcpy(ptr, ca->ptr + ca->bytes * addr, ca->bytes);
483
- }
484
-
485
450
  void
486
- ca_array_func_fetch_index (void *ap, ca_size_t *idx, void *ptr)
451
+ ca_array_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
487
452
  {
488
453
  CArray *ca = (CArray *) ap;
489
454
  ca_size_t *dim = ca->dim;
490
455
  int8_t i;
491
456
  ca_size_t n;
457
+ char *p;
492
458
  n = idx[0];
493
459
  for (i=1; i<ca->ndim; i++) {
494
460
  n = dim[i]*n+idx[i];
495
461
  }
496
- memcpy(ptr, ca->ptr + ca->bytes * n, ca->bytes);
497
- }
498
-
499
- void
500
- ca_array_func_store_addr (void *ap, ca_size_t addr, void *ptr)
501
- {
502
- CArray *ca = (CArray *) ap;
503
- memcpy(ca->ptr + ca->bytes * addr, ptr, ca->bytes);
462
+ p = ca->ptr + ca->bytes * n;
463
+ if ( dir == CA_XFER_GET ) {
464
+ memcpy(data, p, ca->bytes);
465
+ }
466
+ else {
467
+ memcpy(p, data, ca->bytes);
468
+ }
504
469
  }
505
470
 
506
471
  void
507
- ca_array_func_store_index (void *ap, ca_size_t *idx, void *ptr)
508
- {
509
- CArray *ca = (CArray *) ap;
510
- ca_size_t *dim = ca->dim;
511
- int8_t i;
512
- ca_size_t n;
513
- n = idx[0];
514
- for (i=1; i<ca->ndim; i++) {
515
- n = dim[i]*n+idx[i];
472
+ ca_array_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
473
+ void *data, int dir)
474
+ {
475
+ CArray *ca = (CArray *) ap;
476
+ char *d = (char *) data;
477
+ ca_size_t i;
478
+ for (i=0; i<n; i++) {
479
+ char *p = ca->ptr + ca->bytes * addrs[i];
480
+ if ( dir == CA_XFER_GET ) {
481
+ memcpy(d + i * ca->bytes, p, ca->bytes);
482
+ }
483
+ else {
484
+ memcpy(p, d + i * ca->bytes, ca->bytes);
485
+ }
516
486
  }
517
- memcpy(ca->ptr + ca->bytes * n, ptr, ca->bytes);
518
487
  }
519
488
 
520
489
  void
@@ -543,17 +512,15 @@ ca_array_func_detach (void *ap)
543
512
  }
544
513
 
545
514
  void
546
- ca_array_func_copy_data (void *ap, void *ptr)
547
- {
548
- CArray *ca = (CArray *) ap;
549
- memmove(ptr, ca->ptr, ca_length(ca));
550
- }
551
-
552
- void
553
- ca_array_func_sync_data (void *ap, void *ptr)
515
+ ca_array_func_xfer_all (void *ap, void *data, int dir)
554
516
  {
555
517
  CArray *ca = (CArray *) ap;
556
- memmove(ca->ptr, ptr, ca_length(ca));
518
+ if ( dir == CA_XFER_GET ) {
519
+ memmove(data, ca->ptr, ca_length(ca));
520
+ }
521
+ else {
522
+ memmove(ca->ptr, data, ca_length(ca));
523
+ }
557
524
  }
558
525
 
559
526
  #define proc_fill_bang_fixlen() \
@@ -593,17 +560,99 @@ ca_array_func_fill_data (void *ap, void *val)
593
560
  case CA_INT64:
594
561
  case CA_UINT64:
595
562
  case CA_FLOAT64: proc_fill_bang(float64_t); break;
596
- case CA_FLOAT128: proc_fill_bang(float128_t); break;
597
563
  #ifdef HAVE_COMPLEX_H
598
564
  case CA_CMPLX64: proc_fill_bang(cmplx64_t); break;
599
565
  case CA_CMPLX128: proc_fill_bang(cmplx128_t); break;
600
- case CA_CMPLX256: proc_fill_bang(cmplx256_t); break;
601
566
  #endif
602
567
  case CA_OBJECT: proc_fill_bang(VALUE); break;
603
568
  default: rb_bug("array has an unknown data type");
604
569
  }
605
570
  }
606
571
 
572
+ /* The bottom of the fill_stride descent: the value is already in this
573
+ array's data_type and the region is in its own addresses, so all that is
574
+ left is to write it. The innermost axis runs contiguously whenever its
575
+ step is 1, which is the usual case once a view has composed down to here,
576
+ so that axis is written as a run rather than a cell at a time. */
577
+
578
+ void
579
+ ca_fill_stride_buffer (char *dst, ca_size_t bytes, ca_size_t base, int8_t ndim,
580
+ ca_size_t *counts, ca_size_t *steps, void *ptr)
581
+ {
582
+ ca_size_t idx[CA_RANK_MAX];
583
+ ca_size_t inner_count, inner_step;
584
+ int8_t outer_ndim, k;
585
+
586
+ if ( ndim <= 0 ) {
587
+ memcpy(dst + base * bytes, ptr, bytes);
588
+ return;
589
+ }
590
+
591
+ inner_count = counts[ndim - 1];
592
+ inner_step = steps[ndim - 1];
593
+ outer_ndim = ndim - 1;
594
+
595
+ for ( k = 0; k < outer_ndim; k++ ) idx[k] = 0;
596
+ while ( 1 ) {
597
+ ca_size_t addr = base;
598
+ char *p;
599
+ ca_size_t i;
600
+ for ( k = 0; k < outer_ndim; k++ ) addr += idx[k] * steps[k];
601
+ p = dst + addr * bytes;
602
+ /* The width is known per array, not per cell, so hoist it out of the run
603
+ rather than paying a memcpy call for every element. A step of 1 gets
604
+ its own loop because that is the shape the compiler can widen; a wider
605
+ step still gets the typed store, which is where a view that composed
606
+ down to a strided run lands -- an interleaved channel, say. */
607
+ #define CA_FILL_RUN(T) \
608
+ { T v = *(T *)ptr, *q = (T *)p; \
609
+ if ( inner_step == 1 ) { for ( i = 0; i < inner_count; i++ ) q[i] = v; } \
610
+ else { for ( i = 0; i < inner_count; i++ ) { *q = v; q += inner_step; } } \
611
+ break; }
612
+ switch ( bytes ) {
613
+ case 1: CA_FILL_RUN(uint8_t)
614
+ case 2: CA_FILL_RUN(uint16_t)
615
+ case 4: CA_FILL_RUN(uint32_t)
616
+ case 8: CA_FILL_RUN(uint64_t)
617
+ default:
618
+ for ( i = 0; i < inner_count; i++ ) {
619
+ memcpy(p, ptr, bytes);
620
+ p += inner_step * bytes;
621
+ }
622
+ }
623
+ #undef CA_FILL_RUN
624
+ if ( outer_ndim == 0 ) break;
625
+ k = outer_ndim - 1;
626
+ while ( k >= 0 ) { if ( ++idx[k] < counts[k] ) break; idx[k] = 0; k--; }
627
+ if ( k < 0 ) break;
628
+ }
629
+ }
630
+
631
+ void
632
+ ca_fill_addrs_buffer (char *dst, ca_size_t bytes, ca_size_t n,
633
+ ca_size_t *addrs, void *ptr)
634
+ {
635
+ ca_size_t i;
636
+ for ( i = 0; i < n; i++ ) {
637
+ memcpy(dst + addrs[i] * bytes, ptr, bytes);
638
+ }
639
+ }
640
+
641
+ void
642
+ ca_array_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
643
+ ca_size_t *counts, ca_size_t *steps, void *ptr)
644
+ {
645
+ CArray *ca = (CArray *) ap;
646
+ ca_fill_stride_buffer(ca->ptr, ca->bytes, base, ndim, counts, steps, ptr);
647
+ }
648
+
649
+ void
650
+ ca_array_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
651
+ {
652
+ CArray *ca = (CArray *) ap;
653
+ ca_fill_addrs_buffer(ca->ptr, ca->bytes, n, addrs, ptr);
654
+ }
655
+
607
656
  void
608
657
  ca_array_func_create_mask (void *ap)
609
658
  {
@@ -611,25 +660,45 @@ ca_array_func_create_mask (void *ap)
611
660
  ca->mask = carray_new_safe(CA_BOOLEAN, ca->ndim, ca->dim, 0, NULL);
612
661
  }
613
662
 
663
+ /* Pool framework hooks for the CArray entity (and CAWrap, which shares the
664
+ struct + carray_setup_i). Single ndim-sized tail (dim) lives in _pool.
665
+ These are set in the static func-table literals below so the hooks are
666
+ present the instant ca_func[CA_OBJ_ARRAY] is assigned -- carray_new runs
667
+ during Init, before any per-class Init_* would have a chance to register
668
+ them. */
669
+ static size_t
670
+ carray_pool_bytes (int8_t ndim)
671
+ {
672
+ ca_size_t n = (ndim > 0) ? ndim : 1;
673
+ return (size_t) n * sizeof(ca_size_t);
674
+ }
675
+
676
+ static void
677
+ carray_pool_init (void *ap, int8_t ndim)
678
+ {
679
+ CArray *ca = (CArray *) ap;
680
+ ca->dim = (ca_size_t *) ca->_pool;
681
+ }
682
+
614
683
  ca_operation_function_t ca_array_func = {
615
684
  CA_OBJ_ARRAY,
616
685
  CA_REAL_ARRAY,
617
686
  free_carray,
618
687
  ca_array_func_clone,
619
- ca_array_func_ptr_at_addr,
620
- ca_array_func_ptr_at_index,
621
- NULL,
622
- ca_array_func_fetch_index,
623
- NULL,
624
- ca_array_func_store_index,
625
688
  ca_array_func_allocate,
626
689
  ca_array_func_attach,
627
690
  ca_array_func_sync,
628
691
  ca_array_func_detach,
629
- ca_array_func_copy_data,
630
- ca_array_func_sync_data,
631
692
  ca_array_func_fill_data,
632
693
  ca_array_func_create_mask,
694
+ ca_array_func_xfer_index,
695
+ ca_array_func_xfer_addrs,
696
+ .xfer_all = ca_array_func_xfer_all,
697
+ .fill_addrs = ca_array_func_fill_addrs,
698
+ .fill_stride = ca_array_func_fill_stride,
699
+ .struct_size = sizeof(CArray),
700
+ .pool_bytes = carray_pool_bytes,
701
+ .pool_init = carray_pool_init,
633
702
  };
634
703
 
635
704
  ca_operation_function_t ca_wrap_func = {
@@ -637,20 +706,20 @@ ca_operation_function_t ca_wrap_func = {
637
706
  CA_REAL_ARRAY,
638
707
  free_ca_wrap,
639
708
  ca_array_func_clone,
640
- ca_array_func_ptr_at_addr,
641
- ca_array_func_ptr_at_index,
642
- NULL,
643
- ca_array_func_fetch_index,
644
- NULL,
645
- ca_array_func_store_index,
646
709
  ca_array_func_allocate,
647
710
  ca_array_func_attach,
648
711
  ca_array_func_sync,
649
712
  ca_array_func_detach,
650
- ca_array_func_copy_data,
651
- ca_array_func_sync_data,
652
713
  ca_array_func_fill_data,
653
714
  ca_array_func_create_mask,
715
+ ca_array_func_xfer_index,
716
+ ca_array_func_xfer_addrs,
717
+ .xfer_all = ca_array_func_xfer_all,
718
+ .fill_addrs = ca_array_func_fill_addrs,
719
+ .fill_stride = ca_array_func_fill_stride,
720
+ .struct_size = sizeof(CArray), /* CAWrap is a typedef of CArray */
721
+ .pool_bytes = carray_pool_bytes,
722
+ .pool_init = carray_pool_init,
654
723
  };
655
724
 
656
725
  /* ------------------------------------------------------------------- */
@@ -666,50 +735,30 @@ ca_scalar_func_clone (void *ap)
666
735
  return co;
667
736
  }
668
737
 
669
- char *
670
- ca_scalar_func_ptr_at_addr (void *ap, ca_size_t addr)
671
- {
672
- CArray *ca = (CArray *) ap;
673
- return ca->ptr;
674
- }
675
-
676
- char *
677
- ca_scalar_func_ptr_at_index (void *ap, ca_size_t *idx)
678
- {
679
- CArray *ca = (CArray *) ap;
680
- return ca->ptr;
681
- }
682
-
683
- #define ca_scalar_func_fetch_index ca_array_func_fetch_index
684
- #define ca_scalar_func_store_index ca_array_func_store_index
685
738
  #define ca_scalar_func_allocate ca_array_func_allocate
686
739
  #define ca_scalar_func_attach ca_array_func_attach
687
740
  #define ca_scalar_func_sync ca_array_func_sync
688
741
  #define ca_scalar_func_detach ca_array_func_detach
689
- #define ca_scalar_func_copy_data ca_array_func_copy_data
690
- #define ca_scalar_func_sync_data ca_array_func_sync_data
691
742
  #define ca_scalar_func_fill_data ca_array_func_fill_data
692
743
  #define ca_scalar_func_create_mask ca_array_func_create_mask
744
+ #define ca_scalar_func_xfer_index ca_array_func_xfer_index
693
745
 
694
746
  ca_operation_function_t ca_scalar_func = {
695
747
  CA_OBJ_SCALAR,
696
748
  CA_REAL_ARRAY,
697
749
  free_cscalar,
698
750
  ca_scalar_func_clone,
699
- ca_scalar_func_ptr_at_addr,
700
- ca_scalar_func_ptr_at_index,
701
- NULL,
702
- ca_scalar_func_fetch_index,
703
- NULL,
704
- ca_scalar_func_store_index,
705
751
  ca_scalar_func_allocate,
706
752
  ca_scalar_func_attach,
707
753
  ca_scalar_func_sync,
708
754
  ca_scalar_func_detach,
709
- ca_scalar_func_copy_data,
710
- ca_scalar_func_sync_data,
711
755
  ca_scalar_func_fill_data,
712
756
  ca_scalar_func_create_mask,
757
+ ca_scalar_func_xfer_index,
758
+ ca_array_func_xfer_addrs,
759
+ .xfer_all = ca_array_func_xfer_all,
760
+ .fill_addrs = ca_array_func_fill_addrs,
761
+ .fill_stride = ca_array_func_fill_stride,
713
762
  };
714
763
 
715
764
  /* ------------------------------------------------------------------- */
@@ -730,6 +779,14 @@ rb_carray_new_safe (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t byt
730
779
  return ca_wrap_struct(ca);
731
780
  }
732
781
 
782
+ VALUE
783
+ rb_carray_new_adopt (int8_t data_type, int8_t ndim, ca_size_t *dim,
784
+ ca_size_t bytes, char *ptr)
785
+ {
786
+ CArray *ca = carray_new_adopt(data_type, ndim, dim, bytes, ptr);
787
+ return ca_wrap_struct(ca);
788
+ }
789
+
733
790
 
734
791
  VALUE
735
792
  rb_ca_wrap_new (int8_t data_type, int8_t ndim, ca_size_t *dim, ca_size_t bytes,
@@ -765,7 +822,6 @@ static VALUE
765
822
  rb_ca_s_allocate (VALUE klass)
766
823
  {
767
824
  CArray *ca;
768
- ca_check_mem_count();
769
825
  return TypedData_Make_Struct(klass, CArray, &carray_data_type, ca);
770
826
  }
771
827
 
@@ -794,8 +850,20 @@ rb_ca_initialize (int argc, VALUE *argv, VALUE self)
794
850
  rb_scan_args(argc, argv, "21", (VALUE *)&rtype, (VALUE *) &rdim, (VALUE *) &ropt);
795
851
  rb_scan_options(ropt, "bytes", &rbytes);
796
852
 
853
+ /* data_class may only be attached to a CARecord (= Face), so
854
+ constructing a data_class-bearing entity with `CArray.new(MyStruct,
855
+ [N])` is not offered: a Class first argument raises with migration
856
+ guidance. (View-side data_class propagation, e.g. refer(MyStruct,
857
+ [N]), is handled elsewhere via the data_class inherit path.) */
858
+ if ( TYPE(rtype) == T_CLASS ) {
859
+ rb_raise(rb_eArgError,
860
+ "CArray.new(%"PRIsVALUE", ...) was removed in 3.0. "
861
+ "Use `CARecord.new(%"PRIsVALUE", *shape)` or define "
862
+ "`class MyArr < CARecord; data_class %"PRIsVALUE"; end`.",
863
+ rtype, rtype, rtype);
864
+ }
865
+
797
866
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
798
- rb_ca_data_type_import(self, rtype);
799
867
 
800
868
  Check_Type(rdim, T_ARRAY);
801
869
  ndim = RARRAY_LEN(rdim);
@@ -804,13 +872,42 @@ rb_ca_initialize (int argc, VALUE *argv, VALUE self)
804
872
  }
805
873
 
806
874
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
875
+ if ( ca_func[CA_OBJ_ARRAY].pool_init ) {
876
+ ca_array_pool_alloc(ca, CA_OBJ_ARRAY, ndim);
877
+ }
807
878
  carray_safe_setup(ca, data_type, ndim, dim, bytes, NULL);
808
879
 
809
880
  if ( rb_block_given_p() ) {
810
- volatile VALUE rval = rb_yield(self);
811
- if ( rval != self ) {
881
+ /* Two block forms:
882
+ - arity == 0 (`{ 1.0 }`): the block is called *once* and its
883
+ return value is broadcast to the whole array via
884
+ `rb_ca_store_all` (= scalar-fill fast path). This matches
885
+ the dominant `CArray.<type>(n) { value }` idiom and avoids
886
+ the O(n) call overhead of per-cell yield for what is really
887
+ a constant fill.
888
+ - arity != 0 (`{ |i, j| ... }` etc.): per-cell subscript walk
889
+ (= map_index! semantics). The block is called once per cell
890
+ with the multi-dimensional subscript yielded as individual
891
+ integer arguments, so |i|, |i,j|, |i,j,k| all work uniformly
892
+ across ranks. Block forms that want the whole subscript as
893
+ an Array should write |*idx|. */
894
+ if ( rb_proc_arity(rb_block_proc()) == 0 ) {
895
+ volatile VALUE rval = rb_yield_values2(0, NULL);
812
896
  rb_ca_store_all(self, rval);
813
897
  }
898
+ else if ( ca->ndim > 0 ) {
899
+ ca_size_t idx[CA_RANK_MAX];
900
+ volatile VALUE ridx = rb_ary_new2(ca->ndim);
901
+ ca_attach(ca);
902
+ rb_ca_index_walk(self, ca, 0, idx, ridx, CA_LOOP_STORE);
903
+ ca_sync(ca);
904
+ ca_detach(ca);
905
+ }
906
+ else {
907
+ /* 0-D safety net (rare from CArray.new path): yield no args. */
908
+ volatile VALUE rval = rb_yield_values2(0, NULL);
909
+ rb_ca_store_addr(self, 0, rval);
910
+ }
814
911
  }
815
912
 
816
913
  return Qnil;
@@ -954,16 +1051,6 @@ static VALUE rb_ca_s_float64 (int argc, VALUE *argv, VALUE klass)
954
1051
  rb_ca_s_body(CA_FLOAT64);
955
1052
  }
956
1053
 
957
- /* @overload float128(*dim) { ... }
958
-
959
- (Construction)
960
- Short-Hand of `CArray.new(:float128, dim, bytes: bytes) { ... }`
961
- */
962
- static VALUE rb_ca_s_float128 (int argc, VALUE *argv, VALUE klass)
963
- {
964
- rb_ca_s_body(CA_FLOAT128);
965
- }
966
-
967
1054
  #ifdef HAVE_COMPLEX_H
968
1055
  /* @overload cmplx64(*dim) { ... }
969
1056
 
@@ -985,15 +1072,6 @@ static VALUE rb_ca_s_cmplx128 (int argc, VALUE *argv, VALUE klass)
985
1072
  rb_ca_s_body(CA_CMPLX128);
986
1073
  }
987
1074
 
988
- /* @overload cmplx256(*dim) { ... }
989
-
990
- (Construction)
991
- Short-Hand of `CArray.new(:cmplx256, dim, bytes: bytes) { ... }`
992
- */
993
- static VALUE rb_ca_s_cmplx256 (int argc, VALUE *argv, VALUE klass)
994
- {
995
- rb_ca_s_body(CA_CMPLX256);
996
- }
997
1075
  #endif
998
1076
 
999
1077
  /* @overload object(*dim) { ... }
@@ -1020,6 +1098,9 @@ rb_ca_initialize_copy (VALUE self, VALUE other)
1020
1098
  TypedData_Get_Struct(other, CArray, &carray_data_type, cs);
1021
1099
 
1022
1100
  ca_update_mask(cs);
1101
+ if ( ca_func[CA_OBJ_ARRAY].pool_init ) {
1102
+ ca_array_pool_alloc(ca, CA_OBJ_ARRAY, cs->ndim);
1103
+ }
1023
1104
  carray_setup(ca, cs->data_type, cs->ndim, cs->dim, cs->bytes, cs->mask);
1024
1105
 
1025
1106
  memcpy(ca->ptr, cs->ptr, ca_length(cs));
@@ -1115,7 +1196,6 @@ rb_cs_initialize (int argc, VALUE *argv, VALUE self)
1115
1196
  rb_scan_options(ropt, "bytes", &rbytes);
1116
1197
 
1117
1198
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
1118
- rb_ca_data_type_import(self, rtype);
1119
1199
 
1120
1200
  TypedData_Get_Struct(self, CScalar, &cscalar_data_type, ca);
1121
1201
  cscalar_setup(ca, data_type, bytes, NULL);
@@ -1268,16 +1348,6 @@ rb_cs_s_float64 (int argc, VALUE *argv, VALUE klass) {
1268
1348
  rb_cs_s_body(CA_FLOAT64);
1269
1349
  }
1270
1350
 
1271
- /* @overload float128() { ... }
1272
-
1273
- (Construction)
1274
- Short-Hand of `CScalar.new(:float128) { ... }`
1275
- */
1276
- static VALUE
1277
- rb_cs_s_float128 (int argc, VALUE *argv, VALUE klass) {
1278
- rb_cs_s_body(CA_FLOAT128);
1279
- }
1280
-
1281
1351
  #ifdef HAVE_COMPLEX_H
1282
1352
  /* @overload cmplx64() { ... }
1283
1353
 
@@ -1299,15 +1369,6 @@ rb_cs_s_cmplx128 (int argc, VALUE *argv, VALUE klass) {
1299
1369
  rb_cs_s_body(CA_CMPLX128);
1300
1370
  }
1301
1371
 
1302
- /* @overload cmplx256() { ... }
1303
-
1304
- (Construction)
1305
- Short-Hand of `CScalar.new(:cmplx256) { ... }`
1306
- */
1307
- static VALUE
1308
- rb_cs_s_cmplx256 (int argc, VALUE *argv, VALUE klass) {
1309
- rb_cs_s_body(CA_CMPLX256);
1310
- }
1311
1372
  #endif
1312
1373
 
1313
1374
  /* @overload object() { ... }
@@ -1335,7 +1396,6 @@ rb_cs_initialize_copy (VALUE self, VALUE other)
1335
1396
  cscalar_setup(ca, cs->data_type, cs->bytes, NULL);
1336
1397
  memcpy(ca->ptr, cs->ptr, ca->bytes);
1337
1398
 
1338
- rb_ca_data_type_inherit(self, other);
1339
1399
 
1340
1400
  return self;
1341
1401
  }
@@ -1357,35 +1417,38 @@ rb_cs_coerce (VALUE self, VALUE other)
1357
1417
  }
1358
1418
  */
1359
1419
 
1360
- /* @private
1361
- @overload mem_usage
1362
- */
1363
-
1420
+ /* Internal primitive that wraps rb_carray_new (= uninit alloc) for the
1421
+ Ruby-side CArray.empty factory in lib/carray/data_type_extension.rb.
1422
+ Bypasses the explicit MEMZERO that CArray.new (= rb_carray_new_safe)
1423
+ pays for safety. CA_OBJECT silently falls through to the zero-VALUE
1424
+ init inside carray_setup_i (= required for GC), so it is safe to
1425
+ call this with any data_type. */
1364
1426
  static VALUE
1365
- rb_ca_mem_usage (VALUE self)
1427
+ rb_ca_s_alloc_uninit (VALUE klass, VALUE rtype, VALUE rshape)
1366
1428
  {
1367
- return rb_float_new(ca_mem_usage);
1429
+ int8_t data_type;
1430
+ ca_size_t bytes;
1431
+ ca_size_t dim[CA_RANK_MAX];
1432
+ int8_t ndim;
1433
+ int8_t i;
1434
+ rb_ca_guess_type_and_bytes(rtype, Qnil, &data_type, &bytes);
1435
+ Check_Type(rshape, T_ARRAY);
1436
+ ndim = (int8_t) RARRAY_LEN(rshape);
1437
+ for (i = 0; i < ndim; i++) dim[i] = NUM2SIZE(rb_ary_entry(rshape, i));
1438
+ return rb_carray_new(data_type, ndim, dim, bytes, NULL);
1368
1439
  }
1369
1440
 
1370
1441
  void
1371
- Init_ca_obj_array ()
1442
+ Init_ca_obj_array (void)
1372
1443
  {
1373
1444
  /* rb_cCArray, CA_OBJ_ARRAY are defined in rb_carray.c */
1374
1445
  /* rb_cCAWrap, CA_OBJ_ARRAY_WRAP are defined in rb_carray.c */
1375
1446
  /* rb_cCScalar, CA_OBJ_SCALAR are defined in rb_carray.c */
1376
1447
 
1377
- /* ------------------------------------------------------------------- */
1378
- ca_gc_interval = ca_default_gc_interval;
1379
-
1380
- /* @private */
1381
- rb_define_const(rb_cCArray, "DEFAULT_GC_INTERVAL", rb_float_new(ca_default_gc_interval));
1382
-
1383
- rb_define_singleton_method(rb_cCArray, "gc_interval", rb_ca_get_gc_interval, 0);
1384
- rb_define_singleton_method(rb_cCArray, "gc_interval=", rb_ca_set_gc_interval, 1);
1385
- rb_define_singleton_method(rb_cCArray, "reset_gc_interval", rb_ca_reset_gc_interval, 0);
1386
-
1387
1448
  rb_define_alloc_func(rb_cCArray, rb_ca_s_allocate);
1388
1449
  rb_define_method(rb_cCArray, "initialize", rb_ca_initialize, -1);
1450
+ rb_define_singleton_method(rb_cCArray, "__alloc_uninit__",
1451
+ rb_ca_s_alloc_uninit, 2);
1389
1452
 
1390
1453
  rb_define_singleton_method(rb_cCArray, "fixlen", rb_ca_s_fixlen, -1);
1391
1454
  rb_define_singleton_method(rb_cCArray, "boolean", rb_ca_s_boolean, -1);
@@ -1399,11 +1462,9 @@ Init_ca_obj_array ()
1399
1462
  rb_define_singleton_method(rb_cCArray, "uint64", rb_ca_s_uint64, -1);
1400
1463
  rb_define_singleton_method(rb_cCArray, "float32", rb_ca_s_float32, -1);
1401
1464
  rb_define_singleton_method(rb_cCArray, "float64", rb_ca_s_float64, -1);
1402
- rb_define_singleton_method(rb_cCArray, "float128", rb_ca_s_float128, -1);
1403
1465
  #ifdef HAVE_COMPLEX_H
1404
1466
  rb_define_singleton_method(rb_cCArray, "cmplx64", rb_ca_s_cmplx64, -1);
1405
1467
  rb_define_singleton_method(rb_cCArray, "cmplx128", rb_ca_s_cmplx128, -1);
1406
- rb_define_singleton_method(rb_cCArray, "cmplx256", rb_ca_s_cmplx256, -1);
1407
1468
  #endif
1408
1469
  rb_define_singleton_method(rb_cCArray, "object", rb_ca_s_VALUE, -1);
1409
1470
 
@@ -1438,11 +1499,9 @@ Init_ca_obj_array ()
1438
1499
  rb_define_singleton_method(rb_cCScalar, "uint64", rb_cs_s_uint64, -1);
1439
1500
  rb_define_singleton_method(rb_cCScalar, "float32", rb_cs_s_float32, -1);
1440
1501
  rb_define_singleton_method(rb_cCScalar, "float64", rb_cs_s_float64, -1);
1441
- rb_define_singleton_method(rb_cCScalar, "float128", rb_cs_s_float128, -1);
1442
1502
  #ifdef HAVE_COMPLEX_H
1443
1503
  rb_define_singleton_method(rb_cCScalar, "cmplx64", rb_cs_s_cmplx64, -1);
1444
1504
  rb_define_singleton_method(rb_cCScalar, "cmplx128", rb_cs_s_cmplx128, -1);
1445
- rb_define_singleton_method(rb_cCScalar, "cmplx256", rb_cs_s_cmplx256, -1);
1446
1505
  #endif
1447
1506
  rb_define_singleton_method(rb_cCScalar, "object", rb_cs_s_VALUE, -1);
1448
1507
 
@@ -1463,67 +1522,4 @@ Init_ca_obj_array ()
1463
1522
  rb_define_const(rb_cObject, "CA_OBJ_ARRAY_WRAP", INT2NUM(CA_OBJ_ARRAY_WRAP));
1464
1523
  rb_define_const(rb_cObject, "CA_OBJ_SCALAR", INT2NUM(CA_OBJ_SCALAR));
1465
1524
 
1466
- rb_define_singleton_method(rb_cCArray, "mem_usage", rb_ca_mem_usage, 0);
1467
-
1468
- }
1469
-
1470
-
1471
- /* yard:
1472
- # call-seq:
1473
- # CArray.boolean(...) { init_value }
1474
- # CArray.int8(...) { init_value }
1475
- # CArray.uint8(...) { init_value }
1476
- # CArray.int16(...) { init_value }
1477
- # CArray.uint16(...) { init_value }
1478
- # CArray.int32(...) { init_value }
1479
- # CArray.uint32(...) { init_value }
1480
- # CArray.int64(...) { init_value }
1481
- # CArray.uint64(...) { init_value }
1482
- # CArray.float32(...) { init_value }
1483
- # CArray.float64(...) { init_value }
1484
- # CArray.float128(...) { init_value }
1485
- # CArray.cmplx64(...) { init_value }
1486
- # CArray.cmplx128(...) { init_value }
1487
- # CArray.cmplx256(...) { init_value }
1488
- # CArray.fixlen(...) { init_value }
1489
- # CArray.object(...) { init_value }
1490
- # CArray.byte(...) { init_value }
1491
- # CArray.short(...) { init_value }
1492
- # CArray.int(...) { init_value }
1493
- # CArray.float(...) { init_value }
1494
- # CArray.double(...) { init_value }
1495
- # CArray.complex(...) { init_value }
1496
- # CArray.dcomplex(...) { init_value }
1497
- #
1498
- def CArray.type
1499
- end
1500
-
1501
- # call-seq:
1502
- # CScalar.boolean { init_value }
1503
- # CScalar.int8 { init_value }
1504
- # CScalar.uint8 { init_value }
1505
- # CScalar.int16 { init_value }
1506
- # CScalar.uint16 { init_value }
1507
- # CScalar.int32 { init_value }
1508
- # CScalar.uint32 { init_value }
1509
- # CScalar.int64 { init_value }
1510
- # CScalar.uint64 { init_value }
1511
- # CScalar.float32 { init_value }
1512
- # CScalar.float64 { init_value }
1513
- # CScalar.float128 { init_value }
1514
- # CScalar.cmplx64 { init_value }
1515
- # CScalar.cmplx128 { init_value }
1516
- # CScalar.cmplx256 { init_value }
1517
- # CScalar.fixlen { init_value }
1518
- # CScalar.object { init_value }
1519
- # CScalar.byte { init_value }
1520
- # CScalar.short { init_value }
1521
- # CScalar.int { init_value }
1522
- # CScalar.float { init_value }
1523
- # CScalar.double { init_value }
1524
- # CScalar.complex { init_value }
1525
- # CScalar.dcomplex { init_value }
1526
- #
1527
- def CScalar.type
1528
- end
1529
- */
1525
+ }