OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
dyncombuff.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 dyncombuff_h
36 #define dyncombuff_h
37 
38 #include "parallel.h"
39 #include "combuff.h"
40 #include <list>
41 
42 namespace oofem {
43 class IntArray;
44 class FloatArray;
45 class FloatMatrix;
46 
47  #define __CommunicationPacket_DEFAULT_SIZE 40960
48 
60 class OOFEM_EXPORT CommunicationPacket : public MPIBuffer
61 {
62 protected:
63  int number;
64  bool EOF_Flag;
65 
66 public:
67 
68  #ifdef __USE_MPI
69  CommunicationPacket(MPI_Comm comm, int size, int num);
72  CommunicationPacket(MPI_Comm comm, int num);
73  #endif
74  virtual ~CommunicationPacket();
76 
80  virtual void init(MPI_Comm comm);
81 
84  #ifdef __USE_MPI
85 
92  int iSend(MPI_Comm communicator, int dest, int tag);
102  int iRecv(MPI_Comm communicator, int source, int tag, int count = 0);
110  virtual int testCompletion();
119  virtual int waitCompletion();
120  #endif
121 
122 
123  void setNumber(int _num) { this->number = _num; }
124  void setEOFFlag() { this->EOF_Flag = true; }
125  int getNumber() { return number; }
126  bool hasEOFFlag() { return EOF_Flag; }
127 
129  int packHeader(MPI_Comm);
130  int unpackHeader(MPI_Comm);
131 };
132 
133 class OOFEM_EXPORT CommunicationPacketPool
134 {
135 private:
136  std :: list< CommunicationPacket * >available_packets;
137  std :: list< CommunicationPacket * >leased_packets;
138 
139  int allocatedPackets, leasedPackets, freePackets;
140 public:
141  CommunicationPacketPool() : available_packets(), leased_packets() {
142  allocatedPackets = leasedPackets = freePackets;
143  }
145  this->clear();
146  }
147 
148  CommunicationPacket *popPacket(MPI_Comm);
149  void pushPacket(CommunicationPacket *);
150 
151  void printInfo();
152 
153 private:
154  void clear();
155 };
156 
157 
159 {
160 protected:
161  std :: list< CommunicationPacket * >packet_list;
163  std :: list< CommunicationPacket * > :: iterator recvIt;
167  int active_tag, active_rank;
169 
171  enum DCB_Mode { DCB_null, DCB_send, DCB_receive } mode;
175  bool completed;
176 public:
178  DynamicCommunicationBuffer(MPI_Comm comm, int size, bool dynamic = 0);
180  DynamicCommunicationBuffer(MPI_Comm comm, bool dynamic = 0);
182  virtual ~DynamicCommunicationBuffer();
183 
184  virtual int resize(int newSize) { return 1; }
185  virtual void init();
186 
188  virtual void initForPacking();
190  virtual void initForUnpacking();
191 
192  virtual int write(const int *src, int n)
193  { return __write(src, n, MPI_INT); }
194  virtual int write(const long *src, int n)
195  { return __write(src, n, MPI_LONG); }
196  virtual int write(const unsigned long *src, int n)
197  { return __write(src, n, MPI_UNSIGNED_LONG); }
198  virtual int write(const double *src, int n)
199  { return __write(src, n, MPI_DOUBLE); }
200  virtual int write(const char *src, int n)
201  { return __write(src, n, MPI_CHAR); }
202 
203  virtual int read(int *dest, int n)
204  { return __read(dest, n, MPI_INT); }
205  virtual int read(long *dest, int n)
206  { return __read(dest, n, MPI_LONG); }
207  virtual int read(unsigned long *dest, int n)
208  { return __read(dest, n, MPI_UNSIGNED_LONG); }
209  virtual int read(double *dest, int n)
210  { return __read(dest, n, MPI_DOUBLE); }
211  virtual int read(char *dest, int n)
212  { return __read(dest, n, MPI_CHAR); }
213 
214 
215  virtual int iSend(int dest, int tag);
216  virtual int iRecv(int source, int tag, int count = 0);
217  virtual int bcast(int root);
218 
226  int testCompletion();
235  virtual int waitCompletion();
236 
237 
238  static void printInfo() { packetPool.printInfo(); }
239 
240 protected:
241  CommunicationPacket *allocateNewPacket(int);
242  void freePacket(CommunicationPacket *);
243 
244  int receiveCompleted();
245  int sendCompleted();
246 
247  void popNewRecvPacket();
248  void pushNewRecvPacket(CommunicationPacket *);
249 
250  void clear();
251  int giveFitSize(MPI_Datatype type, int availableSpace, int arrySize);
252 
258  template< class T > int __write(T *src, int n, MPI_Datatype type) {
259  int _result = 1;
260  int start_indx = 0, end_indx, _size;
261  int remaining_size = n;
262 
263  do {
264  _size = this->giveFitSize(type, active_packet->giveAvailableSpace(), remaining_size);
265  end_indx = start_indx + _size;
266 
267  if ( _size ) {
268  _result &= active_packet->packArray(communicator, src + start_indx, _size, type);
269  }
270 
271  if ( end_indx >= n ) {
272  break;
273  }
274 
275  // active packet full, allocate a new one
276  active_packet = this->allocateNewPacket(++number_of_packets);
277  packet_list.push_back(active_packet);
278  start_indx = end_indx;
279  remaining_size -= _size;
280  } while ( 1 );
281 
282  return _result;
283  }
284 
290  template< class T > int __read(T *dest, int n, MPI_Datatype type) {
291  int _result = 1;
292  int start_indx = 0, end_indx, _size;
293  int remaining_size = n;
294 
295  do {
296  _size = this->giveFitSize(type, active_packet->giveAvailableSpace(), remaining_size);
297  end_indx = start_indx + _size;
298 
299  if ( _size ) {
300  _result &= active_packet->unpackArray(communicator, dest + start_indx, _size, type);
301  }
302 
303  if ( end_indx >= n ) {
304  break;
305  }
306 
307  // active packet exhausted, pop a new one
308  this->popNewRecvPacket();
309  start_indx = end_indx;
310  remaining_size -= _size;
311  } while ( 1 );
312 
313  return _result;
314  }
315 };
316 } // end namespace oofem
317 
318 #endif // dyncombuff_h
virtual int write(const char *src, int n)
Writes count char values from array pointed by data.
Definition: dyncombuff.h:200
virtual int read(long *dest, int n)
Reads count long values into array pointed by data.
Definition: dyncombuff.h:205
CommunicationPacket * active_packet
Active packet.
Definition: dyncombuff.h:165
int packArray(MPI_Comm communicator, const void *src, int n, MPI_Datatype type)
Packs array of a values of given type into buffer.
Definition: combuff.C:123
static CommunicationPacketPool packetPool
Static packet pool.
Definition: dyncombuff.h:173
int __write(T *src, int n, MPI_Datatype type)
Templated low-level array packing method.
Definition: dyncombuff.h:258
virtual int read(int *dest, int n)
Reads count integer values into array pointed by data.
Definition: dyncombuff.h:203
virtual int read(char *dest, int n)
Reads count char values into array pointed by data.
Definition: dyncombuff.h:211
virtual int read(unsigned long *dest, int n)
Reads count unsigned long values into array pointed by data.
Definition: dyncombuff.h:207
int active_tag
Active rank and tag (send by initSend,initReceive, and initExchange).
Definition: dyncombuff.h:167
std::list< CommunicationPacket * >::iterator recvIt
Iterator to iterate over received packets.
Definition: dyncombuff.h:163
bool completed
Communication completion flag.
Definition: dyncombuff.h:175
std::list< CommunicationPacket * > packet_list
Definition: dyncombuff.h:161
Class CommunicationPacket represent a data-packet, that is used to implement dynamic communicator...
Definition: dyncombuff.h:60
Class CommunicationBuffer provides abstraction for communication buffer.
Definition: combuff.h:208
std::list< CommunicationPacket * > available_packets
Definition: dyncombuff.h:136
virtual int write(const unsigned long *src, int n)
Writes count unsigned long values from array pointed by data.
Definition: dyncombuff.h:196
void setNumber(int _num)
Definition: dyncombuff.h:123
virtual int write(const long *src, int n)
Writes count long values from array pointed by data.
Definition: dyncombuff.h:194
virtual int read(double *dest, int n)
Reads count double values into array pointed by data.
Definition: dyncombuff.h:209
virtual int write(const int *src, int n)
Writes count integer values from array pointed by data.
Definition: dyncombuff.h:192
int __read(T *dest, int n, MPI_Datatype type)
Templated low-level array unpacking method.
Definition: dyncombuff.h:290
int unpackArray(MPI_Comm communicator, void *dest, int n, MPI_Datatype type)
Unpacks array of values of given type from buffer.
Definition: combuff.C:147
int giveAvailableSpace()
Definition: combuff.h:92
std::list< CommunicationPacket * > leased_packets
Definition: dyncombuff.h:137
the oofem namespace is to define a context or scope in which all oofem names are defined.
virtual int write(const double *src, int n)
Writes count double values from array pointed by data.
Definition: dyncombuff.h:198
virtual int resize(int newSize)
Resizes buffer to given size.
Definition: dyncombuff.h:184

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:28 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011