9.2
general documentation
cs_parall.h
Go to the documentation of this file.
1#ifndef CS_PARALL_H
2#define CS_PARALL_H
3
4/*============================================================================
5 * Functions dealing with parallelism
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/*----------------------------------------------------------------------------
31 * Local headers
32 *----------------------------------------------------------------------------*/
33
34#include "base/cs_defs.h"
36
37/*----------------------------------------------------------------------------*/
38
40
41/*============================================================================
42 * General types and macros used throughout code_saturne
43 *============================================================================*/
44
45/*----------------------------------------------------------------------------
46 * Variable value type.
47 *----------------------------------------------------------------------------*/
48
52typedef enum {
53
59
60/*============================================================================
61 * Global variables
62 *============================================================================*/
63
64/* Preferred indexed sum option, adapted to shared-memory parallelism */
65
67
68/*=============================================================================
69 * Public function prototypes
70 *============================================================================*/
71
72/*----------------------------------------------------------------------------*/
79/*----------------------------------------------------------------------------*/
80
81inline static void
83 const int n)
84{
85#if defined(HAVE_MPI)
86
87 if (cs_glob_n_ranks > 1) {
88 MPI_Allreduce(MPI_IN_PLACE, cpt, n, CS_MPI_GNUM, MPI_SUM,
90 }
91
92#else
93
94 CS_UNUSED(cpt);
95 CS_UNUSED(n);
96
97#endif
98}
99
100/*----------------------------------------------------------------------------*/
107/*----------------------------------------------------------------------------*/
108
109inline static void
111 const int n)
112{
113#if defined(HAVE_MPI)
114
115 if (cs_glob_n_ranks > 1) {
116 MPI_Allreduce(MPI_IN_PLACE, cpt, n, CS_MPI_LNUM, MPI_MAX,
118 }
119
120#else
121
122 CS_UNUSED(cpt);
123 CS_UNUSED(n);
124
125#endif
126}
127
128/*----------------------------------------------------------------------------*/
136/*----------------------------------------------------------------------------*/
137
138inline static void
140 cs_datatype_t datatype,
141 void *val)
142{
143#if defined(HAVE_MPI)
144
145 if (cs_glob_n_ranks > 1) {
146 MPI_Allreduce(MPI_IN_PLACE, val, n, cs_datatype_to_mpi[datatype], MPI_SUM,
148 }
149
150#else
151
152 CS_UNUSED(n);
153 CS_UNUSED(datatype);
154 CS_UNUSED(val);
155
156#endif
157}
158
159/*----------------------------------------------------------------------------*/
168/*----------------------------------------------------------------------------*/
169
170inline static void
172 cs_datatype_t datatype,
173 void *val)
174{
175#if defined(HAVE_MPI)
176
177 if (cs_glob_n_ranks > 1) {
178 MPI_Allreduce(MPI_IN_PLACE, val, n, cs_datatype_to_mpi[datatype], MPI_MAX,
180 }
181
182#else
183
184 CS_UNUSED(n);
185 CS_UNUSED(datatype);
186 CS_UNUSED(val);
187
188#endif
189}
190
191/*----------------------------------------------------------------------------*/
200/*----------------------------------------------------------------------------*/
201
202inline static void
204 cs_datatype_t datatype,
205 void *val)
206{
207#if defined(HAVE_MPI)
208
209 if (cs_glob_n_ranks > 1) {
210 MPI_Allreduce(MPI_IN_PLACE, val, n, cs_datatype_to_mpi[datatype], MPI_MIN,
212 }
213
214#else
215
216 CS_UNUSED(n);
217 CS_UNUSED(datatype);
218 CS_UNUSED(val);
219
220#endif
221}
222
223/*----------------------------------------------------------------------------*/
234/*----------------------------------------------------------------------------*/
235
236inline static void
237cs_parall_bcast(int root_rank,
238 int n,
239 cs_datatype_t datatype,
240 void *val)
241{
242#if defined(HAVE_MPI)
243
244 if (cs_glob_n_ranks > 1)
245 MPI_Bcast(val, n, cs_datatype_to_mpi[datatype], root_rank,
247
248#else
249
250 CS_UNUSED(root_rank);
251 CS_UNUSED(n);
252 CS_UNUSED(datatype);
253 CS_UNUSED(val);
254
255#endif
256}
257
258/*----------------------------------------------------------------------------*/
274/*----------------------------------------------------------------------------*/
275
276void
277cs_parall_allgather_r(int n_elts,
278 int n_g_elts,
279 cs_real_t array[],
280 cs_real_t g_array[]);
281
282/*----------------------------------------------------------------------------*/
302/*----------------------------------------------------------------------------*/
303
304void
306 int n_g_elts,
307 int stride,
308 cs_real_t o_key[],
309 cs_real_t array[],
310 cs_real_t g_array[]);
311
312/*----------------------------------------------------------------------------*/
330/*----------------------------------------------------------------------------*/
331
332void
333cs_parall_gather_r(int root_rank,
334 int n_elts,
335 int n_g_elts,
336 const cs_real_t array[],
337 cs_real_t g_array[]);
338
339/*----------------------------------------------------------------------------*/
361/*----------------------------------------------------------------------------*/
362
363void
364cs_parall_gather_ordered_r(int root_rank,
365 int n_elts,
366 int n_g_elts,
367 int stride,
368 cs_real_t o_key[],
369 cs_real_t array[],
370 cs_real_t g_array[]);
371
372/*----------------------------------------------------------------------------*/
390/*----------------------------------------------------------------------------*/
391
392void
393cs_parall_scatter_r(int root_rank,
394 int n_elts,
395 int n_g_elts,
396 const cs_real_t g_array[],
397 cs_real_t array[]);
398
399/*----------------------------------------------------------------------------*/
418/*----------------------------------------------------------------------------*/
419
420void
421cs_parall_gather_f(int root_rank,
422 int n_elts,
423 int n_g_elts,
424 const float array[],
425 float g_array[]);
426
427/*----------------------------------------------------------------------------*/
446/*----------------------------------------------------------------------------*/
447
448void
449cs_parall_scatter_f(int root_rank,
450 int n_elts,
451 int n_g_elts,
452 const float g_array[],
453 float array[]);
454
455/*----------------------------------------------------------------------------*/
465/*----------------------------------------------------------------------------*/
466
467void
469 cs_real_t *max,
470 cs_real_t max_loc_vals[]);
471
472/*----------------------------------------------------------------------------*/
482/*----------------------------------------------------------------------------*/
483
484void
486 cs_real_t *min,
487 cs_real_t min_loc_vals[]);
488
489/*----------------------------------------------------------------------------*/
500/*----------------------------------------------------------------------------*/
501
502void
504 int *rank_id,
505 cs_real_t val);
506
507/*----------------------------------------------------------------------------*/
516/*----------------------------------------------------------------------------*/
517
518size_t
520
521/*----------------------------------------------------------------------------*/
531/*----------------------------------------------------------------------------*/
532
533void
534cs_parall_set_min_coll_buf_size(size_t buffer_size);
535
536/*----------------------------------------------------------------------------*/
546/*----------------------------------------------------------------------------*/
547
548inline static int
550 cs_lnum_t min_thread_elements)
551{
552#if defined(HAVE_OPENMP)
553 int n_t = omp_get_max_threads();
554 int n_t_l = n_elements / min_thread_elements;
555 if (n_t_l < n_t)
556 n_t = n_t_l;
557 if (n_t < 1)
558 n_t = 1;
559 return n_t;
560#else
561 CS_UNUSED(n_elements); /* avoid compiler warning */
562 CS_UNUSED(min_thread_elements);
563 return 1;
564#endif
565}
566
567/*----------------------------------------------------------------------------*/
580/*----------------------------------------------------------------------------*/
581
582inline static void
584 size_t type_size,
585 cs_lnum_t *s_id,
586 cs_lnum_t *e_id)
587{
588#if defined(HAVE_OPENMP)
589 const int t_id = omp_get_thread_num();
590 const int n_t = omp_get_num_threads();
591 const cs_lnum_t t_n = (n + n_t - 1) / n_t;
592 const cs_lnum_t cl_m = CS_CL_SIZE / type_size; /* Cache line multiple */
593
594 *s_id = t_id * t_n;
595 *e_id = (t_id+1) * t_n;
596 *s_id = cs_align(*s_id, cl_m);
597 *e_id = cs_align(*e_id, cl_m);
598 if (*e_id > n) *e_id = n;
599#else
600 CS_UNUSED(type_size); /* avoid compiler warning */
601 *s_id = 0;
602 *e_id = n;
603#endif
604}
605
606/*----------------------------------------------------------------------------*/
625/*----------------------------------------------------------------------------*/
626
627inline static void
629 size_t type_size,
630 cs_lnum_t *s_id,
631 cs_lnum_t *e_id)
632{
633#if defined(HAVE_OPENMP)
634 const int t_id = omp_get_thread_num();
635 const double n_t = omp_get_num_threads();
636 const cs_lnum_t cl_m = CS_CL_SIZE / type_size; /* Cache line multiple */
637
638 double r0 = (double)t_id / (double)n_t;
639 double r1 = (double)(t_id+1) / (double)n_t;
640
641 r0 = r0*r0;
642 r1 = r1*r1;
643
644 const cs_lnum_t t_0 = r0*n;
645 const cs_lnum_t t_1 = r1*n;
646
647 *s_id = t_0 * n;
648 *e_id = t_1 * n;
649 *s_id = cs_align(*s_id, cl_m);
650 *e_id = cs_align(*e_id, cl_m);
651 if (*e_id > n) *e_id = n;
652#else
653 CS_UNUSED(type_size); /* avoid compiler warning */
654 *s_id = 0;
655 *e_id = n;
656#endif
657}
658
659/*----------------------------------------------------------------------------*/
668/*----------------------------------------------------------------------------*/
669
670static inline size_t
672 size_t block_size)
673{
674 return (n % block_size) ? n/block_size + 1 : n/block_size;
675}
676
677/*----------------------------------------------------------------------------*/
678
680
681#if defined(__cplusplus)
682
683/*=============================================================================
684 * Public C++ functions
685 *============================================================================*/
686
687/*----------------------------------------------------------------------------*/
695/*----------------------------------------------------------------------------*/
696
697inline static void
699(
700 [[maybe_unused]] const cs_mpi_wrapper& mpi_w,
701 [[maybe_unused]] cs_gnum_t cpt[],
702 [[maybe_unused]] const int n)
703{
704#if defined(HAVE_MPI)
705
706 if (mpi_w.active()) {
707 MPI_Allreduce(MPI_IN_PLACE, cpt, n, CS_MPI_GNUM, MPI_SUM,
708 mpi_w.comm());
709 }
710
711#endif
712}
713
714/*----------------------------------------------------------------------------*/
722/*----------------------------------------------------------------------------*/
723
724inline static void
726(
727 [[maybe_unused]] const cs_mpi_wrapper& mpi_w,
728 [[maybe_unused]] cs_lnum_t cpt[],
729 [[maybe_unused]] const int n
730)
731{
732#if defined(HAVE_MPI)
733
734 if (mpi_w.active()) {
735 MPI_Allreduce(MPI_IN_PLACE, cpt, n, CS_MPI_LNUM, MPI_MAX,
736 mpi_w.comm());
737 }
738
739#endif
740}
741
742/*----------------------------------------------------------------------------*/
751/*----------------------------------------------------------------------------*/
752
753inline static void
755(
756 [[maybe_unused]] const cs_mpi_wrapper& mpi_w,
757 [[maybe_unused]] int n,
758 [[maybe_unused]] cs_datatype_t datatype,
759 [[maybe_unused]] void *val
760)
761{
762#if defined(HAVE_MPI)
763
764 if (mpi_w.active()) {
765 MPI_Allreduce(MPI_IN_PLACE, val, n,
766 cs_datatype_to_mpi[datatype], MPI_SUM,
767 mpi_w.comm());
768 }
769
770#endif
771}
772
773/*----------------------------------------------------------------------------*/
783/*----------------------------------------------------------------------------*/
784
785inline static void
787(
788 [[maybe_unused]] const cs_mpi_wrapper& mpi_w,
789 [[maybe_unused]] int n,
790 [[maybe_unused]] cs_datatype_t datatype,
791 [[maybe_unused]] void *val
792)
793{
794#if defined(HAVE_MPI)
795
796 if (mpi_w.active()) {
797 MPI_Allreduce(MPI_IN_PLACE, val, n,
798 cs_datatype_to_mpi[datatype], MPI_MAX,
799 mpi_w.comm());
800 }
801
802#endif
803}
804
805/*----------------------------------------------------------------------------*/
815/*----------------------------------------------------------------------------*/
816
817inline static void
819(
820 [[maybe_unused]] const cs_mpi_wrapper& mpi_w,
821 [[maybe_unused]] int n,
822 [[maybe_unused]] cs_datatype_t datatype,
823 [[maybe_unused]] void *val
824)
825{
826#if defined(HAVE_MPI)
827
828 if (mpi_w.active()) {
829 MPI_Allreduce(MPI_IN_PLACE, val, n,
830 cs_datatype_to_mpi[datatype], MPI_MIN,
831 mpi_w.comm());
832 }
833
834#endif
835}
836
837/*----------------------------------------------------------------------------*/
852/*----------------------------------------------------------------------------*/
853
854inline static void
856 size_t type_size,
857 int t_id,
858 int n_t,
859 cs_lnum_t *s_id,
860 cs_lnum_t *e_id)
861{
862 const cs_lnum_t t_n = (n + n_t - 1) / n_t;
863 const cs_lnum_t cl_m = CS_CL_SIZE / type_size; /* Cache line multiple */
864
865 *s_id = t_id * t_n;
866 *e_id = (t_id+1) * t_n;
867 *s_id = cs_align(*s_id, cl_m);
868 *e_id = cs_align(*e_id, cl_m);
869 if (*s_id > n) *s_id = n;
870 if (*e_id > n) *e_id = n;
871}
872
873/*=============================================================================
874 * Public C++ templates
875 *============================================================================*/
876
877namespace cs {
878namespace parall {
879
880/*----------------------------------------------------------------------------*/
886/*----------------------------------------------------------------------------*/
887
888template <typename T,
889 typename... Vals,
890 typename std::enable_if<!std::is_array<T>::value, int>::type = 0>
891static void
893(
894 const cs_mpi_wrapper& mpi_w,
895 T& first,
896 Vals&... values
897)
898{
899#if defined(HAVE_MPI)
900 /* If no parallel ranks exit the function */
901 if (!mpi_w.active())
902 return;
903
904 /* Count number of values */
905 constexpr int n_vals = sizeof...(Vals);
906
907 /* Set datatype for global communication */
908 cs_datatype_t datatype = cs_datatype_from_type<T>();
909
910 /* Temporary work array and parallel sum */
911 if (n_vals == 0)
912 cs_parall_sum(mpi_w, 1, datatype, &first);
913 else {
914 /* Unpack values */
915 T *_values[] = {&values ...};
916
917 T w[n_vals + 1];
918 w[0] = first;
919 for (int i = 0; i < n_vals; i++)
920 w[i+1] = *(_values[i]);
921
922 cs_parall_sum(mpi_w, n_vals + 1, datatype, w);
923
924 first = w[0];
925 for (int i = 0; i < n_vals; i++)
926 *(_values[i]) = w[i+1];
927 }
928#else
929 return;
930#endif
931}
932
933/*----------------------------------------------------------------------------*/
939/*----------------------------------------------------------------------------*/
940
941template <typename T,
942 typename... Vals,
943 typename std::enable_if<!std::is_array<T>::value, int>::type = 0>
944static void
945sum(T &first,
946 Vals &...values
947)
948{
949#if defined(HAVE_MPI)
950 const auto& mpi_w = cs::execution::default_mpi();
951 sum<T>(mpi_w, first, values...);
952#else
953 return;
954#endif
955}
956
957/*----------------------------------------------------------------------------*/
964/*----------------------------------------------------------------------------*/
965
966template <int Stride, typename T, typename... Vals>
967static void
969(
970 const cs_mpi_wrapper& mpi_w,
971 T first[],
972 Vals&&... values
973)
974{
975#if defined(HAVE_MPI)
976
977 if (!mpi_w.active())
978 return;
979
980 /* Count number of values */
981 constexpr int n_vals = sizeof...(Vals);
982
983 /* Set datatype for global communication */
984 cs_datatype_t datatype = cs_datatype_from_type<T>();
985
986 /* Temporary work array and parallel sum */
987 if (n_vals == 0)
988 cs_parall_sum(mpi_w, Stride, datatype, first);
989 else {
990 /* Unpack values */
991 T *_values[] = {values ...};
992
993 constexpr int work_size = (n_vals + 1) * Stride;
994
995 T w[work_size];
996 for (int i = 0; i < Stride; i++)
997 w[i] = first[i];
998
999 for (int i = 0; i < n_vals; i++) {
1000 for (int j = 0; j < Stride; j++)
1001 w[(i+1)*Stride + j] = _values[i][j];
1002 }
1003
1004 cs_parall_sum(mpi_w, work_size, datatype, w);
1005
1006 for (int i = 0; i < Stride; i++)
1007 first[i] = w[i];
1008
1009 for (int i = 0; i < n_vals; i++) {
1010 for (int j = 0; j < Stride; j++)
1011 _values[i][j] = w[(i+1)*Stride + j];
1012 }
1013 }
1014
1015#endif
1016}
1017
1018/*----------------------------------------------------------------------------*/
1026/*----------------------------------------------------------------------------*/
1027
1028template <int Stride, typename T, typename... Vals>
1029static void
1031(
1032 T first[],
1033 Vals&&... values
1034)
1035{
1036#if defined(HAVE_MPI)
1037 const auto& mpi_w = cs::execution::default_mpi();
1038 sum<Stride, T>(mpi_w, first, values...);
1039#else
1040 return;
1041#endif
1042}
1043
1044/*----------------------------------------------------------------------------*/
1053/*----------------------------------------------------------------------------*/
1054
1055template <typename T, int N, typename... Vals>
1056static void
1058(
1059 T (&first)[N],
1060 Vals &&...values
1061)
1062{
1063 // Appel à la version existante avec Stride = N
1064 sum<N>(first, std::forward<Vals>(values)...);
1065}
1066
1067/*----------------------------------------------------------------------------*/
1076/*----------------------------------------------------------------------------*/
1077
1078template <typename T, int N, typename... Vals>
1079static void
1081(
1082 const cs_mpi_wrapper& mpi_w,
1083 T (&first)[N],
1084 Vals &&... values
1085)
1086{
1087 sum<N>(mpi_w, first, std::forward<Vals>(values)...);
1088}
1089
1090/*----------------------------------------------------------------------------*/
1097/*----------------------------------------------------------------------------*/
1098
1099template <typename T, typename... Vals>
1100static void
1102(
1103 const cs_mpi_wrapper& mpi_w,
1104 T& first,
1105 Vals&... values
1106)
1107{
1108#if defined(HAVE_MPI)
1109
1110 /* Count number of values */
1111 constexpr int n_vals = sizeof...(Vals);
1112
1113 /* Set datatype for global communication */
1114 cs_datatype_t datatype = cs_datatype_from_type<T>();
1115
1116 /* Temporary work array and parallel sum */
1117 if (n_vals == 0)
1118 cs_parall_max(mpi_w, 1, datatype, &first);
1119 else {
1120
1121 /* Unpack values */
1122 T *_values[] = {&values ...};
1123
1124 T w[n_vals + 1];
1125 w[0] = first;
1126 for (int i = 0; i < n_vals; i++)
1127 w[i+1] = *(_values[i]);
1128
1129 cs_parall_max(mpi_w, n_vals + 1, datatype, w);
1130
1131 first = w[0];
1132 for (int i = 0; i < n_vals; i++)
1133 *(_values[i]) = w[i+1];
1134 }
1135
1136#endif // defined(HAVE_MPI)
1137}
1138
1139/*----------------------------------------------------------------------------*/
1146/*----------------------------------------------------------------------------*/
1147
1148template <typename T, typename... Vals>
1149static void
1151(
1152 T& first,
1153 Vals&... values
1154)
1155{
1156#if defined(HAVE_MPI)
1157 const auto& mpi_w = cs::execution::default_mpi();
1158 max(mpi_w, first, values...);
1159#else
1160 return;
1161#endif
1162}
1163
1164/*----------------------------------------------------------------------------*/
1172/*----------------------------------------------------------------------------*/
1173
1174template <int Stride, typename T, typename... Vals>
1175static void
1177(
1178 const cs_mpi_wrapper& mpi_w,
1179 T first[],
1180 Vals&&... values
1181)
1182{
1183#if defined(HAVE_MPI)
1184
1185 if (!mpi_w.active())
1186 return;
1187
1188 /* Count number of values */
1189 constexpr int n_vals = sizeof...(Vals);
1190
1191 /* Set datatype for global communication */
1192 cs_datatype_t datatype = cs_datatype_from_type<T>();
1193
1194 /* Temporary work array and parallel sum */
1195 if (n_vals == 0)
1196 cs_parall_max(mpi_w, Stride, datatype, first);
1197 else {
1198 /* Unpack values */
1199 T *_values[] = {values ...};
1200
1201 constexpr int work_size = (n_vals + 1) * Stride;
1202
1203 T w[work_size];
1204 for (int i = 0; i < Stride; i++)
1205 w[i] = first[i];
1206
1207 for (int i = 0; i < n_vals; i++)
1208 for (int j = 0; j < Stride; j++)
1209 w[(i+1)*Stride + j] = _values[i][j];
1210
1211 cs_parall_max(mpi_w, work_size, datatype, w);
1212
1213 for (int i = 0; i < Stride; i++)
1214 first[i] = w[i];
1215
1216 for (int i = 0; i < n_vals; i++)
1217 for (int j = 0; j < Stride; j++)
1218 _values[i][j] = w[(i+1)*Stride + j];
1219 }
1220
1221#endif // defined(HAVE_MPI)
1222}
1223
1224/*----------------------------------------------------------------------------*/
1231/*----------------------------------------------------------------------------*/
1232
1233template <int Stride, typename T, typename... Vals>
1234static void
1236(
1237 T first[],
1238 Vals&&... values
1239)
1240{
1241#if defined(HAVE_MPI)
1242 const auto& mpi_w = cs::execution::default_mpi();
1243 max<Stride>(mpi_w, first, values...);
1244#else
1245 return;
1246#endif
1247}
1248
1249/*----------------------------------------------------------------------------*/
1256/*----------------------------------------------------------------------------*/
1257
1258template <typename T, typename... Vals>
1259static void
1261(
1262 const cs_mpi_wrapper& mpi_w,
1263 T& first,
1264 Vals&... values
1265)
1266{
1267#if defined(HAVE_MPI)
1268
1269 if (!mpi_w.active())
1270 return;
1271
1272 /* Count number of values */
1273 constexpr int n_vals = sizeof...(Vals);
1274
1275 /* Set datatype for global communication */
1276 cs_datatype_t datatype = cs_datatype_from_type<T>();
1277
1278 if (n_vals == 0)
1279 cs_parall_min(mpi_w, 1, datatype, &first);
1280
1281 else {
1282 /* Temporary work array and parallel sum */
1283
1284 /* Unpack values */
1285 T *_values[] = {&values ...};
1286
1287 T w[n_vals + 1];
1288 w[0] = first;
1289 for (int i = 0; i < n_vals; i++)
1290 w[i + 1] = *(_values[i]);
1291
1292 cs_parall_min(mpi_w, n_vals + 1, datatype, w);
1293
1294 first = w[0];
1295 for (int i = 0; i < n_vals; i++)
1296 *(_values[i]) = w[i + 1];
1297 }
1298
1299#endif // defined(HAVE_MPI)
1300}
1301
1302/*----------------------------------------------------------------------------*/
1309/*----------------------------------------------------------------------------*/
1310
1311template <typename T, typename... Vals>
1312static void
1314(
1315 T& first,
1316 Vals&... values
1317)
1318{
1319#if defined(HAVE_MPI)
1320 const auto& mpi_w = cs::execution::default_mpi();
1321 min(mpi_w, first, values...);
1322#else
1323 return;
1324#endif
1325}
1326
1327/*----------------------------------------------------------------------------*/
1335/*----------------------------------------------------------------------------*/
1336
1337template <int Stride, typename T, typename... Vals>
1338static void
1340(
1341 const cs_mpi_wrapper& mpi_w,
1342 T first[],
1343 Vals&&... values
1344)
1345{
1346#if defined(HAVE_MPI)
1347
1348 if (!mpi_w.active())
1349 return;
1350
1351 /* Count number of values */
1352 constexpr int n_vals = sizeof...(Vals);
1353
1354 /* Set datatype for global communication */
1355 cs_datatype_t datatype = cs_datatype_from_type<T>();
1356
1357 /* Temporary work array and parallel sum */
1358 if (n_vals == 0)
1359 cs_parall_min(mpi_w, Stride, datatype, first);
1360 else {
1361 /* Unpack values */
1362 T *_values[] = {values ...};
1363
1364 constexpr int work_size = (n_vals + 1) * Stride;
1365
1366 T w[work_size];
1367 for (int i = 0; i < Stride; i++)
1368 w[i] = first[i];
1369
1370 for (int i = 0; i < n_vals; i++)
1371 for (int j = 0; j < Stride; j++)
1372 w[(i+1)*Stride + j] = _values[i][j];
1373
1374 cs_parall_min(mpi_w, work_size, datatype, w);
1375
1376 for (int i = 0; i < Stride; i++)
1377 first[i] = w[i];
1378
1379 for (int i = 0; i < n_vals; i++)
1380 for (int j = 0; j < Stride; j++)
1381 _values[i][j] = w[(i+1)*Stride + j];
1382 }
1383
1384#endif
1385}
1386
1387/*----------------------------------------------------------------------------*/
1395/*----------------------------------------------------------------------------*/
1396
1397template <int Stride, typename T, typename... Vals>
1398static void
1400(
1401 T first[],
1402 Vals&&... values
1403)
1404{
1405#if defined(HAVE_MPI)
1406 const auto& mpi_w = cs::execution::default_mpi();
1407 min<Stride>(mpi_w, first, values...);
1408#else
1409 return;
1410#endif
1411}
1412
1413} /* namespace parall */
1414} /* namespace cs */
1415
1416/*----------------------------------------------------------------------------*/
1422/*----------------------------------------------------------------------------*/
1423
1424template <typename T, typename... Vals>
1425static void
1427(
1428 T& first,
1429 Vals&... values
1430)
1431{
1432#if defined(HAVE_MPI)
1433
1434 if (cs_glob_n_ranks == 1)
1435 return;
1436
1437 /* Count number of values */
1438 constexpr size_t n_vals = sizeof...(Vals);
1439
1440 /* Set datatype for global communication */
1441 cs_datatype_t datatype = cs_datatype_from_type<T>();
1442
1443 /* Temporary work array and parallel sum */
1444 if (n_vals == 0)
1445 cs_parall_sum(1, datatype, &first);
1446 else {
1447 /* Unpack values */
1448 T *_values[] = {&values ...};
1449
1450 T w[n_vals + 1];
1451 w[0] = first;
1452 for (size_t i = 0; i < n_vals; i++)
1453 w[i+1] = *(_values[i]);
1454
1455 cs_parall_sum(n_vals + 1, datatype, w);
1456
1457 first = w[0];
1458 for (size_t i = 0; i < n_vals; i++)
1459 *(_values[i]) = w[i+1];
1460 }
1461
1462#endif // defined(HAVE_MPI)
1463}
1464
1465/*----------------------------------------------------------------------------*/
1471/*----------------------------------------------------------------------------*/
1472
1473template <typename T, typename... Vals>
1474static void
1476(
1477 const cs_mpi_wrapper& mpi_w,
1478 T& first,
1479 Vals&... values
1480)
1481{
1482#if defined(HAVE_MPI)
1483
1484 /* Count number of values */
1485 constexpr size_t n_vals = sizeof...(Vals);
1486
1487 /* Set datatype for global communication */
1488 cs_datatype_t datatype = cs_datatype_from_type<T>();
1489
1490 /* Temporary work array and parallel sum */
1491 if (n_vals == 0)
1492 cs_parall_sum(mpi_w, 1, datatype, &first);
1493 else {
1494 /* Unpack values */
1495 T *_values[] = {&values ...};
1496
1497 T w[n_vals + 1];
1498 w[0] = first;
1499 for (size_t i = 0; i < n_vals; i++)
1500 w[i+1] = *(_values[i]);
1501
1502 cs_parall_sum(mpi_w, n_vals + 1, datatype, w);
1503
1504 first = w[0];
1505 for (size_t i = 0; i < n_vals; i++)
1506 *(_values[i]) = w[i+1];
1507 }
1508
1509#endif // defined(HAVE_MPI)
1510}
1511
1512/*----------------------------------------------------------------------------*/
1519/*----------------------------------------------------------------------------*/
1520
1521template <int Stride, typename T, typename... Vals>
1522static void
1524(
1525 const cs_mpi_wrapper& mpi_w,
1526 T first[],
1527 Vals&&... values
1528)
1529{
1530#if defined(HAVE_MPI)
1531 if (!mpi_w.active())
1532 return;
1533
1534 /* Count number of values */
1535 constexpr size_t n_vals = sizeof...(Vals);
1536
1537 /* Set datatype for global communication */
1538 cs_datatype_t datatype = cs_datatype_from_type<T>();
1539
1540 /* Temporary work array and parallel sum */
1541 if (n_vals == 0)
1542 cs_parall_sum(mpi_w, Stride, datatype, first);
1543 else {
1544 /* Unpack values */
1545 T *_values[] = {values ...};
1546
1547 constexpr size_t work_size = (n_vals + 1) * Stride;
1548
1549 T w[work_size];
1550 for (int i = 0; i < Stride; i++)
1551 w[i] = first[i];
1552
1553 for (size_t i = 0; i < n_vals; i++)
1554 for (int j = 0; j < Stride; j++)
1555 w[(i+1)*Stride + j] = _values[i][j];
1556
1557 cs_parall_sum(mpi_w, work_size, datatype, w);
1558
1559 for (int i = 0; i < Stride; i++)
1560 first[i] = w[i];
1561
1562 for (size_t i = 0; i < n_vals; i++) {
1563 for (int j = 0; j < Stride; j++)
1564 _values[i][j] = w[(i+1)*Stride + j];
1565 }
1566 }
1567
1568#endif // defined(HAVE_MPI)
1569}
1570
1571/*----------------------------------------------------------------------------*/
1579/*----------------------------------------------------------------------------*/
1580
1581template <int Stride, typename T, typename... Vals>
1582static void
1584(
1585 T first[],
1586 Vals&&... values
1587)
1588{
1589#if defined(HAVE_MPI)
1590
1591 if (cs_glob_n_ranks == 1)
1592 return;
1593
1594 /* Count number of values */
1595 constexpr size_t n_vals = sizeof...(Vals);
1596
1597 /* Set datatype for global communication */
1598 cs_datatype_t datatype = cs_datatype_from_type<T>();
1599
1600 /* Temporary work array and parallel sum */
1601 if (n_vals == 0)
1602 cs_parall_sum(Stride, datatype, first);
1603 else {
1604 /* Unpack values */
1605 T *_values[] = {values ...};
1606
1607 constexpr size_t work_size = (n_vals + 1) * Stride;
1608
1609 T w[work_size];
1610 for (int i = 0; i < Stride; i++)
1611 w[i] = first[i];
1612
1613 for (int i = 0; i < n_vals; i++) {
1614 for (int j = 0; j < Stride; j++)
1615 w[(i+1)*Stride + j] = _values[i][j];
1616 }
1617
1618 cs_parall_sum(work_size, datatype, w);
1619
1620 for (int i = 0; i < Stride; i++)
1621 first[i] = w[i];
1622
1623 for (size_t i = 0; i < n_vals; i++) {
1624 for (int j = 0; j < Stride; j++)
1625 _values[i][j] = w[(i+1)*Stride + j];
1626 }
1627 }
1628
1629#endif // defined(HAVE_MPI)
1630}
1631
1632/*----------------------------------------------------------------------------*/
1639/*----------------------------------------------------------------------------*/
1640
1641template <typename T, typename... Vals>
1642static void
1644(
1645 T& first,
1646 Vals&... values
1647)
1648{
1649#if defined(HAVE_MPI)
1650
1651 if (cs_glob_n_ranks == 1)
1652 return;
1653
1654 /* Count number of values */
1655 constexpr size_t n_vals = sizeof...(Vals);
1656
1657 /* Set datatype for global communication */
1658 cs_datatype_t datatype = cs_datatype_from_type<T>();
1659
1660 /* Temporary work array and parallel sum */
1661 if (n_vals == 0)
1662 cs_parall_max(1, datatype, &first);
1663 else {
1664
1665 /* Unpack values */
1666 T *_values[] = {&values ...};
1667
1668 T w[n_vals + 1];
1669 w[0] = first;
1670 for (size_t i = 0; i < n_vals; i++)
1671 w[i+1] = *(_values[i]);
1672
1673 cs_parall_max(n_vals + 1, datatype, w);
1674
1675 first = w[0];
1676 for (size_t i = 0; i < n_vals; i++)
1677 *(_values[i]) = w[i+1];
1678 }
1679
1680#endif // defined(HAVE_MPI)
1681}
1682
1683/*----------------------------------------------------------------------------*/
1689/*----------------------------------------------------------------------------*/
1690
1691template <typename T, typename... Vals>
1692static void
1694(
1695 const cs_mpi_wrapper& mpi_w,
1696 T& first,
1697 Vals&... values
1698)
1699{
1700#if defined(HAVE_MPI)
1701
1702 /* Count number of values */
1703 constexpr size_t n_vals = sizeof...(Vals);
1704
1705 /* Set datatype for global communication */
1706 cs_datatype_t datatype = cs_datatype_from_type<T>();
1707
1708 /* Temporary work array and parallel sum */
1709 if (n_vals == 0)
1710 cs_parall_max(mpi_w, 1, datatype, &first);
1711 else {
1712
1713 /* Unpack values */
1714 T *_values[] = {&values ...};
1715
1716 T w[n_vals + 1];
1717 w[0] = first;
1718 for (size_t i = 0; i < n_vals; i++)
1719 w[i+1] = *(_values[i]);
1720
1721 cs_parall_max(mpi_w, n_vals + 1, datatype, w);
1722
1723 first = w[0];
1724 for (size_t i = 0; i < n_vals; i++)
1725 *(_values[i]) = w[i+1];
1726 }
1727
1728#endif // defined(HAVE_MPI)
1729}
1730
1731/*----------------------------------------------------------------------------*/
1739/*----------------------------------------------------------------------------*/
1740
1741template <int Stride, typename T, typename... Vals>
1742static void
1744(
1745 T first[],
1746 Vals&&... values
1747)
1748{
1749#if defined(HAVE_MPI)
1750
1751 if (cs_glob_n_ranks == 1)
1752 return;
1753
1754 /* Count number of values */
1755 constexpr size_t n_vals = sizeof...(Vals);
1756
1757 /* Set datatype for global communication */
1758 cs_datatype_t datatype = cs_datatype_from_type<T>();
1759
1760 /* Temporary work array and parallel sum */
1761 if (n_vals == 0)
1762 cs_parall_max(Stride, datatype, first);
1763 else {
1764 /* Unpack values */
1765 T *_values[] = {values ...};
1766
1767 constexpr size_t work_size = (n_vals + 1) * Stride;
1768
1769 T w[work_size];
1770 for (int i = 0; i < Stride; i++)
1771 w[i] = first[i];
1772
1773 for (size_t i = 0; i < n_vals; i++)
1774 for (int j = 0; j < Stride; j++)
1775 w[(i+1)*Stride + j] = _values[i][j];
1776
1777 cs_parall_max(work_size, datatype, w);
1778
1779 for (int i = 0; i < Stride; i++)
1780 first[i] = w[i];
1781
1782 for (size_t i = 0; i < n_vals; i++)
1783 for (int j = 0; j < Stride; j++)
1784 _values[i][j] = w[(i+1)*Stride + j];
1785 }
1786
1787#endif // defined(HAVE_MPI)
1788}
1789
1790/*----------------------------------------------------------------------------*/
1797/*----------------------------------------------------------------------------*/
1798
1799template <int Stride, typename T, typename... Vals>
1800static void
1802(
1803 const cs_mpi_wrapper& mpi_w,
1804 T first[],
1805 Vals&&... values
1806)
1807{
1808#if defined(HAVE_MPI)
1809
1810 /* Count number of values */
1811 constexpr size_t n_vals = sizeof...(Vals);
1812
1813 /* Set datatype for global communication */
1814 cs_datatype_t datatype = cs_datatype_from_type<T>();
1815
1816 /* Temporary work array and parallel sum */
1817 if (n_vals == 0)
1818 cs_parall_max(mpi_w, Stride, datatype, first);
1819 else {
1820 /* Unpack values */
1821 T *_values[] = {values ...};
1822
1823 constexpr size_t work_size = (n_vals + 1) * Stride;
1824
1825 T w[work_size];
1826 for (int i = 0; i < Stride; i++)
1827 w[i] = first[i];
1828
1829 for (size_t i = 0; i < n_vals; i++)
1830 for (int j = 0; j < Stride; j++)
1831 w[(i+1)*Stride + j] = _values[i][j];
1832
1833 cs_parall_max(mpi_w, work_size, datatype, w);
1834
1835 for (int i = 0; i < Stride; i++)
1836 first[i] = w[i];
1837
1838 for (size_t i = 0; i < n_vals; i++)
1839 for (int j = 0; j < Stride; j++)
1840 _values[i][j] = w[(i+1)*Stride + j];
1841 }
1842
1843#endif // defined(HAVE_MPI)
1844}
1845
1846/*----------------------------------------------------------------------------*/
1853/*----------------------------------------------------------------------------*/
1854
1855template <typename T, typename... Vals>
1856static void
1858(
1859 T& first,
1860 Vals&... values
1861)
1862{
1863#if defined(HAVE_MPI)
1864
1865 if (cs_glob_n_ranks == 1)
1866 return;
1867
1868 /* Count number of values */
1869 constexpr size_t n_vals = sizeof...(Vals);
1870
1871 /* Set datatype for global communication */
1872 cs_datatype_t datatype = cs_datatype_from_type<T>();
1873
1874 if (n_vals == 0)
1875 cs_parall_min(1, datatype, &first);
1876
1877 else {
1878 /* Temporary work array and parallel sum */
1879
1880 /* Unpack values */
1881 T *_values[] = {&values ...};
1882
1883 T w[n_vals + 1];
1884 w[0] = first;
1885 for (size_t i = 0; i < n_vals; i++)
1886 w[i + 1] = *(_values[i]);
1887
1888 cs_parall_min(n_vals + 1, datatype, w);
1889
1890 first = w[0];
1891 for (size_t i = 0; i < n_vals; i++)
1892 *(_values[i]) = w[i + 1];
1893 }
1894
1895#endif // defined(HAVE_MPI)
1896}
1897
1898/*----------------------------------------------------------------------------*/
1904/*----------------------------------------------------------------------------*/
1905
1906template <typename T, typename... Vals>
1907static void
1909(
1910 const cs_mpi_wrapper& mpi_w,
1911 T& first,
1912 Vals&... values
1913)
1914{
1915#if defined(HAVE_MPI)
1916
1917 /* Count number of values */
1918 constexpr size_t n_vals = sizeof...(Vals);
1919
1920 /* Set datatype for global communication */
1921 cs_datatype_t datatype = cs_datatype_from_type<T>();
1922
1923 if (n_vals == 0)
1924 cs_parall_min(mpi_w, 1, datatype, &first);
1925
1926 else {
1927 /* Temporary work array and parallel sum */
1928
1929 /* Unpack values */
1930 T *_values[] = {&values ...};
1931
1932 T w[n_vals + 1];
1933 w[0] = first;
1934 for (size_t i = 0; i < n_vals; i++)
1935 w[i + 1] = *(_values[i]);
1936
1937 cs_parall_min(mpi_w, n_vals + 1, datatype, w);
1938
1939 first = w[0];
1940 for (size_t i = 0; i < n_vals; i++)
1941 *(_values[i]) = w[i + 1];
1942 }
1943
1944#endif // defined(HAVE_MPI)
1945}
1946
1947/*----------------------------------------------------------------------------*/
1955/*----------------------------------------------------------------------------*/
1956
1957template <int Stride, typename T, typename... Vals>
1958static void
1960(
1961 T first[],
1962 Vals&&... values
1963)
1964{
1965#if defined(HAVE_MPI)
1966
1967 if (cs_glob_n_ranks == 1)
1968 return;
1969
1970 /* Count number of values */
1971 constexpr size_t n_vals = sizeof...(Vals);
1972
1973 /* Set datatype for global communication */
1974 cs_datatype_t datatype = cs_datatype_from_type<T>();
1975
1976 /* Temporary work array and parallel sum */
1977 if (n_vals == 0)
1978 cs_parall_min(Stride, datatype, first);
1979 else {
1980 /* Unpack values */
1981 T *_values[] = {values ...};
1982
1983 constexpr size_t work_size = (n_vals + 1) * Stride;
1984
1985 T w[work_size];
1986 for (int i = 0; i < Stride; i++)
1987 w[i] = first[i];
1988
1989 for (size_t i = 0; i < n_vals; i++)
1990 for (int j = 0; j < Stride; j++)
1991 w[(i+1)*Stride + j] = _values[i][j];
1992
1993 cs_parall_min(work_size, datatype, w);
1994
1995 for (int i = 0; i < Stride; i++)
1996 first[i] = w[i];
1997
1998 for (size_t i = 0; i < n_vals; i++)
1999 for (int j = 0; j < Stride; j++)
2000 _values[i][j] = w[(i+1)*Stride + j];
2001 }
2002
2003#endif
2004}
2005
2006/*----------------------------------------------------------------------------*/
2013/*----------------------------------------------------------------------------*/
2014
2015template <int Stride, typename T, typename... Vals>
2016static void
2018(
2019 const cs_mpi_wrapper& mpi_w,
2020 T first[],
2021 Vals&&... values
2022)
2023{
2024#if defined(HAVE_MPI)
2025
2026 /* Count number of values */
2027 constexpr size_t n_vals = sizeof...(Vals);
2028
2029 /* Set datatype for global communication */
2030 cs_datatype_t datatype = cs_datatype_from_type<T>();
2031
2032 /* Temporary work array and parallel sum */
2033 if (n_vals == 0)
2034 cs_parall_min(mpi_w, Stride, datatype, first);
2035
2036 else {
2037 /* Unpack values */
2038 T *_values[] = {values ...};
2039
2040 constexpr size_t work_size = (n_vals + 1) * Stride;
2041
2042 T w[work_size];
2043 for (int i = 0; i < Stride; i++)
2044 w[i] = first[i];
2045
2046 for (size_t i = 0; i < n_vals; i++)
2047 for (int j = 0; j < Stride; j++)
2048 w[(i+1)*Stride + j] = _values[i][j];
2049
2050 cs_parall_min(mpi_w, work_size, datatype, w);
2051
2052 for (int i = 0; i < Stride; i++)
2053 first[i] = w[i];
2054
2055 for (size_t i = 0; i < n_vals; i++)
2056 for (int j = 0; j < Stride; j++)
2057 _values[i][j] = w[(i+1)*Stride + j];
2058 }
2059#endif // defined(HAVE_MPI)
2060}
2061
2062#endif //__cplusplus
2063
2064/*----------------------------------------------------------------------------*/
2065
2066#endif /* CS_PARALL_H */
Definition: cs_execution_context.h:46
CS_F_HOST_DEVICE bool active() const
Definition: cs_execution_context.h:77
int cs_glob_n_ranks
Definition: cs_defs.cpp:171
MPI_Datatype cs_datatype_to_mpi[]
Definition: cs_defs.cpp:153
MPI_Comm cs_glob_mpi_comm
Definition: cs_defs.cpp:179
cs_datatype_t
Definition: cs_defs.h:290
#define BEGIN_C_DECLS
Definition: cs_defs.h:528
double cs_real_t
Floating-point value.
Definition: cs_defs.h:332
#define CS_MPI_LNUM
Definition: cs_defs.h:428
#define CS_MPI_GNUM
Definition: cs_defs.h:420
unsigned cs_gnum_t
global mesh entity number
Definition: cs_defs.h:317
static cs_lnum_t cs_align(cs_lnum_t i, cs_lnum_t m)
Given a base index i, return the next index aligned with a size m.
Definition: cs_defs.h:639
#define CS_UNUSED(x)
Definition: cs_defs.h:518
#define END_C_DECLS
Definition: cs_defs.h:529
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:325
#define CS_CL_SIZE
Definition: cs_defs.h:488
void cs_parall_gather_r(int root_rank, int n_elts, int n_g_elts, const cs_real_t array[], cs_real_t g_array[])
Build a global array on the given root rank from all local arrays.
Definition: cs_parall.cpp:527
static void cs_parall_bcast(int root_rank, int n, cs_datatype_t datatype, void *val)
Broadcast values of a given datatype to all default communicator processes.
Definition: cs_parall.h:237
static void cs_parall_min_strided(T first[], Vals &&... values)
Minimum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1960
void cs_parall_set_min_coll_buf_size(size_t buffer_size)
Define minimum recommended scatter or gather buffer size.
Definition: cs_parall.cpp:850
void cs_parall_gather_ordered_r(int root_rank, int n_elts, int n_g_elts, int stride, cs_real_t o_key[], cs_real_t array[], cs_real_t g_array[])
Build an ordered global array on the given root rank from all local arrays.
Definition: cs_parall.cpp:594
void cs_parall_min_id_rank_r(cs_lnum_t *elt_id, int *rank_id, cs_real_t val)
Given an (id, rank, value) tuple, return the local id and rank corresponding to the global minimum va...
Definition: cs_parall.cpp:352
static void cs_parall_thread_range_upper(cs_lnum_t n, size_t type_size, cs_lnum_t *s_id, cs_lnum_t *e_id)
Compute array index bounds for a local thread for upper triangular matrix elements.
Definition: cs_parall.h:628
static void cs_parall_max(int n, cs_datatype_t datatype, void *val)
Maximum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:171
static void cs_parall_counter_max(cs_lnum_t cpt[], const int n)
Maximum values of a counter on all default communicator processes.
Definition: cs_parall.h:110
void cs_parall_allgather_r(int n_elts, int n_g_elts, cs_real_t array[], cs_real_t g_array[])
Build a global array from each local array in each domain.
Definition: cs_parall.cpp:406
static int cs_parall_n_threads(cs_lnum_t n_elements, cs_lnum_t min_thread_elements)
Compute recommended number of threads for a section.
Definition: cs_parall.h:549
static void cs_parall_max_scalars(T &first, Vals &... values)
Maximum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1644
static void cs_parall_counter(cs_gnum_t cpt[], const int n)
Sum values of a counter on all default communicator processes.
Definition: cs_parall.h:82
void cs_parall_scatter_r(int root_rank, int n_elts, int n_g_elts, const cs_real_t g_array[], cs_real_t array[])
Distribute a global array from a given root rank over all ranks. Each rank receive the part related t...
Definition: cs_parall.cpp:643
static void cs_parall_sum(int n, cs_datatype_t datatype, void *val)
Sum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:139
void cs_parall_allgather_ordered_r(int n_elts, int n_g_elts, int stride, cs_real_t o_key[], cs_real_t array[], cs_real_t g_array[])
Build an ordered global array from each local array in each domain.
Definition: cs_parall.cpp:483
void cs_parall_scatter_f(int root_rank, int n_elts, int n_g_elts, const float g_array[], float array[])
Distribute a global array from a given root rank over all ranks. Each rank receive the part related t...
Definition: cs_parall.cpp:773
static void cs_parall_thread_range(cs_lnum_t n, size_t type_size, cs_lnum_t *s_id, cs_lnum_t *e_id)
Compute array index bounds for a local thread. When called inside an OpenMP parallel section,...
Definition: cs_parall.h:583
void cs_parall_min_loc_vals(int n, cs_real_t *min, cs_real_t min_loc_vals[])
Minimum value of a real and the value of related array on all default communicator processes.
Definition: cs_parall.cpp:313
static void cs_parall_sum_scalars(T &first, Vals &... values)
Sum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1427
static void cs_parall_min(int n, cs_datatype_t datatype, void *val)
Minimum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:203
void cs_parall_gather_f(int root_rank, int n_elts, int n_g_elts, const float array[], float g_array[])
Build a global array on the given root rank from all local arrays. Function dealing with single-preci...
Definition: cs_parall.cpp:708
void cs_parall_max_loc_vals(int n, cs_real_t *max, cs_real_t max_loc_vals[])
Maximum value of a real and the value of related array on all default communicator processes.
Definition: cs_parall.cpp:275
size_t cs_parall_get_min_coll_buf_size(void)
Return minimum recommended scatter or gather buffer size.
Definition: cs_parall.cpp:828
static size_t cs_parall_block_count(size_t n, size_t block_size)
Compute number of blocks needed for a given array and block sizes.
Definition: cs_parall.h:671
static void cs_parall_min_scalars(T &first, Vals &... values)
Minimum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1858
static void cs_parall_max_strided(T first[], Vals &&... values)
Maximum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1744
cs_e2n_sum_t
Definition: cs_parall.h:52
@ CS_E2N_SUM_SCATTER
Definition: cs_parall.h:54
@ CS_E2N_SUM_GATHER
Definition: cs_parall.h:56
static void cs_parall_sum_strided(const cs_mpi_wrapper &mpi_w, T first[], Vals &&... values)
Sum strided-values of a given datatype over a communicator.
Definition: cs_parall.h:1524
cs_e2n_sum_t cs_glob_e2n_sum_type
mpi_wrapper & default_mpi(void)
Definition: cs_execution_context.cpp:78
static void min(const cs_mpi_wrapper &mpi_w, T &first, Vals &... values)
Minimum values of a given datatype on a given communicator processes.
Definition: cs_parall.h:1261
static void sum(const cs_mpi_wrapper &mpi_w, T &first, Vals &... values)
Sum values of a given datatype over a given communicator.
Definition: cs_parall.h:893
static void max(T first[], Vals &&... values)
Maximum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1236
static void max(const cs_mpi_wrapper &mpi_w, T &first, Vals &... values)
Maximum values of a given datatype on a given communicator processes.
Definition: cs_parall.h:1102
static void min(T first[], Vals &&... values)
Minimum values of a given datatype on all default communicator processes.
Definition: cs_parall.h:1400
Definition: cs_algorithm.h:51
Definition: parall.f90:26