ENH: use UList instead of List for some Pstream gather/scatter

- can use UList signature since the routines do not resize the list
  or attempt to broadcast it: useful for SubList handling.

ENH: add IPstream/OPstream send/recv static methods
This commit is contained in:
Mark Olesen
2024-02-02 17:48:33 +01:00
parent 91a1eaa01b
commit 47c44a5783
14 changed files with 321 additions and 192 deletions

View File

@ -50,37 +50,37 @@ scalar sumReduce
) )
{ {
scalar sum = 0; scalar sum = 0;
if (Pstream::parRun()) if (UPstream::parRun())
{ {
if (UPstream::master(comm)) if (UPstream::master(comm))
{ {
// Add master value and all slaves // Add master value and all sub-procs
sum = localValue; sum = localValue;
for (const int slave : UPstream::subProcs(comm)) for (const int proci : UPstream::subProcs(comm))
{ {
scalar slaveValue; scalar procValue;
UIPstream::read UIPstream::read
( (
Pstream::commsTypes::blocking, UPstream::commsTypes::blocking,
slave, proci,
reinterpret_cast<char*>(&slaveValue), reinterpret_cast<char*>(&procValue),
sizeof(scalar), sizeof(scalar),
UPstream::msgType(), // tag UPstream::msgType(), // tag
comm // communicator comm // communicator
); );
sum += slaveValue; sum += procValue;
} }
// Send back to slaves // Send back
for (const int slave : UPstream::subProcs(comm)) for (const int proci : UPstream::subProcs(comm))
{ {
UOPstream::write UOPstream::write
( (
UPstream::commsTypes::blocking, UPstream::commsTypes::blocking,
slave, proci,
reinterpret_cast<const char*>(&sum), reinterpret_cast<const char*>(&sum),
sizeof(scalar), sizeof(scalar),
UPstream::msgType(), // tag UPstream::msgType(), // tag

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -52,27 +52,27 @@ void testMapDistribute()
// Generate random data. // Generate random data.
List<Tuple2<label, List<scalar>>> complexData(100); List<Tuple2<label, List<scalar>>> complexData(100);
forAll(complexData, i) for (auto& data : complexData)
{ {
complexData[i].first() = rndGen.position(0, Pstream::nProcs()-1); data.first() = rndGen.position(0, UPstream::nProcs()-1);
complexData[i].second().setSize(3); data.second().resize(3);
complexData[i].second()[0] = 1; data.second()[0] = 1;
complexData[i].second()[1] = 2; data.second()[1] = 2;
complexData[i].second()[2] = 3; data.second()[2] = 3;
} }
// Send all ones to processor indicated by .first() // Send all ones to processor indicated by .first()
// Count how many to send // Count how many to send
labelList nSend(Pstream::nProcs(), Zero); labelList nSend(UPstream::nProcs(), Foam::zero{});
forAll(complexData, i) for (const auto& data : complexData)
{ {
const label proci = complexData[i].first(); const label proci = data.first();
nSend[proci]++; nSend[proci]++;
} }
// Collect items to be sent // Collect items to be sent
labelListList sendMap(Pstream::nProcs()); labelListList sendMap(UPstream::nProcs());
forAll(sendMap, proci) forAll(sendMap, proci)
{ {
sendMap[proci].resize_nocopy(nSend[proci]); sendMap[proci].resize_nocopy(nSend[proci]);
@ -116,40 +116,31 @@ void testTransfer(const T& input)
{ {
T data = input; T data = input;
if (Pstream::master()) if (UPstream::master())
{ {
Perr<<"test transfer (" << (typeid(T).name()) << "): "; Perr<<"test transfer (" << (typeid(T).name()) << "): ";
perrInfo(data) << nl << endl; perrInfo(data) << nl << endl;
}
if (Pstream::master()) for (const int proci : UPstream::subProcs())
{
for (const int slave : Pstream::subProcs())
{ {
Perr<< "master receiving from slave " << slave << endl; Perr<< "master receiving from proc:" << proci << endl;
IPstream fromSlave(Pstream::commsTypes::blocking, slave); IPstream::recv(data, proci);
fromSlave >> data;
perrInfo(data) << endl; perrInfo(data) << endl;
} }
for (const int slave : Pstream::subProcs()) for (const int proci : UPstream::subProcs())
{ {
Perr<< "master sending to slave " << slave << endl; Perr<< "master sending to proc:" << proci << endl;
OPstream toSlave(Pstream::commsTypes::blocking, slave); OPstream::bsend(data, proci);
toSlave << data;
} }
} }
else else
{ {
{ Perr<< "proc sending to master" << endl;
Perr<< "slave sending to master " << Pstream::masterNo() << endl; OPstream::bsend(data, UPstream::masterNo());
OPstream toMaster(Pstream::commsTypes::blocking, Pstream::masterNo());
toMaster << data;
}
Perr<< "slave receiving from master " << Pstream::masterNo() << endl; Perr<< "proc receiving from master" << endl;
IPstream fromMaster(Pstream::commsTypes::blocking, Pstream::masterNo()); IPstream::recv(data, UPstream::masterNo());
fromMaster >> data;
perrInfo(data) << endl; perrInfo(data) << endl;
} }
} }
@ -160,49 +151,31 @@ void testTokenized(const T& data)
{ {
token tok; token tok;
if (Pstream::master()) if (UPstream::master())
{ {
Perr<<"test tokenized \"" << data << "\"" << nl << endl; Perr<< "test tokenized \"" << data << "\"" << nl << endl;
}
if (Pstream::master()) for (const int proci : UPstream::subProcs())
{
for (const int slave : Pstream::subProcs())
{ {
Perr<< "master receiving from slave " << slave << endl; Perr<< "master receiving from proc:" << proci << endl;
IPstream fromSlave(Pstream::commsTypes::blocking, slave); IPstream::recv(tok, proci);
fromSlave >> tok;
Perr<< tok.info() << endl; Perr<< tok.info() << endl;
} }
for (const int slave : Pstream::subProcs()) for (const int proci : UPstream::subProcs())
{ {
Perr<< "master sending to slave " << slave << endl; Perr<< "master sending to proc:" << proci << endl;
OPstream toSlave(Pstream::commsTypes::blocking, slave); OPstream::bsend(tok, proci);
toSlave << data;
} }
} }
else else
{ {
{ Perr<< "proc sending to master" << endl;
Perr<< "slave sending to master " << Pstream::masterNo() << endl; OPstream::bsend(tok, UPstream::masterNo());
OPstream toMaster
(
Pstream::commsTypes::blocking,
Pstream::masterNo()
);
toMaster << data; Perr<< "proc receiving from master" << endl;
} IPstream::recv(tok, UPstream::masterNo());
Perr<< "slave receiving from master " << Pstream::masterNo() << endl;
IPstream fromMaster
(
Pstream::commsTypes::blocking,
Pstream::masterNo()
);
fromMaster >> tok;
Perr<< tok.info() << endl; Perr<< tok.info() << endl;
} }
} }
@ -212,12 +185,14 @@ void testTokenized(const T& data)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::noCheckProcessorDirectories();
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
testMapDistribute(); testMapDistribute();
if (!Pstream::parRun()) if (!UPstream::parRun())
{ {
Info<< "\nWarning: not parallel - skipping further tests\n" << endl; Info<< "\nWarning: not parallel - skipping further tests\n" << endl;
return 0; return 0;

View File

@ -51,7 +51,7 @@ void printConnection(Ostream& os, const label proci, const labelUList& below)
// The number of receives - as per gatherList (v2112) // The number of receives - as per gatherList (v2112)
void printRecvCount_gatherList void printRecvCount_gatherList
( (
const List<UPstream::commsStruct>& comms, const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
) )
{ {
@ -91,7 +91,7 @@ void printRecvCount_gatherList
// The number of sends - as per scatterList (v2112) // The number of sends - as per scatterList (v2112)
void printSendCount_scatterList void printSendCount_scatterList
( (
const List<UPstream::commsStruct>& comms, const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
) )
{ {
@ -131,7 +131,7 @@ void printSendCount_scatterList
// Transmission widths (contiguous data) // Transmission widths (contiguous data)
void printWidths void printWidths
( (
const List<UPstream::commsStruct>& comms, const UList<UPstream::commsStruct>& comms,
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
) )
{ {

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2021-2023 OpenCFD Ltd. Copyright (C) 2021-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -71,6 +71,33 @@ public:
const label comm = UPstream::worldComm, const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
); );
// Static Functions
//- Receive and deserialize a value.
//- Uses \c operator>> for de-serialization
template<class Type>
static void recv
(
Type& value,
const int fromProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
IPstream is
(
UPstream::commsTypes::scheduled,
fromProcNo,
0, // bufSize
tag,
comm,
fmt
);
is >> value;
}
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation Copyright (C) 2011-2013 OpenFOAM Foundation
Copyright (C) 2021-2023 OpenCFD Ltd. Copyright (C) 2021-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -71,6 +71,73 @@ public:
const label comm = UPstream::worldComm, const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
); );
// Static Functions
//- Serialize a value and send (buffered/blocking or standard mode).
//- Uses \c operator<< for serialization
template<class Type>
static void send
(
const Type& value,
//! blocking or scheduled only!
const UPstream::commsTypes commsType,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream os(commsType, toProcNo, 0, tag, comm, fmt);
os << value;
}
//- Serialize a value and send (buffered/blocking mode).
//- Uses \c operator<< for serialization
template<class Type>
static void bsend
(
const Type& value,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream::send
(
value,
UPstream::commsTypes::blocking,
toProcNo,
tag,
comm,
fmt
);
}
//- Serialize a value and send (standard mode).
//- Uses \c operator<< for serialization
template<class Type>
static void send
(
const Type& value,
const int toProcNo,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm,
IOstreamOption::streamFormat fmt = IOstreamOption::BINARY
)
{
OPstream::send
(
value,
UPstream::commsTypes::scheduled,
toProcNo,
tag,
comm,
fmt
);
}
}; };

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd. Copyright (C) 2016-2024 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -170,7 +170,7 @@ public:
// Gather/combine data // Gather/combine data
// Inplace combine values from processors. // Inplace combine values from processors.
// (Uses construct from Istream instead of <<) // (Uses construct from Istream instead of \c << operator)
//- Gather data, applying \c cop to inplace combine \c value //- Gather data, applying \c cop to inplace combine \c value
//- from different processors. //- from different processors.
@ -178,6 +178,7 @@ public:
template<class T, class CombineOp> template<class T, class CombineOp>
static void combineGather static void combineGather
( (
//! [in,out]
T& value, T& value,
const CombineOp& cop, const CombineOp& cop,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
@ -193,6 +194,7 @@ public:
template<class T, class CombineOp> template<class T, class CombineOp>
static void combineReduce static void combineReduce
( (
//! [in,out]
T& value, T& value,
const CombineOp& cop, const CombineOp& cop,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
@ -220,7 +222,8 @@ public:
template<class T, class CombineOp> template<class T, class CombineOp>
static void listCombineGather static void listCombineGather
( (
List<T>& values, //! [in,out]
UList<T>& values,
const CombineOp& cop, const CombineOp& cop,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
@ -232,6 +235,7 @@ public:
template<class T, class CombineOp> template<class T, class CombineOp>
static void listCombineReduce static void listCombineReduce
( (
//! [in,out] - List (not UList) due to broadcast()
List<T>& values, List<T>& values,
const CombineOp& cop, const CombineOp& cop,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
@ -242,6 +246,7 @@ public:
template<class T, class CombineOp> template<class T, class CombineOp>
static void listCombineAllGather static void listCombineAllGather
( (
//! [in,out] - List (not UList) due to broadcast()
List<T>& values, List<T>& values,
const CombineOp& cop, const CombineOp& cop,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
@ -305,8 +310,9 @@ public:
template<class T> template<class T>
static void gatherList static void gatherList
( (
const List<commsStruct>& comms, const UList<commsStruct>& comms,
List<T>& values, //! [in,out]
UList<T>& values,
const int tag, const int tag,
const label comm const label comm
); );
@ -316,7 +322,8 @@ public:
template<class T> template<class T>
static void gatherList static void gatherList
( (
List<T>& values, //! [in,out]
UList<T>& values,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
); );
@ -328,73 +335,35 @@ public:
template<class T> template<class T>
static void allGatherList static void allGatherList
( (
List<T>& values, //! [in,out]
UList<T>& values,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
); );
// Scatter // Scatter
//- Broadcast data //- Inverse of gatherList.
template<class T> //- Uses the specified communication schedule.
FOAM_DEPRECATED_FOR(2024-01, "broadcast()") template<class T>
static void scatter static void scatterList
( (
T& value, const UList<commsStruct>& comms,
const int tag = UPstream::msgType(), //!< ignored UList<T>& values,
const label comm = UPstream::worldComm const int tag,
); const label comm
);
//- Broadcast data //- Inverse of gatherList.
template<class T> //- Uses linear/tree communication.
FOAM_DEPRECATED_FOR(2024-01, "broadcast()") template<class T>
static void combineScatter static void scatterList
( (
T& value, UList<T>& values,
const int tag = UPstream::msgType(), //!< ignored const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm const label comm = UPstream::worldComm
); );
//- Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "broadcast()")
static void listCombineScatter
(
List<T>& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
);
//- Broadcast data
template<class Container>
FOAM_DEPRECATED_FOR(2024-01, "broadcast()")
static void mapCombineScatter
(
Container& values,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
);
//- Scatter data. Reverse of gatherList
template<class T>
static void scatterList
(
const List<commsStruct>& comms,
List<T>& values,
const int tag,
const label comm
);
//- Like above but switches between linear/tree communication
template<class T>
static void scatterList
(
List<T>& values,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
// Exchange // Exchange
@ -573,6 +542,61 @@ public:
const label comm, const label comm,
const bool wait = true //!< (ignored) const bool wait = true //!< (ignored)
); );
// Housekeeping
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void scatter
(
T& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void combineScatter
(
T& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class T>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void listCombineScatter
(
List<T>& value,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(value, comm);
}
//- \deprecated(2024-01) Broadcast data
template<class Container>
FOAM_DEPRECATED_FOR(2024-01, "Pstream::broadcast()")
static void mapCombineScatter
(
Container& values,
const int tag = UPstream::msgType(), //!< ignored
const label comm = UPstream::worldComm
)
{
Pstream::broadcast(values, comm);
}
}; };

View File

@ -148,7 +148,11 @@ namespace Foam
//- Return a broadcasted value (uses a copy internally) //- Return a broadcasted value (uses a copy internally)
template<class Type> template<class Type>
Type returnBroadcast(const Type& value, const label comm) Type returnBroadcast
(
const Type& value,
const label comm = UPstream::worldComm
)
{ {
Type work(value); Type work(value);
Pstream::broadcast(work, comm); Pstream::broadcast(work, comm);

View File

@ -107,7 +107,7 @@ void Foam::Pstream::combineGather
} }
// Send up value // Send up value
if (myComm.above() != -1) if (myComm.above() >= 0)
{ {
if (debug & 2) if (debug & 2)
{ {
@ -166,7 +166,7 @@ void Foam::Pstream::combineReduce
template<class T, class CombineOp> template<class T, class CombineOp>
void Foam::Pstream::listCombineGather void Foam::Pstream::listCombineGather
( (
List<T>& values, UList<T>& values,
const CombineOp& cop, const CombineOp& cop,
const int tag, const int tag,
const label comm const label comm
@ -233,7 +233,7 @@ void Foam::Pstream::listCombineGather
} }
// Send up values // Send up values
if (myComm.above() != -1) if (myComm.above() >= 0)
{ {
if (debug & 2) if (debug & 2)
{ {
@ -349,7 +349,7 @@ void Foam::Pstream::mapCombineGather
} }
// Send up values // Send up values
if (myComm.above() != -1) if (myComm.above() >= 0)
{ {
if (debug & 2) if (debug & 2)
{ {

View File

@ -26,7 +26,7 @@ License
Description Description
Gather data from all processors onto single processor according to some Gather data from all processors onto single processor according to some
communication schedule (usually linear-to-master or tree-to-master). communication schedule (usually tree-to-master).
The gathered data will be a single value constructed from the values The gathered data will be a single value constructed from the values
on individual processors using a user-specified operator. on individual processors using a user-specified operator.
@ -88,7 +88,7 @@ void Foam::Pstream::gather
} }
// Send up value // Send up value
if (myComm.above() != -1) if (myComm.above() >= 0)
{ {
if (is_contiguous<T>::value) if (is_contiguous<T>::value)
{ {

View File

@ -26,7 +26,7 @@ License
Description Description
Gather data from all processors onto single processor according to some Gather data from all processors onto single processor according to some
communication schedule (usually linear-to-master or tree-to-master). communication schedule (usually 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)].
@ -45,24 +45,27 @@ Description
template<class T> template<class T>
void Foam::Pstream::gatherList void Foam::Pstream::gatherList
( (
const List<UPstream::commsStruct>& comms, const UList<UPstream::commsStruct>& comms,
List<T>& values, UList<T>& values,
const int tag, const int tag,
const label comm const label comm
) )
{ {
if (!comms.empty() && UPstream::is_parallel(comm)) if (!comms.empty() && UPstream::is_parallel(comm))
{ {
if (values.size() < UPstream::nProcs(comm)) const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
if (values.size() < numProc)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "List of values is too small:" << values.size() << "List of values:" << values.size()
<< " vs numProcs:" << UPstream::nProcs(comm) << nl << " < numProcs:" << numProc << nl
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
// My communication order // My communication order
const auto& myComm = comms[UPstream::myProcNo(comm)]; const auto& myComm = comms[myProci];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
for (const label belowID : myComm.below()) for (const label belowID : myComm.below())
@ -127,21 +130,21 @@ void Foam::Pstream::gatherList
// 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() >= 0)
{ {
const labelList& belowLeaves = myComm.allBelow(); const labelList& belowLeaves = myComm.allBelow();
if (debug & 2) if (debug & 2)
{ {
Pout<< " sending to " << myComm.above() Pout<< " sending to " << myComm.above()
<< " data from me:" << UPstream::myProcNo(comm) << " data from me:" << myProci
<< " data:" << values[UPstream::myProcNo(comm)] << endl; << " data:" << values[myProci] << endl;
} }
if (is_contiguous<T>::value) if (is_contiguous<T>::value)
{ {
List<T> sending(belowLeaves.size() + 1); List<T> sending(belowLeaves.size() + 1);
sending[0] = values[UPstream::myProcNo(comm)]; sending[0] = values[myProci];
forAll(belowLeaves, leafI) forAll(belowLeaves, leafI)
{ {
@ -168,7 +171,7 @@ void Foam::Pstream::gatherList
tag, tag,
comm comm
); );
toAbove << values[UPstream::myProcNo(comm)]; toAbove << values[myProci];
for (const label leafID : belowLeaves) for (const label leafID : belowLeaves)
{ {
@ -189,8 +192,8 @@ void Foam::Pstream::gatherList
template<class T> template<class T>
void Foam::Pstream::scatterList void Foam::Pstream::scatterList
( (
const List<UPstream::commsStruct>& comms, const UList<UPstream::commsStruct>& comms,
List<T>& values, UList<T>& values,
const int tag, const int tag,
const label comm const label comm
) )
@ -201,19 +204,22 @@ void Foam::Pstream::scatterList
if (!comms.empty() && UPstream::is_parallel(comm)) if (!comms.empty() && UPstream::is_parallel(comm))
{ {
if (values.size() < UPstream::nProcs(comm)) const label myProci = UPstream::myProcNo(comm);
const label numProc = UPstream::nProcs(comm);
if (values.size() < numProc)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "List of values is too small:" << values.size() << "List of values:" << values.size()
<< " vs numProcs:" << UPstream::nProcs(comm) << nl << " < numProcs:" << numProc << nl
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
// My communication order // My communication order
const auto& myComm = comms[UPstream::myProcNo(comm)]; const auto& myComm = comms[myProci];
// Receive from up // Receive from up
if (myComm.above() != -1) if (myComm.above() >= 0)
{ {
const labelList& notBelowLeaves = myComm.allNotBelow(); const labelList& notBelowLeaves = myComm.allNotBelow();
@ -318,7 +324,7 @@ void Foam::Pstream::scatterList
template<class T> template<class T>
void Foam::Pstream::gatherList void Foam::Pstream::gatherList
( (
List<T>& values, UList<T>& values,
const int tag, const int tag,
const label comm const label comm
) )
@ -337,7 +343,7 @@ void Foam::Pstream::gatherList
template<class T> template<class T>
void Foam::Pstream::scatterList void Foam::Pstream::scatterList
( (
List<T>& values, UList<T>& values,
const int tag, const int tag,
const label comm const label comm
) )
@ -355,7 +361,7 @@ void Foam::Pstream::scatterList
template<class T> template<class T>
void Foam::Pstream::allGatherList void Foam::Pstream::allGatherList
( (
List<T>& values, UList<T>& values,
const int tag, const int tag,
const label comm const label comm
) )

View File

@ -1202,6 +1202,7 @@ public:
//- Process index of first sub-process //- Process index of first sub-process
// \deprecated(2020-09) use subProcs() method instead // \deprecated(2020-09) use subProcs() method instead
FOAM_DEPRECATED_FOR(2020-09, "subProcs() method")
static constexpr int firstSlave() noexcept static constexpr int firstSlave() noexcept
{ {
return 1; return 1;
@ -1209,6 +1210,7 @@ public:
//- Process index of last sub-process //- Process index of last sub-process
// \deprecated(2020-09) use subProcs() method instead // \deprecated(2020-09) use subProcs() method instead
FOAM_DEPRECATED_FOR(2020-09, "subProcs() or allProcs() method")
static int lastSlave(const label communicator = worldComm) static int lastSlave(const label communicator = worldComm)
{ {
return nProcs(communicator) - 1; return nProcs(communicator) - 1;

View File

@ -290,7 +290,7 @@ Foam::globalIndex::bin
if (!globalIds.empty()) if (!globalIds.empty())
{ {
labelList& binOffsets = bins.offsets(); labelList& binOffsets = bins.offsets();
binOffsets.resize(offsets.size(), Zero); binOffsets.resize(offsets.size(), Foam::zero{});
labelList& binValues = bins.values(); labelList& binValues = bins.values();
binValues = UIndirectList<label>(globalIds, order); binValues = UIndirectList<label>(globalIds, order);
@ -372,7 +372,7 @@ void Foam::globalIndex::reset
// TBD: check for (proci >= 0) ? // TBD: check for (proci >= 0) ?
const auto proci = UPstream::myProcNo(comm); const auto proci = UPstream::myProcNo(comm);
counts.resize(len, Zero); counts.resize(len, Foam::zero{});
counts[proci] = localSize; counts[proci] = localSize;
} }

View File

@ -83,6 +83,14 @@ class globalIndex
DynamicList<label>& validBins DynamicList<label>& validBins
); );
// Cannot use non-blocking for non-contiguous data.
// template<class Type>
// inline static UPstream::commsTypes getCommsType
// (
// const UPstream::commsTypes preferred
// = UPstream::commsTypes::nonBlocking
// );
//- Report overflow at specified (non-negative) index //- Report overflow at specified (non-negative) index
static void reportOverflowAndExit static void reportOverflowAndExit
( (
@ -187,7 +195,7 @@ public:
inline label length() const noexcept; inline label length() const noexcept;
//- Global sum of localSizes. Same as totalSize() //- Global sum of localSizes. Same as totalSize()
FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - less ambiguous") FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - unambiguous")
inline label size() const; inline label size() const;
//- The span size covered by the offsets, zero if empty //- The span size covered by the offsets, zero if empty
@ -722,10 +730,11 @@ public:
//- Inplace collect data in processor order on master //- Inplace collect data in processor order on master
//- (in serial: a no-op). //- (in serial: a no-op).
// Communication with default/specified communicator, message tag. // Communication with default/specified communicator, message tag.
// After the gather, the field is zero-sized on the slaves. // After the gather, the field is zero-sized on non-master.
template<class Type> template<class Type>
void gatherInplace void gatherInplace
( (
//! [in,out]
List<Type>& fld, List<Type>& fld,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking, const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -737,12 +746,11 @@ public:
// Communication with default/specified communicator. // Communication with default/specified communicator.
// \attention The nProcs for globalIndex and communicator // \attention The nProcs for globalIndex and communicator
// must match!! // must match!!
//
// The allData is output (master), zero-sized on non-master
template<class Type, class OutputContainer = List<Type>> template<class Type, class OutputContainer = List<Type>>
void mpiGather void mpiGather
( (
const UList<Type>& sendData, const UList<Type>& sendData,
//! [out] output on master, zero-sized on non-master
OutputContainer& allData, OutputContainer& allData,
const label comm = UPstream::worldComm, //!< communicator const label comm = UPstream::worldComm, //!< communicator
@ -780,6 +788,7 @@ public:
template<class Type> template<class Type>
void mpiGatherInplace void mpiGatherInplace
( (
//! [in,out]
List<Type>& fld, List<Type>& fld,
const label comm = UPstream::worldComm, //!< communicator const label comm = UPstream::worldComm, //!< communicator
@ -833,6 +842,7 @@ public:
template<class Type> template<class Type>
static void mpiGatherInplaceOp static void mpiGatherInplaceOp
( (
//! [in,out]
List<Type>& fld, List<Type>& fld,
const label comm = UPstream::worldComm, //!< communicator const label comm = UPstream::worldComm, //!< communicator
@ -844,12 +854,11 @@ public:
//- Collect data in processor order on master //- Collect data in processor order on master
//- (in serial: performs a simple copy). //- (in serial: performs a simple copy).
// Communication with default/specified communicator, message tag. // Communication with default/specified communicator, message tag.
//
// The allFld is output (master), zero-sized on non-master
template<class Type> template<class Type>
static void gatherOp static void gatherOp
( (
const UList<Type>& sendData, const UList<Type>& sendData,
//! [out] output on master, zero-sized on non-master
List<Type>& allData, List<Type>& allData,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking, const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -859,12 +868,11 @@ public:
//- Collect data in processor order on master //- Collect data in processor order on master
//- (in serial: performs a simple copy). //- (in serial: performs a simple copy).
// Communication with default/specified communicator, message tag. // Communication with default/specified communicator, message tag.
//
// The allFld is output (master), zero-sized on non-master
template<class Type, class Addr> template<class Type, class Addr>
static void gatherOp static void gatherOp
( (
const IndirectListBase<Type, Addr>& sendData, const IndirectListBase<Type, Addr>& sendData,
//! [out] output on master, zero-sized on non-master
List<Type>& allData, List<Type>& allData,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking, const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,
@ -903,10 +911,11 @@ public:
//- (in serial: a no-op). //- (in serial: a no-op).
// Communication with default/specified communicator, message tag. // Communication with default/specified communicator, message tag.
// //
// After the gather, the field is zero-sized on the slaves. // After the gather, the field is zero-sized on non-master.
template<class Type> template<class Type>
static void gatherInplaceOp static void gatherInplaceOp
( (
//! [in,out]
List<Type>& fld, List<Type>& fld,
const int tag = UPstream::msgType(), const int tag = UPstream::msgType(),
const UPstream::commsTypes = UPstream::commsTypes::nonBlocking, const UPstream::commsTypes = UPstream::commsTypes::nonBlocking,

View File

@ -30,6 +30,25 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// Cannot use non-blocking for non-contiguous data.
// template<class Type>
// inline Foam::UPstream::commsTypes getCommsType
// (
// const UPstream::commsTypes preferred
// )
// {
// return
// (
// (
// !is_contiguous<Type>::value
// && UPstream::commsTypes::nonBlocking == preferred
// )
// ? UPstream::commsTypes::scheduled
// : preferred
// );
// }
template<class Addr> template<class Addr>
Foam::labelList Foam::labelList
Foam::globalIndex::calcOffsets Foam::globalIndex::calcOffsets
@ -115,8 +134,7 @@ void Foam::globalIndex::gatherValues
{ {
// low-level: no parRun guard // low-level: no parRun guard
// Automatically change from nonBlocking to scheduled for // Cannot use non-blocking for non-contiguous data.
// non-contiguous data.
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
@ -202,8 +220,7 @@ void Foam::globalIndex::gather
{ {
// low-level: no parRun guard // low-level: no parRun guard
// Automatically change from nonBlocking to scheduled for // Cannot use non-blocking for non-contiguous data.
// non-contiguous data.
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
@ -322,8 +339,7 @@ void Foam::globalIndex::gather
return; return;
} }
// Automatically change from nonBlocking to scheduled for // Cannot use non-blocking for non-contiguous data.
// non-contiguous data.
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (
@ -907,8 +923,7 @@ void Foam::globalIndex::scatter
{ {
// low-level: no parRun guard // low-level: no parRun guard
// Automatically change from nonBlocking to scheduled for // Cannot use non-blocking for non-contiguous data.
// non-contiguous data.
const UPstream::commsTypes commsType = const UPstream::commsTypes commsType =
( (
( (