carray 3.0.4 → 3.0.6

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 (155) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +438 -0
  3. data/README.md +1 -1
  4. data/carray.gemspec +3 -2
  5. data/ext/ca_array_pool.c +25 -1
  6. data/ext/ca_axis_dispatch.c +19 -20
  7. data/ext/ca_axis_group.c +1 -1
  8. data/ext/ca_categorical_iterator.c +34 -27
  9. data/ext/ca_compare.c +4 -4
  10. data/ext/ca_composite_dispatch.c +9 -9
  11. data/ext/ca_kernel_iterator.c +122 -237
  12. data/ext/ca_kernel_iterator.h +522 -337
  13. data/ext/ca_obj_array.c +69 -19
  14. data/ext/ca_obj_bincmp.c +10 -1
  15. data/ext/ca_obj_binop.c +11 -1
  16. data/ext/ca_obj_bitarray.c +5 -1
  17. data/ext/ca_obj_bitfield.c +60 -43
  18. data/ext/ca_obj_byte_swap.c +4 -1
  19. data/ext/ca_obj_const_string.c +15 -3
  20. data/ext/ca_obj_face.c +44 -1
  21. data/ext/ca_obj_fake.c +3 -1
  22. data/ext/ca_obj_field.c +13 -3
  23. data/ext/ca_obj_grid.c +219 -17
  24. data/ext/ca_obj_meld.c +69 -113
  25. data/ext/ca_obj_moncmp.c +9 -1
  26. data/ext/ca_obj_monop.c +86 -12
  27. data/ext/ca_obj_object.c +118 -32
  28. data/ext/ca_obj_record.c +3 -0
  29. data/ext/ca_obj_reduce.c +19 -1
  30. data/ext/ca_obj_refer.c +80 -26
  31. data/ext/ca_obj_remap.c +69 -10
  32. data/ext/ca_obj_roll.c +27 -6
  33. data/ext/ca_obj_select.c +38 -6
  34. data/ext/ca_obj_select_axis.c +1 -0
  35. data/ext/ca_obj_shift.c +32 -7
  36. data/ext/ca_obj_stack.c +311 -111
  37. data/ext/ca_obj_stride.c +159 -64
  38. data/ext/ca_obj_string.c +27 -2
  39. data/ext/ca_obj_tile.c +28 -7
  40. data/ext/ca_obj_transpose.c +8 -4
  41. data/ext/ca_obj_triop.c +12 -1
  42. data/ext/ca_obj_window.c +80 -50
  43. data/ext/ca_op_ipower.c +12 -12
  44. data/ext/ca_sort_kernels.h +6 -3
  45. data/ext/caframe_csv_reader.c +1 -1
  46. data/ext/carray.h +35 -1
  47. data/ext/carray_access.c +43 -67
  48. data/ext/carray_address_basis.c +134 -0
  49. data/ext/carray_attribute.c +32 -0
  50. data/ext/carray_broadcast.c +3 -4
  51. data/ext/carray_build_flags.h +1 -1
  52. data/ext/carray_cast.c +251 -93
  53. data/ext/carray_cast_func.rb +56 -26
  54. data/ext/carray_conversion.c +11 -7
  55. data/ext/carray_core.c +814 -72
  56. data/ext/carray_count.c +6 -0
  57. data/ext/carray_element.c +22 -13
  58. data/ext/carray_factorize.c +20 -20
  59. data/ext/carray_generate.c +8 -2
  60. data/ext/carray_histogram.c +26 -4
  61. data/ext/carray_index_classifier.c +4 -4
  62. data/ext/carray_internal.h +159 -12
  63. data/ext/carray_kernels_bincmp.c +2174 -170
  64. data/ext/carray_kernels_binop.c +25653 -5487
  65. data/ext/carray_kernels_init.c +8 -8
  66. data/ext/carray_kernels_moncmp.c +96 -96
  67. data/ext/carray_kernels_monop.c +12253 -5235
  68. data/ext/carray_kernels_reduce_aggregate.c +6150 -2423
  69. data/ext/carray_kernels_reduce_boolean.c +1533 -15
  70. data/ext/carray_kernels_reduce_cumulative.c +2442 -882
  71. data/ext/carray_kernels_reduce_extreme.c +5658 -1661
  72. data/ext/carray_kernels_reduce_variance.c +2534 -402
  73. data/ext/carray_kernels_scan.c +368 -368
  74. data/ext/carray_kernels_search.c +4551 -604
  75. data/ext/carray_kernels_sort.c +659 -751
  76. data/ext/carray_kernels_triop.c +114 -114
  77. data/ext/carray_key_windows.c +4 -0
  78. data/ext/carray_lazy.c +47 -0
  79. data/ext/carray_loop.c +1 -1
  80. data/ext/carray_mask.c +175 -161
  81. data/ext/carray_median_percentile.c +4 -4
  82. data/ext/carray_memory_view.c +15 -9
  83. data/ext/carray_operator.c +152 -49
  84. data/ext/carray_order.c +230 -10
  85. data/ext/carray_random.c +22 -19
  86. data/ext/carray_scatter.c +24 -7
  87. data/ext/carray_slab.c +128 -29
  88. data/ext/carray_sort.c +224 -16
  89. data/ext/carray_sort_kernel.c +5 -7
  90. data/ext/carray_struct.c +35 -43
  91. data/ext/carray_test.c +74 -19
  92. data/ext/carray_time_text.c +6 -4
  93. data/ext/carray_utils.c +63 -21
  94. data/ext/extconf.rb +11 -0
  95. data/ext/mkkernel.rb +546 -199
  96. data/ext/ruby_carray.c +4 -1
  97. data/ext/version.h +4 -4
  98. data/lib/carray/attribute.rb +42 -5
  99. data/lib/carray/autoload_carray.rb +3 -3
  100. data/lib/carray/autoload_method_extension.rb +5 -3
  101. data/lib/carray/axis_group.rb +13 -7
  102. data/lib/carray/basics.rb +28 -8
  103. data/lib/carray/block_iterator.rb +17 -3
  104. data/lib/carray/categorical.rb +35 -23
  105. data/lib/carray/categorical_iterator.rb +8 -8
  106. data/lib/carray/complex.rb +2 -2
  107. data/lib/carray/conditional.rb +3 -2
  108. data/lib/carray/const_string.rb +10 -0
  109. data/lib/carray/data_type_extension.rb +8 -1
  110. data/lib/carray/fixlen_string.rb +41 -2
  111. data/lib/carray/frame/column_verbs.rb +48 -16
  112. data/lib/carray/frame/concat.rb +17 -3
  113. data/lib/carray/frame/convert.rb +19 -0
  114. data/lib/carray/frame/csv_parser.rb +32 -32
  115. data/lib/carray/frame/describe.rb +4 -2
  116. data/lib/carray/frame/frame.rb +405 -85
  117. data/lib/carray/frame/group.rb +777 -64
  118. data/lib/carray/frame/io.rb +212 -72
  119. data/lib/carray/frame/join.rb +146 -37
  120. data/lib/carray/frame/records.rb +3 -3
  121. data/lib/carray/frame/reshape.rb +89 -11
  122. data/lib/carray/frame/sort.rb +57 -9
  123. data/lib/carray/frame/verbs.rb +384 -49
  124. data/lib/carray/frame/windows.rb +44 -6
  125. data/lib/carray/fuse_source.rb +31 -2
  126. data/lib/carray/inspect.rb +7 -2
  127. data/lib/carray/iterator.rb +32 -0
  128. data/lib/carray/lazy.rb +52 -8
  129. data/lib/carray/mask_gap_fill.rb +37 -17
  130. data/lib/carray/meld_reduce.rb +1 -1
  131. data/lib/carray/methods/choose.rb +3 -2
  132. data/lib/carray/methods/is_in.rb +8 -1
  133. data/lib/carray/methods/meshgrid.rb +3 -1
  134. data/lib/carray/runtime.rb +47 -8
  135. data/lib/carray/segment_iterator.rb +35 -16
  136. data/lib/carray/serialize.rb +53 -19
  137. data/lib/carray/stack.rb +33 -18
  138. data/lib/carray/string.rb +8 -0
  139. data/lib/carray/string_operation_extension.rb +13 -5
  140. data/lib/carray/struct_builder.rb +5 -3
  141. data/lib/carray/time.rb +112 -68
  142. data/lib/carray/window_iterator.rb +16 -4
  143. data/yard-stubs/ca_obj_array.rb +26 -1
  144. data/yard-stubs/ca_obj_transpose.rb +5 -4
  145. data/yard-stubs/carray_attribute.rb +3 -1
  146. data/yard-stubs/carray_cast.rb +10 -5
  147. data/yard-stubs/carray_conversion.rb +13 -3
  148. data/yard-stubs/carray_element.rb +7 -6
  149. data/yard-stubs/carray_mask.rb +28 -4
  150. data/yard-stubs/carray_math.rb +45 -20
  151. data/yard-stubs/carray_memory_view.rb +7 -0
  152. data/yard-stubs/carray_order.rb +100 -4
  153. data/yard-stubs/carray_scatter.rb +7 -5
  154. data/yard-stubs/carray_test.rb +7 -4
  155. metadata +18 -4
@@ -63,6 +63,13 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
63
63
  positions align between iterators. */
64
64
  int8_t slab_axes[CA_RANK_MAX];
65
65
  slab_axes[0] = (int8_t) axis;
66
+ ca_size_t fiber_n = ca->dim[axis];
67
+ volatile VALUE hbuf = 0, haux = 0;
68
+ sort_index_pair_i8 *buf = ALLOCV_N(sort_index_pair_i8, hbuf, fiber_n);
69
+ sort_index_pair_i8 *aux = NULL;
70
+ if ( do_stable ) {
71
+ aux = ALLOCV_N(sort_index_pair_i8, haux, fiber_n);
72
+ }
66
73
  ca_iter_state st_in, st_out;
67
74
  int rc;
68
75
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -77,14 +84,6 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
77
84
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
78
85
  }
79
86
 
80
- ca_size_t fiber_n = st_in.slab_elements;
81
- volatile VALUE hbuf = 0, haux = 0;
82
- sort_index_pair_i8 *buf = ALLOCV_N(sort_index_pair_i8, hbuf, fiber_n);
83
- sort_index_pair_i8 *aux = NULL;
84
- if ( do_stable ) {
85
- aux = ALLOCV_N(sort_index_pair_i8, haux, fiber_n);
86
- }
87
-
88
87
  char *pi, *po;
89
88
  boolean8_t *mi, *mo;
90
89
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -101,13 +100,13 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
101
100
  if ( masked_last ) {
102
101
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
103
102
  if ( mi[k * mstride] ) continue;
104
- buf[n_valid].v = *(int8_t *) (pi + k * istride);
103
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
105
104
  buf[n_valid].i = k;
106
105
  n_valid++;
107
106
  }
108
107
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
109
108
  if ( ! mi[k * mstride] ) continue;
110
- buf[n_valid + n_masked].v = *(int8_t *) (pi + k * istride);
109
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
111
110
  buf[n_valid + n_masked].i = k;
112
111
  n_masked++;
113
112
  }
@@ -115,13 +114,13 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
115
114
  } else {
116
115
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
117
116
  if ( ! mi[k * mstride] ) continue;
118
- buf[n_masked].v = *(int8_t *) (pi + k * istride);
117
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
119
118
  buf[n_masked].i = k;
120
119
  n_masked++;
121
120
  }
122
121
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
123
122
  if ( mi[k * mstride] ) continue;
124
- buf[n_masked + n_valid].v = *(int8_t *) (pi + k * istride);
123
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
125
124
  buf[n_masked + n_valid].i = k;
126
125
  n_valid++;
127
126
  }
@@ -129,7 +128,7 @@ sort_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
129
128
  }
130
129
  } else {
131
130
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
132
- buf[k].v = *(int8_t *) (pi + k * istride);
131
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
133
132
  buf[k].i = k;
134
133
  }
135
134
  sort_lo = 0; sort_n = fiber_n;
@@ -178,6 +177,13 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
178
177
  positions align between iterators. */
179
178
  int8_t slab_axes[CA_RANK_MAX];
180
179
  slab_axes[0] = (int8_t) axis;
180
+ ca_size_t fiber_n = ca->dim[axis];
181
+ volatile VALUE hbuf = 0, haux = 0;
182
+ sort_index_pair_u8 *buf = ALLOCV_N(sort_index_pair_u8, hbuf, fiber_n);
183
+ sort_index_pair_u8 *aux = NULL;
184
+ if ( do_stable ) {
185
+ aux = ALLOCV_N(sort_index_pair_u8, haux, fiber_n);
186
+ }
181
187
  ca_iter_state st_in, st_out;
182
188
  int rc;
183
189
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -192,14 +198,6 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
192
198
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
193
199
  }
194
200
 
195
- ca_size_t fiber_n = st_in.slab_elements;
196
- volatile VALUE hbuf = 0, haux = 0;
197
- sort_index_pair_u8 *buf = ALLOCV_N(sort_index_pair_u8, hbuf, fiber_n);
198
- sort_index_pair_u8 *aux = NULL;
199
- if ( do_stable ) {
200
- aux = ALLOCV_N(sort_index_pair_u8, haux, fiber_n);
201
- }
202
-
203
201
  char *pi, *po;
204
202
  boolean8_t *mi, *mo;
205
203
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -216,13 +214,13 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
216
214
  if ( masked_last ) {
217
215
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
218
216
  if ( mi[k * mstride] ) continue;
219
- buf[n_valid].v = *(uint8_t *) (pi + k * istride);
217
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
220
218
  buf[n_valid].i = k;
221
219
  n_valid++;
222
220
  }
223
221
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
224
222
  if ( ! mi[k * mstride] ) continue;
225
- buf[n_valid + n_masked].v = *(uint8_t *) (pi + k * istride);
223
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
226
224
  buf[n_valid + n_masked].i = k;
227
225
  n_masked++;
228
226
  }
@@ -230,13 +228,13 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
230
228
  } else {
231
229
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
232
230
  if ( ! mi[k * mstride] ) continue;
233
- buf[n_masked].v = *(uint8_t *) (pi + k * istride);
231
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
234
232
  buf[n_masked].i = k;
235
233
  n_masked++;
236
234
  }
237
235
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
238
236
  if ( mi[k * mstride] ) continue;
239
- buf[n_masked + n_valid].v = *(uint8_t *) (pi + k * istride);
237
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
240
238
  buf[n_masked + n_valid].i = k;
241
239
  n_valid++;
242
240
  }
@@ -244,7 +242,7 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
244
242
  }
245
243
  } else {
246
244
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
247
- buf[k].v = *(uint8_t *) (pi + k * istride);
245
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
248
246
  buf[k].i = k;
249
247
  }
250
248
  sort_lo = 0; sort_n = fiber_n;
@@ -276,7 +274,7 @@ sort_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int ma
276
274
  }
277
275
 
278
276
  typedef struct {
279
- int16_t v;
277
+ ca_u_int16_t v;
280
278
  ca_size_t i;
281
279
  } sort_index_pair_i16;
282
280
 
@@ -293,6 +291,13 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
293
291
  positions align between iterators. */
294
292
  int8_t slab_axes[CA_RANK_MAX];
295
293
  slab_axes[0] = (int8_t) axis;
294
+ ca_size_t fiber_n = ca->dim[axis];
295
+ volatile VALUE hbuf = 0, haux = 0;
296
+ sort_index_pair_i16 *buf = ALLOCV_N(sort_index_pair_i16, hbuf, fiber_n);
297
+ sort_index_pair_i16 *aux = NULL;
298
+ if ( do_stable ) {
299
+ aux = ALLOCV_N(sort_index_pair_i16, haux, fiber_n);
300
+ }
296
301
  ca_iter_state st_in, st_out;
297
302
  int rc;
298
303
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -307,14 +312,6 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
307
312
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
308
313
  }
309
314
 
310
- ca_size_t fiber_n = st_in.slab_elements;
311
- volatile VALUE hbuf = 0, haux = 0;
312
- sort_index_pair_i16 *buf = ALLOCV_N(sort_index_pair_i16, hbuf, fiber_n);
313
- sort_index_pair_i16 *aux = NULL;
314
- if ( do_stable ) {
315
- aux = ALLOCV_N(sort_index_pair_i16, haux, fiber_n);
316
- }
317
-
318
315
  char *pi, *po;
319
316
  boolean8_t *mi, *mo;
320
317
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -331,13 +328,13 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
331
328
  if ( masked_last ) {
332
329
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
333
330
  if ( mi[k * mstride] ) continue;
334
- buf[n_valid].v = *(int16_t *) (pi + k * istride);
331
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
335
332
  buf[n_valid].i = k;
336
333
  n_valid++;
337
334
  }
338
335
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
339
336
  if ( ! mi[k * mstride] ) continue;
340
- buf[n_valid + n_masked].v = *(int16_t *) (pi + k * istride);
337
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
341
338
  buf[n_valid + n_masked].i = k;
342
339
  n_masked++;
343
340
  }
@@ -345,13 +342,13 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
345
342
  } else {
346
343
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
347
344
  if ( ! mi[k * mstride] ) continue;
348
- buf[n_masked].v = *(int16_t *) (pi + k * istride);
345
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
349
346
  buf[n_masked].i = k;
350
347
  n_masked++;
351
348
  }
352
349
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
353
350
  if ( mi[k * mstride] ) continue;
354
- buf[n_masked + n_valid].v = *(int16_t *) (pi + k * istride);
351
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
355
352
  buf[n_masked + n_valid].i = k;
356
353
  n_valid++;
357
354
  }
@@ -359,7 +356,7 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
359
356
  }
360
357
  } else {
361
358
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
362
- buf[k].v = *(int16_t *) (pi + k * istride);
359
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
363
360
  buf[k].i = k;
364
361
  }
365
362
  sort_lo = 0; sort_n = fiber_n;
@@ -391,7 +388,7 @@ sort_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int m
391
388
  }
392
389
 
393
390
  typedef struct {
394
- uint16_t v;
391
+ ca_u_uint16_t v;
395
392
  ca_size_t i;
396
393
  } sort_index_pair_u16;
397
394
 
@@ -408,6 +405,13 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
408
405
  positions align between iterators. */
409
406
  int8_t slab_axes[CA_RANK_MAX];
410
407
  slab_axes[0] = (int8_t) axis;
408
+ ca_size_t fiber_n = ca->dim[axis];
409
+ volatile VALUE hbuf = 0, haux = 0;
410
+ sort_index_pair_u16 *buf = ALLOCV_N(sort_index_pair_u16, hbuf, fiber_n);
411
+ sort_index_pair_u16 *aux = NULL;
412
+ if ( do_stable ) {
413
+ aux = ALLOCV_N(sort_index_pair_u16, haux, fiber_n);
414
+ }
411
415
  ca_iter_state st_in, st_out;
412
416
  int rc;
413
417
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -422,14 +426,6 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
422
426
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
423
427
  }
424
428
 
425
- ca_size_t fiber_n = st_in.slab_elements;
426
- volatile VALUE hbuf = 0, haux = 0;
427
- sort_index_pair_u16 *buf = ALLOCV_N(sort_index_pair_u16, hbuf, fiber_n);
428
- sort_index_pair_u16 *aux = NULL;
429
- if ( do_stable ) {
430
- aux = ALLOCV_N(sort_index_pair_u16, haux, fiber_n);
431
- }
432
-
433
429
  char *pi, *po;
434
430
  boolean8_t *mi, *mo;
435
431
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -446,13 +442,13 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
446
442
  if ( masked_last ) {
447
443
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
448
444
  if ( mi[k * mstride] ) continue;
449
- buf[n_valid].v = *(uint16_t *) (pi + k * istride);
445
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
450
446
  buf[n_valid].i = k;
451
447
  n_valid++;
452
448
  }
453
449
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
454
450
  if ( ! mi[k * mstride] ) continue;
455
- buf[n_valid + n_masked].v = *(uint16_t *) (pi + k * istride);
451
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
456
452
  buf[n_valid + n_masked].i = k;
457
453
  n_masked++;
458
454
  }
@@ -460,13 +456,13 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
460
456
  } else {
461
457
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
462
458
  if ( ! mi[k * mstride] ) continue;
463
- buf[n_masked].v = *(uint16_t *) (pi + k * istride);
459
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
464
460
  buf[n_masked].i = k;
465
461
  n_masked++;
466
462
  }
467
463
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
468
464
  if ( mi[k * mstride] ) continue;
469
- buf[n_masked + n_valid].v = *(uint16_t *) (pi + k * istride);
465
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
470
466
  buf[n_masked + n_valid].i = k;
471
467
  n_valid++;
472
468
  }
@@ -474,7 +470,7 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
474
470
  }
475
471
  } else {
476
472
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
477
- buf[k].v = *(uint16_t *) (pi + k * istride);
473
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
478
474
  buf[k].i = k;
479
475
  }
480
476
  sort_lo = 0; sort_n = fiber_n;
@@ -506,7 +502,7 @@ sort_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int m
506
502
  }
507
503
 
508
504
  typedef struct {
509
- int32_t v;
505
+ ca_u_int32_t v;
510
506
  ca_size_t i;
511
507
  } sort_index_pair_i32;
512
508
 
@@ -523,6 +519,13 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
523
519
  positions align between iterators. */
524
520
  int8_t slab_axes[CA_RANK_MAX];
525
521
  slab_axes[0] = (int8_t) axis;
522
+ ca_size_t fiber_n = ca->dim[axis];
523
+ volatile VALUE hbuf = 0, haux = 0;
524
+ sort_index_pair_i32 *buf = ALLOCV_N(sort_index_pair_i32, hbuf, fiber_n);
525
+ sort_index_pair_i32 *aux = NULL;
526
+ if ( do_stable ) {
527
+ aux = ALLOCV_N(sort_index_pair_i32, haux, fiber_n);
528
+ }
526
529
  ca_iter_state st_in, st_out;
527
530
  int rc;
528
531
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -537,14 +540,6 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
537
540
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
538
541
  }
539
542
 
540
- ca_size_t fiber_n = st_in.slab_elements;
541
- volatile VALUE hbuf = 0, haux = 0;
542
- sort_index_pair_i32 *buf = ALLOCV_N(sort_index_pair_i32, hbuf, fiber_n);
543
- sort_index_pair_i32 *aux = NULL;
544
- if ( do_stable ) {
545
- aux = ALLOCV_N(sort_index_pair_i32, haux, fiber_n);
546
- }
547
-
548
543
  char *pi, *po;
549
544
  boolean8_t *mi, *mo;
550
545
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -561,13 +556,13 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
561
556
  if ( masked_last ) {
562
557
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
563
558
  if ( mi[k * mstride] ) continue;
564
- buf[n_valid].v = *(int32_t *) (pi + k * istride);
559
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
565
560
  buf[n_valid].i = k;
566
561
  n_valid++;
567
562
  }
568
563
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
569
564
  if ( ! mi[k * mstride] ) continue;
570
- buf[n_valid + n_masked].v = *(int32_t *) (pi + k * istride);
565
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
571
566
  buf[n_valid + n_masked].i = k;
572
567
  n_masked++;
573
568
  }
@@ -575,13 +570,13 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
575
570
  } else {
576
571
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
577
572
  if ( ! mi[k * mstride] ) continue;
578
- buf[n_masked].v = *(int32_t *) (pi + k * istride);
573
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
579
574
  buf[n_masked].i = k;
580
575
  n_masked++;
581
576
  }
582
577
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
583
578
  if ( mi[k * mstride] ) continue;
584
- buf[n_masked + n_valid].v = *(int32_t *) (pi + k * istride);
579
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
585
580
  buf[n_masked + n_valid].i = k;
586
581
  n_valid++;
587
582
  }
@@ -589,7 +584,7 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
589
584
  }
590
585
  } else {
591
586
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
592
- buf[k].v = *(int32_t *) (pi + k * istride);
587
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
593
588
  buf[k].i = k;
594
589
  }
595
590
  sort_lo = 0; sort_n = fiber_n;
@@ -621,7 +616,7 @@ sort_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int m
621
616
  }
622
617
 
623
618
  typedef struct {
624
- uint32_t v;
619
+ ca_u_uint32_t v;
625
620
  ca_size_t i;
626
621
  } sort_index_pair_u32;
627
622
 
@@ -638,6 +633,13 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
638
633
  positions align between iterators. */
639
634
  int8_t slab_axes[CA_RANK_MAX];
640
635
  slab_axes[0] = (int8_t) axis;
636
+ ca_size_t fiber_n = ca->dim[axis];
637
+ volatile VALUE hbuf = 0, haux = 0;
638
+ sort_index_pair_u32 *buf = ALLOCV_N(sort_index_pair_u32, hbuf, fiber_n);
639
+ sort_index_pair_u32 *aux = NULL;
640
+ if ( do_stable ) {
641
+ aux = ALLOCV_N(sort_index_pair_u32, haux, fiber_n);
642
+ }
641
643
  ca_iter_state st_in, st_out;
642
644
  int rc;
643
645
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -652,14 +654,6 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
652
654
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
653
655
  }
654
656
 
655
- ca_size_t fiber_n = st_in.slab_elements;
656
- volatile VALUE hbuf = 0, haux = 0;
657
- sort_index_pair_u32 *buf = ALLOCV_N(sort_index_pair_u32, hbuf, fiber_n);
658
- sort_index_pair_u32 *aux = NULL;
659
- if ( do_stable ) {
660
- aux = ALLOCV_N(sort_index_pair_u32, haux, fiber_n);
661
- }
662
-
663
657
  char *pi, *po;
664
658
  boolean8_t *mi, *mo;
665
659
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -676,13 +670,13 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
676
670
  if ( masked_last ) {
677
671
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
678
672
  if ( mi[k * mstride] ) continue;
679
- buf[n_valid].v = *(uint32_t *) (pi + k * istride);
673
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
680
674
  buf[n_valid].i = k;
681
675
  n_valid++;
682
676
  }
683
677
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
684
678
  if ( ! mi[k * mstride] ) continue;
685
- buf[n_valid + n_masked].v = *(uint32_t *) (pi + k * istride);
679
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
686
680
  buf[n_valid + n_masked].i = k;
687
681
  n_masked++;
688
682
  }
@@ -690,13 +684,13 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
690
684
  } else {
691
685
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
692
686
  if ( ! mi[k * mstride] ) continue;
693
- buf[n_masked].v = *(uint32_t *) (pi + k * istride);
687
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
694
688
  buf[n_masked].i = k;
695
689
  n_masked++;
696
690
  }
697
691
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
698
692
  if ( mi[k * mstride] ) continue;
699
- buf[n_masked + n_valid].v = *(uint32_t *) (pi + k * istride);
693
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
700
694
  buf[n_masked + n_valid].i = k;
701
695
  n_valid++;
702
696
  }
@@ -704,7 +698,7 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
704
698
  }
705
699
  } else {
706
700
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
707
- buf[k].v = *(uint32_t *) (pi + k * istride);
701
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
708
702
  buf[k].i = k;
709
703
  }
710
704
  sort_lo = 0; sort_n = fiber_n;
@@ -736,7 +730,7 @@ sort_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int m
736
730
  }
737
731
 
738
732
  typedef struct {
739
- int64_t v;
733
+ ca_u_int64_t v;
740
734
  ca_size_t i;
741
735
  } sort_index_pair_i64;
742
736
 
@@ -753,6 +747,13 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
753
747
  positions align between iterators. */
754
748
  int8_t slab_axes[CA_RANK_MAX];
755
749
  slab_axes[0] = (int8_t) axis;
750
+ ca_size_t fiber_n = ca->dim[axis];
751
+ volatile VALUE hbuf = 0, haux = 0;
752
+ sort_index_pair_i64 *buf = ALLOCV_N(sort_index_pair_i64, hbuf, fiber_n);
753
+ sort_index_pair_i64 *aux = NULL;
754
+ if ( do_stable ) {
755
+ aux = ALLOCV_N(sort_index_pair_i64, haux, fiber_n);
756
+ }
756
757
  ca_iter_state st_in, st_out;
757
758
  int rc;
758
759
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -767,14 +768,6 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
767
768
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
768
769
  }
769
770
 
770
- ca_size_t fiber_n = st_in.slab_elements;
771
- volatile VALUE hbuf = 0, haux = 0;
772
- sort_index_pair_i64 *buf = ALLOCV_N(sort_index_pair_i64, hbuf, fiber_n);
773
- sort_index_pair_i64 *aux = NULL;
774
- if ( do_stable ) {
775
- aux = ALLOCV_N(sort_index_pair_i64, haux, fiber_n);
776
- }
777
-
778
771
  char *pi, *po;
779
772
  boolean8_t *mi, *mo;
780
773
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -791,13 +784,13 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
791
784
  if ( masked_last ) {
792
785
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
793
786
  if ( mi[k * mstride] ) continue;
794
- buf[n_valid].v = *(int64_t *) (pi + k * istride);
787
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
795
788
  buf[n_valid].i = k;
796
789
  n_valid++;
797
790
  }
798
791
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
799
792
  if ( ! mi[k * mstride] ) continue;
800
- buf[n_valid + n_masked].v = *(int64_t *) (pi + k * istride);
793
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
801
794
  buf[n_valid + n_masked].i = k;
802
795
  n_masked++;
803
796
  }
@@ -805,13 +798,13 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
805
798
  } else {
806
799
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
807
800
  if ( ! mi[k * mstride] ) continue;
808
- buf[n_masked].v = *(int64_t *) (pi + k * istride);
801
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
809
802
  buf[n_masked].i = k;
810
803
  n_masked++;
811
804
  }
812
805
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
813
806
  if ( mi[k * mstride] ) continue;
814
- buf[n_masked + n_valid].v = *(int64_t *) (pi + k * istride);
807
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
815
808
  buf[n_masked + n_valid].i = k;
816
809
  n_valid++;
817
810
  }
@@ -819,7 +812,7 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
819
812
  }
820
813
  } else {
821
814
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
822
- buf[k].v = *(int64_t *) (pi + k * istride);
815
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
823
816
  buf[k].i = k;
824
817
  }
825
818
  sort_lo = 0; sort_n = fiber_n;
@@ -851,7 +844,7 @@ sort_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int m
851
844
  }
852
845
 
853
846
  typedef struct {
854
- uint64_t v;
847
+ ca_u_uint64_t v;
855
848
  ca_size_t i;
856
849
  } sort_index_pair_u64;
857
850
 
@@ -868,6 +861,13 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
868
861
  positions align between iterators. */
869
862
  int8_t slab_axes[CA_RANK_MAX];
870
863
  slab_axes[0] = (int8_t) axis;
864
+ ca_size_t fiber_n = ca->dim[axis];
865
+ volatile VALUE hbuf = 0, haux = 0;
866
+ sort_index_pair_u64 *buf = ALLOCV_N(sort_index_pair_u64, hbuf, fiber_n);
867
+ sort_index_pair_u64 *aux = NULL;
868
+ if ( do_stable ) {
869
+ aux = ALLOCV_N(sort_index_pair_u64, haux, fiber_n);
870
+ }
871
871
  ca_iter_state st_in, st_out;
872
872
  int rc;
873
873
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -882,14 +882,6 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
882
882
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
883
883
  }
884
884
 
885
- ca_size_t fiber_n = st_in.slab_elements;
886
- volatile VALUE hbuf = 0, haux = 0;
887
- sort_index_pair_u64 *buf = ALLOCV_N(sort_index_pair_u64, hbuf, fiber_n);
888
- sort_index_pair_u64 *aux = NULL;
889
- if ( do_stable ) {
890
- aux = ALLOCV_N(sort_index_pair_u64, haux, fiber_n);
891
- }
892
-
893
885
  char *pi, *po;
894
886
  boolean8_t *mi, *mo;
895
887
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -906,13 +898,13 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
906
898
  if ( masked_last ) {
907
899
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
908
900
  if ( mi[k * mstride] ) continue;
909
- buf[n_valid].v = *(uint64_t *) (pi + k * istride);
901
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
910
902
  buf[n_valid].i = k;
911
903
  n_valid++;
912
904
  }
913
905
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
914
906
  if ( ! mi[k * mstride] ) continue;
915
- buf[n_valid + n_masked].v = *(uint64_t *) (pi + k * istride);
907
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
916
908
  buf[n_valid + n_masked].i = k;
917
909
  n_masked++;
918
910
  }
@@ -920,13 +912,13 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
920
912
  } else {
921
913
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
922
914
  if ( ! mi[k * mstride] ) continue;
923
- buf[n_masked].v = *(uint64_t *) (pi + k * istride);
915
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
924
916
  buf[n_masked].i = k;
925
917
  n_masked++;
926
918
  }
927
919
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
928
920
  if ( mi[k * mstride] ) continue;
929
- buf[n_masked + n_valid].v = *(uint64_t *) (pi + k * istride);
921
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
930
922
  buf[n_masked + n_valid].i = k;
931
923
  n_valid++;
932
924
  }
@@ -934,7 +926,7 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
934
926
  }
935
927
  } else {
936
928
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
937
- buf[k].v = *(uint64_t *) (pi + k * istride);
929
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
938
930
  buf[k].i = k;
939
931
  }
940
932
  sort_lo = 0; sort_n = fiber_n;
@@ -966,7 +958,7 @@ sort_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int m
966
958
  }
967
959
 
968
960
  typedef struct {
969
- float v;
961
+ ca_u_float32_t v;
970
962
  ca_size_t i;
971
963
  } sort_index_pair_f32;
972
964
 
@@ -983,6 +975,10 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
983
975
  positions align between iterators. */
984
976
  int8_t slab_axes[CA_RANK_MAX];
985
977
  slab_axes[0] = (int8_t) axis;
978
+ ca_size_t fiber_n = ca->dim[axis];
979
+ volatile VALUE hbuf = 0, haux = 0;
980
+ sort_index_pair_f32 *buf = ALLOCV_N(sort_index_pair_f32, hbuf, fiber_n);
981
+ sort_index_pair_f32 *aux = ALLOCV_N(sort_index_pair_f32, haux, fiber_n);
986
982
  ca_iter_state st_in, st_out;
987
983
  int rc;
988
984
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -997,14 +993,6 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
997
993
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
998
994
  }
999
995
 
1000
- ca_size_t fiber_n = st_in.slab_elements;
1001
- volatile VALUE hbuf = 0, haux = 0;
1002
- sort_index_pair_f32 *buf = ALLOCV_N(sort_index_pair_f32, hbuf, fiber_n);
1003
- sort_index_pair_f32 *aux = NULL;
1004
- if ( do_stable ) {
1005
- aux = ALLOCV_N(sort_index_pair_f32, haux, fiber_n);
1006
- }
1007
-
1008
996
  char *pi, *po;
1009
997
  boolean8_t *mi, *mo;
1010
998
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1021,13 +1009,13 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1021
1009
  if ( masked_last ) {
1022
1010
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1023
1011
  if ( mi[k * mstride] ) continue;
1024
- buf[n_valid].v = *(float *) (pi + k * istride);
1012
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1025
1013
  buf[n_valid].i = k;
1026
1014
  n_valid++;
1027
1015
  }
1028
1016
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1029
1017
  if ( ! mi[k * mstride] ) continue;
1030
- buf[n_valid + n_masked].v = *(float *) (pi + k * istride);
1018
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1031
1019
  buf[n_valid + n_masked].i = k;
1032
1020
  n_masked++;
1033
1021
  }
@@ -1035,13 +1023,13 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1035
1023
  } else {
1036
1024
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1037
1025
  if ( ! mi[k * mstride] ) continue;
1038
- buf[n_masked].v = *(float *) (pi + k * istride);
1026
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1039
1027
  buf[n_masked].i = k;
1040
1028
  n_masked++;
1041
1029
  }
1042
1030
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1043
1031
  if ( mi[k * mstride] ) continue;
1044
- buf[n_masked + n_valid].v = *(float *) (pi + k * istride);
1032
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1045
1033
  buf[n_masked + n_valid].i = k;
1046
1034
  n_valid++;
1047
1035
  }
@@ -1049,7 +1037,7 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1049
1037
  }
1050
1038
  } else {
1051
1039
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1052
- buf[k].v = *(float *) (pi + k * istride);
1040
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1053
1041
  buf[k].i = k;
1054
1042
  }
1055
1043
  sort_lo = 0; sort_n = fiber_n;
@@ -1065,7 +1053,7 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1065
1053
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
1066
1054
  pushed to the tail (= NaN-at-end policy, matches sort_copy
1067
1055
  AC8). Only the finite slice is sorted. */
1068
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n);
1056
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f32 *) aux);
1069
1057
  if ( do_stable ) {
1070
1058
  ca_sort_merge_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_pair_f32 *) aux, finite_n);
1071
1059
  } else {
@@ -1085,7 +1073,7 @@ sort_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int m
1085
1073
  }
1086
1074
 
1087
1075
  typedef struct {
1088
- double v;
1076
+ ca_u_float64_t v;
1089
1077
  ca_size_t i;
1090
1078
  } sort_index_pair_f64;
1091
1079
 
@@ -1102,6 +1090,10 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1102
1090
  positions align between iterators. */
1103
1091
  int8_t slab_axes[CA_RANK_MAX];
1104
1092
  slab_axes[0] = (int8_t) axis;
1093
+ ca_size_t fiber_n = ca->dim[axis];
1094
+ volatile VALUE hbuf = 0, haux = 0;
1095
+ sort_index_pair_f64 *buf = ALLOCV_N(sort_index_pair_f64, hbuf, fiber_n);
1096
+ sort_index_pair_f64 *aux = ALLOCV_N(sort_index_pair_f64, haux, fiber_n);
1105
1097
  ca_iter_state st_in, st_out;
1106
1098
  int rc;
1107
1099
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1116,14 +1108,6 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1116
1108
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1117
1109
  }
1118
1110
 
1119
- ca_size_t fiber_n = st_in.slab_elements;
1120
- volatile VALUE hbuf = 0, haux = 0;
1121
- sort_index_pair_f64 *buf = ALLOCV_N(sort_index_pair_f64, hbuf, fiber_n);
1122
- sort_index_pair_f64 *aux = NULL;
1123
- if ( do_stable ) {
1124
- aux = ALLOCV_N(sort_index_pair_f64, haux, fiber_n);
1125
- }
1126
-
1127
1111
  char *pi, *po;
1128
1112
  boolean8_t *mi, *mo;
1129
1113
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1140,13 +1124,13 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1140
1124
  if ( masked_last ) {
1141
1125
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1142
1126
  if ( mi[k * mstride] ) continue;
1143
- buf[n_valid].v = *(double *) (pi + k * istride);
1127
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1144
1128
  buf[n_valid].i = k;
1145
1129
  n_valid++;
1146
1130
  }
1147
1131
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1148
1132
  if ( ! mi[k * mstride] ) continue;
1149
- buf[n_valid + n_masked].v = *(double *) (pi + k * istride);
1133
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1150
1134
  buf[n_valid + n_masked].i = k;
1151
1135
  n_masked++;
1152
1136
  }
@@ -1154,13 +1138,13 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1154
1138
  } else {
1155
1139
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1156
1140
  if ( ! mi[k * mstride] ) continue;
1157
- buf[n_masked].v = *(double *) (pi + k * istride);
1141
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1158
1142
  buf[n_masked].i = k;
1159
1143
  n_masked++;
1160
1144
  }
1161
1145
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1162
1146
  if ( mi[k * mstride] ) continue;
1163
- buf[n_masked + n_valid].v = *(double *) (pi + k * istride);
1147
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1164
1148
  buf[n_masked + n_valid].i = k;
1165
1149
  n_valid++;
1166
1150
  }
@@ -1168,7 +1152,7 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1168
1152
  }
1169
1153
  } else {
1170
1154
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1171
- buf[k].v = *(double *) (pi + k * istride);
1155
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1172
1156
  buf[k].i = k;
1173
1157
  }
1174
1158
  sort_lo = 0; sort_n = fiber_n;
@@ -1184,7 +1168,7 @@ sort_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int m
1184
1168
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
1185
1169
  pushed to the tail (= NaN-at-end policy, matches sort_copy
1186
1170
  AC8). Only the finite slice is sorted. */
1187
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n);
1171
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f64 *) aux);
1188
1172
  if ( do_stable ) {
1189
1173
  ca_sort_merge_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_pair_f64 *) aux, finite_n);
1190
1174
  } else {
@@ -1221,6 +1205,13 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1221
1205
  positions align between iterators. */
1222
1206
  int8_t slab_axes[CA_RANK_MAX];
1223
1207
  slab_axes[0] = (int8_t) axis;
1208
+ ca_size_t fiber_n = ca->dim[axis];
1209
+ volatile VALUE hbuf = 0, haux = 0;
1210
+ sort_index_pair_bool *buf = ALLOCV_N(sort_index_pair_bool, hbuf, fiber_n);
1211
+ sort_index_pair_bool *aux = NULL;
1212
+ if ( do_stable ) {
1213
+ aux = ALLOCV_N(sort_index_pair_bool, haux, fiber_n);
1214
+ }
1224
1215
  ca_iter_state st_in, st_out;
1225
1216
  int rc;
1226
1217
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1235,14 +1226,6 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1235
1226
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1236
1227
  }
1237
1228
 
1238
- ca_size_t fiber_n = st_in.slab_elements;
1239
- volatile VALUE hbuf = 0, haux = 0;
1240
- sort_index_pair_bool *buf = ALLOCV_N(sort_index_pair_bool, hbuf, fiber_n);
1241
- sort_index_pair_bool *aux = NULL;
1242
- if ( do_stable ) {
1243
- aux = ALLOCV_N(sort_index_pair_bool, haux, fiber_n);
1244
- }
1245
-
1246
1229
  char *pi, *po;
1247
1230
  boolean8_t *mi, *mo;
1248
1231
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1259,13 +1242,13 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1259
1242
  if ( masked_last ) {
1260
1243
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1261
1244
  if ( mi[k * mstride] ) continue;
1262
- buf[n_valid].v = *(boolean8_t *) (pi + k * istride);
1245
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1263
1246
  buf[n_valid].i = k;
1264
1247
  n_valid++;
1265
1248
  }
1266
1249
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1267
1250
  if ( ! mi[k * mstride] ) continue;
1268
- buf[n_valid + n_masked].v = *(boolean8_t *) (pi + k * istride);
1251
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1269
1252
  buf[n_valid + n_masked].i = k;
1270
1253
  n_masked++;
1271
1254
  }
@@ -1273,13 +1256,13 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1273
1256
  } else {
1274
1257
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1275
1258
  if ( ! mi[k * mstride] ) continue;
1276
- buf[n_masked].v = *(boolean8_t *) (pi + k * istride);
1259
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1277
1260
  buf[n_masked].i = k;
1278
1261
  n_masked++;
1279
1262
  }
1280
1263
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1281
1264
  if ( mi[k * mstride] ) continue;
1282
- buf[n_masked + n_valid].v = *(boolean8_t *) (pi + k * istride);
1265
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1283
1266
  buf[n_masked + n_valid].i = k;
1284
1267
  n_valid++;
1285
1268
  }
@@ -1287,7 +1270,7 @@ sort_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
1287
1270
  }
1288
1271
  } else {
1289
1272
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1290
- buf[k].v = *(boolean8_t *) (pi + k * istride);
1273
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1291
1274
  buf[k].i = k;
1292
1275
  }
1293
1276
  sort_lo = 0; sort_n = fiber_n;
@@ -1336,9 +1319,9 @@ sort_index_cmp_object (const void *a, const void *b)
1336
1319
  return 0;
1337
1320
  }
1338
1321
 
1339
- /* The object lane calls Ruby for every cell, so a walk can raise part
1340
- way. Its states live in the caller's frame, and ca_iter_ensure
1341
- finishes them however the body leaves. */
1322
+ /* The walks can raise part way (a Ruby call per cell in the object
1323
+ lane, an allocation in any lane). Their states live in the caller's
1324
+ frame, and ca_iter_ensure finishes them however the body leaves. */
1342
1325
  typedef struct {
1343
1326
  ca_iter_state states[2];
1344
1327
  VALUE self;
@@ -1374,6 +1357,10 @@ sort_index_ki_native_object_body (VALUE arg)
1374
1357
  positions align between iterators. */
1375
1358
  int8_t slab_axes[CA_RANK_MAX];
1376
1359
  slab_axes[0] = (int8_t) axis;
1360
+ ca_size_t fiber_n = ca->dim[axis];
1361
+ volatile VALUE hbuf = 0, haux = 0;
1362
+ sort_index_pair_object *buf = ALLOCV_N(sort_index_pair_object, hbuf, fiber_n);
1363
+ sort_index_pair_object *aux = ALLOCV_N(sort_index_pair_object, haux, fiber_n);
1377
1364
  int rc;
1378
1365
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
1379
1366
  slab_axes, 1, 0);
@@ -1387,11 +1374,6 @@ sort_index_ki_native_object_body (VALUE arg)
1387
1374
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1388
1375
  }
1389
1376
 
1390
- ca_size_t fiber_n = st_in.slab_elements;
1391
- volatile VALUE hbuf = 0, haux = 0;
1392
- sort_index_pair_object *buf = ALLOCV_N(sort_index_pair_object, hbuf, fiber_n);
1393
- sort_index_pair_object *aux = ALLOCV_N(sort_index_pair_object, haux, fiber_n);
1394
-
1395
1377
  char *pi, *po;
1396
1378
  boolean8_t *mi, *mo;
1397
1379
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1408,13 +1390,13 @@ sort_index_ki_native_object_body (VALUE arg)
1408
1390
  if ( masked_last ) {
1409
1391
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1410
1392
  if ( mi[k * mstride] ) continue;
1411
- buf[n_valid].v = *(VALUE *) (pi + k * istride);
1393
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1412
1394
  buf[n_valid].i = k;
1413
1395
  n_valid++;
1414
1396
  }
1415
1397
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1416
1398
  if ( ! mi[k * mstride] ) continue;
1417
- buf[n_valid + n_masked].v = *(VALUE *) (pi + k * istride);
1399
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1418
1400
  buf[n_valid + n_masked].i = k;
1419
1401
  n_masked++;
1420
1402
  }
@@ -1422,13 +1404,13 @@ sort_index_ki_native_object_body (VALUE arg)
1422
1404
  } else {
1423
1405
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1424
1406
  if ( ! mi[k * mstride] ) continue;
1425
- buf[n_masked].v = *(VALUE *) (pi + k * istride);
1407
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1426
1408
  buf[n_masked].i = k;
1427
1409
  n_masked++;
1428
1410
  }
1429
1411
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1430
1412
  if ( mi[k * mstride] ) continue;
1431
- buf[n_masked + n_valid].v = *(VALUE *) (pi + k * istride);
1413
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1432
1414
  buf[n_masked + n_valid].i = k;
1433
1415
  n_valid++;
1434
1416
  }
@@ -1436,7 +1418,7 @@ sort_index_ki_native_object_body (VALUE arg)
1436
1418
  }
1437
1419
  } else {
1438
1420
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1439
- buf[k].v = *(VALUE *) (pi + k * istride);
1421
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1440
1422
  buf[k].i = k;
1441
1423
  }
1442
1424
  sort_lo = 0; sort_n = fiber_n;
@@ -1475,7 +1457,7 @@ sort_index_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, in
1475
1457
  fr.axis = axis;
1476
1458
  fr.do_stable = do_stable;
1477
1459
  fr.masked_last = masked_last;
1478
- return ca_iter_ensure(2, fr.states, sort_index_ki_native_object_body, (VALUE) &fr);
1460
+ return ca_iter_ensure_computing(ca, 2, fr.states, sort_index_ki_native_object_body, (VALUE) &fr);
1479
1461
  }
1480
1462
 
1481
1463
 
@@ -1511,6 +1493,10 @@ sort_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
1511
1493
  positions align between iterators. */
1512
1494
  int8_t slab_axes[CA_RANK_MAX];
1513
1495
  slab_axes[0] = (int8_t) axis;
1496
+ ca_size_t fiber_n = ca->dim[axis];
1497
+ volatile VALUE hbuf = 0, haux = 0;
1498
+ sort_index_pair_fixlen *buf = ALLOCV_N(sort_index_pair_fixlen, hbuf, fiber_n);
1499
+ (void) haux;
1514
1500
  ca_iter_state st_in, st_out;
1515
1501
  int rc;
1516
1502
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1525,14 +1511,6 @@ sort_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
1525
1511
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1526
1512
  }
1527
1513
 
1528
- ca_size_t fiber_n = st_in.slab_elements;
1529
- volatile VALUE hbuf = 0, haux = 0;
1530
- sort_index_pair_fixlen *buf = ALLOCV_N(sort_index_pair_fixlen, hbuf, fiber_n);
1531
- sort_index_pair_fixlen *aux = NULL;
1532
- if ( do_stable ) {
1533
- aux = ALLOCV_N(sort_index_pair_fixlen, haux, fiber_n);
1534
- }
1535
-
1536
1514
  char *pi, *po;
1537
1515
  boolean8_t *mi, *mo;
1538
1516
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -1713,6 +1691,13 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1713
1691
  positions align between iterators. */
1714
1692
  int8_t slab_axes[CA_RANK_MAX];
1715
1693
  slab_axes[0] = (int8_t) axis;
1694
+ ca_size_t fiber_n = ca->dim[axis];
1695
+ volatile VALUE hbuf = 0, haux = 0;
1696
+ sort_addr_pair_i8 *buf = ALLOCV_N(sort_addr_pair_i8, hbuf, fiber_n);
1697
+ sort_addr_pair_i8 *aux = NULL;
1698
+ if ( do_stable ) {
1699
+ aux = ALLOCV_N(sort_addr_pair_i8, haux, fiber_n);
1700
+ }
1716
1701
  ca_iter_state st_in, st_out;
1717
1702
  int rc;
1718
1703
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1727,14 +1712,6 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1727
1712
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1728
1713
  }
1729
1714
 
1730
- ca_size_t fiber_n = st_in.slab_elements;
1731
- volatile VALUE hbuf = 0, haux = 0;
1732
- sort_addr_pair_i8 *buf = ALLOCV_N(sort_addr_pair_i8, hbuf, fiber_n);
1733
- sort_addr_pair_i8 *aux = NULL;
1734
- if ( do_stable ) {
1735
- aux = ALLOCV_N(sort_addr_pair_i8, haux, fiber_n);
1736
- }
1737
-
1738
1715
  /* :view_flat semantics: kernel computes view-flat address
1739
1716
  (= row-major position in ca's shape, 0..elements-1) for
1740
1717
  each cell. Used to feed CARemap.idx directly (= sort
@@ -1778,13 +1755,13 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1778
1755
  if ( masked_last ) {
1779
1756
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1780
1757
  if ( mi[k * mstride] ) continue;
1781
- buf[n_valid].v = *(int8_t *) (pi + k * istride);
1758
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1782
1759
  buf[n_valid].i = outer_off + k * axis_vstride;
1783
1760
  n_valid++;
1784
1761
  }
1785
1762
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1786
1763
  if ( ! mi[k * mstride] ) continue;
1787
- buf[n_valid + n_masked].v = *(int8_t *) (pi + k * istride);
1764
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1788
1765
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
1789
1766
  n_masked++;
1790
1767
  }
@@ -1792,13 +1769,13 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1792
1769
  } else {
1793
1770
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1794
1771
  if ( ! mi[k * mstride] ) continue;
1795
- buf[n_masked].v = *(int8_t *) (pi + k * istride);
1772
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1796
1773
  buf[n_masked].i = outer_off + k * axis_vstride;
1797
1774
  n_masked++;
1798
1775
  }
1799
1776
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1800
1777
  if ( mi[k * mstride] ) continue;
1801
- buf[n_masked + n_valid].v = *(int8_t *) (pi + k * istride);
1778
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1802
1779
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
1803
1780
  n_valid++;
1804
1781
  }
@@ -1806,7 +1783,7 @@ sort_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1806
1783
  }
1807
1784
  } else {
1808
1785
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1809
- buf[k].v = *(int8_t *) (pi + k * istride);
1786
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1810
1787
  buf[k].i = outer_off + k * axis_vstride;
1811
1788
  }
1812
1789
  sort_lo = 0; sort_n = fiber_n;
@@ -1860,6 +1837,13 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1860
1837
  positions align between iterators. */
1861
1838
  int8_t slab_axes[CA_RANK_MAX];
1862
1839
  slab_axes[0] = (int8_t) axis;
1840
+ ca_size_t fiber_n = ca->dim[axis];
1841
+ volatile VALUE hbuf = 0, haux = 0;
1842
+ sort_addr_pair_u8 *buf = ALLOCV_N(sort_addr_pair_u8, hbuf, fiber_n);
1843
+ sort_addr_pair_u8 *aux = NULL;
1844
+ if ( do_stable ) {
1845
+ aux = ALLOCV_N(sort_addr_pair_u8, haux, fiber_n);
1846
+ }
1863
1847
  ca_iter_state st_in, st_out;
1864
1848
  int rc;
1865
1849
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -1874,14 +1858,6 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1874
1858
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
1875
1859
  }
1876
1860
 
1877
- ca_size_t fiber_n = st_in.slab_elements;
1878
- volatile VALUE hbuf = 0, haux = 0;
1879
- sort_addr_pair_u8 *buf = ALLOCV_N(sort_addr_pair_u8, hbuf, fiber_n);
1880
- sort_addr_pair_u8 *aux = NULL;
1881
- if ( do_stable ) {
1882
- aux = ALLOCV_N(sort_addr_pair_u8, haux, fiber_n);
1883
- }
1884
-
1885
1861
  /* :view_flat semantics: kernel computes view-flat address
1886
1862
  (= row-major position in ca's shape, 0..elements-1) for
1887
1863
  each cell. Used to feed CARemap.idx directly (= sort
@@ -1925,13 +1901,13 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1925
1901
  if ( masked_last ) {
1926
1902
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1927
1903
  if ( mi[k * mstride] ) continue;
1928
- buf[n_valid].v = *(uint8_t *) (pi + k * istride);
1904
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
1929
1905
  buf[n_valid].i = outer_off + k * axis_vstride;
1930
1906
  n_valid++;
1931
1907
  }
1932
1908
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1933
1909
  if ( ! mi[k * mstride] ) continue;
1934
- buf[n_valid + n_masked].v = *(uint8_t *) (pi + k * istride);
1910
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
1935
1911
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
1936
1912
  n_masked++;
1937
1913
  }
@@ -1939,13 +1915,13 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1939
1915
  } else {
1940
1916
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1941
1917
  if ( ! mi[k * mstride] ) continue;
1942
- buf[n_masked].v = *(uint8_t *) (pi + k * istride);
1918
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
1943
1919
  buf[n_masked].i = outer_off + k * axis_vstride;
1944
1920
  n_masked++;
1945
1921
  }
1946
1922
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1947
1923
  if ( mi[k * mstride] ) continue;
1948
- buf[n_masked + n_valid].v = *(uint8_t *) (pi + k * istride);
1924
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
1949
1925
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
1950
1926
  n_valid++;
1951
1927
  }
@@ -1953,7 +1929,7 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1953
1929
  }
1954
1930
  } else {
1955
1931
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
1956
- buf[k].v = *(uint8_t *) (pi + k * istride);
1932
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
1957
1933
  buf[k].i = outer_off + k * axis_vstride;
1958
1934
  }
1959
1935
  sort_lo = 0; sort_n = fiber_n;
@@ -1990,7 +1966,7 @@ sort_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int mas
1990
1966
  }
1991
1967
 
1992
1968
  typedef struct {
1993
- int16_t v;
1969
+ ca_u_int16_t v;
1994
1970
  ca_size_t i;
1995
1971
  } sort_addr_pair_i16;
1996
1972
 
@@ -2007,6 +1983,13 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2007
1983
  positions align between iterators. */
2008
1984
  int8_t slab_axes[CA_RANK_MAX];
2009
1985
  slab_axes[0] = (int8_t) axis;
1986
+ ca_size_t fiber_n = ca->dim[axis];
1987
+ volatile VALUE hbuf = 0, haux = 0;
1988
+ sort_addr_pair_i16 *buf = ALLOCV_N(sort_addr_pair_i16, hbuf, fiber_n);
1989
+ sort_addr_pair_i16 *aux = NULL;
1990
+ if ( do_stable ) {
1991
+ aux = ALLOCV_N(sort_addr_pair_i16, haux, fiber_n);
1992
+ }
2010
1993
  ca_iter_state st_in, st_out;
2011
1994
  int rc;
2012
1995
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2021,14 +2004,6 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2021
2004
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2022
2005
  }
2023
2006
 
2024
- ca_size_t fiber_n = st_in.slab_elements;
2025
- volatile VALUE hbuf = 0, haux = 0;
2026
- sort_addr_pair_i16 *buf = ALLOCV_N(sort_addr_pair_i16, hbuf, fiber_n);
2027
- sort_addr_pair_i16 *aux = NULL;
2028
- if ( do_stable ) {
2029
- aux = ALLOCV_N(sort_addr_pair_i16, haux, fiber_n);
2030
- }
2031
-
2032
2007
  /* :view_flat semantics: kernel computes view-flat address
2033
2008
  (= row-major position in ca's shape, 0..elements-1) for
2034
2009
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2072,13 +2047,13 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2072
2047
  if ( masked_last ) {
2073
2048
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2074
2049
  if ( mi[k * mstride] ) continue;
2075
- buf[n_valid].v = *(int16_t *) (pi + k * istride);
2050
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2076
2051
  buf[n_valid].i = outer_off + k * axis_vstride;
2077
2052
  n_valid++;
2078
2053
  }
2079
2054
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2080
2055
  if ( ! mi[k * mstride] ) continue;
2081
- buf[n_valid + n_masked].v = *(int16_t *) (pi + k * istride);
2056
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2082
2057
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2083
2058
  n_masked++;
2084
2059
  }
@@ -2086,13 +2061,13 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2086
2061
  } else {
2087
2062
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2088
2063
  if ( ! mi[k * mstride] ) continue;
2089
- buf[n_masked].v = *(int16_t *) (pi + k * istride);
2064
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2090
2065
  buf[n_masked].i = outer_off + k * axis_vstride;
2091
2066
  n_masked++;
2092
2067
  }
2093
2068
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2094
2069
  if ( mi[k * mstride] ) continue;
2095
- buf[n_masked + n_valid].v = *(int16_t *) (pi + k * istride);
2070
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2096
2071
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2097
2072
  n_valid++;
2098
2073
  }
@@ -2100,7 +2075,7 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2100
2075
  }
2101
2076
  } else {
2102
2077
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2103
- buf[k].v = *(int16_t *) (pi + k * istride);
2078
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2104
2079
  buf[k].i = outer_off + k * axis_vstride;
2105
2080
  }
2106
2081
  sort_lo = 0; sort_n = fiber_n;
@@ -2137,7 +2112,7 @@ sort_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2137
2112
  }
2138
2113
 
2139
2114
  typedef struct {
2140
- uint16_t v;
2115
+ ca_u_uint16_t v;
2141
2116
  ca_size_t i;
2142
2117
  } sort_addr_pair_u16;
2143
2118
 
@@ -2154,6 +2129,13 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2154
2129
  positions align between iterators. */
2155
2130
  int8_t slab_axes[CA_RANK_MAX];
2156
2131
  slab_axes[0] = (int8_t) axis;
2132
+ ca_size_t fiber_n = ca->dim[axis];
2133
+ volatile VALUE hbuf = 0, haux = 0;
2134
+ sort_addr_pair_u16 *buf = ALLOCV_N(sort_addr_pair_u16, hbuf, fiber_n);
2135
+ sort_addr_pair_u16 *aux = NULL;
2136
+ if ( do_stable ) {
2137
+ aux = ALLOCV_N(sort_addr_pair_u16, haux, fiber_n);
2138
+ }
2157
2139
  ca_iter_state st_in, st_out;
2158
2140
  int rc;
2159
2141
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2168,14 +2150,6 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2168
2150
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2169
2151
  }
2170
2152
 
2171
- ca_size_t fiber_n = st_in.slab_elements;
2172
- volatile VALUE hbuf = 0, haux = 0;
2173
- sort_addr_pair_u16 *buf = ALLOCV_N(sort_addr_pair_u16, hbuf, fiber_n);
2174
- sort_addr_pair_u16 *aux = NULL;
2175
- if ( do_stable ) {
2176
- aux = ALLOCV_N(sort_addr_pair_u16, haux, fiber_n);
2177
- }
2178
-
2179
2153
  /* :view_flat semantics: kernel computes view-flat address
2180
2154
  (= row-major position in ca's shape, 0..elements-1) for
2181
2155
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2219,13 +2193,13 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2219
2193
  if ( masked_last ) {
2220
2194
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2221
2195
  if ( mi[k * mstride] ) continue;
2222
- buf[n_valid].v = *(uint16_t *) (pi + k * istride);
2196
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2223
2197
  buf[n_valid].i = outer_off + k * axis_vstride;
2224
2198
  n_valid++;
2225
2199
  }
2226
2200
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2227
2201
  if ( ! mi[k * mstride] ) continue;
2228
- buf[n_valid + n_masked].v = *(uint16_t *) (pi + k * istride);
2202
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2229
2203
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2230
2204
  n_masked++;
2231
2205
  }
@@ -2233,13 +2207,13 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2233
2207
  } else {
2234
2208
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2235
2209
  if ( ! mi[k * mstride] ) continue;
2236
- buf[n_masked].v = *(uint16_t *) (pi + k * istride);
2210
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2237
2211
  buf[n_masked].i = outer_off + k * axis_vstride;
2238
2212
  n_masked++;
2239
2213
  }
2240
2214
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2241
2215
  if ( mi[k * mstride] ) continue;
2242
- buf[n_masked + n_valid].v = *(uint16_t *) (pi + k * istride);
2216
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2243
2217
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2244
2218
  n_valid++;
2245
2219
  }
@@ -2247,7 +2221,7 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2247
2221
  }
2248
2222
  } else {
2249
2223
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2250
- buf[k].v = *(uint16_t *) (pi + k * istride);
2224
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2251
2225
  buf[k].i = outer_off + k * axis_vstride;
2252
2226
  }
2253
2227
  sort_lo = 0; sort_n = fiber_n;
@@ -2284,7 +2258,7 @@ sort_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2284
2258
  }
2285
2259
 
2286
2260
  typedef struct {
2287
- int32_t v;
2261
+ ca_u_int32_t v;
2288
2262
  ca_size_t i;
2289
2263
  } sort_addr_pair_i32;
2290
2264
 
@@ -2301,6 +2275,13 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2301
2275
  positions align between iterators. */
2302
2276
  int8_t slab_axes[CA_RANK_MAX];
2303
2277
  slab_axes[0] = (int8_t) axis;
2278
+ ca_size_t fiber_n = ca->dim[axis];
2279
+ volatile VALUE hbuf = 0, haux = 0;
2280
+ sort_addr_pair_i32 *buf = ALLOCV_N(sort_addr_pair_i32, hbuf, fiber_n);
2281
+ sort_addr_pair_i32 *aux = NULL;
2282
+ if ( do_stable ) {
2283
+ aux = ALLOCV_N(sort_addr_pair_i32, haux, fiber_n);
2284
+ }
2304
2285
  ca_iter_state st_in, st_out;
2305
2286
  int rc;
2306
2287
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2315,14 +2296,6 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2315
2296
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2316
2297
  }
2317
2298
 
2318
- ca_size_t fiber_n = st_in.slab_elements;
2319
- volatile VALUE hbuf = 0, haux = 0;
2320
- sort_addr_pair_i32 *buf = ALLOCV_N(sort_addr_pair_i32, hbuf, fiber_n);
2321
- sort_addr_pair_i32 *aux = NULL;
2322
- if ( do_stable ) {
2323
- aux = ALLOCV_N(sort_addr_pair_i32, haux, fiber_n);
2324
- }
2325
-
2326
2299
  /* :view_flat semantics: kernel computes view-flat address
2327
2300
  (= row-major position in ca's shape, 0..elements-1) for
2328
2301
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2366,13 +2339,13 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2366
2339
  if ( masked_last ) {
2367
2340
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2368
2341
  if ( mi[k * mstride] ) continue;
2369
- buf[n_valid].v = *(int32_t *) (pi + k * istride);
2342
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2370
2343
  buf[n_valid].i = outer_off + k * axis_vstride;
2371
2344
  n_valid++;
2372
2345
  }
2373
2346
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2374
2347
  if ( ! mi[k * mstride] ) continue;
2375
- buf[n_valid + n_masked].v = *(int32_t *) (pi + k * istride);
2348
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2376
2349
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2377
2350
  n_masked++;
2378
2351
  }
@@ -2380,13 +2353,13 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2380
2353
  } else {
2381
2354
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2382
2355
  if ( ! mi[k * mstride] ) continue;
2383
- buf[n_masked].v = *(int32_t *) (pi + k * istride);
2356
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2384
2357
  buf[n_masked].i = outer_off + k * axis_vstride;
2385
2358
  n_masked++;
2386
2359
  }
2387
2360
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2388
2361
  if ( mi[k * mstride] ) continue;
2389
- buf[n_masked + n_valid].v = *(int32_t *) (pi + k * istride);
2362
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2390
2363
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2391
2364
  n_valid++;
2392
2365
  }
@@ -2394,7 +2367,7 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2394
2367
  }
2395
2368
  } else {
2396
2369
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2397
- buf[k].v = *(int32_t *) (pi + k * istride);
2370
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2398
2371
  buf[k].i = outer_off + k * axis_vstride;
2399
2372
  }
2400
2373
  sort_lo = 0; sort_n = fiber_n;
@@ -2431,7 +2404,7 @@ sort_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2431
2404
  }
2432
2405
 
2433
2406
  typedef struct {
2434
- uint32_t v;
2407
+ ca_u_uint32_t v;
2435
2408
  ca_size_t i;
2436
2409
  } sort_addr_pair_u32;
2437
2410
 
@@ -2448,6 +2421,13 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2448
2421
  positions align between iterators. */
2449
2422
  int8_t slab_axes[CA_RANK_MAX];
2450
2423
  slab_axes[0] = (int8_t) axis;
2424
+ ca_size_t fiber_n = ca->dim[axis];
2425
+ volatile VALUE hbuf = 0, haux = 0;
2426
+ sort_addr_pair_u32 *buf = ALLOCV_N(sort_addr_pair_u32, hbuf, fiber_n);
2427
+ sort_addr_pair_u32 *aux = NULL;
2428
+ if ( do_stable ) {
2429
+ aux = ALLOCV_N(sort_addr_pair_u32, haux, fiber_n);
2430
+ }
2451
2431
  ca_iter_state st_in, st_out;
2452
2432
  int rc;
2453
2433
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2462,14 +2442,6 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2462
2442
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2463
2443
  }
2464
2444
 
2465
- ca_size_t fiber_n = st_in.slab_elements;
2466
- volatile VALUE hbuf = 0, haux = 0;
2467
- sort_addr_pair_u32 *buf = ALLOCV_N(sort_addr_pair_u32, hbuf, fiber_n);
2468
- sort_addr_pair_u32 *aux = NULL;
2469
- if ( do_stable ) {
2470
- aux = ALLOCV_N(sort_addr_pair_u32, haux, fiber_n);
2471
- }
2472
-
2473
2445
  /* :view_flat semantics: kernel computes view-flat address
2474
2446
  (= row-major position in ca's shape, 0..elements-1) for
2475
2447
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2513,13 +2485,13 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2513
2485
  if ( masked_last ) {
2514
2486
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2515
2487
  if ( mi[k * mstride] ) continue;
2516
- buf[n_valid].v = *(uint32_t *) (pi + k * istride);
2488
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2517
2489
  buf[n_valid].i = outer_off + k * axis_vstride;
2518
2490
  n_valid++;
2519
2491
  }
2520
2492
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2521
2493
  if ( ! mi[k * mstride] ) continue;
2522
- buf[n_valid + n_masked].v = *(uint32_t *) (pi + k * istride);
2494
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2523
2495
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2524
2496
  n_masked++;
2525
2497
  }
@@ -2527,13 +2499,13 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2527
2499
  } else {
2528
2500
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2529
2501
  if ( ! mi[k * mstride] ) continue;
2530
- buf[n_masked].v = *(uint32_t *) (pi + k * istride);
2502
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2531
2503
  buf[n_masked].i = outer_off + k * axis_vstride;
2532
2504
  n_masked++;
2533
2505
  }
2534
2506
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2535
2507
  if ( mi[k * mstride] ) continue;
2536
- buf[n_masked + n_valid].v = *(uint32_t *) (pi + k * istride);
2508
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2537
2509
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2538
2510
  n_valid++;
2539
2511
  }
@@ -2541,7 +2513,7 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2541
2513
  }
2542
2514
  } else {
2543
2515
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2544
- buf[k].v = *(uint32_t *) (pi + k * istride);
2516
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2545
2517
  buf[k].i = outer_off + k * axis_vstride;
2546
2518
  }
2547
2519
  sort_lo = 0; sort_n = fiber_n;
@@ -2578,7 +2550,7 @@ sort_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2578
2550
  }
2579
2551
 
2580
2552
  typedef struct {
2581
- int64_t v;
2553
+ ca_u_int64_t v;
2582
2554
  ca_size_t i;
2583
2555
  } sort_addr_pair_i64;
2584
2556
 
@@ -2595,6 +2567,13 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2595
2567
  positions align between iterators. */
2596
2568
  int8_t slab_axes[CA_RANK_MAX];
2597
2569
  slab_axes[0] = (int8_t) axis;
2570
+ ca_size_t fiber_n = ca->dim[axis];
2571
+ volatile VALUE hbuf = 0, haux = 0;
2572
+ sort_addr_pair_i64 *buf = ALLOCV_N(sort_addr_pair_i64, hbuf, fiber_n);
2573
+ sort_addr_pair_i64 *aux = NULL;
2574
+ if ( do_stable ) {
2575
+ aux = ALLOCV_N(sort_addr_pair_i64, haux, fiber_n);
2576
+ }
2598
2577
  ca_iter_state st_in, st_out;
2599
2578
  int rc;
2600
2579
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2609,14 +2588,6 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2609
2588
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2610
2589
  }
2611
2590
 
2612
- ca_size_t fiber_n = st_in.slab_elements;
2613
- volatile VALUE hbuf = 0, haux = 0;
2614
- sort_addr_pair_i64 *buf = ALLOCV_N(sort_addr_pair_i64, hbuf, fiber_n);
2615
- sort_addr_pair_i64 *aux = NULL;
2616
- if ( do_stable ) {
2617
- aux = ALLOCV_N(sort_addr_pair_i64, haux, fiber_n);
2618
- }
2619
-
2620
2591
  /* :view_flat semantics: kernel computes view-flat address
2621
2592
  (= row-major position in ca's shape, 0..elements-1) for
2622
2593
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2660,13 +2631,13 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2660
2631
  if ( masked_last ) {
2661
2632
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2662
2633
  if ( mi[k * mstride] ) continue;
2663
- buf[n_valid].v = *(int64_t *) (pi + k * istride);
2634
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2664
2635
  buf[n_valid].i = outer_off + k * axis_vstride;
2665
2636
  n_valid++;
2666
2637
  }
2667
2638
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2668
2639
  if ( ! mi[k * mstride] ) continue;
2669
- buf[n_valid + n_masked].v = *(int64_t *) (pi + k * istride);
2640
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2670
2641
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2671
2642
  n_masked++;
2672
2643
  }
@@ -2674,13 +2645,13 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2674
2645
  } else {
2675
2646
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2676
2647
  if ( ! mi[k * mstride] ) continue;
2677
- buf[n_masked].v = *(int64_t *) (pi + k * istride);
2648
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2678
2649
  buf[n_masked].i = outer_off + k * axis_vstride;
2679
2650
  n_masked++;
2680
2651
  }
2681
2652
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2682
2653
  if ( mi[k * mstride] ) continue;
2683
- buf[n_masked + n_valid].v = *(int64_t *) (pi + k * istride);
2654
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2684
2655
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2685
2656
  n_valid++;
2686
2657
  }
@@ -2688,7 +2659,7 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2688
2659
  }
2689
2660
  } else {
2690
2661
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2691
- buf[k].v = *(int64_t *) (pi + k * istride);
2662
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2692
2663
  buf[k].i = outer_off + k * axis_vstride;
2693
2664
  }
2694
2665
  sort_lo = 0; sort_n = fiber_n;
@@ -2725,7 +2696,7 @@ sort_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2725
2696
  }
2726
2697
 
2727
2698
  typedef struct {
2728
- uint64_t v;
2699
+ ca_u_uint64_t v;
2729
2700
  ca_size_t i;
2730
2701
  } sort_addr_pair_u64;
2731
2702
 
@@ -2742,6 +2713,13 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2742
2713
  positions align between iterators. */
2743
2714
  int8_t slab_axes[CA_RANK_MAX];
2744
2715
  slab_axes[0] = (int8_t) axis;
2716
+ ca_size_t fiber_n = ca->dim[axis];
2717
+ volatile VALUE hbuf = 0, haux = 0;
2718
+ sort_addr_pair_u64 *buf = ALLOCV_N(sort_addr_pair_u64, hbuf, fiber_n);
2719
+ sort_addr_pair_u64 *aux = NULL;
2720
+ if ( do_stable ) {
2721
+ aux = ALLOCV_N(sort_addr_pair_u64, haux, fiber_n);
2722
+ }
2745
2723
  ca_iter_state st_in, st_out;
2746
2724
  int rc;
2747
2725
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2756,14 +2734,6 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2756
2734
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2757
2735
  }
2758
2736
 
2759
- ca_size_t fiber_n = st_in.slab_elements;
2760
- volatile VALUE hbuf = 0, haux = 0;
2761
- sort_addr_pair_u64 *buf = ALLOCV_N(sort_addr_pair_u64, hbuf, fiber_n);
2762
- sort_addr_pair_u64 *aux = NULL;
2763
- if ( do_stable ) {
2764
- aux = ALLOCV_N(sort_addr_pair_u64, haux, fiber_n);
2765
- }
2766
-
2767
2737
  /* :view_flat semantics: kernel computes view-flat address
2768
2738
  (= row-major position in ca's shape, 0..elements-1) for
2769
2739
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2807,13 +2777,13 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2807
2777
  if ( masked_last ) {
2808
2778
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2809
2779
  if ( mi[k * mstride] ) continue;
2810
- buf[n_valid].v = *(uint64_t *) (pi + k * istride);
2780
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2811
2781
  buf[n_valid].i = outer_off + k * axis_vstride;
2812
2782
  n_valid++;
2813
2783
  }
2814
2784
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2815
2785
  if ( ! mi[k * mstride] ) continue;
2816
- buf[n_valid + n_masked].v = *(uint64_t *) (pi + k * istride);
2786
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2817
2787
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2818
2788
  n_masked++;
2819
2789
  }
@@ -2821,13 +2791,13 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2821
2791
  } else {
2822
2792
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2823
2793
  if ( ! mi[k * mstride] ) continue;
2824
- buf[n_masked].v = *(uint64_t *) (pi + k * istride);
2794
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2825
2795
  buf[n_masked].i = outer_off + k * axis_vstride;
2826
2796
  n_masked++;
2827
2797
  }
2828
2798
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2829
2799
  if ( mi[k * mstride] ) continue;
2830
- buf[n_masked + n_valid].v = *(uint64_t *) (pi + k * istride);
2800
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2831
2801
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2832
2802
  n_valid++;
2833
2803
  }
@@ -2835,7 +2805,7 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2835
2805
  }
2836
2806
  } else {
2837
2807
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2838
- buf[k].v = *(uint64_t *) (pi + k * istride);
2808
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2839
2809
  buf[k].i = outer_off + k * axis_vstride;
2840
2810
  }
2841
2811
  sort_lo = 0; sort_n = fiber_n;
@@ -2872,7 +2842,7 @@ sort_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2872
2842
  }
2873
2843
 
2874
2844
  typedef struct {
2875
- float v;
2845
+ ca_u_float32_t v;
2876
2846
  ca_size_t i;
2877
2847
  } sort_addr_pair_f32;
2878
2848
 
@@ -2889,6 +2859,10 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2889
2859
  positions align between iterators. */
2890
2860
  int8_t slab_axes[CA_RANK_MAX];
2891
2861
  slab_axes[0] = (int8_t) axis;
2862
+ ca_size_t fiber_n = ca->dim[axis];
2863
+ volatile VALUE hbuf = 0, haux = 0;
2864
+ sort_addr_pair_f32 *buf = ALLOCV_N(sort_addr_pair_f32, hbuf, fiber_n);
2865
+ sort_addr_pair_f32 *aux = ALLOCV_N(sort_addr_pair_f32, haux, fiber_n);
2892
2866
  ca_iter_state st_in, st_out;
2893
2867
  int rc;
2894
2868
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -2903,14 +2877,6 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2903
2877
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
2904
2878
  }
2905
2879
 
2906
- ca_size_t fiber_n = st_in.slab_elements;
2907
- volatile VALUE hbuf = 0, haux = 0;
2908
- sort_addr_pair_f32 *buf = ALLOCV_N(sort_addr_pair_f32, hbuf, fiber_n);
2909
- sort_addr_pair_f32 *aux = NULL;
2910
- if ( do_stable ) {
2911
- aux = ALLOCV_N(sort_addr_pair_f32, haux, fiber_n);
2912
- }
2913
-
2914
2880
  /* :view_flat semantics: kernel computes view-flat address
2915
2881
  (= row-major position in ca's shape, 0..elements-1) for
2916
2882
  each cell. Used to feed CARemap.idx directly (= sort
@@ -2954,13 +2920,13 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2954
2920
  if ( masked_last ) {
2955
2921
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2956
2922
  if ( mi[k * mstride] ) continue;
2957
- buf[n_valid].v = *(float *) (pi + k * istride);
2923
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
2958
2924
  buf[n_valid].i = outer_off + k * axis_vstride;
2959
2925
  n_valid++;
2960
2926
  }
2961
2927
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2962
2928
  if ( ! mi[k * mstride] ) continue;
2963
- buf[n_valid + n_masked].v = *(float *) (pi + k * istride);
2929
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
2964
2930
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
2965
2931
  n_masked++;
2966
2932
  }
@@ -2968,13 +2934,13 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2968
2934
  } else {
2969
2935
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2970
2936
  if ( ! mi[k * mstride] ) continue;
2971
- buf[n_masked].v = *(float *) (pi + k * istride);
2937
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
2972
2938
  buf[n_masked].i = outer_off + k * axis_vstride;
2973
2939
  n_masked++;
2974
2940
  }
2975
2941
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2976
2942
  if ( mi[k * mstride] ) continue;
2977
- buf[n_masked + n_valid].v = *(float *) (pi + k * istride);
2943
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
2978
2944
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
2979
2945
  n_valid++;
2980
2946
  }
@@ -2982,7 +2948,7 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2982
2948
  }
2983
2949
  } else {
2984
2950
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
2985
- buf[k].v = *(float *) (pi + k * istride);
2951
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
2986
2952
  buf[k].i = outer_off + k * axis_vstride;
2987
2953
  }
2988
2954
  sort_lo = 0; sort_n = fiber_n;
@@ -2998,7 +2964,7 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
2998
2964
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
2999
2965
  pushed to the tail (= NaN-at-end policy, matches sort_copy
3000
2966
  AC8). Only the finite slice is sorted. */
3001
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n);
2967
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f32 *) aux);
3002
2968
  if ( do_stable ) {
3003
2969
  ca_sort_merge_pair_f32((ca_pair_f32 *) (buf + sort_lo), (ca_pair_f32 *) aux, finite_n);
3004
2970
  } else {
@@ -3023,7 +2989,7 @@ sort_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3023
2989
  }
3024
2990
 
3025
2991
  typedef struct {
3026
- double v;
2992
+ ca_u_float64_t v;
3027
2993
  ca_size_t i;
3028
2994
  } sort_addr_pair_f64;
3029
2995
 
@@ -3040,6 +3006,10 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3040
3006
  positions align between iterators. */
3041
3007
  int8_t slab_axes[CA_RANK_MAX];
3042
3008
  slab_axes[0] = (int8_t) axis;
3009
+ ca_size_t fiber_n = ca->dim[axis];
3010
+ volatile VALUE hbuf = 0, haux = 0;
3011
+ sort_addr_pair_f64 *buf = ALLOCV_N(sort_addr_pair_f64, hbuf, fiber_n);
3012
+ sort_addr_pair_f64 *aux = ALLOCV_N(sort_addr_pair_f64, haux, fiber_n);
3043
3013
  ca_iter_state st_in, st_out;
3044
3014
  int rc;
3045
3015
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3054,14 +3024,6 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3054
3024
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3055
3025
  }
3056
3026
 
3057
- ca_size_t fiber_n = st_in.slab_elements;
3058
- volatile VALUE hbuf = 0, haux = 0;
3059
- sort_addr_pair_f64 *buf = ALLOCV_N(sort_addr_pair_f64, hbuf, fiber_n);
3060
- sort_addr_pair_f64 *aux = NULL;
3061
- if ( do_stable ) {
3062
- aux = ALLOCV_N(sort_addr_pair_f64, haux, fiber_n);
3063
- }
3064
-
3065
3027
  /* :view_flat semantics: kernel computes view-flat address
3066
3028
  (= row-major position in ca's shape, 0..elements-1) for
3067
3029
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3105,13 +3067,13 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3105
3067
  if ( masked_last ) {
3106
3068
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3107
3069
  if ( mi[k * mstride] ) continue;
3108
- buf[n_valid].v = *(double *) (pi + k * istride);
3070
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
3109
3071
  buf[n_valid].i = outer_off + k * axis_vstride;
3110
3072
  n_valid++;
3111
3073
  }
3112
3074
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3113
3075
  if ( ! mi[k * mstride] ) continue;
3114
- buf[n_valid + n_masked].v = *(double *) (pi + k * istride);
3076
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
3115
3077
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
3116
3078
  n_masked++;
3117
3079
  }
@@ -3119,13 +3081,13 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3119
3081
  } else {
3120
3082
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3121
3083
  if ( ! mi[k * mstride] ) continue;
3122
- buf[n_masked].v = *(double *) (pi + k * istride);
3084
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
3123
3085
  buf[n_masked].i = outer_off + k * axis_vstride;
3124
3086
  n_masked++;
3125
3087
  }
3126
3088
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3127
3089
  if ( mi[k * mstride] ) continue;
3128
- buf[n_masked + n_valid].v = *(double *) (pi + k * istride);
3090
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
3129
3091
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
3130
3092
  n_valid++;
3131
3093
  }
@@ -3133,7 +3095,7 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3133
3095
  }
3134
3096
  } else {
3135
3097
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3136
- buf[k].v = *(double *) (pi + k * istride);
3098
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
3137
3099
  buf[k].i = outer_off + k * axis_vstride;
3138
3100
  }
3139
3101
  sort_lo = 0; sort_n = fiber_n;
@@ -3149,7 +3111,7 @@ sort_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int ma
3149
3111
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
3150
3112
  pushed to the tail (= NaN-at-end policy, matches sort_copy
3151
3113
  AC8). Only the finite slice is sorted. */
3152
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n);
3114
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_size_t) sort_n, (ca_pair_f64 *) aux);
3153
3115
  if ( do_stable ) {
3154
3116
  ca_sort_merge_pair_f64((ca_pair_f64 *) (buf + sort_lo), (ca_pair_f64 *) aux, finite_n);
3155
3117
  } else {
@@ -3191,6 +3153,13 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3191
3153
  positions align between iterators. */
3192
3154
  int8_t slab_axes[CA_RANK_MAX];
3193
3155
  slab_axes[0] = (int8_t) axis;
3156
+ ca_size_t fiber_n = ca->dim[axis];
3157
+ volatile VALUE hbuf = 0, haux = 0;
3158
+ sort_addr_pair_bool *buf = ALLOCV_N(sort_addr_pair_bool, hbuf, fiber_n);
3159
+ sort_addr_pair_bool *aux = NULL;
3160
+ if ( do_stable ) {
3161
+ aux = ALLOCV_N(sort_addr_pair_bool, haux, fiber_n);
3162
+ }
3194
3163
  ca_iter_state st_in, st_out;
3195
3164
  int rc;
3196
3165
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3205,14 +3174,6 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3205
3174
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3206
3175
  }
3207
3176
 
3208
- ca_size_t fiber_n = st_in.slab_elements;
3209
- volatile VALUE hbuf = 0, haux = 0;
3210
- sort_addr_pair_bool *buf = ALLOCV_N(sort_addr_pair_bool, hbuf, fiber_n);
3211
- sort_addr_pair_bool *aux = NULL;
3212
- if ( do_stable ) {
3213
- aux = ALLOCV_N(sort_addr_pair_bool, haux, fiber_n);
3214
- }
3215
-
3216
3177
  /* :view_flat semantics: kernel computes view-flat address
3217
3178
  (= row-major position in ca's shape, 0..elements-1) for
3218
3179
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3256,13 +3217,13 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3256
3217
  if ( masked_last ) {
3257
3218
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3258
3219
  if ( mi[k * mstride] ) continue;
3259
- buf[n_valid].v = *(boolean8_t *) (pi + k * istride);
3220
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
3260
3221
  buf[n_valid].i = outer_off + k * axis_vstride;
3261
3222
  n_valid++;
3262
3223
  }
3263
3224
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3264
3225
  if ( ! mi[k * mstride] ) continue;
3265
- buf[n_valid + n_masked].v = *(boolean8_t *) (pi + k * istride);
3226
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
3266
3227
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
3267
3228
  n_masked++;
3268
3229
  }
@@ -3270,13 +3231,13 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3270
3231
  } else {
3271
3232
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3272
3233
  if ( ! mi[k * mstride] ) continue;
3273
- buf[n_masked].v = *(boolean8_t *) (pi + k * istride);
3234
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
3274
3235
  buf[n_masked].i = outer_off + k * axis_vstride;
3275
3236
  n_masked++;
3276
3237
  }
3277
3238
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3278
3239
  if ( mi[k * mstride] ) continue;
3279
- buf[n_masked + n_valid].v = *(boolean8_t *) (pi + k * istride);
3240
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
3280
3241
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
3281
3242
  n_valid++;
3282
3243
  }
@@ -3284,7 +3245,7 @@ sort_addr_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int m
3284
3245
  }
3285
3246
  } else {
3286
3247
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3287
- buf[k].v = *(boolean8_t *) (pi + k * istride);
3248
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
3288
3249
  buf[k].i = outer_off + k * axis_vstride;
3289
3250
  }
3290
3251
  sort_lo = 0; sort_n = fiber_n;
@@ -3338,9 +3299,9 @@ sort_addr_cmp_object (const void *a, const void *b)
3338
3299
  return 0;
3339
3300
  }
3340
3301
 
3341
- /* The object lane calls Ruby for every cell, so a walk can raise part
3342
- way. Its states live in the caller's frame, and ca_iter_ensure
3343
- finishes them however the body leaves. */
3302
+ /* The walks can raise part way (a Ruby call per cell in the object
3303
+ lane, an allocation in any lane). Their states live in the caller's
3304
+ frame, and ca_iter_ensure finishes them however the body leaves. */
3344
3305
  typedef struct {
3345
3306
  ca_iter_state states[2];
3346
3307
  VALUE self;
@@ -3376,6 +3337,10 @@ sort_addr_ki_native_object_body (VALUE arg)
3376
3337
  positions align between iterators. */
3377
3338
  int8_t slab_axes[CA_RANK_MAX];
3378
3339
  slab_axes[0] = (int8_t) axis;
3340
+ ca_size_t fiber_n = ca->dim[axis];
3341
+ volatile VALUE hbuf = 0, haux = 0;
3342
+ sort_addr_pair_object *buf = ALLOCV_N(sort_addr_pair_object, hbuf, fiber_n);
3343
+ sort_addr_pair_object *aux = ALLOCV_N(sort_addr_pair_object, haux, fiber_n);
3379
3344
  int rc;
3380
3345
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
3381
3346
  slab_axes, 1, 0);
@@ -3389,11 +3354,6 @@ sort_addr_ki_native_object_body (VALUE arg)
3389
3354
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3390
3355
  }
3391
3356
 
3392
- ca_size_t fiber_n = st_in.slab_elements;
3393
- volatile VALUE hbuf = 0, haux = 0;
3394
- sort_addr_pair_object *buf = ALLOCV_N(sort_addr_pair_object, hbuf, fiber_n);
3395
- sort_addr_pair_object *aux = ALLOCV_N(sort_addr_pair_object, haux, fiber_n);
3396
-
3397
3357
  /* :view_flat semantics: kernel computes view-flat address
3398
3358
  (= row-major position in ca's shape, 0..elements-1) for
3399
3359
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3437,13 +3397,13 @@ sort_addr_ki_native_object_body (VALUE arg)
3437
3397
  if ( masked_last ) {
3438
3398
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3439
3399
  if ( mi[k * mstride] ) continue;
3440
- buf[n_valid].v = *(VALUE *) (pi + k * istride);
3400
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
3441
3401
  buf[n_valid].i = outer_off + k * axis_vstride;
3442
3402
  n_valid++;
3443
3403
  }
3444
3404
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3445
3405
  if ( ! mi[k * mstride] ) continue;
3446
- buf[n_valid + n_masked].v = *(VALUE *) (pi + k * istride);
3406
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
3447
3407
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
3448
3408
  n_masked++;
3449
3409
  }
@@ -3451,13 +3411,13 @@ sort_addr_ki_native_object_body (VALUE arg)
3451
3411
  } else {
3452
3412
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3453
3413
  if ( ! mi[k * mstride] ) continue;
3454
- buf[n_masked].v = *(VALUE *) (pi + k * istride);
3414
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
3455
3415
  buf[n_masked].i = outer_off + k * axis_vstride;
3456
3416
  n_masked++;
3457
3417
  }
3458
3418
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3459
3419
  if ( mi[k * mstride] ) continue;
3460
- buf[n_masked + n_valid].v = *(VALUE *) (pi + k * istride);
3420
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
3461
3421
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
3462
3422
  n_valid++;
3463
3423
  }
@@ -3465,7 +3425,7 @@ sort_addr_ki_native_object_body (VALUE arg)
3465
3425
  }
3466
3426
  } else {
3467
3427
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3468
- buf[k].v = *(VALUE *) (pi + k * istride);
3428
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
3469
3429
  buf[k].i = outer_off + k * axis_vstride;
3470
3430
  }
3471
3431
  sort_lo = 0; sort_n = fiber_n;
@@ -3509,7 +3469,7 @@ sort_addr_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, int
3509
3469
  fr.axis = axis;
3510
3470
  fr.do_stable = do_stable;
3511
3471
  fr.masked_last = masked_last;
3512
- return ca_iter_ensure(2, fr.states, sort_addr_ki_native_object_body, (VALUE) &fr);
3472
+ return ca_iter_ensure_computing(ca, 2, fr.states, sort_addr_ki_native_object_body, (VALUE) &fr);
3513
3473
  }
3514
3474
 
3515
3475
 
@@ -3545,6 +3505,10 @@ sort_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, int
3545
3505
  positions align between iterators. */
3546
3506
  int8_t slab_axes[CA_RANK_MAX];
3547
3507
  slab_axes[0] = (int8_t) axis;
3508
+ ca_size_t fiber_n = ca->dim[axis];
3509
+ volatile VALUE hbuf = 0, haux = 0;
3510
+ sort_addr_pair_fixlen *buf = ALLOCV_N(sort_addr_pair_fixlen, hbuf, fiber_n);
3511
+ (void) haux;
3548
3512
  ca_iter_state st_in, st_out;
3549
3513
  int rc;
3550
3514
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3559,14 +3523,6 @@ sort_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, int
3559
3523
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3560
3524
  }
3561
3525
 
3562
- ca_size_t fiber_n = st_in.slab_elements;
3563
- volatile VALUE hbuf = 0, haux = 0;
3564
- sort_addr_pair_fixlen *buf = ALLOCV_N(sort_addr_pair_fixlen, hbuf, fiber_n);
3565
- sort_addr_pair_fixlen *aux = NULL;
3566
- if ( do_stable ) {
3567
- aux = ALLOCV_N(sort_addr_pair_fixlen, haux, fiber_n);
3568
- }
3569
-
3570
3526
  /* :view_flat semantics: kernel computes view-flat address
3571
3527
  (= row-major position in ca's shape, 0..elements-1) for
3572
3528
  each cell. Used to feed CARemap.idx directly (= sort
@@ -3817,6 +3773,10 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3817
3773
  positions align between iterators. */
3818
3774
  int8_t slab_axes[CA_RANK_MAX];
3819
3775
  slab_axes[0] = (int8_t) axis;
3776
+ ca_size_t fiber_n = ca->dim[axis];
3777
+ volatile VALUE hbuf = 0, haux = 0;
3778
+ partition_index_pair_i8 *buf = ALLOCV_N(partition_index_pair_i8, hbuf, fiber_n);
3779
+ (void) haux;
3820
3780
  ca_iter_state st_in, st_out;
3821
3781
  int rc;
3822
3782
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -3831,11 +3791,6 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3831
3791
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
3832
3792
  }
3833
3793
 
3834
- ca_size_t fiber_n = st_in.slab_elements;
3835
- volatile VALUE hbuf = 0, haux = 0;
3836
- partition_index_pair_i8 *buf = ALLOCV_N(partition_index_pair_i8, hbuf, fiber_n);
3837
- (void) haux;
3838
-
3839
3794
  char *pi, *po;
3840
3795
  boolean8_t *mi, *mo;
3841
3796
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -3852,13 +3807,13 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3852
3807
  if ( masked_last ) {
3853
3808
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3854
3809
  if ( mi[k * mstride] ) continue;
3855
- buf[n_valid].v = *(int8_t *) (pi + k * istride);
3810
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
3856
3811
  buf[n_valid].i = k;
3857
3812
  n_valid++;
3858
3813
  }
3859
3814
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3860
3815
  if ( ! mi[k * mstride] ) continue;
3861
- buf[n_valid + n_masked].v = *(int8_t *) (pi + k * istride);
3816
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
3862
3817
  buf[n_valid + n_masked].i = k;
3863
3818
  n_masked++;
3864
3819
  }
@@ -3866,13 +3821,13 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3866
3821
  } else {
3867
3822
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3868
3823
  if ( ! mi[k * mstride] ) continue;
3869
- buf[n_masked].v = *(int8_t *) (pi + k * istride);
3824
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
3870
3825
  buf[n_masked].i = k;
3871
3826
  n_masked++;
3872
3827
  }
3873
3828
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3874
3829
  if ( mi[k * mstride] ) continue;
3875
- buf[n_masked + n_valid].v = *(int8_t *) (pi + k * istride);
3830
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
3876
3831
  buf[n_masked + n_valid].i = k;
3877
3832
  n_valid++;
3878
3833
  }
@@ -3880,7 +3835,7 @@ partition_index_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3880
3835
  }
3881
3836
  } else {
3882
3837
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
3883
- buf[k].v = *(int8_t *) (pi + k * istride);
3838
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
3884
3839
  buf[k].i = k;
3885
3840
  }
3886
3841
  sort_lo = 0; sort_n = fiber_n;
@@ -3996,6 +3951,10 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
3996
3951
  positions align between iterators. */
3997
3952
  int8_t slab_axes[CA_RANK_MAX];
3998
3953
  slab_axes[0] = (int8_t) axis;
3954
+ ca_size_t fiber_n = ca->dim[axis];
3955
+ volatile VALUE hbuf = 0, haux = 0;
3956
+ partition_index_pair_u8 *buf = ALLOCV_N(partition_index_pair_u8, hbuf, fiber_n);
3957
+ (void) haux;
3999
3958
  ca_iter_state st_in, st_out;
4000
3959
  int rc;
4001
3960
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4010,11 +3969,6 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4010
3969
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4011
3970
  }
4012
3971
 
4013
- ca_size_t fiber_n = st_in.slab_elements;
4014
- volatile VALUE hbuf = 0, haux = 0;
4015
- partition_index_pair_u8 *buf = ALLOCV_N(partition_index_pair_u8, hbuf, fiber_n);
4016
- (void) haux;
4017
-
4018
3972
  char *pi, *po;
4019
3973
  boolean8_t *mi, *mo;
4020
3974
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4031,13 +3985,13 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4031
3985
  if ( masked_last ) {
4032
3986
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4033
3987
  if ( mi[k * mstride] ) continue;
4034
- buf[n_valid].v = *(uint8_t *) (pi + k * istride);
3988
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4035
3989
  buf[n_valid].i = k;
4036
3990
  n_valid++;
4037
3991
  }
4038
3992
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4039
3993
  if ( ! mi[k * mstride] ) continue;
4040
- buf[n_valid + n_masked].v = *(uint8_t *) (pi + k * istride);
3994
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4041
3995
  buf[n_valid + n_masked].i = k;
4042
3996
  n_masked++;
4043
3997
  }
@@ -4045,13 +3999,13 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4045
3999
  } else {
4046
4000
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4047
4001
  if ( ! mi[k * mstride] ) continue;
4048
- buf[n_masked].v = *(uint8_t *) (pi + k * istride);
4002
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4049
4003
  buf[n_masked].i = k;
4050
4004
  n_masked++;
4051
4005
  }
4052
4006
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4053
4007
  if ( mi[k * mstride] ) continue;
4054
- buf[n_masked + n_valid].v = *(uint8_t *) (pi + k * istride);
4008
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4055
4009
  buf[n_masked + n_valid].i = k;
4056
4010
  n_valid++;
4057
4011
  }
@@ -4059,7 +4013,7 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4059
4013
  }
4060
4014
  } else {
4061
4015
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4062
- buf[k].v = *(uint8_t *) (pi + k * istride);
4016
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4063
4017
  buf[k].i = k;
4064
4018
  }
4065
4019
  sort_lo = 0; sort_n = fiber_n;
@@ -4090,7 +4044,7 @@ partition_index_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
4090
4044
  }
4091
4045
 
4092
4046
  typedef struct {
4093
- int16_t v;
4047
+ ca_u_int16_t v;
4094
4048
  ca_size_t i;
4095
4049
  } partition_index_pair_i16;
4096
4050
 
@@ -4175,6 +4129,10 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4175
4129
  positions align between iterators. */
4176
4130
  int8_t slab_axes[CA_RANK_MAX];
4177
4131
  slab_axes[0] = (int8_t) axis;
4132
+ ca_size_t fiber_n = ca->dim[axis];
4133
+ volatile VALUE hbuf = 0, haux = 0;
4134
+ partition_index_pair_i16 *buf = ALLOCV_N(partition_index_pair_i16, hbuf, fiber_n);
4135
+ (void) haux;
4178
4136
  ca_iter_state st_in, st_out;
4179
4137
  int rc;
4180
4138
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4189,11 +4147,6 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4189
4147
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4190
4148
  }
4191
4149
 
4192
- ca_size_t fiber_n = st_in.slab_elements;
4193
- volatile VALUE hbuf = 0, haux = 0;
4194
- partition_index_pair_i16 *buf = ALLOCV_N(partition_index_pair_i16, hbuf, fiber_n);
4195
- (void) haux;
4196
-
4197
4150
  char *pi, *po;
4198
4151
  boolean8_t *mi, *mo;
4199
4152
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4210,13 +4163,13 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4210
4163
  if ( masked_last ) {
4211
4164
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4212
4165
  if ( mi[k * mstride] ) continue;
4213
- buf[n_valid].v = *(int16_t *) (pi + k * istride);
4166
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4214
4167
  buf[n_valid].i = k;
4215
4168
  n_valid++;
4216
4169
  }
4217
4170
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4218
4171
  if ( ! mi[k * mstride] ) continue;
4219
- buf[n_valid + n_masked].v = *(int16_t *) (pi + k * istride);
4172
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4220
4173
  buf[n_valid + n_masked].i = k;
4221
4174
  n_masked++;
4222
4175
  }
@@ -4224,13 +4177,13 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4224
4177
  } else {
4225
4178
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4226
4179
  if ( ! mi[k * mstride] ) continue;
4227
- buf[n_masked].v = *(int16_t *) (pi + k * istride);
4180
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4228
4181
  buf[n_masked].i = k;
4229
4182
  n_masked++;
4230
4183
  }
4231
4184
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4232
4185
  if ( mi[k * mstride] ) continue;
4233
- buf[n_masked + n_valid].v = *(int16_t *) (pi + k * istride);
4186
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4234
4187
  buf[n_masked + n_valid].i = k;
4235
4188
  n_valid++;
4236
4189
  }
@@ -4238,7 +4191,7 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4238
4191
  }
4239
4192
  } else {
4240
4193
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4241
- buf[k].v = *(int16_t *) (pi + k * istride);
4194
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4242
4195
  buf[k].i = k;
4243
4196
  }
4244
4197
  sort_lo = 0; sort_n = fiber_n;
@@ -4269,7 +4222,7 @@ partition_index_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4269
4222
  }
4270
4223
 
4271
4224
  typedef struct {
4272
- uint16_t v;
4225
+ ca_u_uint16_t v;
4273
4226
  ca_size_t i;
4274
4227
  } partition_index_pair_u16;
4275
4228
 
@@ -4354,6 +4307,10 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4354
4307
  positions align between iterators. */
4355
4308
  int8_t slab_axes[CA_RANK_MAX];
4356
4309
  slab_axes[0] = (int8_t) axis;
4310
+ ca_size_t fiber_n = ca->dim[axis];
4311
+ volatile VALUE hbuf = 0, haux = 0;
4312
+ partition_index_pair_u16 *buf = ALLOCV_N(partition_index_pair_u16, hbuf, fiber_n);
4313
+ (void) haux;
4357
4314
  ca_iter_state st_in, st_out;
4358
4315
  int rc;
4359
4316
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4368,11 +4325,6 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4368
4325
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4369
4326
  }
4370
4327
 
4371
- ca_size_t fiber_n = st_in.slab_elements;
4372
- volatile VALUE hbuf = 0, haux = 0;
4373
- partition_index_pair_u16 *buf = ALLOCV_N(partition_index_pair_u16, hbuf, fiber_n);
4374
- (void) haux;
4375
-
4376
4328
  char *pi, *po;
4377
4329
  boolean8_t *mi, *mo;
4378
4330
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4389,13 +4341,13 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4389
4341
  if ( masked_last ) {
4390
4342
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4391
4343
  if ( mi[k * mstride] ) continue;
4392
- buf[n_valid].v = *(uint16_t *) (pi + k * istride);
4344
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4393
4345
  buf[n_valid].i = k;
4394
4346
  n_valid++;
4395
4347
  }
4396
4348
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4397
4349
  if ( ! mi[k * mstride] ) continue;
4398
- buf[n_valid + n_masked].v = *(uint16_t *) (pi + k * istride);
4350
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4399
4351
  buf[n_valid + n_masked].i = k;
4400
4352
  n_masked++;
4401
4353
  }
@@ -4403,13 +4355,13 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4403
4355
  } else {
4404
4356
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4405
4357
  if ( ! mi[k * mstride] ) continue;
4406
- buf[n_masked].v = *(uint16_t *) (pi + k * istride);
4358
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4407
4359
  buf[n_masked].i = k;
4408
4360
  n_masked++;
4409
4361
  }
4410
4362
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4411
4363
  if ( mi[k * mstride] ) continue;
4412
- buf[n_masked + n_valid].v = *(uint16_t *) (pi + k * istride);
4364
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4413
4365
  buf[n_masked + n_valid].i = k;
4414
4366
  n_valid++;
4415
4367
  }
@@ -4417,7 +4369,7 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4417
4369
  }
4418
4370
  } else {
4419
4371
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4420
- buf[k].v = *(uint16_t *) (pi + k * istride);
4372
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4421
4373
  buf[k].i = k;
4422
4374
  }
4423
4375
  sort_lo = 0; sort_n = fiber_n;
@@ -4448,7 +4400,7 @@ partition_index_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4448
4400
  }
4449
4401
 
4450
4402
  typedef struct {
4451
- int32_t v;
4403
+ ca_u_int32_t v;
4452
4404
  ca_size_t i;
4453
4405
  } partition_index_pair_i32;
4454
4406
 
@@ -4533,6 +4485,10 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4533
4485
  positions align between iterators. */
4534
4486
  int8_t slab_axes[CA_RANK_MAX];
4535
4487
  slab_axes[0] = (int8_t) axis;
4488
+ ca_size_t fiber_n = ca->dim[axis];
4489
+ volatile VALUE hbuf = 0, haux = 0;
4490
+ partition_index_pair_i32 *buf = ALLOCV_N(partition_index_pair_i32, hbuf, fiber_n);
4491
+ (void) haux;
4536
4492
  ca_iter_state st_in, st_out;
4537
4493
  int rc;
4538
4494
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4547,11 +4503,6 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4547
4503
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4548
4504
  }
4549
4505
 
4550
- ca_size_t fiber_n = st_in.slab_elements;
4551
- volatile VALUE hbuf = 0, haux = 0;
4552
- partition_index_pair_i32 *buf = ALLOCV_N(partition_index_pair_i32, hbuf, fiber_n);
4553
- (void) haux;
4554
-
4555
4506
  char *pi, *po;
4556
4507
  boolean8_t *mi, *mo;
4557
4508
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4568,13 +4519,13 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4568
4519
  if ( masked_last ) {
4569
4520
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4570
4521
  if ( mi[k * mstride] ) continue;
4571
- buf[n_valid].v = *(int32_t *) (pi + k * istride);
4522
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4572
4523
  buf[n_valid].i = k;
4573
4524
  n_valid++;
4574
4525
  }
4575
4526
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4576
4527
  if ( ! mi[k * mstride] ) continue;
4577
- buf[n_valid + n_masked].v = *(int32_t *) (pi + k * istride);
4528
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4578
4529
  buf[n_valid + n_masked].i = k;
4579
4530
  n_masked++;
4580
4531
  }
@@ -4582,13 +4533,13 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4582
4533
  } else {
4583
4534
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4584
4535
  if ( ! mi[k * mstride] ) continue;
4585
- buf[n_masked].v = *(int32_t *) (pi + k * istride);
4536
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4586
4537
  buf[n_masked].i = k;
4587
4538
  n_masked++;
4588
4539
  }
4589
4540
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4590
4541
  if ( mi[k * mstride] ) continue;
4591
- buf[n_masked + n_valid].v = *(int32_t *) (pi + k * istride);
4542
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4592
4543
  buf[n_masked + n_valid].i = k;
4593
4544
  n_valid++;
4594
4545
  }
@@ -4596,7 +4547,7 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4596
4547
  }
4597
4548
  } else {
4598
4549
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4599
- buf[k].v = *(int32_t *) (pi + k * istride);
4550
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4600
4551
  buf[k].i = k;
4601
4552
  }
4602
4553
  sort_lo = 0; sort_n = fiber_n;
@@ -4627,7 +4578,7 @@ partition_index_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4627
4578
  }
4628
4579
 
4629
4580
  typedef struct {
4630
- uint32_t v;
4581
+ ca_u_uint32_t v;
4631
4582
  ca_size_t i;
4632
4583
  } partition_index_pair_u32;
4633
4584
 
@@ -4712,6 +4663,10 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4712
4663
  positions align between iterators. */
4713
4664
  int8_t slab_axes[CA_RANK_MAX];
4714
4665
  slab_axes[0] = (int8_t) axis;
4666
+ ca_size_t fiber_n = ca->dim[axis];
4667
+ volatile VALUE hbuf = 0, haux = 0;
4668
+ partition_index_pair_u32 *buf = ALLOCV_N(partition_index_pair_u32, hbuf, fiber_n);
4669
+ (void) haux;
4715
4670
  ca_iter_state st_in, st_out;
4716
4671
  int rc;
4717
4672
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4726,11 +4681,6 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4726
4681
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4727
4682
  }
4728
4683
 
4729
- ca_size_t fiber_n = st_in.slab_elements;
4730
- volatile VALUE hbuf = 0, haux = 0;
4731
- partition_index_pair_u32 *buf = ALLOCV_N(partition_index_pair_u32, hbuf, fiber_n);
4732
- (void) haux;
4733
-
4734
4684
  char *pi, *po;
4735
4685
  boolean8_t *mi, *mo;
4736
4686
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4747,13 +4697,13 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4747
4697
  if ( masked_last ) {
4748
4698
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4749
4699
  if ( mi[k * mstride] ) continue;
4750
- buf[n_valid].v = *(uint32_t *) (pi + k * istride);
4700
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4751
4701
  buf[n_valid].i = k;
4752
4702
  n_valid++;
4753
4703
  }
4754
4704
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4755
4705
  if ( ! mi[k * mstride] ) continue;
4756
- buf[n_valid + n_masked].v = *(uint32_t *) (pi + k * istride);
4706
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4757
4707
  buf[n_valid + n_masked].i = k;
4758
4708
  n_masked++;
4759
4709
  }
@@ -4761,13 +4711,13 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4761
4711
  } else {
4762
4712
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4763
4713
  if ( ! mi[k * mstride] ) continue;
4764
- buf[n_masked].v = *(uint32_t *) (pi + k * istride);
4714
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4765
4715
  buf[n_masked].i = k;
4766
4716
  n_masked++;
4767
4717
  }
4768
4718
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4769
4719
  if ( mi[k * mstride] ) continue;
4770
- buf[n_masked + n_valid].v = *(uint32_t *) (pi + k * istride);
4720
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4771
4721
  buf[n_masked + n_valid].i = k;
4772
4722
  n_valid++;
4773
4723
  }
@@ -4775,7 +4725,7 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4775
4725
  }
4776
4726
  } else {
4777
4727
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4778
- buf[k].v = *(uint32_t *) (pi + k * istride);
4728
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4779
4729
  buf[k].i = k;
4780
4730
  }
4781
4731
  sort_lo = 0; sort_n = fiber_n;
@@ -4806,7 +4756,7 @@ partition_index_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4806
4756
  }
4807
4757
 
4808
4758
  typedef struct {
4809
- int64_t v;
4759
+ ca_u_int64_t v;
4810
4760
  ca_size_t i;
4811
4761
  } partition_index_pair_i64;
4812
4762
 
@@ -4891,6 +4841,10 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4891
4841
  positions align between iterators. */
4892
4842
  int8_t slab_axes[CA_RANK_MAX];
4893
4843
  slab_axes[0] = (int8_t) axis;
4844
+ ca_size_t fiber_n = ca->dim[axis];
4845
+ volatile VALUE hbuf = 0, haux = 0;
4846
+ partition_index_pair_i64 *buf = ALLOCV_N(partition_index_pair_i64, hbuf, fiber_n);
4847
+ (void) haux;
4894
4848
  ca_iter_state st_in, st_out;
4895
4849
  int rc;
4896
4850
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -4905,11 +4859,6 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4905
4859
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
4906
4860
  }
4907
4861
 
4908
- ca_size_t fiber_n = st_in.slab_elements;
4909
- volatile VALUE hbuf = 0, haux = 0;
4910
- partition_index_pair_i64 *buf = ALLOCV_N(partition_index_pair_i64, hbuf, fiber_n);
4911
- (void) haux;
4912
-
4913
4862
  char *pi, *po;
4914
4863
  boolean8_t *mi, *mo;
4915
4864
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -4926,13 +4875,13 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4926
4875
  if ( masked_last ) {
4927
4876
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4928
4877
  if ( mi[k * mstride] ) continue;
4929
- buf[n_valid].v = *(int64_t *) (pi + k * istride);
4878
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
4930
4879
  buf[n_valid].i = k;
4931
4880
  n_valid++;
4932
4881
  }
4933
4882
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4934
4883
  if ( ! mi[k * mstride] ) continue;
4935
- buf[n_valid + n_masked].v = *(int64_t *) (pi + k * istride);
4884
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
4936
4885
  buf[n_valid + n_masked].i = k;
4937
4886
  n_masked++;
4938
4887
  }
@@ -4940,13 +4889,13 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4940
4889
  } else {
4941
4890
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4942
4891
  if ( ! mi[k * mstride] ) continue;
4943
- buf[n_masked].v = *(int64_t *) (pi + k * istride);
4892
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
4944
4893
  buf[n_masked].i = k;
4945
4894
  n_masked++;
4946
4895
  }
4947
4896
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4948
4897
  if ( mi[k * mstride] ) continue;
4949
- buf[n_masked + n_valid].v = *(int64_t *) (pi + k * istride);
4898
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
4950
4899
  buf[n_masked + n_valid].i = k;
4951
4900
  n_valid++;
4952
4901
  }
@@ -4954,7 +4903,7 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4954
4903
  }
4955
4904
  } else {
4956
4905
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
4957
- buf[k].v = *(int64_t *) (pi + k * istride);
4906
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
4958
4907
  buf[k].i = k;
4959
4908
  }
4960
4909
  sort_lo = 0; sort_n = fiber_n;
@@ -4985,7 +4934,7 @@ partition_index_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
4985
4934
  }
4986
4935
 
4987
4936
  typedef struct {
4988
- uint64_t v;
4937
+ ca_u_uint64_t v;
4989
4938
  ca_size_t i;
4990
4939
  } partition_index_pair_u64;
4991
4940
 
@@ -5070,6 +5019,10 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5070
5019
  positions align between iterators. */
5071
5020
  int8_t slab_axes[CA_RANK_MAX];
5072
5021
  slab_axes[0] = (int8_t) axis;
5022
+ ca_size_t fiber_n = ca->dim[axis];
5023
+ volatile VALUE hbuf = 0, haux = 0;
5024
+ partition_index_pair_u64 *buf = ALLOCV_N(partition_index_pair_u64, hbuf, fiber_n);
5025
+ (void) haux;
5073
5026
  ca_iter_state st_in, st_out;
5074
5027
  int rc;
5075
5028
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5084,11 +5037,6 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5084
5037
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5085
5038
  }
5086
5039
 
5087
- ca_size_t fiber_n = st_in.slab_elements;
5088
- volatile VALUE hbuf = 0, haux = 0;
5089
- partition_index_pair_u64 *buf = ALLOCV_N(partition_index_pair_u64, hbuf, fiber_n);
5090
- (void) haux;
5091
-
5092
5040
  char *pi, *po;
5093
5041
  boolean8_t *mi, *mo;
5094
5042
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5105,13 +5053,13 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5105
5053
  if ( masked_last ) {
5106
5054
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5107
5055
  if ( mi[k * mstride] ) continue;
5108
- buf[n_valid].v = *(uint64_t *) (pi + k * istride);
5056
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
5109
5057
  buf[n_valid].i = k;
5110
5058
  n_valid++;
5111
5059
  }
5112
5060
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5113
5061
  if ( ! mi[k * mstride] ) continue;
5114
- buf[n_valid + n_masked].v = *(uint64_t *) (pi + k * istride);
5062
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
5115
5063
  buf[n_valid + n_masked].i = k;
5116
5064
  n_masked++;
5117
5065
  }
@@ -5119,13 +5067,13 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5119
5067
  } else {
5120
5068
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5121
5069
  if ( ! mi[k * mstride] ) continue;
5122
- buf[n_masked].v = *(uint64_t *) (pi + k * istride);
5070
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
5123
5071
  buf[n_masked].i = k;
5124
5072
  n_masked++;
5125
5073
  }
5126
5074
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5127
5075
  if ( mi[k * mstride] ) continue;
5128
- buf[n_masked + n_valid].v = *(uint64_t *) (pi + k * istride);
5076
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
5129
5077
  buf[n_masked + n_valid].i = k;
5130
5078
  n_valid++;
5131
5079
  }
@@ -5133,7 +5081,7 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5133
5081
  }
5134
5082
  } else {
5135
5083
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5136
- buf[k].v = *(uint64_t *) (pi + k * istride);
5084
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
5137
5085
  buf[k].i = k;
5138
5086
  }
5139
5087
  sort_lo = 0; sort_n = fiber_n;
@@ -5164,7 +5112,7 @@ partition_index_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5164
5112
  }
5165
5113
 
5166
5114
  typedef struct {
5167
- float v;
5115
+ ca_u_float32_t v;
5168
5116
  ca_size_t i;
5169
5117
  } partition_index_pair_f32;
5170
5118
 
@@ -5249,6 +5197,10 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5249
5197
  positions align between iterators. */
5250
5198
  int8_t slab_axes[CA_RANK_MAX];
5251
5199
  slab_axes[0] = (int8_t) axis;
5200
+ ca_size_t fiber_n = ca->dim[axis];
5201
+ volatile VALUE hbuf = 0, haux = 0;
5202
+ partition_index_pair_f32 *buf = ALLOCV_N(partition_index_pair_f32, hbuf, fiber_n);
5203
+ (void) haux;
5252
5204
  ca_iter_state st_in, st_out;
5253
5205
  int rc;
5254
5206
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5263,11 +5215,6 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5263
5215
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5264
5216
  }
5265
5217
 
5266
- ca_size_t fiber_n = st_in.slab_elements;
5267
- volatile VALUE hbuf = 0, haux = 0;
5268
- partition_index_pair_f32 *buf = ALLOCV_N(partition_index_pair_f32, hbuf, fiber_n);
5269
- (void) haux;
5270
-
5271
5218
  char *pi, *po;
5272
5219
  boolean8_t *mi, *mo;
5273
5220
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5284,13 +5231,13 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5284
5231
  if ( masked_last ) {
5285
5232
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5286
5233
  if ( mi[k * mstride] ) continue;
5287
- buf[n_valid].v = *(float *) (pi + k * istride);
5234
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
5288
5235
  buf[n_valid].i = k;
5289
5236
  n_valid++;
5290
5237
  }
5291
5238
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5292
5239
  if ( ! mi[k * mstride] ) continue;
5293
- buf[n_valid + n_masked].v = *(float *) (pi + k * istride);
5240
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
5294
5241
  buf[n_valid + n_masked].i = k;
5295
5242
  n_masked++;
5296
5243
  }
@@ -5298,13 +5245,13 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5298
5245
  } else {
5299
5246
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5300
5247
  if ( ! mi[k * mstride] ) continue;
5301
- buf[n_masked].v = *(float *) (pi + k * istride);
5248
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
5302
5249
  buf[n_masked].i = k;
5303
5250
  n_masked++;
5304
5251
  }
5305
5252
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5306
5253
  if ( mi[k * mstride] ) continue;
5307
- buf[n_masked + n_valid].v = *(float *) (pi + k * istride);
5254
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
5308
5255
  buf[n_masked + n_valid].i = k;
5309
5256
  n_valid++;
5310
5257
  }
@@ -5312,7 +5259,7 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5312
5259
  }
5313
5260
  } else {
5314
5261
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5315
- buf[k].v = *(float *) (pi + k * istride);
5262
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
5316
5263
  buf[k].i = k;
5317
5264
  }
5318
5265
  sort_lo = 0; sort_n = fiber_n;
@@ -5343,7 +5290,7 @@ partition_index_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5343
5290
  }
5344
5291
 
5345
5292
  typedef struct {
5346
- double v;
5293
+ ca_u_float64_t v;
5347
5294
  ca_size_t i;
5348
5295
  } partition_index_pair_f64;
5349
5296
 
@@ -5428,6 +5375,10 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5428
5375
  positions align between iterators. */
5429
5376
  int8_t slab_axes[CA_RANK_MAX];
5430
5377
  slab_axes[0] = (int8_t) axis;
5378
+ ca_size_t fiber_n = ca->dim[axis];
5379
+ volatile VALUE hbuf = 0, haux = 0;
5380
+ partition_index_pair_f64 *buf = ALLOCV_N(partition_index_pair_f64, hbuf, fiber_n);
5381
+ (void) haux;
5431
5382
  ca_iter_state st_in, st_out;
5432
5383
  int rc;
5433
5384
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5442,11 +5393,6 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5442
5393
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5443
5394
  }
5444
5395
 
5445
- ca_size_t fiber_n = st_in.slab_elements;
5446
- volatile VALUE hbuf = 0, haux = 0;
5447
- partition_index_pair_f64 *buf = ALLOCV_N(partition_index_pair_f64, hbuf, fiber_n);
5448
- (void) haux;
5449
-
5450
5396
  char *pi, *po;
5451
5397
  boolean8_t *mi, *mo;
5452
5398
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5463,13 +5409,13 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5463
5409
  if ( masked_last ) {
5464
5410
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5465
5411
  if ( mi[k * mstride] ) continue;
5466
- buf[n_valid].v = *(double *) (pi + k * istride);
5412
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
5467
5413
  buf[n_valid].i = k;
5468
5414
  n_valid++;
5469
5415
  }
5470
5416
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5471
5417
  if ( ! mi[k * mstride] ) continue;
5472
- buf[n_valid + n_masked].v = *(double *) (pi + k * istride);
5418
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
5473
5419
  buf[n_valid + n_masked].i = k;
5474
5420
  n_masked++;
5475
5421
  }
@@ -5477,13 +5423,13 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5477
5423
  } else {
5478
5424
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5479
5425
  if ( ! mi[k * mstride] ) continue;
5480
- buf[n_masked].v = *(double *) (pi + k * istride);
5426
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
5481
5427
  buf[n_masked].i = k;
5482
5428
  n_masked++;
5483
5429
  }
5484
5430
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5485
5431
  if ( mi[k * mstride] ) continue;
5486
- buf[n_masked + n_valid].v = *(double *) (pi + k * istride);
5432
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
5487
5433
  buf[n_masked + n_valid].i = k;
5488
5434
  n_valid++;
5489
5435
  }
@@ -5491,7 +5437,7 @@ partition_index_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth,
5491
5437
  }
5492
5438
  } else {
5493
5439
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5494
- buf[k].v = *(double *) (pi + k * istride);
5440
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
5495
5441
  buf[k].i = k;
5496
5442
  }
5497
5443
  sort_lo = 0; sort_n = fiber_n;
@@ -5607,6 +5553,10 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5607
5553
  positions align between iterators. */
5608
5554
  int8_t slab_axes[CA_RANK_MAX];
5609
5555
  slab_axes[0] = (int8_t) axis;
5556
+ ca_size_t fiber_n = ca->dim[axis];
5557
+ volatile VALUE hbuf = 0, haux = 0;
5558
+ partition_index_pair_bool *buf = ALLOCV_N(partition_index_pair_bool, hbuf, fiber_n);
5559
+ (void) haux;
5610
5560
  ca_iter_state st_in, st_out;
5611
5561
  int rc;
5612
5562
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -5621,11 +5571,6 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5621
5571
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5622
5572
  }
5623
5573
 
5624
- ca_size_t fiber_n = st_in.slab_elements;
5625
- volatile VALUE hbuf = 0, haux = 0;
5626
- partition_index_pair_bool *buf = ALLOCV_N(partition_index_pair_bool, hbuf, fiber_n);
5627
- (void) haux;
5628
-
5629
5574
  char *pi, *po;
5630
5575
  boolean8_t *mi, *mo;
5631
5576
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5642,13 +5587,13 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5642
5587
  if ( masked_last ) {
5643
5588
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5644
5589
  if ( mi[k * mstride] ) continue;
5645
- buf[n_valid].v = *(boolean8_t *) (pi + k * istride);
5590
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
5646
5591
  buf[n_valid].i = k;
5647
5592
  n_valid++;
5648
5593
  }
5649
5594
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5650
5595
  if ( ! mi[k * mstride] ) continue;
5651
- buf[n_valid + n_masked].v = *(boolean8_t *) (pi + k * istride);
5596
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
5652
5597
  buf[n_valid + n_masked].i = k;
5653
5598
  n_masked++;
5654
5599
  }
@@ -5656,13 +5601,13 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5656
5601
  } else {
5657
5602
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5658
5603
  if ( ! mi[k * mstride] ) continue;
5659
- buf[n_masked].v = *(boolean8_t *) (pi + k * istride);
5604
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
5660
5605
  buf[n_masked].i = k;
5661
5606
  n_masked++;
5662
5607
  }
5663
5608
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5664
5609
  if ( mi[k * mstride] ) continue;
5665
- buf[n_masked + n_valid].v = *(boolean8_t *) (pi + k * istride);
5610
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
5666
5611
  buf[n_masked + n_valid].i = k;
5667
5612
  n_valid++;
5668
5613
  }
@@ -5670,7 +5615,7 @@ partition_index_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
5670
5615
  }
5671
5616
  } else {
5672
5617
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5673
- buf[k].v = *(boolean8_t *) (pi + k * istride);
5618
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
5674
5619
  buf[k].i = k;
5675
5620
  }
5676
5621
  sort_lo = 0; sort_n = fiber_n;
@@ -5773,9 +5718,9 @@ partition_index_quickselect_object (partition_index_pair_object *arr,
5773
5718
  }
5774
5719
  }
5775
5720
 
5776
- /* The object lane calls Ruby for every cell, so a walk can raise part
5777
- way. Its states live in the caller's frame, and ca_iter_ensure
5778
- finishes them however the body leaves. */
5721
+ /* The walks can raise part way (a Ruby call per cell in the object
5722
+ lane, an allocation in any lane). Their states live in the caller's
5723
+ frame, and ca_iter_ensure finishes them however the body leaves. */
5779
5724
  typedef struct {
5780
5725
  ca_iter_state states[2];
5781
5726
  VALUE self;
@@ -5811,6 +5756,10 @@ partition_index_ki_native_object_body (VALUE arg)
5811
5756
  positions align between iterators. */
5812
5757
  int8_t slab_axes[CA_RANK_MAX];
5813
5758
  slab_axes[0] = (int8_t) axis;
5759
+ ca_size_t fiber_n = ca->dim[axis];
5760
+ volatile VALUE hbuf = 0, haux = 0;
5761
+ partition_index_pair_object *buf = ALLOCV_N(partition_index_pair_object, hbuf, fiber_n);
5762
+ (void) haux;
5814
5763
  int rc;
5815
5764
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
5816
5765
  slab_axes, 1, 0);
@@ -5824,11 +5773,6 @@ partition_index_ki_native_object_body (VALUE arg)
5824
5773
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
5825
5774
  }
5826
5775
 
5827
- ca_size_t fiber_n = st_in.slab_elements;
5828
- volatile VALUE hbuf = 0, haux = 0;
5829
- partition_index_pair_object *buf = ALLOCV_N(partition_index_pair_object, hbuf, fiber_n);
5830
- (void) haux;
5831
-
5832
5776
  char *pi, *po;
5833
5777
  boolean8_t *mi, *mo;
5834
5778
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -5845,13 +5789,13 @@ partition_index_ki_native_object_body (VALUE arg)
5845
5789
  if ( masked_last ) {
5846
5790
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5847
5791
  if ( mi[k * mstride] ) continue;
5848
- buf[n_valid].v = *(VALUE *) (pi + k * istride);
5792
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
5849
5793
  buf[n_valid].i = k;
5850
5794
  n_valid++;
5851
5795
  }
5852
5796
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5853
5797
  if ( ! mi[k * mstride] ) continue;
5854
- buf[n_valid + n_masked].v = *(VALUE *) (pi + k * istride);
5798
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
5855
5799
  buf[n_valid + n_masked].i = k;
5856
5800
  n_masked++;
5857
5801
  }
@@ -5859,13 +5803,13 @@ partition_index_ki_native_object_body (VALUE arg)
5859
5803
  } else {
5860
5804
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5861
5805
  if ( ! mi[k * mstride] ) continue;
5862
- buf[n_masked].v = *(VALUE *) (pi + k * istride);
5806
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
5863
5807
  buf[n_masked].i = k;
5864
5808
  n_masked++;
5865
5809
  }
5866
5810
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5867
5811
  if ( mi[k * mstride] ) continue;
5868
- buf[n_masked + n_valid].v = *(VALUE *) (pi + k * istride);
5812
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
5869
5813
  buf[n_masked + n_valid].i = k;
5870
5814
  n_valid++;
5871
5815
  }
@@ -5873,7 +5817,7 @@ partition_index_ki_native_object_body (VALUE arg)
5873
5817
  }
5874
5818
  } else {
5875
5819
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
5876
- buf[k].v = *(VALUE *) (pi + k * istride);
5820
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
5877
5821
  buf[k].i = k;
5878
5822
  }
5879
5823
  sort_lo = 0; sort_n = fiber_n;
@@ -5914,7 +5858,7 @@ partition_index_ki_native_object (VALUE self, CArray *ca, int axis, ca_size_t kt
5914
5858
  fr.axis = axis;
5915
5859
  fr.kth = kth;
5916
5860
  fr.masked_last = masked_last;
5917
- return ca_iter_ensure(2, fr.states, partition_index_ki_native_object_body, (VALUE) &fr);
5861
+ return ca_iter_ensure_computing(ca, 2, fr.states, partition_index_ki_native_object_body, (VALUE) &fr);
5918
5862
  }
5919
5863
 
5920
5864
 
@@ -6005,6 +5949,10 @@ partition_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kt
6005
5949
  positions align between iterators. */
6006
5950
  int8_t slab_axes[CA_RANK_MAX];
6007
5951
  slab_axes[0] = (int8_t) axis;
5952
+ ca_size_t fiber_n = ca->dim[axis];
5953
+ volatile VALUE hbuf = 0, haux = 0;
5954
+ partition_index_pair_fixlen *buf = ALLOCV_N(partition_index_pair_fixlen, hbuf, fiber_n);
5955
+ (void) haux;
6008
5956
  ca_iter_state st_in, st_out;
6009
5957
  int rc;
6010
5958
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6019,11 +5967,6 @@ partition_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kt
6019
5967
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6020
5968
  }
6021
5969
 
6022
- ca_size_t fiber_n = st_in.slab_elements;
6023
- volatile VALUE hbuf = 0, haux = 0;
6024
- partition_index_pair_fixlen *buf = ALLOCV_N(partition_index_pair_fixlen, hbuf, fiber_n);
6025
- (void) haux;
6026
-
6027
5970
  char *pi, *po;
6028
5971
  boolean8_t *mi, *mo;
6029
5972
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -6260,6 +6203,10 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6260
6203
  positions align between iterators. */
6261
6204
  int8_t slab_axes[CA_RANK_MAX];
6262
6205
  slab_axes[0] = (int8_t) axis;
6206
+ ca_size_t fiber_n = ca->dim[axis];
6207
+ volatile VALUE hbuf = 0, haux = 0;
6208
+ partition_addr_pair_i8 *buf = ALLOCV_N(partition_addr_pair_i8, hbuf, fiber_n);
6209
+ (void) haux;
6263
6210
  ca_iter_state st_in, st_out;
6264
6211
  int rc;
6265
6212
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6274,11 +6221,6 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6274
6221
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6275
6222
  }
6276
6223
 
6277
- ca_size_t fiber_n = st_in.slab_elements;
6278
- volatile VALUE hbuf = 0, haux = 0;
6279
- partition_addr_pair_i8 *buf = ALLOCV_N(partition_addr_pair_i8, hbuf, fiber_n);
6280
- (void) haux;
6281
-
6282
6224
  /* :view_flat semantics: kernel computes view-flat address
6283
6225
  (= row-major position in ca's shape, 0..elements-1) for
6284
6226
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6322,13 +6264,13 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6322
6264
  if ( masked_last ) {
6323
6265
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6324
6266
  if ( mi[k * mstride] ) continue;
6325
- buf[n_valid].v = *(int8_t *) (pi + k * istride);
6267
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
6326
6268
  buf[n_valid].i = outer_off + k * axis_vstride;
6327
6269
  n_valid++;
6328
6270
  }
6329
6271
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6330
6272
  if ( ! mi[k * mstride] ) continue;
6331
- buf[n_valid + n_masked].v = *(int8_t *) (pi + k * istride);
6273
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
6332
6274
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
6333
6275
  n_masked++;
6334
6276
  }
@@ -6336,13 +6278,13 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6336
6278
  } else {
6337
6279
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6338
6280
  if ( ! mi[k * mstride] ) continue;
6339
- buf[n_masked].v = *(int8_t *) (pi + k * istride);
6281
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
6340
6282
  buf[n_masked].i = outer_off + k * axis_vstride;
6341
6283
  n_masked++;
6342
6284
  }
6343
6285
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6344
6286
  if ( mi[k * mstride] ) continue;
6345
- buf[n_masked + n_valid].v = *(int8_t *) (pi + k * istride);
6287
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
6346
6288
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
6347
6289
  n_valid++;
6348
6290
  }
@@ -6350,7 +6292,7 @@ partition_addr_ki_native_i8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6350
6292
  }
6351
6293
  } else {
6352
6294
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6353
- buf[k].v = *(int8_t *) (pi + k * istride);
6295
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
6354
6296
  buf[k].i = outer_off + k * axis_vstride;
6355
6297
  }
6356
6298
  sort_lo = 0; sort_n = fiber_n;
@@ -6471,6 +6413,10 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6471
6413
  positions align between iterators. */
6472
6414
  int8_t slab_axes[CA_RANK_MAX];
6473
6415
  slab_axes[0] = (int8_t) axis;
6416
+ ca_size_t fiber_n = ca->dim[axis];
6417
+ volatile VALUE hbuf = 0, haux = 0;
6418
+ partition_addr_pair_u8 *buf = ALLOCV_N(partition_addr_pair_u8, hbuf, fiber_n);
6419
+ (void) haux;
6474
6420
  ca_iter_state st_in, st_out;
6475
6421
  int rc;
6476
6422
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6485,11 +6431,6 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6485
6431
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6486
6432
  }
6487
6433
 
6488
- ca_size_t fiber_n = st_in.slab_elements;
6489
- volatile VALUE hbuf = 0, haux = 0;
6490
- partition_addr_pair_u8 *buf = ALLOCV_N(partition_addr_pair_u8, hbuf, fiber_n);
6491
- (void) haux;
6492
-
6493
6434
  /* :view_flat semantics: kernel computes view-flat address
6494
6435
  (= row-major position in ca's shape, 0..elements-1) for
6495
6436
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6533,13 +6474,13 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6533
6474
  if ( masked_last ) {
6534
6475
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6535
6476
  if ( mi[k * mstride] ) continue;
6536
- buf[n_valid].v = *(uint8_t *) (pi + k * istride);
6477
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
6537
6478
  buf[n_valid].i = outer_off + k * axis_vstride;
6538
6479
  n_valid++;
6539
6480
  }
6540
6481
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6541
6482
  if ( ! mi[k * mstride] ) continue;
6542
- buf[n_valid + n_masked].v = *(uint8_t *) (pi + k * istride);
6483
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
6543
6484
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
6544
6485
  n_masked++;
6545
6486
  }
@@ -6547,13 +6488,13 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6547
6488
  } else {
6548
6489
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6549
6490
  if ( ! mi[k * mstride] ) continue;
6550
- buf[n_masked].v = *(uint8_t *) (pi + k * istride);
6491
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
6551
6492
  buf[n_masked].i = outer_off + k * axis_vstride;
6552
6493
  n_masked++;
6553
6494
  }
6554
6495
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6555
6496
  if ( mi[k * mstride] ) continue;
6556
- buf[n_masked + n_valid].v = *(uint8_t *) (pi + k * istride);
6497
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
6557
6498
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
6558
6499
  n_valid++;
6559
6500
  }
@@ -6561,7 +6502,7 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6561
6502
  }
6562
6503
  } else {
6563
6504
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6564
- buf[k].v = *(uint8_t *) (pi + k * istride);
6505
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
6565
6506
  buf[k].i = outer_off + k * axis_vstride;
6566
6507
  }
6567
6508
  sort_lo = 0; sort_n = fiber_n;
@@ -6597,7 +6538,7 @@ partition_addr_ki_native_u8 (VALUE self, CArray *ca, int axis, ca_size_t kth, in
6597
6538
  }
6598
6539
 
6599
6540
  typedef struct {
6600
- int16_t v;
6541
+ ca_u_int16_t v;
6601
6542
  ca_size_t i;
6602
6543
  } partition_addr_pair_i16;
6603
6544
 
@@ -6682,6 +6623,10 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6682
6623
  positions align between iterators. */
6683
6624
  int8_t slab_axes[CA_RANK_MAX];
6684
6625
  slab_axes[0] = (int8_t) axis;
6626
+ ca_size_t fiber_n = ca->dim[axis];
6627
+ volatile VALUE hbuf = 0, haux = 0;
6628
+ partition_addr_pair_i16 *buf = ALLOCV_N(partition_addr_pair_i16, hbuf, fiber_n);
6629
+ (void) haux;
6685
6630
  ca_iter_state st_in, st_out;
6686
6631
  int rc;
6687
6632
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6696,11 +6641,6 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6696
6641
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6697
6642
  }
6698
6643
 
6699
- ca_size_t fiber_n = st_in.slab_elements;
6700
- volatile VALUE hbuf = 0, haux = 0;
6701
- partition_addr_pair_i16 *buf = ALLOCV_N(partition_addr_pair_i16, hbuf, fiber_n);
6702
- (void) haux;
6703
-
6704
6644
  /* :view_flat semantics: kernel computes view-flat address
6705
6645
  (= row-major position in ca's shape, 0..elements-1) for
6706
6646
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6744,13 +6684,13 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6744
6684
  if ( masked_last ) {
6745
6685
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6746
6686
  if ( mi[k * mstride] ) continue;
6747
- buf[n_valid].v = *(int16_t *) (pi + k * istride);
6687
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
6748
6688
  buf[n_valid].i = outer_off + k * axis_vstride;
6749
6689
  n_valid++;
6750
6690
  }
6751
6691
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6752
6692
  if ( ! mi[k * mstride] ) continue;
6753
- buf[n_valid + n_masked].v = *(int16_t *) (pi + k * istride);
6693
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
6754
6694
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
6755
6695
  n_masked++;
6756
6696
  }
@@ -6758,13 +6698,13 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6758
6698
  } else {
6759
6699
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6760
6700
  if ( ! mi[k * mstride] ) continue;
6761
- buf[n_masked].v = *(int16_t *) (pi + k * istride);
6701
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
6762
6702
  buf[n_masked].i = outer_off + k * axis_vstride;
6763
6703
  n_masked++;
6764
6704
  }
6765
6705
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6766
6706
  if ( mi[k * mstride] ) continue;
6767
- buf[n_masked + n_valid].v = *(int16_t *) (pi + k * istride);
6707
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
6768
6708
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
6769
6709
  n_valid++;
6770
6710
  }
@@ -6772,7 +6712,7 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6772
6712
  }
6773
6713
  } else {
6774
6714
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6775
- buf[k].v = *(int16_t *) (pi + k * istride);
6715
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
6776
6716
  buf[k].i = outer_off + k * axis_vstride;
6777
6717
  }
6778
6718
  sort_lo = 0; sort_n = fiber_n;
@@ -6808,7 +6748,7 @@ partition_addr_ki_native_i16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6808
6748
  }
6809
6749
 
6810
6750
  typedef struct {
6811
- uint16_t v;
6751
+ ca_u_uint16_t v;
6812
6752
  ca_size_t i;
6813
6753
  } partition_addr_pair_u16;
6814
6754
 
@@ -6893,6 +6833,10 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6893
6833
  positions align between iterators. */
6894
6834
  int8_t slab_axes[CA_RANK_MAX];
6895
6835
  slab_axes[0] = (int8_t) axis;
6836
+ ca_size_t fiber_n = ca->dim[axis];
6837
+ volatile VALUE hbuf = 0, haux = 0;
6838
+ partition_addr_pair_u16 *buf = ALLOCV_N(partition_addr_pair_u16, hbuf, fiber_n);
6839
+ (void) haux;
6896
6840
  ca_iter_state st_in, st_out;
6897
6841
  int rc;
6898
6842
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -6907,11 +6851,6 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6907
6851
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
6908
6852
  }
6909
6853
 
6910
- ca_size_t fiber_n = st_in.slab_elements;
6911
- volatile VALUE hbuf = 0, haux = 0;
6912
- partition_addr_pair_u16 *buf = ALLOCV_N(partition_addr_pair_u16, hbuf, fiber_n);
6913
- (void) haux;
6914
-
6915
6854
  /* :view_flat semantics: kernel computes view-flat address
6916
6855
  (= row-major position in ca's shape, 0..elements-1) for
6917
6856
  each cell. Used to feed CARemap.idx directly (= sort
@@ -6955,13 +6894,13 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6955
6894
  if ( masked_last ) {
6956
6895
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6957
6896
  if ( mi[k * mstride] ) continue;
6958
- buf[n_valid].v = *(uint16_t *) (pi + k * istride);
6897
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
6959
6898
  buf[n_valid].i = outer_off + k * axis_vstride;
6960
6899
  n_valid++;
6961
6900
  }
6962
6901
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6963
6902
  if ( ! mi[k * mstride] ) continue;
6964
- buf[n_valid + n_masked].v = *(uint16_t *) (pi + k * istride);
6903
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
6965
6904
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
6966
6905
  n_masked++;
6967
6906
  }
@@ -6969,13 +6908,13 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6969
6908
  } else {
6970
6909
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6971
6910
  if ( ! mi[k * mstride] ) continue;
6972
- buf[n_masked].v = *(uint16_t *) (pi + k * istride);
6911
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
6973
6912
  buf[n_masked].i = outer_off + k * axis_vstride;
6974
6913
  n_masked++;
6975
6914
  }
6976
6915
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6977
6916
  if ( mi[k * mstride] ) continue;
6978
- buf[n_masked + n_valid].v = *(uint16_t *) (pi + k * istride);
6917
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
6979
6918
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
6980
6919
  n_valid++;
6981
6920
  }
@@ -6983,7 +6922,7 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
6983
6922
  }
6984
6923
  } else {
6985
6924
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
6986
- buf[k].v = *(uint16_t *) (pi + k * istride);
6925
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
6987
6926
  buf[k].i = outer_off + k * axis_vstride;
6988
6927
  }
6989
6928
  sort_lo = 0; sort_n = fiber_n;
@@ -7019,7 +6958,7 @@ partition_addr_ki_native_u16 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7019
6958
  }
7020
6959
 
7021
6960
  typedef struct {
7022
- int32_t v;
6961
+ ca_u_int32_t v;
7023
6962
  ca_size_t i;
7024
6963
  } partition_addr_pair_i32;
7025
6964
 
@@ -7104,6 +7043,10 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7104
7043
  positions align between iterators. */
7105
7044
  int8_t slab_axes[CA_RANK_MAX];
7106
7045
  slab_axes[0] = (int8_t) axis;
7046
+ ca_size_t fiber_n = ca->dim[axis];
7047
+ volatile VALUE hbuf = 0, haux = 0;
7048
+ partition_addr_pair_i32 *buf = ALLOCV_N(partition_addr_pair_i32, hbuf, fiber_n);
7049
+ (void) haux;
7107
7050
  ca_iter_state st_in, st_out;
7108
7051
  int rc;
7109
7052
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7118,11 +7061,6 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7118
7061
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7119
7062
  }
7120
7063
 
7121
- ca_size_t fiber_n = st_in.slab_elements;
7122
- volatile VALUE hbuf = 0, haux = 0;
7123
- partition_addr_pair_i32 *buf = ALLOCV_N(partition_addr_pair_i32, hbuf, fiber_n);
7124
- (void) haux;
7125
-
7126
7064
  /* :view_flat semantics: kernel computes view-flat address
7127
7065
  (= row-major position in ca's shape, 0..elements-1) for
7128
7066
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7166,13 +7104,13 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7166
7104
  if ( masked_last ) {
7167
7105
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7168
7106
  if ( mi[k * mstride] ) continue;
7169
- buf[n_valid].v = *(int32_t *) (pi + k * istride);
7107
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
7170
7108
  buf[n_valid].i = outer_off + k * axis_vstride;
7171
7109
  n_valid++;
7172
7110
  }
7173
7111
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7174
7112
  if ( ! mi[k * mstride] ) continue;
7175
- buf[n_valid + n_masked].v = *(int32_t *) (pi + k * istride);
7113
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
7176
7114
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
7177
7115
  n_masked++;
7178
7116
  }
@@ -7180,13 +7118,13 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7180
7118
  } else {
7181
7119
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7182
7120
  if ( ! mi[k * mstride] ) continue;
7183
- buf[n_masked].v = *(int32_t *) (pi + k * istride);
7121
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
7184
7122
  buf[n_masked].i = outer_off + k * axis_vstride;
7185
7123
  n_masked++;
7186
7124
  }
7187
7125
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7188
7126
  if ( mi[k * mstride] ) continue;
7189
- buf[n_masked + n_valid].v = *(int32_t *) (pi + k * istride);
7127
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
7190
7128
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
7191
7129
  n_valid++;
7192
7130
  }
@@ -7194,7 +7132,7 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7194
7132
  }
7195
7133
  } else {
7196
7134
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7197
- buf[k].v = *(int32_t *) (pi + k * istride);
7135
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
7198
7136
  buf[k].i = outer_off + k * axis_vstride;
7199
7137
  }
7200
7138
  sort_lo = 0; sort_n = fiber_n;
@@ -7230,7 +7168,7 @@ partition_addr_ki_native_i32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7230
7168
  }
7231
7169
 
7232
7170
  typedef struct {
7233
- uint32_t v;
7171
+ ca_u_uint32_t v;
7234
7172
  ca_size_t i;
7235
7173
  } partition_addr_pair_u32;
7236
7174
 
@@ -7315,6 +7253,10 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7315
7253
  positions align between iterators. */
7316
7254
  int8_t slab_axes[CA_RANK_MAX];
7317
7255
  slab_axes[0] = (int8_t) axis;
7256
+ ca_size_t fiber_n = ca->dim[axis];
7257
+ volatile VALUE hbuf = 0, haux = 0;
7258
+ partition_addr_pair_u32 *buf = ALLOCV_N(partition_addr_pair_u32, hbuf, fiber_n);
7259
+ (void) haux;
7318
7260
  ca_iter_state st_in, st_out;
7319
7261
  int rc;
7320
7262
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7329,11 +7271,6 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7329
7271
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7330
7272
  }
7331
7273
 
7332
- ca_size_t fiber_n = st_in.slab_elements;
7333
- volatile VALUE hbuf = 0, haux = 0;
7334
- partition_addr_pair_u32 *buf = ALLOCV_N(partition_addr_pair_u32, hbuf, fiber_n);
7335
- (void) haux;
7336
-
7337
7274
  /* :view_flat semantics: kernel computes view-flat address
7338
7275
  (= row-major position in ca's shape, 0..elements-1) for
7339
7276
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7377,13 +7314,13 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7377
7314
  if ( masked_last ) {
7378
7315
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7379
7316
  if ( mi[k * mstride] ) continue;
7380
- buf[n_valid].v = *(uint32_t *) (pi + k * istride);
7317
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
7381
7318
  buf[n_valid].i = outer_off + k * axis_vstride;
7382
7319
  n_valid++;
7383
7320
  }
7384
7321
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7385
7322
  if ( ! mi[k * mstride] ) continue;
7386
- buf[n_valid + n_masked].v = *(uint32_t *) (pi + k * istride);
7323
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
7387
7324
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
7388
7325
  n_masked++;
7389
7326
  }
@@ -7391,13 +7328,13 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7391
7328
  } else {
7392
7329
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7393
7330
  if ( ! mi[k * mstride] ) continue;
7394
- buf[n_masked].v = *(uint32_t *) (pi + k * istride);
7331
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
7395
7332
  buf[n_masked].i = outer_off + k * axis_vstride;
7396
7333
  n_masked++;
7397
7334
  }
7398
7335
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7399
7336
  if ( mi[k * mstride] ) continue;
7400
- buf[n_masked + n_valid].v = *(uint32_t *) (pi + k * istride);
7337
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
7401
7338
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
7402
7339
  n_valid++;
7403
7340
  }
@@ -7405,7 +7342,7 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7405
7342
  }
7406
7343
  } else {
7407
7344
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7408
- buf[k].v = *(uint32_t *) (pi + k * istride);
7345
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
7409
7346
  buf[k].i = outer_off + k * axis_vstride;
7410
7347
  }
7411
7348
  sort_lo = 0; sort_n = fiber_n;
@@ -7441,7 +7378,7 @@ partition_addr_ki_native_u32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7441
7378
  }
7442
7379
 
7443
7380
  typedef struct {
7444
- int64_t v;
7381
+ ca_u_int64_t v;
7445
7382
  ca_size_t i;
7446
7383
  } partition_addr_pair_i64;
7447
7384
 
@@ -7526,6 +7463,10 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7526
7463
  positions align between iterators. */
7527
7464
  int8_t slab_axes[CA_RANK_MAX];
7528
7465
  slab_axes[0] = (int8_t) axis;
7466
+ ca_size_t fiber_n = ca->dim[axis];
7467
+ volatile VALUE hbuf = 0, haux = 0;
7468
+ partition_addr_pair_i64 *buf = ALLOCV_N(partition_addr_pair_i64, hbuf, fiber_n);
7469
+ (void) haux;
7529
7470
  ca_iter_state st_in, st_out;
7530
7471
  int rc;
7531
7472
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7540,11 +7481,6 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7540
7481
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7541
7482
  }
7542
7483
 
7543
- ca_size_t fiber_n = st_in.slab_elements;
7544
- volatile VALUE hbuf = 0, haux = 0;
7545
- partition_addr_pair_i64 *buf = ALLOCV_N(partition_addr_pair_i64, hbuf, fiber_n);
7546
- (void) haux;
7547
-
7548
7484
  /* :view_flat semantics: kernel computes view-flat address
7549
7485
  (= row-major position in ca's shape, 0..elements-1) for
7550
7486
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7588,13 +7524,13 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7588
7524
  if ( masked_last ) {
7589
7525
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7590
7526
  if ( mi[k * mstride] ) continue;
7591
- buf[n_valid].v = *(int64_t *) (pi + k * istride);
7527
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
7592
7528
  buf[n_valid].i = outer_off + k * axis_vstride;
7593
7529
  n_valid++;
7594
7530
  }
7595
7531
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7596
7532
  if ( ! mi[k * mstride] ) continue;
7597
- buf[n_valid + n_masked].v = *(int64_t *) (pi + k * istride);
7533
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
7598
7534
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
7599
7535
  n_masked++;
7600
7536
  }
@@ -7602,13 +7538,13 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7602
7538
  } else {
7603
7539
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7604
7540
  if ( ! mi[k * mstride] ) continue;
7605
- buf[n_masked].v = *(int64_t *) (pi + k * istride);
7541
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
7606
7542
  buf[n_masked].i = outer_off + k * axis_vstride;
7607
7543
  n_masked++;
7608
7544
  }
7609
7545
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7610
7546
  if ( mi[k * mstride] ) continue;
7611
- buf[n_masked + n_valid].v = *(int64_t *) (pi + k * istride);
7547
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
7612
7548
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
7613
7549
  n_valid++;
7614
7550
  }
@@ -7616,7 +7552,7 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7616
7552
  }
7617
7553
  } else {
7618
7554
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7619
- buf[k].v = *(int64_t *) (pi + k * istride);
7555
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
7620
7556
  buf[k].i = outer_off + k * axis_vstride;
7621
7557
  }
7622
7558
  sort_lo = 0; sort_n = fiber_n;
@@ -7652,7 +7588,7 @@ partition_addr_ki_native_i64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7652
7588
  }
7653
7589
 
7654
7590
  typedef struct {
7655
- uint64_t v;
7591
+ ca_u_uint64_t v;
7656
7592
  ca_size_t i;
7657
7593
  } partition_addr_pair_u64;
7658
7594
 
@@ -7737,6 +7673,10 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7737
7673
  positions align between iterators. */
7738
7674
  int8_t slab_axes[CA_RANK_MAX];
7739
7675
  slab_axes[0] = (int8_t) axis;
7676
+ ca_size_t fiber_n = ca->dim[axis];
7677
+ volatile VALUE hbuf = 0, haux = 0;
7678
+ partition_addr_pair_u64 *buf = ALLOCV_N(partition_addr_pair_u64, hbuf, fiber_n);
7679
+ (void) haux;
7740
7680
  ca_iter_state st_in, st_out;
7741
7681
  int rc;
7742
7682
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7751,11 +7691,6 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7751
7691
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7752
7692
  }
7753
7693
 
7754
- ca_size_t fiber_n = st_in.slab_elements;
7755
- volatile VALUE hbuf = 0, haux = 0;
7756
- partition_addr_pair_u64 *buf = ALLOCV_N(partition_addr_pair_u64, hbuf, fiber_n);
7757
- (void) haux;
7758
-
7759
7694
  /* :view_flat semantics: kernel computes view-flat address
7760
7695
  (= row-major position in ca's shape, 0..elements-1) for
7761
7696
  each cell. Used to feed CARemap.idx directly (= sort
@@ -7799,13 +7734,13 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7799
7734
  if ( masked_last ) {
7800
7735
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7801
7736
  if ( mi[k * mstride] ) continue;
7802
- buf[n_valid].v = *(uint64_t *) (pi + k * istride);
7737
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
7803
7738
  buf[n_valid].i = outer_off + k * axis_vstride;
7804
7739
  n_valid++;
7805
7740
  }
7806
7741
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7807
7742
  if ( ! mi[k * mstride] ) continue;
7808
- buf[n_valid + n_masked].v = *(uint64_t *) (pi + k * istride);
7743
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
7809
7744
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
7810
7745
  n_masked++;
7811
7746
  }
@@ -7813,13 +7748,13 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7813
7748
  } else {
7814
7749
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7815
7750
  if ( ! mi[k * mstride] ) continue;
7816
- buf[n_masked].v = *(uint64_t *) (pi + k * istride);
7751
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
7817
7752
  buf[n_masked].i = outer_off + k * axis_vstride;
7818
7753
  n_masked++;
7819
7754
  }
7820
7755
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7821
7756
  if ( mi[k * mstride] ) continue;
7822
- buf[n_masked + n_valid].v = *(uint64_t *) (pi + k * istride);
7757
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
7823
7758
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
7824
7759
  n_valid++;
7825
7760
  }
@@ -7827,7 +7762,7 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7827
7762
  }
7828
7763
  } else {
7829
7764
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
7830
- buf[k].v = *(uint64_t *) (pi + k * istride);
7765
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
7831
7766
  buf[k].i = outer_off + k * axis_vstride;
7832
7767
  }
7833
7768
  sort_lo = 0; sort_n = fiber_n;
@@ -7863,7 +7798,7 @@ partition_addr_ki_native_u64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7863
7798
  }
7864
7799
 
7865
7800
  typedef struct {
7866
- float v;
7801
+ ca_u_float32_t v;
7867
7802
  ca_size_t i;
7868
7803
  } partition_addr_pair_f32;
7869
7804
 
@@ -7948,6 +7883,10 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7948
7883
  positions align between iterators. */
7949
7884
  int8_t slab_axes[CA_RANK_MAX];
7950
7885
  slab_axes[0] = (int8_t) axis;
7886
+ ca_size_t fiber_n = ca->dim[axis];
7887
+ volatile VALUE hbuf = 0, haux = 0;
7888
+ partition_addr_pair_f32 *buf = ALLOCV_N(partition_addr_pair_f32, hbuf, fiber_n);
7889
+ (void) haux;
7951
7890
  ca_iter_state st_in, st_out;
7952
7891
  int rc;
7953
7892
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -7962,11 +7901,6 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
7962
7901
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
7963
7902
  }
7964
7903
 
7965
- ca_size_t fiber_n = st_in.slab_elements;
7966
- volatile VALUE hbuf = 0, haux = 0;
7967
- partition_addr_pair_f32 *buf = ALLOCV_N(partition_addr_pair_f32, hbuf, fiber_n);
7968
- (void) haux;
7969
-
7970
7904
  /* :view_flat semantics: kernel computes view-flat address
7971
7905
  (= row-major position in ca's shape, 0..elements-1) for
7972
7906
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8010,13 +7944,13 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8010
7944
  if ( masked_last ) {
8011
7945
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8012
7946
  if ( mi[k * mstride] ) continue;
8013
- buf[n_valid].v = *(float *) (pi + k * istride);
7947
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
8014
7948
  buf[n_valid].i = outer_off + k * axis_vstride;
8015
7949
  n_valid++;
8016
7950
  }
8017
7951
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8018
7952
  if ( ! mi[k * mstride] ) continue;
8019
- buf[n_valid + n_masked].v = *(float *) (pi + k * istride);
7953
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
8020
7954
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
8021
7955
  n_masked++;
8022
7956
  }
@@ -8024,13 +7958,13 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8024
7958
  } else {
8025
7959
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8026
7960
  if ( ! mi[k * mstride] ) continue;
8027
- buf[n_masked].v = *(float *) (pi + k * istride);
7961
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
8028
7962
  buf[n_masked].i = outer_off + k * axis_vstride;
8029
7963
  n_masked++;
8030
7964
  }
8031
7965
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8032
7966
  if ( mi[k * mstride] ) continue;
8033
- buf[n_masked + n_valid].v = *(float *) (pi + k * istride);
7967
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
8034
7968
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
8035
7969
  n_valid++;
8036
7970
  }
@@ -8038,7 +7972,7 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8038
7972
  }
8039
7973
  } else {
8040
7974
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8041
- buf[k].v = *(float *) (pi + k * istride);
7975
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
8042
7976
  buf[k].i = outer_off + k * axis_vstride;
8043
7977
  }
8044
7978
  sort_lo = 0; sort_n = fiber_n;
@@ -8074,7 +8008,7 @@ partition_addr_ki_native_f32 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8074
8008
  }
8075
8009
 
8076
8010
  typedef struct {
8077
- double v;
8011
+ ca_u_float64_t v;
8078
8012
  ca_size_t i;
8079
8013
  } partition_addr_pair_f64;
8080
8014
 
@@ -8159,6 +8093,10 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8159
8093
  positions align between iterators. */
8160
8094
  int8_t slab_axes[CA_RANK_MAX];
8161
8095
  slab_axes[0] = (int8_t) axis;
8096
+ ca_size_t fiber_n = ca->dim[axis];
8097
+ volatile VALUE hbuf = 0, haux = 0;
8098
+ partition_addr_pair_f64 *buf = ALLOCV_N(partition_addr_pair_f64, hbuf, fiber_n);
8099
+ (void) haux;
8162
8100
  ca_iter_state st_in, st_out;
8163
8101
  int rc;
8164
8102
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8173,11 +8111,6 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8173
8111
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8174
8112
  }
8175
8113
 
8176
- ca_size_t fiber_n = st_in.slab_elements;
8177
- volatile VALUE hbuf = 0, haux = 0;
8178
- partition_addr_pair_f64 *buf = ALLOCV_N(partition_addr_pair_f64, hbuf, fiber_n);
8179
- (void) haux;
8180
-
8181
8114
  /* :view_flat semantics: kernel computes view-flat address
8182
8115
  (= row-major position in ca's shape, 0..elements-1) for
8183
8116
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8221,13 +8154,13 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8221
8154
  if ( masked_last ) {
8222
8155
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8223
8156
  if ( mi[k * mstride] ) continue;
8224
- buf[n_valid].v = *(double *) (pi + k * istride);
8157
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
8225
8158
  buf[n_valid].i = outer_off + k * axis_vstride;
8226
8159
  n_valid++;
8227
8160
  }
8228
8161
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8229
8162
  if ( ! mi[k * mstride] ) continue;
8230
- buf[n_valid + n_masked].v = *(double *) (pi + k * istride);
8163
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
8231
8164
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
8232
8165
  n_masked++;
8233
8166
  }
@@ -8235,13 +8168,13 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8235
8168
  } else {
8236
8169
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8237
8170
  if ( ! mi[k * mstride] ) continue;
8238
- buf[n_masked].v = *(double *) (pi + k * istride);
8171
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
8239
8172
  buf[n_masked].i = outer_off + k * axis_vstride;
8240
8173
  n_masked++;
8241
8174
  }
8242
8175
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8243
8176
  if ( mi[k * mstride] ) continue;
8244
- buf[n_masked + n_valid].v = *(double *) (pi + k * istride);
8177
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
8245
8178
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
8246
8179
  n_valid++;
8247
8180
  }
@@ -8249,7 +8182,7 @@ partition_addr_ki_native_f64 (VALUE self, CArray *ca, int axis, ca_size_t kth, i
8249
8182
  }
8250
8183
  } else {
8251
8184
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8252
- buf[k].v = *(double *) (pi + k * istride);
8185
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
8253
8186
  buf[k].i = outer_off + k * axis_vstride;
8254
8187
  }
8255
8188
  sort_lo = 0; sort_n = fiber_n;
@@ -8370,6 +8303,10 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8370
8303
  positions align between iterators. */
8371
8304
  int8_t slab_axes[CA_RANK_MAX];
8372
8305
  slab_axes[0] = (int8_t) axis;
8306
+ ca_size_t fiber_n = ca->dim[axis];
8307
+ volatile VALUE hbuf = 0, haux = 0;
8308
+ partition_addr_pair_bool *buf = ALLOCV_N(partition_addr_pair_bool, hbuf, fiber_n);
8309
+ (void) haux;
8373
8310
  ca_iter_state st_in, st_out;
8374
8311
  int rc;
8375
8312
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8384,11 +8321,6 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8384
8321
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8385
8322
  }
8386
8323
 
8387
- ca_size_t fiber_n = st_in.slab_elements;
8388
- volatile VALUE hbuf = 0, haux = 0;
8389
- partition_addr_pair_bool *buf = ALLOCV_N(partition_addr_pair_bool, hbuf, fiber_n);
8390
- (void) haux;
8391
-
8392
8324
  /* :view_flat semantics: kernel computes view-flat address
8393
8325
  (= row-major position in ca's shape, 0..elements-1) for
8394
8326
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8432,13 +8364,13 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8432
8364
  if ( masked_last ) {
8433
8365
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8434
8366
  if ( mi[k * mstride] ) continue;
8435
- buf[n_valid].v = *(boolean8_t *) (pi + k * istride);
8367
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
8436
8368
  buf[n_valid].i = outer_off + k * axis_vstride;
8437
8369
  n_valid++;
8438
8370
  }
8439
8371
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8440
8372
  if ( ! mi[k * mstride] ) continue;
8441
- buf[n_valid + n_masked].v = *(boolean8_t *) (pi + k * istride);
8373
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
8442
8374
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
8443
8375
  n_masked++;
8444
8376
  }
@@ -8446,13 +8378,13 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8446
8378
  } else {
8447
8379
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8448
8380
  if ( ! mi[k * mstride] ) continue;
8449
- buf[n_masked].v = *(boolean8_t *) (pi + k * istride);
8381
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
8450
8382
  buf[n_masked].i = outer_off + k * axis_vstride;
8451
8383
  n_masked++;
8452
8384
  }
8453
8385
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8454
8386
  if ( mi[k * mstride] ) continue;
8455
- buf[n_masked + n_valid].v = *(boolean8_t *) (pi + k * istride);
8387
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
8456
8388
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
8457
8389
  n_valid++;
8458
8390
  }
@@ -8460,7 +8392,7 @@ partition_addr_ki_native_bool (VALUE self, CArray *ca, int axis, ca_size_t kth,
8460
8392
  }
8461
8393
  } else {
8462
8394
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8463
- buf[k].v = *(boolean8_t *) (pi + k * istride);
8395
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
8464
8396
  buf[k].i = outer_off + k * axis_vstride;
8465
8397
  }
8466
8398
  sort_lo = 0; sort_n = fiber_n;
@@ -8568,9 +8500,9 @@ partition_addr_quickselect_object (partition_addr_pair_object *arr,
8568
8500
  }
8569
8501
  }
8570
8502
 
8571
- /* The object lane calls Ruby for every cell, so a walk can raise part
8572
- way. Its states live in the caller's frame, and ca_iter_ensure
8573
- finishes them however the body leaves. */
8503
+ /* The walks can raise part way (a Ruby call per cell in the object
8504
+ lane, an allocation in any lane). Their states live in the caller's
8505
+ frame, and ca_iter_ensure finishes them however the body leaves. */
8574
8506
  typedef struct {
8575
8507
  ca_iter_state states[2];
8576
8508
  VALUE self;
@@ -8606,6 +8538,10 @@ partition_addr_ki_native_object_body (VALUE arg)
8606
8538
  positions align between iterators. */
8607
8539
  int8_t slab_axes[CA_RANK_MAX];
8608
8540
  slab_axes[0] = (int8_t) axis;
8541
+ ca_size_t fiber_n = ca->dim[axis];
8542
+ volatile VALUE hbuf = 0, haux = 0;
8543
+ partition_addr_pair_object *buf = ALLOCV_N(partition_addr_pair_object, hbuf, fiber_n);
8544
+ (void) haux;
8609
8545
  int rc;
8610
8546
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
8611
8547
  slab_axes, 1, 0);
@@ -8619,11 +8555,6 @@ partition_addr_ki_native_object_body (VALUE arg)
8619
8555
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8620
8556
  }
8621
8557
 
8622
- ca_size_t fiber_n = st_in.slab_elements;
8623
- volatile VALUE hbuf = 0, haux = 0;
8624
- partition_addr_pair_object *buf = ALLOCV_N(partition_addr_pair_object, hbuf, fiber_n);
8625
- (void) haux;
8626
-
8627
8558
  /* :view_flat semantics: kernel computes view-flat address
8628
8559
  (= row-major position in ca's shape, 0..elements-1) for
8629
8560
  each cell. Used to feed CARemap.idx directly (= sort
@@ -8667,13 +8598,13 @@ partition_addr_ki_native_object_body (VALUE arg)
8667
8598
  if ( masked_last ) {
8668
8599
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8669
8600
  if ( mi[k * mstride] ) continue;
8670
- buf[n_valid].v = *(VALUE *) (pi + k * istride);
8601
+ memcpy(&buf[n_valid].v, pi + k * istride, sizeof(buf[n_valid].v));
8671
8602
  buf[n_valid].i = outer_off + k * axis_vstride;
8672
8603
  n_valid++;
8673
8604
  }
8674
8605
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8675
8606
  if ( ! mi[k * mstride] ) continue;
8676
- buf[n_valid + n_masked].v = *(VALUE *) (pi + k * istride);
8607
+ memcpy(&buf[n_valid + n_masked].v, pi + k * istride, sizeof(buf[n_valid + n_masked].v));
8677
8608
  buf[n_valid + n_masked].i = outer_off + k * axis_vstride;
8678
8609
  n_masked++;
8679
8610
  }
@@ -8681,13 +8612,13 @@ partition_addr_ki_native_object_body (VALUE arg)
8681
8612
  } else {
8682
8613
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8683
8614
  if ( ! mi[k * mstride] ) continue;
8684
- buf[n_masked].v = *(VALUE *) (pi + k * istride);
8615
+ memcpy(&buf[n_masked].v, pi + k * istride, sizeof(buf[n_masked].v));
8685
8616
  buf[n_masked].i = outer_off + k * axis_vstride;
8686
8617
  n_masked++;
8687
8618
  }
8688
8619
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8689
8620
  if ( mi[k * mstride] ) continue;
8690
- buf[n_masked + n_valid].v = *(VALUE *) (pi + k * istride);
8621
+ memcpy(&buf[n_masked + n_valid].v, pi + k * istride, sizeof(buf[n_masked + n_valid].v));
8691
8622
  buf[n_masked + n_valid].i = outer_off + k * axis_vstride;
8692
8623
  n_valid++;
8693
8624
  }
@@ -8695,7 +8626,7 @@ partition_addr_ki_native_object_body (VALUE arg)
8695
8626
  }
8696
8627
  } else {
8697
8628
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
8698
- buf[k].v = *(VALUE *) (pi + k * istride);
8629
+ memcpy(&buf[k].v, pi + k * istride, sizeof(buf[k].v));
8699
8630
  buf[k].i = outer_off + k * axis_vstride;
8700
8631
  }
8701
8632
  sort_lo = 0; sort_n = fiber_n;
@@ -8741,7 +8672,7 @@ partition_addr_ki_native_object (VALUE self, CArray *ca, int axis, ca_size_t kth
8741
8672
  fr.axis = axis;
8742
8673
  fr.kth = kth;
8743
8674
  fr.masked_last = masked_last;
8744
- return ca_iter_ensure(2, fr.states, partition_addr_ki_native_object_body, (VALUE) &fr);
8675
+ return ca_iter_ensure_computing(ca, 2, fr.states, partition_addr_ki_native_object_body, (VALUE) &fr);
8745
8676
  }
8746
8677
 
8747
8678
 
@@ -8832,6 +8763,10 @@ partition_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kth
8832
8763
  positions align between iterators. */
8833
8764
  int8_t slab_axes[CA_RANK_MAX];
8834
8765
  slab_axes[0] = (int8_t) axis;
8766
+ ca_size_t fiber_n = ca->dim[axis];
8767
+ volatile VALUE hbuf = 0, haux = 0;
8768
+ partition_addr_pair_fixlen *buf = ALLOCV_N(partition_addr_pair_fixlen, hbuf, fiber_n);
8769
+ (void) haux;
8835
8770
  ca_iter_state st_in, st_out;
8836
8771
  int rc;
8837
8772
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -8846,11 +8781,6 @@ partition_addr_ki_native_fixlen (VALUE self, CArray *ca, int axis, ca_size_t kth
8846
8781
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
8847
8782
  }
8848
8783
 
8849
- ca_size_t fiber_n = st_in.slab_elements;
8850
- volatile VALUE hbuf = 0, haux = 0;
8851
- partition_addr_pair_fixlen *buf = ALLOCV_N(partition_addr_pair_fixlen, hbuf, fiber_n);
8852
- (void) haux;
8853
-
8854
8784
  /* :view_flat semantics: kernel computes view-flat address
8855
8785
  (= row-major position in ca's shape, 0..elements-1) for
8856
8786
  each cell. Used to feed CARemap.idx directly (= sort
@@ -9034,6 +8964,13 @@ rank_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9034
8964
  next_slab_axes will then be non-NULL). Created up-front
9035
8965
  when input has any mask. */
9036
8966
  if ( ca_has_mask(ca) ) ca_create_mask(co);
8967
+ ca_size_t fiber_n = ca->dim[axis];
8968
+ volatile VALUE hbuf = 0, haux = 0;
8969
+ rank_index_pair_i8 *buf = ALLOCV_N(rank_index_pair_i8, hbuf, fiber_n);
8970
+ rank_index_pair_i8 *aux = NULL;
8971
+ if ( do_stable ) {
8972
+ aux = ALLOCV_N(rank_index_pair_i8, haux, fiber_n);
8973
+ }
9037
8974
  ca_iter_state st_in, st_out;
9038
8975
  int rc;
9039
8976
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9048,14 +8985,6 @@ rank_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9048
8985
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9049
8986
  }
9050
8987
 
9051
- ca_size_t fiber_n = st_in.slab_elements;
9052
- volatile VALUE hbuf = 0, haux = 0;
9053
- rank_index_pair_i8 *buf = ALLOCV_N(rank_index_pair_i8, hbuf, fiber_n);
9054
- rank_index_pair_i8 *aux = NULL;
9055
- if ( do_stable ) {
9056
- aux = ALLOCV_N(rank_index_pair_i8, haux, fiber_n);
9057
- }
9058
-
9059
8988
  char *pi, *po;
9060
8989
  boolean8_t *mi, *mo;
9061
8990
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9068,7 +8997,7 @@ rank_index_ki_native_i8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9068
8997
  ca_size_t k_unmasked = 0;
9069
8998
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9070
8999
  if ( mi && mi[k * mstride] ) continue;
9071
- buf[k_unmasked].v = *(int8_t *) (pi + k * istride);
9000
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9072
9001
  buf[k_unmasked].i = k;
9073
9002
  k_unmasked++;
9074
9003
  }
@@ -9165,6 +9094,13 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9165
9094
  next_slab_axes will then be non-NULL). Created up-front
9166
9095
  when input has any mask. */
9167
9096
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9097
+ ca_size_t fiber_n = ca->dim[axis];
9098
+ volatile VALUE hbuf = 0, haux = 0;
9099
+ rank_index_pair_u8 *buf = ALLOCV_N(rank_index_pair_u8, hbuf, fiber_n);
9100
+ rank_index_pair_u8 *aux = NULL;
9101
+ if ( do_stable ) {
9102
+ aux = ALLOCV_N(rank_index_pair_u8, haux, fiber_n);
9103
+ }
9168
9104
  ca_iter_state st_in, st_out;
9169
9105
  int rc;
9170
9106
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9179,14 +9115,6 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9179
9115
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9180
9116
  }
9181
9117
 
9182
- ca_size_t fiber_n = st_in.slab_elements;
9183
- volatile VALUE hbuf = 0, haux = 0;
9184
- rank_index_pair_u8 *buf = ALLOCV_N(rank_index_pair_u8, hbuf, fiber_n);
9185
- rank_index_pair_u8 *aux = NULL;
9186
- if ( do_stable ) {
9187
- aux = ALLOCV_N(rank_index_pair_u8, haux, fiber_n);
9188
- }
9189
-
9190
9118
  char *pi, *po;
9191
9119
  boolean8_t *mi, *mo;
9192
9120
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9199,7 +9127,7 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9199
9127
  ca_size_t k_unmasked = 0;
9200
9128
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9201
9129
  if ( mi && mi[k * mstride] ) continue;
9202
- buf[k_unmasked].v = *(uint8_t *) (pi + k * istride);
9130
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9203
9131
  buf[k_unmasked].i = k;
9204
9132
  k_unmasked++;
9205
9133
  }
@@ -9274,7 +9202,7 @@ rank_index_ki_native_u8 (VALUE self, CArray *ca, int axis, int do_stable, int de
9274
9202
  }
9275
9203
 
9276
9204
  typedef struct {
9277
- int16_t v;
9205
+ ca_u_int16_t v;
9278
9206
  ca_size_t i;
9279
9207
  } rank_index_pair_i16;
9280
9208
 
@@ -9296,6 +9224,13 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9296
9224
  next_slab_axes will then be non-NULL). Created up-front
9297
9225
  when input has any mask. */
9298
9226
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9227
+ ca_size_t fiber_n = ca->dim[axis];
9228
+ volatile VALUE hbuf = 0, haux = 0;
9229
+ rank_index_pair_i16 *buf = ALLOCV_N(rank_index_pair_i16, hbuf, fiber_n);
9230
+ rank_index_pair_i16 *aux = NULL;
9231
+ if ( do_stable ) {
9232
+ aux = ALLOCV_N(rank_index_pair_i16, haux, fiber_n);
9233
+ }
9299
9234
  ca_iter_state st_in, st_out;
9300
9235
  int rc;
9301
9236
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9310,14 +9245,6 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9310
9245
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9311
9246
  }
9312
9247
 
9313
- ca_size_t fiber_n = st_in.slab_elements;
9314
- volatile VALUE hbuf = 0, haux = 0;
9315
- rank_index_pair_i16 *buf = ALLOCV_N(rank_index_pair_i16, hbuf, fiber_n);
9316
- rank_index_pair_i16 *aux = NULL;
9317
- if ( do_stable ) {
9318
- aux = ALLOCV_N(rank_index_pair_i16, haux, fiber_n);
9319
- }
9320
-
9321
9248
  char *pi, *po;
9322
9249
  boolean8_t *mi, *mo;
9323
9250
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9330,7 +9257,7 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9330
9257
  ca_size_t k_unmasked = 0;
9331
9258
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9332
9259
  if ( mi && mi[k * mstride] ) continue;
9333
- buf[k_unmasked].v = *(int16_t *) (pi + k * istride);
9260
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9334
9261
  buf[k_unmasked].i = k;
9335
9262
  k_unmasked++;
9336
9263
  }
@@ -9405,7 +9332,7 @@ rank_index_ki_native_i16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9405
9332
  }
9406
9333
 
9407
9334
  typedef struct {
9408
- uint16_t v;
9335
+ ca_u_uint16_t v;
9409
9336
  ca_size_t i;
9410
9337
  } rank_index_pair_u16;
9411
9338
 
@@ -9427,6 +9354,13 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9427
9354
  next_slab_axes will then be non-NULL). Created up-front
9428
9355
  when input has any mask. */
9429
9356
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9357
+ ca_size_t fiber_n = ca->dim[axis];
9358
+ volatile VALUE hbuf = 0, haux = 0;
9359
+ rank_index_pair_u16 *buf = ALLOCV_N(rank_index_pair_u16, hbuf, fiber_n);
9360
+ rank_index_pair_u16 *aux = NULL;
9361
+ if ( do_stable ) {
9362
+ aux = ALLOCV_N(rank_index_pair_u16, haux, fiber_n);
9363
+ }
9430
9364
  ca_iter_state st_in, st_out;
9431
9365
  int rc;
9432
9366
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9441,14 +9375,6 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9441
9375
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9442
9376
  }
9443
9377
 
9444
- ca_size_t fiber_n = st_in.slab_elements;
9445
- volatile VALUE hbuf = 0, haux = 0;
9446
- rank_index_pair_u16 *buf = ALLOCV_N(rank_index_pair_u16, hbuf, fiber_n);
9447
- rank_index_pair_u16 *aux = NULL;
9448
- if ( do_stable ) {
9449
- aux = ALLOCV_N(rank_index_pair_u16, haux, fiber_n);
9450
- }
9451
-
9452
9378
  char *pi, *po;
9453
9379
  boolean8_t *mi, *mo;
9454
9380
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9461,7 +9387,7 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9461
9387
  ca_size_t k_unmasked = 0;
9462
9388
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9463
9389
  if ( mi && mi[k * mstride] ) continue;
9464
- buf[k_unmasked].v = *(uint16_t *) (pi + k * istride);
9390
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9465
9391
  buf[k_unmasked].i = k;
9466
9392
  k_unmasked++;
9467
9393
  }
@@ -9536,7 +9462,7 @@ rank_index_ki_native_u16 (VALUE self, CArray *ca, int axis, int do_stable, int d
9536
9462
  }
9537
9463
 
9538
9464
  typedef struct {
9539
- int32_t v;
9465
+ ca_u_int32_t v;
9540
9466
  ca_size_t i;
9541
9467
  } rank_index_pair_i32;
9542
9468
 
@@ -9558,6 +9484,13 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9558
9484
  next_slab_axes will then be non-NULL). Created up-front
9559
9485
  when input has any mask. */
9560
9486
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9487
+ ca_size_t fiber_n = ca->dim[axis];
9488
+ volatile VALUE hbuf = 0, haux = 0;
9489
+ rank_index_pair_i32 *buf = ALLOCV_N(rank_index_pair_i32, hbuf, fiber_n);
9490
+ rank_index_pair_i32 *aux = NULL;
9491
+ if ( do_stable ) {
9492
+ aux = ALLOCV_N(rank_index_pair_i32, haux, fiber_n);
9493
+ }
9561
9494
  ca_iter_state st_in, st_out;
9562
9495
  int rc;
9563
9496
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9572,14 +9505,6 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9572
9505
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9573
9506
  }
9574
9507
 
9575
- ca_size_t fiber_n = st_in.slab_elements;
9576
- volatile VALUE hbuf = 0, haux = 0;
9577
- rank_index_pair_i32 *buf = ALLOCV_N(rank_index_pair_i32, hbuf, fiber_n);
9578
- rank_index_pair_i32 *aux = NULL;
9579
- if ( do_stable ) {
9580
- aux = ALLOCV_N(rank_index_pair_i32, haux, fiber_n);
9581
- }
9582
-
9583
9508
  char *pi, *po;
9584
9509
  boolean8_t *mi, *mo;
9585
9510
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9592,7 +9517,7 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9592
9517
  ca_size_t k_unmasked = 0;
9593
9518
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9594
9519
  if ( mi && mi[k * mstride] ) continue;
9595
- buf[k_unmasked].v = *(int32_t *) (pi + k * istride);
9520
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9596
9521
  buf[k_unmasked].i = k;
9597
9522
  k_unmasked++;
9598
9523
  }
@@ -9667,7 +9592,7 @@ rank_index_ki_native_i32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9667
9592
  }
9668
9593
 
9669
9594
  typedef struct {
9670
- uint32_t v;
9595
+ ca_u_uint32_t v;
9671
9596
  ca_size_t i;
9672
9597
  } rank_index_pair_u32;
9673
9598
 
@@ -9689,6 +9614,13 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9689
9614
  next_slab_axes will then be non-NULL). Created up-front
9690
9615
  when input has any mask. */
9691
9616
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9617
+ ca_size_t fiber_n = ca->dim[axis];
9618
+ volatile VALUE hbuf = 0, haux = 0;
9619
+ rank_index_pair_u32 *buf = ALLOCV_N(rank_index_pair_u32, hbuf, fiber_n);
9620
+ rank_index_pair_u32 *aux = NULL;
9621
+ if ( do_stable ) {
9622
+ aux = ALLOCV_N(rank_index_pair_u32, haux, fiber_n);
9623
+ }
9692
9624
  ca_iter_state st_in, st_out;
9693
9625
  int rc;
9694
9626
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9703,14 +9635,6 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9703
9635
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9704
9636
  }
9705
9637
 
9706
- ca_size_t fiber_n = st_in.slab_elements;
9707
- volatile VALUE hbuf = 0, haux = 0;
9708
- rank_index_pair_u32 *buf = ALLOCV_N(rank_index_pair_u32, hbuf, fiber_n);
9709
- rank_index_pair_u32 *aux = NULL;
9710
- if ( do_stable ) {
9711
- aux = ALLOCV_N(rank_index_pair_u32, haux, fiber_n);
9712
- }
9713
-
9714
9638
  char *pi, *po;
9715
9639
  boolean8_t *mi, *mo;
9716
9640
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9723,7 +9647,7 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9723
9647
  ca_size_t k_unmasked = 0;
9724
9648
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9725
9649
  if ( mi && mi[k * mstride] ) continue;
9726
- buf[k_unmasked].v = *(uint32_t *) (pi + k * istride);
9650
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9727
9651
  buf[k_unmasked].i = k;
9728
9652
  k_unmasked++;
9729
9653
  }
@@ -9798,7 +9722,7 @@ rank_index_ki_native_u32 (VALUE self, CArray *ca, int axis, int do_stable, int d
9798
9722
  }
9799
9723
 
9800
9724
  typedef struct {
9801
- int64_t v;
9725
+ ca_u_int64_t v;
9802
9726
  ca_size_t i;
9803
9727
  } rank_index_pair_i64;
9804
9728
 
@@ -9820,6 +9744,13 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9820
9744
  next_slab_axes will then be non-NULL). Created up-front
9821
9745
  when input has any mask. */
9822
9746
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9747
+ ca_size_t fiber_n = ca->dim[axis];
9748
+ volatile VALUE hbuf = 0, haux = 0;
9749
+ rank_index_pair_i64 *buf = ALLOCV_N(rank_index_pair_i64, hbuf, fiber_n);
9750
+ rank_index_pair_i64 *aux = NULL;
9751
+ if ( do_stable ) {
9752
+ aux = ALLOCV_N(rank_index_pair_i64, haux, fiber_n);
9753
+ }
9823
9754
  ca_iter_state st_in, st_out;
9824
9755
  int rc;
9825
9756
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9834,14 +9765,6 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9834
9765
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9835
9766
  }
9836
9767
 
9837
- ca_size_t fiber_n = st_in.slab_elements;
9838
- volatile VALUE hbuf = 0, haux = 0;
9839
- rank_index_pair_i64 *buf = ALLOCV_N(rank_index_pair_i64, hbuf, fiber_n);
9840
- rank_index_pair_i64 *aux = NULL;
9841
- if ( do_stable ) {
9842
- aux = ALLOCV_N(rank_index_pair_i64, haux, fiber_n);
9843
- }
9844
-
9845
9768
  char *pi, *po;
9846
9769
  boolean8_t *mi, *mo;
9847
9770
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9854,7 +9777,7 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9854
9777
  ca_size_t k_unmasked = 0;
9855
9778
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9856
9779
  if ( mi && mi[k * mstride] ) continue;
9857
- buf[k_unmasked].v = *(int64_t *) (pi + k * istride);
9780
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9858
9781
  buf[k_unmasked].i = k;
9859
9782
  k_unmasked++;
9860
9783
  }
@@ -9929,7 +9852,7 @@ rank_index_ki_native_i64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9929
9852
  }
9930
9853
 
9931
9854
  typedef struct {
9932
- uint64_t v;
9855
+ ca_u_uint64_t v;
9933
9856
  ca_size_t i;
9934
9857
  } rank_index_pair_u64;
9935
9858
 
@@ -9951,6 +9874,13 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9951
9874
  next_slab_axes will then be non-NULL). Created up-front
9952
9875
  when input has any mask. */
9953
9876
  if ( ca_has_mask(ca) ) ca_create_mask(co);
9877
+ ca_size_t fiber_n = ca->dim[axis];
9878
+ volatile VALUE hbuf = 0, haux = 0;
9879
+ rank_index_pair_u64 *buf = ALLOCV_N(rank_index_pair_u64, hbuf, fiber_n);
9880
+ rank_index_pair_u64 *aux = NULL;
9881
+ if ( do_stable ) {
9882
+ aux = ALLOCV_N(rank_index_pair_u64, haux, fiber_n);
9883
+ }
9954
9884
  ca_iter_state st_in, st_out;
9955
9885
  int rc;
9956
9886
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -9965,14 +9895,6 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9965
9895
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
9966
9896
  }
9967
9897
 
9968
- ca_size_t fiber_n = st_in.slab_elements;
9969
- volatile VALUE hbuf = 0, haux = 0;
9970
- rank_index_pair_u64 *buf = ALLOCV_N(rank_index_pair_u64, hbuf, fiber_n);
9971
- rank_index_pair_u64 *aux = NULL;
9972
- if ( do_stable ) {
9973
- aux = ALLOCV_N(rank_index_pair_u64, haux, fiber_n);
9974
- }
9975
-
9976
9898
  char *pi, *po;
9977
9899
  boolean8_t *mi, *mo;
9978
9900
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -9985,7 +9907,7 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
9985
9907
  ca_size_t k_unmasked = 0;
9986
9908
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
9987
9909
  if ( mi && mi[k * mstride] ) continue;
9988
- buf[k_unmasked].v = *(uint64_t *) (pi + k * istride);
9910
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
9989
9911
  buf[k_unmasked].i = k;
9990
9912
  k_unmasked++;
9991
9913
  }
@@ -10060,7 +9982,7 @@ rank_index_ki_native_u64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10060
9982
  }
10061
9983
 
10062
9984
  typedef struct {
10063
- float v;
9985
+ ca_u_float32_t v;
10064
9986
  ca_size_t i;
10065
9987
  } rank_index_pair_f32;
10066
9988
 
@@ -10082,6 +10004,10 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10082
10004
  next_slab_axes will then be non-NULL). Created up-front
10083
10005
  when input has any mask. */
10084
10006
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10007
+ ca_size_t fiber_n = ca->dim[axis];
10008
+ volatile VALUE hbuf = 0, haux = 0;
10009
+ rank_index_pair_f32 *buf = ALLOCV_N(rank_index_pair_f32, hbuf, fiber_n);
10010
+ rank_index_pair_f32 *aux = ALLOCV_N(rank_index_pair_f32, haux, fiber_n);
10085
10011
  ca_iter_state st_in, st_out;
10086
10012
  int rc;
10087
10013
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10096,14 +10022,6 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10096
10022
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10097
10023
  }
10098
10024
 
10099
- ca_size_t fiber_n = st_in.slab_elements;
10100
- volatile VALUE hbuf = 0, haux = 0;
10101
- rank_index_pair_f32 *buf = ALLOCV_N(rank_index_pair_f32, hbuf, fiber_n);
10102
- rank_index_pair_f32 *aux = NULL;
10103
- if ( do_stable ) {
10104
- aux = ALLOCV_N(rank_index_pair_f32, haux, fiber_n);
10105
- }
10106
-
10107
10025
  char *pi, *po;
10108
10026
  boolean8_t *mi, *mo;
10109
10027
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10116,7 +10034,7 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10116
10034
  ca_size_t k_unmasked = 0;
10117
10035
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
10118
10036
  if ( mi && mi[k * mstride] ) continue;
10119
- buf[k_unmasked].v = *(float *) (pi + k * istride);
10037
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
10120
10038
  buf[k_unmasked].i = k;
10121
10039
  k_unmasked++;
10122
10040
  }
@@ -10130,7 +10048,7 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10130
10048
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
10131
10049
  pushed to the tail (= NaN-at-end policy, matches sort_copy
10132
10050
  AC8). Only the finite slice is sorted. */
10133
- ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) buf, (ca_size_t) k_unmasked);
10051
+ ca_size_t finite_n = ca_partition_nan_pair_f32((ca_pair_f32 *) buf, (ca_size_t) k_unmasked, (ca_pair_f32 *) aux);
10134
10052
  if ( do_stable ) {
10135
10053
  ca_sort_merge_pair_f32((ca_pair_f32 *) buf, (ca_pair_f32 *) aux, finite_n);
10136
10054
  } else {
@@ -10197,7 +10115,7 @@ rank_index_ki_native_f32 (VALUE self, CArray *ca, int axis, int do_stable, int d
10197
10115
  }
10198
10116
 
10199
10117
  typedef struct {
10200
- double v;
10118
+ ca_u_float64_t v;
10201
10119
  ca_size_t i;
10202
10120
  } rank_index_pair_f64;
10203
10121
 
@@ -10219,6 +10137,10 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10219
10137
  next_slab_axes will then be non-NULL). Created up-front
10220
10138
  when input has any mask. */
10221
10139
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10140
+ ca_size_t fiber_n = ca->dim[axis];
10141
+ volatile VALUE hbuf = 0, haux = 0;
10142
+ rank_index_pair_f64 *buf = ALLOCV_N(rank_index_pair_f64, hbuf, fiber_n);
10143
+ rank_index_pair_f64 *aux = ALLOCV_N(rank_index_pair_f64, haux, fiber_n);
10222
10144
  ca_iter_state st_in, st_out;
10223
10145
  int rc;
10224
10146
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10233,14 +10155,6 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10233
10155
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10234
10156
  }
10235
10157
 
10236
- ca_size_t fiber_n = st_in.slab_elements;
10237
- volatile VALUE hbuf = 0, haux = 0;
10238
- rank_index_pair_f64 *buf = ALLOCV_N(rank_index_pair_f64, hbuf, fiber_n);
10239
- rank_index_pair_f64 *aux = NULL;
10240
- if ( do_stable ) {
10241
- aux = ALLOCV_N(rank_index_pair_f64, haux, fiber_n);
10242
- }
10243
-
10244
10158
  char *pi, *po;
10245
10159
  boolean8_t *mi, *mo;
10246
10160
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10253,7 +10167,7 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10253
10167
  ca_size_t k_unmasked = 0;
10254
10168
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
10255
10169
  if ( mi && mi[k * mstride] ) continue;
10256
- buf[k_unmasked].v = *(double *) (pi + k * istride);
10170
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
10257
10171
  buf[k_unmasked].i = k;
10258
10172
  k_unmasked++;
10259
10173
  }
@@ -10267,7 +10181,7 @@ rank_index_ki_native_f64 (VALUE self, CArray *ca, int axis, int do_stable, int d
10267
10181
  /* P.3/P.4: NaN pre-partition for float argsort -- NaN pairs are
10268
10182
  pushed to the tail (= NaN-at-end policy, matches sort_copy
10269
10183
  AC8). Only the finite slice is sorted. */
10270
- ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) buf, (ca_size_t) k_unmasked);
10184
+ ca_size_t finite_n = ca_partition_nan_pair_f64((ca_pair_f64 *) buf, (ca_size_t) k_unmasked, (ca_pair_f64 *) aux);
10271
10185
  if ( do_stable ) {
10272
10186
  ca_sort_merge_pair_f64((ca_pair_f64 *) buf, (ca_pair_f64 *) aux, finite_n);
10273
10187
  } else {
@@ -10356,6 +10270,13 @@ rank_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
10356
10270
  next_slab_axes will then be non-NULL). Created up-front
10357
10271
  when input has any mask. */
10358
10272
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10273
+ ca_size_t fiber_n = ca->dim[axis];
10274
+ volatile VALUE hbuf = 0, haux = 0;
10275
+ rank_index_pair_bool *buf = ALLOCV_N(rank_index_pair_bool, hbuf, fiber_n);
10276
+ rank_index_pair_bool *aux = NULL;
10277
+ if ( do_stable ) {
10278
+ aux = ALLOCV_N(rank_index_pair_bool, haux, fiber_n);
10279
+ }
10359
10280
  ca_iter_state st_in, st_out;
10360
10281
  int rc;
10361
10282
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10370,14 +10291,6 @@ rank_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
10370
10291
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10371
10292
  }
10372
10293
 
10373
- ca_size_t fiber_n = st_in.slab_elements;
10374
- volatile VALUE hbuf = 0, haux = 0;
10375
- rank_index_pair_bool *buf = ALLOCV_N(rank_index_pair_bool, hbuf, fiber_n);
10376
- rank_index_pair_bool *aux = NULL;
10377
- if ( do_stable ) {
10378
- aux = ALLOCV_N(rank_index_pair_bool, haux, fiber_n);
10379
- }
10380
-
10381
10294
  char *pi, *po;
10382
10295
  boolean8_t *mi, *mo;
10383
10296
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10390,7 +10303,7 @@ rank_index_ki_native_bool (VALUE self, CArray *ca, int axis, int do_stable, int
10390
10303
  ca_size_t k_unmasked = 0;
10391
10304
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
10392
10305
  if ( mi && mi[k * mstride] ) continue;
10393
- buf[k_unmasked].v = *(boolean8_t *) (pi + k * istride);
10306
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
10394
10307
  buf[k_unmasked].i = k;
10395
10308
  k_unmasked++;
10396
10309
  }
@@ -10482,9 +10395,9 @@ rank_index_cmp_object (const void *a, const void *b)
10482
10395
  return 0;
10483
10396
  }
10484
10397
 
10485
- /* The object lane calls Ruby for every cell, so a walk can raise part
10486
- way. Its states live in the caller's frame, and ca_iter_ensure
10487
- finishes them however the body leaves. */
10398
+ /* The walks can raise part way (a Ruby call per cell in the object
10399
+ lane, an allocation in any lane). Their states live in the caller's
10400
+ frame, and ca_iter_ensure finishes them however the body leaves. */
10488
10401
  typedef struct {
10489
10402
  ca_iter_state states[2];
10490
10403
  VALUE self;
@@ -10525,6 +10438,10 @@ rank_index_ki_native_object_body (VALUE arg)
10525
10438
  next_slab_axes will then be non-NULL). Created up-front
10526
10439
  when input has any mask. */
10527
10440
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10441
+ ca_size_t fiber_n = ca->dim[axis];
10442
+ volatile VALUE hbuf = 0, haux = 0;
10443
+ rank_index_pair_object *buf = ALLOCV_N(rank_index_pair_object, hbuf, fiber_n);
10444
+ rank_index_pair_object *aux = ALLOCV_N(rank_index_pair_object, haux, fiber_n);
10528
10445
  int rc;
10529
10446
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
10530
10447
  slab_axes, 1, 0);
@@ -10538,11 +10455,6 @@ rank_index_ki_native_object_body (VALUE arg)
10538
10455
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10539
10456
  }
10540
10457
 
10541
- ca_size_t fiber_n = st_in.slab_elements;
10542
- volatile VALUE hbuf = 0, haux = 0;
10543
- rank_index_pair_object *buf = ALLOCV_N(rank_index_pair_object, hbuf, fiber_n);
10544
- rank_index_pair_object *aux = ALLOCV_N(rank_index_pair_object, haux, fiber_n);
10545
-
10546
10458
  char *pi, *po;
10547
10459
  boolean8_t *mi, *mo;
10548
10460
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&
@@ -10555,7 +10467,7 @@ rank_index_ki_native_object_body (VALUE arg)
10555
10467
  ca_size_t k_unmasked = 0;
10556
10468
  for ( ca_size_t k = 0; k < fiber_n; k++ ) {
10557
10469
  if ( mi && mi[k * mstride] ) continue;
10558
- buf[k_unmasked].v = *(VALUE *) (pi + k * istride);
10470
+ memcpy(&buf[k_unmasked].v, pi + k * istride, sizeof(buf[k_unmasked].v));
10559
10471
  buf[k_unmasked].i = k;
10560
10472
  k_unmasked++;
10561
10473
  }
@@ -10639,7 +10551,7 @@ rank_index_ki_native_object (VALUE self, CArray *ca, int axis, int do_stable, in
10639
10551
  fr.axis = axis;
10640
10552
  fr.do_stable = do_stable;
10641
10553
  fr.dense = dense;
10642
- return ca_iter_ensure(2, fr.states, rank_index_ki_native_object_body, (VALUE) &fr);
10554
+ return ca_iter_ensure_computing(ca, 2, fr.states, rank_index_ki_native_object_body, (VALUE) &fr);
10643
10555
  }
10644
10556
 
10645
10557
 
@@ -10680,6 +10592,10 @@ rank_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
10680
10592
  next_slab_axes will then be non-NULL). Created up-front
10681
10593
  when input has any mask. */
10682
10594
  if ( ca_has_mask(ca) ) ca_create_mask(co);
10595
+ ca_size_t fiber_n = ca->dim[axis];
10596
+ volatile VALUE hbuf = 0, haux = 0;
10597
+ rank_index_pair_fixlen *buf = ALLOCV_N(rank_index_pair_fixlen, hbuf, fiber_n);
10598
+ (void) haux;
10683
10599
  ca_iter_state st_in, st_out;
10684
10600
  int rc;
10685
10601
  rc = ca_iter_state_init_l2(&st_in, ca, CA_SLAB_AXES,
@@ -10694,14 +10610,6 @@ rank_index_ki_native_fixlen (VALUE self, CArray *ca, int axis, int do_stable, in
10694
10610
  rb_raise(rb_eRuntimeError, "%s: output init failed rc=%d", ca_calling_method_name(), rc);
10695
10611
  }
10696
10612
 
10697
- ca_size_t fiber_n = st_in.slab_elements;
10698
- volatile VALUE hbuf = 0, haux = 0;
10699
- rank_index_pair_fixlen *buf = ALLOCV_N(rank_index_pair_fixlen, hbuf, fiber_n);
10700
- rank_index_pair_fixlen *aux = NULL;
10701
- if ( do_stable ) {
10702
- aux = ALLOCV_N(rank_index_pair_fixlen, haux, fiber_n);
10703
- }
10704
-
10705
10613
  char *pi, *po;
10706
10614
  boolean8_t *mi, *mo;
10707
10615
  while ( ca_iter_state_next_slab_axes(&st_in, &pi, &mi) &&