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
@@ -1,88 +1,151 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- ca_obj_unbound_repeat.c
4
-
5
- This file is part of Ruby/CArray extension library.
6
-
7
- Copyright (C) 2005-2020 Hiroki Motoyoshi
3
+ CAUnboundRepeat — a CAStride subclass representing the "shape
4
+ pending" broadcast view. Each `:*` axis becomes a size-1 stride-0
5
+ entry in the CAStride prefix; each sized axis inherits the parent's
6
+ contiguous byte stride. The original spec is preserved in the
7
+ rep_dim[] tail (0 = `*`, n = sized) so #spec / #bind / #bind_with /
8
+ #shave observe the user's original layout.
8
9
 
9
10
  ---------------------------------------------------------------------------- */
10
11
 
11
12
  #include "carray.h"
13
+ #include "carray_internal.h" /* per-obj_type view constructors */
14
+ #include "ca_obj_face.h" /* CA_FACE_LIFT_IF_FACE */
15
+
16
+ extern ca_operation_function_t ca_stride_func;
17
+
18
+ VALUE rb_cCAUnboundRepeat;
19
+ VALUE rb_cCAUnboundRepeatMask;
20
+
21
+ /* Filled in by Init_ca_obj_unbound_repeat as `ca_stride_func` plus
22
+ custom free / clone / create_mask. */
23
+ ca_operation_function_t ca_ubrep_func;
24
+
25
+ static size_t
26
+ ca_ubrep_dsize (const void *ap)
27
+ {
28
+ const CAUnboundRepeat *ca = (const CAUnboundRepeat *) ap;
29
+ /* dim + strides + rep_dim, each ndim cells (legacy ALLOC_N x3 or one
30
+ framework-managed _pool buffer; same byte total). */
31
+ return sizeof(CAUnboundRepeat) + 3 * ca->ndim * sizeof(ca_size_t);
32
+ }
33
+
34
+ /* Pool framework hooks (CABlock pattern: CAStride base + one extra
35
+ tail). The view ndim equals rep_ndim, so dim, strides and rep_dim
36
+ are all ndim-sized. CAREFUL: dim/strides must stay at CAStride
37
+ base offsets (0, n) so ca_stride_setup's pool branch finds them;
38
+ the rep_dim tail follows at 2n. */
39
+ static size_t
40
+ ca_ubrep_pool_bytes (int8_t ndim)
41
+ {
42
+ ca_size_t n = (ndim > 0) ? ndim : 1;
43
+ return 3 * (size_t) n * sizeof(ca_size_t);
44
+ }
45
+
46
+ static void
47
+ ca_ubrep_pool_init (void *ap, int8_t ndim)
48
+ {
49
+ CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
50
+ ca_size_t n = (ndim > 0) ? ndim : 1;
51
+ ca_size_t *base = (ca_size_t *) ca->_pool;
52
+ ca->dim = base + 0 * n; /* CAStride prefix */
53
+ ca->strides = base + 1 * n; /* CAStride prefix */
54
+ ca->rep_dim = base + 2 * n; /* CAUnboundRepeat tail */
55
+ }
12
56
 
13
57
  const rb_data_type_t caunboundrepeat_data_type = {
14
- .parent = &cavirtual_data_type,
58
+ .parent = &castride_data_type,
15
59
  .wrap_struct_name = "CAUnboundRepeat",
16
60
  .function = {
17
61
  .dmark = ca_mark,
18
62
  .dfree = ca_free,
19
- .dsize = NULL,
63
+ .dsize = ca_ubrep_dsize,
20
64
  .dcompact = NULL
21
65
  },
22
66
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
23
67
  };
24
68
 
25
69
  const rb_data_type_t caunboundrepeat_mask_data_type = {
26
- .parent = &cavirtual_data_type,
70
+ .parent = &caunboundrepeat_data_type,
27
71
  .wrap_struct_name = "CAUnboundRepeatMask",
28
72
  .function = {
29
73
  .dmark = NULL,
30
74
  .dfree = ca_free_nop,
31
- .dsize = NULL,
75
+ .dsize = ca_ubrep_dsize,
32
76
  .dcompact = NULL
33
77
  },
34
78
  .flags = RUBY_TYPED_FREE_IMMEDIATELY
35
79
  };
36
80
 
37
- VALUE rb_cCAUnboundRepeat;
38
- VALUE rb_cCAUnboundRepeatMask;
39
-
40
- /* yard:
41
- class CAUnboundRepeat < CArray
42
- end
43
- */
44
-
45
81
  int
46
82
  ca_ubrep_setup (CAUnboundRepeat *ca, CArray *parent,
47
83
  int32_t rep_ndim, ca_size_t *rep_dim)
48
84
  {
49
- int8_t data_type;
50
- ca_size_t bytes, elements;
51
- int8_t i;
52
-
53
- /* check arguments */
85
+ ca_size_t parent_byte_stride[CA_RANK_MAX];
86
+ ca_size_t newdim[CA_RANK_MAX];
87
+ ca_size_t strides[CA_RANK_MAX];
88
+ int8_t data_ndim = 0;
89
+ int8_t i, j;
54
90
 
55
91
  CA_CHECK_RANK(rep_ndim);
56
92
 
57
- data_type = parent->data_type;
58
- bytes = parent->bytes;
59
- elements = parent->elements;
60
-
61
- ca->obj_type = CA_OBJ_UNBOUND_REPEAT;
62
- ca->data_type = data_type;
63
- ca->flags = 0;
64
- ca->ndim = rep_ndim;
65
- ca->bytes = bytes;
66
- ca->elements = elements;
67
- ca->ptr = NULL;
68
- ca->mask = NULL;
69
- ca->dim = ALLOC_N(ca_size_t, rep_ndim);
70
-
71
- ca->parent = parent;
72
- ca->attach = 0;
73
- ca->nosync = 0;
93
+ /* parent_byte_stride[k] = bytes * Π_{i>k} parent->dim[i]. Only the
94
+ [0, parent->ndim) entries are touched; the array is private to this
95
+ setup call. */
96
+ {
97
+ ca_size_t s = parent->bytes;
98
+ for (i = parent->ndim - 1; i >= 0; i--) {
99
+ parent_byte_stride[i] = s;
100
+ s *= parent->dim[i];
101
+ }
102
+ }
74
103
 
75
- ca->rep_ndim = rep_ndim;
76
- ca->rep_dim = ALLOC_N(ca_size_t, rep_ndim);
104
+ j = 0;
105
+ for (i = 0; i < rep_ndim; i++) {
106
+ if (rep_dim[i] == 0) {
107
+ /* `*` (unbound) axis: size 1 placeholder, stride 0. */
108
+ newdim[i] = 1;
109
+ strides[i] = 0;
110
+ }
111
+ else {
112
+ if (j >= parent->ndim) {
113
+ rb_raise(rb_eArgError,
114
+ "too many sized axes for parent of ndim %d",
115
+ (int) parent->ndim);
116
+ }
117
+ if (rep_dim[i] != parent->dim[j]) {
118
+ rb_raise(rb_eArgError,
119
+ "mismatch in entity dim at axis %d (%lld vs parent %lld)",
120
+ (int) i,
121
+ (long long) rep_dim[i], (long long) parent->dim[j]);
122
+ }
123
+ newdim[i] = parent->dim[j];
124
+ strides[i] = parent_byte_stride[j];
125
+ data_ndim += 1;
126
+ j++;
127
+ }
128
+ }
129
+ if (data_ndim != parent->ndim) {
130
+ rb_raise(rb_eArgError,
131
+ "mismatch in number of sized axes (%d for parent ndim %d)",
132
+ (int) data_ndim, (int) parent->ndim);
133
+ }
77
134
 
78
- for (i=0; i<rep_ndim; i++) {
135
+ /* CAREFUL: initialise the rep_dim tail before ca_stride_setup.
136
+ ca_stride_setup may call ca_create_mask when the parent has a
137
+ mask, which dispatches into ca_ubrep_func_create_mask — and that
138
+ reads ca->rep_dim. */
139
+ if ( ! ca->_pool ) {
140
+ ca->rep_dim = ALLOC_N(ca_size_t, rep_ndim > 0 ? rep_ndim : 1);
141
+ }
142
+ for (i = 0; i < rep_ndim; i++) {
79
143
  ca->rep_dim[i] = rep_dim[i];
80
- ca->dim[i] = ( rep_dim[i] ) ? rep_dim[i] : 1;
81
144
  }
82
145
 
83
- if ( ca_has_mask(parent) ) {
84
- ca_create_mask(ca);
85
- }
146
+ ca_stride_setup((CAStride *) ca, CA_OBJ_UNBOUND_REPEAT, parent,
147
+ parent->data_type, parent->bytes,
148
+ (int8_t) rep_ndim, newdim, strides, 0);
86
149
 
87
150
  return 0;
88
151
  }
@@ -90,7 +153,8 @@ ca_ubrep_setup (CAUnboundRepeat *ca, CArray *parent,
90
153
  CAUnboundRepeat *
91
154
  ca_ubrep_new (CArray *parent, int32_t rep_ndim, ca_size_t *rep_dim)
92
155
  {
93
- CAUnboundRepeat *ca = ALLOC(CAUnboundRepeat);
156
+ CAUnboundRepeat *ca =
157
+ (CAUnboundRepeat *) ca_array_alloc(CA_OBJ_UNBOUND_REPEAT, (int8_t) rep_ndim);
94
158
  ca_ubrep_setup(ca, parent, rep_ndim, rep_dim);
95
159
  return ca;
96
160
  }
@@ -99,112 +163,25 @@ static void
99
163
  free_ca_ubrep (void *ap)
100
164
  {
101
165
  CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
102
- if ( ca != NULL ) {
103
- ca_free(ca->mask);
104
- xfree(ca->dim);
166
+ if (ca == NULL) return;
167
+ ca_free(ca->mask);
168
+ if (ca->_pool) {
169
+ /* dim/strides/rep_dim all live in ca->_pool. */
170
+ ca_array_free(ca);
171
+ }
172
+ else {
105
173
  xfree(ca->rep_dim);
174
+ xfree(ca->strides);
175
+ xfree(ca->dim);
106
176
  xfree(ca);
107
177
  }
108
178
  }
109
179
 
110
- /* ------------------------------------------------------------------- */
111
-
112
180
  static void *
113
181
  ca_ubrep_func_clone (void *ap)
114
182
  {
115
183
  CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
116
- return ca_ubrep_new(ca->parent, ca->rep_ndim, ca->rep_dim);
117
- }
118
-
119
- static char *
120
- ca_ubrep_func_ptr_at_addr (void *ap, ca_size_t addr)
121
- {
122
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
123
- return ca_ptr_at_addr(ca->parent, addr);
124
- }
125
-
126
- static void
127
- ca_ubrep_func_fetch_addr (void *ap, ca_size_t addr, void *ptr)
128
- {
129
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
130
- ca_fetch_addr(ca->parent, addr, ptr);
131
- }
132
-
133
- static void
134
- ca_ubrep_func_store_addr (void *ap, ca_size_t addr, void *ptr)
135
- {
136
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
137
- ca_store_addr(ca->parent, addr, ptr);
138
- }
139
-
140
- static void
141
- ca_ubrep_func_allocate (void *ap)
142
- {
143
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
144
- ca_allocate(ca->parent);
145
- ca->ptr = ca->parent->ptr;
146
- }
147
-
148
- static void
149
- ca_ubrep_func_attach (void *ap)
150
- {
151
- void ca_ubrep_attach (CAUnboundRepeat *cb);
152
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
153
- ca_attach(ca->parent);
154
- ca->ptr = ca->parent->ptr;
155
- return;
156
- }
157
-
158
- static void
159
- ca_ubrep_func_sync (void *ap)
160
- {
161
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
162
- ca_sync(ca->parent);
163
- return;
164
- }
165
-
166
- static void
167
- ca_ubrep_func_detach (void *ap)
168
- {
169
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
170
- ca->ptr = NULL;
171
- ca_detach(ca->parent);
172
- return;
173
- }
174
-
175
- static void
176
- ca_ubrep_func_copy_data (void *ap, void *ptr)
177
- {
178
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
179
- if ( ptr != ca->ptr ) {
180
- ca_attach(ca->parent);
181
- memmove(ptr, ca->parent->ptr, ca_length(ca));
182
- ca_detach(ca->parent);
183
- }
184
- }
185
-
186
- static void
187
- ca_ubrep_func_sync_data (void *ap, void *ptr)
188
- {
189
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
190
- if ( ptr != ca->ptr ) {
191
- ca_allocate(ca->parent);
192
- memmove(ptr, ca->parent->ptr, ca_length(ca));
193
- ca_sync(ca->parent);
194
- ca_detach(ca->parent);
195
- }
196
- }
197
-
198
- static void
199
- ca_ubrep_func_fill_data (void *ap, void *ptr)
200
- {
201
- CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
202
- if ( ptr != ca->ptr ) {
203
- ca_allocate(ca->parent);
204
- ca_func[CA_OBJ_ARRAY].fill_data(ca->parent, ptr);
205
- ca_sync(ca->parent);
206
- ca_detach(ca->parent);
207
- }
184
+ return ca_ubrep_new(ca->parent, ca->ndim, ca->rep_dim);
208
185
  }
209
186
 
210
187
  static void
@@ -212,36 +189,31 @@ ca_ubrep_func_create_mask (void *ap)
212
189
  {
213
190
  CAUnboundRepeat *ca = (CAUnboundRepeat *) ap;
214
191
  ca_update_mask(ca->parent);
215
- if ( ! ca->parent->mask ) {
192
+ if (!ca->parent->mask) {
216
193
  ca_create_mask(ca->parent);
217
194
  }
218
195
  ca->mask =
219
- (CArray *) ca_ubrep_new(ca->parent->mask, ca->rep_ndim, ca->rep_dim);
196
+ (CArray *) ca_ubrep_new(ca->parent->mask, ca->ndim, ca->rep_dim);
220
197
  }
221
198
 
222
- ca_operation_function_t ca_ubrep_func = {
223
- -1, /* CA_OBJ_UNBOUND_REPEAT */
224
- CA_VIRTUAL_ARRAY,
225
- free_ca_ubrep,
226
- ca_ubrep_func_clone,
227
- ca_ubrep_func_ptr_at_addr,
228
- NULL,
229
- ca_ubrep_func_fetch_addr,
230
- NULL,
231
- ca_ubrep_func_store_addr,
232
- NULL,
233
- ca_ubrep_func_allocate,
234
- ca_ubrep_func_attach,
235
- ca_ubrep_func_sync,
236
- ca_ubrep_func_detach,
237
- ca_ubrep_func_copy_data,
238
- ca_ubrep_func_sync_data,
239
- ca_ubrep_func_fill_data,
240
- ca_ubrep_func_create_mask,
241
- };
242
-
243
199
  /* ------------------------------------------------------------------- */
244
200
 
201
+ /* rb_ca_rewrap_unbound_repeat(src, out) — when src is an unresolved
202
+ * CAUnboundRepeat, re-wrap out so the result carries the same `*`
203
+ * markers; otherwise return out unchanged. Called from the unary /
204
+ * binary operator and math paths so downstream `.bind` / `.bind_with`
205
+ * on the operator result still see the `*` axes. */
206
+ VALUE
207
+ rb_ca_rewrap_unbound_repeat (VALUE src, VALUE out)
208
+ {
209
+ CArray *ca;
210
+ CAUnboundRepeat *cx;
211
+ TypedData_Get_Struct(src, CArray, &carray_data_type, ca);
212
+ if (ca->obj_type != CA_OBJ_UNBOUND_REPEAT) return out;
213
+ cx = (CAUnboundRepeat *) ca;
214
+ return rb_ca_ubrep_new(rb_ca_ubrep_shave(src, out), cx->ndim, cx->rep_dim);
215
+ }
216
+
245
217
  VALUE
246
218
  rb_ca_ubrep_shave (VALUE self, VALUE other)
247
219
  {
@@ -256,13 +228,13 @@ rb_ca_ubrep_shave (VALUE self, VALUE other)
256
228
  TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
257
229
  TypedData_Get_Struct(other, CArray, &carray_data_type, co);
258
230
 
259
- if ( ca->elements != co->elements ) {
231
+ if (ca->elements != co->elements) {
260
232
  rb_raise(rb_eRuntimeError, "mismatch in # of elements");
261
233
  }
262
234
 
263
235
  ndim = 0;
264
- for (i=0; i<ca->ndim; i++) {
265
- if ( ca->rep_dim[i] ) {
236
+ for (i = 0; i < ca->ndim; i++) {
237
+ if (ca->rep_dim[i]) {
266
238
  dim[ndim] = ca->rep_dim[i];
267
239
  ndim += 1;
268
240
  }
@@ -271,7 +243,6 @@ rb_ca_ubrep_shave (VALUE self, VALUE other)
271
243
  return rb_ca_refer_new(other, co->data_type, ndim, dim, co->bytes, 0);
272
244
  }
273
245
 
274
-
275
246
  VALUE
276
247
  rb_ca_ubrep_new (VALUE cary, int32_t rep_ndim, ca_size_t *rep_dim)
277
248
  {
@@ -283,7 +254,6 @@ rb_ca_ubrep_new (VALUE cary, int32_t rep_ndim, ca_size_t *rep_dim)
283
254
  ca = ca_ubrep_new(parent, rep_ndim, rep_dim);
284
255
  obj = ca_wrap_struct(ca);
285
256
  rb_ca_set_parent(obj, cary);
286
- rb_ca_data_type_inherit(obj, cary);
287
257
  return obj;
288
258
  }
289
259
 
@@ -292,7 +262,6 @@ rb_ca_unbound_repeat (int argc, VALUE *argv, VALUE self)
292
262
  {
293
263
  CArray *ca;
294
264
  int8_t ndim;
295
- ca_size_t dim[CA_RANK_MAX];
296
265
  int32_t rep_ndim;
297
266
  ca_size_t rep_dim[CA_RANK_MAX];
298
267
  ca_size_t elements, count, i;
@@ -304,9 +273,9 @@ rb_ca_unbound_repeat (int argc, VALUE *argv, VALUE self)
304
273
  count = 0;
305
274
  ndim = 0;
306
275
  elements = 1;
307
- for (i=0; i<rep_ndim; i++) {
308
- if ( TYPE(argv[i]) == T_SYMBOL ) {
309
- if ( argv[i] == ID2SYM(rb_intern("*")) ) {
276
+ for (i = 0; i < rep_ndim; i++) {
277
+ if (TYPE(argv[i]) == T_SYMBOL) {
278
+ if (argv[i] == ID2SYM(rb_intern("*"))) {
310
279
  rep_dim[i] = 0;
311
280
  }
312
281
  else {
@@ -314,32 +283,38 @@ rb_ca_unbound_repeat (int argc, VALUE *argv, VALUE self)
314
283
  }
315
284
  }
316
285
  else {
317
- if ( ! NIL_P(argv[i]) ) {
286
+ if (!NIL_P(argv[i])) {
318
287
  rb_raise(rb_eArgError, "invalid argument");
319
288
  }
320
289
  rep_dim[i] = ca->dim[count];
321
- dim[ndim] = ca->dim[count];
322
290
  elements *= ca->dim[count];
323
291
  count++; ndim++;
324
292
  }
325
293
  }
326
294
 
327
- if ( elements != ca->elements ) {
328
- rb_raise(rb_eArgError, "mismatch in entity elements (%lli for %lli)", elements, ca->elements);
295
+ if (elements != ca->elements) {
296
+ rb_raise(rb_eArgError, "mismatch in entity elements (%lli for %lli)",
297
+ (long long) elements, (long long) ca->elements);
329
298
  }
330
299
 
331
- if ( ndim != ca->ndim ) {
332
- rb_raise(rb_eArgError, "invalid number of nil's (%i for %i)", ndim, ca->ndim);
300
+ if (ndim != ca->ndim) {
301
+ rb_raise(rb_eArgError, "invalid number of nil's (%i for %i)",
302
+ (int) ndim, (int) ca->ndim);
333
303
  }
334
304
 
335
- return rb_ca_ubrep_new(self, rep_ndim, rep_dim);
305
+ {
306
+ VALUE obj = rb_ca_ubrep_new(self, rep_ndim, rep_dim);
307
+ CA_FACE_LIFT_IF_FACE(obj, self, ca);
308
+ return obj;
309
+ }
336
310
  }
337
311
 
338
312
  static VALUE
339
313
  rb_ca_ubrep_s_allocate (VALUE klass)
340
314
  {
341
315
  CAUnboundRepeat *ca;
342
- return TypedData_Make_Struct(klass, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
316
+ return TypedData_Make_Struct(klass, CAUnboundRepeat,
317
+ &caunboundrepeat_data_type, ca);
343
318
  }
344
319
 
345
320
  static VALUE
@@ -350,32 +325,14 @@ rb_ca_ubrep_initialize_copy (VALUE self, VALUE other)
350
325
  TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
351
326
  TypedData_Get_Struct(other, CAUnboundRepeat, &caunboundrepeat_data_type, cs);
352
327
 
353
- ca_ubrep_setup(ca, cs->parent, cs->rep_ndim, cs->rep_dim);
328
+ if ( ca_func[CA_OBJ_UNBOUND_REPEAT].pool_init ) {
329
+ ca_array_pool_alloc(ca, CA_OBJ_UNBOUND_REPEAT, cs->ndim);
330
+ }
331
+ ca_ubrep_setup(ca, cs->parent, cs->ndim, cs->rep_dim);
354
332
 
355
333
  return self;
356
334
  }
357
335
 
358
- /*
359
- static CARepeat *
360
- ca_ubrep_bind (CAUnboundRepeat *ca, int32_t new_ndim, ca_size_t *new_dim)
361
- {
362
- ca_size_t rep_spec[CA_RANK_MAX];
363
- int i;
364
- if ( ca->rep_ndim != new_ndim ) {
365
- rb_raise(rb_eArgError, "invalid new_ndim");
366
- }
367
- for (i=0; i<new_ndim; i++) {
368
- if ( ca->rep_dim[i] == 0 ) {
369
- rep_spec[i] = new_dim[i];
370
- }
371
- else {
372
- rep_spec[i] = 0;
373
- }
374
- }
375
- return ca_repeat_new((CArray*)ca, new_ndim, rep_spec);
376
- }
377
- */
378
-
379
336
  VALUE
380
337
  ca_ubrep_bind2 (VALUE self, int32_t new_ndim, ca_size_t *new_dim)
381
338
  {
@@ -389,16 +346,16 @@ ca_ubrep_bind2 (VALUE self, int32_t new_ndim, ca_size_t *new_dim)
389
346
 
390
347
  TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
391
348
 
392
- if ( ca->rep_ndim != new_ndim ) {
349
+ if (ca->ndim != new_ndim) {
393
350
  rb_raise(rb_eArgError, "invalid new_ndim (%i <-> %i)",
394
- ca->rep_ndim, new_ndim);
351
+ (int) ca->ndim, (int) new_ndim);
395
352
  }
396
353
 
397
354
  srp_ndim = 0;
398
355
  ndim_real = 0;
399
- for (i=0; i<new_ndim; i++) {
400
- if ( ca->rep_dim[i] == 0 ) {
401
- if ( new_dim[i] == 0 ) {
356
+ for (i = 0; i < new_ndim; i++) {
357
+ if (ca->rep_dim[i] == 0) {
358
+ if (new_dim[i] == 0) {
402
359
  uprep = 1;
403
360
  }
404
361
  else {
@@ -414,10 +371,10 @@ ca_ubrep_bind2 (VALUE self, int32_t new_ndim, ca_size_t *new_dim)
414
371
  upr_spec[i] = ca->rep_dim[i];
415
372
  }
416
373
  }
417
-
418
- if ( uprep ) {
374
+
375
+ if (uprep) {
419
376
  volatile VALUE rep;
420
- if ( srp_ndim >= ndim_real ) {
377
+ if (srp_ndim >= ndim_real) {
421
378
  rep = rb_ca_repeat_new(rb_ca_parent(self), srp_ndim, srp_spec);
422
379
  }
423
380
  else {
@@ -430,26 +387,24 @@ ca_ubrep_bind2 (VALUE self, int32_t new_ndim, ca_size_t *new_dim)
430
387
  }
431
388
  }
432
389
 
433
- /* @overload bind_with (other)
434
-
435
- */
436
-
390
+ /* CAUnboundRepeat#bind_with(other) — bind `*` axes to shape borrowed
391
+ * from `other` (CArray, another CAUnboundRepeat, or a scalar). */
437
392
  VALUE
438
393
  ca_ubrep_bind_with (VALUE self, VALUE other)
439
394
  {
440
- CAUnboundRepeat *ca, *cup;
395
+ CAUnboundRepeat *cup;
441
396
  CArray *co;
442
397
 
443
398
  rb_check_carray_object(other);
444
399
 
445
- TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
446
400
  TypedData_Get_Struct(other, CArray, &carray_data_type, co);
447
401
 
448
- if ( co->obj_type == CA_OBJ_UNBOUND_REPEAT ) {
449
- TypedData_Get_Struct(other, CAUnboundRepeat, &caunboundrepeat_data_type, cup);
450
- return ca_ubrep_bind2(self, cup->rep_ndim, cup->rep_dim);
402
+ if (co->obj_type == CA_OBJ_UNBOUND_REPEAT) {
403
+ TypedData_Get_Struct(other, CAUnboundRepeat,
404
+ &caunboundrepeat_data_type, cup);
405
+ return ca_ubrep_bind2(self, cup->ndim, cup->rep_dim);
451
406
  }
452
- else if ( ca_is_scalar(co) ) {
407
+ else if (ca_is_scalar(co)) {
453
408
  return self;
454
409
  }
455
410
  else {
@@ -457,10 +412,8 @@ ca_ubrep_bind_with (VALUE self, VALUE other)
457
412
  }
458
413
  }
459
414
 
460
- /* @overload bind (*index)
461
-
462
- */
463
-
415
+ /* CAUnboundRepeat#bind(*sizes) (alias broadcast_to) — bind each `*`
416
+ * axis to an explicit size and return the resulting CARepeat view. */
464
417
  static VALUE
465
418
  rb_ca_ubrep_bind (int argc, VALUE *argv, VALUE self)
466
419
  {
@@ -470,12 +423,12 @@ rb_ca_ubrep_bind (int argc, VALUE *argv, VALUE self)
470
423
 
471
424
  TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
472
425
 
473
- if ( ca->rep_ndim != argc ) {
426
+ if (ca->ndim != argc) {
474
427
  rb_raise(rb_eArgError, "invalid new_ndim");
475
428
  }
476
-
477
- for (i=0; i<argc; i++) {
478
- if ( ca->rep_dim[i] == 0 ) {
429
+
430
+ for (i = 0; i < argc; i++) {
431
+ if (ca->rep_dim[i] == 0) {
479
432
  rep_spec[i] = NUM2SIZE(argv[i]);
480
433
  }
481
434
  else {
@@ -495,9 +448,9 @@ rb_ca_ubrep_spec (VALUE self)
495
448
 
496
449
  TypedData_Get_Struct(self, CAUnboundRepeat, &caunboundrepeat_data_type, ca);
497
450
 
498
- spec = rb_ary_new2(ca->rep_ndim);
499
- for (i=0; i<ca->rep_ndim; i++) {
500
- if ( ca->rep_dim[i] ) {
451
+ spec = rb_ary_new2(ca->ndim);
452
+ for (i = 0; i < ca->ndim; i++) {
453
+ if (ca->rep_dim[i]) {
501
454
  rb_ary_store(spec, i, SIZE2NUM(ca->rep_dim[i]));
502
455
  }
503
456
  else {
@@ -509,11 +462,26 @@ rb_ca_ubrep_spec (VALUE self)
509
462
  }
510
463
 
511
464
  void
512
- Init_ca_obj_unbound_repeat ()
465
+ Init_ca_obj_unbound_repeat (void)
513
466
  {
514
- /* rb_cCAUnboundRepeat, CA_OBJ_UNBOUND_REPEAT are defined in rb_carray.c */
515
-
516
- rb_define_const(rb_cObject, "CA_OBJ_UNBOUND_REPEAT", INT2NUM(CA_OBJ_UNBOUND_REPEAT));
467
+ /* rb_cCAUnboundRepeat, CA_OBJ_UNBOUND_REPEAT are defined in
468
+ ruby_carray.c / carray.h. Build the custom op table by copying
469
+ ca_stride_func and overriding only the slots that need to know
470
+ about the rep_dim tail (free + clone + create_mask). */
471
+ ca_ubrep_func = ca_stride_func;
472
+ ca_ubrep_func.free_object = free_ca_ubrep;
473
+ ca_ubrep_func.clone = ca_ubrep_func_clone;
474
+ ca_ubrep_func.create_mask = ca_ubrep_func_create_mask;
475
+ /* CAUnboundRepeat owns 3*ndim cells (dim/strides + rep_dim); override the
476
+ 2*ndim CAStride base pool hooks and the struct_size so ca_array_alloc
477
+ reserves room for the rep_dim tail too. */
478
+ ca_ubrep_func.struct_size = sizeof(CAUnboundRepeat);
479
+ ca_ubrep_func.pool_bytes = ca_ubrep_pool_bytes;
480
+ ca_ubrep_func.pool_init = ca_ubrep_pool_init;
481
+ ca_func[CA_OBJ_UNBOUND_REPEAT] = ca_ubrep_func;
482
+
483
+ rb_define_const(rb_cObject, "CA_OBJ_UNBOUND_REPEAT",
484
+ INT2NUM(CA_OBJ_UNBOUND_REPEAT));
517
485
 
518
486
  rb_define_method(rb_cCArray, "unbound_repeat", rb_ca_unbound_repeat, -1);
519
487
 
@@ -522,8 +490,7 @@ Init_ca_obj_unbound_repeat ()
522
490
  rb_ca_ubrep_initialize_copy, 1);
523
491
 
524
492
  rb_define_method(rb_cCAUnboundRepeat, "bind", rb_ca_ubrep_bind, -1);
493
+ rb_define_alias(rb_cCAUnboundRepeat, "broadcast_to", "bind");
525
494
  rb_define_method(rb_cCAUnboundRepeat, "bind_with", ca_ubrep_bind_with, 1);
526
495
  rb_define_method(rb_cCAUnboundRepeat, "spec", rb_ca_ubrep_spec, 0);
527
-
528
496
  }
529
-