UOPstream.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2016-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "UOPstream.H"
30 #include "int.H"
31 #include "token.H"
32 #include <cctype>
33 
34 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 // Return the position with word boundary alignment
40 inline static label byteAlign(const label pos, const size_t align)
41 {
42  return
43  (
44  (align > 1)
45  ? (align + ((pos - 1) & ~(align - 1)))
46  : pos
47  );
48 }
49 
50 } // End namespace Foam
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
55 inline void Foam::UOPstream::prepareBuffer
56 (
57  const size_t count,
58  const size_t align
59 )
60 {
61  if (!count)
62  {
63  return;
64  }
65 
66  // Align for the next output position
67  const label pos = byteAlign(sendBuf_.size(), align);
68 
69  // Extend buffer (as required)
70  sendBuf_.reserve(max(1000, label(pos + count)));
71 
72  // Move to the aligned output position. Fill any gap with nul char.
73  sendBuf_.resize(pos, '\0');
74 }
75 
76 
77 template<class T>
78 inline void Foam::UOPstream::writeToBuffer(const T& val)
79 {
80  writeToBuffer(&val, sizeof(T), sizeof(T));
81 }
82 
83 
84 inline void Foam::UOPstream::writeToBuffer
85 (
86  const void* data,
87  const size_t count,
88  const size_t align
89 )
90 {
91  if (!count)
92  {
93  return;
94  }
95 
96  prepareBuffer(count, align);
97 
98  // The aligned output position
99  const label pos = sendBuf_.size();
100 
101  // Extend the addressable range for direct pointer access
102  sendBuf_.resize(pos + count);
103 
104  char* const __restrict__ buf = (sendBuf_.data() + pos);
105  const char* const __restrict__ input = reinterpret_cast<const char*>(data);
106 
107  for (size_t i = 0; i < count; ++i)
108  {
109  buf[i] = input[i];
110  }
111 }
112 
113 
114 inline void Foam::UOPstream::putChar(const char c)
115 {
116  if (!sendBuf_.capacity())
117  {
118  sendBuf_.setCapacity(1000);
119  }
120  sendBuf_.append(c);
121 }
122 
123 
124 inline void Foam::UOPstream::putString(const std::string& str)
125 {
126  const size_t len = str.size();
127  writeToBuffer(len);
128  writeToBuffer(str.data(), len, 1); // no-op when len == 0
129 }
130 
131 
132 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
133 
135 (
136  const commsTypes commsType,
137  const int toProcNo,
138  DynamicList<char>& sendBuf,
139  const int tag,
140  const label comm,
141  const bool sendAtDestruct,
143 )
144 :
145  UPstream(commsType),
146  Ostream(fmt, IOstreamOption::currentVersion),
147  toProcNo_(toProcNo),
148  sendBuf_(sendBuf),
149  tag_(tag),
150  comm_(comm),
151  sendAtDestruct_(sendAtDestruct)
152 {
153  setOpened();
154  setGood();
155 }
156 
157 
158 Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers)
159 :
160  UPstream(buffers.commsType_),
161  Ostream(buffers.format_, IOstreamOption::currentVersion),
162  toProcNo_(toProcNo),
163  sendBuf_(buffers.sendBuf_[toProcNo]),
164  tag_(buffers.tag_),
165  comm_(buffers.comm_),
166  sendAtDestruct_(buffers.commsType_ != UPstream::commsTypes::nonBlocking)
167 {
169  setGood();
170 }
171 
172 
173 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
174 
176 {
177  if (sendAtDestruct_)
178  {
179  if
180  (
182  (
183  commsType_,
184  toProcNo_,
185  sendBuf_.cdata(),
186  sendBuf_.size(),
187  tag_,
188  comm_
189  )
190  )
191  {
193  << "Failed sending outgoing message of size " << sendBuf_.size()
194  << " to processor " << toProcNo_
196  }
197  }
198 }
199 
200 
201 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
202 
203 bool Foam::UOPstream::write(const token& tok)
204 {
205  // Direct token handling only for some types
206 
207  switch (tok.type())
208  {
209  case token::tokenType::FLAG :
210  {
211  putChar(token::tokenType::FLAG);
212  putChar(tok.flagToken());
213 
214  return true;
215  }
216 
217  // The word-variants
218  case token::tokenType::WORD :
219  case token::tokenType::DIRECTIVE :
220  {
221  putChar(tok.type());
222  putString(tok.wordToken());
223 
224  return true;
225  }
226 
227  // The string-variants
228  case token::tokenType::STRING :
229  case token::tokenType::EXPRESSION :
230  case token::tokenType::VARIABLE :
231  case token::tokenType::VERBATIM :
232  {
233  putChar(tok.type());
234  putString(tok.stringToken());
235 
236  return true;
237  }
238 
239  default:
240  break;
241  }
242 
243  return false;
244 }
245 
246 
248 {
249  if (!isspace(c))
250  {
251  putChar(c);
252  }
253 
254  return *this;
255 }
256 
257 
258 Foam::Ostream& Foam::UOPstream::write(const char* str)
259 {
260  const word nonWhiteChars(string::validate<word>(str));
261 
262  if (nonWhiteChars.size() == 1)
263  {
264  return write(nonWhiteChars[0]);
265  }
266  else if (nonWhiteChars.size())
267  {
268  return write(nonWhiteChars);
269  }
270 
271  return *this;
272 }
273 
274 
275 Foam::Ostream& Foam::UOPstream::write(const word& str)
276 {
277  putChar(token::tokenType::WORD);
278  putString(str);
279 
280  return *this;
281 }
282 
283 
284 Foam::Ostream& Foam::UOPstream::write(const string& str)
285 {
286  putChar(token::tokenType::STRING);
287  putString(str);
288 
289  return *this;
290 }
291 
292 
294 (
295  const std::string& str,
296  const bool quoted
297 )
298 {
299  if (quoted)
300  {
301  putChar(token::tokenType::STRING);
302  }
303  else
304  {
305  putChar(token::tokenType::WORD);
306  }
307  putString(str);
308 
309  return *this;
310 }
311 
312 
313 Foam::Ostream& Foam::UOPstream::write(const int32_t val)
314 {
315  putChar(token::tokenType::LABEL);
316  writeToBuffer(val);
317  return *this;
318 }
319 
320 
321 Foam::Ostream& Foam::UOPstream::write(const int64_t val)
322 {
323  putChar(token::tokenType::LABEL);
324  writeToBuffer(val);
325  return *this;
326 }
327 
328 
330 {
331  putChar(token::tokenType::FLOAT);
332  writeToBuffer(val);
333  return *this;
334 }
335 
336 
338 {
339  putChar(token::tokenType::DOUBLE);
340  writeToBuffer(val);
341  return *this;
342 }
343 
344 
345 Foam::Ostream& Foam::UOPstream::write(const char* data, std::streamsize count)
346 {
347  if (format() != BINARY)
348  {
350  << "stream format not binary"
352  }
353 
354  // Align on word boundary (64-bit)
355  writeToBuffer(data, count, 8);
356 
357  return *this;
358 }
359 
360 
362 (
363  const char* data,
364  std::streamsize count
365 )
366 {
367  // No check for format() == BINARY since this is either done in the
368  // beginRawWrite() method, or the caller knows what they are doing.
369 
370  // Previously aligned and sizes reserved via beginRawWrite()
371  writeToBuffer(data, count, 1);
372 
373  return *this;
374 }
375 
376 
377 bool Foam::UOPstream::beginRawWrite(std::streamsize count)
378 {
379  if (format() != BINARY)
380  {
382  << "stream format not binary"
384  }
385 
386  // Align on word boundary (64-bit)
387  // - as per write(const char*, streamsize)
388  prepareBuffer(count, 8);
389 
390  return true;
391 }
392 
393 
394 void Foam::UOPstream::print(Ostream& os) const
395 {
396  os << "Writing from processor " << toProcNo_
397  << " to processor " << myProcNo() << " in communicator " << comm_
398  << " and tag " << tag_ << Foam::endl;
399 }
400 
401 
402 // ************************************************************************* //
Foam::DynamicList::resize
void resize(const label len)
Definition: DynamicListI.H:346
token.H
Foam::UOPstream::UOPstream
UOPstream(const commsTypes commsType, const int toProcNo, DynamicList< char > &sendBuf, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, const bool sendAtDestruct=true, IOstreamOption::streamFormat fmt=IOstreamOption::BINARY)
Definition: UOPstream.C:128
Foam::doubleScalar
double doubleScalar
Floating-point double precision scalar type.
Definition: scalarFwd.H:48
int.H
System signed integer.
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:63
Foam::UOPstream::write
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Definition: UOPwrite.C:30
Foam::isspace
bool isspace(char c) noexcept
Definition: char.H:71
Foam::DynamicList< char >
Foam::token::stringToken
const string & stringToken() const
Definition: tokenI.H:682
Foam::floatScalar
float floatScalar
Floating-point single precision scalar type.
Definition: scalarFwd.H:43
Foam::UOPstream::print
void print(Ostream &os) const
Definition: UOPstream.C:387
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:84
Foam::IOstreamOption::currentVersion
static const versionNumber currentVersion
Definition: IOstreamOption.H:161
Foam::endl
Ostream & endl(Ostream &os)
Definition: Ostream.H:381
Foam::token
A token holds an item read from Istream.
Definition: token.H:64
Foam::DynamicList::reserve
void reserve(const label len)
Definition: DynamicListI.H:326
Foam::IOstream::setOpened
void setOpened() noexcept
Definition: IOstream.H:125
Foam::IOstream::setGood
void setGood() noexcept
Definition: IOstream.H:143
format
word format(conversionProperties.get< word >("format"))
Foam::byteAlign
static label byteAlign(const label pos, const size_t align)
Definition: UIPstream.C:55
Foam::UPstream
Inter-processor communications stream.
Definition: UPstream.H:57
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:51
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:59
Foam::UOPstream::beginRawWrite
virtual bool beginRawWrite(std::streamsize count)
Definition: UOPstream.C:370
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Definition: hashSets.C:40
Foam::IOstreamOption::streamFormat
streamFormat
Definition: IOstreamOption.H:66
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
Foam
Definition: atmBoundaryLayer.C:26
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Foam::token::wordToken
const word & wordToken() const
Definition: tokenI.H:624
Foam::UPstream::commsTypes
commsTypes
Definition: UPstream.H:65
Foam::token::type
tokenType type() const noexcept
Definition: tokenI.H:304
FatalErrorInFunction
#define FatalErrorInFunction
Definition: error.H:465
UOPstream.H
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Definition: BitOps.H:75
Foam::UOPstream::~UOPstream
~UOPstream()
Definition: UOPstream.C:168
Foam::input
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:48
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Definition: foamVtkOutputTemplates.C:29
Foam::constant::universal::c
const dimensionedScalar c
Foam::UOPstream::writeQuoted
virtual Ostream & writeQuoted(const std::string &str, const bool quoted=true)
Definition: UOPstream.C:287
Foam::token::flagToken
int flagToken() const
Definition: tokenI.H:440
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:52
Foam::UOPstream::writeRaw
virtual Ostream & writeRaw(const char *data, std::streamsize count)
Definition: UOPstream.C:355
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:51
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:170