10 #define OMPI_SKIP_MPICXX 1
36 void printf(
int rank,
const char *fmt, ...)
const;
39 std::vector<int>
jid(
const int n)
const;
43 void send(
int n,
const T *data,
int dest,
int tag=0)
const;
45 void isend(
int n,
const T *data,
int dest,
int tag=0)
const;
47 void recv(
int n, T *data,
int source,
int tag=0)
const;
49 void irecv(
int n, T *data,
int source,
int tag=0)
const;
54 void allreduce(
int n, T *data, MPI_Op op=MPI_SUM)
const;
56 void reduce(
int n, T *data, MPI_Op op=MPI_SUM,
int root=0)
const;
58 void bcast(
int n, T *data,
int root)
const;
64 int rank()
const {
return _rank;};
66 int size()
const {
return _size;};
83 void check_ret(
const int ret)
const;
85 MPI_Datatype mpi_type_lookup(
const T *x)
const;
136 int mpi_ret = MPI_Comm_create(_comm, group, &newcomm);
155 int mpi_ret = MPI_Comm_split(_comm, color, key, &newcomm);
167 int mpi_ret = MPI_Comm_free(&_comm);
170 _comm = MPI_COMM_NULL;
180 int ret = MPI_Finalize();
204 vfprintf(stdout, fmt, args);
217 printf(0,
"## MPI on %d ranks\n\n", _size);
240 std::vector<int> ret;
244 int local = n / _size;
247 if (rem == 0 || (_rank < (_size - rem)))
250 for (
int i=0; i<local; i++)
251 ret[i] = i + (_rank*local);
256 for (
int i=0; i<=local; i++)
257 ret[i] = i + (_rank*(local+1)) - (_size - rem);
286 template <
typename T>
290 MPI_Datatype type = mpi_type_lookup(data);
291 int ret = MPI_Send(data, n, type, dest, tag, _comm);
295 template <
typename T>
296 inline void fml::comm::isend(
int n,
const T *data,
int dest,
int tag)
const
298 MPI_Datatype type = mpi_type_lookup(data);
299 int ret = MPI_Isend(data, n, type, dest, tag, _comm);
315 template <
typename T>
319 MPI_Datatype type = mpi_type_lookup(data);
320 int ret = MPI_Recv(data, n, type, source, tag, _comm, MPI_STATUS_IGNORE);
324 template <
typename T>
325 inline void fml::comm::irecv(
int n, T *data,
int source,
int tag)
const
327 MPI_Datatype type = mpi_type_lookup(data);
328 int ret = MPI_Irecv(data, n, type, source, tag, _comm, MPI_STATUS_IGNORE);
342 int ret = MPI_Barrier(_comm);
355 template <
typename T>
359 MPI_Datatype type = mpi_type_lookup(data);
360 int ret = MPI_Allreduce(MPI_IN_PLACE, data, n, type, op, _comm);
374 template <
typename T>
378 MPI_Datatype type = mpi_type_lookup(data);
379 int ret = MPI_Reduce(MPI_IN_PLACE, data, n, type, op, root, _comm);
393 template <
typename T>
397 MPI_Datatype type = mpi_type_lookup(data);
398 int ret = MPI_Bcast(data, n, type, root, _comm);
409 inline void fml::comm::init()
414 ret = MPI_Initialized(&flag);
419 ret = MPI_Init(NULL, NULL);
426 inline void fml::comm::set_metadata()
430 ret = MPI_Comm_rank(_comm, &_rank);
432 ret = MPI_Comm_size(_comm, &_size);
436 ret = MPI_Comm_split_type(_comm, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL, &localcomm);
439 ret = MPI_Comm_rank(localcomm, &_localrank);
441 ret = MPI_Comm_size(localcomm, &_localsize);
447 inline void fml::comm::check_ret(
const int ret)
const
449 if (ret != MPI_SUCCESS && _rank == 0)
452 char s[MPI_MAX_ERROR_STRING];
454 MPI_Error_string(ret, s, &slen);
455 throw std::runtime_error(s);
461 template <
typename T>
462 inline MPI_Datatype fml::comm::mpi_type_lookup(
const T *x)
const
467 if (
typeid(T) ==
typeid(char))
469 else if (
typeid(T) ==
typeid(double))
471 else if (
typeid(T) ==
typeid(float))
473 else if (
typeid(T) ==
typeid(int))
475 else if (
typeid(T) ==
typeid(long))
477 else if (
typeid(T) ==
typeid(
long double))
478 return MPI_LONG_DOUBLE;
479 else if (
typeid(T) ==
typeid(
long long))
480 return MPI_LONG_LONG_INT;
481 else if (
typeid(T) ==
typeid(short))
483 else if (
typeid(T) ==
typeid(
unsigned int))
485 else if (
typeid(T) ==
typeid(
unsigned char))
486 return MPI_UNSIGNED_CHAR;
487 else if (
typeid(T) ==
typeid(
unsigned long))
488 return MPI_UNSIGNED_LONG;
489 else if (
typeid(T) ==
typeid(
unsigned short))
490 return MPI_UNSIGNED_SHORT;
491 else if (
typeid(T) ==
typeid(uint32_t))
495 else if (
typeid(T) ==
typeid(int8_t))
497 else if (
typeid(T) ==
typeid(int16_t))
499 else if (
typeid(T) ==
typeid(int32_t))
501 else if (
typeid(T) ==
typeid(int64_t))
503 else if (
typeid(T) ==
typeid(uint8_t))
505 else if (
typeid(T) ==
typeid(uint16_t))
507 else if (
typeid(T) ==
typeid(uint32_t))
509 else if (
typeid(T) ==
typeid(uint64_t))
513 return MPI_DATATYPE_NULL;