ug4
pcl_util.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-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_UTIL__
34 #define __H__PCL_UTIL__
35 
36 #include <iostream>
37 #include <vector>
38 #include <algorithm>
39 #include <string>
40 #include <functional> // for std::less
41 #include "pcl_layout_util.h"
42 #include "pcl_base.h"
46 
47 #ifdef PCL_DEBUG_BARRIER_ENABLED
50 
52  #define PCL_DEBUG_BARRIER(communicator) communicator.barrier()
53  #define PCL_DEBUG_BARRIER_ALL() {pcl::ProcessCommunicator com; com.barrier();}
54 
55 #else
56  #define PCL_DEBUG_BARRIER(communicator)
57  #define PCL_DEBUG_BARRIER_ALL()
58 #endif
59 
60 namespace pcl
61 {
62 
65 
68 
72 
75 bool AllProcsTrue(bool bFlag, ProcessCommunicator comm = ProcessCommunicator());
76 
79 bool OneProcTrue(bool bFlag, ProcessCommunicator comm = ProcessCommunicator());
80 
83 
98 void CommunicateInvolvedProcesses(std::vector<int>& vReceiveFromRanksOut,
99  const std::vector<int>& vSendToRanks,
100  const ProcessCommunicator& procComm
101  = ProcessCommunicator());
102 
104 
116 template <class TLayout, class TSelector>
117 bool RemoveUnselectedInterfaceEntries(TLayout& layout, TSelector& sel)
118 {
119 // iterate over all interfaces of the layout.
120 // for each we'll create a new one, into which elements selected
121 // elements will be inserted.
122 // Finally we'll swap the content of the those interfaces.
123 // if the interface is empty at the end of the operation, it will be
124 // removed from the layout.
125  bool retVal = false;
126 
127 // some typedefs first
128  typedef typename TLayout::Interface Interface;
129  typedef typename TLayout::iterator InterfaceIter;
130  typedef typename Interface::Element Elem;
131  typedef typename Interface::iterator ElemIter;
132 
133 // iterate over all levels
134  for(size_t level = 0; level < layout.num_levels(); ++level)
135  {
136  // iterate over all interfaces
137  for(InterfaceIter iiter = layout.begin(level);
138  iiter != layout.end(level);)
139  {
140  bool interfaceChanged = false;
141  Interface& interface = layout.interface(iiter);
142 
143  // create a temporary interface and fill it with the selected entries
144  Interface tInterface;
145 
146  for(ElemIter iter = interface.begin();
147  iter != interface.end(); ++iter)
148  {
149  Elem& e = interface.get_element(iter);
150  if(sel.is_selected(e))
151  tInterface.push_back(e);
152  else
153  interfaceChanged = true;
154  }
155 
156  // now swap the interface contents.
157  if(interfaceChanged){
158  interface.swap(tInterface);
159 
160  // if the interface is empty, erase it.
161  // if not, simply increase the iterator
162  if(interface.size() == 0){
163  iiter = layout.erase(iiter, level);
164  }
165  else{
166  ++iiter;
167  }
168 
169  retVal = true;
170  }
171  else{
172  ++iiter;
173  }
174  }
175  }
176 
177  return retVal;
178 }
179 
181 
194 template <class TType, class TLayoutMap, class TSelector>
195 bool RemoveUnselectedInterfaceEntries(TLayoutMap& lm, TSelector& sel)
196 {
197  typedef typename TLayoutMap::template Types<TType>::Map::iterator iterator;
198  typedef typename TLayoutMap::template Types<TType>::Layout Layout;
199 
200  bool retVal = false;
201  for(iterator iter = lm.template layouts_begin<TType>();
202  iter != lm.template layouts_end<TType>();)
203  {
204  // get the layout
205  Layout& layout = iter->second;
206  // remove unnecessary interface entries and interfaces
207  retVal |= RemoveUnselectedInterfaceEntries(layout, sel);
208  // if the layout is empty, it can be removed from the map
209  // if not we'll simply increase the iterator
210  if(layout.empty()){
211  iter = lm.template erase_layout<TType>(iter);
212  }
213  else{
214  ++iter;
215  }
216  }
217  return retVal;
218 }
219 
222 
236 template <class TLayout, class TSelectorIn, class TSelectorOut>
237 class SelectionCommPol : public ICommunicationPolicy<TLayout>
238 {
239  public:
241 
242  public:
243  SelectionCommPol(TSelectorIn& selIn, TSelectorOut& selOut) :
244  m_selIn(selIn), m_selOut(selOut) {}
245 
247  virtual bool
248  collect(ug::BinaryBuffer& buff, Interface& interface)
249  {
250  char zero = 0;
251  char one = 1;
252 
253  for(typename Interface::iterator iter = interface.begin();
254  iter != interface.end(); ++iter)
255  {
256  if(m_selIn.is_selected(interface.get_element(iter)))
257  buff.write(&one, sizeof(char));
258  else
259  buff.write(&zero, sizeof(char));
260  }
261 
262  return true;
263  }
264 
266  virtual bool
267  extract(ug::BinaryBuffer& buff, Interface& interface)
268  {
269  char tmp;
270  for(typename Interface::iterator iter = interface.begin();
271  iter != interface.end(); ++iter)
272  {
273  buff.read(&tmp, sizeof(char));
274  if(tmp == 0)
275  m_selOut.deselect(interface.get_element(iter));
276  else
277  m_selOut.select(interface.get_element(iter));
278  }
279 
280  return true;
281  }
282 
283  protected:
284  TSelectorIn& m_selIn;
285  TSelectorOut& m_selOut;
286 };
287 
288 
290 
293 bool SendRecvListsMatch(const std::vector<int>& recvFrom,
294  const std::vector<int>& sendTo,
295  const ProcessCommunicator& involvedProcs = ProcessCommunicator());
296 
298 
307 bool SendRecvBuffersMatch(const std::vector<int>& recvFrom, const std::vector<int>& recvBufSizes,
308  const std::vector<int>& sendTo, const std::vector<int>& sendBufSizes,
309  const ProcessCommunicator& involvedProcs = ProcessCommunicator());
310 
311 
312 
313 template<typename TLayout>
314 void AddLayout(TLayout &destLayout, const TLayout &sourceLayout)
315 {
316  for(typename TLayout::const_iterator iter = sourceLayout.begin(); iter != sourceLayout.end(); ++iter)
317  {
318  const typename TLayout::Interface &source_interface = sourceLayout.interface(iter);
319  typename TLayout::Interface &dest_interface = destLayout.interface(sourceLayout.proc_id(iter));
320  for(typename TLayout::Interface::const_iterator iter2 = source_interface.begin(); iter2 != source_interface.end(); ++iter2)
321  dest_interface.push_back(source_interface.get_element(iter2));
322  }
323 }
324 
326 
335 bool ParallelReadFile(std::string &filename, std::vector<char> &file, bool bText, bool bDistributedLoad, const ProcessCommunicator& pc = ProcessCommunicator());
336 
337 
354 template <typename TKey, typename TValue, typename Compare>
355 void MinimalKeyValuePairAcrossAllProcs(TKey& keyInOut, TValue& valInOut, const Compare& cmp = Compare());
356 
357 
358 // end group pcl
360 
361 }// end of namespace
362 
363 
364 #include "pcl_util_impl.h"
365 
366 #endif
specializations are responsible to pack and unpack interface data during communication.
Definition: pcl_communication_structs.h:790
Layout::Interface Interface
Definition: pcl_communication_structs.h:793
Definition: pcl_process_communicator.h:70
communicates selection-status of interface elements
Definition: pcl_util.h:238
ICommunicationPolicy< TLayout >::Interface Interface
Definition: pcl_util.h:240
TSelectorIn & m_selIn
Definition: pcl_util.h:284
virtual bool extract(ug::BinaryBuffer &buff, Interface &interface)
iterates over the interface entries. selects for 1, deselects for 0.
Definition: pcl_util.h:267
virtual bool collect(ug::BinaryBuffer &buff, Interface &interface)
iterates over the interface entries. Writes 1 for selected, 0 for unselected.
Definition: pcl_util.h:248
SelectionCommPol(TSelectorIn &selIn, TSelectorOut &selOut)
Definition: pcl_util.h:243
TSelectorOut & m_selOut
Definition: pcl_util.h:285
A Buffer for binary data.
Definition: binary_buffer.h:56
void read(char *buf, size_t size)
reads data of the given size (in bytes)
Definition: binary_buffer_impl.h:58
void write(const char *buf, size_t size)
writes data of the given size (in bytes)
Definition: binary_buffer_impl.h:71
void SynchronizeProcesses()
Definition: pcl_util.cpp:48
void MinimalKeyValuePairAcrossAllProcs(TKey &keyInOut, TValue &valInOut, const Compare &cmp=Compare())
Find minimal key/value pair across processes This function will receive one key/value pair from each ...
Definition: pcl_util_impl.h:40
bool SendRecvListsMatch(const std::vector< int > &recvFromTmp, const std::vector< int > &sendTo, const ProcessCommunicator &involvedProcs)
checks whether proc-entries in send- and recv-lists on participating processes match
Definition: pcl_util.cpp:167
bool OneProcTrue(bool bFlag, ProcessCommunicator comm)
Definition: pcl_util.cpp:74
void AddLayout(TLayout &destLayout, const TLayout &sourceLayout)
Definition: pcl_util.h:314
bool AllProcsTrue(bool bFlag, ProcessCommunicator comm)
Definition: pcl_util.cpp:54
bool RemoveUnselectedInterfaceEntries(TLayout &layout, TSelector &sel)
Definition: pcl_util.h:117
bool SendRecvBuffersMatch(const std::vector< int > &recvFrom, const std::vector< int > &recvBufSizes, const std::vector< int > &sendTo, const std::vector< int > &sendBufSizes, const ProcessCommunicator &involvedProcs)
checks whether matching buffers in send- and recv-lists have the same size
Definition: pcl_util.cpp:230
void CommunicateInvolvedProcesses(std::vector< int > &vReceiveFromRanksOut, const std::vector< int > &vSendToRanks, const ProcessCommunicator &procComm)
exchanges information about which process wants to communicate with which other process.
Definition: pcl_util.cpp:94
Definition: parallel_grid_layout.h:46
bool ParallelReadFile(string &filename, vector< char > &file, bool bText, bool bDistributedLoad, const ProcessCommunicator &pc)
Definition: pcl_util.cpp:301