1 | //===-- lib/runtime/reduce.cpp ----------------------------------*- C++ -*-===// |
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 "flang-rt/runtime/descriptor.h" |
13 | #include "flang-rt/runtime/reduction-templates.h" |
14 | #include "flang-rt/runtime/terminator.h" |
15 | #include "flang-rt/runtime/tools.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 | |