carray 3.0.2 → 3.0.4

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 (247) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +568 -0
  3. data/README.md +6 -6
  4. data/carray.gemspec +1 -1
  5. data/ext/ca_axis_descriptor.h +27 -24
  6. data/ext/ca_axis_dispatch.c +220 -0
  7. data/ext/ca_axis_group.c +201 -123
  8. data/ext/ca_binop_dispatch.c +46 -52
  9. data/ext/ca_binop_dispatch.h +1 -1
  10. data/ext/ca_categorical_iterator.c +249 -183
  11. data/ext/ca_compare.c +7 -12
  12. data/ext/ca_for_buffer.h +21 -68
  13. data/ext/ca_group_iter.c +38 -23
  14. data/ext/ca_kernel_iterator.c +1765 -2076
  15. data/ext/ca_kernel_iterator.h +584 -566
  16. data/ext/ca_monop_dispatch.c +86 -63
  17. data/ext/ca_monop_dispatch.h +5 -0
  18. data/ext/ca_obj_array.c +223 -56
  19. data/ext/ca_obj_bincmp.c +172 -138
  20. data/ext/ca_obj_binop.c +116 -230
  21. data/ext/ca_obj_bitarray.c +40 -26
  22. data/ext/ca_obj_bitfield.c +100 -68
  23. data/ext/ca_obj_block.c +19 -9
  24. data/ext/ca_obj_byte_swap.c +45 -46
  25. data/ext/ca_obj_const_string.c +269 -44
  26. data/ext/ca_obj_face.c +612 -89
  27. data/ext/ca_obj_face.h +111 -47
  28. data/ext/ca_obj_fake.c +36 -79
  29. data/ext/ca_obj_farray.c +7 -3
  30. data/ext/ca_obj_field.c +33 -8
  31. data/ext/ca_obj_fixlen_string.c +23 -24
  32. data/ext/ca_obj_grid.c +541 -210
  33. data/ext/ca_obj_meld.c +331 -111
  34. data/ext/ca_obj_moncmp.c +80 -65
  35. data/ext/ca_obj_monop.c +177 -149
  36. data/ext/ca_obj_object.c +664 -248
  37. data/ext/ca_obj_record.c +63 -23
  38. data/ext/ca_obj_reduce.c +18 -16
  39. data/ext/ca_obj_refer.c +140 -58
  40. data/ext/ca_obj_remap.c +85 -24
  41. data/ext/ca_obj_repeat.c +24 -9
  42. data/ext/ca_obj_roll.c +121 -16
  43. data/ext/ca_obj_select.c +61 -58
  44. data/ext/ca_obj_select_axis.c +73 -107
  45. data/ext/ca_obj_shift.c +32 -102
  46. data/ext/ca_obj_stack.c +372 -122
  47. data/ext/ca_obj_stride.c +348 -140
  48. data/ext/ca_obj_string.c +88 -22
  49. data/ext/ca_obj_tile.c +38 -21
  50. data/ext/ca_obj_time.c +45 -31
  51. data/ext/ca_obj_timedelta.c +43 -29
  52. data/ext/ca_obj_transpose.c +17 -6
  53. data/ext/ca_obj_triop.c +125 -141
  54. data/ext/ca_obj_window.c +330 -44
  55. data/ext/ca_op_ipower.c +24 -11
  56. data/ext/ca_op_powi.h +57 -30
  57. data/ext/ca_pow5_table.h +656 -0
  58. data/ext/ca_sort_kernels.h +70 -0
  59. data/ext/ca_sweep_engine.c +104 -81
  60. data/ext/ca_sweep_engine.h +7 -20
  61. data/ext/ca_triop_dispatch.c +4 -1
  62. data/ext/ca_triop_dispatch.h +5 -2
  63. data/ext/caframe_csv_reader.c +542 -0
  64. data/ext/carray.h +241 -92
  65. data/ext/carray_access.c +608 -276
  66. data/ext/carray_address_basis.c +494 -97
  67. data/ext/carray_attribute.c +129 -4
  68. data/ext/carray_bincount.c +39 -7
  69. data/ext/carray_broadcast.c +56 -19
  70. data/ext/carray_build_flags.h +1 -1
  71. data/ext/carray_call_cfunc.c +108 -28
  72. data/ext/carray_cast.c +1576 -223
  73. data/ext/carray_cast_func.rb +77 -24
  74. data/ext/carray_class.c +4 -3
  75. data/ext/carray_conversion.c +208 -75
  76. data/ext/carray_copy.c +82 -24
  77. data/ext/carray_core.c +646 -162
  78. data/ext/carray_count.c +171 -88
  79. data/ext/carray_element.c +94 -60
  80. data/ext/carray_factorize.c +670 -324
  81. data/ext/carray_generate.c +260 -83
  82. data/ext/carray_histogram.c +209 -106
  83. data/ext/carray_hold.c +14 -16
  84. data/ext/carray_index_classifier.c +422 -243
  85. data/ext/carray_internal.h +692 -3
  86. data/ext/carray_kernels_bincmp.c +7 -0
  87. data/ext/carray_kernels_binop.c +487 -120
  88. data/ext/carray_kernels_init.c +653 -50
  89. data/ext/carray_kernels_moncmp.c +15 -8
  90. data/ext/carray_kernels_monop.c +99 -43
  91. data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
  92. data/ext/carray_kernels_reduce_boolean.c +112 -36
  93. data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
  94. data/ext/carray_kernels_reduce_extreme.c +3032 -2892
  95. data/ext/carray_kernels_reduce_variance.c +439 -500
  96. data/ext/carray_kernels_scan.c +1097 -488
  97. data/ext/carray_kernels_search.c +3787 -2176
  98. data/ext/carray_kernels_sort.c +1200 -920
  99. data/ext/carray_kernels_triop.c +479 -7
  100. data/ext/carray_key_windows.c +216 -0
  101. data/ext/carray_lazy.c +967 -153
  102. data/ext/carray_loop.c +81 -65
  103. data/ext/carray_mask.c +910 -324
  104. data/ext/carray_math_kernel.h +1 -0
  105. data/ext/carray_median_percentile.c +299 -100
  106. data/ext/carray_memory_view.c +872 -758
  107. data/ext/carray_operator.c +1171 -364
  108. data/ext/carray_order.c +505 -133
  109. data/ext/carray_partition.c +112 -65
  110. data/ext/carray_random.c +327 -239
  111. data/ext/carray_round.c +273 -0
  112. data/ext/carray_scatter.c +346 -78
  113. data/ext/carray_segment.c +257 -0
  114. data/ext/carray_slab.c +249 -86
  115. data/ext/carray_sort.c +224 -227
  116. data/ext/carray_sort_kernel.c +8 -1
  117. data/ext/carray_struct.c +118 -39
  118. data/ext/carray_test.c +193 -69
  119. data/ext/carray_time_text.c +1182 -0
  120. data/ext/carray_undef.c +4 -0
  121. data/ext/carray_utils.c +579 -113
  122. data/ext/extconf.rb +27 -2
  123. data/ext/mk_call_cfunc.rb +19 -4
  124. data/ext/mk_pow5_table.rb +35 -0
  125. data/ext/mkkernel.rb +1202 -1014
  126. data/ext/ruby_carray.c +17 -5
  127. data/ext/version.h +4 -4
  128. data/ext/version.rb +4 -2
  129. data/lib/carray/attribute.rb +160 -17
  130. data/lib/carray/autoload_carray.rb +23 -27
  131. data/lib/carray/autoload_method_extension.rb +20 -5
  132. data/lib/carray/axis_group.rb +360 -63
  133. data/lib/carray/basics.rb +162 -28
  134. data/lib/carray/bincount_nd.rb +18 -2
  135. data/lib/carray/block_iterator.rb +231 -58
  136. data/lib/carray/boolean_reduce.rb +34 -42
  137. data/lib/carray/categorical.rb +242 -52
  138. data/lib/carray/categorical_iterator.rb +437 -827
  139. data/lib/carray/complex.rb +41 -34
  140. data/lib/carray/conditional.rb +150 -14
  141. data/lib/carray/const_string.rb +59 -4
  142. data/lib/carray/construct.rb +15 -11
  143. data/lib/carray/data_type_extension.rb +1 -0
  144. data/lib/carray/distance_limit.rb +77 -0
  145. data/lib/carray/fixlen_string.rb +7 -1
  146. data/lib/carray/frame/column_verbs.rb +70 -0
  147. data/lib/carray/frame/concat.rb +157 -6
  148. data/lib/carray/frame/convert.rb +82 -7
  149. data/lib/carray/frame/csv_parser.rb +688 -87
  150. data/lib/carray/frame/describe.rb +80 -0
  151. data/lib/carray/frame/frame.rb +369 -45
  152. data/lib/carray/frame/group.rb +631 -90
  153. data/lib/carray/frame/io.rb +506 -79
  154. data/lib/carray/frame/join.rb +411 -62
  155. data/lib/carray/frame/records.rb +116 -19
  156. data/lib/carray/frame/reshape.rb +455 -0
  157. data/lib/carray/frame/sort.rb +30 -18
  158. data/lib/carray/frame/verbs.rb +868 -61
  159. data/lib/carray/frame/windows.rb +117 -0
  160. data/lib/carray/frame.rb +4 -0
  161. data/lib/carray/fuse_source.rb +118 -2
  162. data/lib/carray/fusion.rb +257 -42
  163. data/lib/carray/histogram.rb +6 -1
  164. data/lib/carray/inspect.rb +54 -13
  165. data/lib/carray/iterator.rb +99 -9
  166. data/lib/carray/key_windows.rb +620 -0
  167. data/lib/carray/lazy.rb +216 -193
  168. data/lib/carray/mask_gap_fill.rb +112 -92
  169. data/lib/carray/math.rb +32 -19
  170. data/lib/carray/meld_reduce.rb +52 -21
  171. data/lib/carray/methods/align_addr.rb +8 -4
  172. data/lib/carray/methods/bin.rb +26 -18
  173. data/lib/carray/methods/bincount.rb +18 -2
  174. data/lib/carray/methods/bit_string.rb +15 -4
  175. data/lib/carray/methods/choose.rb +16 -3
  176. data/lib/carray/methods/composition.rb +18 -10
  177. data/lib/carray/methods/factorize.rb +2 -2
  178. data/lib/carray/methods/gather_nd.rb +25 -5
  179. data/lib/carray/methods/insert_block.rb +9 -14
  180. data/lib/carray/methods/is_between.rb +59 -0
  181. data/lib/carray/methods/is_in.rb +140 -10
  182. data/lib/carray/methods/join.rb +2 -7
  183. data/lib/carray/methods/lag.rb +49 -0
  184. data/lib/carray/methods/locate_addr.rb +182 -45
  185. data/lib/carray/methods/mode.rb +18 -1
  186. data/lib/carray/methods/nunique.rb +11 -6
  187. data/lib/carray/methods/repeat.rb +1 -20
  188. data/lib/carray/methods/resize.rb +21 -23
  189. data/lib/carray/methods/snap.rb +34 -12
  190. data/lib/carray/methods/unique.rb +11 -2
  191. data/lib/carray/methods/value_counts.rb +4 -11
  192. data/lib/carray/record_order.rb +208 -0
  193. data/lib/carray/rng.rb +3 -0
  194. data/lib/carray/runtime.rb +65 -17
  195. data/lib/carray/segment_iterator.rb +1221 -0
  196. data/lib/carray/serialize.rb +214 -30
  197. data/lib/carray/slab_iterator.rb +101 -27
  198. data/lib/carray/stack.rb +10 -4
  199. data/lib/carray/string.rb +105 -5
  200. data/lib/carray/string_operation_extension.rb +12 -4
  201. data/lib/carray/struct.rb +137 -58
  202. data/lib/carray/struct_builder.rb +124 -17
  203. data/lib/carray/time.rb +1222 -186
  204. data/lib/carray/window_iterator.rb +242 -81
  205. data/lib/carray.rb +9 -2
  206. data/yard-stubs/ca_obj_array.rb +4 -4
  207. data/yard-stubs/ca_obj_bitarray.rb +7 -0
  208. data/yard-stubs/ca_obj_bitfield.rb +23 -12
  209. data/yard-stubs/ca_obj_fake.rb +1 -1
  210. data/yard-stubs/ca_obj_field.rb +5 -1
  211. data/yard-stubs/ca_obj_grid.rb +21 -10
  212. data/yard-stubs/ca_obj_refer.rb +5 -4
  213. data/yard-stubs/ca_obj_roll.rb +2 -3
  214. data/yard-stubs/ca_obj_shift.rb +5 -1
  215. data/yard-stubs/ca_obj_stride.rb +10 -7
  216. data/yard-stubs/ca_obj_tile.rb +1 -1
  217. data/yard-stubs/ca_obj_transpose.rb +1 -1
  218. data/yard-stubs/ca_obj_window.rb +9 -5
  219. data/yard-stubs/carray_access.rb +11 -5
  220. data/yard-stubs/carray_attribute.rb +0 -5
  221. data/yard-stubs/carray_broadcast.rb +1 -1
  222. data/yard-stubs/carray_cast.rb +88 -43
  223. data/yard-stubs/carray_conversion.rb +15 -2
  224. data/yard-stubs/carray_copy.rb +12 -5
  225. data/yard-stubs/carray_core.rb +3 -3
  226. data/yard-stubs/carray_count.rb +9 -0
  227. data/yard-stubs/carray_element.rb +10 -4
  228. data/yard-stubs/carray_generate.rb +21 -1
  229. data/yard-stubs/carray_lazy.rb +5 -1
  230. data/yard-stubs/carray_loop.rb +4 -1
  231. data/yard-stubs/carray_mask.rb +60 -12
  232. data/yard-stubs/carray_math.rb +52 -14
  233. data/yard-stubs/carray_median_percentile.rb +15 -8
  234. data/yard-stubs/carray_memory_view.rb +40 -23
  235. data/yard-stubs/carray_order.rb +61 -29
  236. data/yard-stubs/carray_random.rb +13 -4
  237. data/yard-stubs/carray_scatter.rb +21 -9
  238. data/yard-stubs/carray_segment.rb +72 -0
  239. data/yard-stubs/carray_slab.rb +10 -2
  240. data/yard-stubs/carray_sort.rb +49 -8
  241. data/yard-stubs/carray_test.rb +15 -3
  242. data/yard-stubs/carray_utils.rb +0 -26
  243. metadata +19 -5
  244. data/ext/ca_for_each_element.h +0 -239
  245. data/ext/carray_kernels_map.c +0 -3467
  246. data/lib/carray/arrow_tensor.rb +0 -401
  247. data/lib/carray/table.rb +0 -108
@@ -13,6 +13,7 @@
13
13
 
14
14
  #include "carray.h"
15
15
  #include "ca_obj_face.h" /* CA_OBJ_RECORD + rb_ca_record_get_data_class */
16
+ #include "carray_internal.h" /* rb_ca_inherit_attr */
16
17
 
17
18
  /* ------------------------------------------------------------------- */
18
19
 
@@ -436,6 +437,9 @@ rb_ca_is_object_type (VALUE self)
436
437
  /* ------------------------------------------------------------------- */
437
438
 
438
439
  static ID id_parent;
440
+ static ID id_lifted_from;
441
+ static ID id_attr;
442
+ static ID id_attrs;
439
443
 
440
444
  VALUE
441
445
  rb_ca_parent (VALUE self)
@@ -443,13 +447,83 @@ rb_ca_parent (VALUE self)
443
447
  return rb_ivar_get(self, id_parent);
444
448
  }
445
449
 
450
+ /* A view of a Face is built on the Face's storage and wrapped in a new Face
451
+ (ca_face_lift), so the Face it was taken from is not on its parent chain.
452
+ The lift records that Face here, and the attribute walk goes to it in
453
+ place of the parent: the attributes set on a Face show on its views. */
454
+ void
455
+ rb_ca_set_lifted_from (VALUE lifted, VALUE face)
456
+ {
457
+ rb_ivar_set(lifted, id_lifted_from, face);
458
+ }
459
+
460
+ /* The next array of the attribute walk: the Face a lifted view was taken
461
+ from, or else the parent. */
462
+ static VALUE
463
+ ca_attr_parent (VALUE obj)
464
+ {
465
+ if ( rb_ivar_defined(obj, id_lifted_from) ) {
466
+ return rb_ivar_get(obj, id_lifted_from);
467
+ }
468
+ return rb_ivar_get(obj, id_parent);
469
+ }
470
+
471
+ static VALUE
472
+ rb_ca_attribute_parent (VALUE self)
473
+ {
474
+ return ca_attr_parent(self);
475
+ }
476
+
477
+ /* dup and clone copy the instance variables before initialize_copy, so the
478
+ copy would share the receiver's attribute Hash and a set_attr on it would
479
+ write into the receiver. Give the copy a Hash of its own. */
480
+ void
481
+ rb_ca_own_attr (VALUE self)
482
+ {
483
+ if ( rb_ivar_defined(self, id_attr) ) {
484
+ VALUE h = rb_ivar_get(self, id_attr);
485
+ if ( RB_TYPE_P(h, T_HASH) ) {
486
+ rb_ivar_set(self, id_attr, rb_hash_dup(h));
487
+ }
488
+ }
489
+ }
490
+
491
+ /* Give dst the attributes (lib/carray/attribute.rb) that src shows, as its
492
+ own Hash. Used by the methods that produce a new entity holding the
493
+ same values -- copy, to_type. The parent walk here only decides
494
+ whether any array on the chain has an @attr at all; which of them
495
+ src actually shows (a lazy op view stops the chain) is left to #attrs,
496
+ so the rule lives in one place. */
497
+ void
498
+ rb_ca_inherit_attr (VALUE dst, VALUE src)
499
+ {
500
+ VALUE obj = src, attrs;
501
+ int depth;
502
+
503
+ /* A chain longer than this is left to #attrs, which walks it all. */
504
+ for (depth = 0; depth < 64 && ! NIL_P(obj); depth++) {
505
+ if ( rb_ivar_defined(obj, id_attr) ) {
506
+ break;
507
+ }
508
+ obj = ca_attr_parent(obj);
509
+ }
510
+ if ( NIL_P(obj) ) {
511
+ return;
512
+ }
513
+ attrs = rb_funcall(src, id_attrs, 0);
514
+ if ( RHASH_SIZE(attrs) > 0 ) {
515
+ rb_ivar_set(dst, id_attr, rb_hash_dup(attrs));
516
+ }
517
+ }
518
+
519
+ /* A view of a frozen array is not frozen itself: building it may still set
520
+ it up after this (an ivar, a lift that moves it onto another parent), and
521
+ writes through it are refused by ca_is_readonly, which walks to the
522
+ frozen root and finds CA_FLAG_READ_ONLY there. */
446
523
  VALUE
447
524
  rb_ca_set_parent (VALUE self, VALUE obj)
448
525
  {
449
526
  rb_ivar_set(self, id_parent, obj);
450
- if ( OBJ_FROZEN(obj) ) {
451
- rb_ca_freeze(self);
452
- }
453
527
  return obj;
454
528
  }
455
529
 
@@ -521,6 +595,53 @@ ca_root_array (void *ap)
521
595
  }
522
596
  }
523
597
 
598
+ /* Whether two arrays may share memory: their cells live in the same
599
+ root, or in two entities whose memory overlaps (one wraps the other's
600
+ memory, as wrap_memory_view does). A view with several parents (a
601
+ stack, a meld, a lazy expression) is the end of its own chain, so its
602
+ parents are asked in turn. An operation that writes one while reading
603
+ the other must read from a copy taken before it writes. */
604
+ int
605
+ ca_shares_root (void *ap, void *aq)
606
+ {
607
+ CArray *ra = ca_root_array(ap);
608
+ CArray *rb = ca_root_array(aq);
609
+ if ( ra == rb ) {
610
+ return 1;
611
+ }
612
+ if ( ca_test_flag(ra, CA_FLAG_MULTI_PARENTS) ) {
613
+ CAMultiParent *mp = (CAMultiParent *) ra;
614
+ int32_t k;
615
+ for ( k = 0; k < mp->n_parents; k++ ) {
616
+ if ( mp->parents[k] && ca_shares_root(mp->parents[k], rb) ) {
617
+ return 1;
618
+ }
619
+ }
620
+ return 0;
621
+ }
622
+ if ( ca_test_flag(rb, CA_FLAG_MULTI_PARENTS) ) {
623
+ return ca_shares_root(rb, ra);
624
+ }
625
+ if ( ca_is_entity(ra) && ca_is_entity(rb) && ra->ptr && rb->ptr ) {
626
+ char *a0 = ra->ptr, *a1 = ra->ptr + ca_length(ra);
627
+ char *b0 = rb->ptr, *b1 = rb->ptr + ca_length(rb);
628
+ return a0 < b1 && b0 < a1;
629
+ }
630
+ return 0;
631
+ }
632
+
633
+ /* Whether self and other may share memory (ca_shares_root), for the plan
634
+ reader that keeps an evaluator off a store reading what it writes. */
635
+ static VALUE
636
+ rb_ca_storage_overlaps (VALUE self, VALUE other)
637
+ {
638
+ CArray *ca, *cb;
639
+ rb_check_carray_object(other);
640
+ TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
641
+ TypedData_Get_Struct(other, CArray, &carray_data_type, cb);
642
+ return ca_shares_root(ca, cb) ? Qtrue : Qfalse;
643
+ }
644
+
524
645
  static VALUE
525
646
  rb_ca_root_array (VALUE self)
526
647
  {
@@ -584,13 +705,15 @@ void
584
705
  Init_carray_attribute (void)
585
706
  {
586
707
  id_parent = rb_intern("parent");
708
+ id_lifted_from = rb_intern("lifted_from");
709
+ id_attr = rb_intern("@attr");
710
+ id_attrs = rb_intern("attrs");
587
711
 
588
712
  rb_define_method(rb_cCArray, "obj_type", rb_ca_obj_type, 0);
589
713
  rb_define_method(rb_cCArray, "data_type", rb_ca_data_type, 0);
590
714
  rb_define_method(rb_cCArray, "bytes", rb_ca_bytes, 0);
591
715
  rb_define_method(rb_cCArray, "flags", rb_ca_flags, 0);
592
716
  rb_define_method(rb_cCArray, "ndim", rb_ca_ndim, 0);
593
- rb_define_method(rb_cCArray, "rank", rb_ca_ndim, 0);
594
717
  rb_define_method(rb_cCArray, "shape", rb_ca_dim, 0);
595
718
  rb_define_method(rb_cCArray, "dim", rb_ca_dim, 0);
596
719
  rb_define_method(rb_cCArray, "dim0", rb_ca_dim0, 0);
@@ -604,6 +727,7 @@ Init_carray_attribute (void)
604
727
  rb_define_method(rb_cCArray, "data_type_name", rb_ca_data_type_name, 0);
605
728
 
606
729
  rb_define_method(rb_cCArray, "parent", rb_ca_parent, 0);
730
+ rb_define_private_method(rb_cCArray, "attribute_parent", rb_ca_attribute_parent, 0);
607
731
 
608
732
  rb_define_method(rb_cCArray, "data_class", rb_ca_data_class, 0);
609
733
  rb_define_method(rb_cCArray, "data_class=", rb_ca_set_data_class, 1);
@@ -631,6 +755,7 @@ Init_carray_attribute (void)
631
755
  rb_define_method(rb_cCArray, "object?", rb_ca_is_object_type, 0);
632
756
 
633
757
  rb_define_method(rb_cCArray, "root_array", rb_ca_root_array, 0);
758
+ rb_define_private_method(rb_cCArray, "storage_overlaps?", rb_ca_storage_overlaps, 1);
634
759
  rb_define_method(rb_cCArray, "ancestors", rb_ca_ancestors, 0);
635
760
  }
636
761
 
@@ -67,11 +67,40 @@
67
67
  case CA_UINT64: COUNT_KERNEL(uint64_t, OUT_T); break; \
68
68
  default: \
69
69
  rb_raise(rb_eCADataTypeError, \
70
- "bincount: integer label array required (got %d)", \
71
- cl->data_type); \
70
+ "bincount: integer label array required (got %s)", \
71
+ ca_type_name[cl->data_type]); \
72
72
  } \
73
73
  } while (0)
74
74
 
75
+ /* Checked before a window opens: the dispatches above raise on a type
76
+ they do not cover, which would leave the labels (and weights) attached. */
77
+ static void
78
+ bincount_check_types (CArray *cl, CArray *cw)
79
+ {
80
+ switch ( cl->data_type ) {
81
+ case CA_INT8: case CA_INT16: case CA_INT32: case CA_INT64:
82
+ case CA_UINT8: case CA_UINT16: case CA_UINT32: case CA_UINT64:
83
+ break;
84
+ default:
85
+ rb_raise(rb_eCADataTypeError,
86
+ "bincount: integer label array required (got %s)",
87
+ ca_type_name[cl->data_type]);
88
+ }
89
+ if ( ! cw ) {
90
+ return;
91
+ }
92
+ switch ( cw->data_type ) {
93
+ case CA_FLOAT64: case CA_FLOAT32:
94
+ case CA_INT8: case CA_INT16: case CA_INT32: case CA_INT64:
95
+ case CA_UINT8: case CA_UINT16: case CA_UINT32: case CA_UINT64:
96
+ break;
97
+ default:
98
+ rb_raise(rb_eCADataTypeError,
99
+ "bincount: weights must be numeric (got %s)",
100
+ ca_type_name[cw->data_type]);
101
+ }
102
+ }
103
+
75
104
  /* __bincount_count__(length) -- count occurrences of each label in
76
105
  self. Allocates a zero-filled UInt32 (or UInt64 if length >= 2^32)
77
106
  output of size `length`, then runs the 8-way label dispatch. */
@@ -104,7 +133,8 @@ rb_ca_bincount_count_kernel (VALUE self, VALUE rlength)
104
133
  return vout;
105
134
  }
106
135
 
107
- ca_attach(cl);
136
+ bincount_check_types(cl, NULL);
137
+ ca_attach(cl); /* window: nothing raises inside */
108
138
  n = cl->elements;
109
139
  mlabel = cl->mask ? (boolean8_t *) cl->mask->ptr : NULL;
110
140
 
@@ -170,8 +200,8 @@ rb_ca_bincount_count_kernel (VALUE self, VALUE rlength)
170
200
  case CA_UINT64: WEIGHTED_KERNEL(uint64_t, W_T); break; \
171
201
  default: \
172
202
  rb_raise(rb_eCADataTypeError, \
173
- "bincount: integer label array required (got %d)", \
174
- cl->data_type); \
203
+ "bincount: integer label array required (got %s)", \
204
+ ca_type_name[cl->data_type]); \
175
205
  } \
176
206
  } while (0)
177
207
 
@@ -213,7 +243,8 @@ rb_ca_bincount_weighted_kernel (VALUE self, VALUE rweights, VALUE rlength)
213
243
  return vout;
214
244
  }
215
245
 
216
- ca_attach_n(2, cl, cw);
246
+ bincount_check_types(cl, cw);
247
+ ca_attach_n(2, cl, cw); /* window: nothing raises inside */
217
248
  n = cl->elements;
218
249
  mlabel = cl->mask ? (boolean8_t *) cl->mask->ptr : NULL;
219
250
  mweight = cw->mask ? (boolean8_t *) cw->mask->ptr : NULL;
@@ -232,7 +263,8 @@ rb_ca_bincount_weighted_kernel (VALUE self, VALUE rweights, VALUE rlength)
232
263
  default:
233
264
  ca_detach_n(2, cl, cw);
234
265
  rb_raise(rb_eCADataTypeError,
235
- "bincount: weights must be numeric (got %d)", w_type);
266
+ "bincount: weights must be numeric (got %s)",
267
+ ca_type_name[w_type]);
236
268
  }
237
269
 
238
270
  ca_detach_n(2, cl, cw);
@@ -30,6 +30,8 @@
30
30
  ---------------------------------------------------------------------------- */
31
31
 
32
32
  #include "carray.h"
33
+ #include "carray_internal.h" /* ca_check_rank_fits */
34
+ #include "ca_obj_face.h" /* CA_WRAPPER_LIFT */
33
35
 
34
36
  NORETURN(static void ca_broadcast_refuse_write (VALUE dst, VALUE src));
35
37
 
@@ -39,11 +41,12 @@ ca_broadcast_refuse_write (VALUE dst, VALUE src)
39
41
  {
40
42
  volatile VALUE dst_s = rb_inspect(rb_funcall(dst, rb_intern("shape"), 0));
41
43
  volatile VALUE src_s = rb_inspect(rb_funcall(src, rb_intern("shape"), 0));
42
- rb_raise(rb_eRuntimeError,
43
- "shape mismatch writing to carray (%s <- %s); shapes must agree "
44
+ rb_raise(rb_eArgError,
45
+ "%s: shape mismatch writing to carray (%s <- %s); shapes must agree "
44
46
  "once size-1 axes are dropped, or one side must be 1-D, or the "
45
47
  "source must be smaller and broadcastable -- use .flatten to "
46
48
  "write the values in the order they lie",
49
+ ca_calling_method_name(),
47
50
  StringValueCStr(dst_s), StringValueCStr(src_s));
48
51
  }
49
52
 
@@ -86,7 +89,11 @@ ca_broadcast_to_destination (VALUE dst, volatile VALUE *src)
86
89
  return;
87
90
  }
88
91
 
89
- if ( cs->elements < cd->elements && cs->ndim == cd->ndim ) {
92
+ /* A size-1 axis repeated onto an axis of length 0 leaves the source
93
+ larger than an empty destination; the axes say it is a repeat all
94
+ the same. */
95
+ if ( ( cs->elements < cd->elements || cd->elements == 0 )
96
+ && cs->ndim == cd->ndim ) {
90
97
  int i;
91
98
  for ( i = 0; i < cd->ndim; i++ ) {
92
99
  if ( cs->dim[i] != cd->dim[i] && cs->dim[i] != 1 ) break;
@@ -119,7 +126,7 @@ ca_broadcast_view (VALUE src, int8_t ndim, ca_size_t *target_dim)
119
126
  TypedData_Get_Struct(src, CArray, &carray_data_type, cs);
120
127
 
121
128
  if (cs->ndim != ndim) {
122
- rb_raise(rb_eRuntimeError,
129
+ rb_raise(rb_eArgError,
123
130
  "broadcast: ndim mismatch (%d vs %d)",
124
131
  (int) cs->ndim, (int) ndim);
125
132
  }
@@ -143,7 +150,7 @@ ca_broadcast_view (VALUE src, int8_t ndim, ca_size_t *target_dim)
143
150
  needs_broadcast = 1;
144
151
  }
145
152
  else {
146
- rb_raise(rb_eRuntimeError,
153
+ rb_raise(rb_eArgError,
147
154
  "broadcast: cannot broadcast axis %d (%lld vs %lld)",
148
155
  i, (long long) cs->dim[i], (long long) target_dim[i]);
149
156
  }
@@ -172,20 +179,49 @@ ca_broadcast_view (VALUE src, int8_t ndim, ca_size_t *target_dim)
172
179
  raises). */
173
180
  NORETURN(static void ca_broadcast_refuse (VALUE self, VALUE other));
174
181
 
175
- /* Report a pair that cannot be brought to a common shape. Naming both
176
- shapes is the point of the message: the caller wrote two arrays that
177
- cannot be combined, and the only remedy is to say which two. */
182
+ /* Report a pair that cannot be brought to a common shape. The message
183
+ names both shapes and points to the remedy that fits the pair: when
184
+ the ndim differs, the missing axes are added with :_; when the
185
+ element counts are equal, .flatten pairs the values in the order
186
+ they lie. */
178
187
  static void
179
188
  ca_broadcast_refuse (VALUE self, VALUE other)
180
189
  {
190
+ CArray *ca, *cb;
181
191
  volatile VALUE self_s = rb_inspect(rb_funcall(self, rb_intern("shape"), 0));
182
192
  volatile VALUE other_s = rb_inspect(rb_funcall(other, rb_intern("shape"), 0));
193
+ const char *flatten_hint;
194
+ int i;
195
+
196
+ TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
197
+ TypedData_Get_Struct(other, CArray, &carray_data_type, cb);
198
+
199
+ flatten_hint = (ca->elements == cb->elements)
200
+ ? "; to pair the values in the order they lie, use .flatten on both sides"
201
+ : "";
202
+
203
+ if (ca->ndim != cb->ndim) {
204
+ rb_raise(rb_eArgError,
205
+ "%s: shape mismatch between operands (%s and %s): the operands "
206
+ "have different numbers of axes, and axes are not added "
207
+ "implicitly -- add size-1 axes with :_ so both have the same "
208
+ "number (x[:_, nil] makes a 1-D x a row, x[nil, :_] a column)%s",
209
+ ca_calling_method_name(),
210
+ StringValueCStr(self_s), StringValueCStr(other_s),
211
+ flatten_hint);
212
+ }
213
+
214
+ for (i = 0; i < ca->ndim; i++) {
215
+ if (ca->dim[i] != cb->dim[i] && ca->dim[i] != 1 && cb->dim[i] != 1) {
216
+ break;
217
+ }
218
+ }
183
219
  rb_raise(rb_eArgError,
184
- "shape mismatch between operands (%s and %s); shapes must "
185
- "agree, or differ only in size-1 axes with equal ndim -- use "
186
- ".flatten on both sides to operate on the values in the order "
187
- "they lie",
188
- StringValueCStr(self_s), StringValueCStr(other_s));
220
+ "%s: shape mismatch between operands (%s and %s): axis %d has "
221
+ "sizes %lld and %lld; each axis must have the same size, or "
222
+ "size 1 on one side%s",
223
+ ca_calling_method_name(), StringValueCStr(self_s), StringValueCStr(other_s), i,
224
+ (long long) ca->dim[i], (long long) cb->dim[i], flatten_hint);
189
225
  }
190
226
 
191
227
  void
@@ -266,13 +302,11 @@ rb_ca_broadcast_to (int argc, VALUE *argv, VALUE self)
266
302
 
267
303
  TypedData_Get_Struct(self, CArray, &carray_data_type, cs);
268
304
 
269
- if (argc < 0 || argc > CA_RANK_MAX) {
270
- rb_raise(rb_eArgError, "broadcast_to: invalid number of dims (%d)", argc);
271
- }
305
+ ca_check_rank_fits(argc, "broadcast_to");
272
306
  target_ndim = (int8_t) argc;
273
307
 
274
308
  if (target_ndim < cs->ndim) {
275
- rb_raise(rb_eRuntimeError,
309
+ rb_raise(rb_eArgError,
276
310
  "broadcast_to: target ndim %d smaller than source ndim %d",
277
311
  (int) target_ndim, (int) cs->ndim);
278
312
  }
@@ -303,6 +337,7 @@ rb_ca_broadcast_to (int argc, VALUE *argv, VALUE self)
303
337
  }
304
338
  obj = ca_wrap_struct(view);
305
339
  rb_ca_set_parent(obj, self);
340
+ CA_WRAPPER_LIFT(obj, self, cs);
306
341
  return obj;
307
342
  }
308
343
 
@@ -340,7 +375,7 @@ rb_ca_broadcast_to (int argc, VALUE *argv, VALUE self)
340
375
  else {
341
376
  /* sd == -1 (source exhausted) with dd > 1, or sd > 1 with
342
377
  dd > 1 and not equal: cannot broadcast. */
343
- rb_raise(rb_eRuntimeError,
378
+ rb_raise(rb_eArgError,
344
379
  "broadcast_to: cannot broadcast axis %d "
345
380
  "(source %s, target %lld)",
346
381
  t_idx,
@@ -351,7 +386,7 @@ rb_ca_broadcast_to (int argc, VALUE *argv, VALUE self)
351
386
  }
352
387
 
353
388
  if (s_idx >= 0) {
354
- rb_raise(rb_eRuntimeError,
389
+ rb_raise(rb_eArgError,
355
390
  "broadcast_to: %d source axes left unmatched", s_idx + 1);
356
391
  }
357
392
 
@@ -366,6 +401,8 @@ rb_ca_broadcast_to (int argc, VALUE *argv, VALUE self)
366
401
  }
367
402
  obj = ca_wrap_struct(view);
368
403
  rb_ca_set_parent(obj, self);
404
+ /* The Face stays on top, as for every view. */
405
+ CA_WRAPPER_LIFT(obj, self, cs);
369
406
  return obj;
370
407
  }
371
408
 
@@ -1,3 +1,3 @@
1
1
  /* GENERATED by extconf.rb: the flags this build's arithmetic
2
2
  was compiled with. See CArray::BUILD_FLAGS. */
3
- #define CA_BUILD_FLAGS "-O3 -fno-fast-math -fopenmp-simd -march=native"
3
+ #define CA_BUILD_FLAGS "-O3 -fno-fast-math -fwrapv -fopenmp-simd -march=native"