carray 3.0.0 → 3.0.2

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +845 -3
  4. data/{NEWS.md → CHANGELOG.v1.md} +1 -1
  5. data/README.md +33 -33
  6. data/carray.gemspec +12 -8
  7. data/ext/ca_axis_dispatch.c +33 -4
  8. data/ext/ca_axis_group.c +256 -114
  9. data/ext/ca_binop_dispatch.c +5 -6
  10. data/ext/ca_binop_dispatch.h +0 -7
  11. data/ext/ca_categorical_iterator.c +121 -67
  12. data/ext/ca_for_each_element.h +6 -8
  13. data/ext/ca_group_iter.c +1 -1
  14. data/ext/ca_kernel_iterator.c +386 -74
  15. data/ext/ca_kernel_iterator.h +145 -45
  16. data/ext/ca_obj_array.c +62 -20
  17. data/ext/ca_obj_bincmp.c +57 -27
  18. data/ext/ca_obj_binop.c +86 -30
  19. data/ext/ca_obj_block.c +4 -4
  20. data/ext/ca_obj_const_string.c +88 -27
  21. data/ext/ca_obj_face.c +104 -0
  22. data/ext/ca_obj_face.h +48 -1
  23. data/ext/ca_obj_fake.c +11 -0
  24. data/ext/ca_obj_fixlen_string.c +21 -6
  25. data/ext/ca_obj_grid.c +11 -3
  26. data/ext/ca_obj_meld.c +125 -22
  27. data/ext/ca_obj_moncmp.c +33 -14
  28. data/ext/ca_obj_monop.c +19 -7
  29. data/ext/ca_obj_object.c +107 -4
  30. data/ext/ca_obj_record.c +3 -1
  31. data/ext/ca_obj_refer.c +30 -6
  32. data/ext/ca_obj_roll.c +13 -5
  33. data/ext/ca_obj_select.c +49 -34
  34. data/ext/ca_obj_select_axis.c +16 -6
  35. data/ext/ca_obj_shift.c +3 -3
  36. data/ext/ca_obj_stack.c +3 -8
  37. data/ext/ca_obj_stride.c +178 -24
  38. data/ext/ca_obj_string.c +11 -5
  39. data/ext/ca_obj_tile.c +13 -5
  40. data/ext/ca_obj_time.c +3 -1
  41. data/ext/ca_obj_timedelta.c +3 -1
  42. data/ext/ca_obj_transpose.c +1 -1
  43. data/ext/ca_obj_triop.c +62 -23
  44. data/ext/ca_obj_window.c +94 -19
  45. data/ext/ca_op_cmplx64.h +123 -0
  46. data/ext/ca_op_ipower.c +1 -5
  47. data/ext/ca_rng_normal.h +42 -0
  48. data/ext/ca_rng_xoshiro256pp.h +105 -0
  49. data/ext/ca_sort_kernels.h +5 -5
  50. data/ext/ca_sweep_engine.c +362 -155
  51. data/ext/ca_sweep_engine.h +39 -9
  52. data/ext/ca_transform_common.c +7 -0
  53. data/ext/carray.h +148 -132
  54. data/ext/carray_access.c +83 -49
  55. data/ext/carray_address_basis.c +590 -0
  56. data/ext/carray_bincount.c +8 -8
  57. data/ext/carray_broadcast.c +102 -9
  58. data/ext/carray_build_flags.h +3 -0
  59. data/ext/carray_call_cfunc.c +2010 -335
  60. data/ext/carray_call_cfunc.h +153 -0
  61. data/ext/carray_cast.c +184 -72
  62. data/ext/carray_conversion.c +22 -22
  63. data/ext/carray_copy.c +67 -32
  64. data/ext/carray_core.c +140 -13
  65. data/ext/carray_count.c +10 -11
  66. data/ext/carray_element.c +7 -7
  67. data/ext/carray_factorize.c +72 -51
  68. data/ext/carray_hold.c +1 -1
  69. data/ext/carray_index_classifier.c +7 -21
  70. data/ext/carray_internal.h +36 -3
  71. data/ext/carray_kernels_bincmp.c +1 -0
  72. data/ext/carray_kernels_binop.c +320 -298
  73. data/ext/carray_kernels_init.c +1095 -0
  74. data/ext/carray_kernels_map.c +1 -0
  75. data/ext/carray_kernels_moncmp.c +1 -0
  76. data/ext/carray_kernels_monop.c +412 -411
  77. data/ext/carray_kernels_reduce_aggregate.c +256 -87
  78. data/ext/carray_kernels_reduce_boolean.c +1 -0
  79. data/ext/carray_kernels_reduce_cumulative.c +324 -54
  80. data/ext/carray_kernels_reduce_extreme.c +605 -58
  81. data/ext/carray_kernels_reduce_variance.c +1 -0
  82. data/ext/carray_kernels_scan.c +5 -4
  83. data/ext/carray_kernels_search.c +187 -106
  84. data/ext/carray_kernels_sort.c +1 -0
  85. data/ext/carray_kernels_triop.c +1 -0
  86. data/ext/carray_lazy.c +175 -5
  87. data/ext/carray_loop.c +7 -1
  88. data/ext/carray_mask.c +29 -13
  89. data/ext/carray_median_percentile.c +56 -1
  90. data/ext/carray_memory_view.c +46 -21
  91. data/ext/carray_operator.c +50 -53
  92. data/ext/carray_order.c +1 -1
  93. data/ext/carray_partition.c +4 -4
  94. data/ext/carray_random.c +391 -47
  95. data/ext/carray_scatter.c +1 -1
  96. data/ext/carray_slab.c +13 -0
  97. data/ext/carray_sort.c +22 -24
  98. data/ext/carray_sort_kernel.c +10 -10
  99. data/ext/carray_test.c +1 -1
  100. data/ext/extconf.rb +18 -0
  101. data/ext/mk_call_cfunc.rb +323 -145
  102. data/ext/mkkernel.rb +651 -129
  103. data/ext/ruby_carray.c +28 -17
  104. data/ext/version.h +4 -4
  105. data/lib/carray/autoload_carray.rb +24 -3
  106. data/lib/carray/autoload_method_extension.rb +14 -1
  107. data/lib/carray/axis_group.rb +84 -7
  108. data/lib/carray/basics.rb +63 -59
  109. data/lib/carray/bincount_nd.rb +12 -12
  110. data/lib/carray/block_iterator.rb +111 -25
  111. data/lib/carray/categorical.rb +154 -37
  112. data/lib/carray/categorical_iterator.rb +300 -151
  113. data/lib/carray/conditional.rb +14 -14
  114. data/lib/carray/const_string.rb +131 -27
  115. data/lib/carray/construct.rb +61 -0
  116. data/lib/carray/core_extensions.rb +62 -5
  117. data/lib/carray/data_type_extension.rb +21 -1
  118. data/lib/carray/data_type_limits.rb +91 -0
  119. data/lib/carray/fixlen_string.rb +1 -1
  120. data/lib/carray/frame/concat.rb +3 -3
  121. data/lib/carray/frame/convert.rb +1 -1
  122. data/lib/carray/frame/csv_parser.rb +11 -4
  123. data/lib/carray/frame/frame.rb +85 -21
  124. data/lib/carray/frame/group.rb +36 -3
  125. data/lib/carray/frame/io.rb +224 -15
  126. data/lib/carray/frame/records.rb +18 -4
  127. data/lib/carray/frame/sort.rb +1 -1
  128. data/lib/carray/frame/verbs.rb +32 -12
  129. data/lib/carray/fuse_source.rb +123 -0
  130. data/lib/carray/fusion.rb +218 -0
  131. data/lib/carray/histogram.rb +16 -16
  132. data/lib/carray/inspect.rb +43 -16
  133. data/lib/carray/iterator.rb +147 -3
  134. data/lib/carray/lazy.rb +88 -73
  135. data/lib/carray/mask_gap_fill.rb +3 -1
  136. data/lib/carray/meld_reduce.rb +2 -2
  137. data/lib/carray/methods/align_addr.rb +1 -1
  138. data/lib/carray/methods/composition.rb +1 -1
  139. data/lib/carray/methods/discovery_along.rb +74 -0
  140. data/lib/carray/methods/factorize.rb +50 -0
  141. data/lib/carray/methods/is_in.rb +25 -14
  142. data/lib/carray/methods/locate_addr.rb +81 -3
  143. data/lib/carray/methods/mask_duplicates.rb +36 -2
  144. data/lib/carray/methods/meshgrid.rb +4 -5
  145. data/lib/carray/methods/mode.rb +2 -2
  146. data/lib/carray/methods/nunique.rb +23 -2
  147. data/lib/carray/methods/repeat.rb +110 -0
  148. data/lib/carray/methods/snap.rb +7 -2
  149. data/lib/carray/methods/unique.rb +44 -4
  150. data/lib/carray/methods/value_counts.rb +2 -2
  151. data/lib/carray/rng.rb +86 -0
  152. data/lib/carray/runtime.rb +0 -19
  153. data/lib/carray/slab_iterator.rb +77 -19
  154. data/lib/carray/string_operation_extension.rb +10 -6
  155. data/lib/carray/time.rb +906 -491
  156. data/lib/carray/window_iterator.rb +421 -27
  157. data/lib/carray.rb +7 -5
  158. data/yard-stubs/ca_obj_array.rb +385 -0
  159. data/yard-stubs/ca_obj_bitarray.rb +38 -0
  160. data/yard-stubs/ca_obj_bitfield.rb +43 -0
  161. data/yard-stubs/ca_obj_block.rb +68 -0
  162. data/yard-stubs/ca_obj_byte_swap.rb +56 -0
  163. data/yard-stubs/ca_obj_fake.rb +31 -0
  164. data/yard-stubs/ca_obj_farray.rb +32 -0
  165. data/yard-stubs/ca_obj_field.rb +45 -0
  166. data/yard-stubs/ca_obj_grid.rb +35 -0
  167. data/yard-stubs/ca_obj_refer.rb +72 -0
  168. data/yard-stubs/ca_obj_roll.rb +45 -0
  169. data/yard-stubs/ca_obj_shift.rb +43 -0
  170. data/yard-stubs/ca_obj_stride.rb +181 -0
  171. data/yard-stubs/ca_obj_tile.rb +29 -0
  172. data/yard-stubs/ca_obj_transpose.rb +40 -0
  173. data/yard-stubs/ca_obj_window.rb +57 -0
  174. data/yard-stubs/carray_access.rb +131 -0
  175. data/yard-stubs/carray_attribute.rb +246 -0
  176. data/yard-stubs/carray_broadcast.rb +37 -0
  177. data/yard-stubs/carray_cast.rb +489 -0
  178. data/yard-stubs/carray_class.rb +65 -0
  179. data/yard-stubs/carray_conversion.rb +76 -0
  180. data/yard-stubs/carray_copy.rb +79 -0
  181. data/yard-stubs/carray_core.rb +34 -0
  182. data/yard-stubs/carray_count.rb +84 -0
  183. data/yard-stubs/carray_element.rb +108 -0
  184. data/yard-stubs/carray_generate.rb +66 -0
  185. data/yard-stubs/carray_lazy.rb +228 -0
  186. data/yard-stubs/carray_loop.rb +140 -0
  187. data/yard-stubs/carray_mask.rb +259 -0
  188. data/yard-stubs/carray_math.rb +1615 -0
  189. data/yard-stubs/carray_mathfunc.rb +45 -0
  190. data/yard-stubs/carray_median_percentile.rb +103 -0
  191. data/yard-stubs/carray_memory_view.rb +163 -0
  192. data/yard-stubs/carray_order.rb +252 -0
  193. data/yard-stubs/carray_random.rb +89 -0
  194. data/yard-stubs/carray_scatter.rb +106 -0
  195. data/yard-stubs/carray_slab.rb +59 -0
  196. data/yard-stubs/carray_sort.rb +165 -0
  197. data/yard-stubs/carray_test.rb +85 -0
  198. data/yard-stubs/carray_undef.rb +64 -0
  199. data/yard-stubs/carray_utils.rb +97 -0
  200. data/yard-stubs/ruby_carray.rb +193 -0
  201. metadata +67 -10
  202. data/ext/ca_obj_unbound_repeat.c +0 -496
data/ext/carray_scatter.c CHANGED
@@ -9,7 +9,7 @@
9
9
  duplicates unbuffered (sequential) — collisions accumulate
10
10
  mask pair skipped when any of addrs[i] / vals[i] / self[addrs[i]] is masked
11
11
  cast vals silently cast to self.data_type
12
- dtype arithmetic (add / sub / mul / min / max): numeric only
12
+ data type arithmetic (add / sub / mul / min / max): numeric only
13
13
  (boolean / object / fixlen → CADataTypeError; the bang
14
14
  cannot widen self, same rationale as fma! / fms!)
15
15
  replace: numeric or boolean (assignment, no widening)
data/ext/carray_slab.c CHANGED
@@ -460,6 +460,19 @@ ca_slab_setup_input_slab_view (ca_slab_iter_state_t *st, CArray *src,
460
460
  }
461
461
  }
462
462
 
463
+ /* The slab is a window onto the source when the fiber is contiguous and
464
+ a copy in the iterator's scratch when it is not, so writing through it
465
+ landed on one axis and vanished on the next. Nothing in the surface
466
+ said which you would get. Refuse the write on both instead: the block
467
+ forms that produce values (map_slab, reduce_slab) hand their result
468
+ back rather than writing into the slab, and an in-place walk belongs
469
+ to `ca[] = ...` or a C kernel with CA_KERNEL_WRITE. */
470
+ {
471
+ CArray *slab;
472
+ TypedData_Get_Struct(st->slab_view, CArray, &carray_data_type, slab);
473
+ ca_set_flag(slab, CA_FLAG_READ_ONLY);
474
+ }
475
+
463
476
  return in_alias;
464
477
  }
465
478
 
data/ext/carray_sort.c CHANGED
@@ -46,7 +46,7 @@ struct sort_addr_key {
46
46
  /* Multi-key comparator for CArray.sort_addr: compares keys in priority
47
47
  * order, original index breaks ties (stable). Masked cells are an
48
48
  * incomparable sentinel clustered at base->masked_last's end (same
49
- * role NaN plays for float dtypes, and the same masked_position:
49
+ * role NaN plays for float data types, and the same masked_position:
50
50
  * contract as the sort/partition family's :sentinel kernel mode --
51
51
  * see MASKED_POSITION rev1 in mkkernel.rb's MkKernel.sort doc).
52
52
  *
@@ -531,7 +531,7 @@ rb_ca_axis2addr (int argc, VALUE *argv, VALUE self)
531
531
  * worst case.
532
532
  *
533
533
  * Mask handling: masked cells are an incomparable sentinel, the same
534
- * role NaN plays for float dtypes. They are excluded from the value
534
+ * role NaN plays for float data types. They are excluded from the value
535
535
  * comparison and clustered at one end of each fiber; masked_position:
536
536
  * picks which end (:last, default, or :first). Relative order within
537
537
  * the masked cluster is unspecified (same contract as the < / > regions
@@ -639,12 +639,20 @@ rb_ca_sorted_view (int argc, VALUE *argv, VALUE self)
639
639
  * fiber, no pair struct, no view layer. This fast path is numeric-only
640
640
  * and mask-free (CA_KERNEL_NO_MASK below).
641
641
  *
642
- * CA_FIXLEN and masked input both delegate to {sort} + copy instead of
643
- * duplicating the fixlen dialect / mask-position split in this per-
644
- * fiber loop: masked_position: is forwarded unchanged. Masked cells
645
- * keep their masked-ness (the view's remap gather carries the mask bit
646
- * through, and .copy materializes it), clustered at masked_position:
647
- * within each fiber -- same contract as {sort}.
642
+ * Everything the fast path does not cover -- any data_type outside
643
+ * CA_INT8..CA_FLOAT64 (fixlen, boolean, complex, object), and masked
644
+ * input of any type -- delegates to {sort} + copy rather than duplicate
645
+ * the fixlen dialect / the object comparator / the mask-position split
646
+ * in this per-fiber loop; masked_position: is forwarded unchanged.
647
+ * Masked cells keep their masked-ness (the view's remap gather carries
648
+ * the mask bit through, and .copy materializes it), clustered at
649
+ * masked_position: within each fiber -- same contract as {sort}.
650
+ *
651
+ * So sort_copy answers for exactly what sort answers for, which is what
652
+ * being its eager counterpart means. It once refused everything the
653
+ * fast path could not take: object and boolean sorted through {sort}
654
+ * but not through this, and complex reported its refusal in two
655
+ * different ways depending on which of the pair was asked.
648
656
  */
649
657
  static VALUE
650
658
  rb_ca_sort_copy (int argc, VALUE *argv, VALUE self)
@@ -677,11 +685,12 @@ rb_ca_sort_copy (int argc, VALUE *argv, VALUE self)
677
685
  CArray *ca;
678
686
  TypedData_Get_Struct(self, CArray, &carray_data_type, ca);
679
687
 
680
- /* CA_FIXLEN and masked input: the per-fiber path below covers
681
- unmasked numeric dtypes only. Delegate to {sort} (which handles
682
- both the fixlen dialect and the masked_position split) + copy to
683
- get the same shape/class contract as the fast path. */
684
- if ( ca_is_fixlen_type(ca) || ca_has_mask(ca) ) {
688
+ /* The per-fiber path below covers unmasked CA_INT8..CA_FLOAT64 only.
689
+ Everything else goes to {sort} (which handles the fixlen dialect,
690
+ the object comparator and the masked_position split) + copy, for the
691
+ same shape/class contract as the fast path. */
692
+ if ( ca->data_type < CA_INT8 || ca->data_type > CA_FLOAT64
693
+ || ca_has_mask(ca) ) {
685
694
  VALUE sv_kw = rb_hash_new();
686
695
  if ( !NIL_P(vaxis) ) rb_hash_aset(sv_kw, ID2SYM(rb_intern("axis")), vaxis);
687
696
  if ( !NIL_P(vkind) ) rb_hash_aset(sv_kw, ID2SYM(rb_intern("kind")), vkind);
@@ -717,17 +726,6 @@ rb_ca_sort_copy (int argc, VALUE *argv, VALUE self)
717
726
  NUM2INT(vaxis_use), cat->ndim);
718
727
  }
719
728
 
720
- /* data_type check: ALL_NUMERIC only (CA_INT8..CA_FLOAT64).
721
- Complex / object are rejected here; CA_OBJECT goes through the
722
- axis: lift in rb_ca_sorted_view, and complex sort semantics
723
- differ enough that we do not pick a default. */
724
- if ( cat->data_type < CA_INT8 || cat->data_type > CA_FLOAT64 ) {
725
- rb_raise(rb_eCADataTypeError,
726
- "sort_copy: data_type %d not supported "
727
- "(expected one of: i8, u8, i16, u16, i32, u32, i64, u64, f32, f64)",
728
- cat->data_type);
729
- }
730
-
731
729
  /* Allocate output: same shape and data_type as target
732
730
  (bytes=0 = preserve native bytes). */
733
731
  volatile VALUE vout = rb_ca_template_with_type(target,
@@ -1,8 +1,8 @@
1
1
  /* ---------------------------------------------------------------------------
2
2
 
3
- Portable textbook sort kernels: per-dtype quicksort + bottom-up
3
+ Portable textbook sort kernels: per-type quicksort + bottom-up
4
4
  mergesort with inline comparison (no function-pointer indirection
5
- like libc qsort / mergesort). All 10 numeric dtypes plus paired
5
+ like libc qsort / mergesort). All 10 numeric data types plus paired
6
6
  forms for argsort.
7
7
 
8
8
  Internal C API only (no Ruby surface, no Init function). Declared
@@ -12,13 +12,13 @@
12
12
 
13
13
  Algorithms:
14
14
 
15
- * quicksort (ca_sort_quick_<dtype>)
15
+ * quicksort (ca_sort_quick_<type>)
16
16
  median-of-3 pivot, Hoare partition, strict `<`, insertion-sort
17
17
  base (threshold 16), smaller-side recursion / larger-side
18
18
  iterate (stack O(log n)). Depth-limit escape to mergesort for
19
19
  worst-case O(n log n).
20
20
 
21
- * mergesort (ca_sort_merge_<dtype>)
21
+ * mergesort (ca_sort_merge_<type>)
22
22
  Bottom-up, ping-pong (cur / next) per pass with no inter-pass
23
23
  memcpy. Strict `<` (stable: equal -> take-left). Insertion-
24
24
  sort pre-pass that converts the input into R=16-wide sorted
@@ -27,18 +27,18 @@
27
27
  skip the merge loop; no run-state machine, distinct from
28
28
  Timsort galloping).
29
29
 
30
- * paired forms (ca_sort_quick_pair_<dtype> / ca_sort_merge_pair_<dtype>)
30
+ * paired forms (ca_sort_quick_pair_<type> / ca_sort_merge_pair_<type>)
31
31
  Same algorithms over (value, index) pairs for argsort
32
32
  (sort_index / sort_addr). Stable tie-break by index is built
33
33
  into the comparison, so quicksort is effectively stable for
34
34
  argsort even though the algorithm itself is not.
35
35
 
36
- * NaN partitioning (ca_partition_nan_<dtype> + _pair_<dtype>)
36
+ * NaN partitioning (ca_partition_nan_<type> + _pair_<type>)
37
37
  float32 / float64 only. One-pass Hoare-style partition that
38
38
  separates `[finite | NaN]` regions so the downstream sort
39
39
  kernel can operate on the finite slice with plain `<`.
40
40
 
41
- * value-level quickselect (ca_partition_quick_<dtype>)
41
+ * value-level quickselect (ca_partition_quick_<type>)
42
42
  median-of-3 + Hoare + insertion base + one-sided recursion
43
43
  into the side containing kth (quickselect property, expected
44
44
  O(n)). Depth-limit escape to mergesort matches the sort
@@ -402,13 +402,13 @@ ca_sort_quick_pair_##SUFFIX (ca_pair_##SUFFIX *a, ca_size_t n) \
402
402
  struct ca_sort_pair_##SUFFIX##_eat_semicolon
403
403
 
404
404
 
405
- /* ===== Per-dtype instantiations ===========================================
405
+ /* ===== Per-type instantiations ===========================================
406
406
  `<` is well-defined and IEEE-stable for all numeric C types used
407
407
  here; NaN handling for f32 / f64 lives in the pre-partition pass
408
408
  below. */
409
409
 
410
410
  /* ---------------------------------------------------------------------------
411
- NaN pre-partition (float dtypes only).
411
+ NaN pre-partition (float data types only).
412
412
 
413
413
  One-pass Hoare-style partition that separates `a[0..n)` into
414
414
  `[finite | NaN]` regions in place, returning the finite count k
@@ -447,7 +447,7 @@ struct ca_partition_nan_##SUFFIX##_eat_semicolon
447
447
  DEFINE_PARTITION_NAN(float32_t, f32);
448
448
  DEFINE_PARTITION_NAN(double, f64);
449
449
 
450
- /* Pair variant for argsort: separates ca_pair_<dtype> by
450
+ /* Pair variant for argsort: separates ca_pair_<type> by
451
451
  isnan(v.value). Returns the finite count.
452
452
 
453
453
  Stable within both finite and NaN regions (original order
data/ext/carray_test.c CHANGED
@@ -4,7 +4,7 @@
4
4
  - internal check_* / has_same_* helpers used across ext/ sources
5
5
  - Ruby surface: valid_index? / valid_addr? / same_shape? / == /
6
6
  eql? / hash / freeze (docs in yard-stubs/carray_test.rb)
7
- - per-dtype element-equality table `ca_eql[CA_NTYPE]`
7
+ - per-type element-equality table `ca_eql[CA_NTYPE]`
8
8
  - `ca_compare_common` shared body for `==` and `eql?`
9
9
 
10
10
  ---------------------------------------------------------------------------- */
data/ext/extconf.rb CHANGED
@@ -63,6 +63,17 @@ end
63
63
 
64
64
  $CFLAGS += " -Wall"
65
65
 
66
+ # --- the flags that decide the numbers
67
+ #
68
+ # Two compilations of the same C do not have to agree on the last bit: what
69
+ # the compiler is allowed to fuse or reorder is decided by the flags it was
70
+ # given. Anything computing what these kernels compute, somewhere other
71
+ # than in them, has to be built the same way to arrive at the same answer,
72
+ # so the flags that bear on it are recorded and handed out as
73
+ # CArray::BUILD_FLAGS. Optimisation and architecture only -- warnings,
74
+ # defines and link options change nothing about the arithmetic.
75
+ $carray_build_flags = [RbConfig::CONFIG["optflags"].to_s.strip]
76
+
66
77
  # --- in-build flag (CARRAY_BUILD)
67
78
  #
68
79
  # Marks a translation unit as part of carray itself, i.e. recompiled whenever
@@ -121,6 +132,7 @@ simd_probe = <<~C
121
132
  C
122
133
  if try_compile(simd_probe, "-fopenmp-simd")
123
134
  $CFLAGS += " -fopenmp-simd"
135
+ $carray_build_flags << "-fopenmp-simd"
124
136
  $stderr.puts "carray: -fopenmp-simd enabled (SIMD reduction license)"
125
137
  end
126
138
 
@@ -151,11 +163,17 @@ if enable_config("march-native", default_on)
151
163
  arch_probe = "int main(void) { return 0; }\n"
152
164
  if try_compile(arch_probe, "-march=native")
153
165
  $CFLAGS += " -march=native"
166
+ $carray_build_flags << "-march=native"
154
167
  $stderr.puts "carray: -march=native enabled (build-machine ISA extensions)"
155
168
  else
156
169
  $stderr.puts "carray: -march=native probe FAILED, keeping baseline SIMD"
157
170
  end
158
171
  end
172
+ File.write("carray_build_flags.h",
173
+ "/* GENERATED by extconf.rb: the flags this build's arithmetic\n" \
174
+ " was compiled with. See CArray::BUILD_FLAGS. */\n" \
175
+ "#define CA_BUILD_FLAGS #{$carray_build_flags.join(" ").inspect}\n")
176
+
159
177
  # $CFLAGS += " -m128bit-long-double" ### gcc only
160
178
  # $CFLAGS += " -Wno-absolute-value"
161
179
  # $LDFLAGS += " -L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"