21 #ifndef GISMO_WITH_MPI
23 typedef int MPI_Group;
24 typedef int MPI_Request;
118 static std::ostream &
print(std::ostream &os)
120 os <<
"gsSerialGroup : rank = " <<
rank() <<
", size = " <<
size();
129 static MPI_Group m_group(0);
152 struct MPI_Status {};
156 static int rank () {
return 0; }
161 static int tag () {
return 0; }
175 const MPI_Status* operator& ()
const
177 static MPI_Status status;
184 static std::ostream &
print(std::ostream &os)
246 static gsSerialRequest getNullRequest()
248 gsSerialRequest request;
257 static MPI_Request req(0);
264 static std::ostream &
print(std::ostream &os)
266 os <<
"gsSerialRequest";
297 int rank ()
const {
return 0; }
302 static int size () {
return 1; }
307 static std::string
name() {
return "gsSerialComm"; }
325 static int group (
const MPI_Group*)
337 #ifdef GISMO_WITH_MPI
338 operator MPI_Comm ()
const {
return MPI_COMM_SELF;}
340 operator MPI_Comm ()
const {
return 0;}
362 static int sum (T* inout,
int len)
382 static int prod (T* inout,
int len)
402 static int min (T* inout,
int len)
422 static int max (T* inout,
int len)
472 static int send (T*,
int,
int,
int = 0)
488 static int isend (T*,
int,
int, MPI_Request,
int = 0)
503 static int recv (T*,
int,
int,
int = 0,
const void* = NULL)
519 static int irecv (T*,
int,
int, MPI_Request,
int = 0)
546 static int gather (T* in, T* out,
int len,
int)
549 for (
int i=0; i<len; i++)
574 static int gatherv (T* in,
int sendlen, T* out,
int* recvlen,
int* displ,
int root)
576 for (
int i=*displ; i<sendlen; i++)
598 for (
int i=0; i<len; i++)
625 for (
int i=*displ; i<*sendlen; i++)
645 for(T* end=sbuf+count; sbuf < end; ++sbuf, ++rbuf)
666 static int allgatherv (T* in,
int sendlen, T* out,
int* recvlen,
int* displ)
668 for (
int i=*displ; i<sendlen; i++)
684 template<
typename BinaryFunction,
typename Type>
702 template<
typename BinaryFunction,
typename Type>
710 #ifdef GISMO_WITH_MPI
729 gsMpiGroup(MPI_Group& group) : m_group(group)
737 MPI_Group_free(&m_group);
743 int compare (
const gsMpiGroup& other)
const
746 MPI_Group_compare(m_group, *(&other), &result);
753 int compare (
const MPI_Group& other)
const
756 MPI_Group_compare(m_group, other, &result);
763 gsMpiGroup
diff (
const gsMpiGroup& other)
const
766 MPI_Group_difference(m_group, *(&other), &diff_);
773 gsMpiGroup
diff (
const MPI_Group& other)
const
776 MPI_Group_difference(m_group, other, &diff_);
783 gsMpiGroup
intersect (
const gsMpiGroup& other)
const
785 gsMpiGroup intersect_;
786 MPI_Group_intersection(m_group, *(&other), &intersect_);
793 gsMpiGroup
intersect (
const MPI_Group& other)
const
795 gsMpiGroup intersect_;
796 MPI_Group_intersection(m_group, other, &intersect_);
803 gsMpiGroup
unite (
const gsMpiGroup& other)
const
806 MPI_Group_union(m_group, *(&other), &union_);
813 gsMpiGroup
unite (
const MPI_Group& other)
const
816 MPI_Group_union(m_group, other, &union_);
826 MPI_Group_rank(m_group, &rank_);
836 MPI_Group_size(m_group, &size_);
843 std::ostream &
print(std::ostream &os)
const
845 os <<
"gsMpiGroup : rank = " <<
rank() <<
", size = " <<
size();
872 inline std::ostream&
operator<<(std::ostream& os,
const gsMpiGroup& obj)
883 class gsMpiStatus :
public MPI_Status
889 int rank ()
const {
return MPI_SOURCE; }
894 int tag ()
const {
return MPI_TAG; }
903 MPI_Get_count(
this, MPITraits<T>::getType(), &count);
910 std::ostream &
print(std::ostream &os)
const
912 os <<
"gsMpiStatus : rank = " <<
rank() <<
", tag = " <<
tag();
920 inline std::ostream&
operator<<(std::ostream& os,
const gsMpiStatus& obj)
939 return MPI_Cancel(&m_request);
944 return MPI_Request_free(&m_request);
950 gsMpiStatus
status ()
const
954 MPI_Request_get_status(m_request, &flag, &status);
965 MPI_Test(&m_request, &flag, &status);
975 MPI_Wait(&m_request, &status);
982 std::ostream &
print(std::ostream &os)
const
984 os <<
"gsMpiRequest";
1004 static gsMpiStatus waitAny (
int numberRequests, gsMpiRequest requests[],
int* outIndex)
1007 MPI_Request mpiRequests[numberRequests];
1008 for(
int i = 0; i < numberRequests; i++)
1010 mpiRequests[i] = requests[i].m_request;
1013 MPI_Waitany(numberRequests, mpiRequests, outIndex, &status);
1017 static gsMpiRequest getNullRequest()
1019 gsMpiRequest request;
1020 request.m_request = MPI_REQUEST_NULL;
1025 MPI_Request m_request;
1031 inline std::ostream&
operator<<(std::ostream& os,
const gsMpiRequest& obj)
1042 class GISMO_EXPORT gsMpiComm
1048 gsMpiComm() : rank_(-1), size_(0) { }
1050 gsMpiComm(
const MPI_Comm & _comm)
1053 if(_comm != MPI_COMM_NULL)
1056 int initialized = 0;
1057 MPI_Initialized(&initialized);
1059 "You must call gsMpi::init(..) in your main() function"
1060 " before using gsMpiComm");
1061 MPI_Comm_set_errhandler(m_comm, ErrHandler);
1063 MPI_Comm_rank(m_comm, &rank_);
1064 MPI_Comm_size(m_comm, &size_);
1073 gsMpiComm(
const gsSerialComm &) : m_comm(MPI_COMM_SELF) { }
1078 typedef MPI_Comm Communicator;
1083 int rank ()
const {
return rank_; }
1088 int size ()
const {
return size_; }
1093 std::string name()
const
1095 char str[MPI_MAX_OBJECT_NAME];
1097 MPI_Comm_get_name(m_comm, str, &len);
1098 return std::string(str, len);
1102 int compare ( MPI_Comm comm )
const
1105 MPI_Comm_compare(m_comm, comm, &result);
1110 MPI_Comm duplicate ()
const
1113 MPI_Comm_dup(m_comm, &comm);
1118 int group (MPI_Group* group_)
const
1120 return MPI_Comm_group(m_comm, group_);
1124 MPI_Comm split (
int color,
int key)
const
1127 MPI_Comm_split(m_comm, color, key, &comm);
1131 operator MPI_Comm ()
const {
return m_comm; }
1143 static void ErrCallBack(MPI_Comm *comm,
int *err_code, ...)
1145 char err_string[MPI_MAX_ERROR_STRING];
1146 int err_length, err_class;
1149 MPI_Comm_get_name(*comm, err_string, &err_length);
1150 MPI_Comm_rank(*comm, &rank);
1151 gsWarn <<
"MPI error ("<<*err_code<<
") at process "<< rank
1152 <<
" of "<< err_string <<
"\n";
1153 MPI_Error_class(*err_code, &err_class);
1154 MPI_Error_string(err_class, err_string, &err_length);
1155 gsWarn <<
"gsMpi error class: "<<err_class <<
" ("<< err_string <<
")\n";
1156 MPI_Error_string(*err_code, err_string, &err_length);
1157 gsWarn <<
"gsMpi error : "<<*err_code <<
" ("<< err_string <<
")\n";
1158 throw std::runtime_error(
"GISMO_ERROR: " + std::string(err_string, err_length));
1162 static MPI_Errhandler ErrHandler;
1168 template<
typename T>
1172 allreduce<std::plus<T> >(&in,&out,1);
1177 template<
typename T>
1178 int sum (T* inout,
int len)
const
1180 return allreduce<std::plus<T> >(inout,len);
1183 template<
typename T>
1184 int sum (T* inout,
int len,
int root)
const
1186 return reduce<std::plus<T> >(inout,len,root);
1189 template<
typename T>
1190 int sum (T* in, T* out,
int len,
int root)
const
1192 return reduce<std::plus<T> >(in,out,len,root);
1195 template<
typename T>
1196 int isum (T* in,T* out,
int len,
int root, MPI_Request* req)
const
1198 return iallreduce<std::plus<T> >(in, out,len,req);
1201 template<
typename T>
1202 int isum (T* inout,
int len,
int root, MPI_Request* req)
const
1204 return ireduce<std::plus<T> >(inout,len,root,req);
1207 template<
typename T>
1208 int isum (T* inout,
int len, MPI_Request* req)
const
1210 return iallreduce<std::plus<T> >(inout,len,req);
1215 template<
typename T>
1216 T prod (T& in)
const
1219 allreduce<std::multiplies<T> >(&in,&out,1);
1224 template<
typename T>
1225 int prod (T* inout,
int len)
const
1227 return allreduce<std::multiplies<T> >(inout,len);
1231 template<
typename T>
1235 allreduce<Min<T> >(&in,&out,1);
1240 template<
typename T>
1241 int min (T* inout,
int len)
const
1243 return allreduce<Min<T> >(inout,len);
1248 template<
typename T>
1252 allreduce<Max<T> >(&in,&out,1);
1257 template<
typename T>
1258 int max (T* inout,
int len)
const
1260 return allreduce<Max<T> >(inout,len);
1264 int barrier ()
const
1266 return MPI_Barrier(m_comm);
1270 gsMpiStatus probe (
int source,
int tag = 0)
const
1273 MPI_Probe(source,tag,m_comm,&status);
1277 gsMpiStatus iprobe (
int source,
int* flag,
int tag = 0)
const
1280 MPI_Iprobe(source,tag,m_comm,flag,&status);
1285 template<
typename T>
1286 int send (T* in,
int len,
int dest,
int tag = 0)
const
1288 return MPI_Send(in,len,MPITraits<T>::getType(),
1293 template<
typename T>
1294 int isend (T* in,
int len,
int dest, MPI_Request* req,
int tag = 0)
const
1296 return MPI_Isend(in,len,MPITraits<T>::getType(),
1297 dest,tag,m_comm,req);
1301 template<
typename T>
1302 int recv (T* out,
int len,
int source,
int tag = 0, MPI_Status* status = NULL)
const
1304 return MPI_Recv(out,len,MPITraits<T>::getType(),
1305 source,tag,m_comm,(status == NULL ? MPI_STATUS_IGNORE : status));
1309 template<
typename T>
1310 int irecv (T* out,
int len,
int source, MPI_Request* req,
int tag = 0)
const
1312 return MPI_Irecv(out,len,MPITraits<T>::getType(),
1313 source,tag,m_comm,req);
1317 template<
typename T>
1318 int broadcast (T* inout,
int len,
int root)
const
1320 return MPI_Bcast(inout,len,MPITraits<T>::getType(),root,m_comm);
1325 template<
typename T>
1326 int gather (T* in, T* out,
int len,
int root)
const
1328 return MPI_Gather(in,len,MPITraits<T>::getType(),
1329 out,len,MPITraits<T>::getType(),
1334 template<
typename T>
1335 int gatherv (T* in,
int sendlen, T* out,
int* recvlen,
int* displ,
int root)
const
1337 return MPI_Gatherv(in,sendlen,MPITraits<T>::getType(),
1338 out,recvlen,displ,MPITraits<T>::getType(),
1344 template<
typename T>
1345 int scatter (T* send, T* recv,
int len,
int root)
const
1347 return MPI_Scatter(send,len,MPITraits<T>::getType(),
1348 recv,len,MPITraits<T>::getType(),
1353 template<
typename T>
1354 int scatterv (T* send,
int* sendlen,
int* displ, T* recv,
int recvlen,
int root)
const
1356 return MPI_Scatterv(send,sendlen,displ,MPITraits<T>::getType(),
1357 recv,recvlen,MPITraits<T>::getType(),
1363 template<
typename T>
1364 int alltoall (T* send, T* recv,
int sendcount,
int recvcount)
const
1366 return MPI_Alltoall(send,sendcount,MPITraits<T>::getType(),
1367 recv,recvcount,MPITraits<T>::getType(),
1372 template<
typename T>
1373 int alltoallv (T* send,
int* sendcount,
int* senddispl, T* recv,
int* recvcount,
int* recvdispl)
const
1375 return MPI_Alltoallv(send,sendcount,senddispl,MPITraits<T>::getType(),
1376 recv,recvcount,recvdispl,MPITraits<T>::getType(),
1381 template<
typename T,
typename T1>
1382 int allgather(T* sbuf,
int count, T1* rbuf)
const
1384 return MPI_Allgather(sbuf, count, MPITraits<T>::getType(),
1385 rbuf, count, MPITraits<T1>::getType(),
1390 template<
typename T>
1391 int allgatherv (T* in,
int sendlen, T* out,
int* recvlen,
int* displ)
const
1393 return MPI_Allgatherv(in,sendlen,MPITraits<T>::getType(),
1394 out,recvlen,displ,MPITraits<T>::getType(),
1398 #ifndef MPI_IN_PLACE
1399 #define MPI_IN_PLACE inout
1400 #define MASK_MPI_IN_PLACE
1411 template<
typename BinaryFunction,
typename Type>
1412 int allreduce(Type* inout,
int len)
const
1419 return MPI_Allreduce(MPI_IN_PLACE, inout, len, MPITraits<Type>::getType(),
1420 (Generic_MPI_Op<Type, BinaryFunction>::get()),m_comm);
1425 template<
typename BinaryFunction,
typename Type>
1426 int allreduce(Type* in, Type* out,
int len)
const
1428 return MPI_Allreduce(in, out, len, MPITraits<Type>::getType(),
1429 (Generic_MPI_Op<Type, BinaryFunction>::get()),m_comm);
1435 template<
typename BinaryFunction,
typename Type>
1436 int iallreduce(Type* in, Type* out,
int len, MPI_Request* req)
const
1438 return MPI_Iallreduce(in, out, len, MPITraits<Type>::getType(),
1439 (Generic_MPI_Op<Type, BinaryFunction>::get()),m_comm,req);
1443 template<
typename BinaryFunction,
typename Type>
1444 int iallreduce(Type* inout,
int len, MPI_Request* req)
const
1446 return MPI_Iallreduce(MPI_IN_PLACE, inout, len, MPITraits<Type>::getType(),
1447 (Generic_MPI_Op<Type, BinaryFunction>::get()),m_comm,req);
1450 template<
typename BinaryFunction,
typename Type>
1451 int reduce(Type* inout,
int len,
int root)
const
1455 ret = MPI_Reduce(MPI_IN_PLACE, inout, len, MPITraits<Type>::getType(),
1456 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm);
1458 ret = MPI_Reduce(inout, NULL, len, MPITraits<Type>::getType(),
1459 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm);
1463 template<
typename BinaryFunction,
typename Type>
1464 int reduce(Type* in,Type* out,
int len,
int root)
const
1466 return MPI_Reduce(in, out, len, MPITraits<Type>::getType(),
1467 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm);
1470 template<
typename BinaryFunction,
typename Type>
1471 int ireduce(Type* inout,
int len,
int root, MPI_Request* req)
const
1475 ret = MPI_Ireduce(MPI_IN_PLACE, inout, len, MPITraits<Type>::getType(),
1476 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm,req);
1478 ret = MPI_Ireduce(inout, inout, len, MPITraits<Type>::getType(),
1479 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm,req);
1483 #ifdef MASK_MPI_IN_PLACE
1485 #undef MASK_MPI_IN_PLACE
1488 template<
typename BinaryFunction,
typename Type>
1489 int ireduce(Type* in, Type* out,
int len,
int root, MPI_Request* req)
const
1491 return MPI_Ireduce(in, out, len, MPITraits<Type>::getType(),
1492 (Generic_MPI_Op<Type, BinaryFunction>::get()),root,m_comm,req);
1498 typedef gsSerialComm gsMpiComm;
1499 typedef gsSerialGroup gsMpiGroup;
1500 typedef gsSerialStatus gsMpiStatus;
1501 typedef gsSerialRequest gsMpiRequest;
static T max(T &in)
Compute the maximum of the argument over all processes and return the result in every process...
Definition: gsMpiComm.h:412
static int cancel()
Cancels the communication request.
Definition: gsMpiComm.h:212
static int scatter(T *send, T *recv, int len, int root)
Scatter array from a root to all other task.
Definition: gsMpiComm.h:596
static int compare(gsSerialComm)
Compares two communicators.
Definition: gsMpiComm.h:311
static T prod(T &in)
Compute the product of the argument over all processes and return the result in every process...
Definition: gsMpiComm.h:372
static int barrier()
Wait until all processes have arrived at this point in the program.
Definition: gsMpiComm.h:430
static int rank()
Returns the rank of the group.
Definition: gsMpiComm.h:102
static gsSerialStatus probe(int, int=0)
Query the status from a source process with a defined tag (blocking)
Definition: gsMpiComm.h:443
static gsSerialGroup intersect(const int &)
Creates a group from the intersection of the group with another group.
Definition: gsMpiComm.h:78
int rank() const
return rank of process, i.e. zero
Definition: gsMpiComm.h:297
static int allgatherv(T *in, int sendlen, T *out, int *recvlen, int *displ)
Gathers data of variable length from all tasks and distribute it to all.
Definition: gsMpiComm.h:666
static int isend(T *, int, int, MPI_Request, int=0)
Sends data to a destination process with a defined tag (non-blocking)
Definition: gsMpiComm.h:488
static int rank()
Returns the rank of the status.
Definition: gsMpiComm.h:156
static gsSerialGroup unite(const int &)
Creates a group from the union of the group with another group.
Definition: gsMpiComm.h:94
static int allgather(T *sbuf, int count, T *rbuf)
Gathers data from all tasks and distribute it to all.
Definition: gsMpiComm.h:643
static T sum(T &in)
Compute the sum of the argument over all processes and return the result in every process...
Definition: gsMpiComm.h:352
static int tag()
Returns the tag of the status.
Definition: gsMpiComm.h:161
static std::ostream & print(std::ostream &os)
Prints the status object as a string.
Definition: gsMpiComm.h:184
A sequential communicator status class.
Definition: gsMpiComm.h:149
static int broadcast(T *, int, int)
Distribute an array from the process with rank root to all other processes.
Definition: gsMpiComm.h:528
static gsSerialGroup diff(const int &)
Creates a group from the difference of the group with another group.
Definition: gsMpiComm.h:62
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
static int gatherv(T *in, int sendlen, T *out, int *recvlen, int *displ, int root)
Gather arrays of variable size on root task.
Definition: gsMpiComm.h:574
static int irecv(T *, int, int, MPI_Request, int=0)
Receives data from a source process with a defined tag (non-blocking)
Definition: gsMpiComm.h:519
static T min(T &in)
Compute the minimum of the argument over all processes and return the result in every process...
Definition: gsMpiComm.h:392
static std::ostream & print(std::ostream &os)
Prints the request object as a string.
Definition: gsMpiComm.h:264
static gsSerialStatus wait()
Waits for the communication request.
Definition: gsMpiComm.h:236
static gsSerialGroup diff(const gsSerialGroup &)
Creates a group from the difference of the group with another group.
Definition: gsMpiComm.h:54
static int max(T *inout, int len)
Compute the maximum over all processes for each component of an array and return the result in every ...
Definition: gsMpiComm.h:422
static int gather(T *in, T *out, int len, int)
Gather arrays on root task.
Definition: gsMpiComm.h:546
std::ostream & operator<<(std::ostream &os, const _expr< E > &b)
Stream operator for expressions.
Definition: gsExpressions.h:382
A sequential communicator request class.
Definition: gsMpiComm.h:206
#define gsWarn
Definition: gsDebug.h:50
static gsSerialGroup unite(const gsSerialGroup &)
Creates a group from the union of the group with another group.
Definition: gsMpiComm.h:86
static std::string name()
Returns the name of the communicator.
Definition: gsMpiComm.h:307
static int compare(const int &)
Compares the group with another group.
Definition: gsMpiComm.h:46
static int send(T *, int, int, int=0)
Sends data to a destination process with a defined tag (blocking)
Definition: gsMpiComm.h:472
Provides forward declarations of types and structs.
static int min(T *inout, int len)
Compute the minimum over all processes for each component of an array and return the result in every ...
Definition: gsMpiComm.h:402
static std::ostream & print(std::ostream &os)
Prints the group object as a string.
Definition: gsMpiComm.h:118
static int size()
return rank of process, i.e. one
Definition: gsMpiComm.h:302
gsSerialComm duplicate() const
Duplicates the communicator.
Definition: gsMpiComm.h:318
static int sum(T *inout, int len)
Compute the sum over all processes for each component of an array and return the result in every proc...
Definition: gsMpiComm.h:362
static int prod(T *inout, int len)
Compute the product over all processes for each component of an array and return the result in every ...
Definition: gsMpiComm.h:382
static gsSerialStatus status()
Returns the status of the communication request.
Definition: gsMpiComm.h:220
gsSerialComm split(int, int) const
Splits the communicator into two.
Definition: gsMpiComm.h:332
static int scatterv(T *send, int *sendlen, int *displ, T *recv, int recvlen, int root)
Scatter arrays of variable length from a root to all other tasks.
Definition: gsMpiComm.h:623
static int group(const MPI_Group *)
Returns the group of the communicator.
Definition: gsMpiComm.h:325
A sequential communicator group class.
Definition: gsMpiComm.h:32
static int recv(T *, int, int, int=0, const void *=NULL)
Receives data from a source process with a defined tag (blocking)
Definition: gsMpiComm.h:503
static int compare(const gsSerialGroup &)
Compares the group with another group.
Definition: gsMpiComm.h:38
A serial communication class.
Definition: gsMpiComm.h:288
const MPI_Request * operator&() const
Returns a constant pointer to the internal request object.
Definition: gsMpiComm.h:255
static gsSerialStatus test()
Tests for the completion of for the communication request.
Definition: gsMpiComm.h:228
const MPI_Group * operator&() const
Returns a constant pointer to the internal group object.
Definition: gsMpiComm.h:127
static gsSerialGroup intersect(const gsSerialGroup &)
Creates a group from the intersection of the group with another group.
Definition: gsMpiComm.h:70
static int size()
Returns the size of the status.
Definition: gsMpiComm.h:167
static int allreduce(Type *inout, int len)
Compute something over all processes for each component of an array and return the result in every pr...
Definition: gsMpiComm.h:685
static gsSerialStatus iprobe(int, int *, int=0)
Query the status from a source process with a defined tag (non-blocking)
Definition: gsMpiComm.h:457
static void allreduce(Type *in, Type *out, int len)
Compute something over all processes for each component of an array and return the result in every pr...
Definition: gsMpiComm.h:703
static int size()
Returns the size of the group.
Definition: gsMpiComm.h:110
void copy(T begin, T end, U *result)
Small wrapper for std::copy mimicking std::copy for a raw pointer destination, copies n positions sta...
Definition: gsMemory.h:391