Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
communication_scheme.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 COMMUNICATION_SCHEME_H_
34#define COMMUNICATION_SCHEME_H_
35
36#include "pcl/pcl.h"
37
38#ifdef UG_PARALLEL
39namespace ug
40{
41
49// CommunicationScheme
50//----------------------
103template<typename TDerived, typename TValue>
105{
106public:
108 TDerived& derived() {
109 return static_cast<TDerived&>(*this);
110 }
111
120 virtual bool
121 collect(ug::BinaryBuffer& buff, const Interface& interface)
122
123 {
124 int pid = interface.get_target_proc();
125 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
126 Serialize(buff, derived().send(pid, interface.get_element(iter)));
127 return true;
128 }
129
130
138 virtual bool
139 extract(ug::BinaryBuffer& buff, const Interface& interface)
140 {
141 int pid = interface.get_target_proc();
142 TValue val;
143 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
144 {
145 Deserialize(buff, val);
146 derived().receive(pid, interface.get_element(iter), val);
147 }
148 return true;
149 }
150
157 virtual int
159 {
160 int s = derived().get_element_size();
161 if(s == -1)
162 return -1;
163 else
164 return s * interface.size();
165 }
166};
167
169
176template<typename TDerived>
177class CommunicationScheme<TDerived, bool> : public pcl::ICommunicationPolicy<IndexLayout>
178{
179public:
180 TDerived& derived() { return static_cast<TDerived&>(*this); }
181
182 virtual bool
183 collect(ug::BinaryBuffer& buff, const Interface& interface)
184 {
185 int pid = interface.get_target_proc();
186 int j=0;
187 char a=0;
188 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
189 {
190 bool b = derived().send(pid, interface.get_element(iter));
191 if(b) a |= (1 << j);
192 j++;
193 if(j == 8)
194 {
195 Serialize(buff, a);
196 a = 0;
197 j = 0;
198 }
199 }
200 if(j) Serialize(buff, a);
201 return true;
202 }
203
204 virtual bool
205 extract(ug::BinaryBuffer& buff, const Interface& interface)
206 {
207 int pid = interface.get_target_proc();
208 int j=8;
209 char a=0;
210 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
211 {
212 size_t index = interface.get_element(iter);
213 if(j==8)
214 {
215 Deserialize(buff, a);
216 j=0;
217 }
218 bool b = a & (1 << j);
219 j++;
220 derived().receive(pid, index, b);
221 }
222 return true;
223 }
224
225 virtual int
227 {
228 return sizeof(char) * (interface.size()/8 + (interface.size()%8==0?0:1) );
229 }
230
231};
232
234
235
236// StdArrayCommunicationScheme
237//------------------------------
250template<typename TArray>
251class StdArrayCommunicationScheme : public CommunicationScheme<StdArrayCommunicationScheme<TArray>,
252 typename TArray::value_type >
253{
254 typedef typename TArray::value_type value_type;
255public:
257 {
258
259 }
260
261 inline const value_type &send(int pid, size_t index) const
262 {
263 return m_arr[index];
264 }
265
266 inline void receive(int pid, size_t index, value_type &v)
267 {
268 m_arr[index] = v;
269 }
270
271 inline int get_element_size() const
272 {
274 else
275 return -1;
276 }
277private:
278 TArray &m_arr;
279};
280
282
291template<typename TCommunicationScheme>
293 const IndexLayout &sendingLayout, const IndexLayout &receivingLayout, TCommunicationScheme &scheme)
294{
295 AMG_PROFILE_FUNC();
296 int i=0;
297
298 for(IndexLayout::const_iterator it = sendingLayout.begin(); it != sendingLayout.end(); ++it, ++i)
299 {
300 BinaryBuffer buff;
301 const IndexLayout::Interface &interface = sendingLayout.interface(it);
302 scheme.collect(buff, interface);
303 // todo: don't use parallelcommunicator send_raw
304 // todo: reserve and reuse buff
305 communicator.send_raw(interface.get_target_proc(), buff.buffer(), buff.write_pos(),
306 scheme.get_required_buffer_size(interface) != -1);
307 }
308
309 int receivingLayoutSize=0;
310 for(IndexLayout::const_iterator it = receivingLayout.begin(); it != receivingLayout.end(); ++it)
311 receivingLayoutSize++;
312
313 stdvector< BinaryBuffer > bufs(receivingLayoutSize);
314 i=0;
315 for(IndexLayout::const_iterator it = receivingLayout.begin(); it != receivingLayout.end(); ++it, ++i)
316 communicator.receive_raw(receivingLayout.proc_id(it), bufs[i],
317 scheme.get_required_buffer_size(receivingLayout.interface(it)));
318
319 communicator.communicate();
320 i=0;
321 for(IndexLayout::const_iterator it = receivingLayout.begin(); it != receivingLayout.end(); ++it, ++i)
322 scheme.extract(bufs[i], receivingLayout.interface(it));
323}
324
325template<typename TCommunicationScheme>
326void CommunicateFromSlaveToMaster(HorizontalAlgebraLayouts &layouts, TCommunicationScheme &scheme)
327{
328 CommunicateOnInterfaces(layouts.proc_comm(), layouts.slave(), layouts.master(), scheme);
329}
330template<typename TCommunicationScheme>
331void CommunicateFromMasterToSlave(HorizontalAlgebraLayouts &layouts, TCommunicationScheme &scheme)
332{
333 CommunicateOnInterfaces(layouts.proc_comm(), layouts.master(), layouts.slave(), scheme);
334}
336
346template<typename TSendingScheme, typename TPIDs>
348 IndexLayout &layout, TSendingScheme &sender)
349{
350 AMG_PROFILE_FUNC();
351
352 for(size_t i=0; i<pids.size(); i++)
353 {
354 int pid = pids[i];
355 IndexLayout::Interface &interface = layout.interface(pid);
356
357 BinaryBuffer buff;
358 sender.collect(buff, interface);
359 // todo: don't use parallelcommunicator send_raw
360 // todo: reserve and reuse buff
361 communicator.send_raw(pid, buff.buffer(), buff.write_pos(),
362 sender.get_required_buffer_size(interface) != -1);
363 }
364 communicator.communicate();
365
366}
367
377template<typename TPIDs, typename TReceiveScheme>
379 IndexLayout &layout, TReceiveScheme &receiver)
380{
381 stdvector< BinaryBuffer > bufs(pids.size());
382 for(size_t i=0; i<pids.size(); i++)
383 communicator.receive_raw(pids[i], bufs[i], receiver.get_required_buffer_size(layout.interface(pids[i])));
384
385 communicator.communicate();
386
387 for(size_t i=0; i<pids.size(); i++)
388 receiver.extract(bufs[i], layout.interface(pids[i]));
389}
390
392
393
394
396
397#if 0
398template<typename TDerived, typename TValue>
399class SparseCommunicationScheme : public pcl::ICommunicationPolicy<IndexLayout>
400{
401public:
403 TDerived& derived() {
404 return static_cast<TDerived&>(*this);
405 }
406
415 virtual bool
416 collect(ug::BinaryBuffer& buff, const Interface& interface)
417
418 {
419 int pid = interface.get_target_proc();
420 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
421 {
422 int index;
423 char a = 0;
424 if(derived().need_send(pid, index))
425 a = 1;
426 Serialize(buff, a);
427 if(a) Serialize(buff, derived().send(pid, index);
428 }
429 }
430
431
439 virtual bool
440 extract(ug::BinaryBuffer& buff, const Interface& interface)
441 {
442 int pid = interface.get_target_proc();
443 TValue val;
444 for(IndexLayout::Interface::const_iterator iter = interface.begin(); iter != interface.end(); ++iter)
445 {
446 char a;
447 Deserialize(buff, a);
448 if(a)
449 {
450 Deserialize(buff, val);
451 derived().receive(pid, interface.get_element(iter), val);
452 }
453 }
454 }
455
462 virtual int
463 get_required_buffer_size(const Interface& interface)
464 {
465 int s = derived().get_element_size();
466 if(s == -1)
467 return -1;
468 else
469 return s * interface.size();
470 }
471};
472#endif
473
474// end group lib_algebra_parallelization_scheme
476
477} // namespace ug
478#endif /* SEND_INTERFACE_H_ */
479
480#endif /* UG_PARALLEL */
parameterString s
specializations are responsible to pack and unpack interface data during communication.
Definition pcl_communication_structs.h:790
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
bool communicate(int tag=749345)
sends and receives the collected data.
Definition pcl_interface_communicator_impl.hpp:409
You may add elements to this interface and iterate over them.
Definition pcl_communication_structs.h:207
iterator end()
Definition pcl_communication_structs.h:293
iterator begin()
Definition pcl_communication_structs.h:292
Element & get_element(iterator iter)
Definition pcl_communication_structs.h:298
int get_target_proc() const
Definition pcl_communication_structs.h:309
size_t size() const
returns the number of elements that are stored in the interface.
Definition pcl_communication_structs.h:306
iterator end(size_t level=0)
returns the iterator to the last interface of the layout.
Definition pcl_communication_structs.h:492
Interface & interface(iterator iter)
returns the interface to the given iterator.
Definition pcl_communication_structs.h:505
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::const_iterator const_iterator
Definition pcl_communication_structs.h:477
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
virtual bool collect(ug::BinaryBuffer &buff, const Interface &interface)
should write data which is associated with the interface elements to the buffer.
Definition communication_scheme.h:183
virtual bool extract(ug::BinaryBuffer &buff, const Interface &interface)
extract data from the buffer and assigns it to the interface-elements.
Definition communication_scheme.h:205
TDerived & derived()
Definition communication_scheme.h:180
virtual int get_required_buffer_size(const Interface &interface)
returns the size of the buffer in bytes, that will be required for interface-communication.
Definition communication_scheme.h:226
CRTP Base class for communications on layout/interfaces.
Definition communication_scheme.h:105
TDerived & derived()
get the derived class
Definition communication_scheme.h:108
virtual int get_required_buffer_size(const Interface &interface)
get the size of the required buffer for an interface
Definition communication_scheme.h:158
virtual bool extract(ug::BinaryBuffer &buff, const Interface &interface)
receive data on the interface and hand it over to TDerived::receive
Definition communication_scheme.h:139
virtual bool collect(ug::BinaryBuffer &buff, const Interface &interface)
send data on the interface based on TDerived::send
Definition communication_scheme.h:121
Holds Interfaces and communicators for horizontal communication.
Definition algebra_layouts.h:48
const pcl::ProcessCommunicator & proc_comm() const
returns process communicator
Definition algebra_layouts.h:68
const IndexLayout & master() const
Definition algebra_layouts.h:61
const IndexLayout & slave() const
Definition algebra_layouts.h:63
Communication Scheme for synchronization of arrays or similar datastructures.
Definition communication_scheme.h:253
StdArrayCommunicationScheme(TArray &t)
Definition communication_scheme.h:256
TArray::value_type value_type
Definition communication_scheme.h:254
int get_element_size() const
Definition communication_scheme.h:271
TArray & m_arr
Definition communication_scheme.h:278
void receive(int pid, size_t index, value_type &v)
Definition communication_scheme.h:266
const value_type & send(int pid, size_t index) const
Definition communication_scheme.h:261
Definition stl_debug.h:45
void SendOnInterfaces(pcl::InterfaceCommunicator< IndexLayout > &communicator, TPIDs &pids, IndexLayout &layout, TSendingScheme &sender)
sends data over a interface based on a CommunicationScheme to a subgroup of processes
Definition communication_scheme.h:347
void CommunicateOnInterfaces(pcl::InterfaceCommunicator< IndexLayout > &communicator, const IndexLayout &sendingLayout, const IndexLayout &receivingLayout, TCommunicationScheme &scheme)
sends data over a CommunicationScheme from a sendingLayout to a receivingLayout
Definition communication_scheme.h:292
void ReceiveOnInterfaces(pcl::InterfaceCommunicator< IndexLayout > &communicator, TPIDs &pids, IndexLayout &layout, TReceiveScheme &receiver)
receives data over a interface based on a CommunicationScheme on a subgroup of processes
Definition communication_scheme.h:378
void CommunicateFromMasterToSlave(HorizontalAlgebraLayouts &layouts, TCommunicationScheme &scheme)
Definition communication_scheme.h:331
void CommunicateFromSlaveToMaster(HorizontalAlgebraLayouts &layouts, TCommunicationScheme &scheme)
Definition communication_scheme.h:326
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
Definition communication_policies.h:58