ENH: add node-based gather(), listGather(), mapGather()
This commit is contained in:
parent
7b0ab0dbb3
commit
c4b261c615
@ -155,6 +155,19 @@ public:
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Implementation: gather (reduce) single element data onto
|
||||
//- UPstream::masterNo() using a topo algorithm.
|
||||
// \returns True if topo algorithm was applied
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
static bool gather_topo_algorithm
|
||||
(
|
||||
//! [in,out]
|
||||
T& value,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Gather (reduce) data, applying \c bop to combine \c value
|
||||
//- from different processors. The basis for Foam::reduce().
|
||||
// A no-op for non-parallel.
|
||||
@ -256,6 +269,19 @@ public:
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Implementation: gather (reduce) list element data onto
|
||||
//- UPstream::masterNo() using a topo algorithm.
|
||||
// \returns True if topo algorithm was applied
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
static bool listGather_topo_algorithm
|
||||
(
|
||||
//! [in,out]
|
||||
UList<T>& values,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Gather (reduce) list elements,
|
||||
//- applying \c bop to each list element
|
||||
//
|
||||
@ -337,6 +363,18 @@ public:
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Implementation: gather (reduce) Map/HashTable containers onto
|
||||
//- UPstream::masterNo() using a topo algorithm.
|
||||
// \returns True if topo algorithm was applied
|
||||
template<class Container, class BinaryOp, bool InplaceMode>
|
||||
static bool mapGather_topo_algorithm
|
||||
(
|
||||
Container& values,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const int communicator
|
||||
);
|
||||
|
||||
//- Gather (reduce) Map/HashTable containers,
|
||||
//- applying \c bop to combine entries from different processors.
|
||||
//
|
||||
|
@ -147,6 +147,59 @@ void Foam::Pstream::gather_algorithm
|
||||
}
|
||||
|
||||
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
bool Foam::Pstream::gather_topo_algorithm
|
||||
(
|
||||
T& value,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const int communicator
|
||||
)
|
||||
{
|
||||
const bool withTopo =
|
||||
(
|
||||
UPstream::is_parallel(communicator)
|
||||
&& UPstream::usingTopoControl(UPstream::topoControls::combine)
|
||||
&& UPstream::usingNodeComms(communicator)
|
||||
);
|
||||
|
||||
if (withTopo)
|
||||
{
|
||||
// Topological reduce
|
||||
// - linear for local-node (assume communication is fast)
|
||||
// - tree for inter-node (no assumption about speed)
|
||||
|
||||
using control = std::pair<int, bool>;
|
||||
|
||||
for
|
||||
(
|
||||
auto [subComm, linear] :
|
||||
{
|
||||
// 1: within node
|
||||
control{ UPstream::commLocalNode(), true },
|
||||
// 2: between nodes
|
||||
control{ UPstream::commInterNode(), false }
|
||||
}
|
||||
)
|
||||
{
|
||||
if (UPstream::is_parallel(subComm))
|
||||
{
|
||||
Pstream::gather_algorithm<T, BinaryOp, InplaceMode>
|
||||
(
|
||||
UPstream::whichCommunication(subComm, linear),
|
||||
value,
|
||||
bop,
|
||||
tag,
|
||||
subComm
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return withTopo;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
void Foam::Pstream::gather
|
||||
(
|
||||
@ -172,7 +225,16 @@ void Foam::Pstream::gather
|
||||
communicator
|
||||
);
|
||||
}
|
||||
else
|
||||
else if
|
||||
(
|
||||
!Pstream::gather_topo_algorithm<T, BinaryOp, InplaceMode>
|
||||
(
|
||||
value,
|
||||
bop,
|
||||
tag,
|
||||
communicator
|
||||
)
|
||||
)
|
||||
{
|
||||
// Communication order
|
||||
const auto& commOrder = UPstream::whichCommunication(communicator);
|
||||
@ -337,6 +399,59 @@ void Foam::Pstream::listGather_algorithm
|
||||
}
|
||||
|
||||
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
bool Foam::Pstream::listGather_topo_algorithm
|
||||
(
|
||||
UList<T>& values,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const label communicator
|
||||
)
|
||||
{
|
||||
const bool withTopo =
|
||||
(
|
||||
UPstream::is_parallel(communicator) && !values.empty()
|
||||
&& UPstream::usingTopoControl(UPstream::topoControls::combine)
|
||||
&& UPstream::usingNodeComms(communicator)
|
||||
);
|
||||
|
||||
if (withTopo)
|
||||
{
|
||||
// Topological reduce
|
||||
// - linear for local-node (assume communication is fast)
|
||||
// - tree for inter-node (no assumption about speed)
|
||||
|
||||
using control = std::pair<int, bool>;
|
||||
|
||||
for
|
||||
(
|
||||
auto [subComm, linear] :
|
||||
{
|
||||
// 1: within node
|
||||
control{ UPstream::commLocalNode(), true },
|
||||
// 2: between nodes
|
||||
control{ UPstream::commInterNode(), false }
|
||||
}
|
||||
)
|
||||
{
|
||||
if (UPstream::is_parallel(subComm))
|
||||
{
|
||||
Pstream::listGather_algorithm<T, BinaryOp, InplaceMode>
|
||||
(
|
||||
UPstream::whichCommunication(subComm, linear),
|
||||
values,
|
||||
bop,
|
||||
tag,
|
||||
subComm
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return withTopo;
|
||||
}
|
||||
|
||||
|
||||
template<class T, class BinaryOp, bool InplaceMode>
|
||||
void Foam::Pstream::listGather
|
||||
(
|
||||
@ -373,7 +488,16 @@ void Foam::Pstream::listGather
|
||||
communicator
|
||||
);
|
||||
}
|
||||
else
|
||||
else if
|
||||
(
|
||||
!Pstream::listGather_topo_algorithm<T, BinaryOp, InplaceMode>
|
||||
(
|
||||
values,
|
||||
bop,
|
||||
tag,
|
||||
communicator
|
||||
)
|
||||
)
|
||||
{
|
||||
// Communication order
|
||||
const auto& commOrder = UPstream::whichCommunication(communicator);
|
||||
@ -548,6 +672,59 @@ void Foam::Pstream::mapGather_algorithm
|
||||
}
|
||||
|
||||
|
||||
template<class Container, class BinaryOp, bool InplaceMode>
|
||||
bool Foam::Pstream::mapGather_topo_algorithm
|
||||
(
|
||||
Container& values,
|
||||
BinaryOp bop,
|
||||
const int tag,
|
||||
const int communicator
|
||||
)
|
||||
{
|
||||
const bool withTopo =
|
||||
(
|
||||
UPstream::is_parallel(communicator)
|
||||
&& UPstream::usingTopoControl(UPstream::topoControls::mapGather)
|
||||
&& UPstream::usingNodeComms(communicator)
|
||||
);
|
||||
|
||||
if (withTopo)
|
||||
{
|
||||
// Topological reduce
|
||||
// - linear for local-node (assume communication is fast)
|
||||
// - tree for inter-node (no assumption about speed)
|
||||
|
||||
using control = std::pair<int, bool>;
|
||||
|
||||
for
|
||||
(
|
||||
auto [subComm, linear] :
|
||||
{
|
||||
// 1: within node
|
||||
control{ UPstream::commLocalNode(), true },
|
||||
// 2: between nodes
|
||||
control{ UPstream::commInterNode(), false }
|
||||
}
|
||||
)
|
||||
{
|
||||
if (UPstream::is_parallel(subComm))
|
||||
{
|
||||
Pstream::mapGather_algorithm<Container, BinaryOp, InplaceMode>
|
||||
(
|
||||
UPstream::whichCommunication(subComm, linear),
|
||||
values,
|
||||
bop,
|
||||
tag,
|
||||
subComm
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return withTopo;
|
||||
}
|
||||
|
||||
|
||||
template<class Container, class BinaryOp, bool InplaceMode>
|
||||
void Foam::Pstream::mapGather
|
||||
(
|
||||
@ -562,7 +739,16 @@ void Foam::Pstream::mapGather
|
||||
// Nothing to do
|
||||
return;
|
||||
}
|
||||
else
|
||||
else if
|
||||
(
|
||||
!Pstream::mapGather_topo_algorithm<Container, BinaryOp, InplaceMode>
|
||||
(
|
||||
values,
|
||||
bop,
|
||||
tag,
|
||||
communicator
|
||||
)
|
||||
)
|
||||
{
|
||||
// Communication order
|
||||
const auto& commOrder = UPstream::whichCommunication(communicator);
|
||||
|
Loading…
Reference in New Issue
Block a user