OOFEM 3.0
Loading...
Searching...
No Matches
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 - 2025 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 <cstdint>
39#include "oofemenv.h"
40#include "processcomm.h"
41#include "commbufftype.h"
42#include "communicatormode.h"
43#include "error.h"
44
45namespace oofem {
46class EngngModel;
47
62{
63protected:
65 std::vector<ProcessCommunicatorBuff> processCommBuffs;
66
67public:
69
77 return &this->processCommBuffs[i];
78 }
79};
80
81
100{
101protected:
103 int rank;
105 std::vector<ProcessCommunicator> processComms;
110
111public:
123 virtual ~Communicator() {}
124
132 return &this->processComms[i];
133 }
134
141 template< class T > int packAllData( T *ptr, int ( T :: *packFunc )( ProcessCommunicator & ) );
149 //template <class T> int packAllData (T* ptr, FloatArray* src, int (T::*packFunc) (FloatArray*, ProcessCommunicator&));
150 template< class T, class P > int packAllData( T *ptr, P *src, int ( T :: *packFunc )( P *, ProcessCommunicator & ) );
158 template< class T > int unpackAllData( T *ptr, int ( T :: *unpackFunc )( ProcessCommunicator & ) );
167 //template <class T> int unpackAllData (T* ptr, FloatArray* dest, int (T::*unpackFunc) (FloatArray*, ProcessCommunicator&));
168 template< class T, class P > int unpackAllData( T *ptr, P *src, int ( T :: *unpackFunc )( P *, ProcessCommunicator & ) );
174 int initExchange(int tag);
181 int initSend(int tag);
188 int initReceive(int tag);
193 int finishExchange();
194
198 void clearBuffers();
204 virtual void setUpCommunicationMaps(EngngModel *pm) { }
205
207 std :: string errorInfo(const char *func) const;
208};
209
210template< class T > int
211Communicator :: packAllData( T *ptr, int ( T :: *packFunc )( ProcessCommunicator & ) )
212{
213 int result = 1;
214
215 for ( auto &pc : processComms ) {
216 result &= pc.packData(ptr, packFunc);
217 }
218
219 return result;
220}
221
222#if 0
223template <class T> int
224Communicator :: packAllData (T* ptr, FloatArray* src, int (T::*packFunc) (FloatArray*, ProcessCommunicator&))
225{
226 int result = 1;
227
228 for ( auto &pc : processComms ) result &= pc.packData (ptr, src, packFunc);
229 return result;
230}
231#endif
232
233template< class T, class P > int
234Communicator :: packAllData( T *ptr, P *src, int ( T :: *packFunc )( P *, ProcessCommunicator & ) )
235{
236 int result = 1;
237
238 for ( auto &pc : this->processComms ) {
239 result &= pc.packData(ptr, src, packFunc);
240 }
241
242 return result;
243}
244
245template< class T > int
246Communicator :: unpackAllData( T *ptr, int ( T :: *unpackFunc )( ProcessCommunicator & ) )
247{
248 int num_recv = 0, result = 1, size = processComms.size();
249 IntArray recvFlag(size);
250 //MPI_Status status;
251
252 for ( int i = 0; i < size; i++ ) {
253 // receive if receive map is not empty or mode is dynamic
254 if ( processComms[i].giveToRecvMap().giveSize() || this->mode == CommMode_Dynamic ) {
255 recvFlag[i] = 1;
256 num_recv++;
257 }
258 }
259
260 while ( num_recv-- ) {
261 // wait for any completion
262 while ( 1 ) {
263 bool received = false;
264 for ( int i = 0; i < size; i++ ) {
265 if ( recvFlag[i] ) {
266 //if ( processComms[i].giveRecvBuff()->testCompletion() ) {
267 if ( processComms[i].receiveCompleted() ) {
268 #ifdef __VERBOSE_PARALLEL
269 OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
270 rank, "Communicator :: unpackAllData", i);
271 #endif
272
273 recvFlag[i] = 0;
274 result &= processComms[i].unpackData(ptr, unpackFunc);
275 received = true;
276 break;
277 }
278 }
279 }
280
281 if ( received ) {
282 break;
283 }
284 }
285 }
286
287 #ifdef __VERBOSE_PARALLEL
288 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started", rank)
289 #endif
290
291 MPI_Barrier(MPI_COMM_WORLD);
292
293 #ifdef __VERBOSE_PARALLEL
294 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished", rank)
295 #endif
296
297 return result;
298}
299
300
301#if 0
302template <class T> int
303Communicator :: unpackAllData (T* ptr, FloatArray* dest, int (T::*unpackFunc) (FloatArray*, ProcessCommunicator&))
304{
305 int num_recv = 0, result = 1, size = processComms.size();
306 IntArray recvFlag(size);
307 //MPI_Status status;
308
309 for ( int i = 0; i < size; i++) {
310 // receive if receive map is not empty or mode is dynamic
311 if ( processComms[i].giveToRecvMap()->giveSize() || this->mode == CommMode_Dynamic) {
312 recvFlag[i] = 1;
313 num_recv ++;
314 }
315 }
316
317 while (num_recv--) {
318 // wait for any completion
319 while (1) {
320 bool received = false;
321 for ( int i = 0; i < size; i++ ) {
322 if ( recvFlag[i] ) {
323 //if ( processComms[i].giveRecvBuff()->testCompletion() ) {
324 if ( processComms[i].receiveCompleted() ) {
325
326#ifdef __VERBOSE_PARALLEL
327 OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
328 rank,"Communicator :: unpackAllData", i);
329#endif
330
331 recvFlag[i] = 0;
332 result &= processComms[i].unpackData (ptr, dest, unpackFunc);
333 received = true;
334 break;
335 }
336 }
337 }
338 if (received) break;
339 }
340 }
341
342#ifdef __VERBOSE_PARALLEL
343 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started",rank)
344#endif
345
346 MPI_Barrier (MPI_COMM_WORLD);
347
348#ifdef __VERBOSE_PARALLEL
349 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished",rank)
350#endif
351
352 return result;
353}
354#endif
355
356template< class T, class P > int
357Communicator :: unpackAllData( T *ptr, P *dest, int ( T :: *unpackFunc )( P *, ProcessCommunicator & ) )
358{
359 int num_recv = 0, result = 1, size = processComms.size();
360 IntArray recvFlag(size);
361 //MPI_Status status;
362
363 for ( int i = 0; i < size; i++ ) {
364 // receive if receive map is not empty or mode is dynamic
365 if ( processComms[i].giveToRecvMap().giveSize() || this->mode == CommMode_Dynamic ) {
366 recvFlag[i] = 1;
367 num_recv++;
368 }
369 }
370
371 while ( num_recv-- ) {
372 // wait for any completion
373 while ( 1 ) {
374 bool received = false;
375 for ( int i = 0; i < size; i++ ) {
376 if ( recvFlag[i] ) {
377 //if ( processComms[i].giveRecvBuff()->testCompletion() ) {
378 if ( processComms[i].receiveCompleted() ) {
379 #ifdef __VERBOSE_PARALLEL
380 OOFEM_LOG_DEBUG("[process rank %3d]: %-30s: Received data from partition %3d\n",
381 rank, "Communicator :: unpackAllData", i);
382 #endif
383
384 recvFlag[i] = 0;
385 result &= processComms[i].unpackData(ptr, dest, unpackFunc);
386 received = true;
387 break;
388 }
389 }
390 }
391
392 if ( received ) {
393 break;
394 }
395 }
396 }
397
398 #ifdef __VERBOSE_PARALLEL
399 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier started", rank)
400 #endif
401
402 MPI_Barrier(MPI_COMM_WORLD);
403
404 #ifdef __VERBOSE_PARALLEL
405 VERBOSEPARALLEL_PRINT("Communicator :: unpackAllData", "Synchronize barrier finished", rank)
406 #endif
407
408 return result;
409}
410} // end namespace oofem
411#endif // communicator_h
ProcessCommunicatorBuff * giveProcessCommunicatorBuff(int i)
CommunicatorBuff(int s, CommBuffType t=CBT_static)
std::vector< ProcessCommunicatorBuff > processCommBuffs
Array of process communicators.
int rank
Rank of process.
EngngModel * engngModel
Engineering model.
CommunicatorMode mode
Mode.
std::vector< ProcessCommunicator > processComms
Array of process communicators.
ProcessCommunicator * giveProcessCommunicator(int i)
Communicator(EngngModel *emodel, CommunicatorBuff *buff, int rank, int size, CommunicatorMode mode=CommMode_Static)
virtual void setUpCommunicationMaps(EngngModel *pm)
virtual ~Communicator()
Destructor.
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
std::string errorInfo(const char *func)
Definition error.C:47
@ CBT_static
#define OOFEM_EXPORT
Definition oofemcfg.h:7
#define VERBOSEPARALLEL_PRINT(service, str, rank)
Definition parallel.h:50

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011