9.2
general documentation
cs_reducers.h
Go to the documentation of this file.
1#ifndef CS_REDUCERS_H
2#define CS_REDUCERS_H
3
4/*============================================================================
5 * Structures for reduction
6 *============================================================================*/
7
8/*
9 This file is part of code_saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2026 EDF S.A.
12
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free Software
15 Foundation; either version 2 of the License, or (at your option) any later
16 version.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25 Street, Fifth Floor, Boston, MA 02110-1301, USA.
26*/
27
28/*----------------------------------------------------------------------------*/
29
30#include "base/cs_defs.h"
31
32/*----------------------------------------------------------------------------
33 * External library headers
34 *----------------------------------------------------------------------------*/
35
36/*----------------------------------------------------------------------------
37 * Local headers
38 *----------------------------------------------------------------------------*/
39
40#include "base/cs_base.h"
41#include "base/cs_math.h"
42
43/*============================================================================
44 * Macro definitions
45 *============================================================================*/
46
47/*============================================================================
48 * Type definitions
49 *============================================================================*/
50
51/* Structures for reduction
52 ------------------------ */
53
54// real
55
56template<size_t stride>
57struct cs_float_n {
58 float r[stride];
59};
60
61template<size_t stride>
63 double r[stride];
64};
65
66// integer
67
68template<size_t stride>
69struct cs_int_n {
70 cs_lnum_t i[stride];
71};
72
73// various types
74
77 float r[1];
78};
79
82 float r[2];
83};
84
87 float r[2];
88};
89
91 double d[1];
92 float r[2];
93};
94
96 float r1[3];
97 float r2[3];
98};
99
100template<size_t stride>
102 double r[stride];
103};
104
105// Combined
106
107template<size_t stride>
109 double r[stride];
110 cs_lnum_t i[stride];
111};
112
113/* Reductions
114 ---------- */
115
116// Min (1 real), Max (1 real), Sum (2 reals)
117
120
122 identity(T &a) const {
123 a.r[0] = cs_math_infinite_r;
124 a.r[1] = -cs_math_infinite_r;
125 a.r[2] = 0.;
126 a.r[3] = 0.;
127 }
128
130 combine(volatile T &a, volatile const T &b) const {
131 a.r[0] = cs::min(a.r[0], b.r[0]);
132 a.r[1] = cs::max(a.r[1], b.r[1]);
133 a.r[2] += b.r[2];
134 a.r[3] += b.r[3];
135 }
136};
137
138// Sum (1 lnum) and Min (1 reals)
139
142
144 identity(T &a) const {
145 a.i[0] = 0;
146 a.r[0] = cs_math_infinite_r;
147 }
148
150 combine(volatile T &a, volatile const T &b) const {
151 a.i[0] += b.i[0];
152 a.r[0] = cs::min(a.r[0], b.r[0]);
153 }
154};
155
156// Max (1 cs_gnum_t)
157
159
161 identity(cs_gnum_t &a) const {
162 a = 0;
163 }
164
166 combine(volatile cs_gnum_t &a, volatile const cs_gnum_t &b) const {
167 a = cs::max(a, b);
168 }
169};
170
171// Max (1 real)
172
174
176 identity(cs_real_t &a) const {
177 a = -HUGE_VAL;
178 }
179
181 combine(volatile cs_real_t &a, volatile const cs_real_t &b) const {
182 a = cs::max(a, b);
183 }
184};
185
186// Min (3 reals) and Max (3 reals)
187
190
192 identity(T &a) const {
193 a.r1[0] = cs_math_infinite_r;
194 a.r1[1] = cs_math_infinite_r;
195 a.r1[2] = cs_math_infinite_r;
196
197 a.r2[0] = -cs_math_infinite_r;
198 a.r2[1] = -cs_math_infinite_r;
199 a.r2[2] = -cs_math_infinite_r;
200 }
201
203 combine(volatile T &a, volatile const T &b) const {
204 a.r1[0] = cs::min(a.r1[0], b.r1[0]);
205 a.r1[1] = cs::min(a.r1[1], b.r1[1]);
206 a.r1[2] = cs::min(a.r1[2], b.r1[2]);
207
208 a.r2[0] = cs::max(a.r2[0], b.r2[0]);
209 a.r2[1] = cs::max(a.r2[1], b.r2[1]);
210 a.r2[2] = cs::max(a.r2[2], b.r2[2]);
211 }
212};
213
214// n_sum for double
215
216template<size_t stride>
219
221 identity(T &a) const {
222 for (size_t i = 0; i < stride; i++)
223 a.r[i] = 0.;
224 }
225
227 combine(volatile T &a, volatile const T &b) const {
228 for (size_t i = 0; i < stride; i++)
229 a.r[i] += b.r[i];
230 }
231};
232
233// n_sum for integer
234
235template<size_t stride>
238
240 identity(T &a) const {
241 for (size_t i = 0; i < stride; i++)
242 a.i[i] = 0.;
243 }
244
246 combine(volatile T &a, volatile const T &b) const {
247 for (size_t i = 0; i < stride; i++)
248 a.i[i] += b.i[i];
249 }
250};
251
252// n_min_max
253
254template<size_t stride>
257
259 identity(T &a) const {
260 for (size_t i = 0; i < stride; i++) {
261 a.r[i] = HUGE_VAL;
262 a.r[stride + i] = -HUGE_VAL;
263 }
264 }
265
267 combine(volatile T &a, volatile const T &b) const {
268 for (size_t i = 0; i < stride; i++) {
269 a.r[i] = cs::min(a.r[i], b.r[i]);
270 a.r[stride + i] = cs::max(a.r[stride + i], b.r[stride + i]);
271 }
272 }
273};
274
275// n min_max_sum
276
277template<size_t stride>
280
282 identity(T &a) const {
283 for (size_t i = 0; i < stride; i++) {
284 a.r[i] = HUGE_VAL;
285 a.r[stride + i] = -HUGE_VAL;
286 a.r[2*stride + i] = 0.;
287 }
288 }
289
291 combine(volatile T &a, volatile const T &b) const {
292 for (size_t i = 0; i < stride; i++) {
293 a.r[i] = cs::min(a.r[i], b.r[i]);
294 a.r[stride + i] = cs::max(a.r[stride + i], b.r[stride + i]);
295 a.r[2*stride + i] += b.r[2*stride + i];
296 }
297 }
298};
299
300// Min (1 real), max (1 real) and sum (1 int)
301
304
306 identity(T &a) const {
307 a.r[0] = HUGE_VAL;
308 a.r[1] = -HUGE_VAL;
309 a.i[0] = 0;
310 }
311
313 combine(volatile T &a, volatile const T &b) const {
314 a.r[0] = cs::min(a.r[0], b.r[0]);
315 a.r[1] = cs::max(a.r[1], b.r[1]);
316 a.i[0] += b.i[0];
317 }
318};
319
320// Min (1 real), max (1 real) and sum (2 int)
321
324
326 identity(T &a) const {
327 a.r[0] = cs_math_infinite_r;
328 a.r[1] = -cs_math_infinite_r;
329 a.i[0] = 0;
330 a.i[1] = 0;
331 }
332
334 combine(volatile T &a, volatile const T &b) const {
335 a.r[0] = cs::min(a.r[0], b.r[0]);
336 a.r[1] = cs::max(a.r[1], b.r[1]);
337 a.i[0] += b.i[0];
338 a.i[1] += b.i[1];
339 }
340};
341
342// Min, max (float) and sum (double)
343
346
348 identity(T &a) const {
349 a.d[0] = 0.0;
350
351 a.r[0] = cs_math_infinite_r;
352 a.r[1] = -cs_math_infinite_r;
353 }
354
356 combine(volatile T &a, volatile const T &b) const {
357 a.d[0] += b.d[0];
358
359 a.r[0] = cs::min(a.r[0], b.r[0]);
360 a.r[1] = cs::max(a.r[1], b.r[1]);
361 }
362};
363
364template<size_t stride>
366 using T = cs_double_n<3*(stride + 1)>;
367
369 identity(T &a) const {
370 const size_t _stride = stride + 1;
371 for (size_t i = 0; i < _stride; i++) {
372 a.r[i] = HUGE_VAL;
373 a.r[_stride + i] = -HUGE_VAL;
374 a.r[2*_stride + i] = 0.;
375 }
376 }
377
379 combine(volatile T &a, volatile const T &b) const {
380
381 const size_t _stride = stride + 1;
382
383 for (size_t i = 0; i < stride; i++) {
384 a.r[i] = cs::min(a.r[i], b.r[i]);
385 a.r[_stride + i] = cs::max(a.r[_stride + i], b.r[_stride + i]);
386 a.r[2*_stride + i] += b.r[2*_stride + i];
387 }
388 a.r[_stride - 1] = cs::min(a.r[_stride - 1], b.r[_stride - 1]);
389 a.r[2*_stride - 1] = cs::max(a.r[2*_stride - 1], b.r[2*_stride - 1]);
390 a.r[3*_stride - 1] += b.r[3*_stride - 1];
391 }
392};
393
394template<size_t stride>
397
399 identity(T &a) const {
400 for (size_t i = 0; i < stride; i++) {
401 a.r[i] = HUGE_VAL;
402 a.r[stride + i] = -HUGE_VAL;
403 a.r[2*stride + i] = 0.;
404 a.r[3*stride + i] = 0.;
405 }
406 }
407
409 combine(volatile T &a, volatile const T &b) const {
410 for (size_t i = 0; i < stride; i++) {
411 a.r[i] = cs::min(a.r[i], b.r[i]);
412 a.r[stride + i] = cs::max(a.r[stride + i], b.r[stride + i]);
413 a.r[2*stride + i] += b.r[2*stride + i];
414 a.r[3*stride + i] += b.r[3*stride + i];
415
416 }
417 }
418};
419
420template<size_t stride>
422 using T = cs_double_n<4*(stride + 1)>;
423
425 identity(T &a) const {
426 const size_t _stride = stride + 1;
427 for (size_t i = 0; i < _stride; i++) {
428 a.r[i] = HUGE_VAL;
429 a.r[_stride + i] = -HUGE_VAL;
430 a.r[2*_stride + i] = 0.;
431 a.r[3*_stride + i] = 0.;
432 }
433 }
434
436 combine(volatile T &a, volatile const T &b) const {
437
438 const size_t _stride = stride + 1;
439 for (size_t i = 0; i < stride; i++) {
440 a.r[i] = cs::min(a.r[i], b.r[i]);
441 a.r[_stride + i] = cs::max(a.r[_stride + i], b.r[_stride + i]);
442 a.r[2*_stride + i] += b.r[2*_stride + i];
443 a.r[3*_stride + i] += b.r[3*_stride + i];
444 }
445 a.r[_stride - 1] = cs::min(a.r[_stride - 1], b.r[_stride - 1]);
446 a.r[2*_stride - 1] = cs::max(a.r[2*_stride - 1], b.r[2*_stride - 1]);
447 a.r[3*_stride - 1] += b.r[3*_stride - 1];
448 a.r[4*_stride - 1] += b.r[4*_stride - 1];
449 }
450};
451
454
456 identity(T &a) const {
457 a.r[3] = -cs_math_infinite_r;
458
459 a.r[0] = 0.;
460 a.r[1] = 0.;
461 a.r[2] = 0.;
462 }
463
465 combine(volatile T &a, volatile const T &b) const {
466 if (a.r[3] < b.r[3]) {
467 a.r[3] = b.r[3]; // a=max(a,b)
468
469 a.r[0] = b.r[0];
470 a.r[1] = b.r[1];
471 a.r[2] = b.r[2];
472 }
473 }
474};
475
476// Strided min/max;
477// The first half of the structure is used for min,
478// the second for max.
479// Only the first half needs to be set by the user, as combine
480// handles the rest.
481
482template<size_t stride>
485
487 identity(T &a) const {
488 for (size_t i = 0; i < stride; i++) {
489 a.r[i] = HUGE_VAL;
490 a.r[stride + i] = -HUGE_VAL;
491 }
492 }
493
495 combine(volatile T &a, volatile const T &b) const {
496 for (size_t i = 0; i < stride; i++) {
497 // Do not use stride for b, as only the first half needs to be set.
498 a.r[i] = cs::min(a.r[i], b.r[i]);
499 a.r[stride+i] = cs::max(a.r[stride+i], b.r[stride+i]);
500 }
501 }
502};
503
504// Strided min:
505
506template<size_t stride>
509
511 identity(T &a) const {
512 for (size_t i = 0; i < stride; i++) {
513 a.r[i] = HUGE_VAL;
514 }
515 }
516
518 combine(volatile T &a, volatile const T &b) const {
519 for (size_t i = 0; i < stride; i++) {
520 a.r[i] = cs::min(a.r[i], b.r[i]);
521 }
522 }
523};
524
525// Strided max:
526
527template<size_t stride>
530
532 identity(T &a) const {
533 for (size_t i = 0; i < stride; i++) {
534 a.r[i] = -HUGE_VAL;
535 }
536 }
537
539 combine(volatile T &a, volatile const T &b) const {
540 for (size_t i = 0; i < stride; i++) {
541 a.r[i] = cs::max(a.r[i], b.r[i]);
542 }
543 }
544};
545
546// Strided min/max/loc;
547
548template<size_t stride>
551
553 identity(T &a) const {
554 for (size_t i = 0; i < stride; i++) {
555 a.r[i] = HUGE_VAL;
556 a.r[stride + i] = -HUGE_VAL;
557 a.i[i] = -1.;
558 a.i[stride + i] = -1.;
559 }
560 }
561
563 combine(volatile T &a, volatile const T &b) const {
564 for (size_t i = 0; i < stride; i++) {
565 if (a.r[i] > b.r[i]) {
566 a.r[i] = b.r[i];
567 a.i[i] = b.i[i];
568 }
569 if (a.r[stride + i] < b.r[stride + i]) {
570 a.r[stride + i] = b.r[stride + i];
571 a.i[stride + i] = b.i[stride + i];
572 }
573 }
574 }
575};
576
577// max (double) and sum (double, 2 lnums)
578
581
583 identity(T &a) const {
584 a.r[0] = -cs_math_infinite_r;
585 a.r[1] = -cs_math_infinite_r;
586 a.r[2] = 0.;
587 a.r[3] = 0.;
588 a.i[0] = 0;
589 a.i[1] = 0;
590 a.i[2] = 0;
591 a.i[3] = 0;
592 }
593
595 combine(volatile T &a, volatile const T &b) const {
596 a.r[0] = cs::max(a.r[0], b.r[0]);
597 a.r[1] = cs::max(a.r[1], b.r[1]);
598 a.r[2] += b.r[2];
599 a.r[3] += b.r[3];
600 a.i[0] += b.i[0];
601 a.i[1] += b.i[1];
602 a.i[2] += b.i[2];
603 a.i[3] += b.i[3];
604 }
605};
606
607/*============================================================================
608 * Templated function definitions
609 *============================================================================*/
610
611/*============================================================================
612 * Public function prototypes
613 *============================================================================*/
614
615/*----------------------------------------------------------------------------*/
616
617#endif /* CS_REDUCERS_H */
#define CS_F_HOST_DEVICE
Definition: cs_defs.h:555
double cs_real_t
Floating-point value.
Definition: cs_defs.h:332
unsigned cs_gnum_t
global mesh entity number
Definition: cs_defs.h:317
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:325
static constexpr cs_real_t cs_math_infinite_r
Definition: cs_math.h:105
CS_F_HOST_DEVICE T max(const T a, const T b)
Definition: cs_defs.h:735
CS_F_HOST_DEVICE T min(const T a, const T b)
Definition: cs_defs.h:712
#define HUGE_VAL
Definition: cs_reducers.h:90
double d[1]
Definition: cs_reducers.h:91
float r[2]
Definition: cs_reducers.h:92
Definition: cs_reducers.h:75
float r[1]
Definition: cs_reducers.h:77
cs_lnum_t i[1]
Definition: cs_reducers.h:76
Definition: cs_reducers.h:80
cs_lnum_t i[1]
Definition: cs_reducers.h:81
float r[2]
Definition: cs_reducers.h:82
Definition: cs_reducers.h:85
cs_lnum_t i[2]
Definition: cs_reducers.h:86
float r[2]
Definition: cs_reducers.h:87
Definition: cs_reducers.h:95
float r1[3]
Definition: cs_reducers.h:96
float r2[3]
Definition: cs_reducers.h:97
Definition: cs_reducers.h:108
double r[stride]
Definition: cs_reducers.h:109
cs_lnum_t i[stride]
Definition: cs_reducers.h:110
Definition: cs_reducers.h:101
double r[stride]
Definition: cs_reducers.h:102
Definition: cs_reducers.h:62
double r[stride]
Definition: cs_reducers.h:63
Definition: cs_reducers.h:57
float r[stride]
Definition: cs_reducers.h:58
Definition: cs_reducers.h:69
cs_lnum_t i[stride]
Definition: cs_reducers.h:70
Definition: cs_reducers.h:452
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:456
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:465
Definition: cs_reducers.h:173
CS_F_HOST_DEVICE void combine(volatile cs_real_t &a, volatile const cs_real_t &b) const
Definition: cs_reducers.h:181
CS_F_HOST_DEVICE void identity(cs_real_t &a) const
Definition: cs_reducers.h:176
Definition: cs_reducers.h:579
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:583
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:595
Definition: cs_reducers.h:158
CS_F_HOST_DEVICE void identity(cs_gnum_t &a) const
Definition: cs_reducers.h:161
CS_F_HOST_DEVICE void combine(volatile cs_gnum_t &a, volatile const cs_gnum_t &b) const
Definition: cs_reducers.h:166
Definition: cs_reducers.h:528
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:532
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:539
Definition: cs_reducers.h:302
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:306
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:313
Definition: cs_reducers.h:322
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:326
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:334
Definition: cs_reducers.h:118
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:122
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:130
Definition: cs_reducers.h:188
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:192
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:203
Definition: cs_reducers.h:255
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:259
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:267
Definition: cs_reducers.h:365
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:369
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:379
Definition: cs_reducers.h:278
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:282
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:291
Definition: cs_reducers.h:421
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:425
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:436
Definition: cs_reducers.h:395
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:399
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:409
Definition: cs_reducers.h:507
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:511
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:518
Definition: cs_reducers.h:483
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:487
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:495
Definition: cs_reducers.h:549
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:553
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:563
Definition: cs_reducers.h:344
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:348
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:356
Definition: cs_reducers.h:140
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:144
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:150
Definition: cs_reducers.h:236
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:240
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:246
Definition: cs_reducers.h:217
CS_F_HOST_DEVICE void identity(T &a) const
Definition: cs_reducers.h:221
CS_F_HOST_DEVICE void combine(volatile T &a, volatile const T &b) const
Definition: cs_reducers.h:227