3 #ifndef DUNE_MPICOLLECTIVECOMMUNICATION_HH
4 #define DUNE_MPICOLLECTIVECOMMUNICATION_HH
35 template<
typename Type,
typename BinaryFunction>
44 op = std::shared_ptr<MPI_Op>(
new MPI_Op);
45 MPI_Op_create((
void (*)(
void*,
void*,
int*, MPI_Datatype*))&operation,
true,op.get());
50 static void operation (Type *in, Type *inout,
int *len, MPI_Datatype*)
54 for (
int i=0; i< *len; ++i, ++in, ++inout) {
56 temp = func(*in, *inout);
61 Generic_MPI_Op (
const Generic_MPI_Op& ) {}
62 static std::shared_ptr<MPI_Op> op;
66 template<
typename Type,
typename BinaryFunction>
67 std::shared_ptr<MPI_Op> Generic_MPI_Op<Type,BinaryFunction>::op = std::shared_ptr<MPI_Op>(
static_cast<MPI_Op*
>(0));
69 #define ComposeMPIOp(type,func,op) \
71 class Generic_MPI_Op<type, func<type> >{ \
73 static MPI_Op get(){ \
78 Generic_MPI_Op (const Generic_MPI_Op & ) {}\
82 ComposeMPIOp(
char, std::plus, MPI_SUM);
83 ComposeMPIOp(
unsigned char, std::plus, MPI_SUM);
84 ComposeMPIOp(
short, std::plus, MPI_SUM);
85 ComposeMPIOp(
unsigned short, std::plus, MPI_SUM);
86 ComposeMPIOp(
int, std::plus, MPI_SUM);
87 ComposeMPIOp(
unsigned int, std::plus, MPI_SUM);
88 ComposeMPIOp(
long, std::plus, MPI_SUM);
89 ComposeMPIOp(
unsigned long, std::plus, MPI_SUM);
90 ComposeMPIOp(
float, std::plus, MPI_SUM);
91 ComposeMPIOp(
double, std::plus, MPI_SUM);
92 ComposeMPIOp(
long double, std::plus, MPI_SUM);
94 ComposeMPIOp(
char, std::multiplies, MPI_PROD);
95 ComposeMPIOp(
unsigned char, std::multiplies, MPI_PROD);
96 ComposeMPIOp(
short, std::multiplies, MPI_PROD);
97 ComposeMPIOp(
unsigned short, std::multiplies, MPI_PROD);
98 ComposeMPIOp(
int, std::multiplies, MPI_PROD);
99 ComposeMPIOp(
unsigned int, std::multiplies, MPI_PROD);
100 ComposeMPIOp(
long, std::multiplies, MPI_PROD);
101 ComposeMPIOp(
unsigned long, std::multiplies, MPI_PROD);
102 ComposeMPIOp(
float, std::multiplies, MPI_PROD);
103 ComposeMPIOp(
double, std::multiplies, MPI_PROD);
104 ComposeMPIOp(
long double, std::multiplies, MPI_PROD);
106 ComposeMPIOp(
char, Min, MPI_MIN);
107 ComposeMPIOp(
unsigned char, Min, MPI_MIN);
108 ComposeMPIOp(
short, Min, MPI_MIN);
109 ComposeMPIOp(
unsigned short, Min, MPI_MIN);
110 ComposeMPIOp(
int, Min, MPI_MIN);
111 ComposeMPIOp(
unsigned int, Min, MPI_MIN);
112 ComposeMPIOp(
long, Min, MPI_MIN);
113 ComposeMPIOp(
unsigned long, Min, MPI_MIN);
114 ComposeMPIOp(
float, Min, MPI_MIN);
115 ComposeMPIOp(
double, Min, MPI_MIN);
116 ComposeMPIOp(
long double, Min, MPI_MIN);
118 ComposeMPIOp(
char, Max, MPI_MAX);
119 ComposeMPIOp(
unsigned char, Max, MPI_MAX);
120 ComposeMPIOp(
short, Max, MPI_MAX);
121 ComposeMPIOp(
unsigned short, Max, MPI_MAX);
122 ComposeMPIOp(
int, Max, MPI_MAX);
123 ComposeMPIOp(
unsigned int, Max, MPI_MAX);
124 ComposeMPIOp(
long, Max, MPI_MAX);
125 ComposeMPIOp(
unsigned long, Max, MPI_MAX);
126 ComposeMPIOp(
float, Max, MPI_MAX);
127 ComposeMPIOp(
double, Max, MPI_MAX);
128 ComposeMPIOp(
long double, Max, MPI_MAX);
142 class CollectiveCommunication<MPI_Comm>
149 if(communicator!=MPI_COMM_NULL) {
151 MPI_Initialized(&initialized);
153 DUNE_THROW(ParallelError,
"You must call MPIHelper::instance(argc,argv) in your main() function before using the MPI CollectiveCommunication!");
154 MPI_Comm_rank(communicator,&me);
155 MPI_Comm_size(communicator,&procs);
176 T
sum (
const T& in)
const
179 allreduce<std::plus<T> >(&in,&out,1);
185 int sum (T* inout,
int len)
const
187 return allreduce<std::plus<T> >(inout,len);
192 T
prod (
const T& in)
const
195 allreduce<std::multiplies<T> >(&in,&out,1);
201 int prod (T* inout,
int len)
const
203 return allreduce<std::multiplies<T> >(inout,len);
208 T
min (
const T& in)
const
211 allreduce<Min<T> >(&in,&out,1);
217 int min (T* inout,
int len)
const
219 return allreduce<Min<T> >(inout,len);
225 T
max (
const T& in)
const
228 allreduce<Max<T> >(&in,&out,1);
234 int max (T* inout,
int len)
const
236 return allreduce<Max<T> >(inout,len);
242 return MPI_Barrier(communicator);
247 int broadcast (T* inout,
int len,
int root)
const
249 return MPI_Bcast(inout,len,MPITraits<T>::getType(),root,communicator);
255 int gather (
const T* in, T* out,
int len,
int root)
const
257 return MPI_Gather(
const_cast<T*
>(in),len,MPITraits<T>::getType(),
258 out,len,MPITraits<T>::getType(),
264 int gatherv (
const T* in,
int sendlen, T* out,
int* recvlen,
int* displ,
int root)
const
266 return MPI_Gatherv(
const_cast<T*
>(in),sendlen,MPITraits<T>::getType(),
267 out,recvlen,displ,MPITraits<T>::getType(),
274 int scatter (
const T* send, T* recv,
int len,
int root)
const
276 return MPI_Scatter(
const_cast<T*
>(send),len,MPITraits<T>::getType(),
277 recv,len,MPITraits<T>::getType(),
283 int scatterv (
const T* send,
int* sendlen,
int* displ, T* recv,
int recvlen,
int root)
const
285 return MPI_Scatterv(
const_cast<T*
>(send),sendlen,displ,MPITraits<T>::getType(),
286 recv,recvlen,MPITraits<T>::getType(),
291 operator MPI_Comm ()
const
297 template<
typename T,
typename T1>
298 int allgather(
const T* sbuf,
int count, T1* rbuf)
const
300 return MPI_Allgather(
const_cast<T*
>(sbuf), count, MPITraits<T>::getType(),
301 rbuf, count, MPITraits<T1>::getType(),
307 int allgatherv (
const T* in,
int sendlen, T* out,
int* recvlen,
int* displ)
const
309 return MPI_Allgatherv(
const_cast<T*
>(in),sendlen,MPITraits<T>::getType(),
310 out,recvlen,displ,MPITraits<T>::getType(),
315 template<
typename BinaryFunction,
typename Type>
316 int allreduce(Type* inout,
int len)
const
318 Type* out =
new Type[len];
319 int ret = allreduce<BinaryFunction>(inout,out,len);
320 std::copy(out, out+len, inout);
326 template<
typename BinaryFunction,
typename Type>
327 int allreduce(
const Type* in, Type* out,
int len)
const
329 return MPI_Allreduce(
const_cast<Type*
>(in), out, len, MPITraits<Type>::getType(),
334 MPI_Comm communicator;