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_fake.c CHANGED
@@ -1,14 +1,17 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- ca_obj_fake.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
3
+ CAFake — data_type reinterpret / cast view. Presents self.parent with
4
+ a different data_type (and possibly bytes), casting values on read
5
+ and write via ca_cast_block. Ruby surface: CArray#fake (see
6
+ yard-stubs).
8
7
 
9
8
  ---------------------------------------------------------------------------- */
10
9
 
11
10
  #include "carray.h"
11
+ #include "carray_internal.h" /* per-obj_type view constructors */
12
+ #include "ca_iter_substrate.h" /* ca_xfer_stride_transform_fused */
13
+
14
+ extern ca_operation_function_t ca_stride_func;
12
15
 
13
16
  typedef struct {
14
17
  int16_t obj_type;
@@ -20,18 +23,42 @@ typedef struct {
20
23
  ca_size_t *dim;
21
24
  char *ptr;
22
25
  CArray *mask;
26
+ char *_pool; /* framework-managed pool buffer (NULL = legacy ALLOC_N path). */
23
27
  CArray *parent;
24
28
  uint32_t attach;
25
29
  uint8_t nosync;
26
30
  } CAFake;
27
31
 
32
+ static size_t
33
+ ca_fake_dsize (const void *ap)
34
+ {
35
+ const CAFake *ca = (const CAFake *) ap;
36
+ return sizeof(CAFake) + ca->ndim * sizeof(ca_size_t);
37
+ }
38
+
39
+ /* Pool framework hooks: single ndim-sized tail (dim) in the _pool
40
+ buffer, uniform with the other pool-migrated views. */
41
+ static size_t
42
+ ca_fake_pool_bytes (int8_t ndim)
43
+ {
44
+ ca_size_t n = (ndim > 0) ? ndim : 1;
45
+ return (size_t) n * sizeof(ca_size_t);
46
+ }
47
+
48
+ static void
49
+ ca_fake_pool_init (void *ap, int8_t ndim)
50
+ {
51
+ CAFake *ca = (CAFake *) ap;
52
+ ca->dim = (ca_size_t *) ca->_pool;
53
+ }
54
+
28
55
  const rb_data_type_t cafake_data_type = {
29
- .parent = &cavirtual_data_type,
56
+ .parent = &caview_data_type,
30
57
  .wrap_struct_name = "CAFake",
31
58
  .function = {
32
59
  .dmark = ca_mark,
33
60
  .dfree = ca_free,
34
- .dsize = NULL,
61
+ .dsize = ca_fake_dsize,
35
62
  .dcompact = NULL
36
63
  },
37
64
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
@@ -41,11 +68,6 @@ static int8_t CA_OBJ_FAKE;
41
68
 
42
69
  static VALUE rb_cCAFake;
43
70
 
44
- /* yard:
45
- class CAFake < CAVirtual # :nodoc:
46
- end
47
- */
48
-
49
71
  /* ------------------------------------------------------------------- */
50
72
 
51
73
  int
@@ -71,7 +93,9 @@ ca_fake_setup (CAFake *ca, CArray *parent, int8_t data_type, ca_size_t bytes)
71
93
  ca->elements = elements;
72
94
  ca->ptr = NULL;
73
95
  ca->mask = NULL;
74
- ca->dim = ALLOC_N(ca_size_t, ndim);
96
+ if ( ! ca->_pool ) {
97
+ ca->dim = ALLOC_N(ca_size_t, ndim);
98
+ }
75
99
 
76
100
  ca->parent = parent;
77
101
  ca->attach = 0;
@@ -93,7 +117,7 @@ ca_fake_setup (CAFake *ca, CArray *parent, int8_t data_type, ca_size_t bytes)
93
117
  CAFake *
94
118
  ca_fake_new (CArray *parent, int8_t data_type, ca_size_t bytes)
95
119
  {
96
- CAFake *ca = ALLOC(CAFake);
120
+ CAFake *ca = (CAFake *) ca_array_alloc(CA_OBJ_FAKE, parent->ndim);
97
121
  ca_fake_setup(ca, parent, data_type, bytes);
98
122
  return ca;
99
123
  }
@@ -104,8 +128,13 @@ free_ca_fake (void *ap)
104
128
  CAFake *ca = (CAFake *) ap;
105
129
  if ( ca != NULL ) {
106
130
  ca_free(ca->mask);
107
- xfree(ca->dim);
108
- xfree(ca);
131
+ if ( ca->_pool ) {
132
+ ca_array_free(ca); /* dim lives in _pool */
133
+ }
134
+ else {
135
+ xfree(ca->dim);
136
+ xfree(ca);
137
+ }
109
138
  }
110
139
  }
111
140
 
@@ -119,52 +148,127 @@ ca_fake_func_clone (void *ap)
119
148
  return ca_fake_new(ca->parent, ca->data_type, ca->bytes);
120
149
  }
121
150
 
122
- static char *
123
- ca_fake_func_ptr_at_addr (void *ap, ca_size_t addr)
124
- {
125
- CAFake *ca = (CAFake *) ap;
126
- return ca->ptr + ca->bytes * addr;
127
- }
128
-
129
- static char *
130
- ca_fake_func_ptr_at_index (void *ap, ca_size_t *idx)
151
+ /* Per-cell GET/PUT via a parent-sized scratch cell — same code services
152
+ both directions, casting through the parent data_type. */
153
+ static void
154
+ ca_fake_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
131
155
  {
132
156
  CAFake *ca = (CAFake *) ap;
133
- return ca_func[CA_OBJ_ARRAY].ptr_at_index(ca, idx);
157
+ char sbuf[32];
158
+ char *v = (ca->parent->bytes <= 32) ? sbuf : xmalloc(ca->parent->bytes);
159
+ if ( dir == CA_XFER_GET ) {
160
+ ca_fetch_index(ca->parent, idx, v);
161
+ ca_ptr2ptr(ca->parent, v, ca, data);
162
+ }
163
+ else {
164
+ ca_ptr2ptr(ca, data, ca->parent, v);
165
+ ca_store_index(ca->parent, idx, v);
166
+ }
167
+ if ( v != sbuf ) xfree(v);
134
168
  }
135
169
 
170
+ /* Batched address gather/scatter. CAFake is a 1:1 reinterpret-cast
171
+ view, so its flat addr equals the parent's — the same addr list is
172
+ handed to the parent in one call and the data_type cast is applied
173
+ in flight over a parent-data_type scratch. */
136
174
  static void
137
- ca_fake_func_fetch_index (void *ap, ca_size_t *idx, void *ptr)
175
+ ca_fake_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
176
+ void *data, int dir)
138
177
  {
139
178
  CAFake *ca = (CAFake *) ap;
140
- if ( ca->parent->bytes <= 32 ) {
141
- char v[32];
142
- ca_fetch_index(ca->parent, idx, v);
143
- ca_ptr2ptr(ca->parent, v, ca, ptr);
179
+ CArray *parent = ca->parent;
180
+ CArray *eff;
181
+ ca_size_t base;
182
+ char *v;
183
+ volatile VALUE holder;
184
+
185
+ /* Sequential-run + live-ptr fast path: cast directly from
186
+ parent->ptr + base*pbytes to data, no intermediate scratch. */
187
+ eff = ca_resolve_attached_root_via_identity(parent);
188
+ if ( eff->ptr && ca_xfer_addrs_is_sequential_run(n, addrs, &base) ) {
189
+ char *p = eff->ptr + base * eff->bytes;
190
+ if ( dir == CA_XFER_GET ) {
191
+ ca_cast_block(n, eff, p, (CArray *) ca, data);
192
+ } else {
193
+ ca_cast_block(n, (CArray *) ca, data, eff, p);
194
+ }
195
+ return;
196
+ }
197
+
198
+ /* Fallback 2-pass (arbitrary addrs, non-identity parent): allocate
199
+ a parent-data_type scratch and gather/cast via parent.xfer_addrs. */
200
+ v = ALLOCV_N(char, holder, n * parent->bytes);
201
+ if ( dir == CA_XFER_GET ) {
202
+ ca_xfer_addrs(parent, n, addrs, v, CA_XFER_GET);
203
+ ca_cast_block(n, parent, v, ca, data);
144
204
  }
145
205
  else {
146
- char *v = malloc_with_check(ca->parent->bytes);
147
- ca_fetch_index(ca->parent, idx, v);
148
- ca_ptr2ptr(ca->parent, v, ca, ptr);
149
- free(v);
206
+ ca_cast_block(n, ca, data, parent, v);
207
+ ca_xfer_addrs(parent, n, addrs, v, CA_XFER_PUT);
150
208
  }
209
+ ALLOCV_END(holder);
151
210
  }
152
211
 
212
+ /* Per-row transform callbacks for the fused-walk fast path. CAFake
213
+ is a byte-aligned data_type cast in both directions, so xform_get /
214
+ xform_put are thin ca_cast_block wrappers with swapped src/dst
215
+ array roles. */
153
216
  static void
154
- ca_fake_func_store_index (void *ap, ca_size_t *idx, void *ptr)
217
+ ca_fake_xform_get (ca_size_t n, CArray *src_arr, char *src_row,
218
+ CArray *dst_arr, char *dst_row)
155
219
  {
156
- CAFake *ca = (CAFake *) ap;
157
- if ( ca->parent->bytes <= 32 ) {
158
- char v[32];
159
- ca_ptr2ptr(ca, ptr, ca->parent, v);
160
- ca_store_index(ca->parent, idx, v);
220
+ ca_cast_block(n, src_arr, src_row, dst_arr, dst_row);
221
+ }
222
+
223
+ static void
224
+ ca_fake_xform_put (ca_size_t n, CArray *src_arr, char *src_row,
225
+ CArray *dst_arr, char *dst_row)
226
+ {
227
+ ca_cast_block(n, src_arr, src_row, dst_arr, dst_row);
228
+ }
229
+
230
+ /* xfer_stride — try the fused walk + cast fast path (compose the
231
+ parent chain to its root, gather the inner row from root.ptr
232
+ strided into a row scratch, cast to dst in one pass). Falls back
233
+ to the scratch + cast 2-pass when eligibility fails (non-CAStride
234
+ parent, cold root, byte-mismatch reinterpret). Mask is not
235
+ consulted here — it propagates on a separate channel. */
236
+ static void
237
+ ca_fake_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
238
+ ca_size_t *strides, void *data, int dir)
239
+ {
240
+ CAFake *ca = (CAFake *) ap;
241
+ int8_t ndim = ca->ndim;
242
+ ca_size_t pstrides[CA_RANK_MAX];
243
+ ca_size_t n = 1;
244
+ int8_t k;
245
+ char *v;
246
+ volatile VALUE holder;
247
+
248
+ /* Fast path: fused walk + cast for GET/PUT */
249
+ if ( ca_xfer_stride_transform_fused((CArray *)ca, ca->parent,
250
+ starts, counts, strides,
251
+ (char *)data, dir,
252
+ ca_fake_xform_get,
253
+ ca_fake_xform_put) ) {
254
+ return;
255
+ }
256
+
257
+ /* Fallback: legacy scratch + cast_block 2-pass */
258
+ for ( k = 0; k < ndim; k++ ) {
259
+ n *= counts[k];
260
+ pstrides[k] = strides[k] / ca->bytes * ca->parent->bytes;
261
+ }
262
+ v = ALLOCV_N(char, holder, n * ca->parent->bytes);
263
+ if ( dir == CA_XFER_GET ) {
264
+ ca_xfer_stride(ca->parent, starts, counts, pstrides, v, CA_XFER_GET);
265
+ ca_cast_block(n, ca->parent, v, ca, data);
161
266
  }
162
267
  else {
163
- char *v = malloc_with_check(ca->parent->bytes);
164
- ca_ptr2ptr(ca, ptr, ca->parent, v);
165
- ca_store_index(ca->parent, idx, v);
166
- free(v);
268
+ ca_cast_block(n, ca, data, ca->parent, v);
269
+ ca_xfer_stride(ca->parent, starts, counts, pstrides, v, CA_XFER_PUT);
167
270
  }
271
+ ALLOCV_END(holder);
168
272
  }
169
273
 
170
274
  static void
@@ -172,10 +276,10 @@ ca_fake_func_allocate (void *ap)
172
276
  {
173
277
  CAFake *ca = (CAFake *) ap;
174
278
  ca_attach(ca->parent);
175
- /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
176
- ca->ptr = malloc_with_check(ca_length(ca));
279
+ ca->ptr = xmalloc(ca_length(ca));
177
280
 
178
- /* initialize elements with 0 for CA_OBJECT data_type */
281
+ /* CAREFUL: CA_OBJECT storage must contain valid VALUEs before GC can
282
+ scan it, so seed with Fixnum 0 rather than leaving raw xmalloc bytes. */
179
283
  if ( ca->data_type == CA_OBJECT ) {
180
284
  VALUE *p = (VALUE *) ca->ptr;
181
285
  VALUE zero = SIZE2NUM(0);
@@ -189,14 +293,11 @@ ca_fake_func_allocate (void *ap)
189
293
  static void
190
294
  ca_fake_func_attach (void *ap)
191
295
  {
192
- void ca_fake_attach (CAFake *cb);
193
-
194
296
  CAFake *ca = (CAFake *) ap;
195
297
  ca_attach(ca->parent);
196
- /* ca->ptr = ALLOC_N(char, ca_length(ca)); */
197
- ca->ptr = malloc_with_check(ca_length(ca));
298
+ ca->ptr = xmalloc(ca_length(ca));
198
299
 
199
- /* initialize elements with 0 for CA_OBJECT data_type */
300
+ /* CAREFUL: same VALUE-seed rule as ca_fake_func_allocate. */
200
301
  if ( ca->data_type == CA_OBJECT ) {
201
302
  VALUE *p = (VALUE *) ca->ptr;
202
303
  VALUE zero = SIZE2NUM(0);
@@ -235,56 +336,86 @@ static void
235
336
  ca_fake_func_detach (void *ap)
236
337
  {
237
338
  CAFake *ca = (CAFake *) ap;
238
- free(ca->ptr);
339
+ xfree(ca->ptr);
239
340
  ca->ptr = NULL;
240
341
  ca_detach(ca->parent);
241
342
  }
242
343
 
344
+ /* Thin wrapper around xfer_stride that walks native row-major
345
+ strides. xfer_stride itself picks the right rung via
346
+ ca_xfer_stride_transform_fused:
347
+ CAStride family parent fused walk + cast in one pass
348
+ Non-CAStride parent with live ptr fused via linear stride math
349
+ Cold non-CAStride parent scratch + xfer_stride + cast fallback */
350
+ static void
351
+ ca_fake_func_xfer_all (void *ap, void *data, int dir)
352
+ {
353
+ CAFake *ca = (CAFake *) ap;
354
+ ca_size_t starts[CA_RANK_MAX];
355
+ ca_size_t native[CA_RANK_MAX];
356
+ int8_t k;
357
+ ca_size_t s = ca->bytes;
358
+ for ( k = ca->ndim - 1; k >= 0; k-- ) { native[k] = s; s *= ca->dim[k]; }
359
+ for ( k = 0; k < ca->ndim; k++ ) starts[k] = 0;
360
+ ca_xfer_stride(ca, starts, ca->dim, native, data, dir);
361
+ }
362
+
363
+
243
364
  static void
244
- ca_fake_func_copy_data (void *ap, void *ptr)
365
+ ca_fake_func_fill_data (void *ap, void *ptr)
245
366
  {
246
367
  CAFake *ca = (CAFake *) ap;
247
- ca_attach(ca->parent);
248
- ca_update_mask(ca);
249
- if ( ca->parent->mask ) {
250
- ca_cast_block_with_mask(ca->elements, ca->parent, ca->parent->ptr, ca, ptr,
251
- (boolean8_t*)ca->parent->mask->ptr);
368
+ if ( ca->parent->bytes <= 32 ) {
369
+ char v[32];
370
+ ca_ptr2ptr(ca, ptr, ca->parent, v);
371
+ ca_fill(ca->parent, v);
252
372
  }
253
373
  else {
254
- ca_cast_block(ca->elements, ca->parent, ca->parent->ptr, ca, ptr);
374
+ char *v = xmalloc(ca->parent->bytes);
375
+ ca_ptr2ptr(ca, ptr, ca->parent, v);
376
+ ca_fill(ca->parent, v);
377
+ xfree(v);
255
378
  }
256
- ca_detach(ca->parent);
257
379
  }
258
380
 
381
+ /* Same as fill_data, with a region: convert the one value once and pass the
382
+ region on unchanged. A fake reinterprets the type, not the shape, so its
383
+ addresses are its parent's addresses and there is nothing to translate --
384
+ which is the whole reason a partial fill through a lossy cast need not read
385
+ anything back. */
386
+
259
387
  static void
260
- ca_fake_func_sync_data (void *ap, void *ptr)
388
+ ca_fake_func_fill_stride (void *ap, ca_size_t base, int8_t ndim,
389
+ ca_size_t *counts, ca_size_t *steps, void *ptr)
261
390
  {
262
391
  CAFake *ca = (CAFake *) ap;
263
- ca_attach(ca->parent);
264
- if ( ca->parent->mask ) {
265
- ca_cast_block_with_mask(ca->elements, ca, ptr, ca->parent, ca->parent->ptr,
266
- (boolean8_t*)ca->parent->mask->ptr);
392
+ if ( ca->parent->bytes <= 32 ) {
393
+ char v[32];
394
+ ca_ptr2ptr(ca, ptr, ca->parent, v);
395
+ ca_fill_stride(ca->parent, base, ndim, counts, steps, v);
267
396
  }
268
397
  else {
269
- ca_cast_block(ca->elements, ca, ptr, ca->parent, ca->parent->ptr);
398
+ char *v = xmalloc(ca->parent->bytes);
399
+ ca_ptr2ptr(ca, ptr, ca->parent, v);
400
+ ca_fill_stride(ca->parent, base, ndim, counts, steps, v);
401
+ xfree(v);
270
402
  }
271
- ca_detach(ca->parent);
272
403
  }
273
404
 
274
405
  static void
275
- ca_fake_func_fill_data (void *ap, void *ptr)
406
+ ca_fake_func_fill_addrs (void *ap, ca_size_t n, ca_size_t *addrs, void *ptr)
276
407
  {
277
408
  CAFake *ca = (CAFake *) ap;
278
409
  if ( ca->parent->bytes <= 32 ) {
279
410
  char v[32];
280
411
  ca_ptr2ptr(ca, ptr, ca->parent, v);
281
- ca_fill(ca->parent, v);
412
+ ca_fill_addrs(ca->parent, n, addrs, v);
282
413
  }
283
414
  else {
284
- char *v = malloc_with_check(ca->parent->bytes);
415
+ char *v = xmalloc(ca->parent->bytes);
285
416
  ca_ptr2ptr(ca, ptr, ca->parent, v);
286
- ca_fill(ca->parent, v);
287
- free(v);
417
+ ca_fill_addrs(ca->parent, n, addrs, v);
418
+ xfree(v);
288
419
  }
289
420
  }
290
421
 
@@ -303,23 +434,22 @@ ca_fake_func_create_mask (void *ap)
303
434
 
304
435
  ca_operation_function_t ca_fake_func = {
305
436
  -1, /* CA_OBJ_FAKE */
306
- CA_VIRTUAL_ARRAY,
437
+ CA_VIEW_ARRAY,
307
438
  free_ca_fake,
308
439
  ca_fake_func_clone,
309
- ca_fake_func_ptr_at_addr,
310
- ca_fake_func_ptr_at_index,
311
- NULL,
312
- ca_fake_func_fetch_index,
313
- NULL,
314
- ca_fake_func_store_index,
315
440
  ca_fake_func_allocate,
316
441
  ca_fake_func_attach,
317
442
  ca_fake_func_sync,
318
443
  ca_fake_func_detach,
319
- ca_fake_func_copy_data,
320
- ca_fake_func_sync_data,
321
444
  ca_fake_func_fill_data,
322
445
  ca_fake_func_create_mask,
446
+ ca_fake_func_xfer_index,
447
+ ca_fake_func_xfer_addrs,
448
+ NULL, /* fold_stride: never-fold (transform boundary) */
449
+ ca_fake_func_xfer_stride,
450
+ ca_fake_func_xfer_all,
451
+ .fill_addrs = ca_fake_func_fill_addrs,
452
+ .fill_stride = ca_fake_func_fill_stride,
323
453
  };
324
454
 
325
455
  /* ------------------------------------------------------------------- */
@@ -338,29 +468,21 @@ rb_ca_fake_new (VALUE cary, int8_t data_type, ca_size_t bytes)
338
468
  return obj;
339
469
  }
340
470
 
341
- /* yard:
342
- class CArray
343
- def fake (data_type, options={:bytes=>0})
344
- end
345
- end
346
- */
347
-
471
+ /* CArray#fake(data_type, bytes: 0) — return a CAFake view of self that
472
+ * reinterprets each cell as the given data_type (fixlen needs `bytes:`).
473
+ * Storage is shared with self via ca_cast_block on read/write. */
348
474
  VALUE
349
475
  rb_ca_fake (int argc, VALUE *argv, VALUE self)
350
476
  {
351
477
  volatile VALUE obj, rtype, ropt, rbytes = Qnil;
352
- CArray *ca;
353
478
  int8_t data_type;
354
479
  ca_size_t bytes;
355
480
 
356
- TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
357
-
358
481
  rb_scan_args(argc, argv, "11", (VALUE *) &rtype, (VALUE *) &ropt);
359
482
  rb_scan_options(ropt, "bytes", &rbytes);
360
483
 
361
484
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
362
485
  obj = rb_ca_fake_new(self, data_type, bytes);
363
- rb_ca_data_type_import(obj, rtype);
364
486
 
365
487
  return obj;
366
488
  }
@@ -373,7 +495,6 @@ rb_ca_fake_type (VALUE self, VALUE rtype, VALUE rbytes)
373
495
  ca_size_t bytes;
374
496
  rb_ca_guess_type_and_bytes(rtype, rbytes, &data_type, &bytes);
375
497
  obj = rb_ca_fake_new(self, data_type, bytes);
376
- rb_ca_data_type_import(obj, rtype);
377
498
  return obj;
378
499
  }
379
500
 
@@ -392,20 +513,27 @@ rb_ca_fake_initialize_copy (VALUE self, VALUE other)
392
513
  TypedData_Get_Struct(self, CAFake, &cafake_data_type, ca);
393
514
  TypedData_Get_Struct(other, CAFake, &cafake_data_type, cs);
394
515
 
516
+ if ( ca_func[CA_OBJ_FAKE].pool_init ) {
517
+ ca_array_pool_alloc(ca, CA_OBJ_FAKE, cs->parent->ndim);
518
+ }
395
519
  ca_fake_setup(ca, cs->parent, cs->data_type, cs->bytes);
396
520
 
397
521
  return self;
398
522
  }
399
523
 
400
524
  void
401
- Init_ca_obj_fake ()
525
+ Init_ca_obj_fake (void)
402
526
  {
403
- rb_cCAFake = rb_define_class("CAFake", rb_cCAVirtual);
527
+ rb_cCAFake = rb_define_class("CAFake", rb_cCAView);
528
+
529
+ ca_fake_func.struct_size = sizeof(CAFake);
530
+ ca_fake_func.pool_bytes = ca_fake_pool_bytes;
531
+ ca_fake_func.pool_init = ca_fake_pool_init;
404
532
 
405
- CA_OBJ_FAKE = ca_install_obj_type(rb_cCAFake,
406
- &cafake_data_type,
533
+ CA_OBJ_FAKE = ca_install_obj_type(rb_cCAFake,
534
+ &cafake_data_type,
407
535
  rb_cCArrayMask,
408
- &carray_data_type, ca_fake_func);
536
+ &carray_mask_data_type, &ca_fake_func, sizeof(ca_fake_func));
409
537
  rb_define_const(rb_cObject, "CA_OBJ_FAKE", INT2NUM(CA_OBJ_FAKE));
410
538
 
411
539
  rb_define_method(rb_cCArray, "fake", rb_ca_fake, -1);