17#include "ioss_export.h"
19#include <fmt/format.h>
20#include <fmt/ostream.h>
28 class PropertyManager;
38#if defined(SEACAS_HAVE_MPI)
65 bool get_environment(
const std::string &name, std::string &value,
76 bool get_environment(
const std::string &name,
int &value,
88 IOSS_NODISCARD std::string decode_filename(
const std::string &filename,
bool is_parallel)
const;
112 void memory_stats(int64_t &min, int64_t &max, int64_t &avg)
const;
116 void hwm_memory_stats(int64_t &min, int64_t &max, int64_t &avg)
const;
126 template <
typename T>
130 template <
typename T>
134 template <
typename T>
void gather(T my_value, std::vector<T> &result)
const;
135 template <
typename T>
void all_gather(T my_value, std::vector<T> &result)
const;
136 template <
typename T>
void gather(std::vector<T> &my_values, std::vector<T> &result)
const;
137 template <
typename T>
void all_gather(std::vector<T> &my_values, std::vector<T> &result)
const;
138 template <
typename T>
139 int gather(
int vals_count,
int size_per_val, std::vector<T> &my_values,
140 std::vector<T> &result)
const;
142 template <
typename T>
void broadcast(T &my_value,
int root = 0)
const;
143 template <
typename T>
void broadcast(std::vector<T> &my_value,
int root = 0)
const;
145 void progress(
const std::string &output)
const;
149 mutable int parallelSize_{-1};
150 mutable int parallelRank_{-1};
153#ifdef SEACAS_HAVE_MPI
154 IOSS_NODISCARD inline MPI_Datatype mpi_type(
double ) {
return MPI_DOUBLE; }
155 IOSS_NODISCARD inline MPI_Datatype mpi_type(
float ) {
return MPI_FLOAT; }
156 IOSS_NODISCARD inline MPI_Datatype mpi_type(
int ) {
return MPI_INT; }
157 IOSS_NODISCARD inline MPI_Datatype mpi_type(
long int ) {
return MPI_LONG_LONG_INT; }
158 IOSS_NODISCARD inline MPI_Datatype mpi_type(
long long int ) {
return MPI_LONG_LONG_INT; }
159 IOSS_NODISCARD inline MPI_Datatype mpi_type(
unsigned int ) {
return MPI_UNSIGNED; }
162 return MPI_UNSIGNED_LONG;
164 IOSS_NODISCARD inline MPI_Datatype mpi_type(
unsigned long long int )
166 return MPI_UNSIGNED_LONG_LONG;
168 IOSS_NODISCARD inline MPI_Datatype mpi_type(
char ) {
return MPI_CHAR; }
170 template <
typename T>
171 int MY_Alltoallv64(
const std::vector<T> &sendbuf,
const std::vector<int64_t> &sendcounts,
172 const std::vector<int64_t> &senddisp, std::vector<T> &recvbuf,
173 const std::vector<int64_t> &recvcounts,
const std::vector<int64_t> &recvdisp,
176 int processor_count = 0;
177 int my_processor = 0;
178 MPI_Comm_size(comm, &processor_count);
179 MPI_Comm_rank(comm, &my_processor);
183 for (
int i = 0; i < processor_count; i++) {
184 int snd_cnt =
static_cast<int>(sendcounts[i]);
185 if (
static_cast<int64_t
>(snd_cnt) != sendcounts[i]) {
186 std::ostringstream errmsg;
187 errmsg <<
"ERROR: The number of items that must be communicated via MPI calls from\n"
188 <<
" processor " << my_processor <<
" to processor " << i <<
" is "
190 <<
"\n which exceeds the storage capacity of the integers "
191 "used by MPI functions.\n";
198 for (
size_t i = 1; i < pow_2; i++) {
201 size_t exchange_proc = i ^ my_processor;
202 if (exchange_proc <
static_cast<size_t>(processor_count)) {
203 int snd_cnt =
static_cast<int>(
204 sendcounts[exchange_proc]);
205 int rcv_cnt =
static_cast<int>(recvcounts[exchange_proc]);
207 if (
static_cast<size_t>(my_processor) < exchange_proc) {
208 MPI_Send((
void *)&sendbuf[senddisp[exchange_proc]], snd_cnt, mpi_type(T(0)),
209 exchange_proc, tag, comm);
210 MPI_Recv(&recvbuf[recvdisp[exchange_proc]], rcv_cnt, mpi_type(T(0)), exchange_proc, tag,
214 MPI_Recv(&recvbuf[recvdisp[exchange_proc]], rcv_cnt, mpi_type(T(0)), exchange_proc, tag,
216 MPI_Send((
void *)&sendbuf[senddisp[exchange_proc]], snd_cnt, mpi_type(T(0)),
217 exchange_proc, tag, comm);
223 std::copy(&sendbuf[senddisp[my_processor]],
224 &sendbuf[senddisp[my_processor] + sendcounts[my_processor]],
225 &recvbuf[recvdisp[my_processor]]);
229 template <
typename T>
230 int MY_Alltoallv(
const std::vector<T> &sendbuf,
const std::vector<int64_t> &sendcnts,
231 const std::vector<int64_t> &senddisp, std::vector<T> &recvbuf,
232 const std::vector<int64_t> &recvcnts,
const std::vector<int64_t> &recvdisp,
244 int processor_count = utils.parallel_size();
246 int max_comm = sendcnts[processor_count - 1] + senddisp[processor_count - 1];
247 std::vector<int> comm_size;
249 utils.gather(max_comm, comm_size);
250 int my_rank = utils.parallel_rank();
252 fmt::print(
"Send Communication Size: {}\n", fmt::join(comm_size,
", "));
257 int processor_count = 0;
258 MPI_Comm_size(comm, &processor_count);
259 size_t max_comm = sendcnts[processor_count - 1] + senddisp[processor_count - 1];
261 if (max_comm < one << 31) {
263 std::vector<int> send_cnt(sendcnts.begin(), sendcnts.end());
264 std::vector<int> send_dis(senddisp.begin(), senddisp.end());
265 std::vector<int> recv_cnt(recvcnts.begin(), recvcnts.end());
266 std::vector<int> recv_dis(recvdisp.begin(), recvdisp.end());
267 return MPI_Alltoallv((
void *)
Data(sendbuf),
Data(send_cnt),
Data(send_dis), mpi_type(T(0)),
268 (
void *)
Data(recvbuf),
Data(recv_cnt),
Data(recv_dis), mpi_type(T(0)),
277 return MY_Alltoallv64(sendbuf, sendcnts, senddisp, recvbuf, recvcnts, recvdisp, comm);
283 template <
typename T>
284 int MY_Alltoallv(
const std::vector<T> &sendbuf,
const std::vector<int> &sendcnts,
285 const std::vector<int> &senddisp, std::vector<T> &recvbuf,
286 const std::vector<int> &recvcnts,
const std::vector<int> &recvdisp,
292 int processor_count = utils.parallel_size();
294 int max_comm = sendcnts[processor_count - 1] + senddisp[processor_count - 1];
295 std::vector<int> comm_size;
297 utils.gather(max_comm, comm_size);
298 int my_rank = utils.parallel_rank();
300 fmt::print(
"Send Communication Size: {}\n", fmt::join(comm_size,
", "));
304 return MPI_Alltoallv((
void *)
Data(sendbuf),
const_cast<int *
>(
Data(sendcnts)),
305 const_cast<int *
>(
Data(senddisp)), mpi_type(T(0)),
Data(recvbuf),
306 const_cast<int *
>(
Data(recvcnts)),
const_cast<int *
>(
Data(recvdisp)),
307 mpi_type(T(0)), comm);
311 template <
typename T>
317#ifdef SEACAS_HAVE_MPI
320 std::ostringstream errmsg;
325 std::vector<T> maxout(local_minmax.size());
326 MPI_Op oper = MPI_MAX;
338 MPI_Allreduce((
void *)(
Data(local_minmax)),
Data(maxout),
339 static_cast<int>(local_minmax.size()), mpi_type(T()), oper,
communicator_);
340 if (success != MPI_SUCCESS) {
341 std::ostringstream errmsg;
342 errmsg <<
"Ioss::ParallelUtils::global_array_minmax - MPI_Allreduce failed";
346 for (
size_t i = 0; i < local_minmax.size(); i++) {
347 local_minmax[i] = maxout[i];
#define IOSS_MAYBE_UNUSED
Definition Ioss_CodeTypes.h:53
#define IOSS_NODISCARD
Definition Ioss_CodeTypes.h:54
int Ioss_MPI_Comm
Definition Ioss_CodeTypes.h:63
#define IOSS_PAR_UNUSED(x)
Definition Ioss_CodeTypes.h:68
IOSS_NODISCARD constexpr T * Data(std::vector< T > &vec)
Definition Ioss_Utils.h:56
void IOSS_ERROR(const std::ostringstream &errmsg)
Definition Ioss_Utils.h:38
Definition Ioss_ParallelUtils.h:31
void global_array_minmax(IOSS_MAYBE_UNUSED std::vector< T > &local_minmax, IOSS_MAYBE_UNUSED MinMax which) const
Definition Ioss_ParallelUtils.h:312
int gather(int vals_count, int size_per_val, std::vector< T > &my_values, std::vector< T > &result) const
void broadcast(std::vector< T > &my_value, int root=0) const
static IOSS_NODISCARD constexpr Ioss_MPI_Comm comm_self()
Definition Ioss_ParallelUtils.h:48
IOSS_NODISCARD int parallel_size() const
Definition Ioss_ParallelUtils.C:206
static IOSS_NODISCARD constexpr Ioss_MPI_Comm comm_null()
Definition Ioss_ParallelUtils.h:49
void broadcast(T &my_value, int root=0) const
static IOSS_NODISCARD constexpr Ioss_MPI_Comm comm_world()
Definition Ioss_ParallelUtils.h:47
IOSS_NODISCARD T global_minmax(IOSS_MAYBE_UNUSED T local_minmax, IOSS_MAYBE_UNUSED MinMax which) const
MinMax
Definition Ioss_ParallelUtils.h:36
@ DO_MAX
Definition Ioss_ParallelUtils.h:36
@ DO_MIN
Definition Ioss_ParallelUtils.h:36
@ DO_SUM
Definition Ioss_ParallelUtils.h:36
Ioss_MPI_Comm communicator_
Definition Ioss_ParallelUtils.h:148
IOSS_NODISCARD Ioss_MPI_Comm communicator() const
Definition Ioss_ParallelUtils.h:90
A collection of Ioss::Property objects.
Definition Ioss_PropertyManager.h:36
static IOSS_NODISCARD bool isEnabled()
Definition Ioss_SerializeIO.h:81
static IOSS_NODISCARD int getOwner()
Definition Ioss_SerializeIO.h:69
static IOSS_NODISCARD bool inBarrier()
Definition Ioss_SerializeIO.h:83
static IOSS_NODISCARD int power_2(int count)
Definition Ioss_Utils.h:273
The main namespace for the Ioss library.
Definition Ioad_DatabaseIO.C:40
std::vector< int64_t > Int64Vector
Definition Ioss_CodeTypes.h:22
std::vector< int > IntVector
Definition Ioss_CodeTypes.h:21