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_tile.c ADDED
@@ -0,0 +1,614 @@
1
+ /* ---------------------------------------------------------------------------
2
+
3
+ CATile — N-region expansion view (tiled repetition of the parent).
4
+ Output shape = parent.dim[k] * reps[k] per axis; each tile at output
5
+ offset (i_0 * parent.dim[0], ...) is a full-parent alias. Total
6
+ tiles = product(reps).
7
+
8
+ Attach / sync iterate all tiles, calling
9
+ ca_composite_region_gather / _region_scatter (from
10
+ ca_composite_dispatch.c) for each tile region.
11
+
12
+ CARoll shares this file's struct + operation table (only obj_type
13
+ differs); its constructor emits a 2-region minimal layout instead
14
+ of N-tile expansion, but attach/sync is identical.
15
+
16
+ ---------------------------------------------------------------------------- */
17
+
18
+ #include "carray.h"
19
+ #include "ca_composite_dispatch.h"
20
+ #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
21
+
22
+ /* ------------------------------------------------------------------- */
23
+ /* TypedData */
24
+ /* ------------------------------------------------------------------- */
25
+
26
+ static size_t
27
+ ca_tile_dsize (const void *ap)
28
+ {
29
+ const CATile *ca = (const CATile *) ap;
30
+ /* dim is ALLOC_N(ndim), reps is ALLOC_N(ndim). */
31
+ return sizeof(CATile) + 2 * ca->ndim * sizeof(ca_size_t);
32
+ }
33
+
34
+ const rb_data_type_t catile_data_type = {
35
+ .parent = &caview_data_type,
36
+ .wrap_struct_name = "CATile",
37
+ .function = {
38
+ .dmark = ca_mark,
39
+ .dfree = ca_free,
40
+ .dsize = ca_tile_dsize,
41
+ .dcompact = NULL
42
+ },
43
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
44
+ };
45
+
46
+ const rb_data_type_t catile_mask_data_type = {
47
+ .parent = &catile_data_type,
48
+ .wrap_struct_name = "CATileMask",
49
+ .function = {
50
+ .dmark = ca_mark,
51
+ .dfree = ca_free_nop,
52
+ .dsize = ca_tile_dsize,
53
+ .dcompact = NULL
54
+ },
55
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
56
+ };
57
+
58
+ int8_t CA_OBJ_TILE;
59
+
60
+ VALUE rb_cCATile;
61
+ VALUE rb_cCATileMask;
62
+
63
+ /* ------------------------------------------------------------------- */
64
+ /* setup / new / free / clone */
65
+ /* ------------------------------------------------------------------- */
66
+
67
+ int
68
+ ca_tile_setup (CATile *ca, CArray *parent, ca_size_t *reps)
69
+ {
70
+ int8_t data_type, ndim;
71
+ ca_size_t bytes, elements;
72
+ int8_t i;
73
+
74
+ data_type = parent->data_type;
75
+ ndim = parent->ndim;
76
+ bytes = parent->bytes;
77
+
78
+ elements = 1;
79
+ for (i = 0; i < ndim; i++) {
80
+ if ( reps[i] <= 0 ) {
81
+ rb_raise(rb_eIndexError,
82
+ "invalid reps for %d-th dimension (must be positive)", i);
83
+ }
84
+ if ( parent->dim[i] <= 0 ) {
85
+ rb_raise(rb_eIndexError,
86
+ "invalid parent dim for %d-th dimension", i);
87
+ }
88
+ elements *= parent->dim[i] * reps[i];
89
+ }
90
+
91
+ ca->obj_type = CA_OBJ_TILE;
92
+ ca->data_type = data_type;
93
+ ca->flags = 0;
94
+ ca->ndim = ndim;
95
+ ca->bytes = bytes;
96
+ ca->elements = elements;
97
+ ca->ptr = NULL;
98
+ ca->mask = NULL;
99
+
100
+ ca->parent = parent;
101
+ ca->attach = 0;
102
+ ca->nosync = 0;
103
+ ca->reps = ALLOC_N(ca_size_t, ndim);
104
+ ca->dim = ALLOC_N(ca_size_t, ndim);
105
+
106
+ for (i = 0; i < ndim; i++) {
107
+ ca->reps[i] = reps[i];
108
+ ca->dim[i] = parent->dim[i] * reps[i];
109
+ }
110
+
111
+ if ( ca_has_mask(parent) ) {
112
+ ca_create_mask(ca);
113
+ }
114
+
115
+ return 0;
116
+ }
117
+
118
+ CATile *
119
+ ca_tile_new (CArray *parent, ca_size_t *reps)
120
+ {
121
+ CATile *ca = ALLOC(CATile);
122
+ ca_tile_setup(ca, parent, reps);
123
+ return ca;
124
+ }
125
+
126
+ static void
127
+ free_ca_tile (void *ap)
128
+ {
129
+ CATile *ca = (CATile *) ap;
130
+ if ( ca != NULL ) {
131
+ ca_free(ca->mask);
132
+ xfree(ca->reps);
133
+ xfree(ca->dim);
134
+ xfree(ca);
135
+ }
136
+ }
137
+
138
+ static void *
139
+ ca_tile_func_clone (void *ap)
140
+ {
141
+ CATile *ca = (CATile *) ap;
142
+ return ca_tile_new(ca->parent, ca->reps);
143
+ }
144
+
145
+ /* ------------------------------------------------------------------- */
146
+ /* fetch / store */
147
+ /* ------------------------------------------------------------------- */
148
+
149
+ /* xfer_index: view[i_0, ...] = parent[i_0 % parent.dim[0], ...].
150
+ PUT is last-write-wins when tiles overlap. */
151
+ static void
152
+ ca_tile_func_xfer_index (void *ap, ca_size_t *idx, void *data, int dir)
153
+ {
154
+ CATile *ca = (CATile *) ap;
155
+ ca_size_t pidx[CA_RANK_MAX];
156
+ int8_t i;
157
+ for (i = 0; i < ca->ndim; i++) {
158
+ pidx[i] = idx[i] % ca->parent->dim[i];
159
+ }
160
+ ca_xfer_index(ca->parent, pidx, data, dir);
161
+ }
162
+
163
+ /* Batched address gather/scatter: translate each view addr to a
164
+ parent flat addr (modulo wrap, always in-bounds) and hand the
165
+ whole list to the parent in one ca_xfer_addrs call — no whole-view
166
+ attach. */
167
+ static void
168
+ ca_tile_func_xfer_addrs (void *ap, ca_size_t n, ca_size_t *addrs,
169
+ void *data, int dir)
170
+ {
171
+ CATile *ca = (CATile *) ap;
172
+ ca_size_t *paddrs;
173
+ ca_size_t i;
174
+ int8_t k;
175
+ volatile VALUE holder;
176
+ paddrs = ALLOCV_N(ca_size_t, holder, n);
177
+ for (i = 0; i < n; i++) {
178
+ ca_size_t vidx[CA_RANK_MAX], pidx[CA_RANK_MAX];
179
+ ca_addr2index((CArray *) ca, addrs[i], vidx);
180
+ for (k = 0; k < ca->ndim; k++) pidx[k] = vidx[k] % ca->parent->dim[k];
181
+ paddrs[i] = ca_index2addr(ca->parent, pidx);
182
+ }
183
+ ca_xfer_addrs(ca->parent, n, paddrs, data, dir);
184
+ ALLOCV_END(holder);
185
+ }
186
+
187
+ /* Structural region delivery for CATile. Each axis maps to the
188
+ parent by modulo (view_pos % parent.dim), so a contiguous inner
189
+ run wraps at tile boundaries — split into per-tile segments, each
190
+ a contiguous parent run delivered via parent.xfer_stride. Outer
191
+ axes iterate cell by cell (one modulo per parent position). The
192
+ structural path requires axis-aligned + unit src step; otherwise a
193
+ per-cell fallback runs. data is contiguous (semantics b); no
194
+ whole-view attach. bytes == parent.bytes (no reinterpret). */
195
+ static void
196
+ ca_tile_func_xfer_stride (void *ap, ca_size_t *starts, ca_size_t *counts,
197
+ ca_size_t *strides, void *data, int dir)
198
+ {
199
+ CATile *ca = (CATile *) ap;
200
+ CArray *parent = ca->parent;
201
+ int8_t ndim = ca->ndim;
202
+ int8_t inner = ndim - 1;
203
+ ca_size_t pnative[CA_RANK_MAX], tnative[CA_RANK_MAX], dstride[CA_RANK_MAX];
204
+ ca_size_t o[CA_RANK_MAX];
205
+ ca_size_t s;
206
+ int8_t k;
207
+ int structural = 1;
208
+ char *d = (char *) data;
209
+
210
+ s = parent->bytes;
211
+ for (k = ndim - 1; k >= 0; k--) { pnative[k] = s; s *= parent->dim[k]; }
212
+ s = ca->bytes;
213
+ for (k = ndim - 1; k >= 0; k--) { tnative[k] = s; s *= ca->dim[k]; }
214
+ s = ca->bytes;
215
+ for (k = ndim - 1; k >= 0; k--) { dstride[k] = s; s *= counts[k]; }
216
+
217
+ for (k = 0; k < ndim; k++) {
218
+ if (strides[k] % tnative[k] != 0 || strides[k] / tnative[k] != 1) {
219
+ structural = 0;
220
+ break;
221
+ }
222
+ }
223
+
224
+ if (!structural) {
225
+ ca_size_t idx[CA_RANK_MAX], doff = 0, base = 0;
226
+ for (k = 0; k < ndim; k++) base += starts[k] * tnative[k];
227
+ for (k = 0; k < ndim; k++) idx[k] = 0;
228
+ while (1) {
229
+ ca_size_t toff = base, tidx[CA_RANK_MAX];
230
+ for (k = 0; k < ndim; k++) toff += idx[k] * strides[k];
231
+ ca_addr2index((CArray *) ca, toff / ca->bytes, tidx);
232
+ ca_tile_func_xfer_index(ca, tidx, d + doff, dir);
233
+ doff += ca->bytes;
234
+ k = ndim - 1;
235
+ while (k >= 0) { if (++idx[k] < counts[k]) break; idx[k] = 0; k--; }
236
+ if (k < 0) break;
237
+ }
238
+ return;
239
+ }
240
+
241
+ for (k = 0; k < ndim; k++) o[k] = 0;
242
+ while (1) {
243
+ ca_size_t pbase = 0, doff = 0, i;
244
+ for (k = 0; k < inner; k++) {
245
+ pbase += ((starts[k] + o[k]) % parent->dim[k]) * pnative[k];
246
+ doff += o[k] * dstride[k];
247
+ }
248
+ i = 0;
249
+ while (i < counts[inner]) {
250
+ ca_size_t ppos = (starts[inner] + i) % parent->dim[inner];
251
+ ca_size_t seg = parent->dim[inner] - ppos; /* until the tile boundary */
252
+ ca_size_t pstarts[CA_RANK_MAX], pcounts[CA_RANK_MAX], pstrides[CA_RANK_MAX];
253
+ if (seg > counts[inner] - i) seg = counts[inner] - i;
254
+ ca_addr2index((CArray *) parent, (pbase + ppos * pnative[inner]) / parent->bytes, pstarts);
255
+ for (k = 0; k < ndim; k++) { pcounts[k] = 1; pstrides[k] = 0; }
256
+ pcounts[inner] = seg;
257
+ pstrides[inner] = pnative[inner];
258
+ ca_xfer_stride(parent, pstarts, pcounts, pstrides, d + doff + i * dstride[inner], dir);
259
+ i += seg;
260
+ }
261
+ k = inner - 1;
262
+ while (k >= 0) { if (++o[k] < counts[k]) break; o[k] = 0; k--; }
263
+ if (k < 0) break;
264
+ }
265
+ }
266
+
267
+ /* ------------------------------------------------------------------- */
268
+ /* attach / sync / detach via per-tile region helpers */
269
+ /* ------------------------------------------------------------------- */
270
+
271
+ static void
272
+ ca_tile_compute_strides (CATile *ca,
273
+ ca_size_t *parent_strides,
274
+ ca_size_t *output_strides)
275
+ {
276
+ ca_size_t s;
277
+ int8_t k;
278
+ s = ca->bytes;
279
+ for ( k = ca->ndim - 1; k >= 0; k-- ) {
280
+ parent_strides[k] = s;
281
+ s *= ca->parent->dim[k];
282
+ }
283
+ s = ca->bytes;
284
+ for ( k = ca->ndim - 1; k >= 0; k-- ) {
285
+ output_strides[k] = s;
286
+ s *= ca->dim[k];
287
+ }
288
+ }
289
+
290
+ /* Iterate tiles row-major over reps[] and invoke a per-tile callback.
291
+ tile_idx[k] is the tile coordinate in [0, reps[k]). The callback
292
+ computes per-tile output_offset[k] = tile_idx[k] * parent->dim[k]
293
+ and calls ca_composite_region_gather / _scatter. */
294
+ static void
295
+ ca_tile_attach_into (CATile *ca, char *out_ptr)
296
+ {
297
+ ca_size_t parent_strides[CA_RANK_MAX];
298
+ ca_size_t output_strides[CA_RANK_MAX];
299
+ ca_size_t parent_start[CA_RANK_MAX];
300
+ ca_size_t output_offset[CA_RANK_MAX];
301
+ ca_size_t tile_idx[CA_RANK_MAX];
302
+ ca_size_t total_tiles;
303
+ int8_t ndim = ca->ndim;
304
+ int8_t k;
305
+ ca_size_t t;
306
+
307
+ ca_tile_compute_strides(ca, parent_strides, output_strides);
308
+
309
+ for ( k = 0; k < ndim; k++ ) {
310
+ parent_start[k] = 0; /* always full-parent gather */
311
+ tile_idx[k] = 0;
312
+ output_offset[k] = 0;
313
+ }
314
+
315
+ total_tiles = 1;
316
+ for ( k = 0; k < ndim; k++ ) total_tiles *= ca->reps[k];
317
+
318
+ for ( t = 0; t < total_tiles; t++ ) {
319
+ ca_composite_region_gather(ca->parent->ptr, parent_strides,
320
+ parent_start,
321
+ out_ptr, output_strides, output_offset,
322
+ ca->parent->dim, ndim, ca->bytes);
323
+
324
+ /* Advance tile_idx row-major; output_offset[k] = tile_idx[k] * parent->dim[k]. */
325
+ for ( k = ndim - 1; k >= 0; k-- ) {
326
+ tile_idx[k]++;
327
+ if ( tile_idx[k] < ca->reps[k] ) {
328
+ output_offset[k] += ca->parent->dim[k];
329
+ break;
330
+ }
331
+ tile_idx[k] = 0;
332
+ output_offset[k] = 0;
333
+ }
334
+ }
335
+ }
336
+
337
+ /* Reverse: scatter all tiles back to parent. All tiles alias the same
338
+ parent block, so writes overlap; last-tile-scattered wins for any
339
+ given parent cell. */
340
+ static void
341
+ ca_tile_sync_from (CATile *ca, char *in_ptr)
342
+ {
343
+ ca_size_t parent_strides[CA_RANK_MAX];
344
+ ca_size_t input_strides[CA_RANK_MAX];
345
+ ca_size_t parent_start[CA_RANK_MAX];
346
+ ca_size_t input_offset[CA_RANK_MAX];
347
+ ca_size_t tile_idx[CA_RANK_MAX];
348
+ ca_size_t total_tiles;
349
+ int8_t ndim = ca->ndim;
350
+ int8_t k;
351
+ ca_size_t t;
352
+
353
+ ca_tile_compute_strides(ca, parent_strides, input_strides);
354
+
355
+ for ( k = 0; k < ndim; k++ ) {
356
+ parent_start[k] = 0;
357
+ tile_idx[k] = 0;
358
+ input_offset[k] = 0;
359
+ }
360
+
361
+ total_tiles = 1;
362
+ for ( k = 0; k < ndim; k++ ) total_tiles *= ca->reps[k];
363
+
364
+ for ( t = 0; t < total_tiles; t++ ) {
365
+ ca_composite_region_scatter(ca->parent->ptr, parent_strides,
366
+ parent_start,
367
+ in_ptr, input_strides, input_offset,
368
+ ca->parent->dim, ndim, ca->bytes);
369
+
370
+ for ( k = ndim - 1; k >= 0; k-- ) {
371
+ tile_idx[k]++;
372
+ if ( tile_idx[k] < ca->reps[k] ) {
373
+ input_offset[k] += ca->parent->dim[k];
374
+ break;
375
+ }
376
+ tile_idx[k] = 0;
377
+ input_offset[k] = 0;
378
+ }
379
+ }
380
+ }
381
+
382
+ static void
383
+ ca_tile_func_allocate (void *ap)
384
+ {
385
+ CATile *ca = (CATile *) ap;
386
+ ca_attach(ca->parent);
387
+ ca->ptr = xmalloc(ca_length(ca));
388
+ }
389
+
390
+ static void
391
+ ca_tile_func_attach (void *ap)
392
+ {
393
+ CATile *ca = (CATile *) ap;
394
+ ca_attach(ca->parent);
395
+ ca->ptr = xmalloc(ca_length(ca));
396
+ ca_tile_attach_into(ca, ca->ptr);
397
+ }
398
+
399
+ static void
400
+ ca_tile_func_sync (void *ap)
401
+ {
402
+ CATile *ca = (CATile *) ap;
403
+ ca_tile_sync_from(ca, ca->ptr);
404
+ ca_sync(ca->parent);
405
+ }
406
+
407
+ static void
408
+ ca_tile_func_detach (void *ap)
409
+ {
410
+ CATile *ca = (CATile *) ap;
411
+ xfree(ca->ptr);
412
+ ca->ptr = NULL;
413
+ ca_detach(ca->parent);
414
+ }
415
+
416
+ /* xfer_all: fast path when the parent has a live ptr — reuse
417
+ * attach_into / sync_from directly, no operand attach. Cold parent
418
+ * falls back to a 2-pass gather-then-run over a scratch buffer. */
419
+ static void
420
+ ca_tile_func_xfer_all (void *ap, void *data, int dir)
421
+ {
422
+ CATile *ca = (CATile *) ap;
423
+ if ( ca->parent->ptr ) {
424
+ if ( dir == CA_XFER_GET ) ca_tile_attach_into(ca, (char *) data);
425
+ else ca_tile_sync_from(ca, (char *) data);
426
+ return;
427
+ }
428
+ /* Cold parent: gather into a scratch, alias parent->ptr to it for
429
+ the duration of the tile walk, then scatter back on PUT. */
430
+ {
431
+ volatile VALUE holder;
432
+ CArray *parent = ca->parent;
433
+ ca_size_t plen = parent->elements * parent->bytes;
434
+ char *parent_scratch = ALLOCV_N(char, holder, plen);
435
+ char *parent_ptr_saved = parent->ptr;
436
+ ca_xfer_all(parent, parent_scratch, CA_XFER_GET);
437
+ parent->ptr = parent_scratch;
438
+ if ( dir == CA_XFER_GET ) ca_tile_attach_into(ca, (char *) data);
439
+ else ca_tile_sync_from(ca, (char *) data);
440
+ if ( dir == CA_XFER_PUT ) {
441
+ ca_xfer_all(parent, parent_scratch, CA_XFER_PUT);
442
+ }
443
+ parent->ptr = parent_ptr_saved;
444
+ ALLOCV_END(holder);
445
+ }
446
+ }
447
+
448
+ /* fill_data: broadcast scalar to all view cells = write scalar to parent
449
+ once (= the value lands in every tile alias since they all share). */
450
+ static void
451
+ ca_tile_func_fill_data (void *ap, void *ptr)
452
+ {
453
+ CATile *ca = (CATile *) ap;
454
+ ca_fill(ca->parent, ptr);
455
+ }
456
+
457
+ static void
458
+ ca_tile_func_create_mask (void *ap)
459
+ {
460
+ CATile *ca = (CATile *) ap;
461
+ ca_update_mask(ca->parent);
462
+ if ( ! ca->parent->mask ) {
463
+ ca_create_mask(ca->parent);
464
+ }
465
+ ca->mask = (CArray *) ca_tile_new(ca->parent->mask, ca->reps);
466
+ }
467
+
468
+ ca_operation_function_t ca_tile_func = {
469
+ -1, /* CA_OBJ_TILE */
470
+ CA_VIEW_ARRAY,
471
+ free_ca_tile,
472
+ ca_tile_func_clone,
473
+ ca_tile_func_allocate,
474
+ ca_tile_func_attach,
475
+ ca_tile_func_sync,
476
+ ca_tile_func_detach,
477
+ ca_tile_func_fill_data,
478
+ ca_tile_func_create_mask,
479
+ ca_tile_func_xfer_index,
480
+ ca_tile_func_xfer_addrs,
481
+ NULL, /* fold_stride: never-fold (modulo wrap) */
482
+ ca_tile_func_xfer_stride,
483
+ ca_tile_func_xfer_all,
484
+ };
485
+
486
+ /* ------------------------------------------------------------------- */
487
+ /* Ruby surface */
488
+ /* ------------------------------------------------------------------- */
489
+
490
+ VALUE
491
+ rb_ca_tile_new (VALUE cary, ca_size_t *reps)
492
+ {
493
+ volatile VALUE obj;
494
+ CArray *parent;
495
+ CATile *ca;
496
+ rb_check_carray_object(cary);
497
+ TypedData_Get_Struct(cary, CArray, &carray_data_type, parent);
498
+ ca = ca_tile_new(parent, reps);
499
+ obj = ca_wrap_struct(ca);
500
+ rb_ca_set_parent(obj, cary);
501
+ return obj;
502
+ }
503
+
504
+ /* CArray#tile(*reps) — multi-arg primary, Array of Integer accepted.
505
+ argc == ndim required (no implicit dimension prepending).
506
+
507
+ Examples:
508
+ a.tile(3) # 1D, OK
509
+ a.tile([3]) # 1D, OK (Array form)
510
+ a.tile(2, 3) # 2D, OK
511
+ a.tile([2, 3]) # 2D, OK (Array form, single arg)
512
+ a.tile(3) # 2D, raises ArgumentError (argc != ndim) */
513
+ static VALUE
514
+ rb_ca_tile (int argc, VALUE *argv, VALUE self)
515
+ {
516
+ CArray *ca;
517
+ ca_size_t reps[CA_RANK_MAX];
518
+ int8_t i;
519
+
520
+ TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
521
+
522
+ /* Single-arg Array form: a.tile([2, 3]) */
523
+ if ( argc == 1 && rb_obj_is_kind_of(argv[0], rb_cArray) ) {
524
+ VALUE ary = argv[0];
525
+ long len = RARRAY_LEN(ary);
526
+ if ( len != ca->ndim ) {
527
+ rb_raise(rb_eArgError,
528
+ "tile: array length (%ld) does not match ndim (%d)",
529
+ len, ca->ndim);
530
+ }
531
+ for ( i = 0; i < ca->ndim; i++ ) {
532
+ reps[i] = NUM2SIZE(rb_ary_entry(ary, i));
533
+ }
534
+ }
535
+ else {
536
+ /* Multi-arg form: a.tile(2, 3, ...). */
537
+ if ( argc != ca->ndim ) {
538
+ rb_raise(rb_eArgError,
539
+ "tile: expected %d args (= ndim), got %d",
540
+ ca->ndim, argc);
541
+ }
542
+ for ( i = 0; i < ca->ndim; i++ ) {
543
+ reps[i] = NUM2SIZE(argv[i]);
544
+ }
545
+ }
546
+
547
+ {
548
+ VALUE obj = rb_ca_tile_new(self, reps);
549
+ CA_FACE_LIFT_IF_FACE(obj, self, ca);
550
+ return obj;
551
+ }
552
+ }
553
+
554
+ static VALUE
555
+ rb_ca_tile_s_allocate (VALUE klass)
556
+ {
557
+ CATile *ca;
558
+ return TypedData_Make_Struct(klass, CATile, &catile_data_type, ca);
559
+ }
560
+
561
+ static VALUE
562
+ rb_ca_tile_initialize_copy (VALUE self, VALUE other)
563
+ {
564
+ CATile *ca, *cs;
565
+ TypedData_Get_Struct(self, CATile, &catile_data_type, ca);
566
+ TypedData_Get_Struct(other, CATile, &catile_data_type, cs);
567
+ ca_tile_setup(ca, cs->parent, cs->reps);
568
+ return self;
569
+ }
570
+
571
+ /* Debug-only accessor returning the tile descriptor as a Hash.
572
+ Naming: leading underscore signals internal use. */
573
+ static VALUE
574
+ rb_ca_tile_descriptor (VALUE self)
575
+ {
576
+ CATile *ca = (CATile *) DATA_PTR(self);
577
+ VALUE hash, reps_ary;
578
+ int8_t k;
579
+ ca_size_t total = 1;
580
+
581
+ reps_ary = rb_ary_new_capa(ca->ndim);
582
+ for ( k = 0; k < ca->ndim; k++ ) {
583
+ rb_ary_push(reps_ary, SIZE2NUM(ca->reps[k]));
584
+ total *= ca->reps[k];
585
+ }
586
+ hash = rb_hash_new();
587
+ rb_hash_aset(hash, ID2SYM(rb_intern("reps")), reps_ary);
588
+ rb_hash_aset(hash, ID2SYM(rb_intern("total_tiles")), SIZE2NUM(total));
589
+ rb_hash_aset(hash, ID2SYM(rb_intern("ndim")), INT2NUM(ca->ndim));
590
+ return hash;
591
+ }
592
+
593
+ void
594
+ Init_ca_obj_tile (void)
595
+ {
596
+ rb_cCATile = rb_define_class("CATile", rb_cCAView);
597
+ rb_cCATileMask = rb_define_class("CATileMask", rb_cCATile);
598
+
599
+ CA_OBJ_TILE = ca_install_obj_type(rb_cCATile,
600
+ &catile_data_type,
601
+ rb_cCATileMask,
602
+ &catile_mask_data_type, &ca_tile_func, sizeof(ca_tile_func));
603
+ rb_define_const(rb_cObject, "CA_OBJ_TILE", INT2NUM(CA_OBJ_TILE));
604
+
605
+ rb_define_method(rb_cCArray, "tile", rb_ca_tile, -1);
606
+
607
+ rb_define_alloc_func(rb_cCATile, rb_ca_tile_s_allocate);
608
+ rb_define_method(rb_cCATile, "initialize_copy",
609
+ rb_ca_tile_initialize_copy, 1);
610
+
611
+ /* Debug-only descriptor accessor. */
612
+ rb_define_method(rb_cCATile, "_tile_descriptor",
613
+ rb_ca_tile_descriptor, 0);
614
+ }