OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
communicator.h
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #ifndef communicator_h
36 #define communicator_h
37 
38 #include "oofemcfg.h"
39 #include "processcomm.h"
40 #include "commbufftype.h"
41 #include "communicatormode.h"
42 #include "error.h"
43 
44 namespace oofem {
45 class EngngModel;
46 
60 class OOFEM_EXPORT CommunicatorBuff
61 {
62 protected:
64  int size;
67 
68 public:
71 
79  if ( i < size ) {
80  return processCommBuffs [ i ];
81  } else {
82  return NULL;
83  }
84  }
85 };
86 
87 
105 class OOFEM_EXPORT Communicator
106 {
107 protected:
109  int rank;
111  int size;
118 
119 public:
129  Communicator(EngngModel * emodel, CommunicatorBuff * buff, int rank, int size, CommunicatorMode mode = CommMode_Static);
131  virtual ~Communicator();
132 
140  if ( i < size ) {
141  return processComms [ i ];
142  } else {
143  return NULL;
144  }
145  }
146 
153  template< class T > int packAllData( T *ptr, int ( T :: *packFunc )( ProcessCommunicator & ) );
161  //template <class T> int packAllData (T* ptr, FloatArray* src, int (T::*packFunc) (FloatArray*, ProcessCommunicator&));
162  template< class T, class P > int packAllData( T *ptr, P *src, int ( T :: *packFunc )( P *, ProcessCommunicator & ) );
170  template< class T > int unpackAllData( T *ptr, int ( T :: *unpackFunc )( ProcessCommunicator & ) );
179  //template <class T> int unpackAllData (T* ptr, FloatArray* dest, int (T::*unpackFunc) (FloatArray*, ProcessCommunicator&));
180  template< class T, class P > int unpackAllData( T *ptr, P *src, int ( T :: *unpackFunc )( P *, ProcessCommunicator & ) );
186  int initExchange(int tag);
193  int initSend(int tag);
200  int initReceive(int tag);
205  int finishExchange();
206 
210  void clearBuffers();
216  virtual void setUpCommunicationMaps(EngngModel *pm) { }
217 
219  std :: string errorInfo(const char *func) const;
220 };
221 
222 template< class T > int
223 Communicator :: packAllData( T *ptr, int ( T :: *packFunc )( ProcessCommunicator & ) )
224 {
225  int i = size, result = 1;
226 
227  if ( size ) {
228  for ( i = 0; i < size; i++ ) {
229  result &= giveProcessCommunicator(i)->packData(ptr, packFunc);
230  }
231  }
232 
233  return result;
234 }
235 
236 /*
237  * template <class T> int
238  * Communicator :: packAllData (T* ptr, FloatArray* src, int (T::*packFunc) (FloatArray*, ProcessCommunicator&))
239  * {
240  * int i = size, result = 1;
241  *
242  * if (size)
243  * for (i=0; i< size; i++) result &= giveProcessCommunicator(i)->packData (ptr, src, packFunc);
244  * return result;
245  * }
246  */
247 template< class T, class P > int
248 Communicator :: packAllData( T *ptr, P *src, int ( T :: *packFunc )( P *, ProcessCommunicator & ) )
249 {
250  int i = size, result = 1;
251 
252  if ( size ) {
253  for ( i = 0; i < size; i++ ) {
254  result &= giveProcessCommunicator(i)->packData(ptr, src, packFunc);
255  }
256  }
257 
258  return result;
259 }
260 
261 template< class T > int
262 Communicator :: unpackAllData( T *ptr, int ( T :: *unpackFunc )( ProcessCommunicator & ) )
263 {
264  int i, received, num_recv = 0, result = 1;
265  IntArray recvFlag(size);
266  //MPI_Status status;
267 
268  for ( i = 0; i < size; i++ ) {
269  // receive if receive map is not empty or mode is dynamic
270  if ( ( giveProcessCommunicator(i)->giveToRecvMap()->giveSize() ) ||
271  ( this->mode == CommMode_Dynamic ) ) {
272  recvFlag.at(i + 1) = 1;
273  num_recv++;
274  }
275  }
276 
277  while ( num_recv-- ) {
278  // wait for any completion
279  while ( 1 ) {
280  received = 0;
281  for ( i = 0; i < size; i++ ) {
282  if ( recvFlag.at(i + 1) ) {
283  //if (giveProcessCommunicator(i)->giveRecvBuff()->testCompletion()) {
284  if ( giveProcessCommunicator(i)->receiveCompleted() ) {
285  #ifdef __VERBOSE_PARALLEL
286  OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
287  rank, "Communicator :: unpackAllData", i);
288  #endif
289 
290  recvFlag.at(i + 1) = 0;
291  result &= giveProcessCommunicator(i)->unpackData(ptr, unpackFunc);
292  received = 1;
293  break;
294  }
295  }
296  }
297 
298  if ( received ) {
299  break;
300  }
301  }
302  }
303 
304  #ifdef __VERBOSE_PARALLEL
305  VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started", rank)
306  #endif
307 
308  MPI_Barrier(MPI_COMM_WORLD);
309 
310  #ifdef __VERBOSE_PARALLEL
311  VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished", rank)
312  #endif
313 
314  return result;
315 }
316 
317 
318 /*
319  * template <class T> int
320  * Communicator :: unpackAllData (T* ptr, FloatArray* dest, int (T::*unpackFunc) (FloatArray*, ProcessCommunicator&))
321  * {
322  * int i, received, num_recv = 0, result = 1;
323  * IntArray recvFlag (size);
324  * //MPI_Status status;
325  *
326  * for (i=0; i<size; i++) {
327  * // receive if receive map is not empty or mode is dynamic
328  * if ((giveProcessCommunicator(i)->giveToRecvMap()->giveSize()) ||
329  * (this->mode == CommMode_Dynamic)) {
330  * recvFlag.at(i+1) = 1;
331  * num_recv ++;
332  * }
333  * }
334  *
335  * while (num_recv--) {
336  *
337  * // wait for any completion
338  * while (1) {
339  * received = 0;
340  * for (i=0; i<size; i++) {
341  * if (recvFlag.at(i+1)) {
342  * //if (giveProcessCommunicator(i)->giveRecvBuff()->testCompletion()) {
343  * if (giveProcessCommunicator(i)->receiveCompleted()) {
344  *
345  *
346  ****#ifdef __VERBOSE_PARALLEL
347  * OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
348  * rank,"Communicator :: unpackAllData", i);
349  ****#endif
350  *
351  * recvFlag.at(i+1) = 0;
352  * result &= giveProcessCommunicator(i)->unpackData (ptr, dest, unpackFunc);
353  * received = 1;
354  * break;
355  * }
356  * }
357  * }
358  * if (received) break;
359  * }
360  * }
361  *
362  ****#ifdef __VERBOSE_PARALLEL
363  * VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started",rank)
364  ****#endif
365  *
366  * MPI_Barrier (MPI_COMM_WORLD);
367  *
368  ****#ifdef __VERBOSE_PARALLEL
369  * VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished",rank)
370  ****#endif
371  *
372  * return result;
373  * }
374  */
375 
376 template< class T, class P > int
377 Communicator :: unpackAllData( T *ptr, P *dest, int ( T :: *unpackFunc )( P *, ProcessCommunicator & ) )
378 {
379  int i, received, num_recv = 0, result = 1;
380  IntArray recvFlag(size);
381  //MPI_Status status;
382 
383  for ( i = 0; i < size; i++ ) {
384  // receive if receive map is not empty or mode is dynamic
385  if ( ( giveProcessCommunicator(i)->giveToRecvMap()->giveSize() ) ||
386  ( this->mode == CommMode_Dynamic ) ) {
387  recvFlag.at(i + 1) = 1;
388  num_recv++;
389  }
390  }
391 
392  while ( num_recv-- ) {
393  // wait for any completion
394  while ( 1 ) {
395  received = 0;
396  for ( i = 0; i < size; i++ ) {
397  if ( recvFlag.at(i + 1) ) {
398  //if (giveProcessCommunicator(i)->giveRecvBuff()->testCompletion()) {
399  if ( giveProcessCommunicator(i)->receiveCompleted() ) {
400  #ifdef __VERBOSE_PARALLEL
401  OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
402  rank, "Communicator :: unpackAllData", i);
403  #endif
404 
405  recvFlag.at(i + 1) = 0;
406  result &= giveProcessCommunicator(i)->unpackData(ptr, dest, unpackFunc);
407  received = 1;
408  break;
409  }
410  }
411  }
412 
413  if ( received ) {
414  break;
415  }
416  }
417  }
418 
419  #ifdef __VERBOSE_PARALLEL
420  VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started", rank)
421  #endif
422 
423  MPI_Barrier(MPI_COMM_WORLD);
424 
425  #ifdef __VERBOSE_PARALLEL
426  VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished", rank)
427  #endif
428 
429  return result;
430 }
431 } // end namespace oofem
432 #endif // communicator_h
ProcessCommunicatorBuff * giveProcessCommunicatorBuff(int i)
Returns i-th process communicator buff.
Definition: communicator.h:78
virtual void setUpCommunicationMaps(EngngModel *pm)
Service for setting up the communication patterns with other remote processes.
Definition: communicator.h:216
int size
Number of processes.
Definition: communicator.h:64
int rank
Rank of process.
Definition: communicator.h:109
int packAllData(T *ptr, int(T::*packFunc)(ProcessCommunicator &))
Pack all problemCommunicators data to their send buffers.
Definition: communicator.h:223
CommBuffType
Definition: commbufftype.h:40
The mode can be static, meaning that each node can assemble its communication maps independently (or ...
The ProcessCommunicator and corresponding buffers (represented by this class) are separated in order ...
Definition: processcomm.h:64
#define OOFEM_LOG_DEBUG(...)
Definition: logger.h:128
Class implementing an array of integers.
Definition: intarray.h:61
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
CommunicatorMode
The communicator mode determines the communication.
CommunicatorMode mode
Mode.
Definition: communicator.h:117
#define VERBOSEPARALLEL_PRINT(service, str, rank)
Definition: parallel.h:50
ProcessCommunicator ** processComms
Array of process communicators.
Definition: communicator.h:113
Class representing process communicator for engineering model.
Definition: processcomm.h:176
EngngModel * engngModel
Engineering model.
Definition: communicator.h:115
(Dynamic) In this case the communication pattern and the amount of data sent between nodes is not kno...
int unpackAllData(T *ptr, int(T::*unpackFunc)(ProcessCommunicator &))
Unpack all problemCommuncators data from recv buffers.
Definition: communicator.h:262
Class representing communicator.
Definition: communicator.h:105
int size
Number of processes.
Definition: communicator.h:111
std::string errorInfo(const char *func)
Definition: error.C:41
ProcessCommunicator * giveProcessCommunicator(int i)
Returns i-th problem communicator.
Definition: communicator.h:139
ProcessCommunicatorBuff ** processCommBuffs
Array of process communicators.
Definition: communicator.h:66
The Communicator and corresponding buffers (represented by this class) are separated in order to allo...
Definition: communicator.h:60
Abstract base class representing the "problem" under consideration.
Definition: engngm.h:181
the oofem namespace is to define a context or scope in which all oofem names are defined.

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:27 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011