mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-Pstream-updates' into 'develop'
Pstream performance and handling improvements See merge request Development/openfoam!528
This commit is contained in:
@ -3,12 +3,14 @@ phaseSystem = $(LIB_SRC)/phaseSystemModels/multiphaseInter
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I${phaseSystem}/phasesSystem/lnInclude \
|
-I${phaseSystem}/phasesSystem/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude
|
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
|
-lfileFormats \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
-llagrangian \
|
-llagrangian \
|
||||||
-lradiationModels \
|
-lradiationModels \
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2017-2020 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,11 +31,12 @@ License
|
|||||||
#include "absorptionEmissionModel.H"
|
#include "absorptionEmissionModel.H"
|
||||||
#include "scatterModel.H"
|
#include "scatterModel.H"
|
||||||
#include "constants.H"
|
#include "constants.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "unitConversion.H"
|
#include "unitConversion.H"
|
||||||
#include "interpolationCell.H"
|
#include "interpolationCell.H"
|
||||||
#include "interpolationCellPoint.H"
|
#include "interpolationCellPoint.H"
|
||||||
#include "Random.H"
|
#include "Random.H"
|
||||||
|
#include "OBJstream.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
using namespace Foam::constant;
|
using namespace Foam::constant;
|
||||||
|
|
||||||
@ -679,44 +680,28 @@ void Foam::radiation::laserDTRM::calculate()
|
|||||||
Info<< "Final number of particles..."
|
Info<< "Final number of particles..."
|
||||||
<< returnReduce(DTRMCloud_.size(), sumOp<label>()) << endl;
|
<< returnReduce(DTRMCloud_.size(), sumOp<label>()) << endl;
|
||||||
|
|
||||||
OFstream osRef(type() + ":particlePath.obj");
|
pointField lines(2*DTRMCloud_.size());
|
||||||
label vertI = 0;
|
{
|
||||||
|
label i = 0;
|
||||||
List<pointField> positions(Pstream::nProcs());
|
|
||||||
List<pointField> p0(Pstream::nProcs());
|
|
||||||
|
|
||||||
DynamicList<point> positionsMyProc;
|
|
||||||
DynamicList<point> p0MyProc;
|
|
||||||
|
|
||||||
for (const DTRMParticle& p : DTRMCloud_)
|
for (const DTRMParticle& p : DTRMCloud_)
|
||||||
{
|
{
|
||||||
positionsMyProc.append(p.position());
|
lines[i] = p.position();
|
||||||
p0MyProc.append(p.p0());
|
lines[i+1] = p.p0();
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
positions[Pstream::myProcNo()].transfer(positionsMyProc);
|
globalIndex::gatherInplaceOp(lines);
|
||||||
p0[Pstream::myProcNo()].transfer(p0MyProc);
|
|
||||||
|
|
||||||
Pstream::gatherList(positions);
|
if (Pstream::master())
|
||||||
Pstream::scatterList(positions);
|
|
||||||
Pstream::gatherList(p0);
|
|
||||||
Pstream::scatterList(p0);
|
|
||||||
|
|
||||||
for (const int proci : Pstream::allProcs())
|
|
||||||
{
|
{
|
||||||
const pointField& pos = positions[proci];
|
OBJstream os(type() + ":particlePath.obj");
|
||||||
const pointField& pfinal = p0[proci];
|
|
||||||
forAll(pos, i)
|
|
||||||
{
|
|
||||||
meshTools::writeOBJ(osRef, pos[i]);
|
|
||||||
vertI++;
|
|
||||||
meshTools::writeOBJ(osRef, pfinal[i]);
|
|
||||||
vertI++;
|
|
||||||
osRef << "l " << vertI-1 << ' ' << vertI << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
osRef.flush();
|
for (label pointi = 0; pointi < lines.size(); pointi += 2)
|
||||||
|
{
|
||||||
|
os.write(linePointRef(lines[pointi], lines[pointi+1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scalar totalQ = gSum(Q_.primitiveFieldRef()*mesh_.V());
|
scalar totalQ = gSum(Q_.primitiveFieldRef()*mesh_.V());
|
||||||
Info << "Total energy absorbed [W]: " << totalQ << endl;
|
Info << "Total energy absorbed [W]: " << totalQ << endl;
|
||||||
|
|||||||
3
applications/test/parallel-broadcast/Make/files
Normal file
3
applications/test/parallel-broadcast/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-parallel-broadcast.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-parallel-broadcast
|
||||||
2
applications/test/parallel-broadcast/Make/options
Normal file
2
applications/test/parallel-broadcast/Make/options
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* EXE_INC = */
|
||||||
|
/* EXE_LIBS = */
|
||||||
185
applications/test/parallel-broadcast/Test-parallel-broadcast.C
Normal file
185
applications/test/parallel-broadcast/Test-parallel-broadcast.C
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
Test-parallel-broadcast
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test for various broadcast routines.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "List.H"
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "bitSet.H"
|
||||||
|
#include "vector.H"
|
||||||
|
#include "IPstream.H"
|
||||||
|
#include "OPstream.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void printPre(const T& value)
|
||||||
|
{
|
||||||
|
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
|
||||||
|
Pout<< "pre-broadcast: " << value << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void printPost(const T& value)
|
||||||
|
{
|
||||||
|
Pout<< "post-broadcast: " << value << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void testBroadcast(T& value)
|
||||||
|
{
|
||||||
|
printPre(value);
|
||||||
|
Pstream::broadcast(value);
|
||||||
|
printPost(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void testBroadcast(List<T>& values)
|
||||||
|
{
|
||||||
|
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
|
||||||
|
Pout<< "pre-broadcast: " << flatOutput(values) << endl;
|
||||||
|
Pstream::broadcast(values);
|
||||||
|
Pout<< "post-broadcast: " << flatOutput(values) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void testBroadcast(bitSet& values)
|
||||||
|
{
|
||||||
|
Pout<< "pre-broadcast: "
|
||||||
|
<< values.size() << ": " << flatOutput(values.values()) << endl;
|
||||||
|
Pstream::broadcast(values);
|
||||||
|
Pout<< "post-broadcast: "
|
||||||
|
<< values.size() << ": " << flatOutput(values.values()) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::noCheckProcessorDirectories();
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
|
||||||
|
{
|
||||||
|
label value = -1;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
value = UPstream::nProcs();
|
||||||
|
}
|
||||||
|
testBroadcast(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
labelList values;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
values = identity(UPstream::nProcs());
|
||||||
|
}
|
||||||
|
testBroadcast(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
word value;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
value = args.executable();
|
||||||
|
}
|
||||||
|
printPre(value);
|
||||||
|
UPstream::broadcast(value); // Low-level UPstream broadcast
|
||||||
|
printPost(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
wordList values;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
values.resize(UPstream::nProcs());
|
||||||
|
forAll(values, i)
|
||||||
|
{
|
||||||
|
values[i] = "value_" + Foam::name(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testBroadcast(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
vector values(vector::uniform(-1));
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
values = vector(1,2,3);
|
||||||
|
}
|
||||||
|
testBroadcast(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
FixedList<vector, 3> values(vector::uniform(-1));
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
values = vector(1,2,3);
|
||||||
|
|
||||||
|
scalar mult = 1;
|
||||||
|
for (auto& v : values)
|
||||||
|
{
|
||||||
|
v *= mult;
|
||||||
|
mult += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
testBroadcast(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
bitSet values;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
values.set(labelList({1, 4, 8}));
|
||||||
|
values.resize(10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just something different
|
||||||
|
values.set(labelList({0, 2}));
|
||||||
|
values.resize(5);
|
||||||
|
}
|
||||||
|
testBroadcast(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
3
applications/test/parallel-chunks/Make/files
Normal file
3
applications/test/parallel-chunks/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-parallel-chunks.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-parallel-chunks
|
||||||
2
applications/test/parallel-chunks/Make/options
Normal file
2
applications/test/parallel-chunks/Make/options
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* EXE_INC = */
|
||||||
|
/* EXE_LIBS = */
|
||||||
389
applications/test/parallel-chunks/Test-parallel-chunks.C
Normal file
389
applications/test/parallel-chunks/Test-parallel-chunks.C
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
Test-parallel-chunks
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test for sending contiguous data in chunk-wise.
|
||||||
|
Largely mirrors Pstream::exchange or vice versa
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "List.H"
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "IPstream.H"
|
||||||
|
#include "OPstream.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
|
||||||
|
// Looks like Pstream::exchangeBuf
|
||||||
|
template<class T>
|
||||||
|
void do_exchangeBuf
|
||||||
|
(
|
||||||
|
const label sendSize,
|
||||||
|
const char* sendData,
|
||||||
|
const label recvSize,
|
||||||
|
char* recvData,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label startOfRequests = Pstream::nRequests();
|
||||||
|
|
||||||
|
// Set up receives
|
||||||
|
// ~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// forAll(recvSizes, proci)
|
||||||
|
{
|
||||||
|
// if (proci != Pstream::myProcNo(comm) && recvSizes[proci] > 0)
|
||||||
|
if (!Pstream::master(comm) && recvSize > 0)
|
||||||
|
{
|
||||||
|
UIPstream::read
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
UPstream::myProcNo(comm), // proci,
|
||||||
|
recvData,
|
||||||
|
recvSize*sizeof(T),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set up sends
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// forAll(sendBufs, proci)
|
||||||
|
for (const int proci : Pstream::subProcs(comm))
|
||||||
|
{
|
||||||
|
if (sendSize > 0)
|
||||||
|
// if (proci != Pstream::myProcNo(comm) && sendSizes[proci] > 0)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UOPstream::write
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
proci,
|
||||||
|
sendData,
|
||||||
|
sendSize*sizeof(T),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot send outgoing message. "
|
||||||
|
<< "to:" << proci << " nBytes:"
|
||||||
|
<< label(sendSize*sizeof(T))
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Wait for all to finish
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
UPstream::waitRequests(startOfRequests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Looks like Pstream::exchangeContainer
|
||||||
|
template<class Container, class T>
|
||||||
|
void do_exchangeContainer
|
||||||
|
(
|
||||||
|
const Container& sendData,
|
||||||
|
const label recvSize,
|
||||||
|
Container& recvData,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label startOfRequests = Pstream::nRequests();
|
||||||
|
|
||||||
|
// Set up receives
|
||||||
|
// ~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// for (const int proci : Pstream::allProcs(comm))
|
||||||
|
{
|
||||||
|
if (!Pstream::master(comm) && recvSize > 0)
|
||||||
|
// if (proci != Pstream::myProcNo(comm) && recvSize > 0)
|
||||||
|
{
|
||||||
|
UIPstream::read
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
UPstream::myProcNo(comm), // proci,
|
||||||
|
recvData.data_bytes(),
|
||||||
|
recvSize*sizeof(T),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Set up sends
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if (Pstream::master(comm) && sendData.size() > 0)
|
||||||
|
{
|
||||||
|
for (const int proci : Pstream::subProcs(comm))
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UOPstream::write
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
proci,
|
||||||
|
sendData.cdata_bytes(),
|
||||||
|
sendData.size_bytes(),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot send outgoing message. "
|
||||||
|
<< "to:" << proci << " nBytes:"
|
||||||
|
<< label(sendData.size_bytes())
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all to finish
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
|
UPstream::waitRequests(startOfRequests);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Container, class T>
|
||||||
|
void broadcast_chunks
|
||||||
|
(
|
||||||
|
Container& sendData,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
const bool wait = true
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// OR static_assert(is_contiguous<T>::value, "Contiguous data only!")
|
||||||
|
if (!is_contiguous<T>::value)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Contiguous data only." << sizeof(T) << Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UPstream::maxCommsSize <= int(sizeof(T)))
|
||||||
|
{
|
||||||
|
// Do in one go
|
||||||
|
Info<< "send " << sendData.size() << " elements in one go" << endl;
|
||||||
|
Pstream::broadcast(sendData, comm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
label sendSize(sendData.size());
|
||||||
|
Pstream::broadcast(sendSize, comm);
|
||||||
|
|
||||||
|
label recvSize(sendSize);
|
||||||
|
|
||||||
|
sendData.resize_nocopy(recvSize); // A no-op on master
|
||||||
|
|
||||||
|
// Determine the number of chunks to send. Note that we
|
||||||
|
// only have to look at the sending data since we are
|
||||||
|
// guaranteed that some processor's sending size is some other
|
||||||
|
// processor's receive size. Also we can ignore any local comms.
|
||||||
|
|
||||||
|
// We need to send bytes so the number of iterations:
|
||||||
|
// maxChunkSize iterations
|
||||||
|
// ------------ ----------
|
||||||
|
// 0 0
|
||||||
|
// 1..maxChunkSize 1
|
||||||
|
// maxChunkSize+1..2*maxChunkSize 2
|
||||||
|
// etc.
|
||||||
|
|
||||||
|
const label maxChunkSize(UPstream::maxCommsSize/sizeof(T));
|
||||||
|
|
||||||
|
label nIter(0);
|
||||||
|
{
|
||||||
|
label nSendMax = 0;
|
||||||
|
// forAll(sendBufs, proci)
|
||||||
|
// {
|
||||||
|
// if (proci != Pstream::myProcNo(comm))
|
||||||
|
// {
|
||||||
|
// nSendMax = max(nSendMax, sendBufs[proci].size());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
nSendMax = sendSize;
|
||||||
|
|
||||||
|
if (nSendMax)
|
||||||
|
{
|
||||||
|
nIter = 1 + ((nSendMax-1)/maxChunkSize);
|
||||||
|
}
|
||||||
|
reduce(nIter, maxOp<label>(), tag, comm);
|
||||||
|
|
||||||
|
Info
|
||||||
|
<< "send " << nSendMax << " elements ("
|
||||||
|
<< (nSendMax*sizeof(T)) << " bytes) in " << nIter
|
||||||
|
<< " iterations of " << maxChunkSize << " chunks ("
|
||||||
|
<< (maxChunkSize*sizeof(T)) << " bytes) for maxCommsSize:"
|
||||||
|
<< Pstream::maxCommsSize
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
label nSend(0);
|
||||||
|
label startSend(0);
|
||||||
|
char* charPtrSend;
|
||||||
|
|
||||||
|
for (label iter = 0; iter < nIter; ++iter)
|
||||||
|
{
|
||||||
|
nSend = min
|
||||||
|
(
|
||||||
|
maxChunkSize,
|
||||||
|
sendSize-startSend
|
||||||
|
);
|
||||||
|
|
||||||
|
charPtrSend =
|
||||||
|
(
|
||||||
|
nSend > 0
|
||||||
|
? reinterpret_cast<char*>(&(sendData[startSend]))
|
||||||
|
: nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "iter " << iter
|
||||||
|
<< ": beg=" << startSend << " len=" << nSend
|
||||||
|
<< " (" << (nSend*sizeof(T)) << " bytes)" << endl;
|
||||||
|
|
||||||
|
UPstream::broadcast(charPtrSend, nSend*sizeof(T), comm);
|
||||||
|
|
||||||
|
// forAll(nSend, proci)
|
||||||
|
{
|
||||||
|
startSend += nSend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::noCheckProcessorDirectories();
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
|
||||||
|
if (!Pstream::parRun())
|
||||||
|
{
|
||||||
|
Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList input1;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
input1 = identity(500);
|
||||||
|
}
|
||||||
|
broadcast_chunks<labelList, label>(input1);
|
||||||
|
|
||||||
|
Pstream::maxCommsSize = 33;
|
||||||
|
broadcast_chunks<labelList, label>(input1);
|
||||||
|
|
||||||
|
// Mostly the same with PstreamBuffers
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
|
labelList sendData;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
sendData = identity(500);
|
||||||
|
|
||||||
|
for (const int proci : Pstream::allProcs())
|
||||||
|
{
|
||||||
|
if (proci != Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
UOPstream os(proci, pBufs);
|
||||||
|
os << sendData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "call finishedSends()" << endl;
|
||||||
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
if (!Pstream::master())
|
||||||
|
{
|
||||||
|
UIPstream is(UPstream::masterNo(), pBufs);
|
||||||
|
is >> sendData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manually
|
||||||
|
{
|
||||||
|
labelListList sendBufs(UPstream::nProcs());
|
||||||
|
labelListList recvBufs(UPstream::nProcs());
|
||||||
|
labelList recvSizes;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
for (const int proci : Pstream::allProcs())
|
||||||
|
{
|
||||||
|
if (proci != Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
sendBufs[proci] = identity(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::exchangeSizes(sendBufs, recvSizes);
|
||||||
|
|
||||||
|
Pstream::exchange<labelList, label>
|
||||||
|
(
|
||||||
|
sendBufs,
|
||||||
|
recvSizes,
|
||||||
|
recvBufs
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -163,16 +163,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (Pstream::myProcNo(comm) != -1)
|
if (Pstream::myProcNo(comm) != -1)
|
||||||
{
|
{
|
||||||
//scalar sum = sumReduce(comm, localValue);
|
|
||||||
//scalar sum = localValue;
|
|
||||||
//reduce
|
|
||||||
//(
|
|
||||||
// UPstream::treeCommunication(comm),
|
|
||||||
// sum,
|
|
||||||
// sumOp<scalar>(),
|
|
||||||
// Pstream::msgType(),
|
|
||||||
// comm
|
|
||||||
//);
|
|
||||||
scalar sum = returnReduce
|
scalar sum = returnReduce
|
||||||
(
|
(
|
||||||
localValue,
|
localValue,
|
||||||
|
|||||||
3
applications/test/processorTopology/Make/files
Normal file
3
applications/test/processorTopology/Make/files
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Test-processorTopology.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-processorTopology
|
||||||
2
applications/test/processorTopology/Make/options
Normal file
2
applications/test/processorTopology/Make/options
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/* EXE_INC = */
|
||||||
|
/* EXE_LIBS = */
|
||||||
113
applications/test/processorTopology/Test-processorTopology.C
Normal file
113
applications/test/processorTopology/Test-processorTopology.C
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Description
|
||||||
|
Test/output processor topology
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "argList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
#include "globalMeshData.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
// Main program:
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::noFunctionObjects();
|
||||||
|
argList::addNote
|
||||||
|
(
|
||||||
|
"Create a metis graph file representation for an OpenFOAM mesh"
|
||||||
|
);
|
||||||
|
|
||||||
|
#include "setRootCase.H"
|
||||||
|
|
||||||
|
if (!Pstream::parRun())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Only meaningful in parallel"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "createTime.H"
|
||||||
|
#include "createPolyMesh.H"
|
||||||
|
|
||||||
|
const globalMeshData& globData = mesh.globalData();
|
||||||
|
|
||||||
|
const labelListList& connectivity = globData;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
OFstream os("processorTopology.dot");
|
||||||
|
|
||||||
|
os << "// processorTopology" << nl << nl;
|
||||||
|
os.beginBlock("graph");
|
||||||
|
|
||||||
|
forAll(connectivity, proci)
|
||||||
|
{
|
||||||
|
label nconn = 0;
|
||||||
|
|
||||||
|
for (const label neighProci : connectivity[proci])
|
||||||
|
{
|
||||||
|
if (proci < neighProci)
|
||||||
|
{
|
||||||
|
if (nconn++)
|
||||||
|
{
|
||||||
|
os << " ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << indent;
|
||||||
|
}
|
||||||
|
os << proci << " -- " << neighProci;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nconn)
|
||||||
|
{
|
||||||
|
os << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os.endBlock();
|
||||||
|
|
||||||
|
Info<< "Wrote processorTopology graph: "
|
||||||
|
<< runTime.relativePath(os.name()) << nl;
|
||||||
|
|
||||||
|
Info<< nl
|
||||||
|
<< "Use neato, circo or fdp graphviz tools" << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< nl << "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015-2017 OpenFOAM Foundation
|
Copyright (C) 2015-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -423,8 +423,8 @@ void Foam::mergeAndWrite
|
|||||||
{
|
{
|
||||||
const polyMesh& mesh = refCast<const polyMesh>(set.db());
|
const polyMesh& mesh = refCast<const polyMesh>(set.db());
|
||||||
|
|
||||||
pointField mergedPts;
|
labelField mergedIDs(set.sortedToc());
|
||||||
labelList mergedIDs;
|
pointField mergedPts(mesh.points(), mergedIDs);
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
@ -432,55 +432,12 @@ void Foam::mergeAndWrite
|
|||||||
// (mesh.globalData().mergePoints etc) since this might
|
// (mesh.globalData().mergePoints etc) since this might
|
||||||
// hide any synchronisation problem
|
// hide any synchronisation problem
|
||||||
|
|
||||||
globalIndex globalNumbering(mesh.nPoints());
|
// Renumber local ids -> global ids
|
||||||
|
globalIndex(mesh.nPoints()).inplaceToGlobal(mergedIDs);
|
||||||
|
|
||||||
mergedPts.setSize(returnReduce(set.size(), sumOp<label>()));
|
globalIndex gatherer(mergedIDs.size(), globalIndex::gatherOnly{});
|
||||||
mergedIDs.setSize(mergedPts.size());
|
gatherer.gatherInplace(mergedIDs);
|
||||||
|
gatherer.gatherInplace(mergedPts);
|
||||||
labelList setPointIDs(set.sortedToc());
|
|
||||||
|
|
||||||
// Get renumbered local data
|
|
||||||
pointField myPoints(mesh.points(), setPointIDs);
|
|
||||||
labelList myIDs(globalNumbering.toGlobal(setPointIDs));
|
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
// Insert master data first
|
|
||||||
label pOffset = 0;
|
|
||||||
SubList<point>(mergedPts, myPoints.size(), pOffset) = myPoints;
|
|
||||||
SubList<label>(mergedIDs, myIDs.size(), pOffset) = myIDs;
|
|
||||||
pOffset += myPoints.size();
|
|
||||||
|
|
||||||
// Receive slave ones
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
|
|
||||||
pointField slavePts(fromSlave);
|
|
||||||
labelList slaveIDs(fromSlave);
|
|
||||||
|
|
||||||
SubList<point>(mergedPts, slavePts.size(), pOffset) = slavePts;
|
|
||||||
SubList<label>(mergedIDs, slaveIDs.size(), pOffset) = slaveIDs;
|
|
||||||
pOffset += slaveIDs.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Construct processor stream with estimate of size. Could
|
|
||||||
// be improved.
|
|
||||||
OPstream toMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo(),
|
|
||||||
myPoints.byteSize() + myIDs.byteSize()
|
|
||||||
);
|
|
||||||
toMaster << myPoints << myIDs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mergedIDs = set.sortedToc();
|
|
||||||
mergedPts = pointField(mesh.points(), mergedIDs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2017 OpenFOAM Foundation
|
Copyright (C) 2012-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -88,25 +88,10 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
|||||||
);
|
);
|
||||||
|
|
||||||
Pstream::parRun(oldParRun);
|
Pstream::parRun(oldParRun);
|
||||||
|
|
||||||
// Send patches
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
OPstream toSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
toSlave << patchEntries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Receive patches
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> patchEntries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast: send patches to all
|
||||||
|
Pstream::scatter(patchEntries); // == worldComm;
|
||||||
|
|
||||||
|
|
||||||
// Dummy meshes
|
// Dummy meshes
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015 OpenFOAM Foundation
|
Copyright (C) 2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2018 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -185,9 +185,8 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Start sending. Sets number of bytes transferred
|
// Start sending
|
||||||
labelList allNTrans(Pstream::nProcs());
|
pBufs.finishedSends();
|
||||||
pBufs.finishedSends(allNTrans);
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -205,18 +204,15 @@ Foam::parLagrangianRedistributor::redistributeLagrangianPositions
|
|||||||
IDLList<passivePositionParticle>()
|
IDLList<passivePositionParticle>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Retrieve from receive buffers
|
// Retrieve from receive buffers
|
||||||
forAll(allNTrans, procI)
|
for (const int proci : pBufs.allProcs())
|
||||||
{
|
{
|
||||||
const label nRec = allNTrans[procI];
|
//Pout<< "Receive from processor" << proci << " : "
|
||||||
|
// << pBufs.hasRecvData(proci) << endl;
|
||||||
|
|
||||||
//Pout<< "From processor " << procI << " receiving bytes " << nRec
|
if (pBufs.hasRecvData(proci))
|
||||||
// << endl;
|
|
||||||
|
|
||||||
if (nRec)
|
|
||||||
{
|
{
|
||||||
UIPstream particleStream(procI, pBufs);
|
UIPstream particleStream(proci, pBufs);
|
||||||
|
|
||||||
// Receive particles and locate them
|
// Receive particles and locate them
|
||||||
IDLList<passivePositionParticle> newParticles
|
IDLList<passivePositionParticle> newParticles
|
||||||
|
|||||||
@ -261,15 +261,17 @@ boolList haveFacesFile(const fileName& meshPath)
|
|||||||
{
|
{
|
||||||
const fileName facesPath(meshPath/"faces");
|
const fileName facesPath(meshPath/"faces");
|
||||||
Info<< "Checking for mesh in " << facesPath << nl << endl;
|
Info<< "Checking for mesh in " << facesPath << nl << endl;
|
||||||
boolList haveMesh(Pstream::nProcs(), false);
|
boolList haveMesh
|
||||||
haveMesh[Pstream::myProcNo()] = fileHandler().isFile
|
|
||||||
(
|
(
|
||||||
fileHandler().filePath(facesPath)
|
UPstream::listGatherValues<bool>
|
||||||
|
(
|
||||||
|
fileHandler().isFile(fileHandler().filePath(facesPath))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
Pstream::gatherList(haveMesh);
|
|
||||||
Pstream::scatterList(haveMesh);
|
|
||||||
Info<< "Per processor mesh availability:" << nl
|
Info<< "Per processor mesh availability:" << nl
|
||||||
<< " " << flatOutput(haveMesh) << nl << endl;
|
<< " " << flatOutput(haveMesh) << nl << endl;
|
||||||
|
|
||||||
|
Pstream::broadcast(haveMesh);
|
||||||
return haveMesh;
|
return haveMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -208,8 +208,8 @@ bool setField
|
|||||||
|
|
||||||
doCorrectBoundaryConditions(ctrl.correctBCs, output);
|
doCorrectBoundaryConditions(ctrl.correctBCs, output);
|
||||||
|
|
||||||
const label numTotal = returnReduce(output.size(), plusOp<label>());
|
const label numTotal = returnReduce(output.size(), sumOp<label>());
|
||||||
reduce(numValuesChanged, plusOp<label>());
|
reduce(numValuesChanged, sumOp<label>());
|
||||||
|
|
||||||
if (numValuesChanged == numTotal)
|
if (numValuesChanged == numTotal)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -63,34 +63,30 @@ void writeProcStats
|
|||||||
{
|
{
|
||||||
// Determine surface bounding boxes, faces, points
|
// Determine surface bounding boxes, faces, points
|
||||||
List<treeBoundBox> surfBb(Pstream::nProcs());
|
List<treeBoundBox> surfBb(Pstream::nProcs());
|
||||||
{
|
|
||||||
surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
|
surfBb[Pstream::myProcNo()] = treeBoundBox(s.points());
|
||||||
Pstream::gatherList(surfBb);
|
Pstream::gatherList(surfBb);
|
||||||
Pstream::scatterList(surfBb);
|
|
||||||
}
|
|
||||||
|
|
||||||
labelList nPoints(Pstream::nProcs());
|
labelList nPoints(UPstream::listGatherValues<label>(s.points().size()));
|
||||||
nPoints[Pstream::myProcNo()] = s.points().size();
|
labelList nFaces(UPstream::listGatherValues<label>(s.size()));
|
||||||
Pstream::gatherList(nPoints);
|
|
||||||
Pstream::scatterList(nPoints);
|
|
||||||
|
|
||||||
labelList nFaces(Pstream::nProcs());
|
|
||||||
nFaces[Pstream::myProcNo()] = s.size();
|
|
||||||
Pstream::gatherList(nFaces);
|
|
||||||
Pstream::scatterList(nFaces);
|
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
forAll(surfBb, proci)
|
forAll(surfBb, proci)
|
||||||
{
|
{
|
||||||
Info<< "processor" << proci << nl;
|
Info<< "processor" << proci << nl;
|
||||||
|
|
||||||
const List<treeBoundBox>& bbs = meshBb[proci];
|
const List<treeBoundBox>& bbs = meshBb[proci];
|
||||||
if (bbs.size())
|
forAll(bbs, i)
|
||||||
{
|
{
|
||||||
Info<< "\tMesh bounds : " << bbs[0] << nl;
|
if (!i)
|
||||||
for (label i = 1; i < bbs.size(); i++)
|
|
||||||
{
|
{
|
||||||
Info<< "\t " << bbs[i]<< nl;
|
Info<< "\tMesh bounds : ";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "\t ";
|
||||||
|
}
|
||||||
|
Info<< bbs[i] << nl;
|
||||||
}
|
}
|
||||||
Info<< "\tSurface bounding box : " << surfBb[proci] << nl
|
Info<< "\tSurface bounding box : " << surfBb[proci] << nl
|
||||||
<< "\tTriangles : " << nFaces[proci] << nl
|
<< "\tTriangles : " << nFaces[proci] << nl
|
||||||
@ -99,6 +95,7 @@ void writeProcStats
|
|||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -266,14 +266,16 @@ StringStreams = $(Streams)/StringStreams
|
|||||||
$(StringStreams)/StringStream.C
|
$(StringStreams)/StringStream.C
|
||||||
|
|
||||||
Pstreams = $(Streams)/Pstreams
|
Pstreams = $(Streams)/Pstreams
|
||||||
$(Pstreams)/UIPstream.C
|
/* $(Pstreams)/UPstream.C in global.C */
|
||||||
$(Pstreams)/IPstream.C
|
|
||||||
/* $(Pstreams)/UPstream.C in global.Cver */
|
|
||||||
$(Pstreams)/UPstreamCommsStruct.C
|
$(Pstreams)/UPstreamCommsStruct.C
|
||||||
$(Pstreams)/Pstream.C
|
$(Pstreams)/Pstream.C
|
||||||
$(Pstreams)/UOPstream.C
|
|
||||||
$(Pstreams)/OPstream.C
|
|
||||||
$(Pstreams)/PstreamBuffers.C
|
$(Pstreams)/PstreamBuffers.C
|
||||||
|
$(Pstreams)/UIPstreamBase.C
|
||||||
|
$(Pstreams)/UOPstreamBase.C
|
||||||
|
$(Pstreams)/IPstreams.C
|
||||||
|
$(Pstreams)/OPstreams.C
|
||||||
|
$(Pstreams)/IPBstreams.C
|
||||||
|
$(Pstreams)/OPBstreams.C
|
||||||
|
|
||||||
dictionary = db/dictionary
|
dictionary = db/dictionary
|
||||||
$(dictionary)/dictionary.C
|
$(dictionary)/dictionary.C
|
||||||
@ -590,8 +592,6 @@ polyBoundaryMesh = $(polyMesh)/polyBoundaryMesh
|
|||||||
$(polyBoundaryMesh)/polyBoundaryMesh.C
|
$(polyBoundaryMesh)/polyBoundaryMesh.C
|
||||||
$(polyBoundaryMesh)/polyBoundaryMeshEntries.C
|
$(polyBoundaryMesh)/polyBoundaryMeshEntries.C
|
||||||
|
|
||||||
meshes/ProcessorTopology/commSchedule.C
|
|
||||||
|
|
||||||
globalMeshData = $(polyMesh)/globalMeshData
|
globalMeshData = $(polyMesh)/globalMeshData
|
||||||
$(globalMeshData)/globalMeshData.C
|
$(globalMeshData)/globalMeshData.C
|
||||||
$(globalMeshData)/globalPoints.C
|
$(globalMeshData)/globalPoints.C
|
||||||
@ -810,6 +810,7 @@ algorithms/indexedOctree/volumeType.C
|
|||||||
algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C
|
algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C
|
||||||
algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C
|
algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C
|
||||||
|
|
||||||
|
parallel/commSchedule/commSchedule.C
|
||||||
parallel/globalIndex/globalIndex.C
|
parallel/globalIndex/globalIndex.C
|
||||||
|
|
||||||
meshes/data/data.C
|
meshes/data/data.C
|
||||||
|
|||||||
@ -394,8 +394,7 @@ bool Foam::decomposedBlockData::readBlocks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
labelList recvSizes;
|
pBufs.finishedSends();
|
||||||
pBufs.finishedSends(recvSizes);
|
|
||||||
|
|
||||||
if (!UPstream::master(comm))
|
if (!UPstream::master(comm))
|
||||||
{
|
{
|
||||||
@ -524,8 +523,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
|
|||||||
ok = is.good();
|
ok = is.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
labelList recvSizes;
|
pBufs.finishedSends();
|
||||||
pBufs.finishedSends(recvSizes);
|
|
||||||
|
|
||||||
if (!UPstream::master(comm))
|
if (!UPstream::master(comm))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2017 OpenFOAM Foundation
|
Copyright (C) 2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -115,10 +115,7 @@ void Foam::masterOFstream::commit()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolList valid(Pstream::nProcs());
|
boolList valid(UPstream::listGatherValues<bool>(valid_));
|
||||||
valid[Pstream::myProcNo()] = valid_;
|
|
||||||
Pstream::gatherList(valid);
|
|
||||||
|
|
||||||
|
|
||||||
// Different files
|
// Different files
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -24,16 +23,15 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Read from UIPstream
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "UIPstream.H"
|
#include "UIPstream.H"
|
||||||
|
#include "IPstream.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UIPstream::UIPstream
|
Foam::UIPBstream::UIPBstream
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int fromProcNo,
|
const int fromProcNo,
|
||||||
@ -45,51 +43,65 @@ Foam::UIPstream::UIPstream
|
|||||||
IOstreamOption::streamFormat fmt
|
IOstreamOption::streamFormat fmt
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
UPstream(commsType),
|
UIPstreamBase
|
||||||
Istream(fmt, IOstreamOption::currentVersion),
|
(
|
||||||
fromProcNo_(fromProcNo),
|
commsType,
|
||||||
recvBuf_(receiveBuf),
|
fromProcNo,
|
||||||
recvBufPos_(receiveBufPosition),
|
receiveBuf,
|
||||||
tag_(tag),
|
receiveBufPosition,
|
||||||
comm_(comm),
|
tag,
|
||||||
clearAtEnd_(clearAtEnd),
|
comm,
|
||||||
messageSize_(0)
|
clearAtEnd,
|
||||||
|
fmt
|
||||||
|
)
|
||||||
{
|
{
|
||||||
NotImplemented;
|
bufferIPCrecv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::UIPstream::UIPstream(const int fromProcNo, PstreamBuffers& buffers)
|
Foam::IPBstream::IPBstream
|
||||||
:
|
|
||||||
UPstream(buffers.commsType_),
|
|
||||||
Istream(buffers.format_, IOstreamOption::currentVersion),
|
|
||||||
fromProcNo_(fromProcNo),
|
|
||||||
recvBuf_(buffers.recvBuf_[fromProcNo]),
|
|
||||||
recvBufPos_(buffers.recvBufPos_[fromProcNo]),
|
|
||||||
tag_(buffers.tag_),
|
|
||||||
comm_(buffers.comm_),
|
|
||||||
clearAtEnd_(true),
|
|
||||||
messageSize_(0)
|
|
||||||
{
|
|
||||||
NotImplemented;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::label Foam::UIPstream::read
|
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int fromProcNo,
|
const int fromProcNo,
|
||||||
char* buf,
|
const label bufSize,
|
||||||
const std::streamsize bufSize,
|
|
||||||
const int tag,
|
const int tag,
|
||||||
const label communicator
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
)
|
)
|
||||||
{
|
:
|
||||||
NotImplemented;
|
Pstream(commsType, bufSize),
|
||||||
return 0;
|
UIPBstream
|
||||||
}
|
(
|
||||||
|
commsType,
|
||||||
|
fromProcNo,
|
||||||
|
Pstream::transferBuf_,
|
||||||
|
transferBufPosition_,
|
||||||
|
tag,
|
||||||
|
comm,
|
||||||
|
false, // Do not clear Pstream::transferBuf_ if at end
|
||||||
|
fmt
|
||||||
|
),
|
||||||
|
transferBufPosition_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::IPBstream::IPBstream
|
||||||
|
(
|
||||||
|
const int fromProcNo,
|
||||||
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
IPBstream
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::scheduled, // irrelevant
|
||||||
|
fromProcNo,
|
||||||
|
label(0), // bufSize
|
||||||
|
UPstream::msgType(), // irrelevant
|
||||||
|
comm,
|
||||||
|
fmt
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,14 +31,14 @@ Description
|
|||||||
Input inter-processor communications stream.
|
Input inter-processor communications stream.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
IPstream.C
|
IPstreams.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
#ifndef IPstream_H
|
#ifndef Foam_IPstream_H
|
||||||
#define IPstream_H
|
#define Foam_IPstream_H
|
||||||
|
|
||||||
#include "UIPstream.H"
|
#include "UIPstream.H"
|
||||||
|
|
||||||
@ -79,6 +79,48 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class IPBstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Input inter-processor communications stream
|
||||||
|
//- using MPI broadcast.
|
||||||
|
class IPBstream
|
||||||
|
:
|
||||||
|
public Pstream,
|
||||||
|
public UIPBstream
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Receive index into Pstream::transferBuf_
|
||||||
|
label transferBufPosition_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct for broadcast root, optional buffer size, read format
|
||||||
|
IPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType, //!< ignored
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
const label bufSize = 0,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct for broadcast root with optional communicator,
|
||||||
|
//- write format
|
||||||
|
explicit IPBstream
|
||||||
|
(
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
120
src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C
Normal file
120
src/OpenFOAM/db/IOstreams/Pstreams/IPstreams.C
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UIPstream.H"
|
||||||
|
#include "IPstream.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UIPstream::UIPstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int fromProcNo,
|
||||||
|
DynamicList<char>& receiveBuf,
|
||||||
|
label& receiveBufPosition,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool clearAtEnd,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
UIPstreamBase
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
fromProcNo,
|
||||||
|
receiveBuf,
|
||||||
|
receiveBufPosition,
|
||||||
|
tag,
|
||||||
|
comm,
|
||||||
|
clearAtEnd,
|
||||||
|
fmt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (commsType == commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
// Message is already received into buffer
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufferIPCrecv();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::UIPstream::UIPstream(const int fromProcNo, PstreamBuffers& buffers)
|
||||||
|
:
|
||||||
|
UIPstreamBase(fromProcNo, buffers)
|
||||||
|
{
|
||||||
|
if (commsType() == commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
// Message is already received into buffer
|
||||||
|
messageSize_ = recvBuf_.size();
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "UIPstream::UIPstream PstreamBuffers :"
|
||||||
|
<< " fromProcNo:" << fromProcNo_
|
||||||
|
<< " tag:" << tag_ << " comm:" << comm_
|
||||||
|
<< " receive buffer size:" << messageSize_
|
||||||
|
<< Foam::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufferIPCrecv();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::IPstream::IPstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int fromProcNo,
|
||||||
|
const label bufSize,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Pstream(commsType, bufSize),
|
||||||
|
UIPstream
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
fromProcNo,
|
||||||
|
Pstream::transferBuf_,
|
||||||
|
transferBufPosition_,
|
||||||
|
tag,
|
||||||
|
comm,
|
||||||
|
false, // Do not clear Pstream::transferBuf_ if at end
|
||||||
|
fmt
|
||||||
|
),
|
||||||
|
transferBufPosition_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
109
src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C
Normal file
109
src/OpenFOAM/db/IOstreams/Pstreams/OPBstreams.C
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UOPstream.H"
|
||||||
|
#include "OPstream.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UOPBstream::UOPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int toProcNo,
|
||||||
|
DynamicList<char>& sendBuf,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool sendAtDestruct,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
UOPstreamBase(commsType, toProcNo, sendBuf, tag, comm, sendAtDestruct, fmt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::OPBstream::OPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int toProcNo,
|
||||||
|
const label bufSize,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Pstream(commsType, bufSize),
|
||||||
|
UOPBstream
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
toProcNo,
|
||||||
|
Pstream::transferBuf_,
|
||||||
|
tag,
|
||||||
|
comm,
|
||||||
|
true, // sendAtDestruct
|
||||||
|
fmt
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::OPBstream::OPBstream
|
||||||
|
(
|
||||||
|
const int toProcNo,
|
||||||
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
OPBstream
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::scheduled, // irrelevant
|
||||||
|
toProcNo,
|
||||||
|
label(0), // bufSize
|
||||||
|
UPstream::msgType(), // irrelevant
|
||||||
|
comm,
|
||||||
|
fmt
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UOPBstream::~UOPBstream()
|
||||||
|
{
|
||||||
|
if (sendAtDestruct_)
|
||||||
|
{
|
||||||
|
if (!bufferIPCsend())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Failed broadcast message of size "
|
||||||
|
<< sendBuf_.size() << " root: " << toProcNo_
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -31,14 +31,14 @@ Description
|
|||||||
Output inter-processor communications stream.
|
Output inter-processor communications stream.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
OPstream.C
|
OPstreams.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
#ifndef OPstream_H
|
#ifndef Foam_OPstream_H
|
||||||
#define OPstream_H
|
#define Foam_OPstream_H
|
||||||
|
|
||||||
#include "UOPstream.H"
|
#include "UOPstream.H"
|
||||||
|
|
||||||
@ -74,6 +74,43 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class OPBstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Output inter-processor communications stream
|
||||||
|
//- using MPI broadcast.
|
||||||
|
class OPBstream
|
||||||
|
:
|
||||||
|
public Pstream,
|
||||||
|
public UOPBstream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct for broadcast root, optional buffer size, write format
|
||||||
|
OPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType, //!< ignored
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
const label bufSize = 0,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct for broadcast root with optional communicator,
|
||||||
|
//- write format
|
||||||
|
explicit OPBstream
|
||||||
|
(
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
96
src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C
Normal file
96
src/OpenFOAM/db/IOstreams/Pstreams/OPstreams.C
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UOPstream.H"
|
||||||
|
#include "OPstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UOPstream::UOPstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int toProcNo,
|
||||||
|
DynamicList<char>& sendBuf,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool sendAtDestruct,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
UOPstreamBase(commsType, toProcNo, sendBuf, tag, comm, sendAtDestruct, fmt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers)
|
||||||
|
:
|
||||||
|
UOPstreamBase(toProcNo, buffers)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::OPstream::OPstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int toProcNo,
|
||||||
|
const label bufSize,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Pstream(commsType, bufSize),
|
||||||
|
UOPstream
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
toProcNo,
|
||||||
|
Pstream::transferBuf_,
|
||||||
|
tag,
|
||||||
|
comm,
|
||||||
|
true, // sendAtDestruct
|
||||||
|
fmt
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UOPstream::~UOPstream()
|
||||||
|
{
|
||||||
|
if (sendAtDestruct_)
|
||||||
|
{
|
||||||
|
if (!bufferIPCsend())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Failed sending outgoing message of size "
|
||||||
|
<< sendBuf_.size() << " to processor " << toProcNo_
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -5,7 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2012 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,6 +27,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
#include "bitSet.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -35,4 +37,40 @@ defineTypeNameAndDebug(Pstream, 0);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::Pstream::broadcast
|
||||||
|
(
|
||||||
|
bitSet& values,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
// Broadcast the size
|
||||||
|
label len(values.size());
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&len),
|
||||||
|
sizeof(label),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
|
||||||
|
values.resize_nocopy(len); // A no-op on master
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
values.data_bytes(),
|
||||||
|
values.size_bytes(),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,24 +32,31 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
Pstream.C
|
Pstream.C
|
||||||
combineGatherScatter.C
|
PstreamBroadcast.C
|
||||||
gatherScatter.C
|
PstreamGather.C
|
||||||
gatherScatterList.C
|
PstreamCombineGather.C
|
||||||
exchange.C
|
PstreamGatherList.C
|
||||||
|
PstreamExchange.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef Pstream_H
|
#ifndef Foam_Pstream_H
|
||||||
#define Pstream_H
|
#define Foam_Pstream_H
|
||||||
|
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
// #define Foam_Pstream_scatter_nobroadcast
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class bitSet;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class Pstream Declaration
|
Class Pstream Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -60,33 +67,31 @@ class Pstream
|
|||||||
{
|
{
|
||||||
// Private Static Functions
|
// Private Static Functions
|
||||||
|
|
||||||
//- Exchange contiguous data. Sends sendData, receives into
|
//- Exchange contiguous data. Sends sendBufs, receives into recvBufs.
|
||||||
// recvData. If block=true will wait for all transfers to finish.
|
|
||||||
// Data provided and received as container.
|
// Data provided and received as container.
|
||||||
template<class Container, class T>
|
template<class Container, class T>
|
||||||
static void exchangeContainer
|
static void exchangeContainer
|
||||||
(
|
(
|
||||||
const UList<Container>& sendBufs,
|
const UList<Container>& sendBufs,
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvSizes, //!< Num of recv elements (not bytes)
|
||||||
List<Container>& recvBufs,
|
List<Container>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait //!< Wait for requests to complete
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Exchange contiguous data. Sends sendData, receives into
|
//- Exchange contiguous data. Sends sendBufs, receives into recvBufs.
|
||||||
// recvData. If block=true will wait for all transfers to finish.
|
|
||||||
// Data provided and received as pointers.
|
// Data provided and received as pointers.
|
||||||
template<class T>
|
template<class T>
|
||||||
static void exchangeBuf
|
static void exchangeBuf
|
||||||
(
|
(
|
||||||
const labelUList& sendSizes, // number of T, not number of char
|
const labelUList& sendSizes, //!< Num of send elements (not bytes)
|
||||||
const UList<const char*>& sendBufs,
|
const UList<const char*>& sendBufs,
|
||||||
const labelUList& recvSizes, // number of T, not number of char
|
const labelUList& recvSizes, //!< Num of recv elements (not bytes)
|
||||||
List<char*>& recvBufs,
|
List<char*>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait //!< Wait for requests to complete
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -106,31 +111,82 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct given optional buffer size
|
//- Construct for given commsTypes, with optional buffer size
|
||||||
explicit Pstream
|
explicit Pstream
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const UPstream::commsTypes commsType,
|
||||||
const label bufSize = 0
|
const label bufSize = 0
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
UPstream(commsType)
|
UPstream(commsType)
|
||||||
{
|
{
|
||||||
if (bufSize)
|
if (bufSize > 0)
|
||||||
{
|
{
|
||||||
transferBuf_.setCapacity(bufSize + 2*sizeof(scalar) + 1);
|
transferBuf_.setCapacity(bufSize + 2*sizeof(scalar) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Gather and scatter
|
// Static Functions
|
||||||
|
|
||||||
|
// Broadcast
|
||||||
|
|
||||||
|
//- Broadcast buffer or string content to all processes in communicator
|
||||||
|
using UPstream::broadcast;
|
||||||
|
|
||||||
|
//- Generic broadcast using streams to serialize/de-serialize
|
||||||
|
template<class T>
|
||||||
|
static void genericBroadcast
|
||||||
|
(
|
||||||
|
T& value,
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast value (contiguous or non-contiguous)
|
||||||
|
//- to all processes in communicator.
|
||||||
|
template<class T>
|
||||||
|
static void broadcast
|
||||||
|
(
|
||||||
|
T& value,
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast multiple values (contiguous or non-contiguous)
|
||||||
|
//- to all processes in communicator.
|
||||||
|
template<class T>
|
||||||
|
static void broadcast
|
||||||
|
(
|
||||||
|
List<T>& values,
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast multiple values (contiguous or non-contiguous)
|
||||||
|
//- to all processes in communicator.
|
||||||
|
template<class T, int SizeMin>
|
||||||
|
static void broadcast
|
||||||
|
(
|
||||||
|
DynamicList<T, SizeMin>& values,
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast bitSet values
|
||||||
|
//- to all processes in communicator.
|
||||||
|
static void broadcast
|
||||||
|
(
|
||||||
|
bitSet& values,
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Gather
|
||||||
|
|
||||||
//- Gather data.
|
//- Gather data.
|
||||||
//- Apply bop to combine Value from different processors
|
//- Apply \c bop to combine \c value from different processors
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
static void gather
|
static void gather
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -140,40 +196,22 @@ public:
|
|||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
static void gather
|
static void gather
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = Pstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
|
||||||
|
|
||||||
//- Scatter data. Distribute without modification. Reverse of gather
|
|
||||||
template<class T>
|
|
||||||
static void scatter
|
|
||||||
(
|
|
||||||
const List<commsStruct>& comms,
|
|
||||||
T& Value,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Like above but switches between linear/tree communication
|
|
||||||
template<class T>
|
|
||||||
static void scatter
|
|
||||||
(
|
|
||||||
T& Value,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = Pstream::worldComm
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Combine variants. Inplace combine values from processors.
|
// Gather/combine data
|
||||||
|
// Inplace combine values from processors.
|
||||||
// (Uses construct from Istream instead of <<)
|
// (Uses construct from Istream instead of <<)
|
||||||
|
|
||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
static void combineGather
|
static void combineGather
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -183,29 +221,10 @@ public:
|
|||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
static void combineGather
|
static void combineGather
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = Pstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
|
||||||
|
|
||||||
//- Scatter data. Reverse of combineGather
|
|
||||||
template<class T>
|
|
||||||
static void combineScatter
|
|
||||||
(
|
|
||||||
const List<commsStruct>& comms,
|
|
||||||
T& Value,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Like above but switches between linear/tree communication
|
|
||||||
template<class T>
|
|
||||||
static void combineScatter
|
|
||||||
(
|
|
||||||
T& Value,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = Pstream::worldComm
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -215,7 +234,7 @@ public:
|
|||||||
static void listCombineGather
|
static void listCombineGather
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
List<T>& Value,
|
List<T>& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -225,40 +244,21 @@ public:
|
|||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
static void listCombineGather
|
static void listCombineGather
|
||||||
(
|
(
|
||||||
List<T>& Value,
|
List<T>& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = Pstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
|
||||||
|
|
||||||
//- Scatter data. Reverse of combineGather
|
|
||||||
template<class T>
|
|
||||||
static void listCombineScatter
|
|
||||||
(
|
|
||||||
const List<commsStruct>& comms,
|
|
||||||
List<T>& Value,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Like above but switches between linear/tree communication
|
|
||||||
template<class T>
|
|
||||||
static void listCombineScatter
|
|
||||||
(
|
|
||||||
List<T>& Value,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = Pstream::worldComm
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Combine variants working on whole map at a time. Container needs to
|
// Combine variants working on whole map at a time.
|
||||||
// have iterators and find() defined.
|
// Container needs iterators, find() and insert methods defined.
|
||||||
|
|
||||||
template<class Container, class CombineOp>
|
template<class Container, class CombineOp>
|
||||||
static void mapCombineGather
|
static void mapCombineGather
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
Container& Values,
|
Container& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -268,43 +268,23 @@ public:
|
|||||||
template<class Container, class CombineOp>
|
template<class Container, class CombineOp>
|
||||||
static void mapCombineGather
|
static void mapCombineGather
|
||||||
(
|
(
|
||||||
Container& Values,
|
Container& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Scatter data. Reverse of combineGather
|
|
||||||
template<class Container>
|
|
||||||
static void mapCombineScatter
|
|
||||||
(
|
|
||||||
const List<commsStruct>& comms,
|
|
||||||
Container& Values,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Like above but switches between linear/tree communication
|
|
||||||
template<class Container>
|
|
||||||
static void mapCombineScatter
|
|
||||||
(
|
|
||||||
Container& Values,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Gather/scatter keeping the individual processor data separate.
|
// Gather/scatter keeping the individual processor data separate.
|
||||||
// Values is a List of size UPstream::nProcs() where
|
// The values is a List of size UPstream::nProcs() where
|
||||||
// Values[UPstream::myProcNo()] is the data for the current processor.
|
// values[UPstream::myProcNo()] is the data for the current processor.
|
||||||
|
|
||||||
//- Gather data but keep individual values separate
|
//- Gather data but keep individual values separate
|
||||||
template<class T>
|
template<class T>
|
||||||
static void gatherList
|
static void gatherList
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
);
|
);
|
||||||
@ -313,17 +293,109 @@ public:
|
|||||||
template<class T>
|
template<class T>
|
||||||
static void gatherList
|
static void gatherList
|
||||||
(
|
(
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Scatter
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note comms and tag parameters only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void scatter
|
||||||
|
(
|
||||||
|
const List<commsStruct>& comms,
|
||||||
|
T& value,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note tag parameter only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void scatter
|
||||||
|
(
|
||||||
|
T& value,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note tag parameter only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void combineScatter
|
||||||
|
(
|
||||||
|
const List<commsStruct>& comms,
|
||||||
|
T& value,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note tag parameter only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void combineScatter
|
||||||
|
(
|
||||||
|
T& value,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note comms and tag parameters only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void listCombineScatter
|
||||||
|
(
|
||||||
|
const List<commsStruct>& comms,
|
||||||
|
List<T>& value,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
// \note comms and tag parameters only used when
|
||||||
|
// Foam_Pstream_scatter_nobroadcast is defined
|
||||||
|
template<class T>
|
||||||
|
static void listCombineScatter
|
||||||
|
(
|
||||||
|
List<T>& value,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast data: Distribute without modification.
|
||||||
|
template<class Container>
|
||||||
|
static void mapCombineScatter
|
||||||
|
(
|
||||||
|
const List<commsStruct>& comms,
|
||||||
|
Container& values,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Like above but switches between linear/tree communication
|
||||||
|
template<class Container>
|
||||||
|
static void mapCombineScatter
|
||||||
|
(
|
||||||
|
Container& values,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Scatter data. Reverse of gatherList
|
//- Scatter data. Reverse of gatherList
|
||||||
template<class T>
|
template<class T>
|
||||||
static void scatterList
|
static void scatterList
|
||||||
(
|
(
|
||||||
const List<commsStruct>& comms,
|
const List<commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
);
|
);
|
||||||
@ -332,25 +404,25 @@ public:
|
|||||||
template<class T>
|
template<class T>
|
||||||
static void scatterList
|
static void scatterList
|
||||||
(
|
(
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Exchange
|
// Exchange
|
||||||
|
|
||||||
//- Helper: exchange contiguous data. Sends sendData, receives into
|
//- Helper: exchange sizes of sendData for specified
|
||||||
// recvData. If block=true will wait for all transfers to finish.
|
//- set of send/receive processes.
|
||||||
template<class Container, class T>
|
template<class Container>
|
||||||
static void exchange
|
static void exchangeSizes
|
||||||
(
|
(
|
||||||
const UList<Container>& sendData,
|
const labelUList& sendProcs,
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvProcs,
|
||||||
List<Container>& recvData,
|
const Container& sendData,
|
||||||
const int tag = UPstream::msgType(),
|
labelList& sizes,
|
||||||
const label comm = UPstream::worldComm,
|
const label tag = UPstream::msgType(),
|
||||||
const bool block = true
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Helper: exchange sizes of sendData. sendData is the data per
|
//- Helper: exchange sizes of sendData. sendData is the data per
|
||||||
@ -364,6 +436,20 @@ public:
|
|||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Helper: exchange contiguous data. Sends sendData, receives into
|
||||||
|
// recvData. If block=true will wait for all transfers to finish.
|
||||||
|
template<class Container, class T>
|
||||||
|
static void exchange
|
||||||
|
(
|
||||||
|
const UList<Container>& sendData,
|
||||||
|
const labelUList& recvSizes,
|
||||||
|
List<Container>& recvData,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
const bool wait = true //!< Wait for requests to complete
|
||||||
|
);
|
||||||
|
|
||||||
//- Exchange contiguous data. Sends sendData, receives into
|
//- Exchange contiguous data. Sends sendData, receives into
|
||||||
// recvData. Determines sizes to receive.
|
// recvData. Determines sizes to receive.
|
||||||
// If block=true will wait for all transfers to finish.
|
// If block=true will wait for all transfers to finish.
|
||||||
@ -374,7 +460,7 @@ public:
|
|||||||
List<Container>& recvData,
|
List<Container>& recvData,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm,
|
const label comm = UPstream::worldComm,
|
||||||
const bool block = true
|
const bool wait = true //!< Wait for requests to complete
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -386,10 +472,11 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "gatherScatter.C"
|
#include "PstreamBroadcast.C"
|
||||||
#include "combineGatherScatter.C"
|
#include "PstreamGather.C"
|
||||||
#include "gatherScatterList.C"
|
#include "PstreamCombineGather.C"
|
||||||
#include "exchange.C"
|
#include "PstreamGatherList.C"
|
||||||
|
#include "PstreamExchange.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
142
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.C
Normal file
142
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBroadcast.C
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "OPstream.H"
|
||||||
|
#include "IPstream.H"
|
||||||
|
#include "contiguous.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Foam::Pstream::genericBroadcast(T& value, const label comm)
|
||||||
|
{
|
||||||
|
// Generic: use stream interface
|
||||||
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
if (UPstream::master(comm))
|
||||||
|
{
|
||||||
|
OPBstream toAll(UPstream::masterNo(), comm);
|
||||||
|
toAll << value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IPBstream fromMaster(UPstream::masterNo(), comm);
|
||||||
|
fromMaster >> value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Foam::Pstream::broadcast(T& value, const label comm)
|
||||||
|
{
|
||||||
|
if (!is_contiguous<T>::value)
|
||||||
|
{
|
||||||
|
Pstream::genericBroadcast(value, comm);
|
||||||
|
}
|
||||||
|
else if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&value),
|
||||||
|
sizeof(T),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void Foam::Pstream::broadcast(List<T>& values, const label comm)
|
||||||
|
{
|
||||||
|
if (!is_contiguous<T>::value)
|
||||||
|
{
|
||||||
|
Pstream::genericBroadcast(values, comm);
|
||||||
|
}
|
||||||
|
else if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
// Broadcast the size
|
||||||
|
label len(values.size());
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&len),
|
||||||
|
sizeof(label),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
values.resize_nocopy(len); // A no-op on master
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
values.data_bytes(),
|
||||||
|
values.size_bytes(),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, int SizeMin>
|
||||||
|
void Foam::Pstream::broadcast(DynamicList<T, SizeMin>& values, const label comm)
|
||||||
|
{
|
||||||
|
if (!is_contiguous<T>::value)
|
||||||
|
{
|
||||||
|
Pstream::genericBroadcast(values, comm);
|
||||||
|
}
|
||||||
|
else if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
// Broadcast the size
|
||||||
|
label len(values.size());
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&len),
|
||||||
|
sizeof(label),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
values.resize_nocopy(len); // A no-op on master
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
values.data_bytes(),
|
||||||
|
values.size_bytes(),
|
||||||
|
comm,
|
||||||
|
UPstream::masterNo()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,6 +27,74 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "PstreamBuffers.H"
|
#include "PstreamBuffers.H"
|
||||||
|
#include "bitSet.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::PstreamBuffers::finalExchange
|
||||||
|
(
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Could also check that it is not called twice
|
||||||
|
// but that is used for overlapping send/recv (eg, overset)
|
||||||
|
finishedSendsCalled_ = true;
|
||||||
|
|
||||||
|
if (commsType_ == UPstream::commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
// all-to-all
|
||||||
|
Pstream::exchangeSizes(sendBuf_, recvSizes, comm_);
|
||||||
|
|
||||||
|
Pstream::exchange<DynamicList<char>, char>
|
||||||
|
(
|
||||||
|
sendBuf_,
|
||||||
|
recvSizes,
|
||||||
|
recvBuf_,
|
||||||
|
tag_,
|
||||||
|
comm_,
|
||||||
|
wait
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::PstreamBuffers::finalExchange
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Could also check that it is not called twice
|
||||||
|
// but that is used for overlapping send/recv (eg, overset)
|
||||||
|
finishedSendsCalled_ = true;
|
||||||
|
|
||||||
|
if (commsType_ == UPstream::commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
Pstream::exchangeSizes
|
||||||
|
(
|
||||||
|
sendProcs,
|
||||||
|
recvProcs,
|
||||||
|
sendBuf_,
|
||||||
|
recvSizes,
|
||||||
|
tag_,
|
||||||
|
comm_
|
||||||
|
);
|
||||||
|
|
||||||
|
Pstream::exchange<DynamicList<char>, char>
|
||||||
|
(
|
||||||
|
sendBuf_,
|
||||||
|
recvSizes,
|
||||||
|
recvBuf_,
|
||||||
|
tag_,
|
||||||
|
comm_,
|
||||||
|
wait
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -38,14 +106,15 @@ Foam::PstreamBuffers::PstreamBuffers
|
|||||||
IOstreamOption::streamFormat fmt
|
IOstreamOption::streamFormat fmt
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
|
finishedSendsCalled_(false),
|
||||||
|
allowClearRecv_(true),
|
||||||
|
format_(fmt),
|
||||||
commsType_(commsType),
|
commsType_(commsType),
|
||||||
tag_(tag),
|
tag_(tag),
|
||||||
comm_(comm),
|
comm_(comm),
|
||||||
format_(fmt),
|
|
||||||
sendBuf_(UPstream::nProcs(comm)),
|
sendBuf_(UPstream::nProcs(comm)),
|
||||||
recvBuf_(UPstream::nProcs(comm)),
|
recvBuf_(UPstream::nProcs(comm)),
|
||||||
recvBufPos_(UPstream::nProcs(comm), Zero),
|
recvBufPos_(UPstream::nProcs(comm), Zero)
|
||||||
finishedSendsCalled_(false)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -70,45 +139,125 @@ Foam::PstreamBuffers::~PstreamBuffers()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::PstreamBuffers::finishedSends(const bool block)
|
void Foam::PstreamBuffers::clear()
|
||||||
{
|
{
|
||||||
// Could also check that it is not called twice
|
for (DynamicList<char>& buf : sendBuf_)
|
||||||
finishedSendsCalled_ = true;
|
|
||||||
|
|
||||||
if (commsType_ == UPstream::commsTypes::nonBlocking)
|
|
||||||
{
|
{
|
||||||
Pstream::exchange<DynamicList<char>, char>
|
buf.clear();
|
||||||
(
|
|
||||||
sendBuf_,
|
|
||||||
recvBuf_,
|
|
||||||
tag_,
|
|
||||||
comm_,
|
|
||||||
block
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
for (DynamicList<char>& buf : recvBuf_)
|
||||||
|
{
|
||||||
|
buf.clear();
|
||||||
|
}
|
||||||
|
recvBufPos_ = 0;
|
||||||
|
|
||||||
|
finishedSendsCalled_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::PstreamBuffers::finishedSends(labelList& recvSizes, const bool block)
|
void Foam::PstreamBuffers::clearStorage()
|
||||||
{
|
{
|
||||||
// Could also check that it is not called twice
|
// Could also clear out entire sendBuf_, recvBuf_ and reallocate.
|
||||||
finishedSendsCalled_ = true;
|
// Not sure if it makes much difference
|
||||||
|
for (DynamicList<char>& buf : sendBuf_)
|
||||||
if (commsType_ == UPstream::commsTypes::nonBlocking)
|
|
||||||
{
|
{
|
||||||
Pstream::exchangeSizes(sendBuf_, recvSizes, comm_);
|
buf.clearStorage();
|
||||||
|
|
||||||
Pstream::exchange<DynamicList<char>, char>
|
|
||||||
(
|
|
||||||
sendBuf_,
|
|
||||||
recvSizes,
|
|
||||||
recvBuf_,
|
|
||||||
tag_,
|
|
||||||
comm_,
|
|
||||||
block
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
for (DynamicList<char>& buf : recvBuf_)
|
||||||
|
{
|
||||||
|
buf.clearStorage();
|
||||||
|
}
|
||||||
|
recvBufPos_ = 0;
|
||||||
|
|
||||||
|
finishedSendsCalled_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::hasSendData() const
|
||||||
|
{
|
||||||
|
for (const DynamicList<char>& buf : sendBuf_)
|
||||||
|
{
|
||||||
|
if (!buf.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::hasSendData(const label proci) const
|
||||||
|
{
|
||||||
|
return !sendBuf_[proci].empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::hasRecvData() const
|
||||||
|
{
|
||||||
|
if (finishedSendsCalled_)
|
||||||
|
{
|
||||||
|
for (const DynamicList<char>& buf : recvBuf_)
|
||||||
|
{
|
||||||
|
if (!buf.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef FULLDEBUG
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Call finishedSends first" << exit(FatalError);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::hasRecvData(const label proci) const
|
||||||
|
{
|
||||||
|
if (finishedSendsCalled_)
|
||||||
|
{
|
||||||
|
return !recvBuf_[proci].empty();
|
||||||
|
}
|
||||||
|
#ifdef FULLDEBUG
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Call finishedSends first" << exit(FatalError);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::allowClearRecv(bool on) noexcept
|
||||||
|
{
|
||||||
|
bool old(allowClearRecv_);
|
||||||
|
allowClearRecv_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::PstreamBuffers::finishedSends(const bool wait)
|
||||||
|
{
|
||||||
|
labelList recvSizes;
|
||||||
|
finalExchange(recvSizes, wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::PstreamBuffers::finishedSends
|
||||||
|
(
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
finalExchange(recvSizes, wait);
|
||||||
|
|
||||||
|
if (commsType_ != UPstream::commsTypes::nonBlocking)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Obtaining sizes not supported in "
|
<< "Obtaining sizes not supported in "
|
||||||
@ -122,18 +271,107 @@ void Foam::PstreamBuffers::finishedSends(labelList& recvSizes, const bool block)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::PstreamBuffers::clear()
|
void Foam::PstreamBuffers::finishedSends
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
{
|
{
|
||||||
for (DynamicList<char>& buf : sendBuf_)
|
labelList recvSizes;
|
||||||
{
|
finalExchange(sendProcs, recvProcs, recvSizes, wait);
|
||||||
buf.clear();
|
|
||||||
}
|
}
|
||||||
for (DynamicList<char>& buf : recvBuf_)
|
|
||||||
|
|
||||||
|
void Foam::PstreamBuffers::finishedSends
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
{
|
{
|
||||||
buf.clear();
|
finalExchange(sendProcs, recvProcs, recvSizes, wait);
|
||||||
|
|
||||||
|
if (commsType_ != UPstream::commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Obtaining sizes not supported in "
|
||||||
|
<< UPstream::commsTypeNames[commsType_] << endl
|
||||||
|
<< " since transfers already in progress. Use non-blocking instead."
|
||||||
|
<< exit(FatalError);
|
||||||
|
|
||||||
|
// Note: maybe possible only if using different tag from write started
|
||||||
|
// by ~UOPstream. Needs some work.
|
||||||
}
|
}
|
||||||
recvBufPos_ = 0;
|
}
|
||||||
finishedSendsCalled_ = false;
|
|
||||||
|
|
||||||
|
bool Foam::PstreamBuffers::finishedSends
|
||||||
|
(
|
||||||
|
bitSet& sendConnections,
|
||||||
|
DynamicList<label>& sendProcs,
|
||||||
|
DynamicList<label>& recvProcs,
|
||||||
|
const bool wait
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool changed = (sendConnections.size() != nProcs());
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
sendConnections.resize(nProcs());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update send connections
|
||||||
|
// - reasonable to assume there are no self-sends on UPstream::myProcNo
|
||||||
|
forAll(sendBuf_, proci)
|
||||||
|
{
|
||||||
|
// ie, hasSendData(proci)
|
||||||
|
if (sendConnections.set(proci, !sendBuf_[proci].empty()))
|
||||||
|
{
|
||||||
|
// The state changed
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(changed, orOp<bool>());
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
// Create send/recv topology
|
||||||
|
|
||||||
|
// The send ranks
|
||||||
|
sendProcs.clear();
|
||||||
|
forAll(sendBuf_, proci)
|
||||||
|
{
|
||||||
|
// ie, hasSendData(proci)
|
||||||
|
if (!sendBuf_[proci].empty())
|
||||||
|
{
|
||||||
|
sendProcs.append(proci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finishedSends(wait); // All-to-all
|
||||||
|
|
||||||
|
// The recv ranks
|
||||||
|
recvProcs.clear();
|
||||||
|
forAll(recvBuf_, proci)
|
||||||
|
{
|
||||||
|
// ie, hasRecvData(proci)
|
||||||
|
if (!recvBuf_[proci].empty())
|
||||||
|
{
|
||||||
|
recvProcs.append(proci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use existing send/recv ranks
|
||||||
|
|
||||||
|
finishedSends(sendProcs, recvProcs, wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -70,8 +70,8 @@ SourceFiles
|
|||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
#ifndef PstreamBuffers_H
|
#ifndef Foam_PstreamBuffers_H
|
||||||
#define PstreamBuffers_H
|
#define Foam_PstreamBuffers_H
|
||||||
|
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
@ -82,17 +82,31 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
class bitSet;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class PstreamBuffers Declaration
|
Class PstreamBuffers Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class PstreamBuffers
|
class PstreamBuffers
|
||||||
{
|
{
|
||||||
friend class UOPstream;
|
// Friendship
|
||||||
friend class UIPstream;
|
friend class UOPstreamBase; // Access to sendBuf_
|
||||||
|
friend class UIPstreamBase; // Access to recvBuf_, recvBufPos_
|
||||||
|
|
||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
|
//- Track if sends are complete
|
||||||
|
bool finishedSendsCalled_;
|
||||||
|
|
||||||
|
//- Permit clear of individual receive buffer by external access
|
||||||
|
bool allowClearRecv_;
|
||||||
|
|
||||||
|
//- Buffer format (ascii | binary)
|
||||||
|
const IOstreamOption::streamFormat format_;
|
||||||
|
|
||||||
//- Communications type of this stream
|
//- Communications type of this stream
|
||||||
const UPstream::commsTypes commsType_;
|
const UPstream::commsTypes commsType_;
|
||||||
|
|
||||||
@ -102,20 +116,32 @@ class PstreamBuffers
|
|||||||
//- Communicator
|
//- Communicator
|
||||||
const label comm_;
|
const label comm_;
|
||||||
|
|
||||||
//- Buffer format (ascii | binary)
|
//- Send buffer. Size is nProcs()
|
||||||
const IOstreamOption::streamFormat format_;
|
|
||||||
|
|
||||||
//- Send buffer
|
|
||||||
List<DynamicList<char>> sendBuf_;
|
List<DynamicList<char>> sendBuf_;
|
||||||
|
|
||||||
//- Receive buffer
|
//- Receive buffer. Size is nProcs()
|
||||||
List<DynamicList<char>> recvBuf_;
|
List<DynamicList<char>> recvBuf_;
|
||||||
|
|
||||||
//- Current read positions within recvBuf_
|
//- Current read positions within recvBuf_. Size is nProcs()
|
||||||
labelList recvBufPos_;
|
labelList recvBufPos_;
|
||||||
|
|
||||||
//- Track if sends are complete
|
|
||||||
bool finishedSendsCalled_;
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Mark all sends as having been done.
|
||||||
|
// This will start receives (nonBlocking comms).
|
||||||
|
void finalExchange(labelList& recvSizes, const bool wait);
|
||||||
|
|
||||||
|
//- Mark sends as done.
|
||||||
|
// Only exchange sizes using the sendProcs/recvProcs subset
|
||||||
|
// (nonBlocking comms).
|
||||||
|
void finalExchange
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -138,6 +164,20 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- The associated buffer format (ascii | binary)
|
||||||
|
IOstreamOption::streamFormat format() const noexcept
|
||||||
|
{
|
||||||
|
return format_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- The communications type of the stream
|
||||||
|
UPstream::commsTypes commsType() const noexcept
|
||||||
|
{
|
||||||
|
return commsType_;
|
||||||
|
}
|
||||||
|
|
||||||
//- The transfer message type
|
//- The transfer message type
|
||||||
int tag() const noexcept
|
int tag() const noexcept
|
||||||
{
|
{
|
||||||
@ -150,20 +190,176 @@ public:
|
|||||||
return comm_;
|
return comm_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Mark all sends as having been done.
|
|
||||||
// This will start receives in non-blocking mode.
|
|
||||||
// If block will wait for all transfers to finish
|
|
||||||
// (only relevant for nonBlocking mode)
|
|
||||||
void finishedSends(const bool block = true);
|
|
||||||
|
|
||||||
//- Mark all sends as having been done.
|
// Sizing
|
||||||
// Same as above but also returns sizes (bytes) received.
|
|
||||||
// \note currently only valid for non-blocking.
|
|
||||||
void finishedSends(labelList& recvSizes, const bool block = true);
|
|
||||||
|
|
||||||
//- Reset (clear) individual buffers and reset state.
|
//- Number of ranks associated with PstreamBuffers
|
||||||
// Does not clear buffer storage
|
label nProcs() const noexcept
|
||||||
|
{
|
||||||
|
return recvBufPos_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Range of ranks indices associated with PstreamBuffers
|
||||||
|
UPstream::rangeType allProcs() const noexcept
|
||||||
|
{
|
||||||
|
// Proc 0 -> nProcs (int value)
|
||||||
|
return UPstream::rangeType(static_cast<int>(nProcs()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Queries
|
||||||
|
|
||||||
|
//- True if finishedSends() or finishedNeighbourSends() has been called
|
||||||
|
bool finished() const noexcept
|
||||||
|
{
|
||||||
|
return finishedSendsCalled_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- True if any (local) send buffers have data
|
||||||
|
bool hasSendData() const;
|
||||||
|
|
||||||
|
//- True if (local) send buffer has data on specified processor.
|
||||||
|
bool hasSendData(const label proci) const;
|
||||||
|
|
||||||
|
//- True if any (local) recv buffers have data.
|
||||||
|
//- Must call finishedSends() or finishedNeighbourSends() first!
|
||||||
|
bool hasRecvData() const;
|
||||||
|
|
||||||
|
//- True if (local) recv buffer has data on specified processor.
|
||||||
|
//- Must call finishedSends() or finishedNeighbourSends() first!
|
||||||
|
bool hasRecvData(const label proci) const;
|
||||||
|
|
||||||
|
//- Is clearStorage of individual receive buffer by external hooks
|
||||||
|
//- allowed? (default: true)
|
||||||
|
bool allowClearRecv() const noexcept
|
||||||
|
{
|
||||||
|
return allowClearRecv_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Edit
|
||||||
|
|
||||||
|
//- Clear individual buffers and reset states.
|
||||||
|
// Does not clear individual buffer storage.
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
//- Clear individual buffer storage and reset states.
|
||||||
|
void clearStorage();
|
||||||
|
|
||||||
|
//- Change allowClearRecv, return previous value
|
||||||
|
bool allowClearRecv(bool on) noexcept;
|
||||||
|
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
//- Mark sends as done
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers (all-to-all).
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
void finishedSends(const bool wait = true);
|
||||||
|
|
||||||
|
//- Mark sends as done.
|
||||||
|
//- Recovers the sizes (bytes) received.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers (all-to-all).
|
||||||
|
// \param[out] recvSizes the sizes (bytes) received
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking comms.
|
||||||
|
void finishedSends(labelList& recvSizes, const bool wait = true);
|
||||||
|
|
||||||
|
//- Mark sends as done using subset of send/recv ranks
|
||||||
|
//- to exchange data on.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers.
|
||||||
|
// \param sendProcs ranks used for sends
|
||||||
|
// \param recvProcs ranks used for recvs
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking comms.
|
||||||
|
void finishedSends
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
const bool wait = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Mark sends as done using subset of send/recv ranks
|
||||||
|
//- to exchange data on. Recovers the sizes (bytes) received.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers.
|
||||||
|
//
|
||||||
|
// \param sendProcs ranks used for sends
|
||||||
|
// \param recvProcs ranks used for recvs
|
||||||
|
// \param[out] recvSizes the sizes (bytes) received
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking comms.
|
||||||
|
void finishedSends
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- A caching version that uses a limited send/recv connectivity.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers.
|
||||||
|
// \param sendConnections on/off for sending ranks
|
||||||
|
// \param sendProcs ranks used for sends
|
||||||
|
// \param recvProcs ranks used for recvs
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \return True if the send/recv connectivity changed
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking comms.
|
||||||
|
bool finishedSends
|
||||||
|
(
|
||||||
|
bitSet& sendConnections,
|
||||||
|
DynamicList<label>& sendProcs,
|
||||||
|
DynamicList<label>& recvProcs,
|
||||||
|
const bool wait = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Mark sends as done using subset of send/recv ranks
|
||||||
|
//- and recover the sizes (bytes) received.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: populates receive buffers.
|
||||||
|
//
|
||||||
|
// \param neighProcs ranks used for sends/recvs
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking comms.
|
||||||
|
// \note Same as finishedSends with identical sendProcs/recvProcs
|
||||||
|
void finishedNeighbourSends
|
||||||
|
(
|
||||||
|
const labelUList& neighProcs,
|
||||||
|
const bool wait = true
|
||||||
|
)
|
||||||
|
{
|
||||||
|
finishedSends(neighProcs, neighProcs, wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Mark sends as done using subset of send/recv ranks
|
||||||
|
//- and recover the sizes (bytes) received.
|
||||||
|
//
|
||||||
|
// Non-blocking mode: it will populate receive buffers.
|
||||||
|
//
|
||||||
|
// \param neighProcs ranks used for sends/recvs
|
||||||
|
// \param[out] recvSizes the sizes (bytes) received
|
||||||
|
// \param wait wait for requests to complete (in nonBlocking mode)
|
||||||
|
//
|
||||||
|
// \warning currently only valid for nonBlocking mode.
|
||||||
|
void finishedNeighbourSends
|
||||||
|
(
|
||||||
|
const labelUList& neighProcs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const bool wait = true
|
||||||
|
)
|
||||||
|
{
|
||||||
|
finishedSends(neighProcs, neighProcs, recvSizes, wait);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,7 +27,7 @@ License
|
|||||||
Description
|
Description
|
||||||
Variant of gather, scatter.
|
Variant of gather, scatter.
|
||||||
Normal gather uses:
|
Normal gather uses:
|
||||||
- construct null and read (>>) from Istream
|
- default construct and read (>>) from Istream
|
||||||
- binary operator and assignment operator to combine values
|
- binary operator and assignment operator to combine values
|
||||||
|
|
||||||
combineGather uses:
|
combineGather uses:
|
||||||
@ -47,7 +47,7 @@ template<class T, class CombineOp>
|
|||||||
void Foam::Pstream::combineGather
|
void Foam::Pstream::combineGather
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -55,22 +55,21 @@ void Foam::Pstream::combineGather
|
|||||||
{
|
{
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from my downstairs neighbours
|
// Receive from my downstairs neighbours
|
||||||
forAll(myComm.below(), belowI)
|
for (const label belowID : myComm.below())
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
T value;
|
T received;
|
||||||
|
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
reinterpret_cast<char*>(&value),
|
reinterpret_cast<char*>(&received),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -79,10 +78,10 @@ void Foam::Pstream::combineGather
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< belowID << " data:" << value << endl;
|
<< belowID << " data:" << received << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
cop(Value, value);
|
cop(value, received);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -94,25 +93,25 @@ void Foam::Pstream::combineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
T value(fromBelow);
|
T received(fromBelow);
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< belowID << " data:" << value << endl;
|
<< belowID << " data:" << received << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
cop(Value, value);
|
cop(value, received);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send up Value
|
// Send up value
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
{
|
{
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " sending to " << myComm.above()
|
Pout<< " sending to " << myComm.above()
|
||||||
<< " data:" << Value << endl;
|
<< " data:" << value << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
@ -121,7 +120,7 @@ void Foam::Pstream::combineGather
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
reinterpret_cast<const char*>(&Value),
|
reinterpret_cast<const char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -137,7 +136,7 @@ void Foam::Pstream::combineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toAbove << Value;
|
toAbove << value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,49 +146,38 @@ void Foam::Pstream::combineGather
|
|||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
void Foam::Pstream::combineGather
|
void Foam::Pstream::combineGather
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
|
||||||
{
|
{
|
||||||
combineGather
|
combineGather
|
||||||
(
|
(
|
||||||
UPstream::linearCommunication(comm),
|
UPstream::whichCommunication(comm),
|
||||||
Value,
|
value,
|
||||||
cop,
|
cop,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
combineGather
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Value,
|
|
||||||
cop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::Pstream::combineScatter
|
void Foam::Pstream::combineScatter
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
|
Pstream::broadcast(value, comm);
|
||||||
|
#else
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
@ -201,7 +189,7 @@ void Foam::Pstream::combineScatter
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
reinterpret_cast<char*>(&Value),
|
reinterpret_cast<char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -217,25 +205,14 @@ void Foam::Pstream::combineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
Value = T(fromAbove);
|
value = T(fromAbove);
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " received from "
|
|
||||||
<< myComm.above() << " data:" << Value << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to my downstairs neighbours
|
// Send to my downstairs neighbours
|
||||||
forAllReverse(myComm.below(), belowI)
|
forAllReverse(myComm.below(), belowI)
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
const label belowID = myComm.below()[belowI];
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " sending to " << belowID << " data:" << Value << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
@ -243,7 +220,7 @@ void Foam::Pstream::combineScatter
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
reinterpret_cast<const char*>(&Value),
|
reinterpret_cast<const char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -259,29 +236,27 @@ void Foam::Pstream::combineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toBelow << Value;
|
toBelow << value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::Pstream::combineScatter
|
void Foam::Pstream::combineScatter
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
{
|
Pstream::broadcast(value, comm);
|
||||||
combineScatter(UPstream::linearCommunication(comm), Value, tag, comm);
|
#else
|
||||||
}
|
combineScatter(UPstream::whichCommunication(comm), value, tag, comm);
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
combineScatter(UPstream::treeCommunication(comm), Value, tag, comm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -289,7 +264,7 @@ template<class T, class CombineOp>
|
|||||||
void Foam::Pstream::listCombineGather
|
void Foam::Pstream::listCombineGather
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -297,24 +272,22 @@ void Foam::Pstream::listCombineGather
|
|||||||
{
|
{
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from my downstairs neighbours
|
// Receive from my downstairs neighbours
|
||||||
forAll(myComm.below(), belowI)
|
for (const label belowID : myComm.below())
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
List<T> receivedValues(Values.size());
|
List<T> received(values.size());
|
||||||
|
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
receivedValues.data_bytes(),
|
received.data_bytes(),
|
||||||
receivedValues.size_bytes(),
|
received.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -322,12 +295,12 @@ void Foam::Pstream::listCombineGather
|
|||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< belowID << " data:" << receivedValues << endl;
|
<< belowID << " data:" << received << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(Values, i)
|
forAll(values, i)
|
||||||
{
|
{
|
||||||
cop(Values[i], receivedValues[i]);
|
cop(values[i], received[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -340,28 +313,28 @@ void Foam::Pstream::listCombineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
List<T> receivedValues(fromBelow);
|
List<T> received(fromBelow);
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< belowID << " data:" << receivedValues << endl;
|
<< belowID << " data:" << received << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(Values, i)
|
forAll(values, i)
|
||||||
{
|
{
|
||||||
cop(Values[i], receivedValues[i]);
|
cop(values[i], received[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send up Value
|
// Send up values
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
{
|
{
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " sending to " << myComm.above()
|
Pout<< " sending to " << myComm.above()
|
||||||
<< " data:" << Values << endl;
|
<< " data:" << values << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
@ -370,8 +343,8 @@ void Foam::Pstream::listCombineGather
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
Values.cdata_bytes(),
|
values.cdata_bytes(),
|
||||||
Values.size_bytes(),
|
values.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -386,7 +359,7 @@ void Foam::Pstream::listCombineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toAbove << Values;
|
toAbove << values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,49 +369,38 @@ void Foam::Pstream::listCombineGather
|
|||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
void Foam::Pstream::listCombineGather
|
void Foam::Pstream::listCombineGather
|
||||||
(
|
(
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
|
||||||
{
|
{
|
||||||
listCombineGather
|
listCombineGather
|
||||||
(
|
(
|
||||||
UPstream::linearCommunication(comm),
|
UPstream::whichCommunication(comm),
|
||||||
Values,
|
values,
|
||||||
cop,
|
cop,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
listCombineGather
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Values,
|
|
||||||
cop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::Pstream::listCombineScatter
|
void Foam::Pstream::listCombineScatter
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
|
Pstream::broadcast(values, comm);
|
||||||
|
#else
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
@ -450,8 +412,8 @@ void Foam::Pstream::listCombineScatter
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
Values.data_bytes(),
|
values.data_bytes(),
|
||||||
Values.size_bytes(),
|
values.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -466,25 +428,14 @@ void Foam::Pstream::listCombineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromAbove >> Values;
|
fromAbove >> values;
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " received from "
|
|
||||||
<< myComm.above() << " data:" << Values << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to my downstairs neighbours
|
// Send to my downstairs neighbours
|
||||||
forAllReverse(myComm.below(), belowI)
|
forAllReverse(myComm.below(), belowI)
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
const label belowID = myComm.below()[belowI];
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " sending to " << belowID << " data:" << Values << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
@ -492,8 +443,8 @@ void Foam::Pstream::listCombineScatter
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
Values.cdata_bytes(),
|
values.cdata_bytes(),
|
||||||
Values.size_bytes(),
|
values.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -508,41 +459,33 @@ void Foam::Pstream::listCombineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toBelow << Values;
|
toBelow << values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Foam::Pstream::listCombineScatter
|
void Foam::Pstream::listCombineScatter
|
||||||
(
|
(
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
{
|
Pstream::broadcast(values, comm);
|
||||||
|
#else
|
||||||
listCombineScatter
|
listCombineScatter
|
||||||
(
|
(
|
||||||
UPstream::linearCommunication(comm),
|
UPstream::whichCommunication(comm),
|
||||||
Values,
|
values,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
}
|
#endif
|
||||||
else
|
|
||||||
{
|
|
||||||
listCombineScatter
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Values,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -550,7 +493,7 @@ template<class Container, class CombineOp>
|
|||||||
void Foam::Pstream::mapCombineGather
|
void Foam::Pstream::mapCombineGather
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
Container& Values,
|
Container& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -558,13 +501,13 @@ void Foam::Pstream::mapCombineGather
|
|||||||
{
|
{
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from my downstairs neighbours
|
// Receive from my downstairs neighbours
|
||||||
forAll(myComm.below(), belowI)
|
for (const label belowID : myComm.below())
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
// Map/HashTable: non-contiguous
|
||||||
|
|
||||||
IPstream fromBelow
|
IPstream fromBelow
|
||||||
(
|
(
|
||||||
@ -574,43 +517,43 @@ void Foam::Pstream::mapCombineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
Container receivedValues(fromBelow);
|
Container received(fromBelow);
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< belowID << " data:" << receivedValues << endl;
|
<< belowID << " data:" << received << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
typename Container::const_iterator slaveIter =
|
auto recvIter = received.cbegin();
|
||||||
receivedValues.begin();
|
recvIter != received.cend();
|
||||||
slaveIter != receivedValues.end();
|
++recvIter
|
||||||
++slaveIter
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typename Container::iterator
|
auto masterIter = values.find(recvIter.key());
|
||||||
masterIter = Values.find(slaveIter.key());
|
|
||||||
|
|
||||||
if (masterIter != Values.end())
|
if (masterIter != values.end()) // == found()
|
||||||
{
|
{
|
||||||
cop(masterIter(), slaveIter());
|
// Combine with existing
|
||||||
|
cop(masterIter.val(), recvIter.val());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Values.insert(slaveIter.key(), slaveIter());
|
// Insert new key/value
|
||||||
|
values.insert(recvIter.key(), recvIter.val());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send up Value
|
// Send up values
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
{
|
{
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " sending to " << myComm.above()
|
Pout<< " sending to " << myComm.above()
|
||||||
<< " data:" << Values << endl;
|
<< " data:" << values << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPstream toAbove
|
OPstream toAbove
|
||||||
@ -621,7 +564,7 @@ void Foam::Pstream::mapCombineGather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toAbove << Values;
|
toAbove << values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,49 +573,38 @@ void Foam::Pstream::mapCombineGather
|
|||||||
template<class Container, class CombineOp>
|
template<class Container, class CombineOp>
|
||||||
void Foam::Pstream::mapCombineGather
|
void Foam::Pstream::mapCombineGather
|
||||||
(
|
(
|
||||||
Container& Values,
|
Container& values,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
|
||||||
{
|
{
|
||||||
mapCombineGather
|
mapCombineGather
|
||||||
(
|
(
|
||||||
UPstream::linearCommunication(comm),
|
UPstream::whichCommunication(comm),
|
||||||
Values,
|
values,
|
||||||
cop,
|
cop,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
mapCombineGather
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Values,
|
|
||||||
cop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
void Foam::Pstream::mapCombineScatter
|
void Foam::Pstream::mapCombineScatter
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
Container& Values,
|
Container& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
|
Pstream::broadcast(values, comm);
|
||||||
|
#else
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
@ -686,23 +618,23 @@ void Foam::Pstream::mapCombineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromAbove >> Values;
|
fromAbove >> values;
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received from "
|
Pout<< " received from "
|
||||||
<< myComm.above() << " data:" << Values << endl;
|
<< myComm.above() << " data:" << values << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to my downstairs neighbours
|
// Send to my downstairs neighbours
|
||||||
forAllReverse(myComm.below(), belowI)
|
forAllReverse(myComm.below(), belowI)
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
const label belowID = myComm.below()[belowI];
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " sending to " << belowID << " data:" << Values << endl;
|
Pout<< " sending to " << belowID << " data:" << values << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
OPstream toBelow
|
OPstream toBelow
|
||||||
@ -713,40 +645,32 @@ void Foam::Pstream::mapCombineScatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toBelow << Values;
|
toBelow << values;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
void Foam::Pstream::mapCombineScatter
|
void Foam::Pstream::mapCombineScatter
|
||||||
(
|
(
|
||||||
Container& Values,
|
Container& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
{
|
Pstream::broadcast(values, comm);
|
||||||
|
#else
|
||||||
mapCombineScatter
|
mapCombineScatter
|
||||||
(
|
(
|
||||||
UPstream::linearCommunication(comm),
|
UPstream::whichCommunication(comm),
|
||||||
Values,
|
values,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
}
|
#endif
|
||||||
else
|
|
||||||
{
|
|
||||||
mapCombineScatter
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Values,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,11 +33,10 @@ Description
|
|||||||
combined using the given combination function and the result is
|
combined using the given combination function and the result is
|
||||||
broadcast to all nodes
|
broadcast to all nodes
|
||||||
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PstreamCombineReduceOps_H
|
#ifndef Foam_PstreamCombineReduceOps_H
|
||||||
#define PstreamCombineReduceOps_H
|
#define Foam_PstreamCombineReduceOps_H
|
||||||
|
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
@ -53,61 +53,32 @@ template<class T, class CombineOp>
|
|||||||
void combineReduce
|
void combineReduce
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Pstream::combineGather(comms, Value, cop, tag, comm);
|
Pstream::combineGather(comms, value, cop, tag, comm);
|
||||||
Pstream::combineScatter(comms, Value, tag, comm);
|
Pstream::broadcast(value, comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T, class CombineOp>
|
template<class T, class CombineOp>
|
||||||
void combineReduce
|
void combineReduce
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = Pstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
Pstream::combineGather
|
const auto& comms = UPstream::whichCommunication(comm);
|
||||||
(
|
|
||||||
UPstream::linearCommunication(comm),
|
Pstream::combineGather(comms, value, cop, tag, comm);
|
||||||
Value,
|
Pstream::broadcast(value, comm);
|
||||||
cop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
Pstream::combineScatter
|
|
||||||
(
|
|
||||||
UPstream::linearCommunication(comm),
|
|
||||||
Value,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Pstream::combineGather
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Value,
|
|
||||||
cop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
Pstream::combineScatter
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
Value,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -43,7 +43,7 @@ void Foam::Pstream::exchangeContainer
|
|||||||
List<Container>& recvBufs,
|
List<Container>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const label startOfRequests = Pstream::nRequests();
|
const label startOfRequests = Pstream::nRequests();
|
||||||
@ -91,7 +91,7 @@ void Foam::Pstream::exchangeContainer
|
|||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Cannot send outgoing message. "
|
<< "Cannot send outgoing message. "
|
||||||
<< "to:" << proci << " nBytes:"
|
<< "to:" << proci << " nBytes:"
|
||||||
<< label(sendBufs[proci].size()*sizeof(T))
|
<< label(sendBufs[proci].size_bytes())
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,9 +101,9 @@ void Foam::Pstream::exchangeContainer
|
|||||||
// Wait for all to finish
|
// Wait for all to finish
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if (block)
|
if (wait)
|
||||||
{
|
{
|
||||||
Pstream::waitRequests(startOfRequests);
|
UPstream::waitRequests(startOfRequests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ void Foam::Pstream::exchangeBuf
|
|||||||
List<char*>& recvBufs,
|
List<char*>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const label startOfRequests = Pstream::nRequests();
|
const label startOfRequests = Pstream::nRequests();
|
||||||
@ -175,9 +175,9 @@ void Foam::Pstream::exchangeBuf
|
|||||||
// Wait for all to finish
|
// Wait for all to finish
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
if (block)
|
if (wait)
|
||||||
{
|
{
|
||||||
Pstream::waitRequests(startOfRequests);
|
UPstream::waitRequests(startOfRequests);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ void Foam::Pstream::exchange
|
|||||||
List<Container>& recvBufs,
|
List<Container>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// OR static_assert(is_contiguous<T>::value, "Contiguous data only!")
|
// OR static_assert(is_contiguous<T>::value, "Contiguous data only!")
|
||||||
@ -209,7 +209,7 @@ void Foam::Pstream::exchange
|
|||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
recvBufs.setSize(sendBufs.size());
|
recvBufs.resize_nocopy(sendBufs.size());
|
||||||
|
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
@ -220,11 +220,11 @@ void Foam::Pstream::exchange
|
|||||||
|
|
||||||
if (proci != Pstream::myProcNo(comm) && nRecv > 0)
|
if (proci != Pstream::myProcNo(comm) && nRecv > 0)
|
||||||
{
|
{
|
||||||
recvBufs[proci].setSize(nRecv);
|
recvBufs[proci].resize_nocopy(nRecv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pstream::maxCommsSize <= 0)
|
if (UPstream::maxCommsSize <= int(sizeof(T)))
|
||||||
{
|
{
|
||||||
// Do the exchanging in one go
|
// Do the exchanging in one go
|
||||||
exchangeContainer<Container, T>
|
exchangeContainer<Container, T>
|
||||||
@ -234,7 +234,7 @@ void Foam::Pstream::exchange
|
|||||||
recvBufs,
|
recvBufs,
|
||||||
tag,
|
tag,
|
||||||
comm,
|
comm,
|
||||||
block
|
wait
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -244,55 +244,64 @@ void Foam::Pstream::exchange
|
|||||||
// guaranteed that some processor's sending size is some other
|
// guaranteed that some processor's sending size is some other
|
||||||
// processor's receive size. Also we can ignore any local comms.
|
// processor's receive size. Also we can ignore any local comms.
|
||||||
|
|
||||||
label maxNSend = 0;
|
// We need to send bytes so the number of iterations:
|
||||||
|
// maxChunkSize iterations
|
||||||
|
// ------------ ----------
|
||||||
|
// 0 0
|
||||||
|
// 1..maxChunkSize 1
|
||||||
|
// maxChunkSize+1..2*maxChunkSize 2
|
||||||
|
// etc.
|
||||||
|
|
||||||
|
const label maxChunkSize(UPstream::maxCommsSize/sizeof(T));
|
||||||
|
|
||||||
|
label nIter(0);
|
||||||
|
{
|
||||||
|
label nSendMax = 0;
|
||||||
forAll(sendBufs, proci)
|
forAll(sendBufs, proci)
|
||||||
{
|
{
|
||||||
if (proci != Pstream::myProcNo(comm))
|
if (proci != Pstream::myProcNo(comm))
|
||||||
{
|
{
|
||||||
maxNSend = max(maxNSend, sendBufs[proci].size());
|
nSendMax = max(nSendMax, sendBufs[proci].size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const label maxNBytes = sizeof(T)*maxNSend;
|
if (nSendMax)
|
||||||
|
|
||||||
// We need to send maxNBytes bytes so the number of iterations:
|
|
||||||
// maxNBytes iterations
|
|
||||||
// --------- ----------
|
|
||||||
// 0 0
|
|
||||||
// 1..maxCommsSize 1
|
|
||||||
// maxCommsSize+1..2*maxCommsSize 2
|
|
||||||
// etc.
|
|
||||||
|
|
||||||
label nIter;
|
|
||||||
if (maxNBytes == 0)
|
|
||||||
{
|
{
|
||||||
nIter = 0;
|
nIter = 1 + ((nSendMax-1)/maxChunkSize);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nIter = (maxNBytes-1)/Pstream::maxCommsSize+1;
|
|
||||||
}
|
}
|
||||||
reduce(nIter, maxOp<label>(), tag, comm);
|
reduce(nIter, maxOp<label>(), tag, comm);
|
||||||
|
|
||||||
|
/// Info<< "send " << nSendMax << " elements ("
|
||||||
List<const char*> charSendBufs(sendBufs.size());
|
/// << (nSendMax*sizeof(T)) << " bytes) in " << nIter
|
||||||
List<char*> charRecvBufs(sendBufs.size());
|
/// << " iterations of " << maxChunkSize << " chunks ("
|
||||||
|
/// << (maxChunkSize*sizeof(T)) << " bytes) maxCommsSize:"
|
||||||
|
/// << Pstream::maxCommsSize << endl;
|
||||||
|
}
|
||||||
|
|
||||||
labelList nRecv(sendBufs.size());
|
labelList nRecv(sendBufs.size());
|
||||||
labelList startRecv(sendBufs.size(), Zero);
|
|
||||||
labelList nSend(sendBufs.size());
|
labelList nSend(sendBufs.size());
|
||||||
|
labelList startRecv(sendBufs.size(), Zero);
|
||||||
labelList startSend(sendBufs.size(), Zero);
|
labelList startSend(sendBufs.size(), Zero);
|
||||||
|
|
||||||
for (label iter = 0; iter < nIter; iter++)
|
List<const char*> charPtrSend(sendBufs.size());
|
||||||
|
List<char*> charPtrRecv(sendBufs.size());
|
||||||
|
|
||||||
|
for (label iter = 0; iter < nIter; ++iter)
|
||||||
{
|
{
|
||||||
forAll(sendBufs, proci)
|
forAll(sendBufs, proci)
|
||||||
{
|
{
|
||||||
nSend[proci] = min
|
nSend[proci] = min
|
||||||
(
|
(
|
||||||
Pstream::maxCommsSize,
|
maxChunkSize,
|
||||||
sendBufs[proci].size()-startSend[proci]
|
sendBufs[proci].size()-startSend[proci]
|
||||||
);
|
);
|
||||||
charSendBufs[proci] =
|
nRecv[proci] = min
|
||||||
|
(
|
||||||
|
maxChunkSize,
|
||||||
|
recvBufs[proci].size()-startRecv[proci]
|
||||||
|
);
|
||||||
|
|
||||||
|
charPtrSend[proci] =
|
||||||
(
|
(
|
||||||
nSend[proci] > 0
|
nSend[proci] > 0
|
||||||
? reinterpret_cast<const char*>
|
? reinterpret_cast<const char*>
|
||||||
@ -301,14 +310,7 @@ void Foam::Pstream::exchange
|
|||||||
)
|
)
|
||||||
: nullptr
|
: nullptr
|
||||||
);
|
);
|
||||||
|
charPtrRecv[proci] =
|
||||||
nRecv[proci] = min
|
|
||||||
(
|
|
||||||
Pstream::maxCommsSize,
|
|
||||||
recvBufs[proci].size()-startRecv[proci]
|
|
||||||
);
|
|
||||||
|
|
||||||
charRecvBufs[proci] =
|
|
||||||
(
|
(
|
||||||
nRecv[proci] > 0
|
nRecv[proci] > 0
|
||||||
? reinterpret_cast<char*>
|
? reinterpret_cast<char*>
|
||||||
@ -319,15 +321,19 @@ void Foam::Pstream::exchange
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Info<< "iter " << iter
|
||||||
|
/// << ": beg=" << flatOutput(startSend)
|
||||||
|
/// << " len=" << flatOutput(nSend) << endl;
|
||||||
|
|
||||||
exchangeBuf<T>
|
exchangeBuf<T>
|
||||||
(
|
(
|
||||||
nSend,
|
nSend,
|
||||||
charSendBufs,
|
charPtrSend,
|
||||||
nRecv,
|
nRecv,
|
||||||
charRecvBufs,
|
charPtrRecv,
|
||||||
tag,
|
tag,
|
||||||
comm,
|
comm,
|
||||||
block
|
wait
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(nSend, proci)
|
forAll(nSend, proci)
|
||||||
@ -344,6 +350,83 @@ void Foam::Pstream::exchange
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Container>
|
||||||
|
void Foam::Pstream::exchangeSizes
|
||||||
|
(
|
||||||
|
const labelUList& sendProcs,
|
||||||
|
const labelUList& recvProcs,
|
||||||
|
const Container& sendBufs,
|
||||||
|
labelList& recvSizes,
|
||||||
|
const label tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (sendBufs.size() != UPstream::nProcs(comm))
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Size of container " << sendBufs.size()
|
||||||
|
<< " does not equal the number of processors "
|
||||||
|
<< UPstream::nProcs(comm)
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList sendSizes(sendProcs.size());
|
||||||
|
forAll(sendProcs, i)
|
||||||
|
{
|
||||||
|
sendSizes[i] = sendBufs[sendProcs[i]].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
recvSizes.resize_nocopy(sendBufs.size());
|
||||||
|
recvSizes = 0; // Ensure non-received entries are properly zeroed
|
||||||
|
|
||||||
|
const label startOfRequests = UPstream::nRequests();
|
||||||
|
|
||||||
|
for (const label proci : recvProcs)
|
||||||
|
{
|
||||||
|
UIPstream::read
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
proci,
|
||||||
|
reinterpret_cast<char*>(&recvSizes[proci]),
|
||||||
|
sizeof(label),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(sendProcs, i)
|
||||||
|
{
|
||||||
|
UOPstream::write
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
sendProcs[i],
|
||||||
|
reinterpret_cast<char*>(&sendSizes[i]),
|
||||||
|
sizeof(label),
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
UPstream::waitRequests(startOfRequests);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// FUTURE?
|
||||||
|
///
|
||||||
|
/// template<class Container>
|
||||||
|
/// void Foam::Pstream::exchangeSizes
|
||||||
|
/// (
|
||||||
|
/// const labelUList& neighProcs,
|
||||||
|
/// const Container& sendBufs,
|
||||||
|
/// labelList& recvSizes,
|
||||||
|
/// const label tag,
|
||||||
|
/// const label comm
|
||||||
|
/// )
|
||||||
|
/// {
|
||||||
|
/// exchangeSizes<Container>(neighProcs, neighProcs, sendBufs, tag, comm);
|
||||||
|
/// }
|
||||||
|
|
||||||
|
|
||||||
template<class Container>
|
template<class Container>
|
||||||
void Foam::Pstream::exchangeSizes
|
void Foam::Pstream::exchangeSizes
|
||||||
(
|
(
|
||||||
@ -366,8 +449,8 @@ void Foam::Pstream::exchangeSizes
|
|||||||
{
|
{
|
||||||
sendSizes[proci] = sendBufs[proci].size();
|
sendSizes[proci] = sendBufs[proci].size();
|
||||||
}
|
}
|
||||||
recvSizes.setSize(sendSizes.size());
|
recvSizes.resize_nocopy(sendSizes.size());
|
||||||
allToAll(sendSizes, recvSizes, comm);
|
UPstream::allToAll(sendSizes, recvSizes, comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -378,13 +461,13 @@ void Foam::Pstream::exchange
|
|||||||
List<Container>& recvBufs,
|
List<Container>& recvBufs,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
const bool block
|
const bool wait
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
labelList recvSizes;
|
labelList recvSizes;
|
||||||
exchangeSizes(sendBufs, recvSizes, comm);
|
exchangeSizes(sendBufs, recvSizes, comm);
|
||||||
|
|
||||||
exchange<Container, T>(sendBufs, recvSizes, recvBufs, tag, comm, block);
|
exchange<Container, T>(sendBufs, recvSizes, recvBufs, tag, comm, wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,24 +32,17 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "UOPstream.H"
|
|
||||||
#include "OPstream.H"
|
#include "OPstream.H"
|
||||||
#include "UIPstream.H"
|
|
||||||
#include "IPstream.H"
|
#include "IPstream.H"
|
||||||
#include "contiguous.H"
|
#include "contiguous.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void Pstream::gather
|
void Foam::Pstream::gather
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -57,21 +50,21 @@ void Pstream::gather
|
|||||||
{
|
{
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from my downstairs neighbours
|
// Receive from my downstairs neighbours
|
||||||
forAll(myComm.below(), belowI)
|
for (const label belowID : myComm.below())
|
||||||
{
|
{
|
||||||
T value;
|
T received;
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.below()[belowI],
|
belowID,
|
||||||
reinterpret_cast<char*>(&value),
|
reinterpret_cast<char*>(&received),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -82,18 +75,18 @@ void Pstream::gather
|
|||||||
IPstream fromBelow
|
IPstream fromBelow
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.below()[belowI],
|
belowID,
|
||||||
0,
|
0,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromBelow >> value;
|
fromBelow >> received;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = bop(Value, value);
|
value = bop(value, received);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send up Value
|
// Send up value
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
{
|
{
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
@ -102,7 +95,7 @@ void Pstream::gather
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
reinterpret_cast<const char*>(&Value),
|
reinterpret_cast<const char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -118,7 +111,7 @@ void Pstream::gather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toAbove << Value;
|
toAbove << value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,37 +119,33 @@ void Pstream::gather
|
|||||||
|
|
||||||
|
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void Pstream::gather
|
void Foam::Pstream::gather
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
gather(UPstream::whichCommunication(comm), value, bop, tag, comm);
|
||||||
{
|
|
||||||
gather(UPstream::linearCommunication(comm), Value, bop, tag, comm);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gather(UPstream::treeCommunication(comm), Value, bop, tag, comm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::scatter
|
void Foam::Pstream::scatter
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
|
Pstream::broadcast(value, comm);
|
||||||
|
#else
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
@ -168,7 +157,7 @@ void Pstream::scatter
|
|||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
reinterpret_cast<char*>(&Value),
|
reinterpret_cast<char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -184,7 +173,7 @@ void Pstream::scatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromAbove >> Value;
|
fromAbove >> value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,13 +182,15 @@ void Pstream::scatter
|
|||||||
// (only when using a tree schedule!) first.
|
// (only when using a tree schedule!) first.
|
||||||
forAllReverse(myComm.below(), belowI)
|
forAllReverse(myComm.below(), belowI)
|
||||||
{
|
{
|
||||||
|
const label belowID = myComm.below()[belowI];
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
UOPstream::write
|
UOPstream::write
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.below()[belowI],
|
belowID,
|
||||||
reinterpret_cast<const char*>(&Value),
|
reinterpret_cast<const char*>(&value),
|
||||||
sizeof(T),
|
sizeof(T),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
@ -210,34 +201,28 @@ void Pstream::scatter
|
|||||||
OPstream toBelow
|
OPstream toBelow
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.below()[belowI],
|
belowID,
|
||||||
0,
|
0,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toBelow << Value;
|
toBelow << value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::scatter(T& Value, const int tag, const label comm)
|
void Foam::Pstream::scatter(T& value, const int tag, const label comm)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||||
{
|
Pstream::broadcast(value, comm);
|
||||||
scatter(UPstream::linearCommunication(comm), Value, tag, comm);
|
#else
|
||||||
}
|
scatter(UPstream::whichCommunication(comm), value, tag, comm);
|
||||||
else
|
#endif
|
||||||
{
|
|
||||||
scatter(UPstream::treeCommunication(comm), Value, tag, comm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -29,7 +29,7 @@ Description
|
|||||||
communication schedule (usually linear-to-master or tree-to-master).
|
communication schedule (usually linear-to-master or tree-to-master).
|
||||||
The gathered data will be a list with element procID the data from processor
|
The gathered data will be a list with element procID the data from processor
|
||||||
procID. Before calling every processor should insert its value into
|
procID. Before calling every processor should insert its value into
|
||||||
Values[UPstream::myProcNo(comm)].
|
values[UPstream::myProcNo(comm)].
|
||||||
Note: after gather every processor only knows its own data and that of the
|
Note: after gather every processor only knows its own data and that of the
|
||||||
processors below it. Only the 'master' of the communication schedule holds
|
processors below it. Only the 'master' of the communication schedule holds
|
||||||
a fully filled List. Use scatter to distribute the data.
|
a fully filled List. Use scatter to distribute the data.
|
||||||
@ -40,61 +40,55 @@ Description
|
|||||||
#include "OPstream.H"
|
#include "OPstream.H"
|
||||||
#include "contiguous.H"
|
#include "contiguous.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::gatherList
|
void Foam::Pstream::gatherList
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
if (Values.size() != UPstream::nProcs(comm))
|
if (values.size() != UPstream::nProcs(comm))
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Size of list:" << Values.size()
|
<< "Size of list:" << values.size()
|
||||||
<< " does not equal the number of processors:"
|
<< " does not equal the number of processors:"
|
||||||
<< UPstream::nProcs(comm)
|
<< UPstream::nProcs(comm)
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from my downstairs neighbours
|
// Receive from my downstairs neighbours
|
||||||
forAll(myComm.below(), belowI)
|
for (const label belowID : myComm.below())
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
|
||||||
const labelList& belowLeaves = comms[belowID].allBelow();
|
const labelList& belowLeaves = comms[belowID].allBelow();
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
List<T> receivedValues(belowLeaves.size() + 1);
|
List<T> received(belowLeaves.size() + 1);
|
||||||
|
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
receivedValues.data_bytes(),
|
received.data_bytes(),
|
||||||
receivedValues.size_bytes(),
|
received.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
|
|
||||||
Values[belowID] = receivedValues[0];
|
values[belowID] = received[0];
|
||||||
|
|
||||||
forAll(belowLeaves, leafI)
|
forAll(belowLeaves, leafI)
|
||||||
{
|
{
|
||||||
Values[belowLeaves[leafI]] = receivedValues[leafI + 1];
|
values[belowLeaves[leafI]] = received[leafI + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -107,32 +101,31 @@ void Pstream::gatherList
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromBelow >> Values[belowID];
|
fromBelow >> values[belowID];
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received through "
|
Pout<< " received through "
|
||||||
<< belowID << " data from:" << belowID
|
<< belowID << " data from:" << belowID
|
||||||
<< " data:" << Values[belowID] << endl;
|
<< " data:" << values[belowID] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive from all other processors below belowID
|
// Receive from all other processors below belowID
|
||||||
forAll(belowLeaves, leafI)
|
for (const label leafID : belowLeaves)
|
||||||
{
|
{
|
||||||
label leafID = belowLeaves[leafI];
|
fromBelow >> values[leafID];
|
||||||
fromBelow >> Values[leafID];
|
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " received through "
|
Pout<< " received through "
|
||||||
<< belowID << " data from:" << leafID
|
<< belowID << " data from:" << leafID
|
||||||
<< " data:" << Values[leafID] << endl;
|
<< " data:" << values[leafID] << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send up from Values:
|
// Send up from values:
|
||||||
// - my own value first
|
// - my own value first
|
||||||
// - all belowLeaves next
|
// - all belowLeaves next
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
@ -143,25 +136,25 @@ void Pstream::gatherList
|
|||||||
{
|
{
|
||||||
Pout<< " sending to " << myComm.above()
|
Pout<< " sending to " << myComm.above()
|
||||||
<< " data from me:" << UPstream::myProcNo(comm)
|
<< " data from me:" << UPstream::myProcNo(comm)
|
||||||
<< " data:" << Values[UPstream::myProcNo(comm)] << endl;
|
<< " data:" << values[UPstream::myProcNo(comm)] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
List<T> sendingValues(belowLeaves.size() + 1);
|
List<T> sending(belowLeaves.size() + 1);
|
||||||
sendingValues[0] = Values[UPstream::myProcNo(comm)];
|
sending[0] = values[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
forAll(belowLeaves, leafI)
|
forAll(belowLeaves, leafI)
|
||||||
{
|
{
|
||||||
sendingValues[leafI + 1] = Values[belowLeaves[leafI]];
|
sending[leafI + 1] = values[belowLeaves[leafI]];
|
||||||
}
|
}
|
||||||
|
|
||||||
OPstream::write
|
UOPstream::write
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
sendingValues.cdata_bytes(),
|
sending.cdata_bytes(),
|
||||||
sendingValues.size_bytes(),
|
sending.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -176,19 +169,17 @@ void Pstream::gatherList
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toAbove << Values[UPstream::myProcNo(comm)];
|
toAbove << values[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
forAll(belowLeaves, leafI)
|
for (const label leafID : belowLeaves)
|
||||||
{
|
{
|
||||||
label leafID = belowLeaves[leafI];
|
|
||||||
|
|
||||||
if (debug & 2)
|
if (debug & 2)
|
||||||
{
|
{
|
||||||
Pout<< " sending to "
|
Pout<< " sending to "
|
||||||
<< myComm.above() << " data from:" << leafID
|
<< myComm.above() << " data from:" << leafID
|
||||||
<< " data:" << Values[leafID] << endl;
|
<< " data:" << values[leafID] << endl;
|
||||||
}
|
}
|
||||||
toAbove << Values[leafID];
|
toAbove << values[leafID];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,40 +188,37 @@ void Pstream::gatherList
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::gatherList(List<T>& Values, const int tag, const label comm)
|
void Foam::Pstream::gatherList(List<T>& values, const int tag, const label comm)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
gatherList(UPstream::whichCommunication(comm), values, tag, comm);
|
||||||
{
|
|
||||||
gatherList(UPstream::linearCommunication(comm), Values, tag, comm);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gatherList(UPstream::treeCommunication(comm), Values, tag, comm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::scatterList
|
void Foam::Pstream::scatterList
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
List<T>& Values,
|
List<T>& values,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// Apart from the additional (size == nProcs) check, the only difference
|
||||||
|
// between scatterList() and using broadcast(List<T>&) or a regular
|
||||||
|
// scatter(List<T>&) is that processor-local data is skipped.
|
||||||
|
|
||||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
{
|
{
|
||||||
if (Values.size() != UPstream::nProcs(comm))
|
if (values.size() != UPstream::nProcs(comm))
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Size of list:" << Values.size()
|
<< "Size of list:" << values.size()
|
||||||
<< " does not equal the number of processors:"
|
<< " does not equal the number of processors:"
|
||||||
<< UPstream::nProcs(comm)
|
<< UPstream::nProcs(comm)
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
@ -240,21 +228,21 @@ void Pstream::scatterList
|
|||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
List<T> receivedValues(notBelowLeaves.size());
|
List<T> received(notBelowLeaves.size());
|
||||||
|
|
||||||
UIPstream::read
|
UIPstream::read
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
myComm.above(),
|
myComm.above(),
|
||||||
receivedValues.data_bytes(),
|
received.data_bytes(),
|
||||||
receivedValues.size_bytes(),
|
received.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(notBelowLeaves, leafI)
|
forAll(notBelowLeaves, leafI)
|
||||||
{
|
{
|
||||||
Values[notBelowLeaves[leafI]] = receivedValues[leafI];
|
values[notBelowLeaves[leafI]] = received[leafI];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -268,16 +256,15 @@ void Pstream::scatterList
|
|||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(notBelowLeaves, leafI)
|
for (const label leafID : notBelowLeaves)
|
||||||
{
|
{
|
||||||
label leafID = notBelowLeaves[leafI];
|
fromAbove >> values[leafID];
|
||||||
fromAbove >> Values[leafID];
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< " received through "
|
Pout<< " received through "
|
||||||
<< myComm.above() << " data for:" << leafID
|
<< myComm.above() << " data for:" << leafID
|
||||||
<< " data:" << Values[leafID] << endl;
|
<< " data:" << values[leafID] << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -286,24 +273,24 @@ void Pstream::scatterList
|
|||||||
// Send to my downstairs neighbours
|
// Send to my downstairs neighbours
|
||||||
forAllReverse(myComm.below(), belowI)
|
forAllReverse(myComm.below(), belowI)
|
||||||
{
|
{
|
||||||
label belowID = myComm.below()[belowI];
|
const label belowID = myComm.below()[belowI];
|
||||||
const labelList& notBelowLeaves = comms[belowID].allNotBelow();
|
const labelList& notBelowLeaves = comms[belowID].allNotBelow();
|
||||||
|
|
||||||
if (is_contiguous<T>::value)
|
if (is_contiguous<T>::value)
|
||||||
{
|
{
|
||||||
List<T> sendingValues(notBelowLeaves.size());
|
List<T> sending(notBelowLeaves.size());
|
||||||
|
|
||||||
forAll(notBelowLeaves, leafI)
|
forAll(notBelowLeaves, leafI)
|
||||||
{
|
{
|
||||||
sendingValues[leafI] = Values[notBelowLeaves[leafI]];
|
sending[leafI] = values[notBelowLeaves[leafI]];
|
||||||
}
|
}
|
||||||
|
|
||||||
OPstream::write
|
UOPstream::write
|
||||||
(
|
(
|
||||||
UPstream::commsTypes::scheduled,
|
UPstream::commsTypes::scheduled,
|
||||||
belowID,
|
belowID,
|
||||||
sendingValues.cdata_bytes(),
|
sending.cdata_bytes(),
|
||||||
sendingValues.size_bytes(),
|
sending.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -320,16 +307,15 @@ void Pstream::scatterList
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Send data destined for all other processors below belowID
|
// Send data destined for all other processors below belowID
|
||||||
forAll(notBelowLeaves, leafI)
|
for (const label leafID : notBelowLeaves)
|
||||||
{
|
{
|
||||||
label leafID = notBelowLeaves[leafI];
|
toBelow << values[leafID];
|
||||||
toBelow << Values[leafID];
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< " sent through "
|
Pout<< " sent through "
|
||||||
<< belowID << " data for:" << leafID
|
<< belowID << " data for:" << leafID
|
||||||
<< " data:" << Values[leafID] << endl;
|
<< " data:" << values[leafID] << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,21 +325,15 @@ void Pstream::scatterList
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void Pstream::scatterList(List<T>& Values, const int tag, const label comm)
|
void Foam::Pstream::scatterList
|
||||||
|
(
|
||||||
|
List<T>& values,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
scatterList(UPstream::whichCommunication(comm), values, tag, comm);
|
||||||
{
|
|
||||||
scatterList(UPstream::linearCommunication(comm), Values, tag, comm);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scatterList(UPstream::treeCommunication(comm), Values, tag, comm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -32,11 +32,11 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PstreamReduceOps_H
|
#ifndef Foam_PstreamReduceOps_H
|
||||||
#define PstreamReduceOps_H
|
#define Foam_PstreamReduceOps_H
|
||||||
|
|
||||||
#include "ops.H"
|
#include "ops.H"
|
||||||
#include "vector2D.H"
|
#include "FixedList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -45,12 +45,12 @@ namespace Foam
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Reduce operation with user specified communication schedule
|
//- Reduce operation with user specified communication schedule
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
const List<UPstream::commsStruct>& comms,
|
const List<UPstream::commsStruct>& comms,
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm
|
const label comm
|
||||||
@ -58,96 +58,85 @@ void reduce
|
|||||||
{
|
{
|
||||||
if (UPstream::warnComm != -1 && comm != UPstream::warnComm)
|
if (UPstream::warnComm != -1 && comm != UPstream::warnComm)
|
||||||
{
|
{
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << comm
|
Pout<< "** reducing:" << value << " with comm:" << comm << endl;
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
error::printStack(Pout);
|
||||||
}
|
}
|
||||||
Pstream::gather(comms, Value, bop, tag, comm);
|
Pstream::gather(comms, value, bop, tag, comm);
|
||||||
Pstream::scatter(comms, Value, tag, comm);
|
Pstream::broadcast(value, comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reduce using either linear or tree communication schedule
|
//- Reduce (inplace) using either linear or tree communication schedule
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
if (UPstream::parRun())
|
||||||
{
|
{
|
||||||
reduce(UPstream::linearCommunication(comm), Value, bop, tag, comm);
|
reduce(UPstream::whichCommunication(comm), value, bop, tag, comm);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reduce(UPstream::treeCommunication(comm), Value, bop, tag, comm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reduce using either linear or tree communication schedule
|
//- Reduce (copy) and return value
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
T returnReduce
|
T returnReduce
|
||||||
(
|
(
|
||||||
const T& Value,
|
const T& value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp& bop,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
T WorkValue(Value);
|
T work(value);
|
||||||
|
reduce(work, bop, tag, comm);
|
||||||
if (UPstream::nProcs(comm) < UPstream::nProcsSimpleSum)
|
return work;
|
||||||
{
|
|
||||||
reduce
|
|
||||||
(
|
|
||||||
UPstream::linearCommunication(comm),
|
|
||||||
WorkValue,
|
|
||||||
bop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reduce
|
|
||||||
(
|
|
||||||
UPstream::treeCommunication(comm),
|
|
||||||
WorkValue,
|
|
||||||
bop,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return WorkValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reduce with sum of both value and count (for averaging)
|
//- Reduce with sum of both value and count (for averaging)
|
||||||
template<class T>
|
template<class T>
|
||||||
void sumReduce
|
void sumReduce
|
||||||
(
|
(
|
||||||
T& Value,
|
T& value,
|
||||||
label& Count,
|
label& count,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
reduce(Value, sumOp<T>(), tag, comm);
|
if (UPstream::parRun())
|
||||||
reduce(Count, sumOp<label>(), tag, comm);
|
{
|
||||||
|
reduce(value, sumOp<T>(), tag, comm);
|
||||||
|
reduce(count, sumOp<label>(), tag, comm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Non-blocking version of reduce. Sets request.
|
//- Reduce multiple values (identical size on all processes!)
|
||||||
|
template<class T, class BinaryOp>
|
||||||
|
void reduce
|
||||||
|
(
|
||||||
|
T values[],
|
||||||
|
const int size,
|
||||||
|
const BinaryOp&,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Non-blocking reduce single value. Sets request.
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
T& Value,
|
T& Value,
|
||||||
const BinaryOp& bop,
|
const BinaryOp&,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
label& request
|
label& request
|
||||||
@ -156,13 +145,14 @@ void reduce
|
|||||||
NotImplemented;
|
NotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-blocking version of reduce. Sets request.
|
//- Non-blocking reduce multiple values (identical size on all processes!)
|
||||||
|
//- Sets request.
|
||||||
template<class T, class BinaryOp>
|
template<class T, class BinaryOp>
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
T Value[],
|
T values[],
|
||||||
const int size,
|
const int size,
|
||||||
const BinaryOp& bop,
|
const BinaryOp&,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label comm,
|
||||||
label& request
|
label& request
|
||||||
@ -172,111 +162,139 @@ void reduce
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Insist there are specialisations for the common reductions of scalar(s)
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for bool
|
||||||
|
|
||||||
|
//- Logical (and) reduction
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
scalar& Value,
|
bool& value,
|
||||||
const sumOp<scalar>& bop,
|
const andOp<bool>&,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(), /*!< (ignored) */
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Logical (or) reduction
|
||||||
void reduce
|
void reduce
|
||||||
(
|
(
|
||||||
scalar& Value,
|
bool& value,
|
||||||
const minOp<scalar>& bop,
|
const orOp<bool>&,
|
||||||
const int tag = Pstream::msgType(),
|
const int tag = UPstream::msgType(), /*!< (ignored) */
|
||||||
const label comm = UPstream::worldComm
|
const label comm = UPstream::worldComm
|
||||||
);
|
);
|
||||||
|
|
||||||
void reduce
|
|
||||||
(
|
|
||||||
vector2D& Value,
|
|
||||||
const sumOp<vector2D>& bop,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void sumReduce
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
label& Count,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
// Specialisations for common reduction types
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
const sumOp<scalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm,
|
|
||||||
label& request
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
#undef Pstream_CommonReductions
|
||||||
(
|
#define Pstream_CommonReductions(Native) \
|
||||||
scalar Value[],
|
\
|
||||||
const int size,
|
/*! \brief Reduce (min) single Native value */ \
|
||||||
const sumOp<scalar>& bop,
|
void reduce \
|
||||||
const int tag,
|
( \
|
||||||
const label comm,
|
Native& value, \
|
||||||
label& request
|
const minOp<Native>&, \
|
||||||
|
const int tag = UPstream::msgType(), /*!< (ignored) */ \
|
||||||
|
const label comm = UPstream::worldComm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Reduce (max) single Native value */ \
|
||||||
|
void reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const maxOp<Native>&, \
|
||||||
|
const int tag = UPstream::msgType(), /*!< (ignored) */ \
|
||||||
|
const label comm = UPstream::worldComm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Reduce (sum) single Native value */ \
|
||||||
|
void reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag = UPstream::msgType(), /*!< (ignored) */ \
|
||||||
|
const label comm = UPstream::worldComm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Reduce (sum) multiple Native values (identical size all procs!) */ \
|
||||||
|
void reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /*!< (ignored) */ \
|
||||||
|
const label comm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Reduce (sum) multiple Native values */ \
|
||||||
|
template<unsigned N> \
|
||||||
|
inline void reduce \
|
||||||
|
( \
|
||||||
|
FixedList<Native, N>& values, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag = UPstream::msgType(), /*!< (ignored) */ \
|
||||||
|
const label comm = UPstream::worldComm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
reduce(values.data(), int(values.size()), sumOp<Native>(), tag, comm); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pstream_CommonReductions(int32_t);
|
||||||
|
Pstream_CommonReductions(int64_t);
|
||||||
|
Pstream_CommonReductions(uint32_t);
|
||||||
|
Pstream_CommonReductions(uint64_t);
|
||||||
|
Pstream_CommonReductions(float);
|
||||||
|
Pstream_CommonReductions(double);
|
||||||
|
|
||||||
|
#undef Pstream_CommonReductions
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for floating-point types
|
||||||
|
|
||||||
|
#undef Pstream_FloatReductions
|
||||||
|
#define Pstream_FloatReductions(Native) \
|
||||||
|
\
|
||||||
|
/*! \brief Sum of both Native value and count (for averaging) */ \
|
||||||
|
void sumReduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
label& count, \
|
||||||
|
const int tag = UPstream::msgType(), /*!< (ignored) */ \
|
||||||
|
const label comm = UPstream::worldComm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Non-blocking reduce (sum) single Native value. Sets request */ \
|
||||||
|
void reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /*!< (ignored) */ \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
/*! \brief Non-blocking reduce (sum) multiple Native values. Sets request */ \
|
||||||
|
void reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /*!< (ignored) */ \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
#if defined(WM_SPDP)
|
Pstream_FloatReductions(float);
|
||||||
void reduce
|
Pstream_FloatReductions(double);
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
#undef Pstream_FloatReductions
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const minOp<solveScalar>& bop,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
|
||||||
(
|
|
||||||
Vector2D<solveScalar>& Value,
|
|
||||||
const sumOp<Vector2D<solveScalar>>& bop,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void sumReduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
label& Count,
|
|
||||||
const int tag = Pstream::msgType(),
|
|
||||||
const label comm = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm,
|
|
||||||
label& request
|
|
||||||
);
|
|
||||||
|
|
||||||
void reduce
|
|
||||||
(
|
|
||||||
solveScalar Value[],
|
|
||||||
const int size,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm,
|
|
||||||
label& request
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -25,24 +25,26 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::UIPstream
|
Foam::UIPstreamBase
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Input inter-processor communications stream operating on external
|
Base class for input inter-processor communications stream
|
||||||
buffer.
|
(ie, parallel streams).
|
||||||
|
Not to be used directly, thus contructors are protected.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
UIPstream.C
|
UIPstreamBase.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
#ifndef UIPstream_H
|
#ifndef Foam_UIPstream_H
|
||||||
#define UIPstream_H
|
#define Foam_UIPstream_H
|
||||||
|
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
#include "Istream.H"
|
#include "Istream.H"
|
||||||
|
#include "DynamicList.H"
|
||||||
#include "PstreamBuffers.H"
|
#include "PstreamBuffers.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
@ -51,31 +53,14 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class UIPstream Declaration
|
Class UIPstreamBase Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class UIPstream
|
class UIPstreamBase
|
||||||
:
|
:
|
||||||
public UPstream,
|
public UPstream,
|
||||||
public Istream
|
public Istream
|
||||||
{
|
{
|
||||||
// Private Data
|
|
||||||
|
|
||||||
int fromProcNo_;
|
|
||||||
|
|
||||||
DynamicList<char>& recvBuf_;
|
|
||||||
|
|
||||||
label& recvBufPos_;
|
|
||||||
|
|
||||||
const int tag_;
|
|
||||||
|
|
||||||
const label comm_;
|
|
||||||
|
|
||||||
const bool clearAtEnd_;
|
|
||||||
|
|
||||||
int messageSize_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Check buffer position against messageSize_ for EOF
|
//- Check buffer position against messageSize_ for EOF
|
||||||
@ -96,14 +81,31 @@ class UIPstream
|
|||||||
inline Istream& readString(std::string& str);
|
inline Istream& readString(std::string& str);
|
||||||
|
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
// Constructors
|
// Protected Data
|
||||||
|
|
||||||
|
int fromProcNo_;
|
||||||
|
|
||||||
|
DynamicList<char>& recvBuf_;
|
||||||
|
|
||||||
|
label& recvBufPos_;
|
||||||
|
|
||||||
|
const int tag_;
|
||||||
|
|
||||||
|
const label comm_;
|
||||||
|
|
||||||
|
const bool clearAtEnd_;
|
||||||
|
|
||||||
|
int messageSize_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Constructors
|
||||||
|
|
||||||
//- Construct given process index to read from using the given
|
//- Construct given process index to read from using the given
|
||||||
//- attached receive buffer, optional communication characteristics
|
//- attached receive buffer, optional communication characteristics
|
||||||
//- and IO format
|
//- and IO format
|
||||||
UIPstream
|
UIPstreamBase
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int fromProcNo,
|
const int fromProcNo,
|
||||||
@ -116,11 +118,14 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
//- Construct given buffers
|
//- Construct given buffers
|
||||||
UIPstream(const int fromProcNo, PstreamBuffers& buffers);
|
UIPstreamBase(const int fromProcNo, PstreamBuffers& buffers);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
public:
|
||||||
~UIPstream();
|
|
||||||
|
|
||||||
|
//- Destructor. Optionally clears external receive buffer.
|
||||||
|
virtual ~UIPstreamBase();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
@ -128,7 +133,7 @@ public:
|
|||||||
// Inquiry
|
// Inquiry
|
||||||
|
|
||||||
//- Return flags of output stream
|
//- Return flags of output stream
|
||||||
ios_base::fmtflags flags() const
|
virtual ios_base::fmtflags flags() const
|
||||||
{
|
{
|
||||||
return ios_base::fmtflags(0);
|
return ios_base::fmtflags(0);
|
||||||
}
|
}
|
||||||
@ -136,18 +141,6 @@ public:
|
|||||||
|
|
||||||
// Read Functions
|
// Read Functions
|
||||||
|
|
||||||
//- Read into given buffer from given processor
|
|
||||||
// \return the message size
|
|
||||||
static label read
|
|
||||||
(
|
|
||||||
const commsTypes commsType,
|
|
||||||
const int fromProcNo,
|
|
||||||
char* buf,
|
|
||||||
const std::streamsize bufSize,
|
|
||||||
const int tag = UPstream::msgType(),
|
|
||||||
const label communicator = UPstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Return next token from stream
|
//- Return next token from stream
|
||||||
Istream& read(token& t);
|
Istream& read(token& t);
|
||||||
|
|
||||||
@ -184,14 +177,17 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Rewind the stream so that it may be read again
|
|
||||||
void rewind();
|
// Positioning
|
||||||
|
|
||||||
|
//- Rewind the receive stream position so that it may be read again
|
||||||
|
virtual void rewind();
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
//- Set flags of stream
|
//- Set flags of stream
|
||||||
ios_base::fmtflags flags(const ios_base::fmtflags)
|
virtual ios_base::fmtflags flags(const ios_base::fmtflags)
|
||||||
{
|
{
|
||||||
return ios_base::fmtflags(0);
|
return ios_base::fmtflags(0);
|
||||||
}
|
}
|
||||||
@ -204,6 +200,133 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class UIPstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Input inter-processor communications stream
|
||||||
|
//- using MPI send/recv etc. - operating on external buffer.
|
||||||
|
class UIPstream
|
||||||
|
:
|
||||||
|
public UIPstreamBase
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Initial buffer recv, called by constructor (blocking | scheduled)
|
||||||
|
void bufferIPCrecv();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given process index to read from using the given
|
||||||
|
//- attached receive buffer, optional communication characteristics
|
||||||
|
//- and IO format
|
||||||
|
UIPstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int fromProcNo,
|
||||||
|
DynamicList<char>& receiveBuf,
|
||||||
|
label& receiveBufPosition,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
const bool clearAtEnd = false, // destroy receiveBuf if at end
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct given buffers
|
||||||
|
UIPstream(const int fromProcNo, PstreamBuffers& buffers);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~UIPstream() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Use all read methods from base
|
||||||
|
using UIPstreamBase::read;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Functions
|
||||||
|
|
||||||
|
//- Read buffer contents from given processor
|
||||||
|
// \return the message size
|
||||||
|
static label read
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int fromProcNo,
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class UIPBstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Input inter-processor communications stream
|
||||||
|
//- using MPI broadcast - operating on external buffer.
|
||||||
|
class UIPBstream
|
||||||
|
:
|
||||||
|
public UIPstreamBase
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Initial buffer recv via broadcast, called by constructor
|
||||||
|
void bufferIPCrecv();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given process index to read from using the given
|
||||||
|
//- attached receive buffer, optional communication characteristics
|
||||||
|
//- and IO format
|
||||||
|
UIPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType, //!< ignored
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
DynamicList<char>& receiveBuf,
|
||||||
|
label& receiveBufPosition,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
const bool clearAtEnd = false, //!< destroy receiveBuf if at end
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~UIPBstream() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Use all read methods from base
|
||||||
|
using UIPstreamBase::read;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Functions
|
||||||
|
|
||||||
|
//- Wrapped version of UPstream::broadcast
|
||||||
|
// \return the message size
|
||||||
|
static label read
|
||||||
|
(
|
||||||
|
const commsTypes commsTypes, //!< ignored
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -74,7 +74,7 @@ inline static label byteAlign(const label pos, const size_t align)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
inline void Foam::UIPstream::checkEof()
|
inline void Foam::UIPstreamBase::checkEof()
|
||||||
{
|
{
|
||||||
if (recvBufPos_ == messageSize_)
|
if (recvBufPos_ == messageSize_)
|
||||||
{
|
{
|
||||||
@ -83,14 +83,14 @@ inline void Foam::UIPstream::checkEof()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::UIPstream::prepareBuffer(const size_t align)
|
inline void Foam::UIPstreamBase::prepareBuffer(const size_t align)
|
||||||
{
|
{
|
||||||
recvBufPos_ = byteAlign(recvBufPos_, align);
|
recvBufPos_ = byteAlign(recvBufPos_, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void Foam::UIPstream::readFromBuffer(T& val)
|
inline void Foam::UIPstreamBase::readFromBuffer(T& val)
|
||||||
{
|
{
|
||||||
prepareBuffer(sizeof(T));
|
prepareBuffer(sizeof(T));
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ inline void Foam::UIPstream::readFromBuffer(T& val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::UIPstream::readFromBuffer
|
inline void Foam::UIPstreamBase::readFromBuffer
|
||||||
(
|
(
|
||||||
void* data,
|
void* data,
|
||||||
const size_t count
|
const size_t count
|
||||||
@ -119,7 +119,7 @@ inline void Foam::UIPstream::readFromBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::Istream& Foam::UIPstream::readString(std::string& str)
|
inline Foam::Istream& Foam::UIPstreamBase::readString(std::string& str)
|
||||||
{
|
{
|
||||||
// Use std::string::assign() to copy content, including '\0'.
|
// Use std::string::assign() to copy content, including '\0'.
|
||||||
// Stripping (when desired) is the responsibility of the sending side.
|
// Stripping (when desired) is the responsibility of the sending side.
|
||||||
@ -142,15 +142,78 @@ inline Foam::Istream& Foam::UIPstream::readString(std::string& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::UIPstreamBase::UIPstreamBase
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int fromProcNo,
|
||||||
|
DynamicList<char>& receiveBuf,
|
||||||
|
label& receiveBufPosition,
|
||||||
|
const int tag,
|
||||||
|
const label comm,
|
||||||
|
const bool clearAtEnd,
|
||||||
|
IOstreamOption::streamFormat fmt
|
||||||
|
)
|
||||||
|
:
|
||||||
|
UPstream(commsType),
|
||||||
|
Istream(fmt, IOstreamOption::currentVersion),
|
||||||
|
fromProcNo_(fromProcNo),
|
||||||
|
recvBuf_(receiveBuf),
|
||||||
|
recvBufPos_(receiveBufPosition),
|
||||||
|
tag_(tag),
|
||||||
|
comm_(comm),
|
||||||
|
clearAtEnd_(clearAtEnd),
|
||||||
|
messageSize_(0)
|
||||||
|
{
|
||||||
|
setOpened();
|
||||||
|
setGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::UIPstreamBase::UIPstreamBase
|
||||||
|
(
|
||||||
|
const int fromProcNo,
|
||||||
|
PstreamBuffers& buffers
|
||||||
|
)
|
||||||
|
:
|
||||||
|
UPstream(buffers.commsType()),
|
||||||
|
Istream(buffers.format(), IOstreamOption::currentVersion),
|
||||||
|
fromProcNo_(fromProcNo),
|
||||||
|
recvBuf_(buffers.recvBuf_[fromProcNo]),
|
||||||
|
recvBufPos_(buffers.recvBufPos_[fromProcNo]),
|
||||||
|
tag_(buffers.tag()),
|
||||||
|
comm_(buffers.comm()),
|
||||||
|
clearAtEnd_(buffers.allowClearRecv()),
|
||||||
|
messageSize_(0)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
commsType() != UPstream::commsTypes::scheduled
|
||||||
|
&& !buffers.finished()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "PstreamBuffers::finishedSends() never called." << endl
|
||||||
|
<< "Please call PstreamBuffers::finishedSends() after doing"
|
||||||
|
<< " all your sends (using UOPstream) and before doing any"
|
||||||
|
<< " receives (using UIPstream)" << Foam::exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
setOpened();
|
||||||
|
setGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UIPstream::~UIPstream()
|
Foam::UIPstreamBase::~UIPstreamBase()
|
||||||
{
|
{
|
||||||
if (clearAtEnd_ && eof())
|
if (clearAtEnd_ && eof())
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "UIPstream::~UIPstream() : tag:" << tag_
|
Pout<< "UIPstreamBase Destructor : tag:" << tag_
|
||||||
<< " fromProcNo:" << fromProcNo_
|
<< " fromProcNo:" << fromProcNo_
|
||||||
<< " clearing receive buffer of size "
|
<< " clearing receive buffer of size "
|
||||||
<< recvBuf_.size()
|
<< recvBuf_.size()
|
||||||
@ -163,7 +226,7 @@ Foam::UIPstream::~UIPstream()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(token& t)
|
Foam::Istream& Foam::UIPstreamBase::read(token& t)
|
||||||
{
|
{
|
||||||
// Return the put back token if it exists
|
// Return the put back token if it exists
|
||||||
// - with additional handling for special stream flags
|
// - with additional handling for special stream flags
|
||||||
@ -341,7 +404,7 @@ Foam::Istream& Foam::UIPstream::read(token& t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(char& c)
|
Foam::Istream& Foam::UIPstreamBase::read(char& c)
|
||||||
{
|
{
|
||||||
c = recvBuf_[recvBufPos_];
|
c = recvBuf_[recvBufPos_];
|
||||||
++recvBufPos_;
|
++recvBufPos_;
|
||||||
@ -350,40 +413,40 @@ Foam::Istream& Foam::UIPstream::read(char& c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(word& str)
|
Foam::Istream& Foam::UIPstreamBase::read(word& str)
|
||||||
{
|
{
|
||||||
return readString(str);
|
return readString(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(string& str)
|
Foam::Istream& Foam::UIPstreamBase::read(string& str)
|
||||||
{
|
{
|
||||||
return readString(str);
|
return readString(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(label& val)
|
Foam::Istream& Foam::UIPstreamBase::read(label& val)
|
||||||
{
|
{
|
||||||
readFromBuffer(val);
|
readFromBuffer(val);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(floatScalar& val)
|
Foam::Istream& Foam::UIPstreamBase::read(floatScalar& val)
|
||||||
{
|
{
|
||||||
readFromBuffer(val);
|
readFromBuffer(val);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(doubleScalar& val)
|
Foam::Istream& Foam::UIPstreamBase::read(doubleScalar& val)
|
||||||
{
|
{
|
||||||
readFromBuffer(val);
|
readFromBuffer(val);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::read(char* data, std::streamsize count)
|
Foam::Istream& Foam::UIPstreamBase::read(char* data, std::streamsize count)
|
||||||
{
|
{
|
||||||
if (count)
|
if (count)
|
||||||
{
|
{
|
||||||
@ -398,7 +461,7 @@ Foam::Istream& Foam::UIPstream::read(char* data, std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Istream& Foam::UIPstream::readRaw(char* data, std::streamsize count)
|
Foam::Istream& Foam::UIPstreamBase::readRaw(char* data, std::streamsize count)
|
||||||
{
|
{
|
||||||
// No check for format() == BINARY since this is either done in the
|
// No check for format() == BINARY since this is either done in the
|
||||||
// beginRawRead() method, or the caller knows what they are doing.
|
// beginRawRead() method, or the caller knows what they are doing.
|
||||||
@ -409,7 +472,7 @@ Foam::Istream& Foam::UIPstream::readRaw(char* data, std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::UIPstream::beginRawRead()
|
bool Foam::UIPstreamBase::beginRawRead()
|
||||||
{
|
{
|
||||||
if (format() != BINARY)
|
if (format() != BINARY)
|
||||||
{
|
{
|
||||||
@ -427,13 +490,30 @@ bool Foam::UIPstream::beginRawRead()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::UIPstream::rewind()
|
// Not needed yet
|
||||||
|
///
|
||||||
|
/// //- The current get position (tellg) in the buffer
|
||||||
|
/// label pos() const;
|
||||||
|
///
|
||||||
|
/// Foam::label Foam::UIPstreamBase::pos() const
|
||||||
|
/// {
|
||||||
|
/// return recvBufPos_;
|
||||||
|
/// }
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::UIPstreamBase::rewind()
|
||||||
{
|
{
|
||||||
recvBufPos_ = 0;
|
recvBufPos_ = 0; // Assume the entire buffer is for us to read from
|
||||||
|
setOpened();
|
||||||
|
setGood();
|
||||||
|
if (recvBuf_.empty() || !messageSize_)
|
||||||
|
{
|
||||||
|
setEof();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::UIPstream::print(Ostream& os) const
|
void Foam::UIPstreamBase::print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << "Reading from processor " << fromProcNo_
|
os << "Reading from processor " << fromProcNo_
|
||||||
<< " using communicator " << comm_
|
<< " using communicator " << comm_
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2014 OpenFOAM Foundation
|
Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -25,21 +25,22 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::UOPstream
|
Foam::UOPstreamBase
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Output inter-processor communications stream operating on external
|
Base class for output inter-processor communications stream
|
||||||
buffer.
|
(ie, parallel streams).
|
||||||
|
Not to be used directly, thus contructors are protected.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
UOPstream.C
|
UOPstreamBase.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
#ifndef UOPstream_H
|
#ifndef Foam_UOPstream_H
|
||||||
#define UOPstream_H
|
#define Foam_UOPstream_H
|
||||||
|
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
#include "Ostream.H"
|
#include "Ostream.H"
|
||||||
@ -52,27 +53,14 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class UOPstream Declaration
|
Class UOPstreamBase Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class UOPstream
|
class UOPstreamBase
|
||||||
:
|
:
|
||||||
public UPstream,
|
public UPstream,
|
||||||
public Ostream
|
public Ostream
|
||||||
{
|
{
|
||||||
// Private Data
|
|
||||||
|
|
||||||
int toProcNo_;
|
|
||||||
|
|
||||||
DynamicList<char>& sendBuf_;
|
|
||||||
|
|
||||||
const int tag_;
|
|
||||||
|
|
||||||
const label comm_;
|
|
||||||
|
|
||||||
const bool sendAtDestruct_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Prepare send buffer for count bytes of output,
|
//- Prepare send buffer for count bytes of output,
|
||||||
@ -100,14 +88,27 @@ class UOPstream
|
|||||||
inline void putString(const std::string& str);
|
inline void putString(const std::string& str);
|
||||||
|
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
|
|
||||||
// Constructors
|
// Protected Data
|
||||||
|
|
||||||
|
int toProcNo_;
|
||||||
|
|
||||||
|
DynamicList<char>& sendBuf_;
|
||||||
|
|
||||||
|
const int tag_;
|
||||||
|
|
||||||
|
const label comm_;
|
||||||
|
|
||||||
|
const bool sendAtDestruct_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Constructors
|
||||||
|
|
||||||
//- Construct given process index to write to using the given
|
//- Construct given process index to write to using the given
|
||||||
//- attached send buffer, optional communication characteristics
|
//- attached send buffer, optional communication characteristics
|
||||||
//- and IO format
|
//- and IO format
|
||||||
UOPstream
|
UOPstreamBase
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int toProcNo,
|
const int toProcNo,
|
||||||
@ -119,11 +120,13 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
//- Construct given buffers
|
//- Construct given buffers
|
||||||
UOPstream(const int toProcNo, PstreamBuffers& buffers);
|
UOPstreamBase(const int toProcNo, PstreamBuffers& buffers);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
//- Destructor.
|
//- Destructor.
|
||||||
~UOPstream();
|
virtual ~UOPstreamBase();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
@ -139,17 +142,6 @@ public:
|
|||||||
|
|
||||||
// Write Functions
|
// Write Functions
|
||||||
|
|
||||||
//- Write given buffer to given processor
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Write token to stream or otherwise handle it.
|
//- Write token to stream or otherwise handle it.
|
||||||
// \return false if the token type was not handled by this method
|
// \return false if the token type was not handled by this method
|
||||||
virtual bool write(const token& tok);
|
virtual bool write(const token& tok);
|
||||||
@ -259,10 +251,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Positioning
|
||||||
|
|
||||||
|
//- Rewind the send buffer for overwriting
|
||||||
|
virtual void rewind();
|
||||||
|
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
|
|
||||||
//- Set flags of stream
|
//- Set flags of stream
|
||||||
ios_base::fmtflags flags(const ios_base::fmtflags)
|
virtual ios_base::fmtflags flags(const ios_base::fmtflags)
|
||||||
{
|
{
|
||||||
return ios_base::fmtflags(0);
|
return ios_base::fmtflags(0);
|
||||||
}
|
}
|
||||||
@ -275,6 +273,133 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class UOPstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Output inter-processor communications stream
|
||||||
|
//- using MPI send/recv etc. - operating on external buffer.
|
||||||
|
class UOPstream
|
||||||
|
:
|
||||||
|
public UOPstreamBase
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Final buffer send, called by destructor
|
||||||
|
bool bufferIPCsend();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given process index to write to using the given
|
||||||
|
//- attached send buffer, optional communication characteristics
|
||||||
|
//- and IO format
|
||||||
|
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
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct given buffers
|
||||||
|
UOPstream(const int toProcNo, PstreamBuffers& buffers);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor, usually sends buffer on destruct.
|
||||||
|
virtual ~UOPstream();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Use all write methods from base class
|
||||||
|
using UOPstreamBase::write;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Functions
|
||||||
|
|
||||||
|
//- Write buffer contents to given processor
|
||||||
|
// \return True on success
|
||||||
|
static bool write
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int toProcNo,
|
||||||
|
const char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class UOPBstream Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
//- Output inter-processor communications stream
|
||||||
|
//- using MPI broadcast - operating on external buffer.
|
||||||
|
//
|
||||||
|
// \note does not use commsType, tag etc.
|
||||||
|
class UOPBstream
|
||||||
|
:
|
||||||
|
public UOPstreamBase
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Final buffer send, called by destructor
|
||||||
|
bool bufferIPCsend();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given process index to write to using the given
|
||||||
|
//- attached send buffer, optional communication characteristics
|
||||||
|
//- and IO format
|
||||||
|
UOPBstream
|
||||||
|
(
|
||||||
|
const commsTypes commsType, //!< ignored
|
||||||
|
const int toProcNo, //!< normally UPstream::masterNo()
|
||||||
|
DynamicList<char>& sendBuf,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm,
|
||||||
|
const bool sendAtDestruct = true,
|
||||||
|
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor, usually sends buffer on destruct.
|
||||||
|
virtual ~UOPBstream();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Use all write methods from base
|
||||||
|
using UOPstreamBase::write;
|
||||||
|
|
||||||
|
|
||||||
|
// Static Functions
|
||||||
|
|
||||||
|
//- Wrapped version of UPstream::broadcast with const-cast
|
||||||
|
// \return True on success
|
||||||
|
static bool write
|
||||||
|
(
|
||||||
|
const commsTypes commsType, //!< ignored
|
||||||
|
const int rootProcNo, //!< normally UPstream::masterNo()
|
||||||
|
const char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag = UPstream::msgType(), //!< ignored
|
||||||
|
const label comm = UPstream::worldComm
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -52,7 +52,7 @@ inline static label byteAlign(const label pos, const size_t align)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
inline void Foam::UOPstream::prepareBuffer
|
inline void Foam::UOPstreamBase::prepareBuffer
|
||||||
(
|
(
|
||||||
const size_t count,
|
const size_t count,
|
||||||
const size_t align
|
const size_t align
|
||||||
@ -75,13 +75,13 @@ inline void Foam::UOPstream::prepareBuffer
|
|||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline void Foam::UOPstream::writeToBuffer(const T& val)
|
inline void Foam::UOPstreamBase::writeToBuffer(const T& val)
|
||||||
{
|
{
|
||||||
writeToBuffer(&val, sizeof(T), sizeof(T));
|
writeToBuffer(&val, sizeof(T), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::UOPstream::writeToBuffer
|
inline void Foam::UOPstreamBase::writeToBuffer
|
||||||
(
|
(
|
||||||
const void* data,
|
const void* data,
|
||||||
const size_t count,
|
const size_t count,
|
||||||
@ -111,7 +111,7 @@ inline void Foam::UOPstream::writeToBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::UOPstream::putChar(const char c)
|
inline void Foam::UOPstreamBase::putChar(const char c)
|
||||||
{
|
{
|
||||||
if (!sendBuf_.capacity())
|
if (!sendBuf_.capacity())
|
||||||
{
|
{
|
||||||
@ -121,7 +121,7 @@ inline void Foam::UOPstream::putChar(const char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::UOPstream::putString(const std::string& str)
|
inline void Foam::UOPstreamBase::putString(const std::string& str)
|
||||||
{
|
{
|
||||||
const size_t len = str.size();
|
const size_t len = str.size();
|
||||||
writeToBuffer(len);
|
writeToBuffer(len);
|
||||||
@ -131,7 +131,7 @@ inline void Foam::UOPstream::putString(const std::string& str)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UOPstream::UOPstream
|
Foam::UOPstreamBase::UOPstreamBase
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int toProcNo,
|
const int toProcNo,
|
||||||
@ -155,15 +155,15 @@ Foam::UOPstream::UOPstream
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers)
|
Foam::UOPstreamBase::UOPstreamBase(const int toProcNo, PstreamBuffers& buffers)
|
||||||
:
|
:
|
||||||
UPstream(buffers.commsType_),
|
UPstream(buffers.commsType()),
|
||||||
Ostream(buffers.format_, IOstreamOption::currentVersion),
|
Ostream(buffers.format(), IOstreamOption::currentVersion),
|
||||||
toProcNo_(toProcNo),
|
toProcNo_(toProcNo),
|
||||||
sendBuf_(buffers.sendBuf_[toProcNo]),
|
sendBuf_(buffers.sendBuf_[toProcNo]),
|
||||||
tag_(buffers.tag_),
|
tag_(buffers.tag()),
|
||||||
comm_(buffers.comm_),
|
comm_(buffers.comm()),
|
||||||
sendAtDestruct_(buffers.commsType_ != UPstream::commsTypes::nonBlocking)
|
sendAtDestruct_(buffers.commsType() != UPstream::commsTypes::nonBlocking)
|
||||||
{
|
{
|
||||||
setOpened();
|
setOpened();
|
||||||
setGood();
|
setGood();
|
||||||
@ -172,35 +172,13 @@ Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers)
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UOPstream::~UOPstream()
|
Foam::UOPstreamBase::~UOPstreamBase()
|
||||||
{
|
{}
|
||||||
if (sendAtDestruct_)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
!UOPstream::write
|
|
||||||
(
|
|
||||||
commsType_,
|
|
||||||
toProcNo_,
|
|
||||||
sendBuf_.cdata(),
|
|
||||||
sendBuf_.size(),
|
|
||||||
tag_,
|
|
||||||
comm_
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Failed sending outgoing message of size " << sendBuf_.size()
|
|
||||||
<< " to processor " << toProcNo_
|
|
||||||
<< Foam::abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::UOPstream::write(const token& tok)
|
bool Foam::UOPstreamBase::write(const token& tok)
|
||||||
{
|
{
|
||||||
// Direct token handling only for some types
|
// Direct token handling only for some types
|
||||||
|
|
||||||
@ -244,7 +222,7 @@ bool Foam::UOPstream::write(const token& tok)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const char c)
|
Foam::Ostream& Foam::UOPstreamBase::write(const char c)
|
||||||
{
|
{
|
||||||
if (!isspace(c))
|
if (!isspace(c))
|
||||||
{
|
{
|
||||||
@ -255,7 +233,7 @@ Foam::Ostream& Foam::UOPstream::write(const char c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const char* str)
|
Foam::Ostream& Foam::UOPstreamBase::write(const char* str)
|
||||||
{
|
{
|
||||||
const word nonWhiteChars(string::validate<word>(str));
|
const word nonWhiteChars(string::validate<word>(str));
|
||||||
|
|
||||||
@ -272,7 +250,7 @@ Foam::Ostream& Foam::UOPstream::write(const char* str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const word& str)
|
Foam::Ostream& Foam::UOPstreamBase::write(const word& str)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::WORD);
|
putChar(token::tokenType::WORD);
|
||||||
putString(str);
|
putString(str);
|
||||||
@ -281,7 +259,7 @@ Foam::Ostream& Foam::UOPstream::write(const word& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const string& str)
|
Foam::Ostream& Foam::UOPstreamBase::write(const string& str)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::STRING);
|
putChar(token::tokenType::STRING);
|
||||||
putString(str);
|
putString(str);
|
||||||
@ -290,7 +268,7 @@ Foam::Ostream& Foam::UOPstream::write(const string& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::writeQuoted
|
Foam::Ostream& Foam::UOPstreamBase::writeQuoted
|
||||||
(
|
(
|
||||||
const std::string& str,
|
const std::string& str,
|
||||||
const bool quoted
|
const bool quoted
|
||||||
@ -310,7 +288,7 @@ Foam::Ostream& Foam::UOPstream::writeQuoted
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const int32_t val)
|
Foam::Ostream& Foam::UOPstreamBase::write(const int32_t val)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::LABEL);
|
putChar(token::tokenType::LABEL);
|
||||||
writeToBuffer(val);
|
writeToBuffer(val);
|
||||||
@ -318,7 +296,7 @@ Foam::Ostream& Foam::UOPstream::write(const int32_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const int64_t val)
|
Foam::Ostream& Foam::UOPstreamBase::write(const int64_t val)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::LABEL);
|
putChar(token::tokenType::LABEL);
|
||||||
writeToBuffer(val);
|
writeToBuffer(val);
|
||||||
@ -326,7 +304,7 @@ Foam::Ostream& Foam::UOPstream::write(const int64_t val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
|
Foam::Ostream& Foam::UOPstreamBase::write(const floatScalar val)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::FLOAT);
|
putChar(token::tokenType::FLOAT);
|
||||||
writeToBuffer(val);
|
writeToBuffer(val);
|
||||||
@ -334,7 +312,7 @@ Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const doubleScalar val)
|
Foam::Ostream& Foam::UOPstreamBase::write(const doubleScalar val)
|
||||||
{
|
{
|
||||||
putChar(token::tokenType::DOUBLE);
|
putChar(token::tokenType::DOUBLE);
|
||||||
writeToBuffer(val);
|
writeToBuffer(val);
|
||||||
@ -342,7 +320,7 @@ Foam::Ostream& Foam::UOPstream::write(const doubleScalar val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::write(const char* data, std::streamsize count)
|
Foam::Ostream& Foam::UOPstreamBase::write(const char* data, std::streamsize count)
|
||||||
{
|
{
|
||||||
if (format() != BINARY)
|
if (format() != BINARY)
|
||||||
{
|
{
|
||||||
@ -358,7 +336,7 @@ Foam::Ostream& Foam::UOPstream::write(const char* data, std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::UOPstream::writeRaw
|
Foam::Ostream& Foam::UOPstreamBase::writeRaw
|
||||||
(
|
(
|
||||||
const char* data,
|
const char* data,
|
||||||
std::streamsize count
|
std::streamsize count
|
||||||
@ -374,7 +352,7 @@ Foam::Ostream& Foam::UOPstream::writeRaw
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::UOPstream::beginRawWrite(std::streamsize count)
|
bool Foam::UOPstreamBase::beginRawWrite(std::streamsize count)
|
||||||
{
|
{
|
||||||
if (format() != BINARY)
|
if (format() != BINARY)
|
||||||
{
|
{
|
||||||
@ -391,7 +369,26 @@ bool Foam::UOPstream::beginRawWrite(std::streamsize count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::UOPstream::print(Ostream& os) const
|
// Not needed yet
|
||||||
|
///
|
||||||
|
/// //- The current put position (tellp) in the buffer
|
||||||
|
/// label pos() const;
|
||||||
|
///
|
||||||
|
/// Foam::label Foam::UOPstreamBase::pos() const
|
||||||
|
/// {
|
||||||
|
/// return sendBuf_.size();
|
||||||
|
/// }
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::UOPstreamBase::rewind()
|
||||||
|
{
|
||||||
|
sendBuf_.clear(); // Overwrite into buffer
|
||||||
|
setOpened();
|
||||||
|
setGood();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::UOPstreamBase::print(Ostream& os) const
|
||||||
{
|
{
|
||||||
os << "Writing from processor " << toProcNo_
|
os << "Writing from processor " << toProcNo_
|
||||||
<< " to processor " << myProcNo() << " in communicator " << comm_
|
<< " to processor " << myProcNo() << " in communicator " << comm_
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -51,6 +51,43 @@ Foam::UPstream::commsTypeNames
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::UPstream::broadcast
|
||||||
|
(
|
||||||
|
std::string& str,
|
||||||
|
const label comm,
|
||||||
|
const int rootProcNo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||||
|
{
|
||||||
|
// Broadcast the string length
|
||||||
|
std::size_t len(str.length());
|
||||||
|
|
||||||
|
UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&len),
|
||||||
|
sizeof(std::size_t),
|
||||||
|
comm,
|
||||||
|
rootProcNo
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!UPstream::master(comm))
|
||||||
|
{
|
||||||
|
// Do not touch string on the master even although it would
|
||||||
|
// be a no-op. We are truly paranoid.
|
||||||
|
str.resize(len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
UPstream::broadcast(&str[0], len, comm, rootProcNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
|
void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
|
||||||
@ -414,7 +451,7 @@ registerOptSwitch
|
|||||||
|
|
||||||
int Foam::UPstream::nProcsSimpleSum
|
int Foam::UPstream::nProcsSimpleSum
|
||||||
(
|
(
|
||||||
Foam::debug::optimisationSwitch("nProcsSimpleSum", 16)
|
Foam::debug::optimisationSwitch("nProcsSimpleSum", 0)
|
||||||
);
|
);
|
||||||
registerOptSwitch
|
registerOptSwitch
|
||||||
(
|
(
|
||||||
|
|||||||
@ -34,9 +34,6 @@ SourceFiles
|
|||||||
UPstream.C
|
UPstream.C
|
||||||
UPstreamCommsStruct.C
|
UPstreamCommsStruct.C
|
||||||
UPstreamTemplates.C
|
UPstreamTemplates.C
|
||||||
combineGatherScatter.C
|
|
||||||
gatherScatter.C
|
|
||||||
gatherScatterList.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -69,9 +66,9 @@ public:
|
|||||||
//- Types of communications
|
//- Types of communications
|
||||||
enum class commsTypes : char
|
enum class commsTypes : char
|
||||||
{
|
{
|
||||||
blocking,
|
blocking, //!< "blocking"
|
||||||
scheduled,
|
scheduled, //!< "scheduled"
|
||||||
nonBlocking
|
nonBlocking //!< "nonBlocking"
|
||||||
};
|
};
|
||||||
|
|
||||||
//- Names of the communication types
|
//- Names of the communication types
|
||||||
@ -104,7 +101,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Default construct. Above == -1
|
//- Default construct. Above == -1
|
||||||
commsStruct();
|
commsStruct() noexcept;
|
||||||
|
|
||||||
//- Construct from components
|
//- Construct from components
|
||||||
commsStruct
|
commsStruct
|
||||||
@ -180,6 +177,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Communications type of this stream
|
||||||
|
commsTypes commsType_;
|
||||||
|
|
||||||
|
|
||||||
// Private Static Data
|
// Private Static Data
|
||||||
|
|
||||||
//- By default this is not a parallel run
|
//- By default this is not a parallel run
|
||||||
@ -253,14 +256,6 @@ private:
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected Data
|
|
||||||
|
|
||||||
//- Communications type of this stream
|
|
||||||
commsTypes commsType_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Declare name of the class and its debug switch
|
// Declare name of the class and its debug switch
|
||||||
@ -274,8 +269,7 @@ public:
|
|||||||
//- in accuracy
|
//- in accuracy
|
||||||
static bool floatTransfer;
|
static bool floatTransfer;
|
||||||
|
|
||||||
//- Number of processors at which the sum algorithm changes from linear
|
//- Number of processors to change from linear to tree communication
|
||||||
//- to tree
|
|
||||||
static int nProcsSimpleSum;
|
static int nProcsSimpleSum;
|
||||||
|
|
||||||
//- Default commsType
|
//- Default commsType
|
||||||
@ -413,11 +407,11 @@ public:
|
|||||||
|
|
||||||
static int allocateTag(const char*);
|
static int allocateTag(const char*);
|
||||||
|
|
||||||
static int allocateTag(const word&);
|
static int allocateTag(const std::string&);
|
||||||
|
|
||||||
static void freeTag(const char*, const int tag);
|
static void freeTag(const char*, const int tag);
|
||||||
|
|
||||||
static void freeTag(const word&, const int tag);
|
static void freeTag(const std::string&, const int tag);
|
||||||
|
|
||||||
|
|
||||||
//- Set as parallel run on/off.
|
//- Set as parallel run on/off.
|
||||||
@ -537,13 +531,28 @@ public:
|
|||||||
return treeCommunication_[communicator];
|
return treeCommunication_[communicator];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Communication schedule for linear/tree all-to-master (proc 0).
|
||||||
|
//- Chooses based on the value of UPstream::nProcsSimpleSum
|
||||||
|
static const List<commsStruct>& whichCommunication
|
||||||
|
(
|
||||||
|
const label communicator = worldComm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
nProcs(communicator) < nProcsSimpleSum
|
||||||
|
? linearCommunication_[communicator]
|
||||||
|
: treeCommunication_[communicator]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//- Message tag of standard messages
|
//- Message tag of standard messages
|
||||||
static int& msgType() noexcept
|
static int& msgType() noexcept
|
||||||
{
|
{
|
||||||
return msgType_;
|
return msgType_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//- Get the communications type of the stream
|
//- Get the communications type of the stream
|
||||||
commsTypes commsType() const noexcept
|
commsTypes commsType() const noexcept
|
||||||
{
|
{
|
||||||
@ -551,6 +560,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//- Set the communications type of the stream
|
//- Set the communications type of the stream
|
||||||
|
// \return the previous value
|
||||||
commsTypes commsType(const commsTypes ct) noexcept
|
commsTypes commsType(const commsTypes ct) noexcept
|
||||||
{
|
{
|
||||||
commsTypes old(commsType_);
|
commsTypes old(commsType_);
|
||||||
@ -668,6 +678,28 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Broadcast Functions
|
||||||
|
|
||||||
|
//- Broadcast buffer contents to all processes in communicator.
|
||||||
|
//- The sizes must match on all processes.
|
||||||
|
// \return True on success
|
||||||
|
static bool broadcast
|
||||||
|
(
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const label communicator = worldComm,
|
||||||
|
const int rootProcNo = masterNo()
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Broadcast string content to all processes in communicator.
|
||||||
|
static void broadcast
|
||||||
|
(
|
||||||
|
std::string& str,
|
||||||
|
const label communicator = worldComm,
|
||||||
|
const int rootProcNo = masterNo()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Housekeeping
|
// Housekeeping
|
||||||
|
|
||||||
//- Process index of first sub-process
|
//- Process index of first sub-process
|
||||||
@ -691,11 +723,11 @@ Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
|
|||||||
// Template specialisation for access of commsStruct
|
// Template specialisation for access of commsStruct
|
||||||
template<>
|
template<>
|
||||||
UPstream::commsStruct&
|
UPstream::commsStruct&
|
||||||
UList<UPstream::commsStruct>::operator[](const label);
|
UList<UPstream::commsStruct>::operator[](const label procID);
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
const UPstream::commsStruct&
|
const UPstream::commsStruct&
|
||||||
UList<UPstream::commsStruct>::operator[](const label) const;
|
UList<UPstream::commsStruct>::operator[](const label procID) const;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -30,7 +30,7 @@ License
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UPstream::commsStruct::commsStruct()
|
Foam::UPstream::commsStruct::commsStruct() noexcept
|
||||||
:
|
:
|
||||||
above_(-1),
|
above_(-1),
|
||||||
below_(),
|
below_(),
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2017-2018 OpenFOAM Foundation
|
Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -2072,24 +2072,11 @@ bool Foam::fileOperations::masterUncollatedFileOperation::read
|
|||||||
Pstream::scatter(io.note()); //, Pstream::msgType(), comm_);
|
Pstream::scatter(io.note()); //, Pstream::msgType(), comm_);
|
||||||
|
|
||||||
|
|
||||||
// scatter operation for regIOobjects
|
// Scatter operation for regIOobjects
|
||||||
|
|
||||||
// Get my communication order
|
// My communication order
|
||||||
// const List<Pstream::commsStruct>& comms =
|
const auto& comms = Pstream::whichCommunication(Pstream::worldComm);
|
||||||
//(
|
const auto& myComm = comms[Pstream::myProcNo(Pstream::worldComm)];
|
||||||
// (Pstream::nProcs(comm_) < Pstream::nProcsSimpleSum)
|
|
||||||
// ? Pstream::linearCommunication(comm_)
|
|
||||||
// : Pstream::treeCommunication(comm_)
|
|
||||||
//);
|
|
||||||
// const Pstream::commsStruct& myComm = comms[Pstream::myProcNo(comm_)];
|
|
||||||
const List<Pstream::commsStruct>& comms =
|
|
||||||
(
|
|
||||||
(Pstream::nProcs(Pstream::worldComm) < Pstream::nProcsSimpleSum)
|
|
||||||
? Pstream::linearCommunication(Pstream::worldComm)
|
|
||||||
: Pstream::treeCommunication(Pstream::worldComm)
|
|
||||||
);
|
|
||||||
const Pstream::commsStruct& myComm =
|
|
||||||
comms[Pstream::myProcNo(Pstream::worldComm)];
|
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2017 OpenFOAM Foundation
|
Copyright (C) 2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -654,14 +654,9 @@ bool Foam::fileOperations::uncollatedFileOperation::read
|
|||||||
Pstream::scatter(io.headerClassName());
|
Pstream::scatter(io.headerClassName());
|
||||||
Pstream::scatter(io.note());
|
Pstream::scatter(io.note());
|
||||||
|
|
||||||
// Get my communication order
|
// My communication order
|
||||||
const List<Pstream::commsStruct>& comms =
|
const auto& comms = Pstream::whichCommunication();
|
||||||
(
|
const auto& myComm = comms[Pstream::myProcNo()];
|
||||||
(Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
|
||||||
? Pstream::linearCommunication()
|
|
||||||
: Pstream::treeCommunication()
|
|
||||||
);
|
|
||||||
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
|
|
||||||
|
|
||||||
// Receive from up
|
// Receive from up
|
||||||
if (myComm.above() != -1)
|
if (myComm.above() != -1)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -35,8 +35,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef profilingPstream_H
|
#ifndef Foam_profilingPstream_H
|
||||||
#define profilingPstream_H
|
#define Foam_profilingPstream_H
|
||||||
|
|
||||||
#include "cpuTime.H"
|
#include "cpuTime.H"
|
||||||
#include "FixedList.H"
|
#include "FixedList.H"
|
||||||
@ -62,13 +62,14 @@ public:
|
|||||||
{
|
{
|
||||||
GATHER = 0,
|
GATHER = 0,
|
||||||
SCATTER,
|
SCATTER,
|
||||||
|
BROADCAST,
|
||||||
REDUCE,
|
REDUCE,
|
||||||
WAIT,
|
WAIT,
|
||||||
ALL_TO_ALL
|
ALL_TO_ALL
|
||||||
};
|
};
|
||||||
|
|
||||||
//- The timing values
|
//- The timing values
|
||||||
typedef FixedList<double, 5> timingList;
|
typedef FixedList<double, 6> timingList;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -165,6 +166,12 @@ public:
|
|||||||
addTime(SCATTER);
|
addTime(SCATTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Add time increment to broadcastTime
|
||||||
|
inline static void addBroadcastTime()
|
||||||
|
{
|
||||||
|
addTime(BROADCAST);
|
||||||
|
}
|
||||||
|
|
||||||
//- Add time increment to reduceTime
|
//- Add time increment to reduceTime
|
||||||
inline static void addReduceTime()
|
inline static void addReduceTime()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -38,11 +38,12 @@ namespace Foam
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::processorLduInterface::resizeBuf(List<char>& buf, const label size)
|
void Foam::processorLduInterface::resizeBuf(List<char>& buf, const label len)
|
||||||
{
|
{
|
||||||
if (buf.size() < size)
|
if (buf.size() < len)
|
||||||
{
|
{
|
||||||
buf.resize(size);
|
// Use nocopy variant since it will be overwritten
|
||||||
|
buf.resize_nocopy(len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,8 +36,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef processorLduInterface_H
|
#ifndef Foam_processorLduInterface_H
|
||||||
#define processorLduInterface_H
|
#define Foam_processorLduInterface_H
|
||||||
|
|
||||||
#include "lduInterface.H"
|
#include "lduInterface.H"
|
||||||
#include "primitiveFieldsFwd.H"
|
#include "primitiveFieldsFwd.H"
|
||||||
@ -67,7 +67,7 @@ class processorLduInterface
|
|||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Increase buffer size if required
|
//- Increase buffer size if required
|
||||||
static void resizeBuf(List<char>& buf, const label size);
|
static void resizeBuf(List<char>& buf, const label len);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct null
|
//- Default construct
|
||||||
processorLduInterface() = default;
|
processorLduInterface() = default;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ void Foam::processorLduInterface::send
|
|||||||
const UList<Type>& f
|
const UList<Type>& f
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
label nBytes = f.byteSize();
|
const label nBytes = f.byteSize();
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2019 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,7 +27,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "GAMGSolver.H"
|
#include "GAMGSolver.H"
|
||||||
#include "vector2D.H"
|
#include "FixedList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -58,21 +58,21 @@ void Foam::GAMGSolver::scale
|
|||||||
const solveScalar* const __restrict__ AcfPtr = Acf.begin();
|
const solveScalar* const __restrict__ AcfPtr = Acf.begin();
|
||||||
|
|
||||||
|
|
||||||
solveScalar scalingFactorNum = 0.0;
|
FixedList<solveScalar, 2> scalingFactor(Zero);
|
||||||
solveScalar scalingFactorDenom = 0.0;
|
|
||||||
|
|
||||||
for (label i=0; i<nCells; i++)
|
for (label i=0; i<nCells; i++)
|
||||||
{
|
{
|
||||||
scalingFactorNum += sourcePtr[i]*fieldPtr[i];
|
scalingFactor[0] += fieldPtr[i]*sourcePtr[i];
|
||||||
scalingFactorDenom += AcfPtr[i]*fieldPtr[i];
|
scalingFactor[1] += fieldPtr[i]*AcfPtr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2D<solveScalar> scalingVector(scalingFactorNum, scalingFactorDenom);
|
A.mesh().reduce(scalingFactor, sumOp<solveScalar>());
|
||||||
A.mesh().reduce(scalingVector, sumOp<Vector2D<solveScalar>>());
|
|
||||||
|
|
||||||
const solveScalar sf =
|
const solveScalar sf =
|
||||||
scalingVector.x()
|
(
|
||||||
/stabilise(scalingVector.y(), pTraits<solveScalar>::vsmall);
|
scalingFactor[0]
|
||||||
|
/ stabilise(scalingFactor[1], pTraits<solveScalar>::vsmall)
|
||||||
|
);
|
||||||
|
|
||||||
if (debug >= 2)
|
if (debug >= 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -29,7 +29,6 @@ License
|
|||||||
#include "ListOps.H"
|
#include "ListOps.H"
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
#include "commSchedule.H"
|
#include "commSchedule.H"
|
||||||
#include "boolList.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -50,22 +49,16 @@ Foam::labelList Foam::ProcessorTopology<Container, ProcPatch>::procNeighbours
|
|||||||
|
|
||||||
forAll(patches, patchi)
|
forAll(patches, patchi)
|
||||||
{
|
{
|
||||||
const typename Container::const_reference patch = patches[patchi];
|
const auto* cpp = isA<ProcPatch>(patches[patchi]);
|
||||||
|
if (cpp)
|
||||||
if (isA<ProcPatch>(patch))
|
|
||||||
{
|
{
|
||||||
const ProcPatch& procPatch =
|
const label nbrProci = cpp->neighbProcNo();
|
||||||
refCast<const ProcPatch>(patch);
|
|
||||||
|
|
||||||
label pNeighbProcNo = procPatch.neighbProcNo();
|
if (!isNeighbourProc[nbrProci])
|
||||||
|
|
||||||
if (!isNeighbourProc[pNeighbProcNo])
|
|
||||||
{
|
{
|
||||||
nNeighbours++;
|
isNeighbourProc[nbrProci] = true;
|
||||||
|
maxNb = max(maxNb, nbrProci);
|
||||||
maxNb = max(maxNb, procPatch.neighbProcNo());
|
++nNeighbours;
|
||||||
|
|
||||||
isNeighbourProc[pNeighbProcNo] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,15 +80,13 @@ Foam::labelList Foam::ProcessorTopology<Container, ProcPatch>::procNeighbours
|
|||||||
|
|
||||||
forAll(patches, patchi)
|
forAll(patches, patchi)
|
||||||
{
|
{
|
||||||
const typename Container::const_reference patch = patches[patchi];
|
const auto* cpp = isA<ProcPatch>(patches[patchi]);
|
||||||
|
if (cpp)
|
||||||
if (isA<ProcPatch>(patch))
|
|
||||||
{
|
{
|
||||||
const ProcPatch& procPatch =
|
const label nbrProci = cpp->neighbProcNo();
|
||||||
refCast<const ProcPatch>(patch);
|
|
||||||
|
|
||||||
// Construct reverse map
|
// Reverse map
|
||||||
procPatchMap_[procPatch.neighbProcNo()] = patchi;
|
procPatchMap_[nbrProci] = patchi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +104,7 @@ Foam::ProcessorTopology<Container, ProcPatch>::ProcessorTopology
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
labelListList(Pstream::nProcs(comm)),
|
labelListList(Pstream::nProcs(comm)),
|
||||||
patchSchedule_(2*patches.size())
|
patchSchedule_()
|
||||||
{
|
{
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
@ -132,6 +123,8 @@ Foam::ProcessorTopology<Container, ProcPatch>::ProcessorTopology
|
|||||||
&& Pstream::defaultCommsType == Pstream::commsTypes::scheduled
|
&& Pstream::defaultCommsType == Pstream::commsTypes::scheduled
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
patchSchedule_.resize(2*patches.size());
|
||||||
|
|
||||||
label patchEvali = 0;
|
label patchEvali = 0;
|
||||||
|
|
||||||
// 1. All non-processor patches
|
// 1. All non-processor patches
|
||||||
@ -155,21 +148,21 @@ Foam::ProcessorTopology<Container, ProcPatch>::ProcessorTopology
|
|||||||
// to determine the schedule. Each processor pair stands for both
|
// to determine the schedule. Each processor pair stands for both
|
||||||
// send and receive.
|
// send and receive.
|
||||||
label nComms = 0;
|
label nComms = 0;
|
||||||
forAll(*this, proci)
|
for (const labelList& neighbours : *this)
|
||||||
{
|
{
|
||||||
nComms += operator[](proci).size();
|
nComms += neighbours.size();
|
||||||
}
|
}
|
||||||
DynamicList<labelPair> comms(nComms);
|
DynamicList<labelPair> comms(nComms);
|
||||||
|
|
||||||
forAll(*this, proci)
|
forAll(*this, proci)
|
||||||
{
|
{
|
||||||
const labelList& nbrs = operator[](proci);
|
const labelList& neighbours = operator[](proci);
|
||||||
|
|
||||||
forAll(nbrs, i)
|
for (const label nbrProci : neighbours)
|
||||||
{
|
{
|
||||||
if (proci < nbrs[i])
|
if (proci < nbrProci)
|
||||||
{
|
{
|
||||||
comms.append(labelPair(proci, nbrs[i]));
|
comms.append(labelPair(proci, nbrProci));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,10 +178,8 @@ Foam::ProcessorTopology<Container, ProcPatch>::ProcessorTopology
|
|||||||
).procSchedule()[Pstream::myProcNo(comm)]
|
).procSchedule()[Pstream::myProcNo(comm)]
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(mySchedule, iter)
|
for (const label commI : mySchedule)
|
||||||
{
|
{
|
||||||
label commI = mySchedule[iter];
|
|
||||||
|
|
||||||
// Get the other processor
|
// Get the other processor
|
||||||
label nb = comms[commI][0];
|
label nb = comms[commI][0];
|
||||||
if (nb == Pstream::myProcNo(comm))
|
if (nb == Pstream::myProcNo(comm))
|
||||||
|
|||||||
@ -40,8 +40,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef ProcessorTopology_H
|
#ifndef Foam_ProcessorTopology_H
|
||||||
#define ProcessorTopology_H
|
#define Foam_ProcessorTopology_H
|
||||||
|
|
||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
#include "lduSchedule.H"
|
#include "lduSchedule.H"
|
||||||
@ -60,10 +60,7 @@ class ProcessorTopology
|
|||||||
:
|
:
|
||||||
public labelListList
|
public labelListList
|
||||||
{
|
{
|
||||||
|
// Private Data
|
||||||
private:
|
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Local map from neighbour proc to patchi. Different per processor!
|
//- Local map from neighbour proc to patchi. Different per processor!
|
||||||
// -1 or patchi for connection to procID
|
// -1 or patchi for connection to procID
|
||||||
@ -76,8 +73,8 @@ private:
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Return all neighbouring processors of this processor. Set
|
//- Return all neighbouring processors of this processor.
|
||||||
// procPatchMap_.
|
// Sets procPatchMap_.
|
||||||
labelList procNeighbours(const label nProcs, const Container&);
|
labelList procNeighbours(const label nProcs, const Container&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -88,25 +85,27 @@ public:
|
|||||||
ProcessorTopology(const Container& patches, const label comm);
|
ProcessorTopology(const Container& patches, const label comm);
|
||||||
|
|
||||||
|
|
||||||
|
// Static Functions
|
||||||
|
|
||||||
|
//- Calculate non-blocking (i.e. unscheduled) schedule
|
||||||
|
static lduSchedule nonBlockingSchedule(const Container& patches);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- From neighbour processor to index in boundaryMesh. Local information
|
//- From neighbour processor to index in boundaryMesh.
|
||||||
// (so not same over all processors)
|
// Local information (so not same over all processors)
|
||||||
const labelList& procPatchMap() const
|
const labelList& procPatchMap() const noexcept
|
||||||
{
|
{
|
||||||
return procPatchMap_;
|
return procPatchMap_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Order in which the patches should be initialised/evaluated
|
//- Order in which the patches should be initialised/evaluated
|
||||||
// corresponding to the schedule
|
//- corresponding to the schedule
|
||||||
const lduSchedule& patchSchedule() const
|
const lduSchedule& patchSchedule() const noexcept
|
||||||
{
|
{
|
||||||
return patchSchedule_;
|
return patchSchedule_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Calculate non-blocking (i.e. unscheduled) schedule
|
|
||||||
static lduSchedule nonBlockingSchedule(const Container& patches);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -388,20 +388,20 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
}
|
}
|
||||||
countSharedEdges(localShared, globalShared, sharedEdgeI);
|
countSharedEdges(localShared, globalShared, sharedEdgeI);
|
||||||
|
|
||||||
// Receive data from slaves and insert
|
// Receive data and insert
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
for (const int slave : Pstream::subProcs())
|
for (const int proci : Pstream::subProcs())
|
||||||
{
|
{
|
||||||
// Receive the edges using shared points from the slave.
|
// Receive the edges using shared points from the slave.
|
||||||
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
|
IPstream fromProc(Pstream::commsTypes::blocking, proci);
|
||||||
EdgeMap<labelList> procSharedEdges(fromSlave);
|
EdgeMap<labelList> procSharedEdges(fromProc);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "globalMeshData::calcSharedEdges : "
|
Pout<< "globalMeshData::calcSharedEdges : "
|
||||||
<< "Merging in from proc"
|
<< "Merging in from proc"
|
||||||
<< Foam::name(slave) << " : " << procSharedEdges.size()
|
<< proci << " : " << procSharedEdges.size()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
countSharedEdges(procSharedEdges, globalShared, sharedEdgeI);
|
countSharedEdges(procSharedEdges, globalShared, sharedEdgeI);
|
||||||
@ -430,23 +430,12 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
<< " down to " << globalShared.size() << endl;
|
<< " down to " << globalShared.size() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send back to slaves.
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
// Receive the edges using shared points from the slave.
|
|
||||||
OPstream toSlave(Pstream::commsTypes::blocking, slave);
|
|
||||||
toSlave << globalShared;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Send local edges to master
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
|
// Send local edges to master
|
||||||
OPstream toMaster
|
OPstream toMaster
|
||||||
(
|
(
|
||||||
Pstream::commsTypes::blocking,
|
Pstream::commsTypes::blocking,
|
||||||
@ -454,17 +443,12 @@ void Foam::globalMeshData::calcSharedEdges() const
|
|||||||
);
|
);
|
||||||
toMaster << localShared;
|
toMaster << localShared;
|
||||||
}
|
}
|
||||||
// Receive merged edges from master.
|
|
||||||
{
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::blocking,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> globalShared;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast: merged edges to all
|
||||||
|
Pstream::broadcast(globalShared); // == worldComm;
|
||||||
|
|
||||||
|
|
||||||
// Now use the global shared edges list (globalShared) to classify my local
|
// Now use the global shared edges list (globalShared) to classify my local
|
||||||
// ones (localShared)
|
// ones (localShared)
|
||||||
|
|
||||||
@ -1896,14 +1880,14 @@ Foam::pointField Foam::globalMeshData::sharedPoints() const
|
|||||||
sharedPoints[sharedPointi] = mesh_.points()[pointLabels[i]];
|
sharedPoints[sharedPointi] = mesh_.points()[pointLabels[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive data from slaves and insert
|
// Receive data and insert
|
||||||
for (const int slave : Pstream::subProcs())
|
for (const int proci : Pstream::subProcs())
|
||||||
{
|
{
|
||||||
IPstream fromSlave(Pstream::commsTypes::blocking, slave);
|
IPstream fromProc(Pstream::commsTypes::blocking, proci);
|
||||||
|
|
||||||
labelList nbrSharedPointAddr;
|
labelList nbrSharedPointAddr;
|
||||||
pointField nbrSharedPoints;
|
pointField nbrSharedPoints;
|
||||||
fromSlave >> nbrSharedPointAddr >> nbrSharedPoints;
|
fromProc >> nbrSharedPointAddr >> nbrSharedPoints;
|
||||||
|
|
||||||
forAll(nbrSharedPointAddr, i)
|
forAll(nbrSharedPointAddr, i)
|
||||||
{
|
{
|
||||||
@ -1912,24 +1896,12 @@ Foam::pointField Foam::globalMeshData::sharedPoints() const
|
|||||||
sharedPoints[sharedPointi] = nbrSharedPoints[i];
|
sharedPoints[sharedPointi] = nbrSharedPoints[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send back
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
OPstream toSlave
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::blocking,
|
|
||||||
slave,
|
|
||||||
sharedPoints.size_bytes()
|
|
||||||
);
|
|
||||||
toSlave << sharedPoints;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Slave:
|
if (Pstream::parRun())
|
||||||
// send points
|
|
||||||
{
|
{
|
||||||
|
// Send address and points
|
||||||
OPstream toMaster
|
OPstream toMaster
|
||||||
(
|
(
|
||||||
Pstream::commsTypes::blocking,
|
Pstream::commsTypes::blocking,
|
||||||
@ -1937,19 +1909,13 @@ Foam::pointField Foam::globalMeshData::sharedPoints() const
|
|||||||
);
|
);
|
||||||
toMaster
|
toMaster
|
||||||
<< pointAddr
|
<< pointAddr
|
||||||
<< UIndirectList<point>(mesh_.points(), pointLabels)();
|
<< pointField(mesh_.points(), pointLabels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive sharedPoints
|
// Broadcast: sharedPoints to all
|
||||||
{
|
Pstream::broadcast(sharedPoints); // == worldComm
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::blocking,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> sharedPoints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sharedPoints;
|
return sharedPoints;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015-2017 OpenFOAM Foundation
|
Copyright (C) 2015-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -80,48 +80,31 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reduce
|
// Gather/reduce
|
||||||
if (Pstream::master(comm))
|
if (Pstream::master(comm))
|
||||||
{
|
{
|
||||||
// Receive and merge
|
// Receive and merge
|
||||||
for (const int slave : Pstream::subProcs(comm))
|
for (const int proci : Pstream::subProcs(comm))
|
||||||
{
|
{
|
||||||
IPstream fromSlave
|
IPstream fromProc
|
||||||
(
|
(
|
||||||
Pstream::commsTypes::scheduled,
|
Pstream::commsTypes::scheduled,
|
||||||
slave,
|
proci,
|
||||||
0,
|
0,
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
List<labelPair> nbrData(fromSlave);
|
List<labelPair> nbrData(fromProc);
|
||||||
|
|
||||||
forAll(nbrData, i)
|
for (const labelPair& connection : nbrData)
|
||||||
{
|
{
|
||||||
if (!allComms.found(nbrData[i]))
|
allComms.appendUniq(connection);
|
||||||
{
|
|
||||||
label sz = allComms.size();
|
|
||||||
allComms.setSize(sz+1);
|
|
||||||
allComms[sz] = nbrData[i];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send back
|
|
||||||
for (const int slave : Pstream::subProcs(comm))
|
|
||||||
{
|
|
||||||
OPstream toSlave
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
slave,
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
toSlave << allComms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
OPstream toMaster
|
OPstream toMaster
|
||||||
(
|
(
|
||||||
@ -133,19 +116,11 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
|
|||||||
);
|
);
|
||||||
toMaster << allComms;
|
toMaster << allComms;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo(),
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
fromMaster >> allComms;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast: send comms information to all
|
||||||
|
Pstream::broadcast(allComms, comm);
|
||||||
|
|
||||||
|
|
||||||
// Determine my schedule.
|
// Determine my schedule.
|
||||||
labelList mySchedule
|
labelList mySchedule
|
||||||
@ -158,7 +133,7 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Processors involved in my schedule
|
// Processors involved in my schedule
|
||||||
return List<labelPair>(UIndirectList<labelPair>(allComms, mySchedule));
|
return List<labelPair>(allComms, mySchedule);
|
||||||
|
|
||||||
|
|
||||||
//if (debug)
|
//if (debug)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -127,6 +127,7 @@ void Foam::syncTools::syncPointMap
|
|||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
|
DynamicList<label> neighbProcs;
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
@ -137,6 +138,7 @@ void Foam::syncTools::syncPointMap
|
|||||||
if (ppp && pp.nPoints())
|
if (ppp && pp.nPoints())
|
||||||
{
|
{
|
||||||
const auto& procPatch = *ppp;
|
const auto& procPatch = *ppp;
|
||||||
|
const label nbrProci = procPatch.neighbProcNo();
|
||||||
|
|
||||||
// Get data per patchPoint in neighbouring point numbers.
|
// Get data per patchPoint in neighbouring point numbers.
|
||||||
|
|
||||||
@ -157,12 +159,14 @@ void Foam::syncTools::syncPointMap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
|
neighbProcs.append(nbrProci);
|
||||||
toNeighb << patchInfo;
|
UOPstream toNbr(nbrProci, pBufs);
|
||||||
|
toNbr << patchInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pBufs.finishedSends();
|
// Limit exchange to involved procs
|
||||||
|
pBufs.finishedNeighbourSends(neighbProcs);
|
||||||
|
|
||||||
// Receive and combine.
|
// Receive and combine.
|
||||||
for (const polyPatch& pp : patches)
|
for (const polyPatch& pp : patches)
|
||||||
@ -172,8 +176,9 @@ void Foam::syncTools::syncPointMap
|
|||||||
if (ppp && pp.nPoints())
|
if (ppp && pp.nPoints())
|
||||||
{
|
{
|
||||||
const auto& procPatch = *ppp;
|
const auto& procPatch = *ppp;
|
||||||
|
const label nbrProci = procPatch.neighbProcNo();
|
||||||
|
|
||||||
UIPstream fromNbr(procPatch.neighbProcNo(), pBufs);
|
UIPstream fromNbr(nbrProci, pBufs);
|
||||||
Map<T> nbrPatchInfo(fromNbr);
|
Map<T> nbrPatchInfo(fromNbr);
|
||||||
|
|
||||||
// Transform
|
// Transform
|
||||||
@ -286,11 +291,11 @@ void Foam::syncTools::syncPointMap
|
|||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
// Receive the edges using shared points from the slave.
|
// Receive the edges using shared points from other procs
|
||||||
for (const int slave : Pstream::subProcs())
|
for (const int proci : Pstream::subProcs())
|
||||||
{
|
{
|
||||||
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
IPstream fromProc(Pstream::commsTypes::scheduled, proci);
|
||||||
Map<T> nbrValues(fromSlave);
|
Map<T> nbrValues(fromProc);
|
||||||
|
|
||||||
// Merge neighbouring values with my values
|
// Merge neighbouring values with my values
|
||||||
forAllConstIters(nbrValues, iter)
|
forAllConstIters(nbrValues, iter)
|
||||||
@ -304,18 +309,10 @@ void Foam::syncTools::syncPointMap
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send back
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
OPstream toSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
toSlave << sharedPointValues;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Slave: send to master
|
// Send to master
|
||||||
{
|
|
||||||
OPstream toMaster
|
OPstream toMaster
|
||||||
(
|
(
|
||||||
Pstream::commsTypes::scheduled,
|
Pstream::commsTypes::scheduled,
|
||||||
@ -323,18 +320,10 @@ void Foam::syncTools::syncPointMap
|
|||||||
);
|
);
|
||||||
toMaster << sharedPointValues;
|
toMaster << sharedPointValues;
|
||||||
}
|
}
|
||||||
// Receive merged values
|
|
||||||
{
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> sharedPointValues;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Broadcast: send merged values to all
|
||||||
|
Pstream::scatter(sharedPointValues);
|
||||||
|
}
|
||||||
|
|
||||||
// Merge sharedPointValues (keyed on sharedPointAddr) into
|
// Merge sharedPointValues (keyed on sharedPointAddr) into
|
||||||
// pointValues (keyed on mesh points).
|
// pointValues (keyed on mesh points).
|
||||||
@ -381,6 +370,7 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
|
DynamicList<label> neighbProcs;
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
@ -391,6 +381,7 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
if (ppp && pp.nEdges())
|
if (ppp && pp.nEdges())
|
||||||
{
|
{
|
||||||
const auto& procPatch = *ppp;
|
const auto& procPatch = *ppp;
|
||||||
|
const label nbrProci = procPatch.neighbProcNo();
|
||||||
|
|
||||||
// Get data per patch edge in neighbouring edge.
|
// Get data per patch edge in neighbouring edge.
|
||||||
|
|
||||||
@ -413,12 +404,15 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UOPstream toNeighb(procPatch.neighbProcNo(), pBufs);
|
neighbProcs.append(nbrProci);
|
||||||
toNeighb << patchInfo;
|
UOPstream toNbr(nbrProci, pBufs);
|
||||||
|
toNbr << patchInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pBufs.finishedSends();
|
// Limit exchange to involved procs
|
||||||
|
pBufs.finishedNeighbourSends(neighbProcs);
|
||||||
|
|
||||||
|
|
||||||
// Receive and combine.
|
// Receive and combine.
|
||||||
for (const polyPatch& pp : patches)
|
for (const polyPatch& pp : patches)
|
||||||
@ -640,11 +634,11 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
// Receive the edges using shared points from the slave.
|
// Receive the edges using shared points from other procs
|
||||||
for (const int slave : Pstream::subProcs())
|
for (const int proci : Pstream::subProcs())
|
||||||
{
|
{
|
||||||
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
IPstream fromProc(Pstream::commsTypes::scheduled, proci);
|
||||||
EdgeMap<T> nbrValues(fromSlave);
|
EdgeMap<T> nbrValues(fromProc);
|
||||||
|
|
||||||
// Merge neighbouring values with my values
|
// Merge neighbouring values with my values
|
||||||
forAllConstIters(nbrValues, iter)
|
forAllConstIters(nbrValues, iter)
|
||||||
@ -658,13 +652,6 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send back
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
OPstream toSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
toSlave << sharedEdgeValues;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -677,16 +664,10 @@ void Foam::syncTools::syncEdgeMap
|
|||||||
);
|
);
|
||||||
toMaster << sharedEdgeValues;
|
toMaster << sharedEdgeValues;
|
||||||
}
|
}
|
||||||
// Receive merged values
|
|
||||||
{
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> sharedEdgeValues;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast: send merged values to all
|
||||||
|
Pstream::scatter(sharedEdgeValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1121,6 +1102,7 @@ void Foam::syncTools::syncBoundaryFaceList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
DynamicList<label> neighbProcs;
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
@ -1131,6 +1113,7 @@ void Foam::syncTools::syncBoundaryFaceList
|
|||||||
if (ppp && pp.size())
|
if (ppp && pp.size())
|
||||||
{
|
{
|
||||||
const auto& procPatch = *ppp;
|
const auto& procPatch = *ppp;
|
||||||
|
const label nbrProci = procPatch.neighbProcNo();
|
||||||
|
|
||||||
const SubList<T> fld
|
const SubList<T> fld
|
||||||
(
|
(
|
||||||
@ -1139,12 +1122,15 @@ void Foam::syncTools::syncBoundaryFaceList
|
|||||||
pp.start()-boundaryOffset
|
pp.start()-boundaryOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
UOPstream toNbr(procPatch.neighbProcNo(), pBufs);
|
neighbProcs.append(nbrProci);
|
||||||
toNbr << fld;;
|
UOPstream toNbr(nbrProci, pBufs);
|
||||||
|
toNbr << fld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pBufs.finishedSends();
|
// Limit exchange to involved procs
|
||||||
|
pBufs.finishedNeighbourSends(neighbProcs);
|
||||||
|
|
||||||
|
|
||||||
// Receive and combine.
|
// Receive and combine.
|
||||||
for (const polyPatch& pp : patches)
|
for (const polyPatch& pp : patches)
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2017 OpenFOAM Foundation
|
Copyright (C) 2012-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -136,7 +136,7 @@ void Foam::PatchTools::gatherAndMerge
|
|||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
// Renumber the setPatch points/faces into unique points
|
// Renumber the points/faces into unique points
|
||||||
globalPointsPtr = mesh.globalData().mergePoints
|
globalPointsPtr = mesh.globalData().mergePoints
|
||||||
(
|
(
|
||||||
meshPoints,
|
meshPoints,
|
||||||
@ -147,65 +147,22 @@ void Foam::PatchTools::gatherAndMerge
|
|||||||
|
|
||||||
globalFacesPtr.reset(new globalIndex(localFaces.size()));
|
globalFacesPtr.reset(new globalIndex(localFaces.size()));
|
||||||
|
|
||||||
if (Pstream::master())
|
// Renumber faces locally
|
||||||
{
|
|
||||||
// Get renumbered local data
|
|
||||||
pointField myPoints(mesh.points(), uniqueMeshPointLabels);
|
|
||||||
List<FaceType> myFaces(localFaces);
|
List<FaceType> myFaces(localFaces);
|
||||||
for (auto& f : myFaces)
|
for (auto& f : myFaces)
|
||||||
{
|
{
|
||||||
inplaceRenumber(pointToGlobal, f);
|
inplaceRenumber(pointToGlobal, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can also use
|
||||||
mergedFaces.setSize(globalFacesPtr().totalSize());
|
// UIndirectList<point>(mesh.points(), uniqueMeshPointLabels)
|
||||||
mergedPoints.setSize(globalPointsPtr().totalSize());
|
// but favour communication over local memory use
|
||||||
|
globalPointsPtr().gather
|
||||||
// Insert master data first
|
|
||||||
label pOffset = globalPointsPtr().localStart(Pstream::masterNo());
|
|
||||||
SubList<point>(mergedPoints, myPoints.size(), pOffset) = myPoints;
|
|
||||||
|
|
||||||
label fOffset = globalFacesPtr().localStart(Pstream::masterNo());
|
|
||||||
SubList<FaceType>(mergedFaces, myFaces.size(), fOffset) = myFaces;
|
|
||||||
|
|
||||||
|
|
||||||
// Receive slave ones
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
|
|
||||||
pointField slavePoints(fromSlave);
|
|
||||||
List<FaceType> slaveFaces(fromSlave);
|
|
||||||
|
|
||||||
label pOffset = globalPointsPtr().localStart(slave);
|
|
||||||
SubList<point>(mergedPoints, slavePoints.size(), pOffset) =
|
|
||||||
slavePoints;
|
|
||||||
|
|
||||||
label fOffset = globalFacesPtr().localStart(slave);
|
|
||||||
SubList<FaceType>(mergedFaces, slaveFaces.size(), fOffset) =
|
|
||||||
slaveFaces;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get renumbered local data
|
|
||||||
pointField myPoints(mesh.points(), uniqueMeshPointLabels);
|
|
||||||
List<FaceType> myFaces(localFaces);
|
|
||||||
for (auto& f : myFaces)
|
|
||||||
{
|
|
||||||
inplaceRenumber(pointToGlobal, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct processor stream with estimate of size. Could
|
|
||||||
// be improved.
|
|
||||||
OPstream toMaster
|
|
||||||
(
|
(
|
||||||
Pstream::commsTypes::scheduled,
|
pointField(mesh.points(), uniqueMeshPointLabels),
|
||||||
Pstream::masterNo(),
|
mergedPoints
|
||||||
myPoints.byteSize() + 4*sizeof(label)*myFaces.size()
|
|
||||||
);
|
);
|
||||||
toMaster << myPoints << myFaces;
|
globalFacesPtr().gather(myFaces, mergedFaces);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,8 +27,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "commSchedule.H"
|
#include "commSchedule.H"
|
||||||
#include "SortableList.H"
|
#include "ListOps.H"
|
||||||
#include "boolList.H"
|
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "StringStream.H"
|
#include "StringStream.H"
|
||||||
@ -41,26 +41,32 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::label Foam::commSchedule::outstandingComms
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Count the number of outstanding communications for a single processor
|
||||||
|
static label outstandingComms
|
||||||
(
|
(
|
||||||
const labelList& commToSchedule,
|
const labelList& commToSchedule,
|
||||||
DynamicList<label>& procComms
|
DynamicList<label>& procComms
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
label nOutstanding = 0;
|
label nOutstanding = 0;
|
||||||
|
|
||||||
forAll(procComms, i)
|
for (const label commi : procComms)
|
||||||
{
|
{
|
||||||
if (commToSchedule[procComms[i]] == -1)
|
if (commToSchedule[commi] == -1)
|
||||||
{
|
{
|
||||||
nOutstanding++;
|
++nOutstanding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nOutstanding;
|
return nOutstanding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -92,9 +98,9 @@ Foam::commSchedule::commSchedule
|
|||||||
}
|
}
|
||||||
// Note: no need to shrink procToComms. Are small.
|
// Note: no need to shrink procToComms. Are small.
|
||||||
|
|
||||||
if (debug && Pstream::master())
|
if (debug && UPstream::master())
|
||||||
{
|
{
|
||||||
Pout<< "commSchedule::commSchedule : Wanted communication:" << endl;
|
Pout<< "commSchedule : Wanted communication:" << endl;
|
||||||
|
|
||||||
forAll(comms, i)
|
forAll(comms, i)
|
||||||
{
|
{
|
||||||
@ -106,7 +112,7 @@ Foam::commSchedule::commSchedule
|
|||||||
Pout<< endl;
|
Pout<< endl;
|
||||||
|
|
||||||
|
|
||||||
Pout<< "commSchedule::commSchedule : Schedule:" << endl;
|
Pout<< "commSchedule : Schedule:" << endl;
|
||||||
|
|
||||||
// Print header. Use buffered output to prevent parallel output messing
|
// Print header. Use buffered output to prevent parallel output messing
|
||||||
// up.
|
// up.
|
||||||
@ -191,7 +197,7 @@ Foam::commSchedule::commSchedule
|
|||||||
busy[comms[maxCommI][1]] = true;
|
busy[comms[maxCommI][1]] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug && Pstream::master())
|
if (debug && UPstream::master())
|
||||||
{
|
{
|
||||||
label nIterComms = nScheduled-oldNScheduled;
|
label nIterComms = nScheduled-oldNScheduled;
|
||||||
|
|
||||||
@ -233,14 +239,15 @@ Foam::commSchedule::commSchedule
|
|||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug && Pstream::master())
|
if (debug && UPstream::master())
|
||||||
{
|
{
|
||||||
Pout<< endl;
|
Pout<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sort commToSchedule and obtain order in comms
|
// Sort commToSchedule to obtain order in comms
|
||||||
schedule_ = SortableList<label>(commToSchedule).indices();
|
|
||||||
|
Foam::sortedOrder(commToSchedule, schedule_);
|
||||||
|
|
||||||
// Sort schedule_ by processor
|
// Sort schedule_ by processor
|
||||||
|
|
||||||
@ -274,7 +281,7 @@ Foam::commSchedule::commSchedule
|
|||||||
procSchedule_[proc1][nProcScheduled[proc1]++] = commI;
|
procSchedule_[proc1][nProcScheduled[proc1]++] = commI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug && Pstream::master())
|
if (debug && UPstream::master())
|
||||||
{
|
{
|
||||||
Pout<< "commSchedule::commSchedule : Per processor:" << endl;
|
Pout<< "commSchedule::commSchedule : Per processor:" << endl;
|
||||||
|
|
||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -49,10 +50,9 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef commSchedule_H
|
#ifndef Foam_commSchedule_H
|
||||||
#define commSchedule_H
|
#define Foam_commSchedule_H
|
||||||
|
|
||||||
#include "DynamicList.H"
|
|
||||||
#include "labelPair.H"
|
#include "labelPair.H"
|
||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ namespace Foam
|
|||||||
|
|
||||||
class commSchedule
|
class commSchedule
|
||||||
{
|
{
|
||||||
// Private data
|
// Private Data
|
||||||
|
|
||||||
//- Order in which input communication has been scheduled
|
//- Order in which input communication has been scheduled
|
||||||
labelList schedule_;
|
labelList schedule_;
|
||||||
@ -75,12 +75,6 @@ class commSchedule
|
|||||||
//- Per processor the order in which communication has been scheduled
|
//- Per processor the order in which communication has been scheduled
|
||||||
labelListList procSchedule_;
|
labelListList procSchedule_;
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Count the number of outstanding communications for a single
|
|
||||||
// processor
|
|
||||||
label outstandingComms(const labelList&, DynamicList<label>&) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -34,16 +34,16 @@ License
|
|||||||
void Foam::globalIndex::reportOverflowAndExit
|
void Foam::globalIndex::reportOverflowAndExit
|
||||||
(
|
(
|
||||||
const label idx,
|
const label idx,
|
||||||
const labelUList& localSizes
|
const labelUList& localLens
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Overflow : sum of sizes exceeds labelMax ("
|
<< "Overflow : sum of sizes exceeds labelMax ("
|
||||||
<< labelMax << ") after index " << idx;
|
<< labelMax << ") after index " << idx;
|
||||||
|
|
||||||
if (!localSizes.empty())
|
if (!localLens.empty())
|
||||||
{
|
{
|
||||||
FatalError << " of " << flatOutput(localSizes);
|
FatalError << " of " << flatOutput(localLens);
|
||||||
}
|
}
|
||||||
|
|
||||||
FatalError
|
FatalError
|
||||||
@ -56,13 +56,13 @@ void Foam::globalIndex::reportOverflowAndExit
|
|||||||
Foam::labelList
|
Foam::labelList
|
||||||
Foam::globalIndex::calcOffsets
|
Foam::globalIndex::calcOffsets
|
||||||
(
|
(
|
||||||
const labelUList& localSizes,
|
const labelUList& localLens,
|
||||||
const bool checkOverflow
|
const bool checkOverflow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
labelList values;
|
labelList values;
|
||||||
|
|
||||||
const label len = localSizes.size();
|
const label len = localLens.size();
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
@ -72,11 +72,11 @@ Foam::globalIndex::calcOffsets
|
|||||||
for (label i = 0; i < len; ++i)
|
for (label i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
values[i] = start;
|
values[i] = start;
|
||||||
start += localSizes[i];
|
start += localLens[i];
|
||||||
|
|
||||||
if (checkOverflow && start < values[i])
|
if (checkOverflow && start < values[i])
|
||||||
{
|
{
|
||||||
reportOverflowAndExit(i, localSizes);
|
reportOverflowAndExit(i, localLens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values[len] = start;
|
values[len] = start;
|
||||||
@ -89,13 +89,13 @@ Foam::globalIndex::calcOffsets
|
|||||||
Foam::List<Foam::labelRange>
|
Foam::List<Foam::labelRange>
|
||||||
Foam::globalIndex::calcRanges
|
Foam::globalIndex::calcRanges
|
||||||
(
|
(
|
||||||
const labelUList& localSizes,
|
const labelUList& localLens,
|
||||||
const bool checkOverflow
|
const bool checkOverflow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
List<labelRange> values;
|
List<labelRange> values;
|
||||||
|
|
||||||
const label len = localSizes.size();
|
const label len = localLens.size();
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
@ -104,12 +104,12 @@ Foam::globalIndex::calcRanges
|
|||||||
label start = 0;
|
label start = 0;
|
||||||
for (label i = 0; i < len; ++i)
|
for (label i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
values[i].reset(start, localSizes[i]);
|
values[i].reset(start, localLens[i]);
|
||||||
start += localSizes[i];
|
start += localLens[i];
|
||||||
|
|
||||||
if (checkOverflow && start < values[i].start())
|
if (checkOverflow && start < values[i].start())
|
||||||
{
|
{
|
||||||
reportOverflowAndExit(i, localSizes);
|
reportOverflowAndExit(i, localLens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,16 +221,16 @@ void Foam::globalIndex::reset
|
|||||||
// Seed with localSize, zero elsewhere (for non-parallel branch)
|
// Seed with localSize, zero elsewhere (for non-parallel branch)
|
||||||
// NB: can consider UPstream::listGatherValues
|
// NB: can consider UPstream::listGatherValues
|
||||||
|
|
||||||
labelList localSizes(len, Zero);
|
labelList localLens(len, Zero);
|
||||||
localSizes[Pstream::myProcNo(comm)] = localSize;
|
localLens[Pstream::myProcNo(comm)] = localSize;
|
||||||
|
|
||||||
if (parallel)
|
if (parallel)
|
||||||
{
|
{
|
||||||
Pstream::gatherList(localSizes, tag, comm);
|
Pstream::gatherList(localLens, tag, comm);
|
||||||
Pstream::scatterList(localSizes, tag, comm);
|
Pstream::scatterList(localLens, tag, comm);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(localSizes, true); // checkOverflow = true
|
reset(localLens, true); // checkOverflow = true
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -242,11 +242,11 @@ void Foam::globalIndex::reset
|
|||||||
|
|
||||||
void Foam::globalIndex::reset
|
void Foam::globalIndex::reset
|
||||||
(
|
(
|
||||||
const labelUList& localSizes,
|
const labelUList& localLens,
|
||||||
const bool checkOverflow
|
const bool checkOverflow
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const label len = localSizes.size();
|
const label len = localLens.size();
|
||||||
|
|
||||||
if (len)
|
if (len)
|
||||||
{
|
{
|
||||||
@ -256,11 +256,11 @@ void Foam::globalIndex::reset
|
|||||||
for (label i = 0; i < len; ++i)
|
for (label i = 0; i < len; ++i)
|
||||||
{
|
{
|
||||||
offsets_[i] = start;
|
offsets_[i] = start;
|
||||||
start += localSizes[i];
|
start += localLens[i];
|
||||||
|
|
||||||
if (checkOverflow && start < offsets_[i])
|
if (checkOverflow && start < offsets_[i])
|
||||||
{
|
{
|
||||||
reportOverflowAndExit(i, localSizes);
|
reportOverflowAndExit(i, localLens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offsets_[len] = start;
|
offsets_[len] = start;
|
||||||
@ -290,7 +290,7 @@ void Foam::globalIndex::setLocalSize(const label proci, const label len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::globalIndex::sizes() const
|
Foam::labelList Foam::globalIndex::localSizes() const
|
||||||
{
|
{
|
||||||
labelList values;
|
labelList values;
|
||||||
|
|
||||||
|
|||||||
@ -89,7 +89,7 @@ class globalIndex
|
|||||||
static void reportOverflowAndExit
|
static void reportOverflowAndExit
|
||||||
(
|
(
|
||||||
const label idx,
|
const label idx,
|
||||||
const labelUList& localSizes = labelUList::null()
|
const labelUList& localLens = labelUList::null()
|
||||||
);
|
);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -178,12 +178,15 @@ public:
|
|||||||
//- Global sum of localSizes.
|
//- Global sum of localSizes.
|
||||||
inline label totalSize() const;
|
inline label totalSize() const;
|
||||||
|
|
||||||
//- The local sizes
|
//- The local sizes. Same as localSizes()
|
||||||
labelList sizes() const;
|
inline labelList sizes() const;
|
||||||
|
|
||||||
//- The local starts
|
//- The local starts
|
||||||
inline const labelUList localStarts() const;
|
inline const labelUList localStarts() const;
|
||||||
|
|
||||||
|
//- The local sizes
|
||||||
|
labelList localSizes() const;
|
||||||
|
|
||||||
//- Global max of localSizes
|
//- Global max of localSizes
|
||||||
inline label maxSize() const;
|
inline label maxSize() const;
|
||||||
|
|
||||||
@ -276,7 +279,7 @@ public:
|
|||||||
inline labelList toGlobal(const labelUList& labels) const;
|
inline labelList toGlobal(const labelUList& labels) const;
|
||||||
|
|
||||||
//- From local to global index (inplace)
|
//- From local to global index (inplace)
|
||||||
inline void inplaceToGlobal(labelList& labels) const;
|
inline void inplaceToGlobal(labelUList& labels) const;
|
||||||
|
|
||||||
//- From global to local on current processor.
|
//- From global to local on current processor.
|
||||||
// FatalError if not on local processor.
|
// FatalError if not on local processor.
|
||||||
@ -314,7 +317,7 @@ public:
|
|||||||
inline void inplaceToGlobal
|
inline void inplaceToGlobal
|
||||||
(
|
(
|
||||||
const label proci,
|
const label proci,
|
||||||
labelList& labels
|
labelUList& labels
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
@ -405,7 +408,7 @@ public:
|
|||||||
//- with optional check for label overflow
|
//- with optional check for label overflow
|
||||||
static labelList calcOffsets
|
static labelList calcOffsets
|
||||||
(
|
(
|
||||||
const labelUList& localSizes,
|
const labelUList& localLens,
|
||||||
const bool checkOverflow = false
|
const bool checkOverflow = false
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -422,7 +425,7 @@ public:
|
|||||||
//- with optional check for label overflow
|
//- with optional check for label overflow
|
||||||
static List<labelRange> calcRanges
|
static List<labelRange> calcRanges
|
||||||
(
|
(
|
||||||
const labelUList& localSizes,
|
const labelUList& localLens,
|
||||||
const bool checkOverflow = false
|
const bool checkOverflow = false
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -774,8 +777,21 @@ public:
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void scatter
|
void scatter
|
||||||
(
|
(
|
||||||
const UList<Type>& allFld,
|
const UList<Type>& allData,
|
||||||
UList<Type>& fld,
|
UList<Type>& localData,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking,
|
||||||
|
const label comm = UPstream::worldComm //!< communicator
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Distribute data in processor order
|
||||||
|
//- (in serial: performs a simple copy).
|
||||||
|
// Communication with default/specified communicator, message tag.
|
||||||
|
// \note the globalIndex offsets needed on master only.
|
||||||
|
template<class Type, class OutputContainer = List<Type>>
|
||||||
|
OutputContainer scatter
|
||||||
|
(
|
||||||
|
const UList<Type>& allData,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking,
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking,
|
||||||
const label comm = UPstream::worldComm //!< communicator
|
const label comm = UPstream::worldComm //!< communicator
|
||||||
|
|||||||
@ -142,6 +142,12 @@ inline Foam::label Foam::globalIndex::size() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::labelList Foam::globalIndex::sizes() const
|
||||||
|
{
|
||||||
|
return localSizes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::label Foam::globalIndex::nProcs() const noexcept
|
inline Foam::label Foam::globalIndex::nProcs() const noexcept
|
||||||
{
|
{
|
||||||
const label len = (offsets_.size() - 1);
|
const label len = (offsets_.size() - 1);
|
||||||
@ -289,7 +295,7 @@ inline Foam::labelList Foam::globalIndex::toGlobal
|
|||||||
inline void Foam::globalIndex::inplaceToGlobal
|
inline void Foam::globalIndex::inplaceToGlobal
|
||||||
(
|
(
|
||||||
const label proci,
|
const label proci,
|
||||||
labelList& labels
|
labelUList& labels
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const label off = offsets_[proci];
|
const label off = offsets_[proci];
|
||||||
@ -301,7 +307,7 @@ inline void Foam::globalIndex::inplaceToGlobal
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void Foam::globalIndex::inplaceToGlobal(labelList& labels) const
|
inline void Foam::globalIndex::inplaceToGlobal(labelUList& labels) const
|
||||||
{
|
{
|
||||||
inplaceToGlobal(Pstream::myProcNo(), labels);
|
inplaceToGlobal(Pstream::myProcNo(), labels);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,22 +73,22 @@ void Foam::globalIndex::gather
|
|||||||
const UList<Type>& fld,
|
const UList<Type>& fld,
|
||||||
List<Type>& allFld,
|
List<Type>& allFld,
|
||||||
const int tag,
|
const int tag,
|
||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes preferredCommsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// low-level: no parRun guard
|
// low-level: no parRun guard
|
||||||
|
|
||||||
if
|
// Automatically change from nonBlocking to scheduled for
|
||||||
|
// non-contiguous data.
|
||||||
|
const UPstream::commsTypes commsType =
|
||||||
|
(
|
||||||
(
|
(
|
||||||
!is_contiguous<Type>::value
|
!is_contiguous<Type>::value
|
||||||
&& commsType == Pstream::commsTypes::nonBlocking
|
&& UPstream::commsTypes::nonBlocking == preferredCommsType
|
||||||
)
|
)
|
||||||
{
|
? UPstream::commsTypes::scheduled
|
||||||
FatalErrorInFunction
|
: preferredCommsType
|
||||||
<< "Cannot use nonBlocking with non-contiguous data"
|
);
|
||||||
<< exit(FatalError);
|
|
||||||
// Could also warn and change to scheduled etc...
|
|
||||||
}
|
|
||||||
|
|
||||||
const label startOfRequests = UPstream::nRequests();
|
const label startOfRequests = UPstream::nRequests();
|
||||||
|
|
||||||
@ -126,14 +126,7 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IPstream fromProc
|
IPstream fromProc(commsType, procIDs[i], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[i],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
fromProc >> procSlot;
|
fromProc >> procSlot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,14 +151,7 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OPstream toMaster
|
OPstream toMaster(commsType, procIDs[0], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[0],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
toMaster << fld;
|
toMaster << fld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,18 +173,22 @@ void Foam::globalIndex::gather
|
|||||||
const IndirectListBase<Type, Addr>& fld,
|
const IndirectListBase<Type, Addr>& fld,
|
||||||
List<Type>& allFld,
|
List<Type>& allFld,
|
||||||
const int tag,
|
const int tag,
|
||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes preferredCommsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// low-level: no parRun guard
|
// low-level: no parRun guard
|
||||||
|
|
||||||
if (commsType == Pstream::commsTypes::nonBlocking)
|
// Automatically change from nonBlocking to scheduled for
|
||||||
{
|
// non-contiguous data.
|
||||||
WarningInFunction
|
const UPstream::commsTypes commsType =
|
||||||
<< "Cannot use nonBlocking with indirect list of data"
|
(
|
||||||
<< exit(FatalError);
|
(
|
||||||
// Could also warn and change to scheduled etc...
|
!is_contiguous<Type>::value
|
||||||
}
|
&& UPstream::commsTypes::nonBlocking == preferredCommsType
|
||||||
|
)
|
||||||
|
? UPstream::commsTypes::scheduled
|
||||||
|
: preferredCommsType
|
||||||
|
);
|
||||||
|
|
||||||
if (Pstream::myProcNo(comm) == procIDs[0])
|
if (Pstream::myProcNo(comm) == procIDs[0])
|
||||||
{
|
{
|
||||||
@ -224,14 +214,7 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IPstream fromProc
|
IPstream fromProc(commsType, procIDs[i], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[i],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
fromProc >> procSlot;
|
fromProc >> procSlot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,14 +227,7 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OPstream toMaster
|
OPstream toMaster(commsType, procIDs[0], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[0],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
toMaster << fld;
|
toMaster << fld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -692,20 +668,22 @@ void Foam::globalIndex::scatter
|
|||||||
const UList<Type>& allFld,
|
const UList<Type>& allFld,
|
||||||
UList<Type>& fld,
|
UList<Type>& fld,
|
||||||
const int tag,
|
const int tag,
|
||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes preferredCommsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if
|
// low-level: no parRun guard
|
||||||
|
|
||||||
|
// Automatically change from nonBlocking to scheduled for
|
||||||
|
// non-contiguous data.
|
||||||
|
const UPstream::commsTypes commsType =
|
||||||
|
(
|
||||||
(
|
(
|
||||||
!is_contiguous<Type>::value
|
!is_contiguous<Type>::value
|
||||||
&& commsType == Pstream::commsTypes::nonBlocking
|
&& UPstream::commsTypes::nonBlocking == preferredCommsType
|
||||||
)
|
)
|
||||||
{
|
? UPstream::commsTypes::scheduled
|
||||||
FatalErrorInFunction
|
: preferredCommsType
|
||||||
<< "Cannot use nonBlocking with non-contiguous data"
|
);
|
||||||
<< exit(FatalError);
|
|
||||||
// Could also warn and change to scheduled etc...
|
|
||||||
}
|
|
||||||
|
|
||||||
// FUTURE:
|
// FUTURE:
|
||||||
// could decide which procs will receive data and use mpiScatter
|
// could decide which procs will receive data and use mpiScatter
|
||||||
@ -715,18 +693,15 @@ void Foam::globalIndex::scatter
|
|||||||
|
|
||||||
if (Pstream::myProcNo(comm) == procIDs[0])
|
if (Pstream::myProcNo(comm) == procIDs[0])
|
||||||
{
|
{
|
||||||
const SubList<Type> localSlot(allFld, off[1]-off[0], off[0]);
|
|
||||||
|
|
||||||
if (!localSlot.empty())
|
|
||||||
{
|
|
||||||
fld.deepCopy(localSlot);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (label i = 1; i < procIDs.size(); ++i)
|
for (label i = 1; i < procIDs.size(); ++i)
|
||||||
{
|
{
|
||||||
const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
|
const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
|
||||||
|
|
||||||
if (is_contiguous<Type>::value)
|
if (procSlot.empty())
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
else if (is_contiguous<Type>::value)
|
||||||
{
|
{
|
||||||
OPstream::write
|
OPstream::write
|
||||||
(
|
(
|
||||||
@ -740,21 +715,30 @@ void Foam::globalIndex::scatter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OPstream toProc
|
OPstream toProc(commsType, procIDs[i], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[i],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
toProc << procSlot;
|
toProc << procSlot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assign my local data - respect offset information
|
||||||
|
// so that we can request 0 entries to be copied.
|
||||||
|
// Also handle the case where we have a slice of the full
|
||||||
|
// list.
|
||||||
|
|
||||||
|
SubList<Type>(fld, off[1]-off[0]) =
|
||||||
|
SubList<Type>(allFld, off[1]-off[0], off[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (is_contiguous<Type>::value)
|
// Note: we are receiving into UList, so sizes MUST match or we
|
||||||
|
// have a problem. Can therefore reasonably assume that a zero-sized
|
||||||
|
// send matches a zero-sized receive, and we can skip that.
|
||||||
|
|
||||||
|
if (fld.empty())
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
else if (is_contiguous<Type>::value)
|
||||||
{
|
{
|
||||||
IPstream::read
|
IPstream::read
|
||||||
(
|
(
|
||||||
@ -768,14 +752,7 @@ void Foam::globalIndex::scatter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IPstream fromMaster
|
IPstream fromMaster(commsType, procIDs[0], 0, tag, comm);
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
procIDs[0],
|
|
||||||
0,
|
|
||||||
tag,
|
|
||||||
comm
|
|
||||||
);
|
|
||||||
fromMaster >> fld;
|
fromMaster >> fld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -791,26 +768,64 @@ void Foam::globalIndex::scatter
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::globalIndex::scatter
|
void Foam::globalIndex::scatter
|
||||||
(
|
(
|
||||||
const UList<Type>& allFld,
|
const UList<Type>& allData,
|
||||||
UList<Type>& fld,
|
UList<Type>& localData,
|
||||||
const int tag,
|
const int tag,
|
||||||
const Pstream::commsTypes commsType,
|
const Pstream::commsTypes commsType,
|
||||||
const label comm
|
const label comm
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// TBD: protection and special handling for serial?
|
if (UPstream::parRun())
|
||||||
{
|
{
|
||||||
scatter
|
scatter
|
||||||
(
|
(
|
||||||
offsets_, // needed on master only
|
offsets_, // needed on master only
|
||||||
comm,
|
comm,
|
||||||
UPstream::procID(comm),
|
UPstream::procID(comm),
|
||||||
allFld,
|
allData,
|
||||||
fld,
|
localData,
|
||||||
tag,
|
tag,
|
||||||
commsType
|
commsType
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Serial: direct copy
|
||||||
|
// - fails miserably if incorrectly dimensioned!
|
||||||
|
localData.deepCopy(allData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class OutputContainer>
|
||||||
|
OutputContainer Foam::globalIndex::scatter
|
||||||
|
(
|
||||||
|
const UList<Type>& allData,
|
||||||
|
const int tag,
|
||||||
|
const Pstream::commsTypes commsType,
|
||||||
|
const label comm
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (UPstream::parRun())
|
||||||
|
{
|
||||||
|
// The globalIndex might be correct on master only,
|
||||||
|
// so scatter local sizes to ensure consistency
|
||||||
|
|
||||||
|
const label localLen
|
||||||
|
(
|
||||||
|
UPstream::listScatterValues<label>(this->localSizes(), comm)
|
||||||
|
);
|
||||||
|
|
||||||
|
OutputContainer localData(localLen);
|
||||||
|
this->scatter(allData, localData, tag, commsType, comm);
|
||||||
|
|
||||||
|
return localData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Serial: direct copy
|
||||||
|
return OutputContainer(allData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -856,15 +871,14 @@ void Foam::globalIndex::get
|
|||||||
UOPstream os(proci, sendBufs);
|
UOPstream os(proci, sendBufs);
|
||||||
os << localIDs;
|
os << localIDs;
|
||||||
}
|
}
|
||||||
labelList recvSizes;
|
sendBufs.finishedSends();
|
||||||
sendBufs.finishedSends(recvSizes);
|
|
||||||
|
|
||||||
|
|
||||||
PstreamBuffers returnBufs(Pstream::commsTypes::nonBlocking, tag, comm);
|
PstreamBuffers returnBufs(Pstream::commsTypes::nonBlocking, tag, comm);
|
||||||
|
|
||||||
forAll(recvSizes, proci)
|
for (const int proci : sendBufs.allProcs())
|
||||||
{
|
{
|
||||||
if (recvSizes[proci])
|
if (sendBufs.hasRecvData(proci))
|
||||||
{
|
{
|
||||||
UIPstream is(proci, sendBufs);
|
UIPstream is(proci, sendBufs);
|
||||||
labelList localIDs(is);
|
labelList localIDs(is);
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
UPstream.C
|
UPstream.C
|
||||||
UIPread.C
|
UPstreamBroadcast.C
|
||||||
UOPwrite.C
|
UPstreamReduce.C
|
||||||
|
|
||||||
|
UIPstreamRead.C
|
||||||
|
UOPstreamWrite.C
|
||||||
|
UIPBstreamRead.C
|
||||||
|
UOPBstreamWrite.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/dummy/libPstream
|
LIB = $(FOAM_LIBBIN)/dummy/libPstream
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,32 +25,31 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "OPstream.H"
|
#include "UIPstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::OPstream::OPstream
|
void Foam::UIPBstream::bufferIPCrecv()
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::UIPBstream::read
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int toProcNo,
|
const int rootProcNo,
|
||||||
const label bufSize,
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label communicator
|
||||||
IOstreamOption::streamFormat fmt
|
|
||||||
)
|
)
|
||||||
:
|
{
|
||||||
Pstream(commsType, bufSize),
|
NotImplemented;
|
||||||
UOPstream
|
return 0;
|
||||||
(
|
}
|
||||||
commsType,
|
|
||||||
toProcNo,
|
|
||||||
Pstream::transferBuf_,
|
|
||||||
tag,
|
|
||||||
comm,
|
|
||||||
true, // sendAtDestruct
|
|
||||||
fmt
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -5,8 +5,8 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,34 +26,31 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "IPstream.H"
|
#include "UIPstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::IPstream::IPstream
|
void Foam::UIPstream::bufferIPCrecv()
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::UIPstream::read
|
||||||
(
|
(
|
||||||
const commsTypes commsType,
|
const commsTypes commsType,
|
||||||
const int fromProcNo,
|
const int fromProcNo,
|
||||||
const label bufSize,
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
const int tag,
|
const int tag,
|
||||||
const label comm,
|
const label communicator
|
||||||
IOstreamOption::streamFormat fmt
|
|
||||||
)
|
)
|
||||||
:
|
{
|
||||||
Pstream(commsType, bufSize),
|
NotImplemented;
|
||||||
UIPstream
|
return 0;
|
||||||
(
|
}
|
||||||
commsType,
|
|
||||||
fromProcNo,
|
|
||||||
Pstream::transferBuf_,
|
|
||||||
transferBufPosition_,
|
|
||||||
tag,
|
|
||||||
comm,
|
|
||||||
false, // Do not clear Pstream::transferBuf_ if at end
|
|
||||||
fmt
|
|
||||||
),
|
|
||||||
transferBufPosition_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
56
src/Pstream/dummy/UOPBstreamWrite.C
Normal file
56
src/Pstream/dummy/UOPBstreamWrite.C
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UOPstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPBstream::bufferIPCsend()
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPBstream::write
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int rootProcNo,
|
||||||
|
const char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag,
|
||||||
|
const label communicator
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -23,13 +24,19 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Write primitive and binary block from OPstream
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "UOPstream.H"
|
#include "UOPstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPstream::bufferIPCsend()
|
||||||
|
{
|
||||||
|
NotImplemented;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::UOPstream::write
|
bool Foam::UOPstream::write
|
||||||
@ -43,7 +50,6 @@ bool Foam::UOPstream::write
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
NotImplemented;
|
NotImplemented;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,7 +27,6 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
#include "PstreamReduceOps.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -74,99 +73,7 @@ void Foam::UPstream::abort()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce(scalar&, const sumOp<scalar>&, const int, const label)
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce(scalar&, const minOp<scalar>&, const int, const label)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce(vector2D&, const sumOp<vector2D>&, const int, const label)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::sumReduce
|
|
||||||
(
|
|
||||||
scalar&,
|
|
||||||
label&,
|
|
||||||
const int,
|
|
||||||
const label
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce(scalar&, const sumOp<scalar>&, const int, const label, label&)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
scalar[],
|
|
||||||
const int,
|
|
||||||
const sumOp<scalar>&,
|
|
||||||
const int,
|
|
||||||
const label,
|
|
||||||
label&
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(WM_SPDP)
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const minOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
Vector2D<solveScalar>& Value,
|
|
||||||
const sumOp<Vector2D<solveScalar>>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
void Foam::sumReduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
label& Count,
|
|
||||||
const int tag,
|
|
||||||
const label comm
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label comm,
|
|
||||||
label& request
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar[],
|
|
||||||
const int,
|
|
||||||
const sumOp<solveScalar>&,
|
|
||||||
const int,
|
|
||||||
const label,
|
|
||||||
label&
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::UPstream::allToAll
|
void Foam::UPstream::allToAll
|
||||||
(
|
(
|
||||||
|
|||||||
45
src/Pstream/dummy/UPstreamBroadcast.C
Normal file
45
src/Pstream/dummy/UPstreamBroadcast.C
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UPstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UPstream::broadcast
|
||||||
|
(
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const label communicator,
|
||||||
|
const int rootProcNo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Nothing to do - ignore
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
153
src/Pstream/dummy/UPstreamReduce.C
Normal file
153
src/Pstream/dummy/UPstreamReduce.C
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Pstream.H"
|
||||||
|
#include "PstreamReduceOps.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for bool
|
||||||
|
|
||||||
|
void Foam::reduce
|
||||||
|
(
|
||||||
|
bool& value,
|
||||||
|
const andOp<bool>&,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void Foam::reduce
|
||||||
|
(
|
||||||
|
bool& value,
|
||||||
|
const orOp<bool>&,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for common reduction types
|
||||||
|
|
||||||
|
#undef Pstream_CommonReductions
|
||||||
|
#define Pstream_CommonReductions(Native) \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const minOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const maxOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Pstream_CommonReductions(int32_t);
|
||||||
|
Pstream_CommonReductions(int64_t);
|
||||||
|
Pstream_CommonReductions(uint32_t);
|
||||||
|
Pstream_CommonReductions(uint64_t);
|
||||||
|
Pstream_CommonReductions(float);
|
||||||
|
Pstream_CommonReductions(double);
|
||||||
|
|
||||||
|
#undef Pstream_CommonReductions
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for floating-point types
|
||||||
|
|
||||||
|
#undef Pstream_FloatReductions
|
||||||
|
#define Pstream_FloatReductions(Native) \
|
||||||
|
\
|
||||||
|
void Foam::sumReduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
label& count, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
|
) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
|
) \
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Pstream_FloatReductions(float);
|
||||||
|
Pstream_FloatReductions(double);
|
||||||
|
|
||||||
|
#undef Pstream_FloatReductions
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -1,6 +1,11 @@
|
|||||||
UOPwrite.C
|
|
||||||
UIPread.C
|
|
||||||
UPstream.C
|
|
||||||
PstreamGlobals.C
|
PstreamGlobals.C
|
||||||
|
UPstream.C
|
||||||
|
UPstreamBroadcast.C
|
||||||
|
UPstreamReduce.C
|
||||||
|
|
||||||
|
UIPstreamRead.C
|
||||||
|
UOPstreamWrite.C
|
||||||
|
UIPBstreamRead.C
|
||||||
|
UOPBstreamWrite.C
|
||||||
|
|
||||||
LIB = $(FOAM_MPI_LIBBIN)/libPstream
|
LIB = $(FOAM_MPI_LIBBIN)/libPstream
|
||||||
|
|||||||
@ -35,8 +35,8 @@ SourceFiles
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef PstreamGlobals_H
|
#ifndef Foam_PstreamGlobals_H
|
||||||
#define PstreamGlobals_H
|
#define Foam_PstreamGlobals_H
|
||||||
|
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
@ -62,14 +62,12 @@ extern DynamicList<int> freedTags_;
|
|||||||
extern DynamicList<MPI_Comm> MPICommunicators_;
|
extern DynamicList<MPI_Comm> MPICommunicators_;
|
||||||
extern DynamicList<MPI_Group> MPIGroups_;
|
extern DynamicList<MPI_Group> MPIGroups_;
|
||||||
|
|
||||||
|
|
||||||
void checkCommunicator(const label comm, const label toProcNo);
|
void checkCommunicator(const label comm, const label toProcNo);
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace PstreamGlobals
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
139
src/Pstream/mpi/UIPBstreamRead.C
Normal file
139
src/Pstream/mpi/UIPBstreamRead.C
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UIPstream.H"
|
||||||
|
#include "PstreamGlobals.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::UIPBstream::bufferIPCrecv()
|
||||||
|
{
|
||||||
|
// Uses double broadcast. Symmetric with UOPBstream::bufferIPCsend()
|
||||||
|
// 1. for the data size
|
||||||
|
// 2. for the data itself
|
||||||
|
|
||||||
|
// Expected message size, similar to MPI_Probe
|
||||||
|
// Same type must be expected in UOPBstream::bufferIPCsend()
|
||||||
|
label bufSize(0);
|
||||||
|
|
||||||
|
// Broadcast #1 - data size
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&bufSize),
|
||||||
|
sizeof(label),
|
||||||
|
comm_,
|
||||||
|
fromProcNo_ //< is actually rootProcNo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure receiving buffer size" << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "UOPBstream IPC read buffer :"
|
||||||
|
<< " root:" << fromProcNo_
|
||||||
|
<< " comm:" << comm_
|
||||||
|
<< " probed size:" << bufSize
|
||||||
|
<< " wanted size:" << recvBuf_.capacity()
|
||||||
|
<< Foam::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No buffer size allocated/specified
|
||||||
|
if (!recvBuf_.capacity())
|
||||||
|
{
|
||||||
|
recvBuf_.resize(bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the only real information we can trust
|
||||||
|
messageSize_ = bufSize;
|
||||||
|
|
||||||
|
// Broadcast #2 - data content
|
||||||
|
// - skip if there is no data to receive
|
||||||
|
|
||||||
|
if (messageSize_)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast
|
||||||
|
(
|
||||||
|
recvBuf_.data(),
|
||||||
|
messageSize_, // same as bufSize
|
||||||
|
comm_,
|
||||||
|
fromProcNo_ //< is actually rootProcNo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure receiving buffer data:" << bufSize << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set addressed size. Leave actual allocated memory intact.
|
||||||
|
recvBuf_.resize(messageSize_);
|
||||||
|
|
||||||
|
if (!messageSize_)
|
||||||
|
{
|
||||||
|
setEof();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::UIPBstream::read
|
||||||
|
(
|
||||||
|
const commsTypes commsType,
|
||||||
|
const int rootProcNo,
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast(buf, bufSize, comm, rootProcNo)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure receiving data:" << label(bufSize) << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -24,9 +24,6 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Read from UIPstream
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "UIPstream.H"
|
#include "UIPstream.H"
|
||||||
@ -36,43 +33,15 @@ Description
|
|||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::UIPstream::UIPstream
|
void Foam::UIPstream::bufferIPCrecv()
|
||||||
(
|
|
||||||
const commsTypes commsType,
|
|
||||||
const int fromProcNo,
|
|
||||||
DynamicList<char>& receiveBuf,
|
|
||||||
label& receiveBufPosition,
|
|
||||||
const int tag,
|
|
||||||
const label comm,
|
|
||||||
const bool clearAtEnd,
|
|
||||||
IOstreamOption::streamFormat fmt
|
|
||||||
)
|
|
||||||
:
|
|
||||||
UPstream(commsType),
|
|
||||||
Istream(fmt, IOstreamOption::currentVersion),
|
|
||||||
fromProcNo_(fromProcNo),
|
|
||||||
recvBuf_(receiveBuf),
|
|
||||||
recvBufPos_(receiveBufPosition),
|
|
||||||
tag_(tag),
|
|
||||||
comm_(comm),
|
|
||||||
clearAtEnd_(clearAtEnd),
|
|
||||||
messageSize_(0)
|
|
||||||
{
|
|
||||||
setOpened();
|
|
||||||
setGood();
|
|
||||||
|
|
||||||
if (commsType == commsTypes::nonBlocking)
|
|
||||||
{
|
|
||||||
// Message is already received into buffer
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
// Called by constructor
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "UIPstream::UIPstream :"
|
Pout<< "UIPstream IPC read buffer :"
|
||||||
<< " read from:" << fromProcNo
|
<< " from:" << fromProcNo_
|
||||||
<< " tag:" << tag_ << " comm:" << comm_
|
<< " tag:" << tag_ << " comm:" << comm_
|
||||||
<< " wanted size:" << recvBuf_.capacity()
|
<< " wanted size:" << recvBuf_.capacity()
|
||||||
<< Foam::endl;
|
<< Foam::endl;
|
||||||
@ -106,108 +75,6 @@ Foam::UIPstream::UIPstream
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
messageSize_ = UIPstream::read
|
|
||||||
(
|
|
||||||
commsType,
|
|
||||||
fromProcNo_,
|
|
||||||
recvBuf_.data(),
|
|
||||||
recvBuf_.capacity(),
|
|
||||||
tag_,
|
|
||||||
comm_
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set addressed size. Leave actual allocated memory intact.
|
|
||||||
recvBuf_.resize(messageSize_);
|
|
||||||
|
|
||||||
if (!messageSize_)
|
|
||||||
{
|
|
||||||
setEof();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::UIPstream::UIPstream(const int fromProcNo, PstreamBuffers& buffers)
|
|
||||||
:
|
|
||||||
UPstream(buffers.commsType_),
|
|
||||||
Istream(buffers.format_, IOstreamOption::currentVersion),
|
|
||||||
fromProcNo_(fromProcNo),
|
|
||||||
recvBuf_(buffers.recvBuf_[fromProcNo]),
|
|
||||||
recvBufPos_(buffers.recvBufPos_[fromProcNo]),
|
|
||||||
tag_(buffers.tag_),
|
|
||||||
comm_(buffers.comm_),
|
|
||||||
clearAtEnd_(true),
|
|
||||||
messageSize_(0)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
commsType() != UPstream::commsTypes::scheduled
|
|
||||||
&& !buffers.finishedSendsCalled_
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "PstreamBuffers::finishedSends() never called." << endl
|
|
||||||
<< "Please call PstreamBuffers::finishedSends() after doing"
|
|
||||||
<< " all your sends (using UOPstream) and before doing any"
|
|
||||||
<< " receives (using UIPstream)" << Foam::exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
setOpened();
|
|
||||||
setGood();
|
|
||||||
|
|
||||||
if (commsType() == commsTypes::nonBlocking)
|
|
||||||
{
|
|
||||||
// Message is already received into buffer
|
|
||||||
messageSize_ = recvBuf_.size();
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "UIPstream::UIPstream PstreamBuffers :"
|
|
||||||
<< " fromProcNo:" << fromProcNo
|
|
||||||
<< " tag:" << tag_ << " comm:" << comm_
|
|
||||||
<< " receive buffer size:" << messageSize_
|
|
||||||
<< Foam::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "UIPstream::UIPstream PstreamBuffers :"
|
|
||||||
<< " read from:" << fromProcNo
|
|
||||||
<< " tag:" << tag_ << " comm:" << comm_
|
|
||||||
<< " wanted size:" << recvBuf_.capacity()
|
|
||||||
<< Foam::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No buffer size allocated/specified - probe size of incoming message
|
|
||||||
if (!recvBuf_.capacity())
|
|
||||||
{
|
|
||||||
profilingPstream::beginTiming();
|
|
||||||
|
|
||||||
MPI_Status status;
|
|
||||||
|
|
||||||
MPI_Probe
|
|
||||||
(
|
|
||||||
fromProcNo_,
|
|
||||||
tag_,
|
|
||||||
PstreamGlobals::MPICommunicators_[comm_],
|
|
||||||
&status
|
|
||||||
);
|
|
||||||
MPI_Get_count(&status, MPI_BYTE, &messageSize_);
|
|
||||||
|
|
||||||
// Assume these are from gathers ...
|
|
||||||
profilingPstream::addGatherTime();
|
|
||||||
|
|
||||||
recvBuf_.resize(messageSize_);
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "UIPstream::UIPstream PstreamBuffers : probed size:"
|
|
||||||
<< messageSize_ << Foam::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
messageSize_ = UIPstream::read
|
messageSize_ = UIPstream::read
|
||||||
(
|
(
|
||||||
commsType(),
|
commsType(),
|
||||||
@ -226,7 +93,6 @@ Foam::UIPstream::UIPstream(const int fromProcNo, PstreamBuffers& buffers)
|
|||||||
setEof();
|
setEof();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
@ -287,7 +153,6 @@ Foam::label Foam::UIPstream::read
|
|||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "MPI_Recv cannot receive incoming message"
|
<< "MPI_Recv cannot receive incoming message"
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,7 +201,7 @@ Foam::label Foam::UIPstream::read
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "MPI_Recv cannot start non-blocking receive"
|
<< "MPI_Irecv cannot start non-blocking receive"
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
118
src/Pstream/mpi/UOPBstreamWrite.C
Normal file
118
src/Pstream/mpi/UOPBstreamWrite.C
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UOPstream.H"
|
||||||
|
#include "PstreamGlobals.H"
|
||||||
|
|
||||||
|
#include <mpi.h>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPBstream::bufferIPCsend()
|
||||||
|
{
|
||||||
|
// Uses double broadcast
|
||||||
|
// 1. for the data size
|
||||||
|
// 2. for the data itself
|
||||||
|
// With this information, can determine and resize receive buffer
|
||||||
|
|
||||||
|
PstreamGlobals::checkCommunicator(comm_, toProcNo_);
|
||||||
|
|
||||||
|
// Same type must be expected in UIPBstream::bufferIPCrecv()
|
||||||
|
label bufSize(sendBuf_.size());
|
||||||
|
|
||||||
|
// Broadcast #1 - data size
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(&bufSize),
|
||||||
|
sizeof(label),
|
||||||
|
comm_,
|
||||||
|
toProcNo_ //< is actually rootProcNo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure sending buffer size:" << bufSize << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Broadcast #2 - data content
|
||||||
|
// - skip if there is no data to send
|
||||||
|
if (bufSize)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast
|
||||||
|
(
|
||||||
|
sendBuf_.data(),
|
||||||
|
sendBuf_.size(), // same as bufSize
|
||||||
|
comm_,
|
||||||
|
toProcNo_ //< is actually rootProcNo
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure sending buffer data:" << bufSize << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPBstream::write
|
||||||
|
(
|
||||||
|
const commsTypes commsType, /* unused */
|
||||||
|
const int rootProcNo,
|
||||||
|
const char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const int tag, /* unused */
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UPstream::broadcast(const_cast<char*>(buf), bufSize, comm, rootProcNo)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "MPI_Bcast failure sending buffer data:" << label(bufSize) << nl
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2021 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -24,9 +24,6 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Write primitive and binary block from OPstream
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "UOPstream.H"
|
#include "UOPstream.H"
|
||||||
@ -35,6 +32,22 @@ Description
|
|||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UOPstream::bufferIPCsend()
|
||||||
|
{
|
||||||
|
return UOPstream::write
|
||||||
|
(
|
||||||
|
commsType(),
|
||||||
|
toProcNo_,
|
||||||
|
sendBuf_.cdata(),
|
||||||
|
sendBuf_.size(),
|
||||||
|
tag_,
|
||||||
|
comm_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::UOPstream::write
|
bool Foam::UOPstream::write
|
||||||
@ -70,13 +83,13 @@ bool Foam::UOPstream::write
|
|||||||
PstreamGlobals::checkCommunicator(communicator, toProcNo);
|
PstreamGlobals::checkCommunicator(communicator, toProcNo);
|
||||||
|
|
||||||
|
|
||||||
bool transferFailed = true;
|
bool failed = true;
|
||||||
|
|
||||||
profilingPstream::beginTiming();
|
profilingPstream::beginTiming();
|
||||||
|
|
||||||
if (commsType == commsTypes::blocking)
|
if (commsType == commsTypes::blocking)
|
||||||
{
|
{
|
||||||
transferFailed = MPI_Bsend
|
failed = MPI_Bsend
|
||||||
(
|
(
|
||||||
const_cast<char*>(buf),
|
const_cast<char*>(buf),
|
||||||
bufSize,
|
bufSize,
|
||||||
@ -99,7 +112,7 @@ bool Foam::UOPstream::write
|
|||||||
}
|
}
|
||||||
else if (commsType == commsTypes::scheduled)
|
else if (commsType == commsTypes::scheduled)
|
||||||
{
|
{
|
||||||
transferFailed = MPI_Send
|
failed = MPI_Send
|
||||||
(
|
(
|
||||||
const_cast<char*>(buf),
|
const_cast<char*>(buf),
|
||||||
bufSize,
|
bufSize,
|
||||||
@ -124,7 +137,7 @@ bool Foam::UOPstream::write
|
|||||||
{
|
{
|
||||||
MPI_Request request;
|
MPI_Request request;
|
||||||
|
|
||||||
transferFailed = MPI_Isend
|
failed = MPI_Isend
|
||||||
(
|
(
|
||||||
const_cast<char*>(buf),
|
const_cast<char*>(buf),
|
||||||
bufSize,
|
bufSize,
|
||||||
@ -151,12 +164,11 @@ bool Foam::UOPstream::write
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Unsupported communications type "
|
<< "Unsupported communications type " << int(commsType)
|
||||||
<< UPstream::commsTypeNames[commsType]
|
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
return !transferFailed;
|
return !failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,17 +40,6 @@ License
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
|
|
||||||
#if defined(WM_SP)
|
|
||||||
#define MPI_SCALAR MPI_FLOAT
|
|
||||||
#define MPI_SOLVESCALAR MPI_FLOAT
|
|
||||||
#elif defined(WM_SPDP)
|
|
||||||
#define MPI_SCALAR MPI_FLOAT
|
|
||||||
#define MPI_SOLVESCALAR MPI_DOUBLE
|
|
||||||
#elif defined(WM_DP)
|
|
||||||
#define MPI_SCALAR MPI_DOUBLE
|
|
||||||
#define MPI_SOLVESCALAR MPI_DOUBLE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// The min value and default for MPI buffers length
|
// The min value and default for MPI buffers length
|
||||||
@ -491,245 +480,7 @@ void Foam::UPstream::abort()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
const sumOp<scalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 1, MPI_SCALAR, MPI_SUM, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
const minOp<scalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 1, MPI_SCALAR, MPI_MIN, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
vector2D& Value,
|
|
||||||
const sumOp<vector2D>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 2, MPI_SCALAR, MPI_SUM, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::sumReduce
|
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
label& Count,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** sumReduce:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
vector2D twoScalars(Value, scalar(Count));
|
|
||||||
reduce(twoScalars, sumOp<vector2D>(), tag, communicator);
|
|
||||||
|
|
||||||
Value = twoScalars.x();
|
|
||||||
Count = twoScalars.y();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
scalar& Value,
|
|
||||||
const sumOp<scalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator,
|
|
||||||
label& requestID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
iallReduce<scalar>(&Value, 1, MPI_SCALAR, MPI_SUM, communicator, requestID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
scalar values[],
|
|
||||||
const int size,
|
|
||||||
const sumOp<scalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator,
|
|
||||||
label& requestID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
iallReduce<scalar>
|
|
||||||
(
|
|
||||||
values,
|
|
||||||
size,
|
|
||||||
MPI_SCALAR,
|
|
||||||
MPI_SUM,
|
|
||||||
communicator,
|
|
||||||
requestID
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(WM_SPDP)
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 1, MPI_SOLVESCALAR, MPI_SUM, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const minOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 1, MPI_SOLVESCALAR, MPI_MIN, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
Vector2D<solveScalar>& Value,
|
|
||||||
const sumOp<Vector2D<solveScalar>>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
allReduce(Value, 2, MPI_SOLVESCALAR, MPI_SUM, bop, tag, communicator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::sumReduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
label& Count,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
|
||||||
{
|
|
||||||
Pout<< "** reducing:" << Value << " with comm:" << communicator
|
|
||||||
<< " warnComm:" << UPstream::warnComm
|
|
||||||
<< endl;
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
Vector2D<solveScalar> twoScalars(Value, solveScalar(Count));
|
|
||||||
reduce(twoScalars, sumOp<Vector2D<solveScalar>>(), tag, communicator);
|
|
||||||
|
|
||||||
Value = twoScalars.x();
|
|
||||||
Count = twoScalars.y();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar& Value,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator,
|
|
||||||
label& requestID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
iallReduce<solveScalar>
|
|
||||||
(
|
|
||||||
&Value,
|
|
||||||
1,
|
|
||||||
MPI_SOLVESCALAR,
|
|
||||||
MPI_SUM,
|
|
||||||
communicator,
|
|
||||||
requestID
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::reduce
|
|
||||||
(
|
|
||||||
solveScalar values[],
|
|
||||||
const int size,
|
|
||||||
const sumOp<solveScalar>& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator,
|
|
||||||
label& requestID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
iallReduce<solveScalar>
|
|
||||||
(
|
|
||||||
values,
|
|
||||||
size,
|
|
||||||
MPI_SOLVESCALAR,
|
|
||||||
MPI_SUM,
|
|
||||||
communicator,
|
|
||||||
requestID
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::UPstream::allToAll
|
void Foam::UPstream::allToAll
|
||||||
(
|
(
|
||||||
@ -1437,22 +1188,15 @@ int Foam::UPstream::allocateTag(const char* s)
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
//if (UPstream::lateBlocking > 0)
|
Pout<< "UPstream::allocateTag "
|
||||||
//{
|
<< s << " : tag:" << tag << endl;
|
||||||
// string& poutp = Pout.prefix();
|
|
||||||
// poutp[poutp.size()-2*(UPstream::lateBlocking+2)+tag] = 'X';
|
|
||||||
// Perr.prefix() = Pout.prefix();
|
|
||||||
//}
|
|
||||||
Pout<< "UPstream::allocateTag " << s
|
|
||||||
<< " : tag:" << tag
|
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Foam::UPstream::allocateTag(const word& s)
|
int Foam::UPstream::allocateTag(const std::string& s)
|
||||||
{
|
{
|
||||||
int tag;
|
int tag;
|
||||||
if (PstreamGlobals::freedTags_.size())
|
if (PstreamGlobals::freedTags_.size())
|
||||||
@ -1466,15 +1210,8 @@ int Foam::UPstream::allocateTag(const word& s)
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
//if (UPstream::lateBlocking > 0)
|
Pout<< "UPstream::allocateTag "
|
||||||
//{
|
<< s.c_str() << " : tag:" << tag << endl;
|
||||||
// string& poutp = Pout.prefix();
|
|
||||||
// poutp[poutp.size()-2*(UPstream::lateBlocking+2)+tag] = 'X';
|
|
||||||
// Perr.prefix() = Pout.prefix();
|
|
||||||
//}
|
|
||||||
Pout<< "UPstream::allocateTag " << s
|
|
||||||
<< " : tag:" << tag
|
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag;
|
return tag;
|
||||||
@ -1485,29 +1222,19 @@ void Foam::UPstream::freeTag(const char* s, const int tag)
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
//if (UPstream::lateBlocking > 0)
|
Pout<< "UPstream::freeTag "
|
||||||
//{
|
<< s << " tag:" << tag << endl;
|
||||||
// string& poutp = Pout.prefix();
|
|
||||||
// poutp[poutp.size()-2*(UPstream::lateBlocking+2)+tag] = ' ';
|
|
||||||
// Perr.prefix() = Pout.prefix();
|
|
||||||
//}
|
|
||||||
Pout<< "UPstream::freeTag " << s << " tag:" << tag << endl;
|
|
||||||
}
|
}
|
||||||
PstreamGlobals::freedTags_.append(tag);
|
PstreamGlobals::freedTags_.append(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::UPstream::freeTag(const word& s, const int tag)
|
void Foam::UPstream::freeTag(const std::string& s, const int tag)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
//if (UPstream::lateBlocking > 0)
|
Pout<< "UPstream::freeTag "
|
||||||
//{
|
<< s.c_str() << " tag:" << tag << endl;
|
||||||
// string& poutp = Pout.prefix();
|
|
||||||
// poutp[poutp.size()-2*(UPstream::lateBlocking+2)+tag] = ' ';
|
|
||||||
// Perr.prefix() = Pout.prefix();
|
|
||||||
//}
|
|
||||||
Pout<< "UPstream::freeTag " << s << " tag:" << tag << endl;
|
|
||||||
}
|
}
|
||||||
PstreamGlobals::freedTags_.append(tag);
|
PstreamGlobals::freedTags_.append(tag);
|
||||||
}
|
}
|
||||||
|
|||||||
86
src/Pstream/mpi/UPstreamBroadcast.C
Normal file
86
src/Pstream/mpi/UPstreamBroadcast.C
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "UPstream.H"
|
||||||
|
#include "PstreamGlobals.H"
|
||||||
|
#include "profilingPstream.H"
|
||||||
|
|
||||||
|
#include <mpi.h>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::UPstream::broadcast
|
||||||
|
(
|
||||||
|
char* buf,
|
||||||
|
const std::streamsize bufSize,
|
||||||
|
const label communicator,
|
||||||
|
const int rootProcNo
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!UPstream::parRun() || UPstream::nProcs(communicator) < 2)
|
||||||
|
{
|
||||||
|
// Nothing to do - ignore
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Needed? PstreamGlobals::checkCommunicator(communicator, rootProcNo);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "UPstream::broadcast : root:" << rootProcNo
|
||||||
|
<< " comm:" << communicator
|
||||||
|
<< " size:" << label(bufSize)
|
||||||
|
<< Foam::endl;
|
||||||
|
}
|
||||||
|
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
||||||
|
{
|
||||||
|
Pout<< "UPstream::broadcast : root:" << rootProcNo
|
||||||
|
<< " comm:" << communicator
|
||||||
|
<< " size:" << label(bufSize)
|
||||||
|
<< " warnComm:" << UPstream::warnComm
|
||||||
|
<< Foam::endl;
|
||||||
|
error::printStack(Pout);
|
||||||
|
}
|
||||||
|
|
||||||
|
profilingPstream::beginTiming();
|
||||||
|
|
||||||
|
bool failed = MPI_Bcast
|
||||||
|
(
|
||||||
|
buf,
|
||||||
|
bufSize,
|
||||||
|
MPI_BYTE,
|
||||||
|
rootProcNo,
|
||||||
|
PstreamGlobals::MPICommunicators_[communicator]
|
||||||
|
);
|
||||||
|
|
||||||
|
profilingPstream::addBroadcastTime();
|
||||||
|
|
||||||
|
return !failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
211
src/Pstream/mpi/UPstreamReduce.C
Normal file
211
src/Pstream/mpi/UPstreamReduce.C
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Pstream.H"
|
||||||
|
#include "PstreamReduceOps.H"
|
||||||
|
#include "allReduce.H"
|
||||||
|
|
||||||
|
#include <mpi.h>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for bool
|
||||||
|
|
||||||
|
void Foam::reduce
|
||||||
|
(
|
||||||
|
bool& value,
|
||||||
|
const andOp<bool>&,
|
||||||
|
const int tag, /* (unused) */
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// This can also work:
|
||||||
|
// PstreamDetail::allReduce(&value, 1, MPI_BYTE, MPI_BAND, comm);
|
||||||
|
PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LAND, comm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::reduce
|
||||||
|
(
|
||||||
|
bool& value,
|
||||||
|
const orOp<bool>&,
|
||||||
|
const int tag, /* (unused) */
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// This can also work:
|
||||||
|
// PstreamDetail::allReduce(&value, 1, MPI_BYTE, MPI_BOR, comm);
|
||||||
|
PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LOR, comm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for common reduction types
|
||||||
|
|
||||||
|
#undef Pstream_CommonReductions
|
||||||
|
#define Pstream_CommonReductions(Native, TaggedType) \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const minOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::allReduce<Native> \
|
||||||
|
( \
|
||||||
|
&value, 1, TaggedType, MPI_MIN, comm \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const maxOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::allReduce<Native> \
|
||||||
|
( \
|
||||||
|
&value, 1, TaggedType, MPI_MAX, comm \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::allReduce<Native> \
|
||||||
|
( \
|
||||||
|
&value, 1, TaggedType, MPI_SUM, comm \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::allReduce<Native> \
|
||||||
|
( \
|
||||||
|
values, size, TaggedType, MPI_SUM, comm \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
|
||||||
|
|
||||||
|
Pstream_CommonReductions(int32_t, MPI_INT32_T);
|
||||||
|
Pstream_CommonReductions(int64_t, MPI_INT64_T);
|
||||||
|
Pstream_CommonReductions(uint32_t, MPI_UINT32_T);
|
||||||
|
Pstream_CommonReductions(uint64_t, MPI_UINT64_T);
|
||||||
|
Pstream_CommonReductions(float, MPI_FLOAT);
|
||||||
|
Pstream_CommonReductions(double, MPI_DOUBLE);
|
||||||
|
|
||||||
|
#undef Pstream_CommonReductions
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Specialisations for floating-point types
|
||||||
|
|
||||||
|
#undef Pstream_FloatReductions
|
||||||
|
#define Pstream_FloatReductions(Native, TaggedType) \
|
||||||
|
\
|
||||||
|
void Foam::sumReduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
label& count, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
if (UPstream::parRun()) \
|
||||||
|
{ \
|
||||||
|
Native values[2]; \
|
||||||
|
values[0] = value; \
|
||||||
|
values[1] = static_cast<Native>(count); \
|
||||||
|
\
|
||||||
|
PstreamDetail::allReduce<Native> \
|
||||||
|
( \
|
||||||
|
values, 2, TaggedType, MPI_SUM, comm \
|
||||||
|
); \
|
||||||
|
\
|
||||||
|
value = values[0]; \
|
||||||
|
count = static_cast<label>(values[1]); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native& value, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::iallReduce<Native> \
|
||||||
|
( \
|
||||||
|
&value, 1, TaggedType, MPI_SUM, comm, requestID \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void Foam::reduce \
|
||||||
|
( \
|
||||||
|
Native values[], \
|
||||||
|
const int size, \
|
||||||
|
const sumOp<Native>&, \
|
||||||
|
const int tag, /* (unused) */ \
|
||||||
|
const label comm, \
|
||||||
|
label& requestID \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
PstreamDetail::iallReduce<Native> \
|
||||||
|
( \
|
||||||
|
values, size, TaggedType, MPI_SUM, comm, requestID \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pstream_FloatReductions(float, MPI_FLOAT);
|
||||||
|
Pstream_FloatReductions(double, MPI_DOUBLE);
|
||||||
|
|
||||||
|
#undef Pstream_FloatReductions
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
Copyright (C) 2012-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -23,54 +24,69 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
InNamespace
|
Namespace
|
||||||
Foam
|
Foam::PstreamDetail
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Various functions to wrap MPI_Allreduce
|
Some implementation details for Pstream and/or MPI.
|
||||||
|
|
||||||
|
InNamespace
|
||||||
|
Foam::PstreamDetail
|
||||||
|
|
||||||
|
Description
|
||||||
|
Functions to wrap MPI_Bcast, MPI_Allreduce, MPI_Iallreduce
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
allReduceTemplates.C
|
allReduceTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef allReduce_H
|
#ifndef Foam_allReduce_H
|
||||||
#define allReduce_H
|
#define Foam_allReduce_H
|
||||||
|
|
||||||
#include "UPstream.H"
|
#include "UPstream.H"
|
||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
namespace PstreamDetail
|
||||||
|
{
|
||||||
|
|
||||||
template<class Type, class BinaryOp>
|
template<class Type>
|
||||||
|
void allBroadcast
|
||||||
|
(
|
||||||
|
Type* values,
|
||||||
|
int count,
|
||||||
|
MPI_Datatype datatype,
|
||||||
|
const label communicator
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
void allReduce
|
void allReduce
|
||||||
(
|
(
|
||||||
Type& Value,
|
Type* values,
|
||||||
int count,
|
int count,
|
||||||
MPI_Datatype MPIType,
|
MPI_Datatype datatype,
|
||||||
MPI_Op op,
|
MPI_Op optype,
|
||||||
const BinaryOp& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
const label communicator
|
||||||
);
|
);
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void iallReduce
|
void iallReduce
|
||||||
(
|
(
|
||||||
void* Value,
|
Type* values,
|
||||||
int count,
|
int count,
|
||||||
MPI_Datatype MPIType,
|
MPI_Datatype datatype,
|
||||||
MPI_Op op,
|
MPI_Op optype,
|
||||||
const label communicator,
|
const label communicator,
|
||||||
label& requestID
|
label& requestID
|
||||||
);
|
);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace PstreamDetail
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012-2015 OpenFOAM Foundation
|
Copyright (C) 2012-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -28,18 +28,16 @@ License
|
|||||||
|
|
||||||
#include "allReduce.H"
|
#include "allReduce.H"
|
||||||
#include "profilingPstream.H"
|
#include "profilingPstream.H"
|
||||||
|
#include "PstreamGlobals.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type, class BinaryOp>
|
template<class Type>
|
||||||
void Foam::allReduce
|
void Foam::PstreamDetail::allBroadcast
|
||||||
(
|
(
|
||||||
Type& Value,
|
Type* values,
|
||||||
int MPICount,
|
int count,
|
||||||
MPI_Datatype MPIType,
|
MPI_Datatype datatype,
|
||||||
MPI_Op MPIOp,
|
|
||||||
const BinaryOp& bop,
|
|
||||||
const int tag,
|
|
||||||
const label communicator
|
const label communicator
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -50,129 +48,75 @@ void Foam::allReduce
|
|||||||
|
|
||||||
profilingPstream::beginTiming();
|
profilingPstream::beginTiming();
|
||||||
|
|
||||||
if (UPstream::nProcs(communicator) <= UPstream::nProcsSimpleSum)
|
// const int retval =
|
||||||
{
|
MPI_Bcast
|
||||||
if (UPstream::master(communicator))
|
|
||||||
{
|
|
||||||
for (const int proci : UPstream::subProcs(communicator))
|
|
||||||
{
|
|
||||||
Type value;
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
(
|
||||||
MPI_Recv
|
values,
|
||||||
(
|
count,
|
||||||
&value,
|
datatype,
|
||||||
MPICount,
|
0, // (root process) is master == UPstream::masterNo()
|
||||||
MPIType,
|
|
||||||
proci,
|
|
||||||
tag,
|
|
||||||
PstreamGlobals::MPICommunicators_[communicator],
|
|
||||||
MPI_STATUS_IGNORE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "MPI_Recv failed"
|
|
||||||
<< Foam::abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value = bop(Value, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
MPI_Send
|
|
||||||
(
|
|
||||||
&Value,
|
|
||||||
MPICount,
|
|
||||||
MPIType,
|
|
||||||
UPstream::masterNo(),
|
|
||||||
tag,
|
|
||||||
PstreamGlobals::MPICommunicators_[communicator]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "MPI_Send failed"
|
|
||||||
<< Foam::abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (UPstream::master(communicator))
|
|
||||||
{
|
|
||||||
for (const int proci : UPstream::subProcs(communicator))
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
MPI_Send
|
|
||||||
(
|
|
||||||
&Value,
|
|
||||||
MPICount,
|
|
||||||
MPIType,
|
|
||||||
proci,
|
|
||||||
tag,
|
|
||||||
PstreamGlobals::MPICommunicators_[communicator]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "MPI_Send failed"
|
|
||||||
<< Foam::abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
MPI_Recv
|
|
||||||
(
|
|
||||||
&Value,
|
|
||||||
MPICount,
|
|
||||||
MPIType,
|
|
||||||
UPstream::masterNo(),
|
|
||||||
tag,
|
|
||||||
PstreamGlobals::MPICommunicators_[communicator],
|
|
||||||
MPI_STATUS_IGNORE
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "MPI_Recv failed"
|
|
||||||
<< Foam::abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type sum;
|
|
||||||
MPI_Allreduce
|
|
||||||
(
|
|
||||||
&Value,
|
|
||||||
&sum,
|
|
||||||
MPICount,
|
|
||||||
MPIType,
|
|
||||||
MPIOp,
|
|
||||||
PstreamGlobals::MPICommunicators_[communicator]
|
PstreamGlobals::MPICommunicators_[communicator]
|
||||||
);
|
);
|
||||||
Value = sum;
|
|
||||||
|
profilingPstream::addBroadcastTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::PstreamDetail::allReduce
|
||||||
|
(
|
||||||
|
Type* values,
|
||||||
|
int count,
|
||||||
|
MPI_Datatype datatype,
|
||||||
|
MPI_Op optype,
|
||||||
|
const label communicator
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!UPstream::parRun())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
||||||
|
{
|
||||||
|
Pout<< "** reducing:";
|
||||||
|
if (count == 1)
|
||||||
|
{
|
||||||
|
Pout<< (*values);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pout<< UList<Type>(values, count);
|
||||||
|
}
|
||||||
|
Pout<< " with comm:" << communicator
|
||||||
|
<< " warnComm:" << UPstream::warnComm << endl;
|
||||||
|
error::printStack(Pout);
|
||||||
|
}
|
||||||
|
|
||||||
|
profilingPstream::beginTiming();
|
||||||
|
|
||||||
|
// const int retval =
|
||||||
|
MPI_Allreduce
|
||||||
|
(
|
||||||
|
MPI_IN_PLACE,
|
||||||
|
values,
|
||||||
|
count,
|
||||||
|
datatype,
|
||||||
|
optype,
|
||||||
|
PstreamGlobals::MPICommunicators_[communicator]
|
||||||
|
);
|
||||||
|
|
||||||
profilingPstream::addReduceTime();
|
profilingPstream::addReduceTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::iallReduce
|
void Foam::PstreamDetail::iallReduce
|
||||||
(
|
(
|
||||||
void* recvBuf,
|
Type* values,
|
||||||
int MPICount,
|
int count,
|
||||||
MPI_Datatype MPIType,
|
MPI_Datatype datatype,
|
||||||
MPI_Op MPIOp,
|
MPI_Op optype,
|
||||||
const label communicator,
|
const label communicator,
|
||||||
label& requestID
|
label& requestID
|
||||||
)
|
)
|
||||||
@ -184,9 +128,16 @@ void Foam::iallReduce
|
|||||||
|
|
||||||
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
|
||||||
{
|
{
|
||||||
Pout<< "** non-blocking reducing:"
|
Pout<< "** non-blocking reducing:";
|
||||||
<< UList<Type>(static_cast<Type*>(recvBuf), MPICount)
|
if (count == 1)
|
||||||
<< " with comm:" << communicator
|
{
|
||||||
|
Pout<< (*values);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pout<< UList<Type>(values, count);
|
||||||
|
}
|
||||||
|
Pout<< " with comm:" << communicator
|
||||||
<< " warnComm:" << UPstream::warnComm << endl;
|
<< " warnComm:" << UPstream::warnComm << endl;
|
||||||
error::printStack(Pout);
|
error::printStack(Pout);
|
||||||
}
|
}
|
||||||
@ -200,10 +151,10 @@ void Foam::iallReduce
|
|||||||
MPI_Iallreduce
|
MPI_Iallreduce
|
||||||
(
|
(
|
||||||
MPI_IN_PLACE,
|
MPI_IN_PLACE,
|
||||||
recvBuf,
|
values,
|
||||||
MPICount,
|
count,
|
||||||
MPIType,
|
datatype,
|
||||||
MPIOp,
|
optype,
|
||||||
PstreamGlobals::MPICommunicators_[communicator],
|
PstreamGlobals::MPICommunicators_[communicator],
|
||||||
&request
|
&request
|
||||||
)
|
)
|
||||||
@ -211,7 +162,7 @@ void Foam::iallReduce
|
|||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "MPI_Iallreduce failed for "
|
<< "MPI_Iallreduce failed for "
|
||||||
<< UList<Type>(static_cast<Type*>(recvBuf), MPICount)
|
<< UList<Type>(values, count)
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,17 +189,17 @@ void Foam::iallReduce
|
|||||||
MPI_Allreduce
|
MPI_Allreduce
|
||||||
(
|
(
|
||||||
MPI_IN_PLACE,
|
MPI_IN_PLACE,
|
||||||
recvBuf,
|
values,
|
||||||
MPICount,
|
count,
|
||||||
MPIType,
|
datatype,
|
||||||
MPIOp,
|
optype,
|
||||||
PstreamGlobals::MPICommunicators_[communicator]
|
PstreamGlobals::MPICommunicators_[communicator]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "MPI_Allreduce failed for "
|
<< "MPI_Allreduce failed for "
|
||||||
<< UList<Type>(static_cast<Type*>(recvBuf), MPICount)
|
<< UList<Type>(values, count)
|
||||||
<< Foam::abort(FatalError);
|
<< Foam::abort(FatalError);
|
||||||
}
|
}
|
||||||
requestID = -1;
|
requestID = -1;
|
||||||
|
|||||||
@ -478,25 +478,10 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshTools::newMesh
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
Pstream::parRun(oldParRun);
|
Pstream::parRun(oldParRun);
|
||||||
|
|
||||||
// Send patches
|
|
||||||
for (const int slave : Pstream::subProcs())
|
|
||||||
{
|
|
||||||
OPstream toSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
toSlave << patchEntries;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Receive patches
|
|
||||||
IPstream fromMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
fromMaster >> patchEntries;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcast information to all
|
||||||
|
Pstream::scatter(patchEntries);
|
||||||
Pstream::scatter(facesInstance);
|
Pstream::scatter(facesInstance);
|
||||||
Pstream::scatter(pointsInstance);
|
Pstream::scatter(pointsInstance);
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,6 @@ License
|
|||||||
|
|
||||||
#include "processorFaPatch.H"
|
#include "processorFaPatch.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "IPstream.H"
|
|
||||||
#include "OPstream.H"
|
|
||||||
#include "transformField.H"
|
#include "transformField.H"
|
||||||
#include "faBoundaryMesh.H"
|
#include "faBoundaryMesh.H"
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
|
|||||||
@ -28,8 +28,6 @@ License
|
|||||||
|
|
||||||
#include "processorFaPatchField.H"
|
#include "processorFaPatchField.H"
|
||||||
#include "processorFaPatch.H"
|
#include "processorFaPatch.H"
|
||||||
#include "IPstream.H"
|
|
||||||
#include "OPstream.H"
|
|
||||||
#include "transformField.H"
|
#include "transformField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020 DLR
|
Copyright (C) 2020 DLR
|
||||||
Copyright (C) 2020 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,13 +27,6 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "zoneDistribute.H"
|
#include "zoneDistribute.H"
|
||||||
#include "dummyTransform.H"
|
|
||||||
#include "emptyPolyPatch.H"
|
|
||||||
#include "processorPolyPatch.H"
|
|
||||||
#include "syncTools.H"
|
|
||||||
#include "wedgePolyPatch.H"
|
|
||||||
|
|
||||||
#include "globalPoints.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -43,61 +36,15 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::indirectPrimitivePatch>
|
|
||||||
Foam::zoneDistribute::coupledFacesPatch() const
|
|
||||||
{
|
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
|
||||||
|
|
||||||
label nCoupled = 0;
|
|
||||||
|
|
||||||
for (const polyPatch& pp : patches)
|
|
||||||
{
|
|
||||||
if (isA<processorPolyPatch>(pp))
|
|
||||||
{
|
|
||||||
nCoupled += pp.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
labelList coupledFaces(nCoupled);
|
|
||||||
nCoupled = 0;
|
|
||||||
|
|
||||||
for (const polyPatch& pp : patches)
|
|
||||||
{
|
|
||||||
if (isA<processorPolyPatch>(pp))
|
|
||||||
{
|
|
||||||
label facei = pp.start();
|
|
||||||
|
|
||||||
forAll(pp, i)
|
|
||||||
{
|
|
||||||
coupledFaces[nCoupled++] = facei++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<indirectPrimitivePatch>::New
|
|
||||||
(
|
|
||||||
IndirectList<face>
|
|
||||||
(
|
|
||||||
mesh_.faces(),
|
|
||||||
coupledFaces
|
|
||||||
),
|
|
||||||
mesh_.points()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::zoneDistribute::zoneDistribute(const fvMesh& mesh)
|
Foam::zoneDistribute::zoneDistribute(const fvMesh& mesh)
|
||||||
:
|
:
|
||||||
MeshObject<fvMesh, Foam::TopologicalMeshObject, zoneDistribute>(mesh),
|
MeshObject<fvMesh, Foam::TopologicalMeshObject, zoneDistribute>(mesh),
|
||||||
coupledBoundaryPoints_(coupledFacesPatch()().meshPoints()),
|
|
||||||
send_(Pstream::nProcs()),
|
|
||||||
stencil_(zoneCPCStencil::New(mesh)),
|
stencil_(zoneCPCStencil::New(mesh)),
|
||||||
gblIdx_(stencil_.globalNumbering())
|
globalNumbering_(stencil_.globalNumbering()),
|
||||||
{
|
send_(UPstream::nProcs())
|
||||||
}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * //
|
||||||
@ -124,7 +71,11 @@ void Foam::zoneDistribute::updateStencil(const boolList& zone)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::zoneDistribute::setUpCommforZone(const boolList& zone,bool updateStencil)
|
void Foam::zoneDistribute::setUpCommforZone
|
||||||
|
(
|
||||||
|
const boolList& zone,
|
||||||
|
bool updateStencil
|
||||||
|
)
|
||||||
{
|
{
|
||||||
zoneCPCStencil& stencil = zoneCPCStencil::New(mesh_);
|
zoneCPCStencil& stencil = zoneCPCStencil::New(mesh_);
|
||||||
|
|
||||||
@ -133,60 +84,56 @@ void Foam::zoneDistribute::setUpCommforZone(const boolList& zone,bool updateSten
|
|||||||
stencil.updateStencil(zone);
|
stencil.updateStencil(zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelHashSet comms = stencil.needsComm();
|
if (UPstream::parRun())
|
||||||
|
|
||||||
List<labelHashSet> needed(Pstream::nProcs());
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
|
||||||
{
|
{
|
||||||
for (const label celli : comms)
|
List<labelHashSet> needed(UPstream::nProcs());
|
||||||
|
|
||||||
|
// Bin according to originating (sending) processor
|
||||||
|
for (const label celli : stencil.needsComm())
|
||||||
{
|
{
|
||||||
if (zone[celli])
|
if (zone[celli])
|
||||||
{
|
{
|
||||||
for (const label gblIdx : stencil_[celli])
|
for (const label gblIdx : stencil_[celli])
|
||||||
{
|
{
|
||||||
if (!gblIdx_.isLocal(gblIdx))
|
if (!globalNumbering_.isLocal(gblIdx))
|
||||||
{
|
{
|
||||||
const label procID = gblIdx_.whichProcID (gblIdx);
|
const label procID =
|
||||||
|
globalNumbering_.whichProcID(gblIdx);
|
||||||
needed[procID].insert(gblIdx);
|
needed[procID].insert(gblIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
// Stream the send data into PstreamBuffers,
|
||||||
|
// which we also use to track the current topology.
|
||||||
|
|
||||||
// Stream data into buffer
|
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking);
|
||||||
for (const int domain : Pstream::allProcs())
|
|
||||||
|
for (const int proci : UPstream::allProcs())
|
||||||
{
|
{
|
||||||
if (domain != Pstream::myProcNo())
|
if (proci != UPstream::myProcNo() && !needed[proci].empty())
|
||||||
{
|
{
|
||||||
// Put data into send buffer
|
// Serialize as List
|
||||||
UOPstream toDomain(domain, pBufs);
|
UOPstream toProc(proci, pBufs);
|
||||||
|
toProc << needed[proci].sortedToc();
|
||||||
toDomain << needed[domain];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until everything is written.
|
pBufs.finishedSends(sendConnections_, sendProcs_, recvProcs_);
|
||||||
pBufs.finishedSends();
|
|
||||||
|
|
||||||
for (const int domain : Pstream::allProcs())
|
for (const int proci : pBufs.allProcs())
|
||||||
{
|
{
|
||||||
send_[domain].clear();
|
send_[proci].clear();
|
||||||
|
|
||||||
if (domain != Pstream::myProcNo())
|
if (proci != UPstream::myProcNo() && pBufs.hasRecvData(proci))
|
||||||
{
|
{
|
||||||
// get data from send buffer
|
UIPstream fromProc(proci, pBufs);
|
||||||
UIPstream fromDomain(domain, pBufs);
|
fromProc >> send_[proci];
|
||||||
|
|
||||||
fromDomain >> send_[domain];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020 DLR
|
Copyright (C) 2020 DLR
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -30,29 +31,44 @@ Description
|
|||||||
Class for parallel communication in a narrow band. It either provides a Map
|
Class for parallel communication in a narrow band. It either provides a Map
|
||||||
with the neighbouring values of the selected region or returns a Map of the
|
with the neighbouring values of the selected region or returns a Map of the
|
||||||
required values in global addressing. Also holds a reference to the stencil
|
required values in global addressing. Also holds a reference to the stencil
|
||||||
Before the data transfer the communation has to be set up:
|
Before the data transfer the communication has to be set up:
|
||||||
exchangeFields_.setUpCommforZone(interfaceCell_);
|
exchangeFields_.setUpCommforZone(interfaceCell_);
|
||||||
Is used in the plicRDF
|
Is used in the plicRDF
|
||||||
|
|
||||||
Original code supplied by Henning Scheufler, DLR (2019)
|
Original code supplied by Henning Scheufler, DLR (2019)
|
||||||
|
|
||||||
|
Additional optimization of processor communication
|
||||||
|
provided by Tetsuo AOYAGI, RIST (2022), to use a more compact
|
||||||
|
exchange of sizes with an updated version of PstreamBuffers.
|
||||||
|
This optimization uses additional sendTo/recvFrom member data
|
||||||
|
to track the topological connectivity, acting like an on-the-fly
|
||||||
|
sub-communicator, and respects corner connectivity.
|
||||||
|
|
||||||
|
-# Initially topological connections are empty (or all false).
|
||||||
|
-# Scan the stencil global cellIds (active zones only) and split
|
||||||
|
into sub-lists according the originating processor (the sender).
|
||||||
|
-# If an originating processor appears/disappears, need to update
|
||||||
|
the connectivity information (requires an all-to-all).
|
||||||
|
-# When possible, the topological send/recv is used in PstreamBuffers
|
||||||
|
finishedSends (minimizes communication).
|
||||||
|
.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
|
zoneDistributeI.H
|
||||||
zoneDistribute.C
|
zoneDistribute.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef zoneDistribute_H
|
#ifndef Foam_zoneDistribute_H
|
||||||
#define zoneDistribute_H
|
#define Foam_zoneDistribute_H
|
||||||
|
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
|
|
||||||
#include "zoneCPCStencil.H"
|
#include "zoneCPCStencil.H"
|
||||||
#include "IOobject.H"
|
|
||||||
#include "MeshObject.H"
|
#include "MeshObject.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
@ -68,37 +84,41 @@ class zoneDistribute
|
|||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
|
//- Reference to the zone stencil
|
||||||
//- labels of the points on coupled patches
|
|
||||||
labelList coupledBoundaryPoints_;
|
|
||||||
|
|
||||||
//- storage of the addressing for processor-to-processor comms
|
|
||||||
List<labelHashSet> send_;
|
|
||||||
|
|
||||||
//- Return patch of all coupled faces.
|
|
||||||
autoPtr<indirectPrimitivePatch> coupledFacesPatch() const;
|
|
||||||
|
|
||||||
zoneCPCStencil& stencil_;
|
zoneCPCStencil& stencil_;
|
||||||
|
|
||||||
const globalIndex& gblIdx_;
|
//- Global number into index of cells/faces
|
||||||
|
const globalIndex& globalNumbering_;
|
||||||
|
|
||||||
|
//- Global cell/face index to send for processor-to-processor comms
|
||||||
|
List<labelList> send_;
|
||||||
|
|
||||||
|
//- Parallel [cache]: send connectivity (true/false)
|
||||||
|
bitSet sendConnections_;
|
||||||
|
|
||||||
|
//- Parallel [cache]: send data to these ranks
|
||||||
|
DynamicList<label> sendProcs_;
|
||||||
|
|
||||||
|
//- Parallel [cache]: recv data from these ranks
|
||||||
|
DynamicList<label> recvProcs_;
|
||||||
|
|
||||||
|
|
||||||
//- Gives patchNumber and patchFaceNumber for a given
|
// Private Member Functions
|
||||||
//- Geometric volume field
|
|
||||||
|
//- Return local volField value at (cell or face) index
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type getLocalValue
|
Type getLocalValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const label localIdx
|
const label localIdx
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
//- Gives patchNumber and patchFaceNumber for a given
|
//- Gives patchNumber and patchFaceNumber for a given
|
||||||
//- Geometric volume field
|
//- Geometric volume field
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type faceValue
|
Type faceValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const label localIdx
|
const label localIdx
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
@ -114,14 +134,11 @@ public:
|
|||||||
//- Construct from fvMesh
|
//- Construct from fvMesh
|
||||||
explicit zoneDistribute(const fvMesh&);
|
explicit zoneDistribute(const fvMesh&);
|
||||||
|
|
||||||
|
//- Selector
|
||||||
// Selectors
|
|
||||||
|
|
||||||
static zoneDistribute& New(const fvMesh&);
|
static zoneDistribute& New(const fvMesh&);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
|
|
||||||
virtual ~zoneDistribute() = default;
|
virtual ~zoneDistribute() = default;
|
||||||
|
|
||||||
|
|
||||||
@ -142,7 +159,7 @@ public:
|
|||||||
//- Addressing reference
|
//- Addressing reference
|
||||||
const globalIndex& globalNumbering() const noexcept
|
const globalIndex& globalNumbering() const noexcept
|
||||||
{
|
{
|
||||||
return gblIdx_;
|
return globalNumbering_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Gives patchNumber and patchFaceNumber for a given
|
//- Gives patchNumber and patchFaceNumber for a given
|
||||||
@ -150,7 +167,7 @@ public:
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type getValue
|
Type getValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const Map<Type>& valuesFromOtherProc,
|
const Map<Type>& valuesFromOtherProc,
|
||||||
const label gblIdx
|
const label gblIdx
|
||||||
) const;
|
) const;
|
||||||
@ -160,7 +177,7 @@ public:
|
|||||||
Map<Field<Type>> getFields
|
Map<Field<Type>> getFields
|
||||||
(
|
(
|
||||||
const boolList& zone,
|
const boolList& zone,
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi
|
const VolumeField<Type>& phi
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Returns stencil and provides a Map with globalNumbering
|
//- Returns stencil and provides a Map with globalNumbering
|
||||||
@ -168,10 +185,8 @@ public:
|
|||||||
Map<Type> getDatafromOtherProc
|
Map<Type> getDatafromOtherProc
|
||||||
(
|
(
|
||||||
const boolList& zone,
|
const boolList& zone,
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi
|
const VolumeField<Type>& phi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2020 DLR
|
Copyright (C) 2019-2020 DLR
|
||||||
Copyright (C) 2020 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,16 +26,14 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "zoneDistribute.H"
|
|
||||||
#include "DynamicField.H"
|
#include "DynamicField.H"
|
||||||
#include "syncTools.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type Foam::zoneDistribute::getLocalValue
|
Type Foam::zoneDistribute::getLocalValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const label localIdx
|
const label localIdx
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -51,7 +49,7 @@ Type Foam::zoneDistribute::getLocalValue
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type Foam::zoneDistribute::faceValue
|
Type Foam::zoneDistribute::faceValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const label localIdx
|
const label localIdx
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -80,18 +78,19 @@ Type Foam::zoneDistribute::faceValue
|
|||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type Foam::zoneDistribute::getValue
|
Type Foam::zoneDistribute::getValue
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi,
|
const VolumeField<Type>& phi,
|
||||||
const Map<Type>& valuesFromOtherProc,
|
const Map<Type>& valuesFromOtherProc,
|
||||||
const label gblIdx
|
const label gblIdx
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (gblIdx_.isLocal(gblIdx))
|
if (globalNumbering_.isLocal(gblIdx))
|
||||||
{
|
{
|
||||||
const label idx = gblIdx_.toLocal(gblIdx);
|
const label localIdx = globalNumbering_.toLocal(gblIdx);
|
||||||
return getLocalValue(phi,idx);
|
return getLocalValue(phi,localIdx);
|
||||||
}
|
}
|
||||||
else // from other proc
|
else
|
||||||
{
|
{
|
||||||
|
// From other proc
|
||||||
return valuesFromOtherProc[gblIdx];
|
return valuesFromOtherProc[gblIdx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,7 +100,7 @@ template<typename Type>
|
|||||||
Foam::Map<Foam::Field<Type>> Foam::zoneDistribute::getFields
|
Foam::Map<Foam::Field<Type>> Foam::zoneDistribute::getFields
|
||||||
(
|
(
|
||||||
const boolList& zone,
|
const boolList& zone,
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi
|
const VolumeField<Type>& phi
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (zone.size() != phi.size())
|
if (zone.size() != phi.size())
|
||||||
@ -111,7 +110,6 @@ Foam::Map<Foam::Field<Type>> Foam::zoneDistribute::getFields
|
|||||||
<< "size of phi:" << phi.size()
|
<< "size of phi:" << phi.size()
|
||||||
<< "do not match. Did the mesh change?"
|
<< "do not match. Did the mesh change?"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -120,20 +118,20 @@ Foam::Map<Foam::Field<Type>> Foam::zoneDistribute::getFields
|
|||||||
|
|
||||||
Map<Field<Type>> stencilWithValues;
|
Map<Field<Type>> stencilWithValues;
|
||||||
|
|
||||||
DynamicField<Type> tmpField(100);
|
DynamicField<Type> tmpField(128);
|
||||||
|
|
||||||
forAll(zone, celli)
|
forAll(zone, celli)
|
||||||
{
|
{
|
||||||
if (zone[celli])
|
if (zone[celli])
|
||||||
{
|
{
|
||||||
tmpField.clearStorage();
|
tmpField.clear();
|
||||||
|
|
||||||
for (const label gblIdx : stencil_[celli])
|
for (const label gblIdx : stencil_[celli])
|
||||||
{
|
{
|
||||||
tmpField.append(getValue(phi,neiValues,gblIdx));
|
tmpField.append(getValue(phi,neiValues,gblIdx));
|
||||||
}
|
}
|
||||||
|
|
||||||
stencilWithValues.insert(celli,tmpField);
|
stencilWithValues.emplace(celli, tmpField);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +143,7 @@ template<typename Type>
|
|||||||
Foam::Map<Type> Foam::zoneDistribute::getDatafromOtherProc
|
Foam::Map<Type> Foam::zoneDistribute::getDatafromOtherProc
|
||||||
(
|
(
|
||||||
const boolList& zone,
|
const boolList& zone,
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& phi
|
const VolumeField<Type>& phi
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (zone.size() != phi.size())
|
if (zone.size() != phi.size())
|
||||||
@ -155,57 +153,59 @@ Foam::Map<Type> Foam::zoneDistribute::getDatafromOtherProc
|
|||||||
<< "size of phi:" << phi.size()
|
<< "size of phi:" << phi.size()
|
||||||
<< "do not match. Did the mesh change?"
|
<< "do not match. Did the mesh change?"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get values from other proc
|
// Get values from other proc
|
||||||
Map<Type> neiValues;
|
Map<Type> neiValues;
|
||||||
List<Map<Type>> sendValues(Pstream::nProcs());
|
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (UPstream::parRun())
|
||||||
{
|
{
|
||||||
forAll(send_, domaini)
|
if (sendConnections_.empty())
|
||||||
{
|
{
|
||||||
for (const label sendIdx : send_[domaini])
|
WarningInFunction
|
||||||
|
<< "The send/recv connections not initialized - "
|
||||||
|
<< "likely that setUpCommforZone() was not called"
|
||||||
|
<< endl;
|
||||||
|
// But don't exit/abort for now
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stream the send data into PstreamBuffers,
|
||||||
|
// which we also use to track the current topology.
|
||||||
|
|
||||||
|
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
|
for (const int proci : UPstream::allProcs())
|
||||||
{
|
{
|
||||||
sendValues[domaini].insert
|
if (proci != UPstream::myProcNo() && !send_[proci].empty())
|
||||||
|
{
|
||||||
|
// Serialize as Map
|
||||||
|
Map<Type> sendValues(2*send_[proci].size());
|
||||||
|
|
||||||
|
for (const label sendIdx : send_[proci])
|
||||||
|
{
|
||||||
|
sendValues.insert
|
||||||
(
|
(
|
||||||
sendIdx,
|
sendIdx,
|
||||||
getLocalValue(phi,gblIdx_.toLocal(sendIdx))
|
getLocalValue(phi, globalNumbering_.toLocal(sendIdx))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
UOPstream toProc(proci, pBufs);
|
||||||
|
toProc << sendValues;
|
||||||
// Stream data into buffer
|
|
||||||
for (const int domain : Pstream::allProcs())
|
|
||||||
{
|
|
||||||
if (domain != Pstream::myProcNo())
|
|
||||||
{
|
|
||||||
// Put data into send buffer
|
|
||||||
UOPstream toDomain(domain, pBufs);
|
|
||||||
|
|
||||||
toDomain << sendValues[domain];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until everything is written.
|
pBufs.finishedSends(sendConnections_, sendProcs_, recvProcs_);
|
||||||
pBufs.finishedSends();
|
|
||||||
|
|
||||||
Map<Type> tmpValue;
|
for (const int proci : pBufs.allProcs())
|
||||||
|
|
||||||
for (const int domain : Pstream::allProcs())
|
|
||||||
{
|
{
|
||||||
if (domain != Pstream::myProcNo())
|
if (proci != UPstream::myProcNo() && pBufs.hasRecvData(proci))
|
||||||
{
|
{
|
||||||
// Get data from send buffer
|
UIPstream fromProc(proci, pBufs);
|
||||||
UIPstream fromDomain(domain, pBufs);
|
Map<Type> tmpValues(fromProc);
|
||||||
|
|
||||||
fromDomain >> tmpValue;
|
neiValues += tmpValues;
|
||||||
|
|
||||||
neiValues += tmpValue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -265,8 +265,8 @@ bool Foam::functionObjects::fvExpressionField::setField
|
|||||||
|
|
||||||
if (action_ == actionType::opModify && log)
|
if (action_ == actionType::opModify && log)
|
||||||
{
|
{
|
||||||
const label numTotal = returnReduce(output.size(), plusOp<label>());
|
const label numTotal = returnReduce(output.size(), sumOp<label>());
|
||||||
reduce(numValuesChanged, plusOp<label>());
|
reduce(numValuesChanged, sumOp<label>());
|
||||||
|
|
||||||
Info<< this->name() << ": set ";
|
Info<< this->name() << ": set ";
|
||||||
if (numValuesChanged == numTotal)
|
if (numValuesChanged == numTotal)
|
||||||
|
|||||||
@ -223,7 +223,7 @@ bool Foam::functionObjects::energySpectrum::write()
|
|||||||
{
|
{
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
UOPstream toProc(0, pBufs);
|
UOPstream toProc(Pstream::masterNo(), pBufs);
|
||||||
|
|
||||||
toProc << Uc << C << cellAddr_;
|
toProc << Uc << C << cellAddr_;
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -50,45 +50,6 @@ namespace functionObjects
|
|||||||
);
|
);
|
||||||
|
|
||||||
} // End namespace functionObject
|
} // End namespace functionObject
|
||||||
|
|
||||||
|
|
||||||
// Processor and time for each of: -min -max -sum
|
|
||||||
typedef FixedList<Tuple2<label, scalar>, 3> statData;
|
|
||||||
|
|
||||||
|
|
||||||
//- Reduction class. If x and y are not equal assign value.
|
|
||||||
struct statsEqOp
|
|
||||||
{
|
|
||||||
void operator()
|
|
||||||
(
|
|
||||||
FixedList<statData, 2>& xStats,
|
|
||||||
const FixedList<statData, 2>& yStats
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
forAll(xStats, i)
|
|
||||||
{
|
|
||||||
statData& x = xStats[i];
|
|
||||||
const statData& y = yStats[i];
|
|
||||||
|
|
||||||
// 0 : min
|
|
||||||
// 1 : max
|
|
||||||
// 2 : sum
|
|
||||||
if (x[0].second() > y[0].second())
|
|
||||||
{
|
|
||||||
x[0].second() = y[0].second();
|
|
||||||
x[0].first() = y[0].first();
|
|
||||||
}
|
|
||||||
if (x[1].second() < y[1].second())
|
|
||||||
{
|
|
||||||
x[1].second() = y[1].second();
|
|
||||||
x[1].first() = y[1].first();
|
|
||||||
}
|
|
||||||
x[2].second() += y[2].second();
|
|
||||||
x[2].first()++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
@ -124,57 +85,59 @@ void Foam::functionObjects::parProfiling::report()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef FixedList<Tuple2<label, scalar>, 3> statData;
|
// (Time, Processor) for each of: min/max/sum
|
||||||
FixedList<statData, 2> times;
|
typedef FixedList<Tuple2<double, int>, 3> statData;
|
||||||
|
typedef FixedList<statData, 2> statDataTimes;
|
||||||
|
|
||||||
|
// Reduction: if x and y are unequal assign value.
|
||||||
|
auto statsEqOp = [](statDataTimes& xStats, const statDataTimes& yStats)
|
||||||
|
{
|
||||||
|
forAll(xStats, i)
|
||||||
|
{
|
||||||
|
statData& x = xStats[i];
|
||||||
|
const statData& y = yStats[i];
|
||||||
|
|
||||||
|
// 0: min, 1: max, 2: total (or avg)
|
||||||
|
if (x[0].first() > y[0].first())
|
||||||
|
{
|
||||||
|
x[0] = y[0];
|
||||||
|
}
|
||||||
|
if (x[1].first() < y[1].first())
|
||||||
|
{
|
||||||
|
x[1] = y[1];
|
||||||
|
}
|
||||||
|
x[2].first() += y[2].first();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
statDataTimes times;
|
||||||
|
|
||||||
{
|
{
|
||||||
const scalar masterTime =
|
const double masterTime =
|
||||||
(
|
(
|
||||||
profilingPstream::times(profilingPstream::REDUCE)
|
profilingPstream::times(profilingPstream::REDUCE)
|
||||||
+ profilingPstream::times(profilingPstream::GATHER)
|
+ profilingPstream::times(profilingPstream::GATHER)
|
||||||
+ profilingPstream::times(profilingPstream::SCATTER)
|
+ profilingPstream::times(profilingPstream::SCATTER)
|
||||||
|
// Include broadcast with reduce instead of all-to-all
|
||||||
|
+ profilingPstream::times(profilingPstream::BROADCAST)
|
||||||
);
|
);
|
||||||
|
|
||||||
statData& reduceStats = times[0];
|
times[0] = Tuple2<double, int>(masterTime, Pstream::myProcNo());
|
||||||
|
|
||||||
Tuple2<label, scalar>& minTime = reduceStats[0];
|
|
||||||
minTime.first() = Pstream::myProcNo();
|
|
||||||
minTime.second() = masterTime;
|
|
||||||
|
|
||||||
Tuple2<label, scalar>& maxTime = reduceStats[1];
|
|
||||||
maxTime.first() = Pstream::myProcNo();
|
|
||||||
maxTime.second() = masterTime;
|
|
||||||
|
|
||||||
Tuple2<label, scalar>& sumTime = reduceStats[2];
|
|
||||||
sumTime.first() = 1;
|
|
||||||
sumTime.second() = masterTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const scalar allTime =
|
const double allTime =
|
||||||
(
|
(
|
||||||
profilingPstream::times(profilingPstream::WAIT)
|
profilingPstream::times(profilingPstream::WAIT)
|
||||||
+ profilingPstream::times(profilingPstream::ALL_TO_ALL)
|
+ profilingPstream::times(profilingPstream::ALL_TO_ALL)
|
||||||
);
|
);
|
||||||
|
|
||||||
statData& allToAllStats = times[1];
|
times[1] = Tuple2<double, int>(allTime, Pstream::myProcNo());
|
||||||
|
|
||||||
Tuple2<label, scalar>& minTime = allToAllStats[0];
|
|
||||||
minTime.first() = Pstream::myProcNo();
|
|
||||||
minTime.second() = allTime;
|
|
||||||
|
|
||||||
Tuple2<label, scalar>& maxTime = allToAllStats[1];
|
|
||||||
maxTime.first() = Pstream::myProcNo();
|
|
||||||
maxTime.second() = allTime;
|
|
||||||
|
|
||||||
Tuple2<label, scalar>& sumTime = allToAllStats[2];
|
|
||||||
sumTime.first() = 1;
|
|
||||||
sumTime.second() = allTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
profilingPstream::suspend();
|
profilingPstream::suspend();
|
||||||
|
|
||||||
Pstream::combineGather(times, statsEqOp());
|
Pstream::combineGather(times, statsEqOp);
|
||||||
|
|
||||||
profilingPstream::resume();
|
profilingPstream::resume();
|
||||||
|
|
||||||
@ -184,21 +147,23 @@ void Foam::functionObjects::parProfiling::report()
|
|||||||
const statData& reduceStats = times[0];
|
const statData& reduceStats = times[0];
|
||||||
const statData& allToAllStats = times[1];
|
const statData& allToAllStats = times[1];
|
||||||
|
|
||||||
scalar reduceAvg = reduceStats[2].second()/Pstream::nProcs();
|
double reduceAvg = reduceStats[2].first()/Pstream::nProcs();
|
||||||
scalar allToAllAvg = allToAllStats[2].second()/Pstream::nProcs();
|
double allToAllAvg = allToAllStats[2].first()/Pstream::nProcs();
|
||||||
|
|
||||||
Info<< type() << ':' << nl
|
Info<< type() << ':' << nl
|
||||||
<< incrIndent
|
<< incrIndent
|
||||||
|
|
||||||
<< indent << "reduce : avg = " << reduceAvg << 's' << nl
|
<< indent << "reduce : avg = " << reduceAvg << 's' << nl
|
||||||
<< indent << " min = " << reduceStats[0].second()
|
<< indent << " min = " << reduceStats[0].first()
|
||||||
<< "s (processor " << reduceStats[0].first() << ')' << nl
|
<< "s (processor " << reduceStats[0].second() << ')' << nl
|
||||||
<< indent << " max = " << reduceStats[1].second()
|
<< indent << " max = " << reduceStats[1].first()
|
||||||
<< "s (processor " << reduceStats[1].first() << ')' << nl
|
<< "s (processor " << reduceStats[1].second() << ')' << nl
|
||||||
|
|
||||||
<< indent << "all-all : avg = " << allToAllAvg << 's' << nl
|
<< indent << "all-all : avg = " << allToAllAvg << 's' << nl
|
||||||
<< indent << " min = " << allToAllStats[0].second()
|
<< indent << " min = " << allToAllStats[0].first()
|
||||||
<< "s (processor " << allToAllStats[0].first() << ')' << nl
|
<< "s (processor " << allToAllStats[0].second() << ')' << nl
|
||||||
<< indent << " max = " << allToAllStats[1].second()
|
<< indent << " max = " << allToAllStats[1].first()
|
||||||
<< "s (processor " << allToAllStats[1].first() << ')'
|
<< "s (processor " << allToAllStats[1].second() << ')'
|
||||||
<< decrIndent << endl;
|
<< decrIndent << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -96,8 +96,7 @@ void Foam::functionObjects::syncObjects::sync()
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
const label nProcs = Pstream::nProcs(pBufs.comm());
|
for (const int proci : pBufs.allProcs())
|
||||||
for (label proci = 0; proci < nProcs; proci++)
|
|
||||||
{
|
{
|
||||||
// Get database to send
|
// Get database to send
|
||||||
const objectRegistry& sendObr = mappedPatchBase::subRegistry
|
const objectRegistry& sendObr = mappedPatchBase::subRegistry
|
||||||
@ -123,7 +122,7 @@ void Foam::functionObjects::syncObjects::sync()
|
|||||||
// Start sending and receiving and block
|
// Start sending and receiving and block
|
||||||
pBufs.finishedSends();
|
pBufs.finishedSends();
|
||||||
|
|
||||||
for (label proci = 0; proci < nProcs; proci++)
|
for (const int proci : pBufs.allProcs())
|
||||||
{
|
{
|
||||||
// Get database to receive data into
|
// Get database to receive data into
|
||||||
const objectRegistry& receiveObr = mappedPatchBase::subRegistry
|
const objectRegistry& receiveObr = mappedPatchBase::subRegistry
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2015-2016 OpenFOAM Foundation
|
Copyright (C) 2015-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -71,15 +72,15 @@ Foam::scalar Foam::fv::patchMeanVelocityForce::magUbarAve
|
|||||||
const volVectorField& U
|
const volVectorField& U
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
vector2D sumAmagUsumA
|
FixedList<scalar, 2> sumAmagUsumA(Zero);
|
||||||
(
|
|
||||||
|
sumAmagUsumA[0] +=
|
||||||
sum
|
sum
|
||||||
(
|
(
|
||||||
(flowDir_ & U.boundaryField()[patchi_])
|
(flowDir_ & U.boundaryField()[patchi_])
|
||||||
* mesh_.boundary()[patchi_].magSf()
|
* mesh_.boundary()[patchi_].magSf()
|
||||||
),
|
|
||||||
sum(mesh_.boundary()[patchi_].magSf())
|
|
||||||
);
|
);
|
||||||
|
sumAmagUsumA[1] += sum(mesh_.boundary()[patchi_].magSf());
|
||||||
|
|
||||||
|
|
||||||
// If the mean velocity force is applied to a cyclic patch
|
// If the mean velocity force is applied to a cyclic patch
|
||||||
@ -89,29 +90,29 @@ Foam::scalar Foam::fv::patchMeanVelocityForce::magUbarAve
|
|||||||
|
|
||||||
if (Pstream::parRun() && isA<cyclicPolyPatch>(patches[patchi_]))
|
if (Pstream::parRun() && isA<cyclicPolyPatch>(patches[patchi_]))
|
||||||
{
|
{
|
||||||
labelList processorCyclicPatches
|
for
|
||||||
(
|
(
|
||||||
processorCyclicPolyPatch::patchIDs(patch_, patches)
|
const label patchi
|
||||||
);
|
: processorCyclicPolyPatch::patchIDs(patch_, patches)
|
||||||
|
)
|
||||||
forAll(processorCyclicPatches, pcpi)
|
|
||||||
{
|
{
|
||||||
const label patchi = processorCyclicPatches[pcpi];
|
sumAmagUsumA[0] +=
|
||||||
|
|
||||||
sumAmagUsumA.x() +=
|
|
||||||
sum
|
sum
|
||||||
(
|
(
|
||||||
(flowDir_ & U.boundaryField()[patchi])
|
(flowDir_ & U.boundaryField()[patchi])
|
||||||
* mesh_.boundary()[patchi].magSf()
|
* mesh_.boundary()[patchi].magSf()
|
||||||
);
|
);
|
||||||
|
sumAmagUsumA[1] += sum(mesh_.boundary()[patchi].magSf());
|
||||||
sumAmagUsumA.y() += sum(mesh_.boundary()[patchi].magSf());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh_.reduce(sumAmagUsumA, sumOp<vector2D>());
|
mesh_.reduce(sumAmagUsumA, sumOp<scalar>());
|
||||||
|
|
||||||
return sumAmagUsumA.x()/sumAmagUsumA.y();
|
return
|
||||||
|
(
|
||||||
|
sumAmagUsumA[0]
|
||||||
|
/ stabilise(sumAmagUsumA[1], VSMALL)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017, 2020 OpenFOAM Foundation
|
Copyright (C) 2011-2017, 2020 OpenFOAM Foundation
|
||||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -89,7 +89,7 @@ Foam::Cloud<ParticleType>::Cloud
|
|||||||
// Ask for the tetBasePtIs to trigger all processors to build
|
// Ask for the tetBasePtIs to trigger all processors to build
|
||||||
// them, otherwise, if some processors have no particles then
|
// them, otherwise, if some processors have no particles then
|
||||||
// there is a comms mismatch.
|
// there is a comms mismatch.
|
||||||
polyMesh_.tetBasePtIs();
|
(void)polyMesh_.tetBasePtIs();
|
||||||
|
|
||||||
if (particles.size())
|
if (particles.size())
|
||||||
{
|
{
|
||||||
@ -163,54 +163,55 @@ void Foam::Cloud<ParticleType>::move
|
|||||||
// Which processors this processor is connected to
|
// Which processors this processor is connected to
|
||||||
const labelList& neighbourProcs = pData[Pstream::myProcNo()];
|
const labelList& neighbourProcs = pData[Pstream::myProcNo()];
|
||||||
|
|
||||||
// Indexing from the processor number into the neighbourProcs list
|
|
||||||
labelList neighbourProcIndices(Pstream::nProcs(), -1);
|
|
||||||
|
|
||||||
forAll(neighbourProcs, i)
|
|
||||||
{
|
|
||||||
neighbourProcIndices[neighbourProcs[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialise the stepFraction moved for the particles
|
// Initialise the stepFraction moved for the particles
|
||||||
forAllIters(*this, pIter)
|
for (ParticleType& p : *this)
|
||||||
{
|
{
|
||||||
pIter().reset();
|
p.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of lists of particles to be transferred for all of the
|
// Clear the global positions as these are about to change
|
||||||
// neighbour processors
|
|
||||||
List<IDLList<ParticleType>> particleTransferLists
|
|
||||||
(
|
|
||||||
neighbourProcs.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
// List of destination processorPatches indices for all of the
|
|
||||||
// neighbour processors
|
|
||||||
List<DynamicList<label>> patchIndexTransferLists
|
|
||||||
(
|
|
||||||
neighbourProcs.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Allocate transfer buffers
|
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
|
||||||
|
|
||||||
// Clear the global positions as there are about to change
|
|
||||||
globalPositionsPtr_.clear();
|
globalPositionsPtr_.clear();
|
||||||
|
|
||||||
|
|
||||||
|
// For v2112 and earlier: pre-assembled lists of particles
|
||||||
|
// to be transferred and target patch on a per processor basis.
|
||||||
|
// Apart from memory overhead of assembling the lists this adds
|
||||||
|
// allocations/de-allocation when building linked-lists.
|
||||||
|
|
||||||
|
// Now stream particle transfer tuples directly into PstreamBuffers.
|
||||||
|
// Use a local cache of UOPstream wrappers for the formatters
|
||||||
|
// (since there are potentially many particles being shifted about).
|
||||||
|
|
||||||
|
|
||||||
|
// Allocate transfer buffers,
|
||||||
|
// automatic clearStorage when UIPstream closes is disabled.
|
||||||
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
pBufs.allowClearRecv(false);
|
||||||
|
|
||||||
|
// Cache of opened UOPstream wrappers
|
||||||
|
PtrList<UOPstream> UOPstreamPtrs(Pstream::nProcs());
|
||||||
|
|
||||||
// While there are particles to transfer
|
// While there are particles to transfer
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
particleTransferLists = IDLList<ParticleType>();
|
// Reset transfer buffers
|
||||||
forAll(patchIndexTransferLists, i)
|
pBufs.clear();
|
||||||
|
|
||||||
|
// Rewind existing streams
|
||||||
|
forAll(UOPstreamPtrs, proci)
|
||||||
{
|
{
|
||||||
patchIndexTransferLists[i].clear();
|
auto* osptr = UOPstreamPtrs.get(proci);
|
||||||
|
if (osptr)
|
||||||
|
{
|
||||||
|
osptr->rewind();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over all particles
|
// Loop over all particles
|
||||||
for (ParticleType& p : *this)
|
for (ParticleType& p : *this)
|
||||||
{
|
{
|
||||||
// Move the particle
|
// Move the particle
|
||||||
bool keepParticle = p.move(cloud, td, trackTime);
|
const bool keepParticle = p.move(cloud, td, trackTime);
|
||||||
|
|
||||||
// If the particle is to be kept
|
// If the particle is to be kept
|
||||||
// (i.e. it hasn't passed through an inlet or outlet)
|
// (i.e. it hasn't passed through an inlet or outlet)
|
||||||
@ -235,22 +236,27 @@ void Foam::Cloud<ParticleType>::move
|
|||||||
|
|
||||||
const label patchi = p.patch();
|
const label patchi = p.patch();
|
||||||
|
|
||||||
const label n = neighbourProcIndices
|
const label toProci =
|
||||||
[
|
|
||||||
refCast<const processorPolyPatch>
|
|
||||||
(
|
(
|
||||||
pbm[patchi]
|
refCast<const processorPolyPatch>(pbm[patchi])
|
||||||
).neighbProcNo()
|
.neighbProcNo()
|
||||||
];
|
);
|
||||||
|
|
||||||
|
// Get/create output stream
|
||||||
|
auto* osptr = UOPstreamPtrs.get(toProci);
|
||||||
|
if (!osptr)
|
||||||
|
{
|
||||||
|
osptr = new UOPstream(toProci, pBufs);
|
||||||
|
UOPstreamPtrs.set(toProci, osptr);
|
||||||
|
}
|
||||||
|
|
||||||
p.prepareForParallelTransfer();
|
p.prepareForParallelTransfer();
|
||||||
|
|
||||||
particleTransferLists[n].append(this->remove(&p));
|
// Tuple: (patchi particle)
|
||||||
|
(*osptr) << procPatchNeighbours[patchi] << p;
|
||||||
|
|
||||||
patchIndexTransferLists[n].append
|
// Can now remove from my list
|
||||||
(
|
deleteParticle(p);
|
||||||
procPatchNeighbours[patchi]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -264,76 +270,32 @@ void Foam::Cloud<ParticleType>::move
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pBufs.finishedNeighbourSends(neighbourProcs);
|
||||||
|
|
||||||
// Clear transfer buffers
|
if (!returnReduce(pBufs.hasRecvData(), orOp<bool>()))
|
||||||
pBufs.clear();
|
|
||||||
|
|
||||||
// Stream into send buffers
|
|
||||||
forAll(particleTransferLists, i)
|
|
||||||
{
|
|
||||||
if (particleTransferLists[i].size())
|
|
||||||
{
|
|
||||||
UOPstream particleStream
|
|
||||||
(
|
|
||||||
neighbourProcs[i],
|
|
||||||
pBufs
|
|
||||||
);
|
|
||||||
|
|
||||||
particleStream
|
|
||||||
<< patchIndexTransferLists[i]
|
|
||||||
<< particleTransferLists[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Start sending. Sets number of bytes transferred
|
|
||||||
labelList allNTrans(Pstream::nProcs());
|
|
||||||
pBufs.finishedSends(allNTrans);
|
|
||||||
|
|
||||||
|
|
||||||
bool transferred = false;
|
|
||||||
|
|
||||||
for (const label n : allNTrans)
|
|
||||||
{
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
transferred = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reduce(transferred, orOp<bool>());
|
|
||||||
|
|
||||||
if (!transferred)
|
|
||||||
{
|
{
|
||||||
|
// No parcels to transfer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve from receive buffers
|
// Retrieve from receive buffers
|
||||||
for (const label neighbProci : neighbourProcs)
|
for (const label proci : neighbourProcs)
|
||||||
{
|
{
|
||||||
label nRec = allNTrans[neighbProci];
|
if (pBufs.hasRecvData(proci))
|
||||||
|
|
||||||
if (nRec)
|
|
||||||
{
|
{
|
||||||
UIPstream particleStream(neighbProci, pBufs);
|
UIPstream is(proci, pBufs);
|
||||||
|
|
||||||
labelList receivePatchIndex(particleStream);
|
// Read out each (patchi particle) tuple
|
||||||
|
while (!is.eof())
|
||||||
IDLList<ParticleType> newParticles
|
|
||||||
(
|
|
||||||
particleStream,
|
|
||||||
typename ParticleType::iNew(polyMesh_)
|
|
||||||
);
|
|
||||||
|
|
||||||
label pI = 0;
|
|
||||||
|
|
||||||
for (ParticleType& newp : newParticles)
|
|
||||||
{
|
{
|
||||||
label patchi = procPatches[receivePatchIndex[pI++]];
|
label patchi = pTraits<label>(is);
|
||||||
|
auto* newp = new ParticleType(polyMesh_, is);
|
||||||
|
|
||||||
newp.correctAfterParallelTransfer(patchi, td);
|
// The real patch index
|
||||||
|
patchi = procPatches[patchi];
|
||||||
|
|
||||||
addParticle(newParticles.remove(&newp));
|
(*newp).correctAfterParallelTransfer(patchi, td);
|
||||||
|
addParticle(newp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,9 +327,9 @@ void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
|
|||||||
const vectorField& positions = globalPositionsPtr_();
|
const vectorField& positions = globalPositionsPtr_();
|
||||||
|
|
||||||
label i = 0;
|
label i = 0;
|
||||||
forAllIters(*this, iter)
|
for (ParticleType& p : *this)
|
||||||
{
|
{
|
||||||
iter().autoMap(positions[i], mapper);
|
p.autoMap(positions[i], mapper);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -376,20 +338,19 @@ void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
|
|||||||
template<class ParticleType>
|
template<class ParticleType>
|
||||||
void Foam::Cloud<ParticleType>::writePositions() const
|
void Foam::Cloud<ParticleType>::writePositions() const
|
||||||
{
|
{
|
||||||
OFstream pObj
|
OFstream os
|
||||||
(
|
(
|
||||||
this->db().time().path()/this->name() + "_positions.obj"
|
this->db().time().path()/this->name() + "_positions.obj"
|
||||||
);
|
);
|
||||||
|
|
||||||
forAllConstIters(*this, pIter)
|
for (const ParticleType& p : *this)
|
||||||
{
|
{
|
||||||
const ParticleType& p = pIter();
|
|
||||||
const point position(p.position());
|
const point position(p.position());
|
||||||
pObj<< "v " << position.x() << " " << position.y() << " "
|
os << "v "
|
||||||
|
<< position.x() << ' '
|
||||||
|
<< position.y() << ' '
|
||||||
<< position.z() << nl;
|
<< position.z() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
pObj.flush();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -402,13 +363,12 @@ void Foam::Cloud<ParticleType>::storeGlobalPositions() const
|
|||||||
// within autoMap, and this pre-processing would not be necessary.
|
// within autoMap, and this pre-processing would not be necessary.
|
||||||
|
|
||||||
globalPositionsPtr_.reset(new vectorField(this->size()));
|
globalPositionsPtr_.reset(new vectorField(this->size()));
|
||||||
|
|
||||||
vectorField& positions = globalPositionsPtr_();
|
vectorField& positions = globalPositionsPtr_();
|
||||||
|
|
||||||
label i = 0;
|
label i = 0;
|
||||||
forAllConstIters(*this, iter)
|
for (const ParticleType& p : *this)
|
||||||
{
|
{
|
||||||
positions[i] = iter().position();
|
positions[i] = p.position();
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020 OpenCFD Ltd.
|
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -205,10 +205,13 @@ void Foam::RecycleInteraction<CloudType>::postEvolve()
|
|||||||
{
|
{
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
// Relocate the recycled parcels into slots for each receiving processor
|
// See comments in Cloud::move() about transfer particles handling
|
||||||
List<IDLList<parcelType>> transferParcels(Pstream::nProcs());
|
|
||||||
List<DynamicList<scalar>> fractions(Pstream::nProcs());
|
// Allocate transfer buffers
|
||||||
List<DynamicList<label>> patchAddr(Pstream::nProcs());
|
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
||||||
|
|
||||||
|
// Cache of opened UOPstream wrappers
|
||||||
|
PtrList<UOPstream> UOPstreamPtrs(Pstream::nProcs());
|
||||||
|
|
||||||
auto& rnd = this->owner().rndGen();
|
auto& rnd = this->owner().rndGen();
|
||||||
|
|
||||||
@ -217,7 +220,7 @@ void Foam::RecycleInteraction<CloudType>::postEvolve()
|
|||||||
auto& patchParcels = recycledParcels_[addri];
|
auto& patchParcels = recycledParcels_[addri];
|
||||||
auto& injectionPatch = injectionPatchPtr_[addri];
|
auto& injectionPatch = injectionPatchPtr_[addri];
|
||||||
|
|
||||||
forAllIters(patchParcels, pIter)
|
for (parcelType& p : patchParcels)
|
||||||
{
|
{
|
||||||
// Choose a random location to insert the parcel
|
// Choose a random location to insert the parcel
|
||||||
const scalar fraction01 = rnd.template sample01<scalar>();
|
const scalar fraction01 = rnd.template sample01<scalar>();
|
||||||
@ -225,101 +228,76 @@ void Foam::RecycleInteraction<CloudType>::postEvolve()
|
|||||||
// Identify the processor that owns the location
|
// Identify the processor that owns the location
|
||||||
const label toProci = injectionPatch.whichProc(fraction01);
|
const label toProci = injectionPatch.whichProc(fraction01);
|
||||||
|
|
||||||
// Store info in slot for target processor
|
// Get/create output stream
|
||||||
transferParcels[toProci].append(patchParcels.remove(pIter));
|
auto* osptr = UOPstreamPtrs.get(toProci);
|
||||||
fractions[toProci].append(fraction01);
|
if (!osptr)
|
||||||
patchAddr[toProci].append(addri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set-up the sends
|
|
||||||
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking);
|
|
||||||
|
|
||||||
// Clear transfer buffers
|
|
||||||
pBufs.clear();
|
|
||||||
|
|
||||||
// Stream into send buffers
|
|
||||||
forAll(transferParcels, proci)
|
|
||||||
{
|
{
|
||||||
if (transferParcels[proci].size())
|
osptr = new UOPstream(toProci, pBufs);
|
||||||
{
|
UOPstreamPtrs.set(toProci, osptr);
|
||||||
UOPstream particleStream(proci, pBufs);
|
}
|
||||||
|
|
||||||
particleStream
|
// Tuple: (address fraction particle)
|
||||||
<< transferParcels[proci]
|
(*osptr) << addri << fraction01 << p;
|
||||||
<< fractions[proci]
|
|
||||||
<< patchAddr[proci];
|
|
||||||
|
|
||||||
transferParcels[proci].clear();
|
// Can now remove from list and delete
|
||||||
|
delete(patchParcels.remove(&p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start sending. Sets number of bytes transferred
|
pBufs.finishedSends();
|
||||||
labelList allNTrans(Pstream::nProcs());
|
|
||||||
pBufs.finishedSends(allNTrans);
|
if (!returnReduce(pBufs.hasRecvData(), orOp<bool>()))
|
||||||
bool transferred = false;
|
|
||||||
for (const label n : allNTrans)
|
|
||||||
{
|
{
|
||||||
if (n)
|
// No parcels to recycle
|
||||||
{
|
|
||||||
transferred = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reduce(transferred, orOp<bool>());
|
|
||||||
if (!transferred)
|
|
||||||
{
|
|
||||||
// No parcels to transfer
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve from receive buffers
|
// Retrieve from receive buffers
|
||||||
for (label proci = 0; proci < Pstream::nProcs(); ++proci)
|
for (const int proci : pBufs.allProcs())
|
||||||
{
|
{
|
||||||
if (allNTrans[proci])
|
if (pBufs.hasRecvData(proci))
|
||||||
{
|
{
|
||||||
UIPstream particleStream(proci, pBufs);
|
UIPstream is(proci, pBufs);
|
||||||
IDLList<parcelType> newParticles
|
|
||||||
(
|
|
||||||
particleStream,
|
|
||||||
typename parcelType::iNew(this->owner().mesh())
|
|
||||||
);
|
|
||||||
scalarList fractions(particleStream);
|
|
||||||
labelList patchAddr(particleStream);
|
|
||||||
|
|
||||||
label parceli = 0;
|
// Read out each (address fraction particle) tuple
|
||||||
for (parcelType& newp : newParticles)
|
while (!is.eof())
|
||||||
{
|
{
|
||||||
|
const label addri = pTraits<label>(is);
|
||||||
|
const scalar fraction01 = pTraits<scalar>(is);
|
||||||
|
auto* newp = new parcelType(this->owner().mesh(), is);
|
||||||
|
|
||||||
// Parcel to be recycled
|
// Parcel to be recycled
|
||||||
vector newPosition;
|
vector newPosition;
|
||||||
label cellOwner;
|
label cellOwner;
|
||||||
label dummy;
|
label dummy;
|
||||||
const label addri = patchAddr[parceli];
|
|
||||||
injectionPatchPtr_[addri].setPositionAndCell
|
injectionPatchPtr_[addri].setPositionAndCell
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
fractions[parceli],
|
fraction01,
|
||||||
this->owner().rndGen(),
|
this->owner().rndGen(),
|
||||||
newPosition,
|
newPosition,
|
||||||
cellOwner,
|
cellOwner,
|
||||||
dummy,
|
dummy,
|
||||||
dummy
|
dummy
|
||||||
);
|
);
|
||||||
newp.relocate(newPosition, cellOwner);
|
newp->relocate(newPosition, cellOwner);
|
||||||
newp.U() = this->owner().U()[cellOwner];
|
newp->nParticle() *= recycleFraction_;
|
||||||
newp.nParticle() *= recycleFraction_;
|
|
||||||
|
|
||||||
|
// Assume parcel velocity is same as the carrier velocity
|
||||||
|
newp->U() = this->owner().U()[cellOwner];
|
||||||
|
|
||||||
|
// Injector ID
|
||||||
const label idx =
|
const label idx =
|
||||||
(
|
(
|
||||||
injIdToIndex_.size()
|
injIdToIndex_.size()
|
||||||
? injIdToIndex_.lookup(newp.typeId(), 0)
|
? injIdToIndex_.lookup(newp->typeId(), 0)
|
||||||
: 0
|
: 0
|
||||||
);
|
);
|
||||||
++nInjected_[addri][idx];
|
|
||||||
massInjected_[addri][idx] += newp.nParticle()*newp.mass();
|
|
||||||
|
|
||||||
this->owner().addParticle(newParticles.remove(&newp));
|
++nInjected_[addri][idx];
|
||||||
++parceli;
|
massInjected_[addri][idx] += newp->nParticle()*newp->mass();
|
||||||
|
|
||||||
|
this->owner().addParticle(newp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,8 +306,10 @@ void Foam::RecycleInteraction<CloudType>::postEvolve()
|
|||||||
{
|
{
|
||||||
forAll(recycledParcels_, addri)
|
forAll(recycledParcels_, addri)
|
||||||
{
|
{
|
||||||
forAllIters(recycledParcels_[addri], iter)
|
for (parcelType& p : recycledParcels_[addri])
|
||||||
{
|
{
|
||||||
|
parcelType* newp = recycledParcels_[addri].remove(&p);
|
||||||
|
|
||||||
// Parcel to be recycled
|
// Parcel to be recycled
|
||||||
vector newPosition;
|
vector newPosition;
|
||||||
label cellOwner;
|
label cellOwner;
|
||||||
@ -345,13 +325,13 @@ void Foam::RecycleInteraction<CloudType>::postEvolve()
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Update parcel properties
|
// Update parcel properties
|
||||||
parcelType* newp = recycledParcels_[addri].remove(iter);
|
|
||||||
newp->relocate(newPosition, cellOwner);
|
newp->relocate(newPosition, cellOwner);
|
||||||
newp->nParticle() *= recycleFraction_;
|
newp->nParticle() *= recycleFraction_;
|
||||||
|
|
||||||
// Assume parcel velocity is same as the carrier velocity
|
// Assume parcel velocity is same as the carrier velocity
|
||||||
newp->U() = this->owner().U()[cellOwner];
|
newp->U() = this->owner().U()[cellOwner];
|
||||||
|
|
||||||
|
// Injector ID
|
||||||
const label idx =
|
const label idx =
|
||||||
(
|
(
|
||||||
injIdToIndex_.size()
|
injIdToIndex_.size()
|
||||||
@ -380,7 +360,7 @@ void Foam::RecycleInteraction<CloudType>::info(Ostream& os)
|
|||||||
|
|
||||||
forAll(nRemoved_, patchi)
|
forAll(nRemoved_, patchi)
|
||||||
{
|
{
|
||||||
label lsd = nRemoved_[patchi].size();
|
const label lsd = nRemoved_[patchi].size();
|
||||||
npr0[patchi].setSize(lsd, Zero);
|
npr0[patchi].setSize(lsd, Zero);
|
||||||
mpr0[patchi].setSize(lsd, Zero);
|
mpr0[patchi].setSize(lsd, Zero);
|
||||||
npi0[patchi].setSize(lsd, Zero);
|
npi0[patchi].setSize(lsd, Zero);
|
||||||
|
|||||||
@ -35,11 +35,11 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef SprayCloud_H
|
#ifndef Foam_SprayCloud_H
|
||||||
#define SprayCloud_H
|
#define Foam_SprayCloud_H
|
||||||
|
|
||||||
#include "sprayCloud.H"
|
#include "sprayCloud.H"
|
||||||
#include "SortableList.H"
|
#include "SortList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -88,95 +88,73 @@ inline Foam::scalar Foam::SprayCloud<CloudType>::penetration
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar distance = 0.0;
|
|
||||||
|
|
||||||
const label nParcel = this->size();
|
const label nParcel = this->size();
|
||||||
globalIndex globalParcels(nParcel);
|
const globalIndex globalParcels(nParcel);
|
||||||
const label nParcelSum = globalParcels.totalSize();
|
const label nTotParcel = globalParcels.totalSize();
|
||||||
|
|
||||||
if (nParcelSum == 0)
|
if (nTotParcel == 0)
|
||||||
{
|
{
|
||||||
return distance;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// lists of parcels mass and distance from initial injection point
|
// lists of parcels mass and distance from initial injection point
|
||||||
List<List<scalar>> procMass(Pstream::nProcs());
|
List<scalar> mass(nParcel);
|
||||||
List<List<scalar>> procDist(Pstream::nProcs());
|
List<scalar> dist(nParcel);
|
||||||
|
|
||||||
List<scalar>& mass = procMass[Pstream::myProcNo()];
|
|
||||||
List<scalar>& dist = procDist[Pstream::myProcNo()];
|
|
||||||
|
|
||||||
mass.setSize(nParcel);
|
|
||||||
dist.setSize(nParcel);
|
|
||||||
|
|
||||||
|
scalar mTotal = 0;
|
||||||
|
{
|
||||||
label i = 0;
|
label i = 0;
|
||||||
scalar mSum = 0.0;
|
|
||||||
for (const parcelType& p : *this)
|
for (const parcelType& p : *this)
|
||||||
{
|
{
|
||||||
scalar m = p.nParticle()*p.mass();
|
scalar m = p.nParticle()*p.mass();
|
||||||
scalar d = mag(p.position() - p.position0());
|
scalar d = mag(p.position() - p.position0());
|
||||||
mSum += m;
|
mTotal += m;
|
||||||
|
|
||||||
mass[i] = m;
|
mass[i] = m;
|
||||||
dist[i] = d;
|
dist[i] = d;
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Total mass across all processors
|
||||||
|
reduce(mTotal, sumOp<scalar>());
|
||||||
|
|
||||||
// calculate total mass across all processors
|
scalar distance = 0;
|
||||||
reduce(mSum, sumOp<scalar>());
|
globalParcels.gatherInplace(mass);
|
||||||
Pstream::gatherList(procMass);
|
globalParcels.gatherInplace(dist);
|
||||||
Pstream::gatherList(procDist);
|
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
// flatten the mass lists
|
if (nTotParcel == 1)
|
||||||
List<scalar> allMass(nParcelSum, Zero);
|
|
||||||
SortableList<scalar> allDist(nParcelSum, Zero);
|
|
||||||
for (const int proci : Pstream::allProcs())
|
|
||||||
{
|
{
|
||||||
SubList<scalar>
|
distance = dist[0];
|
||||||
(
|
|
||||||
allMass,
|
|
||||||
globalParcels.localSize(proci),
|
|
||||||
globalParcels.localStart(proci)
|
|
||||||
) = procMass[proci];
|
|
||||||
|
|
||||||
// flatten the distance list
|
|
||||||
SubList<scalar>
|
|
||||||
(
|
|
||||||
allDist,
|
|
||||||
globalParcels.localSize(proci),
|
|
||||||
globalParcels.localStart(proci)
|
|
||||||
) = procDist[proci];
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// sort allDist distances into ascending order
|
|
||||||
// note: allMass masses are left unsorted
|
|
||||||
allDist.sort();
|
|
||||||
|
|
||||||
if (nParcelSum > 1)
|
|
||||||
{
|
{
|
||||||
const scalar mLimit = fraction*mSum;
|
// Distances - sored into ascending order
|
||||||
const labelList& indices = allDist.indices();
|
// Masses - leave unsorted
|
||||||
|
|
||||||
if (mLimit > (mSum - allMass[indices.last()]))
|
const SortList<scalar> sortedDist(dist);
|
||||||
|
|
||||||
|
const scalar mLimit = fraction*mTotal;
|
||||||
|
const labelList& indices = sortedDist.indices();
|
||||||
|
|
||||||
|
if (mLimit > (mTotal - mass[indices.last()]))
|
||||||
{
|
{
|
||||||
distance = allDist.last();
|
distance = sortedDist.last();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// assuming that 'fraction' is generally closer to 1 than 0,
|
// assuming that 'fraction' is generally closer to 1 than 0,
|
||||||
// loop through in reverse distance order
|
// loop through in reverse distance order
|
||||||
const scalar mThreshold = (1.0 - fraction)*mSum;
|
const scalar mThreshold = (1.0 - fraction)*mTotal;
|
||||||
scalar mCurrent = 0.0;
|
scalar mCurrent = 0;
|
||||||
label i0 = 0;
|
label i0 = 0;
|
||||||
|
|
||||||
forAllReverse(indices, i)
|
forAllReverse(indices, i)
|
||||||
{
|
{
|
||||||
label indI = indices[i];
|
label indI = indices[i];
|
||||||
|
|
||||||
mCurrent += allMass[indI];
|
mCurrent += mass[indI];
|
||||||
|
|
||||||
if (mCurrent > mThreshold)
|
if (mCurrent > mThreshold)
|
||||||
{
|
{
|
||||||
@ -187,21 +165,20 @@ inline Foam::scalar Foam::SprayCloud<CloudType>::penetration
|
|||||||
|
|
||||||
if (i0 == indices.size() - 1)
|
if (i0 == indices.size() - 1)
|
||||||
{
|
{
|
||||||
distance = allDist.last();
|
distance = sortedDist.last();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// linearly interpolate to determine distance
|
// linearly interpolate to determine distance
|
||||||
scalar alpha = (mCurrent - mThreshold)/allMass[indices[i0]];
|
scalar alpha = (mCurrent - mThreshold)/mass[indices[i0]];
|
||||||
distance =
|
distance =
|
||||||
allDist[i0] + alpha*(allDist[i0+1] - allDist[i0]);
|
(
|
||||||
|
sortedDist[i0]
|
||||||
|
+ alpha*(sortedDist[i0+1] - sortedDist[i0])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
distance = allDist.first();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pstream::scatter(distance);
|
Pstream::scatter(distance);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -403,53 +403,14 @@ bool Foam::lumpedPointState::readData
|
|||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
// Scatter master data using communication scheme
|
// Broadcast master data to everyone
|
||||||
|
|
||||||
const List<Pstream::commsStruct>& comms =
|
Pstream::scatter(points_);
|
||||||
(
|
Pstream::scatter(angles_);
|
||||||
(Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
Pstream::scatter(degrees_);
|
||||||
? Pstream::linearCommunication()
|
|
||||||
: Pstream::treeCommunication()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get my communication order
|
|
||||||
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
|
|
||||||
|
|
||||||
// Receive from up
|
|
||||||
if (myComm.above() != -1)
|
|
||||||
{
|
|
||||||
IPstream fromAbove
|
|
||||||
(
|
|
||||||
UPstream::commsTypes::scheduled,
|
|
||||||
myComm.above(),
|
|
||||||
0,
|
|
||||||
Pstream::msgType(),
|
|
||||||
Pstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
fromAbove >> points_ >> angles_ >> degrees_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send to downstairs neighbours
|
|
||||||
forAllReverse(myComm.below(), belowI)
|
|
||||||
{
|
|
||||||
OPstream toBelow
|
|
||||||
(
|
|
||||||
UPstream::commsTypes::scheduled,
|
|
||||||
myComm.below()[belowI],
|
|
||||||
0,
|
|
||||||
Pstream::msgType(),
|
|
||||||
Pstream::worldComm
|
|
||||||
);
|
|
||||||
|
|
||||||
toBelow << points_ << angles_ << degrees_;
|
|
||||||
}
|
|
||||||
|
|
||||||
rotationPtr_.reset(nullptr);
|
|
||||||
|
|
||||||
// MPI barrier
|
|
||||||
Pstream::scatter(ok);
|
Pstream::scatter(ok);
|
||||||
}
|
}
|
||||||
|
rotationPtr_.reset(nullptr);
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -79,47 +79,37 @@ Foam::label Foam::AMIInterpolation::calcDistribution
|
|||||||
const primitivePatch& tgtPatch
|
const primitivePatch& tgtPatch
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
// Either not parallel or no faces on any processor
|
||||||
label proci = 0;
|
label proci = 0;
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
labelList facesPresentOnProc(Pstream::nProcs(), Zero);
|
const bitSet hasFaces
|
||||||
if ((srcPatch.size() > 0) || (tgtPatch.size() > 0))
|
(
|
||||||
{
|
UPstream::listGatherValues<bool>
|
||||||
facesPresentOnProc[Pstream::myProcNo()] = 1;
|
(
|
||||||
}
|
srcPatch.size() > 0 || tgtPatch.size() > 0
|
||||||
else
|
)
|
||||||
{
|
);
|
||||||
facesPresentOnProc[Pstream::myProcNo()] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::gatherList(facesPresentOnProc);
|
const auto nHaveFaces = hasFaces.count();
|
||||||
Pstream::scatterList(facesPresentOnProc);
|
|
||||||
|
|
||||||
label nHaveFaces = sum(facesPresentOnProc);
|
if (nHaveFaces == 1)
|
||||||
|
|
||||||
if (nHaveFaces > 1)
|
|
||||||
{
|
{
|
||||||
proci = -1;
|
proci = hasFaces.find_first();
|
||||||
if (debug)
|
DebugInFunction
|
||||||
{
|
|
||||||
InfoInFunction
|
|
||||||
<< "AMI split across multiple processors" << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (nHaveFaces == 1)
|
|
||||||
{
|
|
||||||
proci = facesPresentOnProc.find(1);
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
InfoInFunction
|
|
||||||
<< "AMI local to processor" << proci << endl;
|
<< "AMI local to processor" << proci << endl;
|
||||||
}
|
}
|
||||||
}
|
else if (nHaveFaces > 1)
|
||||||
|
{
|
||||||
|
proci = -1;
|
||||||
|
DebugInFunction
|
||||||
|
<< "AMI split across multiple processors" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pstream::broadcast(proci);
|
||||||
|
}
|
||||||
|
|
||||||
// Either not parallel or no faces on any processor
|
|
||||||
return proci;
|
return proci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user