STYLE: adjust globalIndex/CompactListList overflow reporting

- report location with previous good offset and the new count that
  would cause overflow. Simpler to report and the (very long) list
  of input sizes is not particularly useful for diagnostics either.

ENH: add globalIndex comparison operators

- for outputting lists of globalIndex
This commit is contained in:
Mark Olesen 2023-11-18 11:48:08 +01:00
parent 5e0cafa637
commit ef201ecfea
6 changed files with 134 additions and 63 deletions

View File

@ -35,16 +35,25 @@ template<class T>
void Foam::CompactListList<T>::reportOverflowAndExit
(
const label idx,
const labelUList& localLens
const label prevOffset,
const label count
)
{
if (idx < 0)
{
// No overflow tagged
return;
}
FatalErrorInFunction
<< "Overflow : sum of sizes exceeds labelMax ("
<< labelMax << ") after index " << idx;
if (!localLens.empty())
if (prevOffset >= 0 && count >= 0)
{
FatalError << " of " << flatOutput(localLens);
FatalError
<< " while trying to add (" << count
<< ") to offset (" << prevOffset << ")";
}
FatalError
@ -76,12 +85,14 @@ Foam::CompactListList<T> Foam::CompactListList<T>::pack_impl
for (label i = 0; i < len; ++i)
{
const label count = lists[i].size();
newOffsets[i] = total;
total += lists[i].size();
total += count;
if (checkOverflow && total < newOffsets[i])
{
reportOverflowAndExit(i);
reportOverflowAndExit(i, newOffsets[i], count);
}
}
newOffsets[len] = total;
@ -162,12 +173,14 @@ Foam::label Foam::CompactListList<T>::resize_offsets
for (label i = 0; i < len; ++i)
{
const label count = listSizes[i];
offsets_[i] = total;
total += listSizes[i];
total += count;
if (checkOverflow && total < offsets_[i])
{
reportOverflowAndExit(i, listSizes);
reportOverflowAndExit(i, offsets_[i], count);
}
}
@ -229,8 +242,8 @@ Foam::label Foam::CompactListList<T>::maxNonLocalSize(const label rowi) const
{
if (i != rowi)
{
const label localLen = (offsets_[i+1] - offsets_[i]);
maxLen = max(maxLen, localLen);
const label count = (offsets_[i+1] - offsets_[i]);
maxLen = max(maxLen, count);
}
}

View File

@ -82,11 +82,12 @@ class CompactListList
// Private Member Functions
//- Report overflow at specified index
//- Report overflow at specified (non-negative) index
static void reportOverflowAndExit
(
const label idx,
const labelUList& listSizes = labelUList::null()
const label prevOffset = -1, // The last valid offset value
const label count = 0 // The count to add to prevOffset
);
//- Construct by packing together the list of lists

View File

@ -34,16 +34,25 @@ License
void Foam::globalIndex::reportOverflowAndExit
(
const label idx,
const labelUList& localLens
const label prevOffset,
const label count
)
{
if (idx < 0)
{
// No overflow tagged
return;
}
FatalErrorInFunction
<< "Overflow : sum of sizes exceeds labelMax ("
<< labelMax << ") after index " << idx;
if (!localLens.empty())
if (prevOffset >= 0 && count >= 0)
{
FatalError << " of " << flatOutput(localLens);
FatalError
<< " while trying to add (" << count
<< ") to offset (" << prevOffset << ")";
}
FatalError
@ -70,27 +79,29 @@ Foam::globalIndex::calcRange
}
const label myProci = UPstream::myProcNo(comm);
const labelList localLens = UPstream::allGatherValues(localSize, comm);
const labelList counts = UPstream::allGatherValues(localSize, comm);
if (checkOverflow)
{
const label len = localLens.size();
const label len = counts.size();
label start = 0;
for (label i = 0; i < len; ++i)
{
const label count = counts[i];
if (i == myProci)
{
myRange.start() = start;
}
const label prev = start;
start += localLens[i];
start += count;
if (start < prev)
{
reportOverflowAndExit(i, localLens);
reportOverflowAndExit(i, prev, count);
}
}
}
@ -98,8 +109,8 @@ Foam::globalIndex::calcRange
{
// std::accumulate
// (
// localLens.cbegin(),
// localLens.cbegin(myProci),
// counts.cbegin(),
// counts.cbegin(myProci),
// label(0)
// );
@ -107,7 +118,7 @@ Foam::globalIndex::calcRange
for (label i = 0; i < myProci; ++i)
{
start += localLens[i];
start += counts[i];
}
myRange.start() = start;
}
@ -133,27 +144,28 @@ Foam::globalIndex::calcOffset
}
const label myProci = UPstream::myProcNo(comm);
const labelList localLens = UPstream::allGatherValues(localSize, comm);
const labelList counts = UPstream::allGatherValues(localSize, comm);
if (checkOverflow)
{
const label len = localLens.size();
const label len = counts.size();
label start = 0;
for (label i = 0; i < len; ++i)
{
const label count = counts[i];
if (i == myProci)
{
myOffset = start;
}
const label prev = start;
start += localLens[i];
start += count;
if (start < prev)
{
reportOverflowAndExit(i, localLens);
reportOverflowAndExit(i, prev, count);
}
}
}
@ -161,8 +173,8 @@ Foam::globalIndex::calcOffset
{
// std::accumulate
// (
// localLens.cbegin(),
// localLens.cbegin(myProci),
// counts.cbegin(),
// counts.cbegin(myProci),
// label(0)
// );
@ -170,7 +182,7 @@ Foam::globalIndex::calcOffset
for (label i = 0; i < myProci; ++i)
{
start += localLens[i];
start += counts[i];
}
myOffset = start;
}
@ -182,13 +194,13 @@ Foam::globalIndex::calcOffset
Foam::labelList
Foam::globalIndex::calcOffsets
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow
)
{
labelList values;
const label len = localLens.size();
const label len = counts.size();
if (len)
{
@ -197,12 +209,13 @@ Foam::globalIndex::calcOffsets
label start = 0;
for (label i = 0; i < len; ++i)
{
const label count = counts[i];
values[i] = start;
start += localLens[i];
start += count;
if (checkOverflow && start < values[i])
{
reportOverflowAndExit(i, localLens);
reportOverflowAndExit(i, values[i], count);
}
}
values[len] = start;
@ -215,13 +228,13 @@ Foam::globalIndex::calcOffsets
Foam::List<Foam::labelRange>
Foam::globalIndex::calcRanges
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow
)
{
List<labelRange> values;
const label len = localLens.size();
const label len = counts.size();
if (len)
{
@ -230,12 +243,18 @@ Foam::globalIndex::calcRanges
label start = 0;
for (label i = 0; i < len; ++i)
{
values[i].reset(start, localLens[i]);
start += localLens[i];
const label count = counts[i];
values[i].reset(start, count);
start += count;
if (checkOverflow && start < values[i].start())
if
(
checkOverflow
&& (start < values[i].start())
&& (i < len-1) // Do not check the one beyond the end range
)
{
reportOverflowAndExit(i, localLens);
reportOverflowAndExit(i, values[i].start(), count);
}
}
}
@ -328,11 +347,11 @@ void Foam::globalIndex::reset
if (len)
{
labelList localLens;
labelList counts;
if (parallel && UPstream::parRun()) // or UPstream::is_parallel(comm)
{
localLens = UPstream::allGatherValues(localSize, comm);
counts = UPstream::allGatherValues(localSize, comm);
}
else
{
@ -340,11 +359,11 @@ void Foam::globalIndex::reset
// TBD: check for (proci >= 0) ?
const auto proci = UPstream::myProcNo(comm);
localLens.resize(len, Zero);
localLens[proci] = localSize;
counts.resize(len, Zero);
counts[proci] = localSize;
}
reset(localLens, true); // checkOverflow = true
reset(counts, true); // checkOverflow = true
}
else
{
@ -356,11 +375,11 @@ void Foam::globalIndex::reset
void Foam::globalIndex::reset
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow
)
{
const label len = localLens.size();
const label len = counts.size();
if (len)
{
@ -369,12 +388,13 @@ void Foam::globalIndex::reset
label start = 0;
for (label i = 0; i < len; ++i)
{
const label count = counts[i];
offsets_[i] = start;
start += localLens[i];
start += count;
if (checkOverflow && start < offsets_[i])
{
reportOverflowAndExit(i, localLens);
reportOverflowAndExit(i, offsets_[i], count);
}
}
offsets_[len] = start;
@ -468,8 +488,8 @@ Foam::label Foam::globalIndex::maxNonLocalSize(const label proci) const
{
if (i != proci)
{
const label localLen = (offsets_[i+1] - offsets_[i]);
maxLen = max(maxLen, localLen);
const label count = (offsets_[i+1] - offsets_[i]);
maxLen = max(maxLen, count);
}
}
@ -506,17 +526,17 @@ Foam::labelRange Foam::globalIndex::back() const
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, globalIndex& gi)
{
return is >> gi.offsets_;
return is >> gi.offsets();
}
Foam::Ostream& Foam::operator<<(Ostream& os, const globalIndex& gi)
{
return os << gi.offsets_;
return os << gi.offsets();
}

View File

@ -83,11 +83,12 @@ class globalIndex
DynamicList<label>& validBins
);
//- Report overflow at specified index
//- Report overflow at specified (non-negative) index
static void reportOverflowAndExit
(
const label idx,
const labelUList& localLens = labelUList::null()
const label prevOffset = -1, // The last valid offset value
const label count = 0 // The count to add to prevOffset
);
public:
@ -122,7 +123,7 @@ public:
//- No communication required
inline explicit globalIndex(labelList&& listOffsets);
//- Copy construct from a list of sizes.
//- Construct from a list of sizes and calculate the offsets.
//- No communication required
inline globalIndex
(
@ -265,12 +266,12 @@ public:
const bool parallel = UPstream::parRun() //!< use parallel comms
);
//- Reset from list of local sizes,
//- Reset offsets from a list of local sizes,
//- with optional check for label overflow.
//- No communication required
void reset
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow = false
);
@ -307,6 +308,9 @@ public:
const label comm = UPstream::worldComm //!< communicator
);
//- Reset the globalIndex. Same as copy assignment.
inline void reset(const globalIndex& gi);
//- Alter local size for given processor
void setLocalSize(const label proci, const label len);
@ -504,7 +508,7 @@ public:
//- with optional check for label overflow
static labelList calcOffsets
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow = false
);
@ -521,7 +525,7 @@ public:
//- with optional check for label overflow
static List<labelRange> calcRanges
(
const labelUList& localLens,
const labelUList& counts,
const bool checkOverflow = false
);
@ -955,6 +959,27 @@ public:
) const;
// Member Operators
//- Compare for equality - uses the offsets
bool operator==(const globalIndex& rhs) const
{
return (this->offsets() == rhs.offsets());
}
//- Compare for inequality - uses the offsets
bool operator!=(const globalIndex& rhs) const
{
return !(*this == rhs);
}
//- Compare for less-than - uses the offsets
bool operator<(const globalIndex& rhs) const
{
return (this->offsets() < rhs.offsets());
}
// IOstream Operators
friend Istream& operator>>(Istream& is, globalIndex& gi);

View File

@ -467,6 +467,16 @@ inline void Foam::globalIndex::reset
}
inline void Foam::globalIndex::reset(const globalIndex& rhs)
{
if (this == &rhs)
{
return; // Self-assignment is a no-op
}
this->offsets_ = rhs.offsets_;
}
// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
inline Foam::globalIndex::const_iterator::

View File

@ -49,12 +49,14 @@ Foam::globalIndex::calcListOffsets
label start = 0;
for (label i = 0; i < len; ++i)
{
const label count = lists[i].size();
values[i] = start;
start += lists[i].size();
start += count;
if (checkOverflow && start < values[i])
{
reportOverflowAndExit(i);
reportOverflowAndExit(i, values[i], count);
}
}
values[len] = start;
@ -1005,12 +1007,12 @@ OutputContainer Foam::globalIndex::scatter
// The globalIndex might be correct on master only,
// so scatter local sizes to ensure consistency
const label localLen
const label count
(
UPstream::listScatterValues<label>(this->localSizes(), comm)
);
OutputContainer localData(localLen);
OutputContainer localData(count);
this->scatter(allData, localData, tag, commsType, comm);
return localData;