ENH: add simplified gather methods for globalIndex with default communicator

- when combining lists in processor order this simplifies code and
  reduces memory overhead.

  Write this:
    ----
    labelList collected;

    const globalIndex sizing(input.size());
    sizing.gather(input, collected);
    ----

  OR

    ----
    labelList collected;
    globalIndex::gatherOp(input, collected);
    ----

  Instead of this:

    ----
    labelList collected;

    List<labelList> scratch(Pstream::nProcs());
    scratch[Pstream::myProcNo()] = input;
    Pstream::gatherList(scratch);

    if (Pstream::master())
    {
        collected = ListListOps::combine<labelList>
        (
            scratch,
            accessOp<labelList>()
        );
    }
    scratch.clear();
    ----
This commit is contained in:
Mark Olesen
2019-01-16 21:33:06 +01:00
parent f19150cd32
commit f498d09dbf
9 changed files with 236 additions and 131 deletions

View File

@ -1014,12 +1014,6 @@ Foam::label Foam::checkGeometry
scalarField mergedWeights; scalarField mergedWeights;
globalFaces().gather globalFaces().gather
( (
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
ami.srcWeightsSum(), ami.srcWeightsSum(),
mergedWeights mergedWeights
); );
@ -1048,18 +1042,14 @@ Foam::label Foam::checkGeometry
{ {
const cyclicACMIPolyPatch& pp = const cyclicACMIPolyPatch& pp =
refCast<const cyclicACMIPolyPatch>(pbm[patchi]); refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
scalarField mergedMask; scalarField mergedMask;
globalFaces().gather globalFaces().gather
( (
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
pp.mask(), pp.mask(),
mergedMask mergedMask
); );
if (Pstream::master()) if (Pstream::master())
{ {
wr.write wr.write
@ -1108,12 +1098,6 @@ Foam::label Foam::checkGeometry
scalarField mergedWeights; scalarField mergedWeights;
globalFaces().gather globalFaces().gather
( (
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
ami.tgtWeightsSum(), ami.tgtWeightsSum(),
mergedWeights mergedWeights
); );
@ -1145,12 +1129,6 @@ Foam::label Foam::checkGeometry
scalarField mergedMask; scalarField mergedMask;
globalFaces().gather globalFaces().gather
( (
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
pp.neighbPatch().mask(), pp.neighbPatch().mask(),
mergedMask mergedMask
); );

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -78,19 +78,10 @@ void writeWeights
mergedFaces, mergedFaces,
mergedPoints mergedPoints
); );
// Collect field // Collect field
scalarField mergedWeights; scalarField mergedWeights;
globalFaces().gather globalFaces().gather(wghtSum, mergedWeights);
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
wghtSum,
mergedWeights
);
instant inst(runTime.value(), runTime.timeName()); instant inst(runTime.value(), runTime.timeName());

View File

@ -58,7 +58,6 @@ namespace Foam
class UPstream class UPstream
{ {
public: public:
//- Types of communications //- Types of communications
@ -72,6 +71,7 @@ public:
//- Names of the communication types //- Names of the communication types
static const Enum<commsTypes> commsTypeNames; static const Enum<commsTypes> commsTypeNames;
// Public classes // Public classes
//- Structure for communicating between processors //- Structure for communicating between processors
@ -159,11 +159,8 @@ public:
//- combineReduce operator for lists. Used for counting. //- combineReduce operator for lists. Used for counting.
class listEq struct listEq
{ {
public:
template<class T> template<class T>
void operator()(T& x, const T& y) const void operator()(T& x, const T& y) const
{ {
@ -430,7 +427,7 @@ public:
} }
//- Process index of the master //- Process index of the master
static int masterNo() static constexpr int masterNo() noexcept
{ {
return 0; return 0;
} }
@ -459,7 +456,7 @@ public:
} }
//- Process index of first slave //- Process index of first slave
static int firstSlave() static constexpr int firstSlave() noexcept
{ {
return 1; return 1;
} }
@ -575,6 +572,7 @@ Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
template<> template<>
UPstream::commsStruct& UPstream::commsStruct&
UList<UPstream::commsStruct>::operator[](const label); UList<UPstream::commsStruct>::operator[](const label);
template<> template<>
const UPstream::commsStruct& const UPstream::commsStruct&
UList<UPstream::commsStruct>::operator[](const label) const; UList<UPstream::commsStruct>::operator[](const label) const;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -74,33 +74,25 @@ void Foam::globalIndex::reset
} }
void Foam::globalIndex::reset(const label localSize) Foam::labelList Foam::globalIndex::sizes() const
{ {
offsets_.resize(Pstream::nProcs()+1); labelList values;
labelList localSizes(Pstream::nProcs(), Zero); const label len = (offsets_.size() - 1);
localSizes[Pstream::myProcNo()] = localSize;
Pstream::gatherList(localSizes, Pstream::msgType()); if (len < 1)
Pstream::scatterList(localSizes, Pstream::msgType());
label offset = 0;
offsets_[0] = 0;
for (label proci = 0; proci < Pstream::nProcs(); ++proci)
{ {
const label oldOffset = offset; return values;
offset += localSizes[proci]; }
if (offset < oldOffset) values.resize(len);
for (label proci=0; proci < len; ++proci)
{ {
FatalErrorInFunction values[proci] = offsets_[proci+1] - offsets_[proci];
<< "Overflow : sum of sizes " << localSizes
<< " exceeds capability of label (" << labelMax
<< "). Please recompile with larger datatype for label."
<< exit(FatalError);
}
offsets_[proci+1] = offset;
} }
return values;
} }

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -108,6 +108,12 @@ public:
//- Const-access to the offsets //- Const-access to the offsets
inline const labelList& offsets() const; inline const labelList& offsets() const;
//- Global sum of localSizes
inline label size() const;
//- The local sizes
labelList sizes() const;
// Edit // Edit
@ -116,7 +122,7 @@ public:
//- Reset from local size. //- Reset from local size.
// Does communication with default communicator and message tag. // Does communication with default communicator and message tag.
void reset(const label localSize); inline void reset(const label localSize);
//- Reset from local size. //- Reset from local size.
// Does communication with given communicator and message tag // Does communication with given communicator and message tag
@ -159,9 +165,6 @@ public:
// Global queries // Global queries
//- Global sum of localSizes
inline label size() const;
//- Start of proci data //- Start of proci data
inline label offset(const label proci) const; inline label offset(const label proci) const;
@ -236,8 +239,33 @@ public:
gather(offsets_, comm, procIDs, fld, allFld, tag, commsType); gather(offsets_, comm, procIDs, fld, allFld, tag, commsType);
} }
//- Inplace collect data in processor order on master //- Collect data in processor order on master.
// (== procIDs[0]). Needs offsets only on master. // Does communication with default communicator and message tag.
template<class Type>
void gather
(
const UList<Type>& fld,
List<Type>& allFld,
const int tag = UPstream::msgType(),
const Pstream::commsTypes commsType =
Pstream::commsTypes::nonBlocking
) const;
//- Collect data in processor order on master.
// Does communication with default communicator and message tag.
template<class Type>
static void gatherOp
(
const UList<Type>& fld,
List<Type>& allFld,
const int tag = UPstream::msgType(),
const Pstream::commsTypes commsType =
Pstream::commsTypes::nonBlocking
);
//- Inplace collect in processor order on master (== procIDs[0]).
//- Needs offsets only on master.
template<class Type> template<class Type>
static void gather static void gather
( (
@ -250,8 +278,8 @@ public:
Pstream::commsTypes::nonBlocking Pstream::commsTypes::nonBlocking
); );
//- Inplace collect data in processor order on master //- Inplace collect in processor order on master (== procIDs[0]).
// (== procIDs[0]). Needs offsets only on master. //- Needs offsets only on master.
template<class Type> template<class Type>
void gather void gather
( (
@ -266,6 +294,31 @@ public:
gather(offsets_, comm, procIDs, fld, tag, commsType); gather(offsets_, comm, procIDs, fld, tag, commsType);
} }
//- Inplace collect data in processor order on master
// Does communication with default communicator and message tag.
// After the gather, the field is zero-sized on the slaves.
template<class Type>
void gather
(
List<Type>& fld,
const int tag = UPstream::msgType(),
const Pstream::commsTypes commsType =
Pstream::commsTypes::nonBlocking
) const;
//- Inplace collect data in processor order on master
// Does communication with default communicator and message tag.
// After the gather, the field is zero-sized on the slaves.
template<class Type>
static void gatherOp
(
List<Type>& fld,
const int tag = UPstream::msgType(),
const Pstream::commsTypes commsType =
Pstream::commsTypes::nonBlocking
);
//- Distribute data in processor order. Requires fld to be sized! //- Distribute data in processor order. Requires fld to be sized!
template<class Type> template<class Type>
static void scatter static void scatter
@ -296,6 +349,18 @@ public:
scatter(offsets_, comm, procIDs, allFld, fld, tag, commsType); scatter(offsets_, comm, procIDs, allFld, fld, tag, commsType);
} }
//- Distribute data in processor order. Requires fld to be sized!
// Does communication with default communicator and message tag.
template<class Type>
void scatter
(
const UList<Type>& allFld,
UList<Type>& fld,
const int tag = UPstream::msgType(),
const Pstream::commsTypes commsType =
Pstream::commsTypes::nonBlocking
) const;
// IOstream Operators // IOstream Operators
@ -310,16 +375,16 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "globalIndexI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
#include "globalIndexTemplates.C" #include "globalIndexTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "globalIndexI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -82,6 +82,18 @@ inline Foam::labelList& Foam::globalIndex::offsets()
} }
inline Foam::label Foam::globalIndex::size() const
{
return offsets_.empty() ? 0 : offsets_.last();
}
inline void Foam::globalIndex::reset(const label localSize)
{
reset(localSize, Pstream::msgType(), 0, true);
}
inline Foam::label Foam::globalIndex::offset(const label proci) const inline Foam::label Foam::globalIndex::offset(const label proci) const
{ {
return offsets_[proci]; return offsets_[proci];
@ -124,12 +136,6 @@ inline Foam::labelRange Foam::globalIndex::range() const
} }
inline Foam::label Foam::globalIndex::size() const
{
return offsets_.last();
}
inline bool Foam::globalIndex::isLocal(const label proci, const label i) const inline bool Foam::globalIndex::isLocal(const label proci, const label i) const
{ {
return i >= offsets_[proci] && i < offsets_[proci+1]; return i >= offsets_[proci] && i < offsets_[proci+1];

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2013-2017 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2017 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -52,7 +52,7 @@ void Foam::globalIndex::gather
|| commsType == Pstream::commsTypes::blocking || commsType == Pstream::commsTypes::blocking
) )
{ {
for (label i = 1; i < procIDs.size(); i++) for (label i = 1; i < procIDs.size(); ++i)
{ {
SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]); SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
@ -96,7 +96,7 @@ void Foam::globalIndex::gather
label startOfRequests = Pstream::nRequests(); label startOfRequests = Pstream::nRequests();
// Set up reads // Set up reads
for (label i = 1; i < procIDs.size(); i++) for (label i = 1; i < procIDs.size(); ++i)
{ {
SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]); SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
@ -179,6 +179,40 @@ void Foam::globalIndex::gather
} }
template<class Type>
void Foam::globalIndex::gather
(
const UList<Type>& fld,
List<Type>& allFld,
const int tag,
const Pstream::commsTypes commsType
) const
{
gather
(
UPstream::worldComm,
identity(Pstream::nProcs(UPstream::worldComm)),
fld,
allFld,
tag,
commsType
);
}
template<class Type>
void Foam::globalIndex::gatherOp
(
const UList<Type>& fld,
List<Type>& allFld,
const int tag,
const Pstream::commsTypes commsType
)
{
globalIndex(fld.size()).gather(fld, allFld, tag, commsType);
}
template<class Type> template<class Type>
void Foam::globalIndex::gather void Foam::globalIndex::gather
( (
@ -201,6 +235,49 @@ void Foam::globalIndex::gather
} }
template<class Type>
void Foam::globalIndex::gather
(
List<Type>& fld,
const int tag,
const Pstream::commsTypes commsType
) const
{
List<Type> allFld;
gather
(
UPstream::worldComm,
identity(Pstream::master(UPstream::worldComm)),
fld,
allFld,
tag,
commsType
);
if (Pstream::master(UPstream::worldComm))
{
fld.transfer(allFld);
}
else
{
fld.clear();
}
}
template<class Type>
void Foam::globalIndex::gatherOp
(
List<Type>& fld,
const int tag,
const Pstream::commsTypes commsType
)
{
globalIndex(fld.size()).gather(fld, tag, commsType);
}
template<class Type> template<class Type>
void Foam::globalIndex::scatter void Foam::globalIndex::scatter
( (
@ -223,7 +300,7 @@ void Foam::globalIndex::scatter
|| commsType == Pstream::commsTypes::blocking || commsType == Pstream::commsTypes::blocking
) )
{ {
for (label i = 1; i < procIDs.size(); i++) for (label i = 1; i < procIDs.size(); ++i)
{ {
const SubList<Type> procSlot const SubList<Type> procSlot
( (
@ -272,7 +349,7 @@ void Foam::globalIndex::scatter
label startOfRequests = Pstream::nRequests(); label startOfRequests = Pstream::nRequests();
// Set up writes // Set up writes
for (label i = 1; i < procIDs.size(); i++) for (label i = 1; i < procIDs.size(); ++i)
{ {
const SubList<Type> procSlot const SubList<Type> procSlot
( (
@ -360,4 +437,26 @@ void Foam::globalIndex::scatter
} }
template<class Type>
void Foam::globalIndex::scatter
(
const UList<Type>& allFld,
UList<Type>& fld,
const int tag,
const Pstream::commsTypes commsType
) const
{
scatter
(
offsets_,
UPstream::worldComm,
identity(Pstream::nProcs(UPstream::worldComm)),
allFld,
fld,
tag,
commsType
);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd. \\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -237,17 +237,7 @@ void Foam::functionObjects::AMIWeights::writeWeightField
// Collect field // Collect field
scalarField mergedWeights; scalarField mergedWeights;
globalFaces().gather globalFaces().gather(weightSum, mergedWeights);
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
weightSum,
mergedWeights
);
const bool isACMI = isA<cyclicACMIPolyPatch>(cpp); const bool isACMI = isA<cyclicACMIPolyPatch>(cpp);
@ -256,17 +246,7 @@ void Foam::functionObjects::AMIWeights::writeWeightField
{ {
const cyclicACMIPolyPatch& pp = refCast<const cyclicACMIPolyPatch>(cpp); const cyclicACMIPolyPatch& pp = refCast<const cyclicACMIPolyPatch>(cpp);
globalFaces().gather globalFaces().gather(pp.mask(), mergedMask);
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
pp.mask(),
mergedMask
);
} }
if (Pstream::master()) if (Pstream::master())

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -161,13 +161,11 @@ void Foam::meshRefinement::collectAndPrint
const UList<T>& data const UList<T>& data
) )
{ {
globalIndex globalPoints(points.size()); const globalIndex globalPoints(points.size());
pointField allPoints; pointField allPoints;
globalPoints.gather globalPoints.gather
( (
Pstream::worldComm,
identity(Pstream::nProcs()),
points, points,
allPoints, allPoints,
UPstream::msgType(), UPstream::msgType(),
@ -177,8 +175,6 @@ void Foam::meshRefinement::collectAndPrint
List<T> allData; List<T> allData;
globalPoints.gather globalPoints.gather
( (
Pstream::worldComm,
identity(Pstream::nProcs()),
data, data,
allData, allData,
UPstream::msgType(), UPstream::msgType(),