1 //===-- runtime/reduce.cpp ------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // REDUCE() implementation
11 #include "flang/Runtime/reduce.h"
12 #include "reduction-templates.h"
13 #include "terminator.h"
15 #include "flang/Runtime/descriptor.h"
17 namespace Fortran::runtime
{
19 template <typename T
, bool isByValue
> class ReduceAccumulator
{
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(); }
29 RT_API_ATTRS
bool AccumulateAt(const SubscriptValue at
[]) {
30 const auto *operand
{array_
.Element
<A
>(at
)};
32 if constexpr (isByValue
) {
33 result_
= operation_(*result_
, *operand
);
35 result_
= operation_(&*result_
, operand
);
43 RT_API_ATTRS
void GetResult(A
*to
, int /*zeroBasedDim*/ = -1) {
46 } else if (identity_
) {
49 terminator_
.Crash("REDUCE() without IDENTITY= has no result");
54 const Descriptor
&array_
;
55 common::optional
<T
> result_
;
57 const T
*identity_
{nullptr};
58 Terminator
&terminator_
;
61 template <typename T
, typename OP
, bool hasLength
>
62 class BufferedReduceAccumulator
{
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; }
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_
);
77 operation_(&*temp_
[1 - activeTemp_
], &*temp_
[activeTemp_
], operand
);
79 activeTemp_
= 1 - activeTemp_
;
82 std::memcpy(&*temp_
[activeTemp_
], operand
, elementBytes_
);
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_
);
93 terminator_
.Crash("REDUCE() without IDENTITY= has no result");
98 const Descriptor
&array_
;
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_
)};
106 std::size_t length_
{elementBytes_
/ sizeof(T
)};
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
,
116 Terminator terminator
{source
, line
};
117 return GetTotalReduction
<TypeCategory::Integer
, 1>(array
, source
, line
, dim
,
119 ReduceAccumulator
<std::int8_t, false>{
120 array
, operation
, identity
, terminator
},
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
,
127 Terminator terminator
{source
, line
};
128 return GetTotalReduction
<TypeCategory::Integer
, 1>(array
, source
, line
, dim
,
130 ReduceAccumulator
<std::int8_t, true>{
131 array
, operation
, identity
, terminator
},
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
,
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
,
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
,
158 Terminator terminator
{source
, line
};
159 return GetTotalReduction
<TypeCategory::Integer
, 2>(array
, source
, line
, dim
,
161 ReduceAccumulator
<std::int16_t, false>{
162 array
, operation
, identity
, terminator
},
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
,
169 Terminator terminator
{source
, line
};
170 return GetTotalReduction
<TypeCategory::Integer
, 2>(array
, source
, line
, dim
,
172 ReduceAccumulator
<std::int16_t, true>{
173 array
, operation
, identity
, terminator
},
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
,
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
,
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
,
200 Terminator terminator
{source
, line
};
201 return GetTotalReduction
<TypeCategory::Integer
, 4>(array
, source
, line
, dim
,
203 ReduceAccumulator
<std::int32_t, false>{
204 array
, operation
, identity
, terminator
},
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
,
211 Terminator terminator
{source
, line
};
212 return GetTotalReduction
<TypeCategory::Integer
, 4>(array
, source
, line
, dim
,
214 ReduceAccumulator
<std::int32_t, true>{
215 array
, operation
, identity
, terminator
},
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
,
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
,
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
,
242 Terminator terminator
{source
, line
};
243 return GetTotalReduction
<TypeCategory::Integer
, 8>(array
, source
, line
, dim
,
245 ReduceAccumulator
<std::int64_t, false>{
246 array
, operation
, identity
, terminator
},
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
,
253 Terminator terminator
{source
, line
};
254 return GetTotalReduction
<TypeCategory::Integer
, 8>(array
, source
, line
, dim
,
256 ReduceAccumulator
<std::int64_t, true>{
257 array
, operation
, identity
, terminator
},
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
,
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
,
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
,
285 Terminator terminator
{source
, line
};
286 return GetTotalReduction
<TypeCategory::Integer
, 16>(array
, source
, line
, dim
,
288 ReduceAccumulator
<common::int128_t
, false>{
289 array
, operation
, identity
, terminator
},
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
,
296 Terminator terminator
{source
, line
};
297 return GetTotalReduction
<TypeCategory::Integer
, 16>(array
, source
, line
, dim
,
299 ReduceAccumulator
<common::int128_t
, true>{
300 array
, operation
, identity
, terminator
},
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
,
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
,
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
);
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
,
332 ReduceAccumulator
<float, false>{array
, operation
, identity
, terminator
},
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
,
341 ReduceAccumulator
<float, true>{array
, operation
, identity
, terminator
},
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
,
368 ReduceAccumulator
<double, false>{array
, operation
, identity
, terminator
},
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
,
377 ReduceAccumulator
<double, true>{array
, operation
, identity
, terminator
},
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
);
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
,
407 ReduceAccumulator
<CppTypeFor
<TypeCategory::Real
, 10>, false>{
408 array
, operation
, identity
, terminator
},
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
,
419 ReduceAccumulator
<CppTypeFor
<TypeCategory::Real
, 10>, true>{
420 array
, operation
, identity
, terminator
},
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
};
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
};
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
);
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
,
451 Terminator terminator
{source
, line
};
452 return GetTotalReduction
<TypeCategory::Real
, 16>(array
, source
, line
, dim
,
454 ReduceAccumulator
<CppFloat128Type
, false>{
455 array
, operation
, identity
, terminator
},
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
,
462 Terminator terminator
{source
, line
};
463 return GetTotalReduction
<TypeCategory::Real
, 16>(array
, source
, line
, dim
,
465 ReduceAccumulator
<CppFloat128Type
, true>{
466 array
, operation
, identity
, terminator
},
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
,
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
,
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
);
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
,
499 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 4>, false>{
500 array
, operation
, identity
, terminator
},
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
,
511 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 4>, true>{
512 array
, operation
, identity
, terminator
},
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
};
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
};
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
,
546 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 8>, false>{
547 array
, operation
, identity
, terminator
},
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
,
558 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 8>, true>{
559 array
, operation
, identity
, terminator
},
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
};
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
};
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
);
586 void RTDEF(CppReduceComplex10Ref
)(CppTypeFor
<TypeCategory::Complex
, 10> &result
,
587 const Descriptor
&array
,
588 ReferenceReductionOperation
<CppTypeFor
<TypeCategory::Complex
, 10>>
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
,
595 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 10>, false>{
596 array
, operation
, identity
, terminator
},
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
,
607 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 10>, true>{
608 array
, operation
, identity
, terminator
},
611 void RTDEF(CppReduceComplex10DimRef
)(Descriptor
&result
,
612 const Descriptor
&array
,
613 ReferenceReductionOperation
<CppTypeFor
<TypeCategory::Complex
, 10>>
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
};
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
};
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
);
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>>
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
,
647 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 16>, false>{
648 array
, operation
, identity
, terminator
},
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
,
659 ReduceAccumulator
<CppTypeFor
<TypeCategory::Complex
, 16>, true>{
660 array
, operation
, identity
, terminator
},
663 void RTDEF(CppReduceComplex16DimRef
)(Descriptor
&result
,
664 const Descriptor
&array
,
665 ReferenceReductionOperation
<CppTypeFor
<TypeCategory::Complex
, 16>>
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
};
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
};
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
);
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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>,
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
>,
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
>,
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
,
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
);
889 } // namespace Fortran::runtime