mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improved parallel transfer of strings
- support send/receive with embedded '\0' characters
This commit is contained in:
@ -120,6 +120,24 @@ void testMapDistribute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print to Perr
|
||||||
|
template<class T>
|
||||||
|
Ostream& perrInfo(const T& data)
|
||||||
|
{
|
||||||
|
Perr<< data;
|
||||||
|
return Perr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Print to Perr
|
||||||
|
template<>
|
||||||
|
Ostream& perrInfo(const string& data)
|
||||||
|
{
|
||||||
|
Perr<< data << " (size: " << data.size() << ")";
|
||||||
|
return Perr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void testTransfer(const T& input)
|
void testTransfer(const T& input)
|
||||||
{
|
{
|
||||||
@ -127,7 +145,8 @@ void testTransfer(const T& input)
|
|||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
Perr<<"test transfer (" << (typeid(T).name()) << "): " << data << nl << endl;
|
Perr<<"test transfer (" << (typeid(T).name()) << "): ";
|
||||||
|
perrInfo(data) << nl << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pstream::myProcNo() != Pstream::masterNo())
|
if (Pstream::myProcNo() != Pstream::masterNo())
|
||||||
@ -141,7 +160,7 @@ void testTransfer(const T& input)
|
|||||||
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
|
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
|
||||||
IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
|
IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
|
||||||
fromMaster >> data;
|
fromMaster >> data;
|
||||||
Perr<< data << endl;
|
perrInfo(data) << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -155,7 +174,7 @@ void testTransfer(const T& input)
|
|||||||
Perr<< "master receiving from slave " << slave << endl;
|
Perr<< "master receiving from slave " << slave << endl;
|
||||||
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
|
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
|
||||||
fromSlave >> data;
|
fromSlave >> data;
|
||||||
Perr<< data << endl;
|
perrInfo(data) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for
|
for
|
||||||
@ -258,6 +277,15 @@ int main(int argc, char *argv[])
|
|||||||
testTransfer(scalar(3.14159));
|
testTransfer(scalar(3.14159));
|
||||||
testTransfer(string("test string"));
|
testTransfer(string("test string"));
|
||||||
testTransfer(string(" x "));
|
testTransfer(string(" x "));
|
||||||
|
|
||||||
|
{
|
||||||
|
// Slightly roundabout way to construct with a nul in string
|
||||||
|
string str1("embedded. nul character in string");
|
||||||
|
str1[8] = '\0';
|
||||||
|
|
||||||
|
Info<< "len: " << str1.size() << endl;
|
||||||
|
testTransfer(str1);
|
||||||
|
}
|
||||||
testTransfer(word("3.141 59")); // bad word, but transfer doesn't care
|
testTransfer(word("3.141 59")); // bad word, but transfer doesn't care
|
||||||
|
|
||||||
testTokenized(label(1234));
|
testTokenized(label(1234));
|
||||||
|
|||||||
@ -42,12 +42,12 @@ inline void Foam::UIPstream::checkEof()
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void Foam::UIPstream::readFromBuffer(T& t)
|
inline void Foam::UIPstream::readFromBuffer(T& val)
|
||||||
{
|
{
|
||||||
const size_t align = sizeof(T);
|
const size_t align = sizeof(T);
|
||||||
externalBufPosition_ = align + ((externalBufPosition_ - 1) & ~(align - 1));
|
externalBufPosition_ = align + ((externalBufPosition_ - 1) & ~(align - 1));
|
||||||
|
|
||||||
t = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
|
val = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
|
||||||
externalBufPosition_ += sizeof(T);
|
externalBufPosition_ += sizeof(T);
|
||||||
checkEof();
|
checkEof();
|
||||||
}
|
}
|
||||||
@ -67,10 +67,14 @@ inline void Foam::UIPstream::readFromBuffer
|
|||||||
+ ((externalBufPosition_ - 1) & ~(align - 1));
|
+ ((externalBufPosition_ - 1) & ~(align - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* bufPtr = &externalBuf_[externalBufPosition_];
|
const char* const __restrict__ buf = &externalBuf_[externalBufPosition_];
|
||||||
char* dataPtr = reinterpret_cast<char*>(data);
|
char* const __restrict__ output = reinterpret_cast<char*>(data);
|
||||||
size_t i = count;
|
|
||||||
while (i--) *dataPtr++ = *bufPtr++;
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
output[i] = buf[i];
|
||||||
|
}
|
||||||
|
|
||||||
externalBufPosition_ += count;
|
externalBufPosition_ += count;
|
||||||
checkEof();
|
checkEof();
|
||||||
}
|
}
|
||||||
@ -78,14 +82,15 @@ inline void Foam::UIPstream::readFromBuffer
|
|||||||
|
|
||||||
inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str)
|
inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str)
|
||||||
{
|
{
|
||||||
|
// Use std::string::assign() to copy content, including '\0'.
|
||||||
|
// Stripping (when desired) is the responsibility of the sending side.
|
||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
readFromBuffer(len);
|
readFromBuffer(len);
|
||||||
// Uses the underlying std::string::operator=()
|
|
||||||
// - no stripInvalid invoked (the sending side should have done that)
|
str.assign(&externalBuf_[externalBufPosition_], len);
|
||||||
// - relies on trailing '\0' char (so cannot send anything with an embedded
|
|
||||||
// nul char)
|
externalBufPosition_ += len;
|
||||||
str = &externalBuf_[externalBufPosition_];
|
|
||||||
externalBufPosition_ += len + 1;
|
|
||||||
checkEof();
|
checkEof();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -276,7 +281,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
|||||||
Foam::Istream& Foam::UIPstream::read(char& c)
|
Foam::Istream& Foam::UIPstream::read(char& c)
|
||||||
{
|
{
|
||||||
c = externalBuf_[externalBufPosition_];
|
c = externalBuf_[externalBufPosition_];
|
||||||
externalBufPosition_++;
|
++externalBufPosition_;
|
||||||
checkEof();
|
checkEof();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ class UIPstream
|
|||||||
|
|
||||||
//- Read a T from the transfer buffer
|
//- Read a T from the transfer buffer
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void readFromBuffer(T& t);
|
inline void readFromBuffer(T& val);
|
||||||
|
|
||||||
//- Read count bytes of data from the transfer buffer
|
//- Read count bytes of data from the transfer buffer
|
||||||
// using align byte alignment
|
// using align byte alignment
|
||||||
|
|||||||
@ -109,7 +109,7 @@ inline void Foam::UOPstream::writeStringToBuffer(const std::string& str)
|
|||||||
{
|
{
|
||||||
const size_t len = str.size();
|
const size_t len = str.size();
|
||||||
writeToBuffer(len);
|
writeToBuffer(len);
|
||||||
writeToBuffer(str.c_str(), len + 1, 1);
|
writeToBuffer(str.data(), len, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user