diff --git a/applications/test/parallel/Test-parallel.C b/applications/test/parallel/Test-parallel.C index 62d6150ce4..9b10ae6107 100644 --- a/applications/test/parallel/Test-parallel.C +++ b/applications/test/parallel/Test-parallel.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -42,154 +42,235 @@ Description using namespace Foam; + +void testMapDistribute() +{ + Random rndGen(43544*Pstream::myProcNo()); + + // Generate random data. + List>> complexData(100); + forAll(complexData, i) + { + complexData[i].first() = rndGen.integer(0, Pstream::nProcs()-1); + complexData[i].second().setSize(3); + complexData[i].second()[0] = 1; + complexData[i].second()[1] = 2; + complexData[i].second()[2] = 3; + } + + // Send all ones to processor indicated by .first() + + // Count how many to send + labelList nSend(Pstream::nProcs(), 0); + forAll(complexData, i) + { + label procI = complexData[i].first(); + nSend[procI]++; + } + + // Collect items to be sent + labelListList sendMap(Pstream::nProcs()); + forAll(sendMap, procI) + { + sendMap[procI].setSize(nSend[procI]); + } + nSend = 0; + forAll(complexData, i) + { + label procI = complexData[i].first(); + sendMap[procI][nSend[procI]++] = i; + } + + // Sync how many to send + labelList nRecv; + Pstream::exchangeSizes(sendMap, nRecv); + + // Collect items to be received + labelListList recvMap(Pstream::nProcs()); + forAll(recvMap, procI) + { + recvMap[procI].setSize(nRecv[procI]); + } + + label constructSize = 0; + // Construct with my own elements first + forAll(recvMap[Pstream::myProcNo()], i) + { + recvMap[Pstream::myProcNo()][i] = constructSize++; + } + // Construct from other processors + forAll(recvMap, procI) + { + if (procI != Pstream::myProcNo()) + { + forAll(recvMap[procI], i) + { + recvMap[procI][i] = constructSize++; + } + } + } + + // Construct distribute map (destructively) + mapDistribute map(constructSize, sendMap.xfer(), recvMap.xfer()); + + // Distribute complexData + map.distribute(complexData); + + Pout<< "complexData:" << complexData << endl; +} + + +template +void testTransfer(const T& input) +{ + T data = input; + + if (Pstream::master()) + { + Perr<<"test transfer (" << (typeid(T).name()) << "): " << data << nl << endl; + } + + if (Pstream::myProcNo() != Pstream::masterNo()) + { + { + Perr<< "slave sending to master " << Pstream::masterNo() << endl; + OPstream toMaster(Pstream::blocking, Pstream::masterNo()); + toMaster << data; + } + + Perr<< "slave receiving from master " << Pstream::masterNo() << endl; + IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); + fromMaster >> data; + Perr<< data << endl; + } + else + { + for + ( + int slave = Pstream::firstSlave(); + slave <= Pstream::lastSlave(); + ++slave + ) + { + Perr<< "master receiving from slave " << slave << endl; + IPstream fromSlave(Pstream::blocking, slave); + fromSlave >> data; + Perr<< data << endl; + } + + for + ( + int slave = Pstream::firstSlave(); + slave <= Pstream::lastSlave(); + ++slave + ) + { + Perr<< "master sending to slave " << slave << endl; + OPstream toSlave(Pstream::blocking, slave); + toSlave << data; + } + } +} + + +template +void testTokenized(const T& data) +{ + token tok; + + if (Pstream::master()) + { + Perr<<"test tokenized \"" << data << "\"" << nl << endl; + } + + if (Pstream::myProcNo() != Pstream::masterNo()) + { + { + Perr<< "slave sending to master " << Pstream::masterNo() << endl; + OPstream toMaster(Pstream::blocking, Pstream::masterNo()); + toMaster << data; + } + + Perr<< "slave receiving from master " << Pstream::masterNo() << endl; + IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); + + fromMaster >> tok; + Perr<< tok.info() << endl; + } + else + { + for + ( + int slave = Pstream::firstSlave(); + slave <= Pstream::lastSlave(); + ++slave + ) + { + Perr<< "master receiving from slave " << slave << endl; + IPstream fromSlave(Pstream::blocking, slave); + fromSlave >> tok; + Perr<< tok.info() << endl; + } + + for + ( + int slave = Pstream::firstSlave(); + slave <= Pstream::lastSlave(); + ++slave + ) + { + Perr<< "master sending to slave " << slave << endl; + OPstream toSlave(Pstream::blocking, slave); + toSlave << data; + } + } +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { - #include "setRootCase.H" #include "createTime.H" + testMapDistribute(); - // Test mapDistribute - // ~~~~~~~~~~~~~~~~~~ - - if (true) + if (!Pstream::parRun()) { - Random rndGen(43544*Pstream::myProcNo()); - - // Generate random data. - List>> complexData(100); - forAll(complexData, i) - { - complexData[i].first() = rndGen.integer(0, Pstream::nProcs()-1); - complexData[i].second().setSize(3); - complexData[i].second()[0] = 1; - complexData[i].second()[1] = 2; - complexData[i].second()[2] = 3; - } - - // Send all ones to processor indicated by .first() - - - // Count how many to send - labelList nSend(Pstream::nProcs(), 0); - forAll(complexData, i) - { - label procI = complexData[i].first(); - nSend[procI]++; - } - - // Collect items to be sent - labelListList sendMap(Pstream::nProcs()); - forAll(sendMap, procI) - { - sendMap[procI].setSize(nSend[procI]); - } - nSend = 0; - forAll(complexData, i) - { - label procI = complexData[i].first(); - sendMap[procI][nSend[procI]++] = i; - } - - // Sync how many to send - labelList nRecv; - Pstream::exchangeSizes(sendMap, nRecv); - - // Collect items to be received - labelListList recvMap(Pstream::nProcs()); - forAll(recvMap, procI) - { - recvMap[procI].setSize(nRecv[procI]); - } - - label constructSize = 0; - // Construct with my own elements first - forAll(recvMap[Pstream::myProcNo()], i) - { - recvMap[Pstream::myProcNo()][i] = constructSize++; - } - // Construct from other processors - forAll(recvMap, procI) - { - if (procI != Pstream::myProcNo()) - { - forAll(recvMap[procI], i) - { - recvMap[procI][i] = constructSize++; - } - } - } - - - - // Construct distribute map (destructively) - mapDistribute map(constructSize, sendMap.xfer(), recvMap.xfer()); - - // Distribute complexData - map.distribute(complexData); - - Pout<< "complexData:" << complexData << endl; + Info<< "\nWarning: not parallel - skipping further tests\n" << endl; + return 0; } + Info<< "\nStarting transfers\n\n" << endl; -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + testTransfer(vector(0, 1, 2)); + testTransfer(label(1234)); + testTransfer(scalar(3.14159)); + testTransfer(string("test string")); + testTransfer(string(" x ")); + testTransfer(word("3.141 59")); // bad word, but transfer doesn't care - Perr<< "\nStarting transfers\n" << endl; + testTokenized(label(1234)); + testTokenized(scalar(3.14159)); + testTokenized('a'); + testTokenized('$'); // will not tokenize well - vector data(0, 1, 2); + testTokenized(string("test string1")); + testTokenized("test string1"); + testTokenized(word("3.141 59")); // bad word, but transfer doesn't care - if (Pstream::parRun()) - { - if (Pstream::myProcNo() != Pstream::masterNo()) - { - { - Perr<< "slave sending to master " - << Pstream::masterNo() << endl; - OPstream toMaster(Pstream::blocking, Pstream::masterNo()); - toMaster << data; - } + testTokenized(string(" a ")); + testTokenized(" a "); - Perr<< "slave receiving from master " - << Pstream::masterNo() << endl; - IPstream fromMaster(Pstream::blocking, Pstream::masterNo()); - fromMaster >> data; + testTokenized(string(" $ ")); + testTokenized(" $ "); // reduces to 'char' and will not tokenize well - Perr<< data << endl; - } - else - { - for - ( - int slave=Pstream::firstSlave(); - slave<=Pstream::lastSlave(); - slave++ - ) - { - Perr << "master receiving from slave " << slave << endl; - IPstream fromSlave(Pstream::blocking, slave); - fromSlave >> data; + testTokenized(string(" $$ ")); + testTokenized(" $$ "); // reduces to 'word' and is tagged as such - Perr<< data << endl; - } - - for - ( - int slave=Pstream::firstSlave(); - slave<=Pstream::lastSlave(); - slave++ - ) - { - Perr << "master sending to slave " << slave << endl; - OPstream toSlave(Pstream::blocking, slave); - toSlave << data; - } - } - } Info<< "End\n" << endl; - return 0; } diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C index 0671d69eca..1b1738d1ad 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -194,7 +194,7 @@ Foam::Ostream& Foam::UOPstream::write(const char* str) if (nonWhiteChars.size() == 1) { - return write(nonWhiteChars.c_str()[1]); + return write(nonWhiteChars[0]); } else if (nonWhiteChars.size()) {