33 #ifndef IOSS_Ioss_ParallelUtils_h 34 #define IOSS_Ioss_ParallelUtils_h 43 #ifdef SEACAS_HAVE_MPI 66 bool get_environment(
const std::string &
name, std::string &value,
bool sync_parallel)
const;
94 std::string
decode_filename(
const std::string &filename,
bool is_parallel)
const;
116 void memory_stats(int64_t &min, int64_t &max, int64_t &avg)
const;
132 template <
typename T>
135 template <
typename T>
void gather(T my_value, std::vector<T> &result)
const;
136 template <
typename T>
void all_gather(T my_value, std::vector<T> &result)
const;
137 template <
typename T>
void gather(std::vector<T> &my_values, std::vector<T> &result)
const;
138 template <
typename T>
void all_gather(std::vector<T> &my_values, std::vector<T> &result)
const;
139 template <
typename T>
140 int gather(
int vals_count,
int size_per_val, std::vector<T> &my_values,
141 std::vector<T> &result)
const;
143 void progress(
const std::string &output)
const;
149 #ifdef SEACAS_HAVE_MPI 150 inline MPI_Datatype mpi_type(
double ) {
return MPI_DOUBLE; }
151 inline MPI_Datatype mpi_type(
float ) {
return MPI_FLOAT; }
152 inline MPI_Datatype mpi_type(
int ) {
return MPI_INT; }
153 inline MPI_Datatype mpi_type(
char ) {
return MPI_CHAR; }
154 inline MPI_Datatype mpi_type(
long int ) {
return MPI_LONG_LONG_INT; }
155 inline MPI_Datatype mpi_type(
long long int ) {
return MPI_LONG_LONG_INT; }
156 inline MPI_Datatype mpi_type(
unsigned int ) {
return MPI_UNSIGNED; }
157 inline MPI_Datatype mpi_type(
unsigned long int ) {
return MPI_UNSIGNED_LONG; }
159 template <
typename T>
160 int MY_Alltoallv64(
const std::vector<T> &sendbuf,
const std::vector<int64_t> &sendcounts,
161 const std::vector<int64_t> &senddisp, std::vector<T> &recvbuf,
162 const std::vector<int64_t> &recvcounts,
const std::vector<int64_t> &recvdisp,
165 int processor_count = 0;
166 int my_processor = 0;
167 MPI_Comm_size(comm, &processor_count);
168 MPI_Comm_rank(comm, &my_processor);
172 for (
int i = 0; i < processor_count; i++) {
173 int snd_cnt = static_cast<int>(sendcounts[i]);
174 if (static_cast<int64_t>(snd_cnt) != sendcounts[i]) {
175 std::ostringstream errmsg;
176 errmsg <<
"ERROR: The number of items that must be communicated via MPI calls from\n" 177 <<
" processor " << my_processor <<
" to processor " << i <<
" is " 179 <<
"\n which exceeds the storage capacity of the integers " 180 "used by MPI functions.\n";
181 std::cerr << errmsg.str();
188 for (
size_t i = 1; i < pow_2; i++) {
192 size_t exchange_proc = i ^ my_processor;
193 if (exchange_proc < static_cast<size_t>(processor_count)) {
194 int snd_cnt = static_cast<int>(
195 sendcounts[exchange_proc]);
196 int rcv_cnt = static_cast<int>(recvcounts[exchange_proc]);
197 if (static_cast<size_t>(my_processor) < exchange_proc) {
198 MPI_Send((
void *)&sendbuf[senddisp[exchange_proc]], snd_cnt, mpi_type(T(0)),
199 exchange_proc, tag, comm);
200 MPI_Recv(&recvbuf[recvdisp[exchange_proc]], rcv_cnt, mpi_type(T(0)), exchange_proc, tag,
204 MPI_Recv(&recvbuf[recvdisp[exchange_proc]], rcv_cnt, mpi_type(T(0)), exchange_proc, tag,
206 MPI_Send((
void *)&sendbuf[senddisp[exchange_proc]], snd_cnt, mpi_type(T(0)),
207 exchange_proc, tag, comm);
213 std::copy(&sendbuf[senddisp[my_processor]],
214 &sendbuf[senddisp[my_processor] + sendcounts[my_processor]],
215 &recvbuf[recvdisp[my_processor]]);
219 template <
typename T>
220 int MY_Alltoallv(
const std::vector<T> &sendbuf,
const std::vector<int64_t> &sendcnts,
221 const std::vector<int64_t> &senddisp, std::vector<T> &recvbuf,
222 const std::vector<int64_t> &recvcnts,
const std::vector<int64_t> &recvdisp,
232 int processor_count = 0;
233 MPI_Comm_size(comm, &processor_count);
234 size_t max_comm = sendcnts[processor_count - 1] + senddisp[processor_count - 1];
236 if (max_comm < one << 31) {
238 std::vector<int> send_cnt(sendcnts.begin(), sendcnts.end());
239 std::vector<int> send_dis(senddisp.begin(), senddisp.end());
240 std::vector<int> recv_cnt(recvcnts.begin(), recvcnts.end());
241 std::vector<int> recv_dis(recvdisp.begin(), recvdisp.end());
242 return MPI_Alltoallv((
void *)sendbuf.data(), send_cnt.data(), send_dis.data(), mpi_type(T(0)),
243 (
void *)recvbuf.data(), recv_cnt.data(), recv_dis.data(), mpi_type(T(0)),
252 return MY_Alltoallv64(sendbuf, sendcnts, senddisp, recvbuf, recvcnts, recvdisp, comm);
258 template <
typename T>
259 int MY_Alltoallv(
const std::vector<T> &sendbuf,
const std::vector<int> &sendcnts,
260 const std::vector<int> &senddisp, std::vector<T> &recvbuf,
261 const std::vector<int> &recvcnts,
const std::vector<int> &recvdisp,
264 return MPI_Alltoallv((
void *)sendbuf.data(), const_cast<int *>(sendcnts.data()),
265 const_cast<int *>(senddisp.data()), mpi_type(T(0)), recvbuf.data(),
266 const_cast<int *>(recvcnts.data()), const_cast<int *>(recvdisp.data()),
267 mpi_type(T(0)), comm);
271 template <
typename T>
276 #ifdef SEACAS_HAVE_MPI 279 std::ostringstream errmsg;
284 std::vector<T> maxout(local_minmax.size());
285 MPI_Op oper = MPI_MAX;
297 MPI_Allreduce((
void *)(local_minmax.data()), maxout.data(),
298 static_cast<int>(local_minmax.size()), mpi_type(T()), oper,
communicator_);
299 if (success != MPI_SUCCESS) {
300 std::ostringstream errmsg;
301 errmsg <<
"Ioss::ParallelUtils::global_array_minmax - MPI_Allreduce failed";
305 for (
size_t i = 0; i < local_minmax.size(); i++) {
306 local_minmax[i] = maxout[i];
T global_minmax(T local_minmax, MinMax which) const
Definition: Ioss_ParallelUtils.C:402
int64_t generate_guid(size_t id, int rank=-1) const
Definition: Ioss_ParallelUtils.C:287
static int power_2(int count)
Definition: Ioss_Utils.h:211
void attribute_reduction(int length, char buffer[]) const
Definition: Ioss_ParallelUtils.C:304
The main namespace for the Ioss library.
Definition: Ioad_DatabaseIO.C:66
#define PAR_UNUSED(x)
Definition: Ioss_CodeTypes.h:81
int parallel_rank() const
Definition: Ioss_ParallelUtils.C:245
int parallel_size() const
Definition: Ioss_ParallelUtils.C:234
void hwm_memory_stats(int64_t &min, int64_t &max, int64_t &avg) const
Definition: Ioss_ParallelUtils.C:270
std::vector< int > IntVector
Definition: Ioss_CodeTypes.h:43
std::string decode_filename(const std::string &filename, bool is_parallel) const
Definition: Ioss_ParallelUtils.C:218
Definition: Ioss_ParallelUtils.h:58
Definition: Ioss_ParallelUtils.h:49
Definition: Ioss_ParallelUtils.h:58
static bool isEnabled()
Definition: Ioss_SerializeIO.h:84
void global_array_minmax(std::vector< T > &local_minmax, MinMax which) const
Definition: Ioss_ParallelUtils.h:272
std::vector< int64_t > Int64Vector
Definition: Ioss_CodeTypes.h:44
void memory_stats(int64_t &min, int64_t &max, int64_t &avg) const
Definition: Ioss_ParallelUtils.C:256
Definition: Ioss_ParallelUtils.h:58
void add_environment_properties(Ioss::PropertyManager &properties)
Definition: Ioss_ParallelUtils.C:78
MinMax
Definition: Ioss_ParallelUtils.h:58
MPI_Comm communicator() const
Definition: Ioss_ParallelUtils.h:96
void progress(const std::string &output) const
Definition: Ioss_ParallelUtils.C:513
int rank
Definition: Iocgns_DecompositionData.C:55
static int getOwner()
Definition: Ioss_SerializeIO.h:72
std::string name(Ioss::GroupingEntity *entity)
Definition: io_info.C:89
void global_count(const IntVector &local_counts, IntVector &global_counts) const
Definition: Ioss_ParallelUtils.C:326
bool get_environment(const std::string &name, std::string &value, bool sync_parallel) const
Definition: Ioss_ParallelUtils.C:126
static bool inBarrier()
Definition: Ioss_SerializeIO.h:86
ParallelUtils(MPI_Comm the_communicator)
Definition: Ioss_ParallelUtils.C:76
int MPI_Comm
Definition: Ioss_CodeTypes.h:88
MPI_Comm communicator_
Definition: Ioss_ParallelUtils.h:146
void gather(T my_value, std::vector< T > &result) const
Definition: Ioss_ParallelUtils.C:446
A collection of Ioss::Property objects.
Definition: Ioss_PropertyManager.h:49
void all_gather(T my_value, std::vector< T > &result) const
Definition: Ioss_ParallelUtils.C:469
#define IOSS_ERROR(errmsg)
Definition: Ioss_Utils.h:65