OOFEM 3.0
Loading...
Searching...
No Matches
combuff.C
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#include <cstdlib>
36#include <cstring> // for memmove
37
38#include "combuff.h"
39#include "intarray.h"
40#include "floatarray.h"
41#include "floatmatrix.h"
42#include "error.h"
43
44namespace oofem {
45#ifdef __USE_MPI
46MPIBuffer :: MPIBuffer(std::size_t size, bool dynamic)
47{
48 this->size = 0;
49 curr_pos = 0;
50 buff = NULL;
51 isDynamic = dynamic;
52 request = MPI_REQUEST_NULL;
53
54 this->resize(size);
55}
56
57
58MPIBuffer :: MPIBuffer(bool dynamic)
59{
60 this->size = 0;
61 curr_pos = 0;
62 buff = NULL;
63 isDynamic = dynamic;
64 request = MPI_REQUEST_NULL;
65}
66
67#endif
68
69MPIBuffer :: ~MPIBuffer()
70{
71 if ( buff ) {
72 free(buff);
73 }
74}
75
76
77int
78MPIBuffer :: resize(std::size_t newSize)
79{
80 // do not shrink
81 if ( size >= newSize ) {
82 return 1;
83 }
84
85
86 ComBuff_BYTE_TYPE *newBuff;
87
88 if ( newSize > 0 ) {
89 // allocate new memory
90 if ( ( newBuff = ( ComBuff_BYTE_TYPE * )
91 malloc( newSize * sizeof( ComBuff_BYTE_TYPE ) ) ) == NULL ) {
92 // alloc failed -> memory error
93 OOFEM_ERROR("resize failed");
94 }
95
96 // copy old buffer into new one
97 memmove(newBuff, this->buff, curr_pos);
98 } else {
99 newBuff = NULL;
100 }
101
102 // dealocate old buffer
103 if ( this->buff ) {
104 free(this->buff);
105 }
106
107 this->buff = newBuff;
108 size = newSize;
109
110 return 1;
111}
112
113void
114MPIBuffer :: init()
115{
116 curr_pos = 0;
117 request = MPI_REQUEST_NULL;
118}
119
120#ifdef __USE_MPI
121
122int
123MPIBuffer :: packArray(MPI_Comm communicator, const void *src, std::size_t n, MPI_Datatype type)
124{
125 int _size;
126 // ask MPI for packing size for integer
127 _size = this->givePackSize(communicator, type, n);
128
129 if ( ( this->curr_pos + _size > this->size ) ) {
130 // reallocate itself
131 if ( isDynamic ) {
132 if ( this->resize(this->curr_pos + _size + __CommunicationBuffer_ALLOC_CHUNK) == 0 ) {
133 return 0;
134 }
135 } else {
136 OOFEM_WARNING("Resize requested in static mode");
137 return 0;
138 }
139 }
140
141 void *__src = const_cast< void * >(src); // throw away const
142 // MPI_Pack requires int for current position
143 int _currPosInt = static_cast<int>(this->curr_pos);
144 int result = (MPI_Pack(__src, n, type, this->buff, this->size,
145 & _currPosInt, communicator) == MPI_SUCCESS );
146 this->curr_pos = static_cast<std::size_t>(_currPosInt);
147 return result;
148}
149
150int
151MPIBuffer :: unpackArray(MPI_Comm communicator, void *dest, std::size_t n, MPI_Datatype type)
152{
153 // MPI_Pack requires int for current position
154 int _currPosInt = static_cast<int>(this->curr_pos);
155 int result = (MPI_Unpack(this->buff, this->size, & _currPosInt,
156 dest, n, type, communicator) == MPI_SUCCESS );
157 this->curr_pos = static_cast<std::size_t>(_currPosInt);
158 return result;
159}
160
161int
162MPIBuffer :: iSend(MPI_Comm communicator, int dest, int tag)
163{
164 return ( MPI_Isend(this->buff, this->curr_pos, MPI_PACKED, dest, tag,
165 communicator, & this->request) == MPI_SUCCESS );
166}
167
168
169int
170MPIBuffer :: iRecv(MPI_Comm communicator, int source, int tag, std::size_t count)
171{
172 if ( count ) {
173 if ( count >= this->size ) {
174 // reallocate itself
175 if ( this->resize(count) == 0 ) {
176 return 0;
177 }
178 }
179 }
180
181 return ( MPI_Irecv(this->buff, this->size, MPI_PACKED, source, tag,
182 communicator, & this->request) == MPI_SUCCESS );
183}
184
185int
186MPIBuffer :: testCompletion()
187{
188 int flag;
189 MPI_Status status;
190
191 MPI_Test(& this->request, & flag, & status);
192 return flag;
193}
194
195int
196MPIBuffer :: testCompletion(int &source, int &tag)
197{
198 int flag;
199 MPI_Status status;
200
201 MPI_Test(& this->request, & flag, & status);
202
203 source = status.MPI_SOURCE;
204 tag = status.MPI_TAG;
205
206 return flag;
207}
208
209int
210MPIBuffer :: waitCompletion()
211{
212 MPI_Status status;
213
214 return ( MPI_Wait(& this->request, & status) == MPI_SUCCESS );
215}
216
217
218int
219MPIBuffer :: bcast(MPI_Comm communicator, int root)
220{
221 return MPI_Bcast(this->buff, this->size, MPI_PACKED, root, communicator);
222}
223
224
225int
226MPIBuffer :: givePackSize(MPI_Comm communicator, MPI_Datatype type, std::size_t size)
227{
228 int requiredSpace;
229 MPI_Pack_size(size, type, communicator, & requiredSpace);
230 return requiredSpace;
231}
232
233
234void
235MPIBuffer :: dump()
236{
237 for ( int _i = 0; _i < 20; ++_i ) {
238 fprintf(stderr, "%d ", buff [ _i ]);
239 }
240
241 fprintf(stderr, "\n");
242}
243
244#endif
245
246
247/*
248int CommunicationBuffer :: read(int *data, int count)
249{
250
251}
252
253int CommunicationBuffer :: read(unsigned long *data, int count)
254int CommunicationBuffer :: read(long *data, int count)
255int CommunicationBuffer :: read(double *data, int count)
256int CommunicationBuffer :: read(char *data, int count)
257
258int CommunicationBuffer :: write(const int *data, int count)
259int CommunicationBuffer :: write(const unsigned long *data, int count)
260int CommunicationBuffer :: write(const long *data, int count)
261int CommunicationBuffer :: write(const double *data, int count)
262int CommunicationBuffer :: write(const char *data, int count)
263*/
264
265int CommunicationBuffer :: read(bool &data)
266{
267 char val;
268 int ret = this->read(& val, 1);
269 data = val != 0;
270 return ret;
271}
272
273int CommunicationBuffer :: write(bool data)
274{
275 char val = data;
276 return this->write(& val, 1);
277}
278
279int CommunicationBuffer :: givePackSizeOfInt(std::size_t count)
280{
281 int requiredSpace;
282 MPI_Pack_size(count, my_MPI_SIZE_T, communicator, & requiredSpace);
283 return requiredSpace;
284}
285
286int CommunicationBuffer :: givePackSizeOfDouble(std::size_t count)
287{
288 int requiredSpace;
289 MPI_Pack_size(count, MPI_DOUBLE, communicator, & requiredSpace);
290 return requiredSpace;
291}
292
293int CommunicationBuffer :: givePackSizeOfChar(std::size_t count)
294{
295 int requiredSpace;
296 MPI_Pack_size(count, MPI_CHAR, communicator, & requiredSpace);
297 return requiredSpace;
298}
299
300int CommunicationBuffer :: givePackSizeOfBool(std::size_t count)
301{
302 int requiredSpace;
303 MPI_Pack_size(count, MPI_CHAR, communicator, & requiredSpace);
304 return requiredSpace;
305}
306
307int CommunicationBuffer :: givePackSizeOfLong(std::size_t count)
308{
309 int requiredSpace;
310 MPI_Pack_size(count, MPI_LONG, communicator, & requiredSpace);
311 return requiredSpace;
312}
313
314int CommunicationBuffer :: givePackSizeOfSizet(std::size_t count)
315{
316 int requiredSpace;
317 MPI_Pack_size(count, my_MPI_SIZE_T, communicator, & requiredSpace);
318 return requiredSpace;
319}
320
321
322} // end namespace oofem
int write(bool data) override
Writes a bool value.
Definition combuff.C:273
int read(bool &data) override
Reads a bool value from data.
Definition combuff.C:265
ComBuff_BYTE_TYPE * buff
Buffer. Dynamically allocated.
Definition combuff.h:78
std::size_t size
Size and current position in buffer in bytes (sizeof(char)).
Definition combuff.h:74
bool isDynamic
Dynamic flag (if true, buffer can grow, but reallocation is needed).
Definition combuff.h:76
MPI_Request request
Definition combuff.h:84
std::size_t curr_pos
Definition combuff.h:74
int givePackSize(MPI_Comm communicator, MPI_Datatype type, std::size_t size)
Definition combuff.C:226
int resize(std::size_t newSize)
Definition combuff.C:78
#define my_MPI_SIZE_T
Definition combuff.h:48
#define __CommunicationBuffer_ALLOC_CHUNK
Definition combuff.h:63
#define OOFEM_WARNING(...)
Definition error.h:80
#define OOFEM_ERROR(...)
Definition error.h:79
char ComBuff_BYTE_TYPE
Definition combuff.h:68

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