xref: /llvm-project/flang/runtime/reduce.cpp (revision fc97d2e68b03bc2979395e84b645e5b3ba35aecd)
1 //===-- runtime/reduce.cpp ------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // REDUCE() implementation
10 
11 #include "flang/Runtime/reduce.h"
12 #include "reduction-templates.h"
13 #include "terminator.h"
14 #include "tools.h"
15 #include "flang/Runtime/descriptor.h"
16 
17 namespace Fortran::runtime {
18 
19 template <typename T, bool isByValue> class ReduceAccumulator {
20 public:
21   using Operation = std::conditional_t<isByValue, ValueReductionOperation<T>,
22       ReferenceReductionOperation<T>>;
23   RT_API_ATTRS ReduceAccumulator(const Descriptor &array, Operation operation,
24       const T *identity, Terminator &terminator)
25       : array_{array}, operation_{operation}, identity_{identity},
26         terminator_{terminator} {}
27   RT_API_ATTRS void Reinitialize() { result_.reset(); }
28   template <typename A>
29   RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) {
30     const auto *operand{array_.Element<A>(at)};
31     if (result_) {
32       if constexpr (isByValue) {
33         result_ = operation_(*result_, *operand);
34       } else {
35         result_ = operation_(&*result_, operand);
36       }
37     } else {
38       result_ = *operand;
39     }
40     return true;
41   }
42   template <typename A>
43   RT_API_ATTRS void GetResult(A *to, int /*zeroBasedDim*/ = -1) {
44     if (result_) {
45       *to = *result_;
46     } else if (identity_) {
47       *to = *identity_;
48     } else {
49       terminator_.Crash("REDUCE() without IDENTITY= has no result");
50     }
51   }
52 
53 private:
54   const Descriptor &array_;
55   common::optional<T> result_;
56   Operation operation_;
57   const T *identity_{nullptr};
58   Terminator &terminator_;
59 };
60 
61 template <typename T, typename OP, bool hasLength>
62 class BufferedReduceAccumulator {
63 public:
64   RT_API_ATTRS BufferedReduceAccumulator(const Descriptor &array, OP operation,
65       const T *identity, Terminator &terminator)
66       : array_{array}, operation_{operation}, identity_{identity},
67         terminator_{terminator} {}
68   RT_API_ATTRS void Reinitialize() { activeTemp_ = -1; }
69   template <typename A>
70   RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) {
71     const auto *operand{array_.Element<A>(at)};
72     if (activeTemp_ >= 0) {
73       if constexpr (hasLength) {
74         operation_(&*temp_[1 - activeTemp_], length_, &*temp_[activeTemp_],
75             operand, length_, length_);
76       } else {
77         operation_(&*temp_[1 - activeTemp_], &*temp_[activeTemp_], operand);
78       }
79       activeTemp_ = 1 - activeTemp_;
80     } else {
81       activeTemp_ = 0;
82       std::memcpy(&*temp_[activeTemp_], operand, elementBytes_);
83     }
84     return true;
85   }
86   template <typename A>
87   RT_API_ATTRS void GetResult(A *to, int /*zeroBasedDim*/ = -1) {
88     if (activeTemp_ >= 0) {
89       std::memcpy(to, &*temp_[activeTemp_], elementBytes_);
90     } else if (identity_) {
91       std::memcpy(to, identity_, elementBytes_);
92     } else {
93       terminator_.Crash("REDUCE() without IDENTITY= has no result");
94     }
95   }
96 
97 private:
98   const Descriptor &array_;
99   OP operation_;
100   const T *identity_{nullptr};
101   Terminator &terminator_;
102   std::size_t elementBytes_{array_.ElementBytes()};
103   OwningPtr<T> temp_[2]{SizedNew<T>{terminator_}(elementBytes_),
104       SizedNew<T>{terminator_}(elementBytes_)};
105   int activeTemp_{-1};
106   std::size_t length_{elementBytes_ / sizeof(T)};
107 };
108 
109 extern "C" {
110 RT_EXT_API_GROUP_BEGIN
111 
112 std::int8_t RTDEF(ReduceInteger1Ref)(const Descriptor &array,
113     ReferenceReductionOperation<std::int8_t> operation, const char *source,
114     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
115     bool ordered) {
116   Terminator terminator{source, line};
117   return GetTotalReduction<TypeCategory::Integer, 1>(array, source, line, dim,
118       mask,
119       ReduceAccumulator<std::int8_t, false>{
120           array, operation, identity, terminator},
121       "REDUCE");
122 }
123 std::int8_t RTDEF(ReduceInteger1Value)(const Descriptor &array,
124     ValueReductionOperation<std::int8_t> operation, const char *source,
125     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
126     bool ordered) {
127   Terminator terminator{source, line};
128   return GetTotalReduction<TypeCategory::Integer, 1>(array, source, line, dim,
129       mask,
130       ReduceAccumulator<std::int8_t, true>{
131           array, operation, identity, terminator},
132       "REDUCE");
133 }
134 void RTDEF(ReduceInteger1DimRef)(Descriptor &result, const Descriptor &array,
135     ReferenceReductionOperation<std::int8_t> operation, const char *source,
136     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
137     bool ordered) {
138   Terminator terminator{source, line};
139   using Accumulator = ReduceAccumulator<std::int8_t, false>;
140   Accumulator accumulator{array, operation, identity, terminator};
141   PartialReduction<Accumulator, TypeCategory::Integer, 1>(result, array,
142       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
143 }
144 void RTDEF(ReduceInteger1DimValue)(Descriptor &result, const Descriptor &array,
145     ValueReductionOperation<std::int8_t> operation, const char *source,
146     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
147     bool ordered) {
148   Terminator terminator{source, line};
149   using Accumulator = ReduceAccumulator<std::int8_t, true>;
150   Accumulator accumulator{array, operation, identity, terminator};
151   PartialReduction<Accumulator, TypeCategory::Integer, 1>(result, array,
152       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
153 }
154 std::int16_t RTDEF(ReduceInteger2Ref)(const Descriptor &array,
155     ReferenceReductionOperation<std::int16_t> operation, const char *source,
156     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
157     bool ordered) {
158   Terminator terminator{source, line};
159   return GetTotalReduction<TypeCategory::Integer, 2>(array, source, line, dim,
160       mask,
161       ReduceAccumulator<std::int16_t, false>{
162           array, operation, identity, terminator},
163       "REDUCE");
164 }
165 std::int16_t RTDEF(ReduceInteger2Value)(const Descriptor &array,
166     ValueReductionOperation<std::int16_t> operation, const char *source,
167     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
168     bool ordered) {
169   Terminator terminator{source, line};
170   return GetTotalReduction<TypeCategory::Integer, 2>(array, source, line, dim,
171       mask,
172       ReduceAccumulator<std::int16_t, true>{
173           array, operation, identity, terminator},
174       "REDUCE");
175 }
176 void RTDEF(ReduceInteger2DimRef)(Descriptor &result, const Descriptor &array,
177     ReferenceReductionOperation<std::int16_t> operation, const char *source,
178     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
179     bool ordered) {
180   Terminator terminator{source, line};
181   using Accumulator = ReduceAccumulator<std::int16_t, false>;
182   Accumulator accumulator{array, operation, identity, terminator};
183   PartialReduction<Accumulator, TypeCategory::Integer, 2>(result, array,
184       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
185 }
186 void RTDEF(ReduceInteger2DimValue)(Descriptor &result, const Descriptor &array,
187     ValueReductionOperation<std::int16_t> operation, const char *source,
188     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
189     bool ordered) {
190   Terminator terminator{source, line};
191   using Accumulator = ReduceAccumulator<std::int16_t, true>;
192   Accumulator accumulator{array, operation, identity, terminator};
193   PartialReduction<Accumulator, TypeCategory::Integer, 2>(result, array,
194       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
195 }
196 std::int32_t RTDEF(ReduceInteger4Ref)(const Descriptor &array,
197     ReferenceReductionOperation<std::int32_t> operation, const char *source,
198     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
199     bool ordered) {
200   Terminator terminator{source, line};
201   return GetTotalReduction<TypeCategory::Integer, 4>(array, source, line, dim,
202       mask,
203       ReduceAccumulator<std::int32_t, false>{
204           array, operation, identity, terminator},
205       "REDUCE");
206 }
207 std::int32_t RTDEF(ReduceInteger4Value)(const Descriptor &array,
208     ValueReductionOperation<std::int32_t> operation, const char *source,
209     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
210     bool ordered) {
211   Terminator terminator{source, line};
212   return GetTotalReduction<TypeCategory::Integer, 4>(array, source, line, dim,
213       mask,
214       ReduceAccumulator<std::int32_t, true>{
215           array, operation, identity, terminator},
216       "REDUCE");
217 }
218 void RTDEF(ReduceInteger4DimRef)(Descriptor &result, const Descriptor &array,
219     ReferenceReductionOperation<std::int32_t> operation, const char *source,
220     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
221     bool ordered) {
222   Terminator terminator{source, line};
223   using Accumulator = ReduceAccumulator<std::int32_t, false>;
224   Accumulator accumulator{array, operation, identity, terminator};
225   PartialReduction<Accumulator, TypeCategory::Integer, 4>(result, array,
226       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
227 }
228 void RTDEF(ReduceInteger4DimValue)(Descriptor &result, const Descriptor &array,
229     ValueReductionOperation<std::int32_t> operation, const char *source,
230     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
231     bool ordered) {
232   Terminator terminator{source, line};
233   using Accumulator = ReduceAccumulator<std::int32_t, true>;
234   Accumulator accumulator{array, operation, identity, terminator};
235   PartialReduction<Accumulator, TypeCategory::Integer, 4>(result, array,
236       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
237 }
238 std::int64_t RTDEF(ReduceInteger8Ref)(const Descriptor &array,
239     ReferenceReductionOperation<std::int64_t> operation, const char *source,
240     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
241     bool ordered) {
242   Terminator terminator{source, line};
243   return GetTotalReduction<TypeCategory::Integer, 8>(array, source, line, dim,
244       mask,
245       ReduceAccumulator<std::int64_t, false>{
246           array, operation, identity, terminator},
247       "REDUCE");
248 }
249 std::int64_t RTDEF(ReduceInteger8Value)(const Descriptor &array,
250     ValueReductionOperation<std::int64_t> operation, const char *source,
251     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
252     bool ordered) {
253   Terminator terminator{source, line};
254   return GetTotalReduction<TypeCategory::Integer, 8>(array, source, line, dim,
255       mask,
256       ReduceAccumulator<std::int64_t, true>{
257           array, operation, identity, terminator},
258       "REDUCE");
259 }
260 void RTDEF(ReduceInteger8DimRef)(Descriptor &result, const Descriptor &array,
261     ReferenceReductionOperation<std::int64_t> operation, const char *source,
262     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
263     bool ordered) {
264   Terminator terminator{source, line};
265   using Accumulator = ReduceAccumulator<std::int64_t, false>;
266   Accumulator accumulator{array, operation, identity, terminator};
267   PartialReduction<Accumulator, TypeCategory::Integer, 8>(result, array,
268       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
269 }
270 void RTDEF(ReduceInteger8DimValue)(Descriptor &result, const Descriptor &array,
271     ValueReductionOperation<std::int64_t> operation, const char *source,
272     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
273     bool ordered) {
274   Terminator terminator{source, line};
275   using Accumulator = ReduceAccumulator<std::int64_t, true>;
276   Accumulator accumulator{array, operation, identity, terminator};
277   PartialReduction<Accumulator, TypeCategory::Integer, 8>(result, array,
278       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
279 }
280 #ifdef __SIZEOF_INT128__
281 common::int128_t RTDEF(ReduceInteger16Ref)(const Descriptor &array,
282     ReferenceReductionOperation<common::int128_t> operation, const char *source,
283     int line, int dim, const Descriptor *mask, const common::int128_t *identity,
284     bool ordered) {
285   Terminator terminator{source, line};
286   return GetTotalReduction<TypeCategory::Integer, 16>(array, source, line, dim,
287       mask,
288       ReduceAccumulator<common::int128_t, false>{
289           array, operation, identity, terminator},
290       "REDUCE");
291 }
292 common::int128_t RTDEF(ReduceInteger16Value)(const Descriptor &array,
293     ValueReductionOperation<common::int128_t> operation, const char *source,
294     int line, int dim, const Descriptor *mask, const common::int128_t *identity,
295     bool ordered) {
296   Terminator terminator{source, line};
297   return GetTotalReduction<TypeCategory::Integer, 16>(array, source, line, dim,
298       mask,
299       ReduceAccumulator<common::int128_t, true>{
300           array, operation, identity, terminator},
301       "REDUCE");
302 }
303 void RTDEF(ReduceInteger16DimRef)(Descriptor &result, const Descriptor &array,
304     ReferenceReductionOperation<common::int128_t> operation, const char *source,
305     int line, int dim, const Descriptor *mask, const common::int128_t *identity,
306     bool ordered) {
307   Terminator terminator{source, line};
308   using Accumulator = ReduceAccumulator<common::int128_t, false>;
309   Accumulator accumulator{array, operation, identity, terminator};
310   PartialReduction<Accumulator, TypeCategory::Integer, 16>(result, array,
311       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
312 }
313 void RTDEF(ReduceInteger16DimValue)(Descriptor &result, const Descriptor &array,
314     ValueReductionOperation<common::int128_t> operation, const char *source,
315     int line, int dim, const Descriptor *mask, const common::int128_t *identity,
316     bool ordered) {
317   Terminator terminator{source, line};
318   using Accumulator = ReduceAccumulator<common::int128_t, true>;
319   Accumulator accumulator{array, operation, identity, terminator};
320   PartialReduction<Accumulator, TypeCategory::Integer, 16>(result, array,
321       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
322 }
323 #endif
324 
325 std::uint8_t RTDEF(ReduceUnsigned1Ref)(const Descriptor &array,
326     ReferenceReductionOperation<std::uint8_t> operation, const char *source,
327     int line, int dim, const Descriptor *mask, const std::uint8_t *identity,
328     bool ordered) {
329   Terminator terminator{source, line};
330   return GetTotalReduction<TypeCategory::Unsigned, 1>(array, source, line, dim,
331       mask,
332       ReduceAccumulator<std::uint8_t, false>{
333           array, operation, identity, terminator},
334       "REDUCE");
335 }
336 std::uint8_t RTDEF(ReduceUnsigned1Value)(const Descriptor &array,
337     ValueReductionOperation<std::uint8_t> operation, const char *source,
338     int line, int dim, const Descriptor *mask, const std::uint8_t *identity,
339     bool ordered) {
340   Terminator terminator{source, line};
341   return GetTotalReduction<TypeCategory::Unsigned, 1>(array, source, line, dim,
342       mask,
343       ReduceAccumulator<std::uint8_t, true>{
344           array, operation, identity, terminator},
345       "REDUCE");
346 }
347 void RTDEF(ReduceUnsigned1DimRef)(Descriptor &result, const Descriptor &array,
348     ReferenceReductionOperation<std::uint8_t> operation, const char *source,
349     int line, int dim, const Descriptor *mask, const std::uint8_t *identity,
350     bool ordered) {
351   Terminator terminator{source, line};
352   using Accumulator = ReduceAccumulator<std::uint8_t, false>;
353   Accumulator accumulator{array, operation, identity, terminator};
354   PartialReduction<Accumulator, TypeCategory::Unsigned, 1>(result, array,
355       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
356 }
357 void RTDEF(ReduceUnsigned1DimValue)(Descriptor &result, const Descriptor &array,
358     ValueReductionOperation<std::uint8_t> operation, const char *source,
359     int line, int dim, const Descriptor *mask, const std::uint8_t *identity,
360     bool ordered) {
361   Terminator terminator{source, line};
362   using Accumulator = ReduceAccumulator<std::uint8_t, true>;
363   Accumulator accumulator{array, operation, identity, terminator};
364   PartialReduction<Accumulator, TypeCategory::Unsigned, 1>(result, array,
365       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
366 }
367 std::uint16_t RTDEF(ReduceUnsigned2Ref)(const Descriptor &array,
368     ReferenceReductionOperation<std::uint16_t> operation, const char *source,
369     int line, int dim, const Descriptor *mask, const std::uint16_t *identity,
370     bool ordered) {
371   Terminator terminator{source, line};
372   return GetTotalReduction<TypeCategory::Unsigned, 2>(array, source, line, dim,
373       mask,
374       ReduceAccumulator<std::uint16_t, false>{
375           array, operation, identity, terminator},
376       "REDUCE");
377 }
378 std::uint16_t RTDEF(ReduceUnsigned2Value)(const Descriptor &array,
379     ValueReductionOperation<std::uint16_t> operation, const char *source,
380     int line, int dim, const Descriptor *mask, const std::uint16_t *identity,
381     bool ordered) {
382   Terminator terminator{source, line};
383   return GetTotalReduction<TypeCategory::Unsigned, 2>(array, source, line, dim,
384       mask,
385       ReduceAccumulator<std::uint16_t, true>{
386           array, operation, identity, terminator},
387       "REDUCE");
388 }
389 void RTDEF(ReduceUnsigned2DimRef)(Descriptor &result, const Descriptor &array,
390     ReferenceReductionOperation<std::uint16_t> operation, const char *source,
391     int line, int dim, const Descriptor *mask, const std::uint16_t *identity,
392     bool ordered) {
393   Terminator terminator{source, line};
394   using Accumulator = ReduceAccumulator<std::uint16_t, false>;
395   Accumulator accumulator{array, operation, identity, terminator};
396   PartialReduction<Accumulator, TypeCategory::Unsigned, 2>(result, array,
397       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
398 }
399 void RTDEF(ReduceUnsigned2DimValue)(Descriptor &result, const Descriptor &array,
400     ValueReductionOperation<std::uint16_t> operation, const char *source,
401     int line, int dim, const Descriptor *mask, const std::uint16_t *identity,
402     bool ordered) {
403   Terminator terminator{source, line};
404   using Accumulator = ReduceAccumulator<std::uint16_t, true>;
405   Accumulator accumulator{array, operation, identity, terminator};
406   PartialReduction<Accumulator, TypeCategory::Unsigned, 2>(result, array,
407       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
408 }
409 std::uint32_t RTDEF(ReduceUnsigned4Ref)(const Descriptor &array,
410     ReferenceReductionOperation<std::uint32_t> operation, const char *source,
411     int line, int dim, const Descriptor *mask, const std::uint32_t *identity,
412     bool ordered) {
413   Terminator terminator{source, line};
414   return GetTotalReduction<TypeCategory::Unsigned, 4>(array, source, line, dim,
415       mask,
416       ReduceAccumulator<std::uint32_t, false>{
417           array, operation, identity, terminator},
418       "REDUCE");
419 }
420 std::uint32_t RTDEF(ReduceUnsigned4Value)(const Descriptor &array,
421     ValueReductionOperation<std::uint32_t> operation, const char *source,
422     int line, int dim, const Descriptor *mask, const std::uint32_t *identity,
423     bool ordered) {
424   Terminator terminator{source, line};
425   return GetTotalReduction<TypeCategory::Unsigned, 4>(array, source, line, dim,
426       mask,
427       ReduceAccumulator<std::uint32_t, true>{
428           array, operation, identity, terminator},
429       "REDUCE");
430 }
431 void RTDEF(ReduceUnsigned4DimRef)(Descriptor &result, const Descriptor &array,
432     ReferenceReductionOperation<std::uint32_t> operation, const char *source,
433     int line, int dim, const Descriptor *mask, const std::uint32_t *identity,
434     bool ordered) {
435   Terminator terminator{source, line};
436   using Accumulator = ReduceAccumulator<std::uint32_t, false>;
437   Accumulator accumulator{array, operation, identity, terminator};
438   PartialReduction<Accumulator, TypeCategory::Unsigned, 4>(result, array,
439       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
440 }
441 void RTDEF(ReduceUnsigned4DimValue)(Descriptor &result, const Descriptor &array,
442     ValueReductionOperation<std::uint32_t> operation, const char *source,
443     int line, int dim, const Descriptor *mask, const std::uint32_t *identity,
444     bool ordered) {
445   Terminator terminator{source, line};
446   using Accumulator = ReduceAccumulator<std::uint32_t, true>;
447   Accumulator accumulator{array, operation, identity, terminator};
448   PartialReduction<Accumulator, TypeCategory::Unsigned, 4>(result, array,
449       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
450 }
451 std::uint64_t RTDEF(ReduceUnsigned8Ref)(const Descriptor &array,
452     ReferenceReductionOperation<std::uint64_t> operation, const char *source,
453     int line, int dim, const Descriptor *mask, const std::uint64_t *identity,
454     bool ordered) {
455   Terminator terminator{source, line};
456   return GetTotalReduction<TypeCategory::Unsigned, 8>(array, source, line, dim,
457       mask,
458       ReduceAccumulator<std::uint64_t, false>{
459           array, operation, identity, terminator},
460       "REDUCE");
461 }
462 std::uint64_t RTDEF(ReduceUnsigned8Value)(const Descriptor &array,
463     ValueReductionOperation<std::uint64_t> operation, const char *source,
464     int line, int dim, const Descriptor *mask, const std::uint64_t *identity,
465     bool ordered) {
466   Terminator terminator{source, line};
467   return GetTotalReduction<TypeCategory::Unsigned, 8>(array, source, line, dim,
468       mask,
469       ReduceAccumulator<std::uint64_t, true>{
470           array, operation, identity, terminator},
471       "REDUCE");
472 }
473 void RTDEF(ReduceUnsigned8DimRef)(Descriptor &result, const Descriptor &array,
474     ReferenceReductionOperation<std::uint64_t> operation, const char *source,
475     int line, int dim, const Descriptor *mask, const std::uint64_t *identity,
476     bool ordered) {
477   Terminator terminator{source, line};
478   using Accumulator = ReduceAccumulator<std::uint64_t, false>;
479   Accumulator accumulator{array, operation, identity, terminator};
480   PartialReduction<Accumulator, TypeCategory::Unsigned, 8>(result, array,
481       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
482 }
483 void RTDEF(ReduceUnsigned8DimValue)(Descriptor &result, const Descriptor &array,
484     ValueReductionOperation<std::uint64_t> operation, const char *source,
485     int line, int dim, const Descriptor *mask, const std::uint64_t *identity,
486     bool ordered) {
487   Terminator terminator{source, line};
488   using Accumulator = ReduceAccumulator<std::uint64_t, true>;
489   Accumulator accumulator{array, operation, identity, terminator};
490   PartialReduction<Accumulator, TypeCategory::Unsigned, 8>(result, array,
491       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
492 }
493 #ifdef __SIZEOF_INT128__
494 common::uint128_t RTDEF(ReduceUnsigned16Ref)(const Descriptor &array,
495     ReferenceReductionOperation<common::uint128_t> operation,
496     const char *source, int line, int dim, const Descriptor *mask,
497     const common::uint128_t *identity, bool ordered) {
498   Terminator terminator{source, line};
499   return GetTotalReduction<TypeCategory::Unsigned, 16>(array, source, line, dim,
500       mask,
501       ReduceAccumulator<common::uint128_t, false>{
502           array, operation, identity, terminator},
503       "REDUCE");
504 }
505 common::uint128_t RTDEF(ReduceUnsigned16Value)(const Descriptor &array,
506     ValueReductionOperation<common::uint128_t> operation, const char *source,
507     int line, int dim, const Descriptor *mask,
508     const common::uint128_t *identity, bool ordered) {
509   Terminator terminator{source, line};
510   return GetTotalReduction<TypeCategory::Unsigned, 16>(array, source, line, dim,
511       mask,
512       ReduceAccumulator<common::uint128_t, true>{
513           array, operation, identity, terminator},
514       "REDUCE");
515 }
516 void RTDEF(ReduceUnsigned16DimRef)(Descriptor &result, const Descriptor &array,
517     ReferenceReductionOperation<common::uint128_t> operation,
518     const char *source, int line, int dim, const Descriptor *mask,
519     const common::uint128_t *identity, bool ordered) {
520   Terminator terminator{source, line};
521   using Accumulator = ReduceAccumulator<common::uint128_t, false>;
522   Accumulator accumulator{array, operation, identity, terminator};
523   PartialReduction<Accumulator, TypeCategory::Unsigned, 16>(result, array,
524       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
525 }
526 void RTDEF(ReduceUnsigned16DimValue)(Descriptor &result,
527     const Descriptor &array,
528     ValueReductionOperation<common::uint128_t> operation, const char *source,
529     int line, int dim, const Descriptor *mask,
530     const common::uint128_t *identity, bool ordered) {
531   Terminator terminator{source, line};
532   using Accumulator = ReduceAccumulator<common::uint128_t, true>;
533   Accumulator accumulator{array, operation, identity, terminator};
534   PartialReduction<Accumulator, TypeCategory::Unsigned, 16>(result, array,
535       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
536 }
537 #endif
538 
539 // TODO: real/complex(2 & 3)
540 float RTDEF(ReduceReal4Ref)(const Descriptor &array,
541     ReferenceReductionOperation<float> operation, const char *source, int line,
542     int dim, const Descriptor *mask, const float *identity, bool ordered) {
543   Terminator terminator{source, line};
544   return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
545       mask,
546       ReduceAccumulator<float, false>{array, operation, identity, terminator},
547       "REDUCE");
548 }
549 float RTDEF(ReduceReal4Value)(const Descriptor &array,
550     ValueReductionOperation<float> operation, const char *source, int line,
551     int dim, const Descriptor *mask, const float *identity, bool ordered) {
552   Terminator terminator{source, line};
553   return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
554       mask,
555       ReduceAccumulator<float, true>{array, operation, identity, terminator},
556       "REDUCE");
557 }
558 void RTDEF(ReduceReal4DimRef)(Descriptor &result, const Descriptor &array,
559     ReferenceReductionOperation<float> operation, const char *source, int line,
560     int dim, const Descriptor *mask, const float *identity, bool ordered) {
561   Terminator terminator{source, line};
562   using Accumulator = ReduceAccumulator<float, false>;
563   Accumulator accumulator{array, operation, identity, terminator};
564   PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
565       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
566 }
567 void RTDEF(ReduceReal4DimValue)(Descriptor &result, const Descriptor &array,
568     ValueReductionOperation<float> operation, const char *source, int line,
569     int dim, const Descriptor *mask, const float *identity, bool ordered) {
570   Terminator terminator{source, line};
571   using Accumulator = ReduceAccumulator<float, true>;
572   Accumulator accumulator{array, operation, identity, terminator};
573   PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
574       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
575 }
576 double RTDEF(ReduceReal8Ref)(const Descriptor &array,
577     ReferenceReductionOperation<double> operation, const char *source, int line,
578     int dim, const Descriptor *mask, const double *identity, bool ordered) {
579   Terminator terminator{source, line};
580   return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
581       mask,
582       ReduceAccumulator<double, false>{array, operation, identity, terminator},
583       "REDUCE");
584 }
585 double RTDEF(ReduceReal8Value)(const Descriptor &array,
586     ValueReductionOperation<double> operation, const char *source, int line,
587     int dim, const Descriptor *mask, const double *identity, bool ordered) {
588   Terminator terminator{source, line};
589   return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
590       mask,
591       ReduceAccumulator<double, true>{array, operation, identity, terminator},
592       "REDUCE");
593 }
594 void RTDEF(ReduceReal8DimRef)(Descriptor &result, const Descriptor &array,
595     ReferenceReductionOperation<double> operation, const char *source, int line,
596     int dim, const Descriptor *mask, const double *identity, bool ordered) {
597   Terminator terminator{source, line};
598   using Accumulator = ReduceAccumulator<double, false>;
599   Accumulator accumulator{array, operation, identity, terminator};
600   PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
601       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
602 }
603 void RTDEF(ReduceReal8DimValue)(Descriptor &result, const Descriptor &array,
604     ValueReductionOperation<double> operation, const char *source, int line,
605     int dim, const Descriptor *mask, const double *identity, bool ordered) {
606   Terminator terminator{source, line};
607   using Accumulator = ReduceAccumulator<double, true>;
608   Accumulator accumulator{array, operation, identity, terminator};
609   PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
610       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
611 }
612 #if HAS_FLOAT80
613 CppTypeFor<TypeCategory::Real, 10> RTDEF(ReduceReal10Ref)(
614     const Descriptor &array,
615     ReferenceReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
616     const char *source, int line, int dim, const Descriptor *mask,
617     const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
618   Terminator terminator{source, line};
619   return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
620       mask,
621       ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, false>{
622           array, operation, identity, terminator},
623       "REDUCE");
624 }
625 CppTypeFor<TypeCategory::Real, 10> RTDEF(ReduceReal10Value)(
626     const Descriptor &array,
627     ValueReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
628     const char *source, int line, int dim, const Descriptor *mask,
629     const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
630   Terminator terminator{source, line};
631   return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
632       mask,
633       ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, true>{
634           array, operation, identity, terminator},
635       "REDUCE");
636 }
637 void RTDEF(ReduceReal10DimRef)(Descriptor &result, const Descriptor &array,
638     ReferenceReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
639     const char *source, int line, int dim, const Descriptor *mask,
640     const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
641   Terminator terminator{source, line};
642   using Accumulator =
643       ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, false>;
644   Accumulator accumulator{array, operation, identity, terminator};
645   PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
646       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
647 }
648 void RTDEF(ReduceReal10DimValue)(Descriptor &result, const Descriptor &array,
649     ValueReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
650     const char *source, int line, int dim, const Descriptor *mask,
651     const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
652   Terminator terminator{source, line};
653   using Accumulator =
654       ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, true>;
655   Accumulator accumulator{array, operation, identity, terminator};
656   PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
657       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
658 }
659 #endif
660 #if HAS_LDBL128 || HAS_FLOAT128
661 CppFloat128Type RTDEF(ReduceReal16Ref)(const Descriptor &array,
662     ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
663     int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
664     bool ordered) {
665   Terminator terminator{source, line};
666   return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
667       mask,
668       ReduceAccumulator<CppFloat128Type, false>{
669           array, operation, identity, terminator},
670       "REDUCE");
671 }
672 CppFloat128Type RTDEF(ReduceReal16Value)(const Descriptor &array,
673     ValueReductionOperation<CppFloat128Type> operation, const char *source,
674     int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
675     bool ordered) {
676   Terminator terminator{source, line};
677   return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
678       mask,
679       ReduceAccumulator<CppFloat128Type, true>{
680           array, operation, identity, terminator},
681       "REDUCE");
682 }
683 void RTDEF(ReduceReal16DimRef)(Descriptor &result, const Descriptor &array,
684     ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
685     int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
686     bool ordered) {
687   Terminator terminator{source, line};
688   using Accumulator = ReduceAccumulator<CppFloat128Type, false>;
689   Accumulator accumulator{array, operation, identity, terminator};
690   PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
691       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
692 }
693 void RTDEF(ReduceReal16DimValue)(Descriptor &result, const Descriptor &array,
694     ValueReductionOperation<CppFloat128Type> operation, const char *source,
695     int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
696     bool ordered) {
697   Terminator terminator{source, line};
698   using Accumulator = ReduceAccumulator<CppFloat128Type, true>;
699   Accumulator accumulator{array, operation, identity, terminator};
700   PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
701       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
702 }
703 #endif
704 
705 void RTDEF(CppReduceComplex4Ref)(CppTypeFor<TypeCategory::Complex, 4> &result,
706     const Descriptor &array,
707     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
708     const char *source, int line, int dim, const Descriptor *mask,
709     const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
710   Terminator terminator{source, line};
711   result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
712       mask,
713       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, false>{
714           array, operation, identity, terminator},
715       "REDUCE");
716 }
717 void RTDEF(CppReduceComplex4Value)(CppTypeFor<TypeCategory::Complex, 4> &result,
718     const Descriptor &array,
719     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
720     const char *source, int line, int dim, const Descriptor *mask,
721     const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
722   Terminator terminator{source, line};
723   result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
724       mask,
725       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, true>{
726           array, operation, identity, terminator},
727       "REDUCE");
728 }
729 void RTDEF(CppReduceComplex4DimRef)(Descriptor &result, const Descriptor &array,
730     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
731     const char *source, int line, int dim, const Descriptor *mask,
732     const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
733   Terminator terminator{source, line};
734   using Accumulator =
735       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, false>;
736   Accumulator accumulator{array, operation, identity, terminator};
737   PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
738       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
739 }
740 void RTDEF(CppReduceComplex4DimValue)(Descriptor &result,
741     const Descriptor &array,
742     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
743     const char *source, int line, int dim, const Descriptor *mask,
744     const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
745   Terminator terminator{source, line};
746   using Accumulator =
747       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, true>;
748   Accumulator accumulator{array, operation, identity, terminator};
749   PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
750       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
751 }
752 void RTDEF(CppReduceComplex8Ref)(CppTypeFor<TypeCategory::Complex, 8> &result,
753     const Descriptor &array,
754     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
755     const char *source, int line, int dim, const Descriptor *mask,
756     const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
757   Terminator terminator{source, line};
758   result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
759       mask,
760       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, false>{
761           array, operation, identity, terminator},
762       "REDUCE");
763 }
764 void RTDEF(CppReduceComplex8Value)(CppTypeFor<TypeCategory::Complex, 8> &result,
765     const Descriptor &array,
766     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
767     const char *source, int line, int dim, const Descriptor *mask,
768     const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
769   Terminator terminator{source, line};
770   result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
771       mask,
772       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, true>{
773           array, operation, identity, terminator},
774       "REDUCE");
775 }
776 void RTDEF(CppReduceComplex8DimRef)(Descriptor &result, const Descriptor &array,
777     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
778     const char *source, int line, int dim, const Descriptor *mask,
779     const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
780   Terminator terminator{source, line};
781   using Accumulator =
782       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, false>;
783   Accumulator accumulator{array, operation, identity, terminator};
784   PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
785       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
786 }
787 void RTDEF(CppReduceComplex8DimValue)(Descriptor &result,
788     const Descriptor &array,
789     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
790     const char *source, int line, int dim, const Descriptor *mask,
791     const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
792   Terminator terminator{source, line};
793   using Accumulator =
794       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, true>;
795   Accumulator accumulator{array, operation, identity, terminator};
796   PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
797       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
798 }
799 #if HAS_FLOAT80
800 void RTDEF(CppReduceComplex10Ref)(CppTypeFor<TypeCategory::Complex, 10> &result,
801     const Descriptor &array,
802     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 10>>
803         operation,
804     const char *source, int line, int dim, const Descriptor *mask,
805     const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
806   Terminator terminator{source, line};
807   result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
808       dim, mask,
809       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, false>{
810           array, operation, identity, terminator},
811       "REDUCE");
812 }
813 void RTDEF(CppReduceComplex10Value)(
814     CppTypeFor<TypeCategory::Complex, 10> &result, const Descriptor &array,
815     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 10>> operation,
816     const char *source, int line, int dim, const Descriptor *mask,
817     const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
818   Terminator terminator{source, line};
819   result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
820       dim, mask,
821       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, true>{
822           array, operation, identity, terminator},
823       "REDUCE");
824 }
825 void RTDEF(CppReduceComplex10DimRef)(Descriptor &result,
826     const Descriptor &array,
827     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 10>>
828         operation,
829     const char *source, int line, int dim, const Descriptor *mask,
830     const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
831   Terminator terminator{source, line};
832   using Accumulator =
833       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, false>;
834   Accumulator accumulator{array, operation, identity, terminator};
835   PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
836       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
837 }
838 void RTDEF(CppReduceComplex10DimValue)(Descriptor &result,
839     const Descriptor &array,
840     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 10>> operation,
841     const char *source, int line, int dim, const Descriptor *mask,
842     const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
843   Terminator terminator{source, line};
844   using Accumulator =
845       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, true>;
846   Accumulator accumulator{array, operation, identity, terminator};
847   PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
848       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
849 }
850 #endif
851 #if HAS_LDBL128 || HAS_FLOAT128
852 void RTDEF(CppReduceComplex16Ref)(CppTypeFor<TypeCategory::Complex, 16> &result,
853     const Descriptor &array,
854     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 16>>
855         operation,
856     const char *source, int line, int dim, const Descriptor *mask,
857     const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
858   Terminator terminator{source, line};
859   result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
860       dim, mask,
861       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, false>{
862           array, operation, identity, terminator},
863       "REDUCE");
864 }
865 void RTDEF(CppReduceComplex16Value)(
866     CppTypeFor<TypeCategory::Complex, 16> &result, const Descriptor &array,
867     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 16>> operation,
868     const char *source, int line, int dim, const Descriptor *mask,
869     const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
870   Terminator terminator{source, line};
871   result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
872       dim, mask,
873       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, true>{
874           array, operation, identity, terminator},
875       "REDUCE");
876 }
877 void RTDEF(CppReduceComplex16DimRef)(Descriptor &result,
878     const Descriptor &array,
879     ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 16>>
880         operation,
881     const char *source, int line, int dim, const Descriptor *mask,
882     const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
883   Terminator terminator{source, line};
884   using Accumulator =
885       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, false>;
886   Accumulator accumulator{array, operation, identity, terminator};
887   PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
888       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
889 }
890 void RTDEF(CppReduceComplex16DimValue)(Descriptor &result,
891     const Descriptor &array,
892     ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 16>> operation,
893     const char *source, int line, int dim, const Descriptor *mask,
894     const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
895   Terminator terminator{source, line};
896   using Accumulator =
897       ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, true>;
898   Accumulator accumulator{array, operation, identity, terminator};
899   PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
900       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
901 }
902 #endif
903 
904 bool RTDEF(ReduceLogical1Ref)(const Descriptor &array,
905     ReferenceReductionOperation<std::int8_t> operation, const char *source,
906     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
907     bool ordered) {
908   return RTNAME(ReduceInteger1Ref)(
909              array, operation, source, line, dim, mask, identity, ordered) != 0;
910 }
911 bool RTDEF(ReduceLogical1Value)(const Descriptor &array,
912     ValueReductionOperation<std::int8_t> operation, const char *source,
913     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
914     bool ordered) {
915   return RTNAME(ReduceInteger1Value)(
916              array, operation, source, line, dim, mask, identity, ordered) != 0;
917 }
918 void RTDEF(ReduceLogical1DimRef)(Descriptor &result, const Descriptor &array,
919     ReferenceReductionOperation<std::int8_t> operation, const char *source,
920     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
921     bool ordered) {
922   RTNAME(ReduceInteger1DimRef)
923   (result, array, operation, source, line, dim, mask, identity, ordered);
924 }
925 void RTDEF(ReduceLogical1DimValue)(Descriptor &result, const Descriptor &array,
926     ValueReductionOperation<std::int8_t> operation, const char *source,
927     int line, int dim, const Descriptor *mask, const std::int8_t *identity,
928     bool ordered) {
929   RTNAME(ReduceInteger1DimValue)
930   (result, array, operation, source, line, dim, mask, identity, ordered);
931 }
932 bool RTDEF(ReduceLogical2Ref)(const Descriptor &array,
933     ReferenceReductionOperation<std::int16_t> operation, const char *source,
934     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
935     bool ordered) {
936   return RTNAME(ReduceInteger2Ref)(
937              array, operation, source, line, dim, mask, identity, ordered) != 0;
938 }
939 bool RTDEF(ReduceLogical2Value)(const Descriptor &array,
940     ValueReductionOperation<std::int16_t> operation, const char *source,
941     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
942     bool ordered) {
943   return RTNAME(ReduceInteger2Value)(
944              array, operation, source, line, dim, mask, identity, ordered) != 0;
945 }
946 void RTDEF(ReduceLogical2DimRef)(Descriptor &result, const Descriptor &array,
947     ReferenceReductionOperation<std::int16_t> operation, const char *source,
948     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
949     bool ordered) {
950   RTNAME(ReduceInteger2DimRef)
951   (result, array, operation, source, line, dim, mask, identity, ordered);
952 }
953 void RTDEF(ReduceLogical2DimValue)(Descriptor &result, const Descriptor &array,
954     ValueReductionOperation<std::int16_t> operation, const char *source,
955     int line, int dim, const Descriptor *mask, const std::int16_t *identity,
956     bool ordered) {
957   RTNAME(ReduceInteger2DimValue)
958   (result, array, operation, source, line, dim, mask, identity, ordered);
959 }
960 bool RTDEF(ReduceLogical4Ref)(const Descriptor &array,
961     ReferenceReductionOperation<std::int32_t> operation, const char *source,
962     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
963     bool ordered) {
964   return RTNAME(ReduceInteger4Ref)(
965              array, operation, source, line, dim, mask, identity, ordered) != 0;
966 }
967 bool RTDEF(ReduceLogical4Value)(const Descriptor &array,
968     ValueReductionOperation<std::int32_t> operation, const char *source,
969     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
970     bool ordered) {
971   return RTNAME(ReduceInteger4Value)(
972              array, operation, source, line, dim, mask, identity, ordered) != 0;
973 }
974 void RTDEF(ReduceLogical4DimRef)(Descriptor &result, const Descriptor &array,
975     ReferenceReductionOperation<std::int32_t> operation, const char *source,
976     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
977     bool ordered) {
978   RTNAME(ReduceInteger4DimRef)
979   (result, array, operation, source, line, dim, mask, identity, ordered);
980 }
981 void RTDEF(ReduceLogical4DimValue)(Descriptor &result, const Descriptor &array,
982     ValueReductionOperation<std::int32_t> operation, const char *source,
983     int line, int dim, const Descriptor *mask, const std::int32_t *identity,
984     bool ordered) {
985   RTNAME(ReduceInteger4DimValue)
986   (result, array, operation, source, line, dim, mask, identity, ordered);
987 }
988 bool RTDEF(ReduceLogical8Ref)(const Descriptor &array,
989     ReferenceReductionOperation<std::int64_t> operation, const char *source,
990     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
991     bool ordered) {
992   return RTNAME(ReduceInteger8Ref)(
993              array, operation, source, line, dim, mask, identity, ordered) != 0;
994 }
995 bool RTDEF(ReduceLogical8Value)(const Descriptor &array,
996     ValueReductionOperation<std::int64_t> operation, const char *source,
997     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
998     bool ordered) {
999   return RTNAME(ReduceInteger8Value)(
1000              array, operation, source, line, dim, mask, identity, ordered) != 0;
1001 }
1002 void RTDEF(ReduceLogical8DimRef)(Descriptor &result, const Descriptor &array,
1003     ReferenceReductionOperation<std::int64_t> operation, const char *source,
1004     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
1005     bool ordered) {
1006   RTNAME(ReduceInteger8DimRef)
1007   (result, array, operation, source, line, dim, mask, identity, ordered);
1008 }
1009 void RTDEF(ReduceLogical8DimValue)(Descriptor &result, const Descriptor &array,
1010     ValueReductionOperation<std::int64_t> operation, const char *source,
1011     int line, int dim, const Descriptor *mask, const std::int64_t *identity,
1012     bool ordered) {
1013   RTNAME(ReduceInteger8DimValue)
1014   (result, array, operation, source, line, dim, mask, identity, ordered);
1015 }
1016 
1017 void RTDEF(ReduceChar1)(char *result, const Descriptor &array,
1018     ReductionCharOperation<char> operation, const char *source, int line,
1019     int dim, const Descriptor *mask, const char *identity, bool ordered) {
1020   Terminator terminator{source, line};
1021   BufferedReduceAccumulator<char, ReductionCharOperation<char>,
1022       /*hasLength=*/true>
1023       accumulator{array, operation, identity, terminator};
1024   DoTotalReduction<char>(array, dim, mask, accumulator, "REDUCE", terminator);
1025   accumulator.GetResult(result);
1026 }
1027 void RTDEF(ReduceCharacter1Dim)(Descriptor &result, const Descriptor &array,
1028     ReductionCharOperation<char> operation, const char *source, int line,
1029     int dim, const Descriptor *mask, const char *identity, bool ordered) {
1030   Terminator terminator{source, line};
1031   using Accumulator = BufferedReduceAccumulator<char,
1032       ReductionCharOperation<char>, /*hasLength=*/true>;
1033   Accumulator accumulator{array, operation, identity, terminator};
1034   PartialReduction<Accumulator, TypeCategory::Character, 1>(result, array,
1035       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
1036 }
1037 void RTDEF(ReduceChar2)(char16_t *result, const Descriptor &array,
1038     ReductionCharOperation<char16_t> operation, const char *source, int line,
1039     int dim, const Descriptor *mask, const char16_t *identity, bool ordered) {
1040   Terminator terminator{source, line};
1041   BufferedReduceAccumulator<char16_t, ReductionCharOperation<char16_t>,
1042       /*hasLength=*/true>
1043       accumulator{array, operation, identity, terminator};
1044   DoTotalReduction<char16_t>(
1045       array, dim, mask, accumulator, "REDUCE", terminator);
1046   accumulator.GetResult(result);
1047 }
1048 void RTDEF(ReduceCharacter2Dim)(Descriptor &result, const Descriptor &array,
1049     ReductionCharOperation<char16_t> operation, const char *source, int line,
1050     int dim, const Descriptor *mask, const char16_t *identity, bool ordered) {
1051   Terminator terminator{source, line};
1052   using Accumulator = BufferedReduceAccumulator<char16_t,
1053       ReductionCharOperation<char16_t>, /*hasLength=*/true>;
1054   Accumulator accumulator{array, operation, identity, terminator};
1055   PartialReduction<Accumulator, TypeCategory::Character, 2>(result, array,
1056       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
1057 }
1058 void RTDEF(ReduceChar4)(char32_t *result, const Descriptor &array,
1059     ReductionCharOperation<char32_t> operation, const char *source, int line,
1060     int dim, const Descriptor *mask, const char32_t *identity, bool ordered) {
1061   Terminator terminator{source, line};
1062   BufferedReduceAccumulator<char32_t, ReductionCharOperation<char32_t>,
1063       /*hasLength=*/true>
1064       accumulator{array, operation, identity, terminator};
1065   DoTotalReduction<char32_t>(
1066       array, dim, mask, accumulator, "REDUCE", terminator);
1067   accumulator.GetResult(result);
1068 }
1069 void RTDEF(ReduceCharacter4Dim)(Descriptor &result, const Descriptor &array,
1070     ReductionCharOperation<char32_t> operation, const char *source, int line,
1071     int dim, const Descriptor *mask, const char32_t *identity, bool ordered) {
1072   Terminator terminator{source, line};
1073   using Accumulator = BufferedReduceAccumulator<char32_t,
1074       ReductionCharOperation<char32_t>, /*hasLength=*/true>;
1075   Accumulator accumulator{array, operation, identity, terminator};
1076   PartialReduction<Accumulator, TypeCategory::Character, 4>(result, array,
1077       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
1078 }
1079 
1080 void RTDEF(ReduceDerivedType)(char *result, const Descriptor &array,
1081     ReductionDerivedTypeOperation operation, const char *source, int line,
1082     int dim, const Descriptor *mask, const char *identity, bool ordered) {
1083   Terminator terminator{source, line};
1084   BufferedReduceAccumulator<char, ReductionDerivedTypeOperation,
1085       /*hasLength=*/false>
1086       accumulator{array, operation, identity, terminator};
1087   DoTotalReduction<char>(array, dim, mask, accumulator, "REDUCE", terminator);
1088   accumulator.GetResult(result);
1089 }
1090 void RTDEF(ReduceDerivedTypeDim)(Descriptor &result, const Descriptor &array,
1091     ReductionDerivedTypeOperation operation, const char *source, int line,
1092     int dim, const Descriptor *mask, const char *identity, bool ordered) {
1093   Terminator terminator{source, line};
1094   using Accumulator = BufferedReduceAccumulator<char,
1095       ReductionDerivedTypeOperation, /*hasLength=*/false>;
1096   Accumulator accumulator{array, operation, identity, terminator};
1097   PartialReduction<Accumulator, TypeCategory::Derived, 0>(result, array,
1098       array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
1099 }
1100 
1101 RT_EXT_API_GROUP_END
1102 } // extern "C"
1103 } // namespace Fortran::runtime
1104