mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
COMP: native MPI reduce not triggered (fixes #2569)
- define returnReduce *after* defining all specializations for reduce
so that the compiler does not take the generic templated reduce.
ENH: add UPstream::reduceAnd, UPstream::reduceOr
- direct wrapper of MPI_LAND, MPI_LOR intrinsics
ENH: provide special purpose returnReduce for logical operations
- returnReduceAnd(bool), returnReduceOr(bool) as a inline wrappers
for returnReduce with andOp<bool>(), orOp<bool>() operators,
respectively.
These forms are more succinct and force casting of the parameter
into a bool. Using MPI bool operations allows vendor/hardware MPI
optimisations.
* Test for existence on any rank:
1. if (returnReduceOr(list.size()) { ... }
1b. if (returnReduceOr(!list.empty()) { ... }
2. if (returnReduce(bool(list.size(), orOp<bool>())) { ... }
3. if (returnReduce(list.size(), sumOp<label>()) != 0) { ... }
3b. if (returnReduce(list.size(), sumOp<label>()) > 0) { ... }
* Test for non-existence on all ranks:
1. if (returnReduceAnd(list.empty()) { ... }
1b. if (!returnReduceOr(list.size()) { ... }
2. if (returnReduce(list.empty(), andOp<bool>())) { ... }
3. if (returnReduce(list.size(), sumOp<label>()) == 0) { ... }
Notes:
Form 1. succinct
Form 2. may require explicit bool() for correct dispatch
Form 3. more expensive sumOp<label> just for testing size!
There are also some places using maxOp<label> instead of sumOp<label>
This commit is contained in:
@ -220,7 +220,7 @@ void Foam::Pstream::scatter(T& value, const int tag, const label comm)
|
||||
#ifndef Foam_Pstream_scatter_nobroadcast
|
||||
Pstream::broadcast(value, comm);
|
||||
#else
|
||||
scatter(UPstream::whichCommunication(comm), value, tag, comm);
|
||||
Pstream::scatter(UPstream::whichCommunication(comm), value, tag, comm);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -80,48 +80,13 @@ void reduce
|
||||
{
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
reduce(UPstream::whichCommunication(comm), value, bop, tag, comm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Reduce (copy) and return value
|
||||
template<class T, class BinaryOp>
|
||||
T returnReduce
|
||||
(
|
||||
const T& value,
|
||||
const BinaryOp& bop,
|
||||
const int tag = UPstream::msgType(),
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
T work(value);
|
||||
reduce(work, bop, tag, comm);
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
//- Reduce inplace (cf. MPI Allreduce)
|
||||
//- the sum of both value and count (for averaging)
|
||||
template<class T>
|
||||
void sumReduce
|
||||
(
|
||||
T& value,
|
||||
label& count,
|
||||
const int tag = UPstream::msgType(),
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
reduce(value, sumOp<T>(), tag, comm);
|
||||
reduce(count, sumOp<label>(), tag, comm);
|
||||
Foam::reduce(UPstream::whichCommunication(comm), value, bop, tag, comm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//- Reduce inplace (cf. MPI Allreduce)
|
||||
//- multiple values (identical size on all processes!)
|
||||
//- multiple values (same size on all processes!)
|
||||
template<class T, class BinaryOp>
|
||||
void reduce
|
||||
(
|
||||
@ -170,9 +135,9 @@ void reduce
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specialisations for bool
|
||||
// Special reductions for bool
|
||||
|
||||
//- Logical (and) reduction (cf. MPI AllReduce)
|
||||
//- Logical (and) inplace reduction. Uses UPstream::reduceAnd
|
||||
void reduce
|
||||
(
|
||||
bool& value,
|
||||
@ -181,7 +146,7 @@ void reduce
|
||||
const label comm = UPstream::worldComm
|
||||
);
|
||||
|
||||
//- Logical (or) reduction (cf. MPI AllReduce)
|
||||
//- Logical (or) inplace reduction. Uses UPstream::reduceOr
|
||||
void reduce
|
||||
(
|
||||
bool& value,
|
||||
@ -193,7 +158,7 @@ void reduce
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specialisations for common reduction types
|
||||
// Common reductions
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#define Pstream_CommonReductions(Native) \
|
||||
@ -225,7 +190,7 @@ void reduce \
|
||||
const label comm = UPstream::worldComm \
|
||||
); \
|
||||
\
|
||||
/*! \brief Reduce (sum) multiple Native values (identical size all procs!) */ \
|
||||
/*! \brief Reduce (sum) multiple Native values (same size all procs!) */ \
|
||||
void reduce \
|
||||
( \
|
||||
Native values[], \
|
||||
@ -249,31 +214,14 @@ inline void reduce \
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
// Floating-point reductions
|
||||
|
||||
#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 \
|
||||
); \
|
||||
Pstream_CommonReductions(Native); \
|
||||
\
|
||||
/*! \brief Non-blocking reduce (sum) single Native value. Sets request */ \
|
||||
void reduce \
|
||||
@ -297,12 +245,115 @@ void reduce \
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Pstream_CommonReductions(int32_t);
|
||||
Pstream_CommonReductions(int64_t);
|
||||
Pstream_CommonReductions(uint32_t);
|
||||
Pstream_CommonReductions(uint64_t);
|
||||
|
||||
Pstream_FloatReductions(float);
|
||||
Pstream_FloatReductions(double);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#undef Pstream_FloatReductions
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Reduce inplace (cf. MPI Allreduce)
|
||||
//- the sum of both value and count (for averaging)
|
||||
template<class T>
|
||||
void sumReduce
|
||||
(
|
||||
T& value,
|
||||
label& count,
|
||||
const int tag = UPstream::msgType(),
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
Foam::reduce(value, sumOp<T>(), tag, comm);
|
||||
Foam::reduce(count, sumOp<label>(), tag, comm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Floating-point sum-reduce
|
||||
|
||||
#undef Pstream_SumReduce
|
||||
#define Pstream_SumReduce(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 \
|
||||
);
|
||||
|
||||
|
||||
Pstream_SumReduce(float);
|
||||
Pstream_SumReduce(double);
|
||||
|
||||
#undef Pstream_SumReduce
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Convenience wrappers for some reduction operations
|
||||
// - defined after all specialisations are known
|
||||
|
||||
//- Perform reduction on a copy, using specified binary operation
|
||||
// \return the resulting value
|
||||
template<class T, class BinaryOp>
|
||||
T returnReduce
|
||||
(
|
||||
const T& value,
|
||||
const BinaryOp& bop,
|
||||
const int tag = UPstream::msgType(),
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
T work(value);
|
||||
Foam::reduce(work, bop, tag, comm);
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
//- Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd
|
||||
// \return the resulting value
|
||||
inline bool returnReduceAnd
|
||||
(
|
||||
const bool value,
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
bool work(value);
|
||||
UPstream::reduceAnd(work, comm);
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
//- Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr
|
||||
// \return the resulting value
|
||||
inline bool returnReduceOr
|
||||
(
|
||||
const bool value,
|
||||
const label comm = UPstream::worldComm
|
||||
)
|
||||
{
|
||||
bool work(value);
|
||||
UPstream::reduceOr(work, comm);
|
||||
return work;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
@ -712,6 +712,23 @@ public:
|
||||
);
|
||||
|
||||
|
||||
// Logical reductions
|
||||
|
||||
//- Logical (and) reduction (cf. MPI AllReduce)
|
||||
static void reduceAnd
|
||||
(
|
||||
bool& value,
|
||||
const label communicator = worldComm
|
||||
);
|
||||
|
||||
//- Logical (or) reduction (cf. MPI AllReduce)
|
||||
static void reduceOr
|
||||
(
|
||||
bool& value,
|
||||
const label communicator = worldComm
|
||||
);
|
||||
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Process index of first sub-process
|
||||
|
||||
@ -30,7 +30,14 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specialisations for bool
|
||||
// Special reductions for bool
|
||||
|
||||
void Foam::UPstream::reduceAnd(bool& value, const label comm)
|
||||
{}
|
||||
|
||||
void Foam::UPstream::reduceOr(bool& value, const label comm)
|
||||
{}
|
||||
|
||||
|
||||
void Foam::reduce
|
||||
(
|
||||
@ -53,7 +60,7 @@ void Foam::reduce
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specialisations for common reduction types
|
||||
// Common reductions
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#define Pstream_CommonReductions(Native) \
|
||||
@ -96,31 +103,14 @@ void Foam::reduce \
|
||||
{}
|
||||
|
||||
|
||||
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
|
||||
// Floating-point reductions
|
||||
|
||||
#undef Pstream_FloatReductions
|
||||
#define Pstream_FloatReductions(Native) \
|
||||
\
|
||||
void Foam::sumReduce \
|
||||
( \
|
||||
Native& value, \
|
||||
label& count, \
|
||||
const int tag, \
|
||||
const label comm \
|
||||
) \
|
||||
{} \
|
||||
Pstream_CommonReductions(Native); \
|
||||
\
|
||||
void Foam::reduce \
|
||||
( \
|
||||
@ -141,12 +131,32 @@ void Foam::reduce \
|
||||
const label comm, \
|
||||
label& requestID \
|
||||
) \
|
||||
{} \
|
||||
\
|
||||
void Foam::sumReduce \
|
||||
( \
|
||||
Native& value, \
|
||||
label& count, \
|
||||
const int tag, \
|
||||
const label comm \
|
||||
) \
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Pstream_CommonReductions(int32_t);
|
||||
Pstream_CommonReductions(int64_t);
|
||||
Pstream_CommonReductions(uint32_t);
|
||||
Pstream_CommonReductions(uint64_t);
|
||||
|
||||
Pstream_FloatReductions(float);
|
||||
Pstream_FloatReductions(double);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#undef Pstream_FloatReductions
|
||||
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include <mpi.h>
|
||||
#include <cinttypes>
|
||||
#include <cstring> // memmove
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@ License
|
||||
|
||||
#include <mpi.h>
|
||||
#include <cinttypes>
|
||||
#include <cstring> // memmove
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -34,7 +34,19 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specialisations for bool
|
||||
// Special reductions for bool
|
||||
|
||||
void Foam::UPstream::reduceAnd(bool& value, const label comm)
|
||||
{
|
||||
PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LAND, comm);
|
||||
}
|
||||
|
||||
|
||||
void Foam::UPstream::reduceOr(bool& value, const label comm)
|
||||
{
|
||||
PstreamDetail::allReduce(&value, 1, MPI_C_BOOL, MPI_LOR, comm);
|
||||
}
|
||||
|
||||
|
||||
void Foam::reduce
|
||||
(
|
||||
@ -44,8 +56,6 @@ void Foam::reduce
|
||||
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);
|
||||
}
|
||||
|
||||
@ -58,15 +68,13 @@ void Foam::reduce
|
||||
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
|
||||
// Common reductions
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#define Pstream_CommonReductions(Native, TaggedType) \
|
||||
@ -126,49 +134,17 @@ void Foam::reduce \
|
||||
( \
|
||||
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
|
||||
// Floating-point reductions
|
||||
|
||||
#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]); \
|
||||
} \
|
||||
} \
|
||||
Pstream_CommonReductions(Native, TaggedType); \
|
||||
\
|
||||
void Foam::reduce \
|
||||
( \
|
||||
@ -199,12 +175,47 @@ void Foam::reduce \
|
||||
( \
|
||||
values, size, TaggedType, MPI_SUM, comm, &requestID \
|
||||
); \
|
||||
} \
|
||||
\
|
||||
void Foam::sumReduce \
|
||||
( \
|
||||
Native& value, \
|
||||
label& count, \
|
||||
const int tag, /* (unused) */ \
|
||||
const label comm \
|
||||
) \
|
||||
{ \
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1) \
|
||||
{ \
|
||||
Native values[2]; \
|
||||
values[0] = static_cast<Native>(count); \
|
||||
values[1] = value; \
|
||||
\
|
||||
PstreamDetail::allReduce<Native> \
|
||||
( \
|
||||
values, 2, TaggedType, MPI_SUM, comm \
|
||||
); \
|
||||
\
|
||||
count = static_cast<label>(values[0]); \
|
||||
value = values[1]; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
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_FloatReductions(float, MPI_FLOAT);
|
||||
Pstream_FloatReductions(double, MPI_DOUBLE);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#undef Pstream_CommonReductions
|
||||
#undef Pstream_FloatReductions
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user