ug4
pcl_process_communicator_impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3  * Author: Sebastian Reiter
4  *
5  * This file is part of UG4.
6  *
7  * UG4 is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License version 3 (as published by the
9  * Free Software Foundation) with the following additional attribution
10  * requirements (according to LGPL/GPL v3 §7):
11  *
12  * (1) The following notice must be displayed in the Appropriate Legal Notices
13  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14  *
15  * (2) The following notice must be displayed at a prominent place in the
16  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17  *
18  * (3) The following bibliography is recommended for citation and must be
19  * preserved in all covered files:
20  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21  * parallel geometric multigrid solver on hierarchically distributed grids.
22  * Computing and visualization in science 16, 4 (2013), 151-164"
23  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24  * flexible software system for simulating pde based models on high performance
25  * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  */
32 
33 #ifndef __H__PCL__pcl_process_communicator_impl__
34 #define __H__PCL__pcl_process_communicator_impl__
35 
37 
38 namespace pcl
39 {
40 
41 template<class TValue>
43 gatherv(std::vector<TValue>& recBufOut,
44  std::vector<TValue>& sendBuf, int root,
45  std::vector<int>* pSizesOut, std::vector<int>* pOffsetsOut) const
46 {
47  if(is_local()) return;
48  using namespace ug;
49 
50 //todo: One could declare a special MPI_Datatype and could thus
51 // directly work on pSizesOut and pOffsetsOut.
52  std::vector<int> sizes(this->size(), 0);
53  std::vector<int> offsets(this->size(), 0);
54 
55 // gather the sizes on root. Note that we send the actual data
56 // in bytes later on.
57  int localSize = (int)sendBuf.size() * sizeof(TValue);
58  gather(&localSize, 1, PCL_DT_INT, GetDataPtr(sizes),
59  1, PCL_DT_INT, root);
60 
61  int totalSize = 0;
62  for(size_t i = 0; i < sizes.size(); ++i){
63  offsets[i] = totalSize;
64  totalSize += sizes[i];
65  }
66 
67  // root now knows all sizes. We can now gather the connections on root.
68  recBufOut.resize(totalSize / sizeof(TValue));
69  gatherv(GetDataPtr(sendBuf),
70  localSize,
72  GetDataPtr(recBufOut),
73  GetDataPtr(sizes),
74  GetDataPtr(offsets),
76  root);
77 
78 // send is complete now. If pSizesOut or pOffsetsOut was specified, we
79 // fill them now.
80 //todo: if sizes and offsets would contain the actual number of entries
81 // instead of bytes, this step could be skipped (see above).
82  if(pSizesOut){
83  std::vector<int>& sizesOut = *pSizesOut;
84  sizesOut.resize(sizes.size());
85  for(size_t i = 0; i < sizes.size(); ++i)
86  sizesOut[i] = sizes[i] / sizeof(TValue);
87  }
88 
89  if(pOffsetsOut){
90  std::vector<int>& offsetsOut = *pOffsetsOut;
91  offsetsOut.resize(offsets.size());
92  for(size_t i = 0; i < offsets.size(); ++i)
93  offsetsOut[i] = offsets[i] / sizeof(TValue);
94  }
95 }
96 
97 template<class TValue>
99 allgatherv(std::vector<TValue>& recBufOut,
100  std::vector<TValue>& sendBuf,
101  std::vector<int>* pSizesOut,
102  std::vector<int>* pOffsetsOut) const
103 {
104  if(is_local()) {
105  recBufOut.resize (sendBuf.size());
106  for(size_t i = 0; i < sendBuf.size(); ++i){
107  recBufOut[i] = sendBuf[i];
108  }
109  if(pSizesOut){
110  pSizesOut->resize (1);
111  pSizesOut->at(0) = sendBuf.size();
112  }
113  if(pOffsetsOut){
114  pOffsetsOut->resize (1);
115  pOffsetsOut->at(0) = 0;
116  }
117  return;
118  }
119  using namespace ug;
120 
121 //todo: One could declare a special MPI_Datatype and could thus
122 // directly work on pSizesOut and pOffsetsOut.
123  std::vector<int> sizes(this->size(), 0);
124  std::vector<int> offsets(this->size(), 0);
125 
126 // gather the sizes on root. Note that we send the actual data
127 // in bytes later on.
128  int localSize = (int)sendBuf.size() * sizeof(TValue);
129  allgather(&localSize, 1, PCL_DT_INT, &sizes.front(),
130  1, PCL_DT_INT);
131 
132  int totalSize = 0;
133  for(size_t i = 0; i < sizes.size(); ++i){
134  offsets[i] = totalSize;
135  totalSize += sizes[i];
136  }
137 
138  if(totalSize == 0){
139  recBufOut.resize(0);
140  if(pSizesOut)
141  pSizesOut->resize (0);
142  if(pOffsetsOut)
143  pOffsetsOut->resize (0);
144  return;
145  }
146 
147  // all procs now know all sizes. We can now gather the connections.
148  recBufOut.resize(totalSize / sizeof(TValue));
149  allgatherv(GetDataPtr(sendBuf), localSize, PCL_DT_BYTE,
150  GetDataPtr(recBufOut), GetDataPtr(sizes),
151  GetDataPtr(offsets), PCL_DT_BYTE);
152 
153 // send is complete now. If pSizesOut or pOffsetsOut was specified, we
154 // fill them now.
155 //todo: if sizes and offsets would contain the actual number of entries
156 // instead of bytes, this step could be skipped (see above).
157  if(pSizesOut){
158  std::vector<int>& sizesOut = *pSizesOut;
159  sizesOut.resize(sizes.size());
160  for(size_t i = 0; i < sizes.size(); ++i)
161  sizesOut[i] = sizes[i] / sizeof(TValue);
162  }
163 
164  if(pOffsetsOut){
165  std::vector<int>& offsetsOut = *pOffsetsOut;
166  offsetsOut.resize(offsets.size());
167  for(size_t i = 0; i < offsets.size(); ++i)
168  offsetsOut[i] = offsets[i] / sizeof(TValue);
169  }
170 }
171 
172 
173 template<typename T>
175 reduce(const T &t, pcl::ReduceOperation op, int rootProc) const
176 {
177  T ret;
178  reduce(&t, &ret, 1, DataTypeTraits<T>::get_data_type(), op, rootProc);
179  return ret;
180 }
181 
182 template<typename T>
184 reduce(const T *pSendBuff, T *pReceiveBuff, size_t count,
185  pcl::ReduceOperation op, int rootProc) const
186 {
187  reduce(pSendBuff, pReceiveBuff, count, DataTypeTraits<T>::get_data_type(),
188  op, rootProc);
189 }
190 
191 template<typename T>
193 reduce(const std::vector<T> &send, std::vector<T> &receive,
194  pcl::ReduceOperation op, int rootProc) const
195 {
196  if(send.size() > 0){
197  receive.resize(send.size());
198  reduce(&send[0], &receive[0], send.size(), op, rootProc);
199  }
200 }
201 
202 
203 template<typename T>
205 allreduce(const T &t, pcl::ReduceOperation op) const
206 {
207  T ret;
208  allreduce(&t, &ret, 1, DataTypeTraits<T>::get_data_type(), op);
209  return ret;
210 }
211 
212 
213 template<typename T>
215 allreduce(const T *pSendBuff, T *pReceiveBuff, size_t count, pcl::ReduceOperation op) const
216 {
217  allreduce(pSendBuff, pReceiveBuff, count, DataTypeTraits<T>::get_data_type(), op);
218 }
219 
220 template<typename T>
222 allreduce(const std::vector<T> &send, std::vector<T> &receive,
223  pcl::ReduceOperation op) const
224 {
225  if(send.size() > 0){
226  receive.resize(send.size());
227  allreduce(&send[0], &receive[0], send.size(), op);
228  }
229 }
230 
231 
232 
233 template<typename T>
235 broadcast(T &t, int root) const
236 {
237  broadcast(t, root, typename DataTypeTraits<T>::supported());
238 }
239 
240 
241 template<typename T>
243 broadcast(T &t, int root, DataTypeDirectlySupported d) const
244 {
246 }
247 
248 template<typename T>
250 broadcast(T &t, int root, DataTypeIndirectlySupported d) const
251 {
252  ug::BinaryBuffer buf;
253  if(pcl::ProcRank() == root)
254  {
255  Serialize(buf, t);
256  broadcast(buf, root);
257  }
258  else
259  {
260  broadcast(buf, root);
261  Deserialize(buf, t);
262  }
263 }
264 
265 
266 template<typename T>
268 broadcast(T *p, size_t size, int root) const
269 {
271 }
272 
273 }// end of namespace
274 
275 #endif
parameterString p
Definition: pcl_datatype.h:63
Definition: pcl_datatype.h:64
Definition: pcl_datatype.h:68
bool is_local() const
return true if the communicator is local, simulating current proc is the only proc
Definition: pcl_process_communicator.h:83
void reduce(const void *sendBuf, void *recBuf, int count, DataType type, ReduceOperation op, int rootProc) const
performs MPI_Reduce on the processes of the communicator.
Definition: pcl_process_communicator.cpp:296
void gather(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int recCount, DataType recType, int root) const
performs MPI_Gather on the processes of the communicator.
Definition: pcl_process_communicator.cpp:339
void gatherv(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int *recCounts, int *displs, DataType recType, int root) const
performs MPI_Gatherv on the processes of the communicator.
Definition: pcl_process_communicator.cpp:406
void allreduce(const void *sendBuf, void *recBuf, int count, DataType type, ReduceOperation op) const
performs MPI_Allreduce on the processes of the communicator.
Definition: pcl_process_communicator.cpp:318
size_t size() const
returns the size of the communicator
Definition: pcl_process_communicator.cpp:71
void broadcast(void *v, size_t size, DataType type, int root=0) const
Definition: pcl_process_communicator.cpp:685
void allgatherv(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int *recCounts, int *displs, DataType recType) const
performs MPI_Allgatherv on the processes of the communicator.
Definition: pcl_process_communicator.cpp:443
void allgather(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int recCount, DataType recType) const
performs MPI_Allgather on the processes of the communicator.
Definition: pcl_process_communicator.cpp:421
A Buffer for binary data.
Definition: binary_buffer.h:56
int ProcRank()
returns the rank of the process
Definition: pcl_base.cpp:83
MPI_Op ReduceOperation
Definition: pcl_methods.h:74
#define PCL_DT_BYTE
Definition: pcl_datatype.h:47
#define PCL_DT_INT
Definition: pcl_datatype.h:51
T * GetDataPtr(std::vector< T > &v)
Returns a pointer to the array which is managed by the std::vector.
Definition: vector_util.h:51
Definition: parallel_grid_layout.h:46
the ug namespace
void Deserialize(TIStream &buf, ParallelVector< T > &v)
Deerialize for ParallelVector<T>
Definition: restart_bridge.cpp:112
void Serialize(TOStream &buf, const ParallelVector< T > &v)
Serialize for ParallelVector<T>
Definition: restart_bridge.cpp:103