Commit f498d09d authored by Mark Olesen's avatar Mark Olesen
Browse files

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();
    ----
parent f19150cd
......@@ -1014,12 +1014,6 @@ Foam::label Foam::checkGeometry
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
ami.srcWeightsSum(),
mergedWeights
);
......@@ -1048,18 +1042,14 @@ Foam::label Foam::checkGeometry
{
const cyclicACMIPolyPatch& pp =
refCast<const cyclicACMIPolyPatch>(pbm[patchi]);
scalarField mergedMask;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
pp.mask(),
mergedMask
);
if (Pstream::master())
{
wr.write
......@@ -1108,12 +1098,6 @@ Foam::label Foam::checkGeometry
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
ami.tgtWeightsSum(),
mergedWeights
);
......@@ -1145,12 +1129,6 @@ Foam::label Foam::checkGeometry
scalarField mergedMask;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
pp.neighbPatch().mask(),
mergedMask
);
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -78,19 +78,10 @@ void writeWeights
mergedFaces,
mergedPoints
);
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
wghtSum,
mergedWeights
);
globalFaces().gather(wghtSum, mergedWeights);
instant inst(runTime.value(), runTime.timeName());
......
......@@ -58,7 +58,6 @@ namespace Foam
class UPstream
{
public:
//- Types of communications
......@@ -72,6 +71,7 @@ public:
//- Names of the communication types
static const Enum<commsTypes> commsTypeNames;
// Public classes
//- Structure for communicating between processors
......@@ -159,11 +159,8 @@ public:
//- combineReduce operator for lists. Used for counting.
class listEq
struct listEq
{
public:
template<class T>
void operator()(T& x, const T& y) const
{
......@@ -430,7 +427,7 @@ public:
}
//- Process index of the master
static int masterNo()
static constexpr int masterNo() noexcept
{
return 0;
}
......@@ -459,7 +456,7 @@ public:
}
//- Process index of first slave
static int firstSlave()
static constexpr int firstSlave() noexcept
{
return 1;
}
......@@ -495,19 +492,19 @@ public:
}
//- Get the communications type of the stream
commsTypes commsType() const
{
return commsType_;
}
//- Get the communications type of the stream
commsTypes commsType() const
{
return commsType_;
}
//- Set the communications type of the stream
commsTypes commsType(const commsTypes ct)
{
commsTypes oldCommsType = commsType_;
commsType_ = ct;
return oldCommsType;
}
//- Set the communications type of the stream
commsTypes commsType(const commsTypes ct)
{
commsTypes oldCommsType = commsType_;
commsType_ = ct;
return oldCommsType;
}
//- Exit program
......@@ -575,6 +572,7 @@ Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
template<>
UPstream::commsStruct&
UList<UPstream::commsStruct>::operator[](const label);
template<>
const UPstream::commsStruct&
UList<UPstream::commsStruct>::operator[](const label) const;
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
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);
localSizes[Pstream::myProcNo()] = localSize;
const label len = (offsets_.size() - 1);
Pstream::gatherList(localSizes, Pstream::msgType());
Pstream::scatterList(localSizes, Pstream::msgType());
label offset = 0;
offsets_[0] = 0;
for (label proci = 0; proci < Pstream::nProcs(); ++proci)
if (len < 1)
{
const label oldOffset = offset;
offset += localSizes[proci];
return values;
}
if (offset < oldOffset)
{
FatalErrorInFunction
<< "Overflow : sum of sizes " << localSizes
<< " exceeds capability of label (" << labelMax
<< "). Please recompile with larger datatype for label."
<< exit(FatalError);
}
offsets_[proci+1] = offset;
values.resize(len);
for (label proci=0; proci < len; ++proci)
{
values[proci] = offsets_[proci+1] - offsets_[proci];
}
return values;
}
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2018-2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -108,6 +108,12 @@ public:
//- Const-access to the offsets
inline const labelList& offsets() const;
//- Global sum of localSizes
inline label size() const;
//- The local sizes
labelList sizes() const;
// Edit
......@@ -116,7 +122,7 @@ public:
//- Reset from local size.
// Does communication with default communicator and message tag.
void reset(const label localSize);
inline void reset(const label localSize);
//- Reset from local size.
// Does communication with given communicator and message tag
......@@ -159,9 +165,6 @@ public:
// Global queries
//- Global sum of localSizes
inline label size() const;
//- Start of proci data
inline label offset(const label proci) const;
......@@ -236,8 +239,33 @@ public:
gather(offsets_, comm, procIDs, fld, allFld, tag, commsType);
}
//- Inplace collect data in processor order on master
// (== procIDs[0]). Needs offsets only on master.
//- Collect data in processor order 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>
static void gather
(
......@@ -250,8 +278,8 @@ public:
Pstream::commsTypes::nonBlocking
);
//- Inplace collect data in processor order on master
// (== procIDs[0]). Needs offsets only on master.
//- Inplace collect in processor order on master (== procIDs[0]).
//- Needs offsets only on master.
template<class Type>
void gather
(
......@@ -266,6 +294,31 @@ public:
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!
template<class Type>
static void scatter
......@@ -296,6 +349,18 @@ public:
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
......@@ -310,13 +375,13 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "globalIndexTemplates.C"
#endif
#include "globalIndexI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "globalIndexI.H"
#ifdef NoRepository
#include "globalIndexTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -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
{
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
{
return i >= offsets_[proci] && i < offsets_[proci+1];
......
......@@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013-2017 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -52,7 +52,7 @@ void Foam::globalIndex::gather
|| 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]);
......@@ -96,7 +96,7 @@ void Foam::globalIndex::gather
label startOfRequests = Pstream::nRequests();
// 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]);
......@@ -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>
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>
void Foam::globalIndex::scatter
(
......@@ -223,7 +300,7 @@ void Foam::globalIndex::scatter
|| commsType == Pstream::commsTypes::blocking
)
{
for (label i = 1; i < procIDs.size(); i++)
for (label i = 1; i < procIDs.size(); ++i)
{
const SubList<Type> procSlot
(
......@@ -272,7 +349,7 @@ void Foam::globalIndex::scatter
label startOfRequests = Pstream::nRequests();
// Set up writes
for (label i = 1; i < procIDs.size(); i++)
for (label i = 1; i < procIDs.size(); ++i)
{
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
);
}
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -237,17 +237,7 @@ void Foam::functionObjects::AMIWeights::writeWeightField
// Collect field
scalarField mergedWeights;
globalFaces().gather
(
UPstream::worldComm,
ListOps::create<label>
(
UPstream::procID(UPstream::worldComm),
labelOp<int>() // int -> label
),
weightSum,
mergedWeights
);
globalFaces().gather(weightSum, mergedWeights);
const bool isACMI = isA<cyclicACMIPolyPatch>(cpp);
......@@ -256,17 +246,7 @@ void Foam::functionObjects::AMIWeights::writeWeightField
{
const cyclicACMIPolyPatch& pp = refCast<const cyclicACMIPolyPatch>(cpp);
globalFaces().gather
(