From 35facb8208fde43986efe271ab4be903a42674de Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Wed, 1 Aug 2018 12:48:35 +0200 Subject: [PATCH] ENH: add PackedList::unpack() method - allows for simpler unpacking of a full list, or list range into any sufficiently large integral type. For example, processorPolyPatch pp = ...; UOPstream toNbr(pp.neighbProcNo(), pBufs); toNbr << faceValues.unpack<char>(pp.range()); --- .../test/PackedList/Test-PackedList.C | 22 ++--- .../test/PackedList1/Test-PackedList1.C | 12 +++ .../containers/Bits/PackedList/PackedList.C | 93 ++++++++++++++++++- .../containers/Bits/PackedList/PackedList.H | 16 ++++ src/OpenFOAM/containers/Bits/bitSet/bitSet.H | 6 +- .../meshes/polyMesh/syncTools/syncTools.H | 16 ++-- .../polyMesh/syncTools/syncToolsTemplates.C | 16 ++-- 7 files changed, 148 insertions(+), 33 deletions(-) diff --git a/applications/test/PackedList/Test-PackedList.C b/applications/test/PackedList/Test-PackedList.C index f2ae2e923a2..35ad7f2dd8c 100644 --- a/applications/test/PackedList/Test-PackedList.C +++ b/applications/test/PackedList/Test-PackedList.C @@ -38,30 +38,30 @@ Description using namespace Foam; -template<unsigned nBits> +template<unsigned Width> inline void reportInfo() { - const unsigned offset = PackedList<nBits>::elem_per_block; + const unsigned offset = PackedList<Width>::elem_per_block; - unsigned useSHL = ((1u << (nBits * offset)) - 1); - unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset)); + unsigned useSHL = ((1u << (Width * offset)) - 1); + unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - Width * offset)); Info<< nl - << "PackedList<" << nBits << ">" << nl - << " max_value: " << PackedList<nBits>::max_value << nl - << " packing: " << PackedList<nBits>::elem_per_block << nl - << " utilization: " << (nBits * offset) << nl; + << "PackedList<" << Width << ">" << nl + << " max_value: " << PackedList<Width>::max_value << nl + << " packing: " << PackedList<Width>::elem_per_block << nl + << " utilization: " << (Width * offset) << nl; Info<< " Masking:" << nl << " shift << " - << unsigned(nBits * offset) << nl + << unsigned(Width * offset) << nl << " shift >> " - << unsigned((sizeof(unsigned)*CHAR_BIT) - nBits * offset) + << unsigned((sizeof(unsigned)*CHAR_BIT) - Width * offset) << nl; hex(Info); Info<< " maskLower: " - << PackedList<nBits>::mask_lower(PackedList<nBits>::elem_per_block) + << PackedList<Width>::mask_lower(PackedList<Width>::elem_per_block) << nl << " useSHL: " << useSHL << nl << " useSHR: " << useSHR << nl; diff --git a/applications/test/PackedList1/Test-PackedList1.C b/applications/test/PackedList1/Test-PackedList1.C index b9e023baff3..81a212ddaa1 100644 --- a/applications/test/PackedList1/Test-PackedList1.C +++ b/applications/test/PackedList1/Test-PackedList1.C @@ -118,6 +118,18 @@ int main(int argc, char *argv[]) list1.set(14, 2); report(list1); + Info<< "values() : " << flatOutput(list1.unpack<char>()) << nl + << "values(5,8) : " << flatOutput(list1.unpack<char>(labelRange(5,8))) + << nl; + + { + labelList locations({-5, -2, 2, 1, 8}); + + Info<< "values at " << flatOutput(locations) << " = " + << flatOutput(list1.unpack<char>(locations)) + << nl; + } + Info<< "\ntest operator== between references\n"; if (list1[1] == list1[8]) { diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.C b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C index 9f636b2c413..79a7911ed7c 100644 --- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.C +++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C @@ -83,14 +83,34 @@ bool Foam::PackedList<Width>::uniform() const template<unsigned Width> Foam::labelList Foam::PackedList<Width>::values() const { + return this->unpack<label>(); +} + + +template<unsigned Width> +template<class IntType> +Foam::List<IntType> +Foam::PackedList<Width>::unpack() const +{ + static_assert + ( + std::is_integral<IntType>::value, + "Integral required for output." + ); + static_assert + ( + std::numeric_limits<IntType>::digits >= Width, + "Width of IntType is too small to hold result" + ); + if (size() < 2 || uniform()) { - const label val = (size() ? get(0) : 0); + const IntType val = (size() ? get(0) : 0); - return labelList(size(), val); + return List<IntType>(size(), val); } - labelList output(size()); + List<IntType> output(size()); label outi = 0; // Process n-1 complete blocks @@ -102,7 +122,7 @@ Foam::labelList Foam::PackedList<Width>::values() const for (unsigned nget = elem_per_block; nget; --nget, ++outi) { - output[outi] = label(blockval & max_value); + output[outi] = IntType(blockval & max_value); blockval >>= Width; } } @@ -117,4 +137,69 @@ Foam::labelList Foam::PackedList<Width>::values() const } +template<unsigned Width> +template<class IntType> +Foam::List<IntType> +Foam::PackedList<Width>::unpack(const labelRange& range) const +{ + static_assert + ( + std::is_integral<IntType>::value, + "Integral required for unpack output." + ); + static_assert + ( + std::numeric_limits<IntType>::digits >= Width, + "Width of IntType is too small to hold unpack output." + ); + + + // Could be more efficient but messier with block-wise access. + // - automatically handles any invalid positions + + auto pos = range.start(); + + List<IntType> output(range.size()); + + for (IntType& out : output) + { + out = IntType(get(pos)); + ++pos; + } + + return output; +} + + +template<unsigned Width> +template<class IntType> +Foam::List<IntType> +Foam::PackedList<Width>::unpack(const labelUList& locations) const +{ + static_assert + ( + std::is_integral<IntType>::value, + "Integral required for unpack output." + ); + static_assert + ( + std::numeric_limits<IntType>::digits >= Width, + "Width of IntType is too small to hold unpack output." + ); + + + label pos = 0; + + List<IntType> output(locations.size()); + + for (IntType& out : output) + { + out = IntType(get(locations[pos])); + ++pos; + } + + return output; +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H index 700ffb6db52..8a133069d6b 100644 --- a/src/OpenFOAM/containers/Bits/PackedList/PackedList.H +++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H @@ -294,6 +294,22 @@ public: //- Return the values as a list of labels labelList values() const; + //- Return the values as a list of integral type. + // The default integral type is unsigned int. + template<class IntType = unsigned int> + List<IntType> unpack() const; + + //- Return the range of values as a list of integral type. + // The default integral type is unsigned int. + template<class IntType = unsigned int> + List<IntType> unpack(const labelRange& range) const; + + //- Extract the values for the specified locations as + //- a list of integral type. + // The default integral type is unsigned int. + template<class IntType = unsigned int> + List<IntType> unpack(const labelUList& locations) const; + // Edit diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H index 9f033ca2976..2acade14166 100644 --- a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H +++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H @@ -248,6 +248,7 @@ public: inline labelList sortedToc() const; //- Return the bitset values as a boolList. + // When the output is a bool, this is more efficient than unpack() List<bool> values() const; @@ -522,17 +523,18 @@ public: return *this; } + // Housekeeping //- Identical to toc() - // \deprecated compatibility method for PackedBoolList (APR-2018) + // \deprecated compatibility name for PackedBoolList (APR-2018) inline labelList used() const { return toc(); } }; // Global Operators -// + Ostream& operator<<(Ostream& os, const InfoProxy<bitSet>& info); Ostream& operator<<(Ostream& os, const bitSet& bitset); diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H index 6c19c323fbf..e81db709295 100644 --- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H +++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H @@ -552,36 +552,36 @@ public: // PackedList versions - template<unsigned nBits, class CombineOp> + template<unsigned Width, class CombineOp> static void syncFaceList ( const polyMesh& mesh, - PackedList<nBits>& faceValues, + PackedList<Width>& faceValues, const CombineOp& cop, const bool parRun = Pstream::parRun() ); - template<unsigned nBits> + template<unsigned Width> static void swapFaceList ( const polyMesh& mesh, - PackedList<nBits>& faceValues + PackedList<Width>& faceValues ); - template<unsigned nBits, class CombineOp> + template<unsigned Width, class CombineOp> static void syncPointList ( const polyMesh& mesh, - PackedList<nBits>& pointValues, + PackedList<Width>& pointValues, const CombineOp& cop, const unsigned int nullValue ); - template<unsigned nBits, class CombineOp> + template<unsigned Width, class CombineOp> static void syncEdgeList ( const polyMesh& mesh, - PackedList<nBits>& edgeValues, + PackedList<Width>& edgeValues, const CombineOp& cop, const unsigned int nullValue ); diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C index 4f5ad0b5c6d..66ffd62cb39 100644 --- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C +++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncToolsTemplates.C @@ -1413,11 +1413,11 @@ void Foam::syncTools::syncBoundaryFaceList // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template<unsigned nBits, class CombineOp> +template<unsigned Width, class CombineOp> void Foam::syncTools::syncFaceList ( const polyMesh& mesh, - PackedList<nBits>& faceValues, + PackedList<Width>& faceValues, const CombineOp& cop, const bool parRun ) @@ -1564,22 +1564,22 @@ void Foam::syncTools::swapBoundaryCellList } -template<unsigned nBits> +template<unsigned Width> void Foam::syncTools::swapFaceList ( const polyMesh& mesh, - PackedList<nBits>& faceValues + PackedList<Width>& faceValues ) { syncFaceList(mesh, faceValues, eqOp<unsigned int>()); } -template<unsigned nBits, class CombineOp> +template<unsigned Width, class CombineOp> void Foam::syncTools::syncPointList ( const polyMesh& mesh, - PackedList<nBits>& pointValues, + PackedList<Width>& pointValues, const CombineOp& cop, const unsigned int nullValue ) @@ -1618,11 +1618,11 @@ void Foam::syncTools::syncPointList } -template<unsigned nBits, class CombineOp> +template<unsigned Width, class CombineOp> void Foam::syncTools::syncEdgeList ( const polyMesh& mesh, - PackedList<nBits>& edgeValues, + PackedList<Width>& edgeValues, const CombineOp& cop, const unsigned int nullValue ) -- GitLab