MPI_IBcastW.hpp 6.13 KB
Newer Older
incardon's avatar
incardon committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * MPI_IBcastW.hpp
 *
 *  Created on: Apr 8, 2017
 *      Author: i-bird
 */

#ifndef OPENFPM_VCLUSTER_SRC_MPI_WRAPPER_MPI_IBCASTW_HPP_
#define OPENFPM_VCLUSTER_SRC_MPI_WRAPPER_MPI_IBCASTW_HPP_



#include <mpi.h>

incardon's avatar
incardon committed
15
16


incardon's avatar
incardon committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*! \brief Set of wrapping classing for MPI_Irecv
 *
 * The purpose of these classes is to correctly choose the right call based on the type we want to receive
 *
 */

/*! \brief General recv for general buffer
 *
 * \param proc processor from which to receive
 * \param tag
 * \param buf buffer where to store the data
 * \param sz size to receive
 * \param req MPI request
 *
 */

class MPI_IBcastWB
{
public:
incardon's avatar
incardon committed
36
	static inline void bcast(size_t proc ,void * buf, size_t sz, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
37
	{
incardon's avatar
incardon committed
38
		MPI_SAFE_CALL(MPI_Ibcast(buf,sz,MPI_BYTE, proc , ext_comm,&req));
incardon's avatar
incardon committed
39
40
41
42
43
44
45
46
47
48
49
50
	}
};

/*! \brief General recv for vector of
 *
 * \tparam any type
 *
 */

template<typename T> class MPI_IBcastW
{
public:
incardon's avatar
incardon committed
51
	template<typename Memory> static inline void bcast(size_t proc ,openfpm::vector<T,Memory> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
52
	{
incardon's avatar
incardon committed
53
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size() * sizeof(T),MPI_BYTE, proc , ext_comm,&req));
incardon's avatar
incardon committed
54
55
56
57
58
59
60
61
62
63
	}
};


/*! \brief specialization for vector of integer
 *
 */
template<> class MPI_IBcastW<int>
{
public:
incardon's avatar
incardon committed
64
	static inline void bcast(size_t proc ,openfpm::vector<int> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
65
	{
incardon's avatar
incardon committed
66
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_INT, proc , ext_comm,&req));
incardon's avatar
incardon committed
67
68
69
70
71
72
73
74
75
	}
};

/*! \brief specialization for unsigned integer
 *
 */
template<> class MPI_IBcastW<unsigned int>
{
public:
incardon's avatar
incardon committed
76
	static inline void bcast(size_t proc ,openfpm::vector<unsigned int> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
77
	{
incardon's avatar
incardon committed
78
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_UNSIGNED, proc , ext_comm,&req));
incardon's avatar
incardon committed
79
80
81
82
83
84
85
86
87
	}
};

/*! \brief specialization for short
 *
 */
template<> class MPI_IBcastW<short>
{
public:
incardon's avatar
incardon committed
88
	static inline void bcast(size_t proc ,openfpm::vector<short> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
89
	{
incardon's avatar
incardon committed
90
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_SHORT, proc , ext_comm,&req));
incardon's avatar
incardon committed
91
92
93
94
95
96
97
98
99
	}
};

/*! \brief specialization for short
 *
 */
template<> class MPI_IBcastW<unsigned short>
{
public:
incardon's avatar
incardon committed
100
	static inline void bcast(size_t proc ,openfpm::vector<unsigned short> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
101
	{
incardon's avatar
incardon committed
102
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_UNSIGNED_SHORT, proc , ext_comm,&req));
incardon's avatar
incardon committed
103
104
105
106
107
108
109
110
111
	}
};

/*! \brief specialization for char
 *
 */
template<> class MPI_IBcastW<char>
{
public:
incardon's avatar
incardon committed
112
	static inline void bcast(size_t proc ,openfpm::vector<char> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
113
	{
incardon's avatar
incardon committed
114
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_CHAR, proc , ext_comm,&req));
incardon's avatar
incardon committed
115
116
117
118
119
120
121
122
123
	}
};

/*! \brief specialization for char
 *
 */
template<> class MPI_IBcastW<unsigned char>
{
public:
incardon's avatar
incardon committed
124
	static inline void bcast(size_t proc ,openfpm::vector<unsigned char> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
125
	{
incardon's avatar
incardon committed
126
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_UNSIGNED_CHAR, proc , ext_comm,&req));
incardon's avatar
incardon committed
127
128
129
130
131
132
133
134
135
	}
};

/*! \brief specialization for size_t
 *
 */
template<> class MPI_IBcastW<size_t>
{
public:
incardon's avatar
incardon committed
136
	static inline void bcast(size_t proc ,openfpm::vector<size_t> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
137
	{
incardon's avatar
incardon committed
138
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_UNSIGNED_LONG, proc , ext_comm,&req));
incardon's avatar
incardon committed
139
140
141
142
143
144
145
146
147
	}
};

/*! \brief specialization for size_t
 *
 */
template<> class MPI_IBcastW<long int>
{
public:
incardon's avatar
incardon committed
148
	static inline void bcast(size_t proc ,openfpm::vector<long int> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
149
	{
incardon's avatar
incardon committed
150
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_LONG, proc , ext_comm,&req));
incardon's avatar
incardon committed
151
152
153
154
155
156
157
158
159
	}
};

/*! \brief specialization for float
 *
 */
template<> class MPI_IBcastW<float>
{
public:
incardon's avatar
incardon committed
160
	static inline void bcast(size_t proc ,openfpm::vector<float> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
161
	{
incardon's avatar
incardon committed
162
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_FLOAT, proc , ext_comm,&req));
incardon's avatar
incardon committed
163
164
165
166
167
168
169
170
171
	}
};

/*! \brief specialization for double
 *
 */
template<> class MPI_IBcastW<double>
{
public:
incardon's avatar
incardon committed
172
	static inline void bcast(size_t proc ,openfpm::vector<double> & v, MPI_Request & req, MPI_Comm ext_comm)
incardon's avatar
incardon committed
173
	{
incardon's avatar
incardon committed
174
		MPI_SAFE_CALL(MPI_Ibcast(v.getPointer(), v.size(),MPI_DOUBLE, proc , ext_comm,&req));
incardon's avatar
incardon committed
175
176
177
178
	}
};


incardon's avatar
incardon committed
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*! \brief this class is a functor for "for_each" algorithm
 *
 * This class is a functor for "for_each" algorithm. For each
 * element of the boost::vector the operator() is called.
 * Is mainly used to process broadcast request for each buffer
 *
 */
template<typename vect>
struct bcast_inte_impl
{
	//! vector to broadcast
	vect & send;

	//! vector of requests
	openfpm::vector<MPI_Request> & req;

	//! root processor
	size_t root;

incardon's avatar
incardon committed
198
199
200
	//! MPI communicator
	MPI_Comm ext_comm;

incardon's avatar
incardon committed
201
202
203
204
205
206
	/*! \brief constructor
	 *
	 * \param v set of pointer buffers to set
	 *
	 */
	inline bcast_inte_impl(vect & send,
incardon's avatar
incardon committed
207
208
			       openfpm::vector<MPI_Request> & req,
			       size_t root,
incardon's avatar
incardon committed
209
			       MPI_Comm ext_comm)
incardon's avatar
incardon committed
210
	:send(send),req(req),root(root),ext_comm(ext_comm)
incardon's avatar
incardon committed
211
212
213
214
215
216
217
218
219
220
221
222
	{};

	//! It call the copy function for each property
	template<typename T>
	inline void operator()(T& t)
	{
		typedef typename boost::mpl::at<typename vect::value_type::type,T>::type send_type;

		// Create one request
		req.add();

		// gather
incardon's avatar
incardon committed
223
		MPI_IBcastWB::bcast(root,&send.template get<T::value>(0),send.size()*sizeof(send_type),req.last(),ext_comm);
incardon's avatar
incardon committed
224
225
226
227
228
229
230
231
232
	}
};

template<bool is_lin_or_inte>
struct b_cast_helper
{
	 template<typename T, typename Mem, typename lt_type, template<typename> class layout_base >
	 static void bcast_(openfpm::vector<MPI_Request> & req,
			            openfpm::vector<T,Mem,lt_type,layout_base> & v,
incardon's avatar
incardon committed
233
234
			            size_t root,
				    MPI_Comm ext_comm)
incardon's avatar
incardon committed
235
236
237
238
239
	{
		// Create one request
		req.add();

		// gather
incardon's avatar
incardon committed
240
		MPI_IBcastW<T>::bcast(root,v,req.last(),ext_comm);
incardon's avatar
incardon committed
241
242
243
244
245
246
247
248
249
	}
};

template<>
struct b_cast_helper<false>
{
	 template<typename T, typename Mem, typename lt_type, template<typename> class layout_base >
	 static void bcast_(openfpm::vector<MPI_Request> & req,
			            openfpm::vector<T,Mem,lt_type,layout_base> & v,
incardon's avatar
incardon committed
250
251
			            size_t root,
				    MPI_Comm ext_comm)
incardon's avatar
incardon committed
252
	{
incardon's avatar
incardon committed
253
		 bcast_inte_impl<openfpm::vector<T,Mem,lt_type,layout_base>> bc(v,req,root,ext_comm);
incardon's avatar
incardon committed
254
255
256
257
258

		 boost::mpl::for_each_ref<boost::mpl::range_c<int,0,T::max_prop>>(bc);
	}
};

incardon's avatar
incardon committed
259
#endif /* OPENFPM_VCLUSTER_SRC_MPI_WRAPPER_MPI_IBCASTW_HPP_ */