ENH: partly align globalIndex and CompactListList methods

- CompactListList::size() corresponds to the number of sub-lists
  whereas globalIndex::size() corresponds to the totalSize().
  This difference can lead to potential coding errors when switching
  between pure addressing (eg globalIndex) and addressing with content
  (eg, CompactListList).

  Within the source tree, there are no longer any occurances of
  globalIndex::size() but it is nonetheless unsafe to change its
  meaning now. Instead provide a commonly named length() method that
  corresponds to the natural length: ie, the number of offsets minus 1
  (with guards).

- add CompactListList::writeMatrix for writing the compact contents
  in an unpacked form (eg, for debugging) without actually needing to
  unpack into storage.

- provide globalIndex::whichProcID() two-parameter version
  with myProcNo as the first argument.
  Symmetric with isLocal etc, useful when using a communicator
  that is not worldComm.
This commit is contained in:
Mark Olesen
2023-11-05 16:19:51 +01:00
parent 0338cf9a84
commit 507805c330
7 changed files with 161 additions and 78 deletions

View File

@ -171,7 +171,8 @@ int main(int argc, char *argv[])
CompactListList<label>::pack(subfaces)
);
Info<< "compact faces:" << subCompact << endl;
Info<< "deserialized:" << subCompact.unpack() << endl;
Info<< "matrix content:" << nl;
subCompact.writeMatrix(Info) << endl;
}
return 0;

View File

@ -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.
@ -144,34 +144,54 @@ Foam::CompactListList<T> Foam::CompactListList<T>::pack
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class T>
Foam::CompactListList<T>::CompactListList(const labelUList& listSizes)
Foam::label Foam::CompactListList<T>::resize_offsets
(
const labelUList& listSizes,
const bool checkOverflow
)
{
const label len = listSizes.size();
label total = 0;
if (len)
{
offsets_.resize(len+1);
label total = 0;
for (label i = 0; i < len; ++i)
{
offsets_[i] = total;
total += listSizes[i];
#ifdef FULLDEBUG
if (total < offsets_[i])
if (checkOverflow && total < offsets_[i])
{
reportOverflowAndExit(i, listSizes);
}
#endif
}
offsets_[len] = total;
values_.resize(total);
}
else
{
clear();
}
return total;
}
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
template<class T>
Foam::CompactListList<T>::CompactListList(const labelUList& listSizes)
{
#ifdef FULLDEBUG
const label total = resize_offsets(listSizes, true);
#else
const label total = resize_offsets(listSizes, false);
#endif
values_.resize(total);
}
@ -182,29 +202,12 @@ Foam::CompactListList<T>::CompactListList
const T& val
)
{
const label len = listSizes.size();
if (len)
{
offsets_.resize(len+1);
label total = 0;
for (label i = 0; i < len; ++i)
{
offsets_[i] = total;
total += listSizes[i];
#ifdef FULLDEBUG
if (total < offsets_[i])
{
reportOverflowAndExit(i, listSizes);
}
#endif
}
offsets_[len] = total;
values_.resize(total, val);
}
#ifdef FULLDEBUG
const label total = resize_offsets(listSizes, true);
#else
const label total = resize_offsets(listSizes, false);
#endif
values_.resize(total, val);
}
@ -282,32 +285,24 @@ Foam::CompactListList<T>::ranges() const
template<class T>
void Foam::CompactListList<T>::resize(const labelUList& listSizes)
{
const label len = listSizes.size();
#ifdef FULLDEBUG
const label total = resize_offsets(listSizes, true);
#else
const label total = resize_offsets(listSizes, false);
#endif
values_.resize(total);
}
if (len)
{
offsets_.resize(len+1);
label total = 0;
for (label i = 0; i < len; ++i)
{
offsets_[i] = total;
total += listSizes[i];
#if 0
if (checkOverflow && total < offsets_[i])
{
reportOverflowAndExit(i, listSizes);
}
#endif
}
offsets_[len] = total;
values_.resize(total);
}
else
{
clear();
}
template<class T>
void Foam::CompactListList<T>::resize_nocopy(const labelUList& listSizes)
{
#ifdef FULLDEBUG
const label total = resize_offsets(listSizes, true);
#else
const label total = resize_offsets(listSizes, false);
#endif
values_.resize_nocopy(total);
}

View File

@ -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.
@ -98,11 +98,19 @@ class CompactListList
);
//- Avoid poorly sized offsets/values
void enforceSizeSanity();
inline void enforceSizeSanity();
//- The max of localSizes, excluding the specified row
label maxNonLocalSize(const label rowi) const;
//- Change the offset table based on the sizes
//- and return the total number of values to be stored but
//- does not touch the values array (unless the list is empty)
label resize_offsets
(
const labelUList& listSizes,
const bool checkOverflow = false
);
public:
@ -202,6 +210,9 @@ public:
//- (for example).
inline bool single() const noexcept;
//- The primary size (the number of rows/sublists)
inline label length() const noexcept;
//- The primary size (the number of rows/sublists)
inline label size() const noexcept;
@ -299,6 +310,10 @@ public:
//- Reset dimensions of CompactListList
void resize(const labelUList& listSizes);
//- Reset dimensions of CompactListList
//- \em without preserving existing content
void resize_nocopy(const labelUList& listSizes);
//- Alter local addressing size for given row, does not change content
void setLocalSize(const label rowi, const label len);
@ -390,6 +405,9 @@ public:
inline const T& operator()(const label i, const label j) const;
// Iteration (FUTURE)
// Reading/writing
//- Read CompactListList as offsets/values pair from Istream,
@ -399,6 +417,9 @@ public:
//- Write CompactListList as offsets/values pair
Ostream& writeList(Ostream& os, const label shortLen=0) const;
//- Write CompactListList as a formatted matrix of values (ASCII)
Ostream& writeMatrix(Ostream& os, const label shortLen=0) const;
// IO Operators

View File

@ -183,9 +183,9 @@ 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);
// Note: could (should?) also check total size??
// const label len = (offsets_.size() - 1);
// return (len < 1) || (*(offsets_.cdata() + len) == 0);
return (offsets_.size() <= 1);
}
@ -197,6 +197,14 @@ inline bool Foam::CompactListList<T>::single() const noexcept
}
template<class T>
inline Foam::label Foam::CompactListList<T>::length() const noexcept
{
const label len = (offsets_.size() - 1);
return (len < 1) ? static_cast<label>(0) : len;
}
template<class T>
inline Foam::label Foam::CompactListList<T>::size() const noexcept
{
@ -375,6 +383,7 @@ inline void Foam::CompactListList<T>::resize
{
offsets_.resize(mRows+1, Zero);
values_.resize(nVals);
// Optionally: enforceSizeSanity();
}
@ -387,6 +396,7 @@ inline void Foam::CompactListList<T>::resize_nocopy
{
offsets_.resize(mRows+1, Zero);
values_.resize_nocopy(nVals);
// Optionally: enforceSizeSanity();
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 OpenCFD Ltd.
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -65,4 +65,34 @@ Foam::Ostream& Foam::CompactListList<T>::writeList
}
template<class T>
Foam::Ostream& Foam::CompactListList<T>::writeMatrix
(
Ostream& os,
const label shortLen
) const
{
const CompactListList<T>& mat = *this;
const auto oldFmt = os.format(IOstreamOption::ASCII);
// Write like multi-line matrix of rows (ASCII)
// TBD: with/without indenting?
const label nRows = mat.length();
os << nRows << nl << token::BEGIN_LIST << nl;
for (label i = 0; i < nRows; ++i)
{
mat.localList(i).writeList(os, shortLen) << nl;
}
os << token::END_LIST << nl;
os.format(oldFmt);
return os;
}
// ************************************************************************* //

View File

@ -67,7 +67,7 @@ class globalIndex
{
// Private Data
//- Start of proci. Size is nProcs()+1. (so like CompactListList)
//- Offset (addressing) table - like CompactListList
labelList offsets_;
@ -182,7 +182,11 @@ public:
//- Check for default constructed or total-size == 0
inline bool empty() const noexcept;
//- The number of items covered by the offsets
inline label length() const noexcept;
//- Global sum of localSizes. Same as totalSize()
FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - less ambiguous")
inline label size() const;
//- The span size covered by the offsets, zero if empty
@ -223,7 +227,8 @@ public:
//- Such content is often created with gatherNone.
inline bool single() const noexcept;
//- The number of processors covered by the offsets
//- The number of processors covered by the offsets,
//- same as the primary length()
inline label nProcs() const noexcept;
//- Range of process indices for all addressed offsets (processes)
@ -353,6 +358,10 @@ public:
//- Fatal for out of range ids (eg, negative or >= totalSize()
inline label whichProcID(const label i) const;
//- Which processor does global id come from?
//- Checks proci first.
inline label whichProcID(const label proci, const label i) const;
// Queries relating to myProcNo (Caution: uses UPstream::worldComm)

View File

@ -131,6 +131,19 @@ inline bool Foam::globalIndex::empty() const noexcept
}
inline bool Foam::globalIndex::single() const noexcept
{
return (offsets_.size() == 2);
}
inline Foam::label Foam::globalIndex::length() const noexcept
{
const label len = (offsets_.size() - 1);
return (len < 1) ? 0 : len;
}
inline Foam::label Foam::globalIndex::span() const noexcept
{
return (end_value() - begin_value());
@ -168,16 +181,9 @@ 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);
return (len < 1) ? 0 : len;
return length();
}
@ -390,7 +396,11 @@ inline Foam::label Foam::globalIndex::toLocal(const label i) const
}
inline Foam::label Foam::globalIndex::whichProcID(const label i) const
inline Foam::label Foam::globalIndex::whichProcID
(
const label proci,
const label i
) const
{
if (i < 0 || i >= totalSize())
{
@ -400,12 +410,19 @@ inline Foam::label Foam::globalIndex::whichProcID(const label i) const
<< abort(FatalError);
}
const auto proci = UPstream::myProcNo(UPstream::worldComm);
return isLocal(proci, i) ? proci : findLower(offsets_, i+1);
}
inline Foam::label Foam::globalIndex::whichProcID
(
const label i
) const
{
return whichProcID(UPstream::myProcNo(UPstream::worldComm), i);
}
inline void Foam::globalIndex::reset
(
const globalIndex::gatherNone,
@ -571,7 +588,7 @@ Foam::globalIndex::cbegin() const noexcept
inline const Foam::globalIndex::const_iterator
Foam::globalIndex::cend() const noexcept
{
return const_iterator(this, this->nProcs());
return const_iterator(this, this->length());
}
@ -585,14 +602,14 @@ Foam::globalIndex::begin() const noexcept
inline const Foam::globalIndex::const_iterator
Foam::globalIndex::end() const noexcept
{
return const_iterator(this, this->nProcs());
return const_iterator(this, this->length());
}
inline Foam::globalIndex::const_iterator
Foam::globalIndex::cbegin(const label i) const noexcept
{
const label len = this->nProcs();
const label len = this->length();
return const_iterator(this, (i < 0 ? 0 : len < i ? len : i));
}