[libc++][Android] Allow testing libc++ with clang-r536225 (#116149)
[llvm-project.git] / flang / runtime / reduce.cpp
blob8fc0bb8c7157e417fc202fe603de144acc2fdf44
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 //===----------------------------------------------------------------------===//
9 // REDUCE() implementation
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"
17 namespace Fortran::runtime {
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);
37 } else {
38 result_ = *operand;
40 return true;
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");
53 private:
54 const Descriptor &array_;
55 common::optional<T> result_;
56 Operation operation_;
57 const T *identity_{nullptr};
58 Terminator &terminator_;
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);
79 activeTemp_ = 1 - activeTemp_;
80 } else {
81 activeTemp_ = 0;
82 std::memcpy(&*temp_[activeTemp_], operand, elementBytes_);
84 return true;
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");
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)};
109 extern "C" {
110 RT_EXT_API_GROUP_BEGIN
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");
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");
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);
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);
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");
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");
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);
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);
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");
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");
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);
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);
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");
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");
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);
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);
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");
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");
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);
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);
323 #endif
325 // TODO: real/complex(2 & 3)
326 float RTDEF(ReduceReal4Ref)(const Descriptor &array,
327 ReferenceReductionOperation<float> operation, const char *source, int line,
328 int dim, const Descriptor *mask, const float *identity, bool ordered) {
329 Terminator terminator{source, line};
330 return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
331 mask,
332 ReduceAccumulator<float, false>{array, operation, identity, terminator},
333 "REDUCE");
335 float RTDEF(ReduceReal4Value)(const Descriptor &array,
336 ValueReductionOperation<float> operation, const char *source, int line,
337 int dim, const Descriptor *mask, const float *identity, bool ordered) {
338 Terminator terminator{source, line};
339 return GetTotalReduction<TypeCategory::Real, 4>(array, source, line, dim,
340 mask,
341 ReduceAccumulator<float, true>{array, operation, identity, terminator},
342 "REDUCE");
344 void RTDEF(ReduceReal4DimRef)(Descriptor &result, const Descriptor &array,
345 ReferenceReductionOperation<float> operation, const char *source, int line,
346 int dim, const Descriptor *mask, const float *identity, bool ordered) {
347 Terminator terminator{source, line};
348 using Accumulator = ReduceAccumulator<float, false>;
349 Accumulator accumulator{array, operation, identity, terminator};
350 PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
351 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
353 void RTDEF(ReduceReal4DimValue)(Descriptor &result, const Descriptor &array,
354 ValueReductionOperation<float> operation, const char *source, int line,
355 int dim, const Descriptor *mask, const float *identity, bool ordered) {
356 Terminator terminator{source, line};
357 using Accumulator = ReduceAccumulator<float, true>;
358 Accumulator accumulator{array, operation, identity, terminator};
359 PartialReduction<Accumulator, TypeCategory::Real, 4>(result, array,
360 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
362 double RTDEF(ReduceReal8Ref)(const Descriptor &array,
363 ReferenceReductionOperation<double> operation, const char *source, int line,
364 int dim, const Descriptor *mask, const double *identity, bool ordered) {
365 Terminator terminator{source, line};
366 return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
367 mask,
368 ReduceAccumulator<double, false>{array, operation, identity, terminator},
369 "REDUCE");
371 double RTDEF(ReduceReal8Value)(const Descriptor &array,
372 ValueReductionOperation<double> operation, const char *source, int line,
373 int dim, const Descriptor *mask, const double *identity, bool ordered) {
374 Terminator terminator{source, line};
375 return GetTotalReduction<TypeCategory::Real, 8>(array, source, line, dim,
376 mask,
377 ReduceAccumulator<double, true>{array, operation, identity, terminator},
378 "REDUCE");
380 void RTDEF(ReduceReal8DimRef)(Descriptor &result, const Descriptor &array,
381 ReferenceReductionOperation<double> operation, const char *source, int line,
382 int dim, const Descriptor *mask, const double *identity, bool ordered) {
383 Terminator terminator{source, line};
384 using Accumulator = ReduceAccumulator<double, false>;
385 Accumulator accumulator{array, operation, identity, terminator};
386 PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
387 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
389 void RTDEF(ReduceReal8DimValue)(Descriptor &result, const Descriptor &array,
390 ValueReductionOperation<double> operation, const char *source, int line,
391 int dim, const Descriptor *mask, const double *identity, bool ordered) {
392 Terminator terminator{source, line};
393 using Accumulator = ReduceAccumulator<double, true>;
394 Accumulator accumulator{array, operation, identity, terminator};
395 PartialReduction<Accumulator, TypeCategory::Real, 8>(result, array,
396 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
398 #if HAS_FLOAT80
399 CppTypeFor<TypeCategory::Real, 10> RTDEF(ReduceReal10Ref)(
400 const Descriptor &array,
401 ReferenceReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
402 const char *source, int line, int dim, const Descriptor *mask,
403 const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
404 Terminator terminator{source, line};
405 return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
406 mask,
407 ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, false>{
408 array, operation, identity, terminator},
409 "REDUCE");
411 CppTypeFor<TypeCategory::Real, 10> RTDEF(ReduceReal10Value)(
412 const Descriptor &array,
413 ValueReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
414 const char *source, int line, int dim, const Descriptor *mask,
415 const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
416 Terminator terminator{source, line};
417 return GetTotalReduction<TypeCategory::Real, 10>(array, source, line, dim,
418 mask,
419 ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, true>{
420 array, operation, identity, terminator},
421 "REDUCE");
423 void RTDEF(ReduceReal10DimRef)(Descriptor &result, const Descriptor &array,
424 ReferenceReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
425 const char *source, int line, int dim, const Descriptor *mask,
426 const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
427 Terminator terminator{source, line};
428 using Accumulator =
429 ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, false>;
430 Accumulator accumulator{array, operation, identity, terminator};
431 PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
432 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
434 void RTDEF(ReduceReal10DimValue)(Descriptor &result, const Descriptor &array,
435 ValueReductionOperation<CppTypeFor<TypeCategory::Real, 10>> operation,
436 const char *source, int line, int dim, const Descriptor *mask,
437 const CppTypeFor<TypeCategory::Real, 10> *identity, bool ordered) {
438 Terminator terminator{source, line};
439 using Accumulator =
440 ReduceAccumulator<CppTypeFor<TypeCategory::Real, 10>, true>;
441 Accumulator accumulator{array, operation, identity, terminator};
442 PartialReduction<Accumulator, TypeCategory::Real, 10>(result, array,
443 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
445 #endif
446 #if HAS_LDBL128 || HAS_FLOAT128
447 CppFloat128Type RTDEF(ReduceReal16Ref)(const Descriptor &array,
448 ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
449 int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
450 bool ordered) {
451 Terminator terminator{source, line};
452 return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
453 mask,
454 ReduceAccumulator<CppFloat128Type, false>{
455 array, operation, identity, terminator},
456 "REDUCE");
458 CppFloat128Type RTDEF(ReduceReal16Value)(const Descriptor &array,
459 ValueReductionOperation<CppFloat128Type> operation, const char *source,
460 int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
461 bool ordered) {
462 Terminator terminator{source, line};
463 return GetTotalReduction<TypeCategory::Real, 16>(array, source, line, dim,
464 mask,
465 ReduceAccumulator<CppFloat128Type, true>{
466 array, operation, identity, terminator},
467 "REDUCE");
469 void RTDEF(ReduceReal16DimRef)(Descriptor &result, const Descriptor &array,
470 ReferenceReductionOperation<CppFloat128Type> operation, const char *source,
471 int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
472 bool ordered) {
473 Terminator terminator{source, line};
474 using Accumulator = ReduceAccumulator<CppFloat128Type, false>;
475 Accumulator accumulator{array, operation, identity, terminator};
476 PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
477 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
479 void RTDEF(ReduceReal16DimValue)(Descriptor &result, const Descriptor &array,
480 ValueReductionOperation<CppFloat128Type> operation, const char *source,
481 int line, int dim, const Descriptor *mask, const CppFloat128Type *identity,
482 bool ordered) {
483 Terminator terminator{source, line};
484 using Accumulator = ReduceAccumulator<CppFloat128Type, true>;
485 Accumulator accumulator{array, operation, identity, terminator};
486 PartialReduction<Accumulator, TypeCategory::Real, 16>(result, array,
487 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
489 #endif
491 void RTDEF(CppReduceComplex4Ref)(CppTypeFor<TypeCategory::Complex, 4> &result,
492 const Descriptor &array,
493 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
494 const char *source, int line, int dim, const Descriptor *mask,
495 const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
496 Terminator terminator{source, line};
497 result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
498 mask,
499 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, false>{
500 array, operation, identity, terminator},
501 "REDUCE");
503 void RTDEF(CppReduceComplex4Value)(CppTypeFor<TypeCategory::Complex, 4> &result,
504 const Descriptor &array,
505 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
506 const char *source, int line, int dim, const Descriptor *mask,
507 const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
508 Terminator terminator{source, line};
509 result = GetTotalReduction<TypeCategory::Complex, 4>(array, source, line, dim,
510 mask,
511 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, true>{
512 array, operation, identity, terminator},
513 "REDUCE");
515 void RTDEF(CppReduceComplex4DimRef)(Descriptor &result, const Descriptor &array,
516 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
517 const char *source, int line, int dim, const Descriptor *mask,
518 const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
519 Terminator terminator{source, line};
520 using Accumulator =
521 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, false>;
522 Accumulator accumulator{array, operation, identity, terminator};
523 PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
524 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
526 void RTDEF(CppReduceComplex4DimValue)(Descriptor &result,
527 const Descriptor &array,
528 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 4>> operation,
529 const char *source, int line, int dim, const Descriptor *mask,
530 const CppTypeFor<TypeCategory::Complex, 4> *identity, bool ordered) {
531 Terminator terminator{source, line};
532 using Accumulator =
533 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 4>, true>;
534 Accumulator accumulator{array, operation, identity, terminator};
535 PartialReduction<Accumulator, TypeCategory::Complex, 4>(result, array,
536 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
538 void RTDEF(CppReduceComplex8Ref)(CppTypeFor<TypeCategory::Complex, 8> &result,
539 const Descriptor &array,
540 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
541 const char *source, int line, int dim, const Descriptor *mask,
542 const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
543 Terminator terminator{source, line};
544 result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
545 mask,
546 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, false>{
547 array, operation, identity, terminator},
548 "REDUCE");
550 void RTDEF(CppReduceComplex8Value)(CppTypeFor<TypeCategory::Complex, 8> &result,
551 const Descriptor &array,
552 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
553 const char *source, int line, int dim, const Descriptor *mask,
554 const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
555 Terminator terminator{source, line};
556 result = GetTotalReduction<TypeCategory::Complex, 8>(array, source, line, dim,
557 mask,
558 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, true>{
559 array, operation, identity, terminator},
560 "REDUCE");
562 void RTDEF(CppReduceComplex8DimRef)(Descriptor &result, const Descriptor &array,
563 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
564 const char *source, int line, int dim, const Descriptor *mask,
565 const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
566 Terminator terminator{source, line};
567 using Accumulator =
568 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, false>;
569 Accumulator accumulator{array, operation, identity, terminator};
570 PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
571 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
573 void RTDEF(CppReduceComplex8DimValue)(Descriptor &result,
574 const Descriptor &array,
575 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 8>> operation,
576 const char *source, int line, int dim, const Descriptor *mask,
577 const CppTypeFor<TypeCategory::Complex, 8> *identity, bool ordered) {
578 Terminator terminator{source, line};
579 using Accumulator =
580 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 8>, true>;
581 Accumulator accumulator{array, operation, identity, terminator};
582 PartialReduction<Accumulator, TypeCategory::Complex, 8>(result, array,
583 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
585 #if HAS_FLOAT80
586 void RTDEF(CppReduceComplex10Ref)(CppTypeFor<TypeCategory::Complex, 10> &result,
587 const Descriptor &array,
588 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 10>>
589 operation,
590 const char *source, int line, int dim, const Descriptor *mask,
591 const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
592 Terminator terminator{source, line};
593 result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
594 dim, mask,
595 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, false>{
596 array, operation, identity, terminator},
597 "REDUCE");
599 void RTDEF(CppReduceComplex10Value)(
600 CppTypeFor<TypeCategory::Complex, 10> &result, const Descriptor &array,
601 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 10>> operation,
602 const char *source, int line, int dim, const Descriptor *mask,
603 const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
604 Terminator terminator{source, line};
605 result = GetTotalReduction<TypeCategory::Complex, 10>(array, source, line,
606 dim, mask,
607 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, true>{
608 array, operation, identity, terminator},
609 "REDUCE");
611 void RTDEF(CppReduceComplex10DimRef)(Descriptor &result,
612 const Descriptor &array,
613 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 10>>
614 operation,
615 const char *source, int line, int dim, const Descriptor *mask,
616 const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
617 Terminator terminator{source, line};
618 using Accumulator =
619 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, false>;
620 Accumulator accumulator{array, operation, identity, terminator};
621 PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
622 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
624 void RTDEF(CppReduceComplex10DimValue)(Descriptor &result,
625 const Descriptor &array,
626 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 10>> operation,
627 const char *source, int line, int dim, const Descriptor *mask,
628 const CppTypeFor<TypeCategory::Complex, 10> *identity, bool ordered) {
629 Terminator terminator{source, line};
630 using Accumulator =
631 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 10>, true>;
632 Accumulator accumulator{array, operation, identity, terminator};
633 PartialReduction<Accumulator, TypeCategory::Complex, 10>(result, array,
634 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
636 #endif
637 #if HAS_LDBL128 || HAS_FLOAT128
638 void RTDEF(CppReduceComplex16Ref)(CppTypeFor<TypeCategory::Complex, 16> &result,
639 const Descriptor &array,
640 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 16>>
641 operation,
642 const char *source, int line, int dim, const Descriptor *mask,
643 const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
644 Terminator terminator{source, line};
645 result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
646 dim, mask,
647 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, false>{
648 array, operation, identity, terminator},
649 "REDUCE");
651 void RTDEF(CppReduceComplex16Value)(
652 CppTypeFor<TypeCategory::Complex, 16> &result, const Descriptor &array,
653 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 16>> operation,
654 const char *source, int line, int dim, const Descriptor *mask,
655 const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
656 Terminator terminator{source, line};
657 result = GetTotalReduction<TypeCategory::Complex, 16>(array, source, line,
658 dim, mask,
659 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, true>{
660 array, operation, identity, terminator},
661 "REDUCE");
663 void RTDEF(CppReduceComplex16DimRef)(Descriptor &result,
664 const Descriptor &array,
665 ReferenceReductionOperation<CppTypeFor<TypeCategory::Complex, 16>>
666 operation,
667 const char *source, int line, int dim, const Descriptor *mask,
668 const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
669 Terminator terminator{source, line};
670 using Accumulator =
671 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, false>;
672 Accumulator accumulator{array, operation, identity, terminator};
673 PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
674 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
676 void RTDEF(CppReduceComplex16DimValue)(Descriptor &result,
677 const Descriptor &array,
678 ValueReductionOperation<CppTypeFor<TypeCategory::Complex, 16>> operation,
679 const char *source, int line, int dim, const Descriptor *mask,
680 const CppTypeFor<TypeCategory::Complex, 16> *identity, bool ordered) {
681 Terminator terminator{source, line};
682 using Accumulator =
683 ReduceAccumulator<CppTypeFor<TypeCategory::Complex, 16>, true>;
684 Accumulator accumulator{array, operation, identity, terminator};
685 PartialReduction<Accumulator, TypeCategory::Complex, 16>(result, array,
686 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
688 #endif
690 bool RTDEF(ReduceLogical1Ref)(const Descriptor &array,
691 ReferenceReductionOperation<std::int8_t> operation, const char *source,
692 int line, int dim, const Descriptor *mask, const std::int8_t *identity,
693 bool ordered) {
694 return RTNAME(ReduceInteger1Ref)(
695 array, operation, source, line, dim, mask, identity, ordered) != 0;
697 bool RTDEF(ReduceLogical1Value)(const Descriptor &array,
698 ValueReductionOperation<std::int8_t> operation, const char *source,
699 int line, int dim, const Descriptor *mask, const std::int8_t *identity,
700 bool ordered) {
701 return RTNAME(ReduceInteger1Value)(
702 array, operation, source, line, dim, mask, identity, ordered) != 0;
704 void RTDEF(ReduceLogical1DimRef)(Descriptor &result, const Descriptor &array,
705 ReferenceReductionOperation<std::int8_t> operation, const char *source,
706 int line, int dim, const Descriptor *mask, const std::int8_t *identity,
707 bool ordered) {
708 RTNAME(ReduceInteger1DimRef)
709 (result, array, operation, source, line, dim, mask, identity, ordered);
711 void RTDEF(ReduceLogical1DimValue)(Descriptor &result, const Descriptor &array,
712 ValueReductionOperation<std::int8_t> operation, const char *source,
713 int line, int dim, const Descriptor *mask, const std::int8_t *identity,
714 bool ordered) {
715 RTNAME(ReduceInteger1DimValue)
716 (result, array, operation, source, line, dim, mask, identity, ordered);
718 bool RTDEF(ReduceLogical2Ref)(const Descriptor &array,
719 ReferenceReductionOperation<std::int16_t> operation, const char *source,
720 int line, int dim, const Descriptor *mask, const std::int16_t *identity,
721 bool ordered) {
722 return RTNAME(ReduceInteger2Ref)(
723 array, operation, source, line, dim, mask, identity, ordered) != 0;
725 bool RTDEF(ReduceLogical2Value)(const Descriptor &array,
726 ValueReductionOperation<std::int16_t> operation, const char *source,
727 int line, int dim, const Descriptor *mask, const std::int16_t *identity,
728 bool ordered) {
729 return RTNAME(ReduceInteger2Value)(
730 array, operation, source, line, dim, mask, identity, ordered) != 0;
732 void RTDEF(ReduceLogical2DimRef)(Descriptor &result, const Descriptor &array,
733 ReferenceReductionOperation<std::int16_t> operation, const char *source,
734 int line, int dim, const Descriptor *mask, const std::int16_t *identity,
735 bool ordered) {
736 RTNAME(ReduceInteger2DimRef)
737 (result, array, operation, source, line, dim, mask, identity, ordered);
739 void RTDEF(ReduceLogical2DimValue)(Descriptor &result, const Descriptor &array,
740 ValueReductionOperation<std::int16_t> operation, const char *source,
741 int line, int dim, const Descriptor *mask, const std::int16_t *identity,
742 bool ordered) {
743 RTNAME(ReduceInteger2DimValue)
744 (result, array, operation, source, line, dim, mask, identity, ordered);
746 bool RTDEF(ReduceLogical4Ref)(const Descriptor &array,
747 ReferenceReductionOperation<std::int32_t> operation, const char *source,
748 int line, int dim, const Descriptor *mask, const std::int32_t *identity,
749 bool ordered) {
750 return RTNAME(ReduceInteger4Ref)(
751 array, operation, source, line, dim, mask, identity, ordered) != 0;
753 bool RTDEF(ReduceLogical4Value)(const Descriptor &array,
754 ValueReductionOperation<std::int32_t> operation, const char *source,
755 int line, int dim, const Descriptor *mask, const std::int32_t *identity,
756 bool ordered) {
757 return RTNAME(ReduceInteger4Value)(
758 array, operation, source, line, dim, mask, identity, ordered) != 0;
760 void RTDEF(ReduceLogical4DimRef)(Descriptor &result, const Descriptor &array,
761 ReferenceReductionOperation<std::int32_t> operation, const char *source,
762 int line, int dim, const Descriptor *mask, const std::int32_t *identity,
763 bool ordered) {
764 RTNAME(ReduceInteger4DimRef)
765 (result, array, operation, source, line, dim, mask, identity, ordered);
767 void RTDEF(ReduceLogical4DimValue)(Descriptor &result, const Descriptor &array,
768 ValueReductionOperation<std::int32_t> operation, const char *source,
769 int line, int dim, const Descriptor *mask, const std::int32_t *identity,
770 bool ordered) {
771 RTNAME(ReduceInteger4DimValue)
772 (result, array, operation, source, line, dim, mask, identity, ordered);
774 bool RTDEF(ReduceLogical8Ref)(const Descriptor &array,
775 ReferenceReductionOperation<std::int64_t> operation, const char *source,
776 int line, int dim, const Descriptor *mask, const std::int64_t *identity,
777 bool ordered) {
778 return RTNAME(ReduceInteger8Ref)(
779 array, operation, source, line, dim, mask, identity, ordered) != 0;
781 bool RTDEF(ReduceLogical8Value)(const Descriptor &array,
782 ValueReductionOperation<std::int64_t> operation, const char *source,
783 int line, int dim, const Descriptor *mask, const std::int64_t *identity,
784 bool ordered) {
785 return RTNAME(ReduceInteger8Value)(
786 array, operation, source, line, dim, mask, identity, ordered) != 0;
788 void RTDEF(ReduceLogical8DimRef)(Descriptor &result, const Descriptor &array,
789 ReferenceReductionOperation<std::int64_t> operation, const char *source,
790 int line, int dim, const Descriptor *mask, const std::int64_t *identity,
791 bool ordered) {
792 RTNAME(ReduceInteger8DimRef)
793 (result, array, operation, source, line, dim, mask, identity, ordered);
795 void RTDEF(ReduceLogical8DimValue)(Descriptor &result, const Descriptor &array,
796 ValueReductionOperation<std::int64_t> operation, const char *source,
797 int line, int dim, const Descriptor *mask, const std::int64_t *identity,
798 bool ordered) {
799 RTNAME(ReduceInteger8DimValue)
800 (result, array, operation, source, line, dim, mask, identity, ordered);
803 void RTDEF(ReduceChar1)(char *result, const Descriptor &array,
804 ReductionCharOperation<char> operation, const char *source, int line,
805 int dim, const Descriptor *mask, const char *identity, bool ordered) {
806 Terminator terminator{source, line};
807 BufferedReduceAccumulator<char, ReductionCharOperation<char>,
808 /*hasLength=*/true>
809 accumulator{array, operation, identity, terminator};
810 DoTotalReduction<char>(array, dim, mask, accumulator, "REDUCE", terminator);
811 accumulator.GetResult(result);
813 void RTDEF(ReduceCharacter1Dim)(Descriptor &result, const Descriptor &array,
814 ReductionCharOperation<char> operation, const char *source, int line,
815 int dim, const Descriptor *mask, const char *identity, bool ordered) {
816 Terminator terminator{source, line};
817 using Accumulator = BufferedReduceAccumulator<char,
818 ReductionCharOperation<char>, /*hasLength=*/true>;
819 Accumulator accumulator{array, operation, identity, terminator};
820 PartialReduction<Accumulator, TypeCategory::Character, 1>(result, array,
821 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
823 void RTDEF(ReduceChar2)(char16_t *result, const Descriptor &array,
824 ReductionCharOperation<char16_t> operation, const char *source, int line,
825 int dim, const Descriptor *mask, const char16_t *identity, bool ordered) {
826 Terminator terminator{source, line};
827 BufferedReduceAccumulator<char16_t, ReductionCharOperation<char16_t>,
828 /*hasLength=*/true>
829 accumulator{array, operation, identity, terminator};
830 DoTotalReduction<char16_t>(
831 array, dim, mask, accumulator, "REDUCE", terminator);
832 accumulator.GetResult(result);
834 void RTDEF(ReduceCharacter2Dim)(Descriptor &result, const Descriptor &array,
835 ReductionCharOperation<char16_t> operation, const char *source, int line,
836 int dim, const Descriptor *mask, const char16_t *identity, bool ordered) {
837 Terminator terminator{source, line};
838 using Accumulator = BufferedReduceAccumulator<char16_t,
839 ReductionCharOperation<char16_t>, /*hasLength=*/true>;
840 Accumulator accumulator{array, operation, identity, terminator};
841 PartialReduction<Accumulator, TypeCategory::Character, 2>(result, array,
842 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
844 void RTDEF(ReduceChar4)(char32_t *result, const Descriptor &array,
845 ReductionCharOperation<char32_t> operation, const char *source, int line,
846 int dim, const Descriptor *mask, const char32_t *identity, bool ordered) {
847 Terminator terminator{source, line};
848 BufferedReduceAccumulator<char32_t, ReductionCharOperation<char32_t>,
849 /*hasLength=*/true>
850 accumulator{array, operation, identity, terminator};
851 DoTotalReduction<char32_t>(
852 array, dim, mask, accumulator, "REDUCE", terminator);
853 accumulator.GetResult(result);
855 void RTDEF(ReduceCharacter4Dim)(Descriptor &result, const Descriptor &array,
856 ReductionCharOperation<char32_t> operation, const char *source, int line,
857 int dim, const Descriptor *mask, const char32_t *identity, bool ordered) {
858 Terminator terminator{source, line};
859 using Accumulator = BufferedReduceAccumulator<char32_t,
860 ReductionCharOperation<char32_t>, /*hasLength=*/true>;
861 Accumulator accumulator{array, operation, identity, terminator};
862 PartialReduction<Accumulator, TypeCategory::Character, 4>(result, array,
863 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
866 void RTDEF(ReduceDerivedType)(char *result, const Descriptor &array,
867 ReductionDerivedTypeOperation operation, const char *source, int line,
868 int dim, const Descriptor *mask, const char *identity, bool ordered) {
869 Terminator terminator{source, line};
870 BufferedReduceAccumulator<char, ReductionDerivedTypeOperation,
871 /*hasLength=*/false>
872 accumulator{array, operation, identity, terminator};
873 DoTotalReduction<char>(array, dim, mask, accumulator, "REDUCE", terminator);
874 accumulator.GetResult(result);
876 void RTDEF(ReduceDerivedTypeDim)(Descriptor &result, const Descriptor &array,
877 ReductionDerivedTypeOperation operation, const char *source, int line,
878 int dim, const Descriptor *mask, const char *identity, bool ordered) {
879 Terminator terminator{source, line};
880 using Accumulator = BufferedReduceAccumulator<char,
881 ReductionDerivedTypeOperation, /*hasLength=*/false>;
882 Accumulator accumulator{array, operation, identity, terminator};
883 PartialReduction<Accumulator, TypeCategory::Derived, 0>(result, array,
884 array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator);
887 RT_EXT_API_GROUP_END
888 } // extern "C"
889 } // namespace Fortran::runtime