ug4
new_layout_creator.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015: G-CSC, Goethe University Frankfurt
3  * Author: Martin Rupp
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__LIB_ALGEBRA__PARALLELIZATION__NEW_LAYOUT_CREATOR_H_
34 #define __H__LIB_ALGEBRA__PARALLELIZATION__NEW_LAYOUT_CREATOR_H_
35 
36 namespace ug
37 {
38 
40 {
41 private:
42  void create_mark_map(IndexLayout &masterLayout)
43  {
44  PROFILE_FUNC();
45  UG_DLOG(LIB_ALG_MATRIX, 4, "\n\nGenerateOverlapClass::CreateMarks\n");
46  notified.clear();
47  for(IndexLayout::iterator iter = masterLayout.begin(); iter != masterLayout.end(); ++iter)
48  {
49  IndexLayout::Interface &interface = masterLayout.interface(iter);
50  int pid = masterLayout.proc_id(iter);
51 
52  std::set<size_t> &mark = notified[pid];
53  for(IndexLayout::Interface::iterator iter2 = interface.begin(); iter2 != interface.end(); ++iter2)
54  {
55  size_t localIndex = interface.get_element(iter2);
56  mark.insert(localIndex);
57  }
58  }
59  }
61  {
63  NewSlaveNotification(const AlgebraID &_id, int _newSlaveOnPID)
64  {
65  id = _id;
66  newSlaveOnPID = _newSlaveOnPID;
67  }
68  friend std::ostream &operator << (std::ostream &out, const NewSlaveNotification &n)
69  {
70  out << "notification that node " << n.id << " is slave on " << n.newSlaveOnPID << " ";
71  return out;
72  }
75  };
76 
77 private:
78  typedef std::map<int, BinaryBuffer> BufferMap;
79 
81  std::set<int> masterPIDs;
82  std::set<int> slavePIDs;
83 
85 
87 
105  std::map<int, std::set<size_t> > notified; // notified[pid] is the set of indices which are slave on pid.
106  std::map<int, std::vector<NewSlaveNotification> > newSlaveNotifications; // newSlaveNotifications is a vector of pids
107  std::map<int, std::set<size_t> > newMasters;
108  std::map<int, std::set<size_t> > newSlaves;
109 
110 public:
111 
112  NewLayoutCreator(ParallelNodes &_PN, IndexLayout &masterLayout, IndexLayout &slaveLayout)
113  : PN(_PN)
114  {
115  for(IndexLayout::iterator it = slaveLayout.begin(); it != slaveLayout.end(); ++it)
116  slavePIDs.insert(slaveLayout.proc_id(it));
117  for(IndexLayout::iterator it = masterLayout.begin(); it != masterLayout.end(); ++it)
118  masterPIDs.insert(masterLayout.proc_id(it));
119  create_mark_map(masterLayout);
120  }
121  size_t create_slave_node(const AlgebraID &globalID, int distanceToMasterOrInner)
122  {
123  bool bCreated;
124  size_t localIndex = PN.get_local_index_or_create_new(globalID, distanceToMasterOrInner, bCreated);
125 
126  if(bCreated)
127  {
128  newSlaves[globalID.master_proc()].insert(localIndex);
129  UG_DLOG(LIB_ALG_MATRIX, 4, "created new slave with GID " << globalID << " with local index " << localIndex << " and distanceToMasterOrInner=" << distanceToMasterOrInner << "\n");
130  }
131  return localIndex;
132  }
133 
135 
136  void create_node(const AlgebraID &globalID, int pid)
137  {
138  create_node(globalID, PN.global_to_local(globalID), pid);
139  }
140 
141  void create_node(size_t localIndex, int pid)
142  {
143  create_node(PN.local_to_global(localIndex), localIndex, pid);
144  }
145 
146 
147  void create_node(const AlgebraID &globalID, size_t localIndex, int pid)
148  {
149  if(globalID.master_proc() == pid) // obviously the owner knows that his node is on his processor
150  return;
151 
152  if(notified[pid].find(localIndex) != notified[pid].end())
153  {
154  UG_DLOG(LIB_ALG_MATRIX, 4, " not sending notification because already send one\n");
155  return;
156  }
157 
158  /*IF_DEBUG(LIB_ALG_MATRIX, 4)
159  {
160  newNodesOn[pid].insert(globalID);
161  }*/
162 
163  notified[pid].insert(localIndex);
164 
165  if(globalID.master_proc() == pcl::ProcRank())
166  {
167  // add i to mNewLayout[pid] if not already in some interface to pid.
168 
169  // only add nodes once to interface
170  UG_DLOG(LIB_ALG_MATRIX, 4, " adding node " << localIndex << " to master interface to processor " << pid << "\n");
171  newMasters[pid].insert(localIndex);
172  }
173  else
174  {
175  // prepare to send a notification to owner of (globalColIndex.master_proc()) that globalColIndex has a copy on pid if not already done so
176 
177  NewSlaveNotification notification(globalID, pid);
178  UG_DLOG(LIB_ALG_MATRIX, 4, "sending " << globalID.master_proc() << " " << notification << "\n");
179  newSlaveNotifications[globalID.master_proc()].push_back(notification);
180  }
181  }
182 
183  /*void check_new_nodes(pcl::InterfaceCommunicator<IndexLayout> &communicator,
184  IndexLayout &sendingLayout, IndexLayout &receivingLayout)
185  {
186  std::set<int> sendingPIDs;
187  for(IndexLayout::iterator it = sendingLayout.begin(); it != sendingLayout.end(); ++it)
188  sendingPIDs.insert(sendingLayout.proc_id(it));
189 
190  std::set<int> receivingPIDs;
191  for(IndexLayout::iterator it = receivingLayout.begin(); it != receivingLayout.end(); ++it)
192  receivingPIDs.insert(receivingLayout.proc_id(it));
193  check_new_nodes(commnunicator, sendingPIDs, receivingPIDs);
194  }
195 
196  void check_new_nodes(std::vector<int> sendingPIDs, std::vector<int> receivingPIDs)
197  {
198  for(size_t i=0; i<sendingPIDs.size(); i++)
199  {
200  BinaryBuffer buf;
201  int pid = sendingPIDs[i];
202  Serialize(buf, newNodesOn[pid]);
203  communicator.send_raw(pid, buf.buffer(), buf.write_pos(), false);
204  }
205 
206  for(size_t i=0; i<receivingPIDs.size(); i++)
207  communicator.receive_raw(pid, newNodesBufferMap[receivingPIDs[i]]);
208 
209  communicator.communicate();
210  }*/
211 
213  {
214  UG_DLOG(LIB_ALG_MATRIX, 4, "NewLayoutCreator::issue\n");
215  // notifications for new Master Nodes
216  for(std::set<int>::iterator it = slavePIDs.begin(); it != slavePIDs.end(); ++it)
217  {
218  BinaryBuffer buf;
219  int pid = *it;
220  for(size_t i=0; i<newSlaveNotifications[pid].size(); i++)
221  Serialize(buf, newSlaveNotifications[pid][i]);
222  UG_DLOG(LIB_ALG_MATRIX, 4, " sending " << newSlaveNotifications[pid].size() << " notifications to processor " << pid << " (" << buf.write_pos() << " bytes)\n");
223  communicator.send_raw(pid, buf.buffer(), buf.write_pos(), false);
224  }
225  newSlaveNotifications.clear();
226 
227  for(std::set<int>::iterator it = masterPIDs.begin(); it != masterPIDs.end(); ++it)
228  {
229  int pid = *it;
230  UG_DLOG(LIB_ALG_MATRIX, 4, " issue receive from processor " << pid << "\n");
231  communicator.receive_raw(pid, notificationBufferMap[pid]);
232  }
233  }
234 
235  void process()
236  {
237  UG_DLOG(LIB_ALG_MATRIX, 4, "NewLayoutCreator::process\n");
238  for(std::set<int>::iterator it = masterPIDs.begin(); it != masterPIDs.end(); ++it)
239  {
240  int pid = *it;
242  UG_DLOG(LIB_ALG_MATRIX, 4, "received " << buf.write_pos() << " bytes of notification from pid " << pid << ":\n");
243  while(!buf.eof())
244  {
245  NewSlaveNotification notification;
246  Deserialize(buf, notification);
247  UG_ASSERT(notification.id.master_proc() == pcl::ProcRank(), notification.id << ", pid = " << pcl::ProcRank());
248  UG_DLOG(LIB_ALG_MATRIX, 4, notification << "\n");
249 
250  std::set<size_t> &mark = notified[notification.newSlaveOnPID];
251  if(mark.find(notification.id.index_on_master()) == mark.end())
252  {
253  newMasters[notification.newSlaveOnPID].insert(notification.id.index_on_master());
254  mark.insert(notification.id.index_on_master());
255  }
256 
257  }
258  }
259 
260  /*for(BufferMap::iterator it = newNodesBufferMap.begin(); it != newNodesBufferMap.end(); ++it)
261  {
262  int pid = it->first;
263  BinaryBuffer &buf = it->second;
264  std::set<AlgebraID> newNodes;
265  Deserialize(buf, newNodes);
266  bool bCreated;
267  for(std::set<AlgebraID>::iterator it = newNodes.begin(); it != newNodes.end(); ++it)
268  {
269  AlgebraID &globalID = (*it);
270  int localIndex = PN.get_local_index_or_create_new(globalID, distanceToMasterOrInner, bCreated);
271  if(bCreated)
272  newSlaves[pid].insert(localIndex);
273  }
274  }*/
275  }
276 
277  void add_new_layouts_to(IndexLayout &newMasterLayout, IndexLayout &newSlaveLayout)
278  {
279  PN.insert_into_layout_sorted(newMasters, newMasterLayout);
280  PN.insert_into_layout_sorted(newSlaves, newSlaveLayout);
281  for(std::map<int, std::set<size_t> >::iterator it = newMasters.begin(); it != newMasters.end(); ++it)
282  masterPIDs.insert(it->first);
283  for(std::map<int, std::set<size_t> >::iterator it = newSlaves.begin(); it != newSlaves.end(); ++it)
284  slavePIDs.insert(it->first);
285  newMasters.clear();
286  newSlaves.clear();
287  }
288 };
289 
290 }
291 
292 #endif /* NEW_LAYOUT_CREATOR_H_ */
Performs communication between interfaces on different processes.
Definition: pcl_interface_communicator.h:68
void send_raw(int targetProc, const void *pBuff, int bufferSize, bool bSizeKnownAtTarget=false)
sends raw data to a target-proc.
Definition: pcl_interface_communicator_impl.hpp:61
void receive_raw(int srcProc, ug::BinaryBuffer &bufOut, int bufSize=-1)
registers a binary-stream to receive data from a source-proc.
Definition: pcl_interface_communicator_impl.hpp:166
You may add elements to this interface and iterate over them.
Definition: pcl_communication_structs.h:207
iterator end(size_t level=0)
returns the iterator to the last interface of the layout.
Definition: pcl_communication_structs.h:492
iterator begin(size_t level=0)
returns the iterator to the first interface of the layout.
Definition: pcl_communication_structs.h:486
int proc_id(iterator iter) const
returns the target process of the interface given in iterator
Definition: pcl_communication_structs.h:509
InterfaceMap::iterator iterator
An iterator that allows to iterate over the interfaces stored in the layout.
Definition: pcl_communication_structs.h:476
A Buffer for binary data.
Definition: binary_buffer.h:56
char * buffer()
returns the raw buffer pointer or NULL if the buffer is empty (capacity() == 0)
Definition: binary_buffer_impl.h:94
size_t write_pos() const
returns the current write-pos (in bytes)
Definition: binary_buffer_impl.h:53
bool eof()
returns true if the read-position reached the write-position
Definition: binary_buffer_impl.h:99
Definition: new_layout_creator.h:40
std::set< int > slavePIDs
Definition: new_layout_creator.h:82
std::set< int > masterPIDs
Definition: new_layout_creator.h:81
NewLayoutCreator(ParallelNodes &_PN, IndexLayout &masterLayout, IndexLayout &slaveLayout)
Definition: new_layout_creator.h:112
ParallelNodes & PN
Definition: new_layout_creator.h:80
std::map< int, std::set< size_t > > newSlaves
Definition: new_layout_creator.h:108
void create_node(const AlgebraID &globalID, int pid)
Definition: new_layout_creator.h:136
std::map< int, BinaryBuffer > BufferMap
Definition: new_layout_creator.h:78
void create_node(const AlgebraID &globalID, size_t localIndex, int pid)
Definition: new_layout_creator.h:147
std::map< int, std::set< size_t > > notified
map for marking nodes
Definition: new_layout_creator.h:105
void create_mark_map(IndexLayout &masterLayout)
Definition: new_layout_creator.h:42
size_t create_slave_node(const AlgebraID &globalID, int distanceToMasterOrInner)
Definition: new_layout_creator.h:121
void add_new_layouts_to(IndexLayout &newMasterLayout, IndexLayout &newSlaveLayout)
Definition: new_layout_creator.h:277
void issue(pcl::InterfaceCommunicator< IndexLayout > &communicator)
Definition: new_layout_creator.h:212
void process()
Definition: new_layout_creator.h:235
std::map< int, std::vector< NewSlaveNotification > > newSlaveNotifications
Definition: new_layout_creator.h:106
BufferMap notificationBufferMap
Definition: new_layout_creator.h:84
void create_node(size_t localIndex, int pid)
Definition: new_layout_creator.h:141
std::map< int, std::set< size_t > > newMasters
Definition: new_layout_creator.h:107
Definition: parallel_nodes.h:112
const AlgebraID & local_to_global(size_t i) const
Definition: parallel_nodes.h:278
void insert_into_layout_sorted(std::map< int, std::set< size_t > > &m, IndexLayout &layout)
size_t get_local_index_or_create_new(const AlgebraID &globalIndex, int distanceToMasterOrInner, bool &bCreated)
get_index_or_create_new: returns a local index by creating and saving a new one or returning an old
Definition: parallel_nodes.cpp:107
size_t global_to_local(const AlgebraID &globalIndex) const
Definition: parallel_nodes.cpp:141
int ProcRank()
returns the rank of the process
Definition: pcl_base.cpp:83
#define UG_ASSERT(expr, msg)
Definition: assert.h:70
#define UG_DLOG(__debugID__, level, msg)
Definition: log.h:298
DebugID LIB_ALG_MATRIX
Definition: debug_id.h:130
the ug namespace
IndexLayout::Interface::iterator find(IndexLayout::Interface &interface, size_t i)
Definition: parallel_index_layout.h:77
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
#define PROFILE_FUNC()
Definition: profiler.h:257
this type is used to identify distributed objects.
Definition: algebra_id.h:46
int master_proc() const
Definition: algebra_id.h:54
size_t index_on_master() const
Definition: algebra_id.h:55
Definition: new_layout_creator.h:61
int newSlaveOnPID
Definition: new_layout_creator.h:74
friend std::ostream & operator<<(std::ostream &out, const NewSlaveNotification &n)
Definition: new_layout_creator.h:68
NewSlaveNotification(const AlgebraID &_id, int _newSlaveOnPID)
Definition: new_layout_creator.h:63
NewSlaveNotification()
Definition: new_layout_creator.h:62
AlgebraID id
Definition: new_layout_creator.h:73