ENH: additional globalIndex methods and helpers
- single() method : simply tests if the globalIndex has nProcs == 1, which is typically from a gatherNone invocation. For example, globalIndex gi; if (...) gi.reset(localSize); else gi.reset(globalIndex::gatherNone{}, localSize); // later... const label begin = (gi.single() ? 0 : gi.localStart()); const label count = (gi.single() ? gi.totalSize() : gi.localSize()); - add front() and back() methods to return the begin/end ranges, and begin_value(), end_value() - as per labelRange. - make more methods noexcept - calcOffset(), calcRange() helper functions to determine the processor-local of a numbering range without the overhead of creating a list of offsets. For example, label myOffset = globalIndex::calcOffset(mesh.nCells()); labelRange mySlice = globalIndex::calcRange(mesh.nCells()); - add globalIndex localEnd() as per CompactListList method STYLE: align looping constructs in CompactListList with List - make more methods noexcept
This commit is contained in:
parent
d9f0587416
commit
b34793c392
@ -55,6 +55,16 @@ int main(int argc, char *argv[])
|
||||
// Global numbering of cells (proc0 elements first, then proc1, etc.)
|
||||
globalIndex globalNumbering(mesh.nCells());
|
||||
|
||||
Pout<< "local-offset: " << globalIndex::calcOffset(mesh.nCells()) << nl;
|
||||
Pout<< "local-range: " << globalIndex::calcRange(mesh.nCells()) << nl;
|
||||
|
||||
Info<< "cells from:" << globalNumbering.begin_value()
|
||||
<< " to:" << globalNumbering.end_value()
|
||||
<< " span:" << globalNumbering.span() << nl;
|
||||
|
||||
Info<< "front: " << globalNumbering.front()
|
||||
<< " back: " << globalNumbering.back() << nl;
|
||||
|
||||
if (globalNumbering.localSize() != mesh.nCells())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
|
@ -56,7 +56,7 @@ void Foam::CompactListList<T>::reportOverflowAndExit
|
||||
|
||||
template<class T>
|
||||
template<class ListListType>
|
||||
Foam::CompactListList<T> Foam::CompactListList<T>::packImpl
|
||||
Foam::CompactListList<T> Foam::CompactListList<T>::pack_impl
|
||||
(
|
||||
const ListListType& lists,
|
||||
const bool checkOverflow
|
||||
@ -89,17 +89,21 @@ Foam::CompactListList<T> Foam::CompactListList<T>::packImpl
|
||||
|
||||
if (total)
|
||||
{
|
||||
// Copy in the data
|
||||
// Make a deepCopy of data
|
||||
newValues.resize(total);
|
||||
|
||||
auto outIter = newValues.begin();
|
||||
auto iter = newValues.begin();
|
||||
|
||||
// NB: operator[] for sub-list read access (eg, an indirect list)
|
||||
// cannot replace with std::copy
|
||||
|
||||
for (const auto& list : lists)
|
||||
{
|
||||
forAll(list, i)
|
||||
const label sublen = list.size();
|
||||
|
||||
for (label i = 0; i < sublen; (void)++i, (void)++iter)
|
||||
{
|
||||
*outIter = list[i];
|
||||
++outIter;
|
||||
*iter = list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,7 +120,7 @@ Foam::CompactListList<T> Foam::CompactListList<T>::pack
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
return CompactListList<T>::packImpl<UList<SubListType>>
|
||||
return CompactListList<T>::pack_impl<UList<SubListType>>
|
||||
(
|
||||
lists,
|
||||
checkOverflow
|
||||
@ -132,7 +136,7 @@ Foam::CompactListList<T> Foam::CompactListList<T>::pack
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
return CompactListList<T>::packImpl<IndirectListBase<SubListType, Addr>>
|
||||
return CompactListList<T>::pack_impl<IndirectListBase<SubListType, Addr>>
|
||||
(
|
||||
lists,
|
||||
checkOverflow
|
||||
@ -404,12 +408,12 @@ Foam::CompactListList<T>::unpack(const labelRange& range) const
|
||||
{
|
||||
List<SubListType> lists(range.size());
|
||||
|
||||
auto outIter = lists.begin();
|
||||
auto iter = lists.begin();
|
||||
|
||||
for (const label i : range)
|
||||
{
|
||||
*outIter = SubListType(this->localList(i));
|
||||
++outIter;
|
||||
*iter = SubListType(this->localList(i));
|
||||
++iter;
|
||||
}
|
||||
|
||||
return lists;
|
||||
|
@ -28,7 +28,7 @@ Class
|
||||
Foam::CompactListList
|
||||
|
||||
Description
|
||||
A packed storage unstructured matrix of objects of type \<T\>
|
||||
A packed storage of objects of type \<T\>
|
||||
using an offset table for access.
|
||||
|
||||
The offset table is the size of the number of rows+1
|
||||
@ -91,7 +91,7 @@ class CompactListList
|
||||
|
||||
//- Construct by packing together the list of lists
|
||||
template<class ListListType>
|
||||
static CompactListList<T> packImpl
|
||||
static CompactListList<T> pack_impl
|
||||
(
|
||||
const ListListType& lists,
|
||||
const bool checkOverflow = false
|
||||
@ -197,23 +197,29 @@ public:
|
||||
//- True if the number of rows/sublists is zero
|
||||
inline bool empty() const noexcept;
|
||||
|
||||
//- True if content is a single row/sublist only.
|
||||
//- Such content could be flattened out into a straight list
|
||||
//- (for example).
|
||||
inline bool single() const noexcept;
|
||||
|
||||
//- The primary size (the number of rows/sublists)
|
||||
inline label size() const noexcept;
|
||||
|
||||
//- The total addressed size
|
||||
inline label totalSize() const;
|
||||
//- The total addressed size, which corresponds to the
|
||||
//- end (back) offset and also the sum of all localSizes.
|
||||
inline label totalSize() const noexcept;
|
||||
|
||||
//- Return the offset table (= size()+1)
|
||||
inline const labelList& offsets() const noexcept;
|
||||
const labelList& offsets() const noexcept { return offsets_; }
|
||||
|
||||
//- Return non-const access to the offset table
|
||||
inline labelList& offsets() noexcept;
|
||||
labelList& offsets() noexcept { return offsets_; }
|
||||
|
||||
//- Return the packed matrix of values
|
||||
inline const List<T>& values() const noexcept;
|
||||
//- Return the packed values
|
||||
const List<T>& values() const noexcept { return values_; }
|
||||
|
||||
//- Return non-const access to the packed matrix of values
|
||||
inline List<T>& values() noexcept;
|
||||
//- Return non-const access to the packed values
|
||||
List<T>& values() noexcept { return values_; }
|
||||
|
||||
|
||||
//- Return const pointer to the first data in values()
|
||||
@ -414,10 +420,12 @@ public:
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Const access to the packed matrix of values
|
||||
//- Const access to the packed values
|
||||
//FOAM_DEPRECATED_STRICT(2022-03, "values()")
|
||||
const List<T>& m() const noexcept { return values_; }
|
||||
|
||||
//- Non-const access to the packed matrix of values
|
||||
//- Non-const access to the packed values
|
||||
//FOAM_DEPRECATED_STRICT(2022-03, "values()")
|
||||
List<T>& m() noexcept { return values_; }
|
||||
|
||||
//- Return flat index into packed values
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -145,34 +145,6 @@ Foam::CompactListList<T>::clone() const
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const Foam::labelList& Foam::CompactListList<T>::offsets() const noexcept
|
||||
{
|
||||
return offsets_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::labelList& Foam::CompactListList<T>::offsets() noexcept
|
||||
{
|
||||
return offsets_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline const Foam::List<T>& Foam::CompactListList<T>::values() const noexcept
|
||||
{
|
||||
return values_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::List<T>& Foam::CompactListList<T>::values() noexcept
|
||||
{
|
||||
return values_;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline const T* Foam::CompactListList<T>::cdata() const noexcept
|
||||
{
|
||||
@ -211,10 +183,20 @@ inline std::streamsize Foam::CompactListList<T>::size_bytes() const noexcept
|
||||
template<class T>
|
||||
inline bool Foam::CompactListList<T>::empty() const noexcept
|
||||
{
|
||||
// Note: could (should?) also check (offsets_.back() == 0)
|
||||
// return offsets_.empty()
|
||||
// || (*(offsets_.cdata() + offsets_.size()-1) == 0);
|
||||
return (offsets_.size() <= 1);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::CompactListList<T>::single() const noexcept
|
||||
{
|
||||
return (offsets_.size() == 2);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::label Foam::CompactListList<T>::size() const noexcept
|
||||
{
|
||||
@ -231,10 +213,9 @@ inline Foam::labelList Foam::CompactListList<T>::sizes() const
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::label Foam::CompactListList<T>::totalSize() const
|
||||
inline Foam::label Foam::CompactListList<T>::totalSize() const noexcept
|
||||
{
|
||||
const label len = (offsets_.size() - 1);
|
||||
return (len < 1) ? static_cast<label>(0) : offsets_[len];
|
||||
return offsets_.empty() ? 0 : *(offsets_.cdata() + offsets_.size()-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,6 +27,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "globalIndex.H"
|
||||
#include "Pair.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
@ -52,6 +53,132 @@ void Foam::globalIndex::reportOverflowAndExit
|
||||
}
|
||||
|
||||
|
||||
Foam::labelRange
|
||||
Foam::globalIndex::calcRange
|
||||
(
|
||||
const label localSize,
|
||||
const label comm,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
// Range with 0-offset initially
|
||||
labelRange myRange(0, localSize);
|
||||
|
||||
if (!UPstream::is_parallel(comm))
|
||||
{
|
||||
return myRange;
|
||||
}
|
||||
|
||||
const label myProci = UPstream::myProcNo(comm);
|
||||
const labelList localLens = UPstream::allGatherValues(localSize, comm);
|
||||
|
||||
if (checkOverflow)
|
||||
{
|
||||
const label len = localLens.size();
|
||||
|
||||
label start = 0;
|
||||
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
if (i == myProci)
|
||||
{
|
||||
myRange.start() = start;
|
||||
}
|
||||
|
||||
const label prev = start;
|
||||
start += localLens[i];
|
||||
|
||||
if (start < prev)
|
||||
{
|
||||
reportOverflowAndExit(i, localLens);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::accumulate
|
||||
// (
|
||||
// localLens.cbegin(),
|
||||
// localLens.cbegin(myProci),
|
||||
// label(0)
|
||||
// );
|
||||
|
||||
label start = 0;
|
||||
|
||||
for (label i = 0; i < myProci; ++i)
|
||||
{
|
||||
start += localLens[i];
|
||||
}
|
||||
myRange.start() = start;
|
||||
}
|
||||
|
||||
return myRange;
|
||||
}
|
||||
|
||||
|
||||
Foam::label
|
||||
Foam::globalIndex::calcOffset
|
||||
(
|
||||
const label localSize,
|
||||
const label comm,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
// Placeholder value
|
||||
label myOffset = 0;
|
||||
|
||||
if (!UPstream::is_parallel(comm))
|
||||
{
|
||||
return myOffset;
|
||||
}
|
||||
|
||||
const label myProci = UPstream::myProcNo(comm);
|
||||
const labelList localLens = UPstream::allGatherValues(localSize, comm);
|
||||
|
||||
if (checkOverflow)
|
||||
{
|
||||
const label len = localLens.size();
|
||||
|
||||
label start = 0;
|
||||
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
if (i == myProci)
|
||||
{
|
||||
myOffset = start;
|
||||
}
|
||||
|
||||
const label prev = start;
|
||||
start += localLens[i];
|
||||
|
||||
if (start < prev)
|
||||
{
|
||||
reportOverflowAndExit(i, localLens);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// std::accumulate
|
||||
// (
|
||||
// localLens.cbegin(),
|
||||
// localLens.cbegin(myProci),
|
||||
// label(0)
|
||||
// );
|
||||
|
||||
label start = 0;
|
||||
|
||||
for (label i = 0; i < myProci; ++i)
|
||||
{
|
||||
start += localLens[i];
|
||||
}
|
||||
myOffset = start;
|
||||
}
|
||||
|
||||
return myOffset;
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList
|
||||
Foam::globalIndex::calcOffsets
|
||||
(
|
||||
@ -197,13 +324,13 @@ void Foam::globalIndex::reset
|
||||
const bool parallel
|
||||
)
|
||||
{
|
||||
labelList localLens;
|
||||
|
||||
const label len = UPstream::nProcs(comm);
|
||||
|
||||
if (len)
|
||||
{
|
||||
if (parallel && UPstream::parRun()) // or UPstream::is_parallel()
|
||||
labelList localLens;
|
||||
|
||||
if (parallel && UPstream::parRun()) // or UPstream::is_parallel(comm)
|
||||
{
|
||||
localLens = UPstream::allGatherValues(localSize, comm);
|
||||
}
|
||||
@ -350,6 +477,35 @@ Foam::label Foam::globalIndex::maxNonLocalSize(const label proci) const
|
||||
}
|
||||
|
||||
|
||||
Foam::labelRange Foam::globalIndex::front() const
|
||||
{
|
||||
return
|
||||
(
|
||||
(offsets_.size() < 2)
|
||||
? labelRange()
|
||||
: labelRange(Pair<label>(offsets_[0], offsets_[1]))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Foam::labelRange Foam::globalIndex::back() const
|
||||
{
|
||||
return
|
||||
(
|
||||
(offsets_.size() < 2)
|
||||
? labelRange()
|
||||
: labelRange
|
||||
(
|
||||
Pair<label>
|
||||
(
|
||||
offsets_[offsets_.size()-2],
|
||||
offsets_[offsets_.size()-1]
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, globalIndex& gi)
|
||||
|
@ -59,9 +59,8 @@ class globalIndex;
|
||||
Istream& operator>>(Istream& is, globalIndex& gi);
|
||||
Ostream& operator<<(Ostream& os, const globalIndex& gi);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class globalIndex Declaration
|
||||
Class globalIndex Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class globalIndex
|
||||
@ -180,14 +179,18 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Check for default constructed or global sum == 0
|
||||
inline bool empty() const;
|
||||
//- Check for default constructed or total-size == 0
|
||||
inline bool empty() const noexcept;
|
||||
|
||||
//- Global sum of localSizes. Same as totalSize()
|
||||
inline label size() const;
|
||||
|
||||
//- Global sum of localSizes.
|
||||
inline label totalSize() const;
|
||||
//- The span size covered by the offsets, zero if empty
|
||||
inline label span() const noexcept;
|
||||
|
||||
//- The total addressed size, which corresponds to the
|
||||
//- end offset and also the sum of all localSizes.
|
||||
inline label totalSize() const noexcept;
|
||||
|
||||
//- The local sizes. Same as localSizes()
|
||||
inline labelList sizes() const;
|
||||
@ -216,6 +219,10 @@ public:
|
||||
|
||||
// Dimensions
|
||||
|
||||
//- True if local-only content (ie, nProcs == 1).
|
||||
//- Such content is often created with gatherNone.
|
||||
inline bool single() const noexcept;
|
||||
|
||||
//- The number of processors covered by the offsets
|
||||
inline label nProcs() const noexcept;
|
||||
|
||||
@ -225,6 +232,19 @@ public:
|
||||
//- Range of process indices for addressed sub-offsets (processes)
|
||||
inline labelRange subProcs() const noexcept;
|
||||
|
||||
//- The value corresponding to the first offset
|
||||
inline label begin_value() const noexcept;
|
||||
|
||||
//- The value corresponding to the last offset (end offset),
|
||||
//- which is 1 beyond the end of the range.
|
||||
inline label end_value() const noexcept;
|
||||
|
||||
//- The first offset range. It is (0,0) if globalIndex is empty
|
||||
labelRange front() const;
|
||||
|
||||
//- The last offset range. It is (0,0) if globalIndex is empty
|
||||
labelRange back() const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
@ -291,6 +311,9 @@ public:
|
||||
//- Start of proci data
|
||||
inline label localStart(const label proci) const;
|
||||
|
||||
//- End of proci data
|
||||
inline label localEnd(const label proci) const;
|
||||
|
||||
//- Size of proci data
|
||||
inline label localSize(const label proci) const;
|
||||
|
||||
@ -336,6 +359,9 @@ public:
|
||||
//- Local start on myProcNo()
|
||||
inline label localStart() const;
|
||||
|
||||
//- Local end on myProcNo()
|
||||
inline label localEnd() const;
|
||||
|
||||
//- Local size on myProcNo()
|
||||
inline label localSize() const;
|
||||
|
||||
@ -443,6 +469,28 @@ public:
|
||||
|
||||
// Helper Functions
|
||||
|
||||
//- Calculate globally-consistent local range (offset/size)
|
||||
//- based on the local input size(s).
|
||||
// Effectively the same as globalIndex(localSize).range()
|
||||
// but without constructing an extra intermediate list of offsets
|
||||
static labelRange calcRange
|
||||
(
|
||||
const label localSize,
|
||||
const label comm = UPstream::worldComm, //!< communicator
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
//- Calculate globally-consistent local start offset
|
||||
//- based on the local input size(s).
|
||||
// Effectively the same as globalIndex(localSize).localStart()
|
||||
// but without constructing an extra intermediate list of offsets
|
||||
static label calcOffset
|
||||
(
|
||||
const label localSize,
|
||||
const label comm = UPstream::worldComm, //!< communicator
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
//- Calculate offsets from a list of local sizes,
|
||||
//- with optional check for label overflow
|
||||
static labelList calcOffsets
|
||||
|
@ -35,7 +35,7 @@ inline Foam::globalIndex::globalIndex
|
||||
const labelUList& listOffsets
|
||||
)
|
||||
{
|
||||
if (listOffsets.size() > 1)
|
||||
if (listOffsets.size() > 1) // Enforce sizing sanity
|
||||
{
|
||||
offsets_ = listOffsets;
|
||||
}
|
||||
@ -49,7 +49,7 @@ inline Foam::globalIndex::globalIndex
|
||||
:
|
||||
offsets_(std::move(listOffsets))
|
||||
{
|
||||
if (offsets_.size() == 1)
|
||||
if (offsets_.size() == 1) // Enforce sizing sanity
|
||||
{
|
||||
offsets_.clear();
|
||||
}
|
||||
@ -124,16 +124,35 @@ inline Foam::globalIndex::globalIndex
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::globalIndex::empty() const
|
||||
inline bool Foam::globalIndex::empty() const noexcept
|
||||
{
|
||||
return offsets_.empty() || offsets_.back() == 0;
|
||||
const label len = (offsets_.size() - 1);
|
||||
return (len < 1) || (*(offsets_.cdata() + len) == 0);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::totalSize() const
|
||||
inline Foam::label Foam::globalIndex::span() const noexcept
|
||||
{
|
||||
return (end_value() - begin_value());
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::begin_value() const noexcept
|
||||
{
|
||||
return (offsets_.empty() ? 0 : *(offsets_.cdata()));
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::end_value() const noexcept
|
||||
{
|
||||
const label len = (offsets_.size() - 1);
|
||||
return (len < 1) ? 0 : offsets_[len];
|
||||
return (len < 1) ? 0 : *(offsets_.cdata() + len);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::totalSize() const noexcept
|
||||
{
|
||||
return end_value();
|
||||
}
|
||||
|
||||
|
||||
@ -149,6 +168,12 @@ inline Foam::labelList Foam::globalIndex::sizes() const
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::globalIndex::single() const noexcept
|
||||
{
|
||||
return (offsets_.size() == 2);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::nProcs() const noexcept
|
||||
{
|
||||
const label len = (offsets_.size() - 1);
|
||||
@ -212,6 +237,18 @@ inline Foam::label Foam::globalIndex::localStart() const
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::localEnd(const label proci) const
|
||||
{
|
||||
return offsets_[proci+1];
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::localEnd() const
|
||||
{
|
||||
return localEnd(UPstream::myProcNo(UPstream::worldComm));
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::localSize(const label proci) const
|
||||
{
|
||||
return offsets_[proci+1] - offsets_[proci];
|
||||
@ -251,6 +288,7 @@ inline Foam::labelRange Foam::globalIndex::range() const
|
||||
|
||||
inline bool Foam::globalIndex::isLocal(const label proci, const label i) const
|
||||
{
|
||||
// range contains()
|
||||
return i >= offsets_[proci] && i < offsets_[proci+1];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user