mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add Pstream::broadcastList()
- broadcasts list contiguous content as a two-step process:
1. broadcast the size, and resize for receiver list
2. broadcast contiguous contents (if non-empty)
This avoids serialization/de-serialization memory overhead but at
the expense of an additional broadcast call.
The trade-off of the extra broadcast of the size will be less
important than avoiding a memory peak for large contiguous mesh data.
REVERT: unstable MPI_Mprobe/MPI_Mrecv on intelmpi + PMI-2 (#2796)
- partial revert of commit c6f528588b, for NBX implementation.
Not yet flagged as causing errors here, but eliminated for
consistency.
This commit is contained in:
@ -183,9 +183,7 @@ int main(int argc, char *argv[])
|
||||
Pout<<"recv: " << flatOutput(recv) << endl;
|
||||
}
|
||||
|
||||
// MPI barrier
|
||||
bool barrier = true;
|
||||
Pstream::broadcast(barrier);
|
||||
UPstream::barrier(UPstream::worldComm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ int main(int argc, char *argv[])
|
||||
labelPair inOut;
|
||||
pointField allCcs(globalNumbering.gather(mesh.cellCentres()));
|
||||
inOut[0] = allCcs.size();
|
||||
Pstream::broadcast(allCcs);
|
||||
Pstream::broadcastList(allCcs);
|
||||
inOut[1] = allCcs.size();
|
||||
Pout<< " " << inOut << endl;
|
||||
|
||||
|
||||
@ -102,9 +102,8 @@ public:
|
||||
//- Broadcast buffer content to all processes in communicator.
|
||||
using UPstream::broadcast;
|
||||
|
||||
//- Broadcast content (contiguous or non-contiguous)
|
||||
//- to all processes in communicator.
|
||||
// For \b non-parallel : do nothing.
|
||||
//- Broadcast content (contiguous or non-contiguous) to all
|
||||
//- communicator ranks. Does nothing in \b non-parallel.
|
||||
template<class Type>
|
||||
static void broadcast
|
||||
(
|
||||
@ -112,11 +111,22 @@ public:
|
||||
const label comm = UPstream::worldComm
|
||||
);
|
||||
|
||||
//- Broadcast multiple items to all processes in communicator.
|
||||
// For \b non-parallel : do nothing.
|
||||
//- Broadcast multiple items to all communicator ranks.
|
||||
//- Does nothing in \b non-parallel.
|
||||
template<class Type, class... Args>
|
||||
static void broadcasts(const label comm, Type& arg1, Args&&... args);
|
||||
|
||||
//- Broadcast list content (contiguous or non-contiguous) to all
|
||||
//- communicator ranks. Does nothing in \b non-parallel.
|
||||
// For contiguous list data, this avoids serialization overhead,
|
||||
// but at the expense of an additional broadcast call.
|
||||
template<class ListType>
|
||||
static void broadcastList
|
||||
(
|
||||
ListType& list,
|
||||
const label comm = UPstream::worldComm
|
||||
);
|
||||
|
||||
|
||||
// Gather
|
||||
|
||||
|
||||
@ -80,4 +80,61 @@ void Foam::Pstream::broadcasts(const label comm, Type& arg1, Args&&... args)
|
||||
}
|
||||
|
||||
|
||||
template<class ListType>
|
||||
void Foam::Pstream::broadcastList(ListType& list, const label comm)
|
||||
{
|
||||
if (is_contiguous<typename ListType::value_type>::value)
|
||||
{
|
||||
// List data are contiguous
|
||||
// 1. broadcast the size
|
||||
// 2. resize for receiver list
|
||||
// 3. broadcast contiguous contents
|
||||
|
||||
if (UPstream::is_parallel(comm))
|
||||
{
|
||||
label len(list.size());
|
||||
|
||||
UPstream::broadcast
|
||||
(
|
||||
reinterpret_cast<char*>(&len),
|
||||
sizeof(label),
|
||||
comm,
|
||||
UPstream::masterNo()
|
||||
);
|
||||
|
||||
if (UPstream::is_subrank(comm))
|
||||
{
|
||||
list.resize_nocopy(len);
|
||||
}
|
||||
|
||||
if (len)
|
||||
{
|
||||
UPstream::broadcast
|
||||
(
|
||||
list.data_bytes(),
|
||||
list.size_bytes(),
|
||||
comm,
|
||||
UPstream::masterNo()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (UPstream::is_parallel(comm))
|
||||
{
|
||||
// List data are non-contiguous - serialize/de-serialize
|
||||
|
||||
if (UPstream::master(comm))
|
||||
{
|
||||
OPBstream os(UPstream::masterNo(), comm);
|
||||
os << list;
|
||||
}
|
||||
else // UPstream::is_subrank(comm)
|
||||
{
|
||||
IPBstream is(UPstream::masterNo(), comm);
|
||||
is >> list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -613,19 +613,6 @@ void Foam::PstreamDetail::allToAllConsensus
|
||||
int flag = 0;
|
||||
MPI_Status status;
|
||||
|
||||
#if defined(MPI_VERSION) && (MPI_VERSION >= 3)
|
||||
// MPI-3 : eg, openmpi-1.7 (2013) and later
|
||||
MPI_Message message;
|
||||
MPI_Improbe
|
||||
(
|
||||
MPI_ANY_SOURCE,
|
||||
tag,
|
||||
PstreamGlobals::MPICommunicators_[comm],
|
||||
&flag,
|
||||
&message,
|
||||
&status
|
||||
);
|
||||
#else
|
||||
MPI_Iprobe
|
||||
(
|
||||
MPI_ANY_SOURCE,
|
||||
@ -634,7 +621,6 @@ void Foam::PstreamDetail::allToAllConsensus
|
||||
&flag,
|
||||
&status
|
||||
);
|
||||
#endif
|
||||
|
||||
if (flag)
|
||||
{
|
||||
@ -654,17 +640,6 @@ void Foam::PstreamDetail::allToAllConsensus
|
||||
|
||||
// Regular blocking receive [the data are small]
|
||||
|
||||
#if defined(MPI_VERSION) && (MPI_VERSION >= 3)
|
||||
// MPI-3 : eg, openmpi-1.7 (2013) and later
|
||||
MPI_Mrecv
|
||||
(
|
||||
&recvData[proci],
|
||||
count, // count=1 (see above)
|
||||
datatype,
|
||||
&message,
|
||||
MPI_STATUS_IGNORE
|
||||
);
|
||||
#else
|
||||
MPI_Recv
|
||||
(
|
||||
&recvData[proci],
|
||||
@ -675,7 +650,6 @@ void Foam::PstreamDetail::allToAllConsensus
|
||||
PstreamGlobals::MPICommunicators_[comm],
|
||||
MPI_STATUS_IGNORE
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (barrier_active)
|
||||
|
||||
Reference in New Issue
Block a user