20 #ifndef JDFTX_CORE_MPIUTIL_H 21 #define JDFTX_CORE_MPIUTIL_H 39 bool isHead()
const {
return iProc==0; }
43 void exit(
int errCode)
const;
48 template<
typename T>
void send(
const T* data,
size_t nData,
int dest,
int tag)
const;
49 template<
typename T>
void recv(T* data,
size_t nData,
int src,
int tag)
const;
50 template<
typename T>
void send(
const T& data,
int dest,
int tag)
const;
51 template<
typename T>
void recv(T& data,
int src,
int tag)
const;
52 void send(
const bool* data,
size_t nData,
int dest,
int tag)
const;
53 void recv(
bool* data,
size_t nData,
int src,
int tag)
const;
54 void send(
const string& s,
int dest,
int tag)
const;
55 void recv(
string& s,
int src,
int tag)
const;
58 template<
typename T>
void bcast(T* data,
size_t nData,
int root=0)
const;
59 template<
typename T>
void bcast(T& data,
int root=0)
const;
60 void bcast(
bool* data,
size_t nData,
int root=0)
const;
61 void bcast(
string& s,
int root=0)
const;
64 enum ReduceOp { ReduceMin, ReduceMax, ReduceSum, ReduceProd, ReduceLAnd, ReduceBAnd, ReduceLOr, ReduceBOr, ReduceLXor, ReduceBXor };
65 template<
typename T>
void allReduce(T* data,
size_t nData, ReduceOp op,
bool safeMode=
false)
const;
66 template<
typename T>
void allReduce(T& data, ReduceOp op,
bool safeMode=
false)
const;
67 void allReduce(
bool* data,
size_t nData, ReduceOp op,
bool safeMode=
false)
const;
68 template<
typename T>
void allReduce(T& data,
int& index, ReduceOp op)
const;
72 typedef MPI_File File;
76 void fopenRead(File& fp,
const char* fname,
size_t fsizeExpected=0,
const char* fsizeErrMsg=0)
const;
77 void fopenWrite(File& fp,
const char* fname)
const;
78 void fopenAppend(File& fp,
const char* fname)
const;
79 void fclose(File& fp)
const;
80 void fseek(File fp,
long offset,
int whence)
const;
81 void fread(
void *ptr,
size_t size,
size_t nmemb, File fp)
const;
82 void fwrite(
const void *ptr,
size_t size,
size_t nmemb, File fp)
const;
91 void init(
size_t nTasks,
const MPIUtil* mpiUtil);
92 inline size_t start()
const {
return startMine; }
93 inline size_t stop()
const {
return stopMine; }
94 inline size_t start(
int iProc)
const {
return iProc ? stopArr[iProc-1] : 0; }
95 inline size_t stop(
int iProc)
const {
return stopArr[iProc]; }
96 inline bool isMine(
size_t task)
const {
return task>=startMine && task<stopMine; }
97 template<
typename T>
void myRange(T& start, T& stop)
const { start=startMine; stop=stopMine; }
98 int whose(
size_t task)
const;
100 size_t startMine, stopMine;
101 std::vector<size_t> stopArr;
107 namespace MPIUtilPrivate
110 template<
typename T>
struct DataType;
111 #define DECLARE_DataType(cName, mpiName) template<> struct DataType<cName> { static MPI_Datatype get() { return MPI_##mpiName; } }; 112 DECLARE_DataType(
char, CHAR)
113 DECLARE_DataType(
unsigned char, UNSIGNED_CHAR)
114 DECLARE_DataType(
short, SHORT)
115 DECLARE_DataType(
unsigned short, UNSIGNED_SHORT)
116 DECLARE_DataType(
int, INT)
117 DECLARE_DataType(
unsigned int, UNSIGNED)
118 DECLARE_DataType(
long, LONG)
119 DECLARE_DataType(
unsigned long, UNSIGNED_LONG)
120 DECLARE_DataType(
long long, LONG_LONG)
121 DECLARE_DataType(
unsigned long long, UNSIGNED_LONG_LONG)
122 DECLARE_DataType(
float, FLOAT)
123 DECLARE_DataType(
double, DOUBLE)
124 #undef DECLARE_DataType 126 static inline MPI_Op mpiOp(MPIUtil::ReduceOp op)
128 {
case MPIUtil::ReduceMax:
return MPI_MAX;
129 case MPIUtil::ReduceMin:
return MPI_MIN;
130 case MPIUtil::ReduceSum:
return MPI_SUM;
131 case MPIUtil::ReduceProd:
return MPI_PROD;
132 case MPIUtil::ReduceLAnd:
return MPI_LAND;
133 case MPIUtil::ReduceBAnd:
return MPI_BAND;
134 case MPIUtil::ReduceLOr:
return MPI_LOR;
135 case MPIUtil::ReduceBOr:
return MPI_BOR;
136 case MPIUtil::ReduceLXor:
return MPI_LXOR;
137 case MPIUtil::ReduceBXor:
return MPI_BXOR;
142 template<
typename T>
struct DataTypeIntPair;
143 #define DECLARE_DataTypeIntPair(cName, mpiName) template<> struct DataTypeIntPair<cName> { static MPI_Datatype get() { return mpiName; } }; 144 DECLARE_DataTypeIntPair(
short, MPI_SHORT_INT)
145 DECLARE_DataTypeIntPair(
int, MPI_2INT)
146 DECLARE_DataTypeIntPair(
long, MPI_LONG_INT)
147 DECLARE_DataTypeIntPair(
float, MPI_FLOAT_INT)
148 DECLARE_DataTypeIntPair(
double, MPI_DOUBLE_INT)
149 #undef DECLARE_DataTypeIntPair 151 static inline MPI_Op mpiLocOp(MPIUtil::ReduceOp op)
153 {
case MPIUtil::ReduceMax:
return MPI_MAXLOC;
154 case MPIUtil::ReduceMin:
return MPI_MINLOC;
161 template<
typename T>
void MPIUtil::send(
const T* data,
size_t nData,
int dest,
int tag)
const 162 {
using namespace MPIUtilPrivate;
164 if(nProcs>1) MPI_Send((T*)data, nData, DataType<T>::get(), dest, tag, MPI_COMM_WORLD);
168 template<
typename T>
void MPIUtil::recv(T* data,
size_t nData,
int src,
int tag)
const 169 {
using namespace MPIUtilPrivate;
171 if(nProcs>1) MPI_Recv(data, nData, DataType<T>::get(), src, tag, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
175 template<
typename T>
void MPIUtil::send(
const T& data,
int dest,
int tag)
const 176 {
send(&data, 1, dest, tag);
179 template<
typename T>
void MPIUtil::recv(T& data,
int src,
int tag)
const 180 {
recv(&data, 1, src, tag);
183 template<
typename T>
void MPIUtil::bcast(T* data,
size_t nData,
int root)
const 184 {
using namespace MPIUtilPrivate;
186 if(nProcs>1) MPI_Bcast(data, nData, DataType<T>::get(), root, MPI_COMM_WORLD);
191 {
bcast(&data, 1, root);
194 template<
typename T>
void MPIUtil::allReduce(T* data,
size_t nData, MPIUtil::ReduceOp op,
bool safeMode)
const 195 {
using namespace MPIUtilPrivate;
199 { MPI_Reduce(
isHead()?MPI_IN_PLACE:data, data, nData, DataType<T>::get(), mpiOp(op), 0, MPI_COMM_WORLD);
200 bcast(data, nData, 0);
203 MPI_Allreduce(MPI_IN_PLACE, data, nData, DataType<T>::get(), mpiOp(op), MPI_COMM_WORLD);
208 template<
typename T>
void MPIUtil::allReduce(T& data, MPIUtil::ReduceOp op,
bool safeMode)
const 212 template<
typename T>
void MPIUtil::allReduce(T& data,
int& index, MPIUtil::ReduceOp op)
const 213 {
using namespace MPIUtilPrivate;
216 {
struct Pair { T data;
int index; } pair;
217 pair.data = data; pair.index = index;
218 MPI_Allreduce(MPI_IN_PLACE, &pair, 1, DataTypeIntPair<T>::get(), mpiLocOp(op), MPI_COMM_WORLD);
219 data = pair.data; index = pair.index;
225 #endif // JDFTX_CORE_MPIUTIL_H int iProcess() const
rank of current process
Definition: MPIUtil.h:37
int nProcesses() const
number of processes
Definition: MPIUtil.h:38
size_t start() const
Task number that current process should start on.
Definition: MPIUtil.h:92
size_t stop(int iProc) const
Task number that the specified process should stop before (non-inclusive)
Definition: MPIUtil.h:95
size_t start(int iProc) const
Task number that the specified process should start on.
Definition: MPIUtil.h:94
STL strings and streams with case insensitive comparison.
void fopenRead(File &fp, const char *fname, size_t fsizeExpected=0, const char *fsizeErrMsg=0) const
open file for reading and optionally check file size
bool isHead() const
whether this is the root process (makes code more readable)
Definition: MPIUtil.h:39
void fopenAppend(File &fp, const char *fname) const
open file for appending to the end. Implied barrier on exit.
void fopenWrite(File &fp, const char *fname) const
open file for writing
void recv(T *data, size_t nData, int src, int tag) const
generic array receive
void send(const T *data, size_t nData, int dest, int tag) const
generic array send
void checkErrors(const ostringstream &) const
collect error messages from all processes; if any, display them and quit
void myRange(T &start, T &stop) const
retrieve range of processes for current task (templated to support other integer types for task range...
Definition: MPIUtil.h:97
void fseek(File fp, long offset, int whence) const
syntax consistent with fseek from stdio
void allReduce(T *data, size_t nData, ReduceOp op, bool safeMode=false) const
generic array reduction
void exit(int errCode) const
global exit (kill other MPI processes as well)
MPI wrapper class.
Definition: MPIUtil.h:33
void bcast(T *data, size_t nData, int root=0) const
generic array broadcast
size_t stop() const
Task number that current process should stop before (non-inclusive)
Definition: MPIUtil.h:93
bool isMine(size_t task) const
Whether current process handle this task number.
Definition: MPIUtil.h:96