mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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());
This commit is contained in:
@ -38,30 +38,30 @@ Description
|
|||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
template<unsigned nBits>
|
template<unsigned Width>
|
||||||
inline void reportInfo()
|
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 useSHL = ((1u << (Width * offset)) - 1);
|
||||||
unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - nBits * offset));
|
unsigned useSHR = (~0u >> (sizeof(unsigned)*CHAR_BIT - Width * offset));
|
||||||
|
|
||||||
Info<< nl
|
Info<< nl
|
||||||
<< "PackedList<" << nBits << ">" << nl
|
<< "PackedList<" << Width << ">" << nl
|
||||||
<< " max_value: " << PackedList<nBits>::max_value << nl
|
<< " max_value: " << PackedList<Width>::max_value << nl
|
||||||
<< " packing: " << PackedList<nBits>::elem_per_block << nl
|
<< " packing: " << PackedList<Width>::elem_per_block << nl
|
||||||
<< " utilization: " << (nBits * offset) << nl;
|
<< " utilization: " << (Width * offset) << nl;
|
||||||
|
|
||||||
Info<< " Masking:" << nl
|
Info<< " Masking:" << nl
|
||||||
<< " shift << "
|
<< " shift << "
|
||||||
<< unsigned(nBits * offset) << nl
|
<< unsigned(Width * offset) << nl
|
||||||
<< " shift >> "
|
<< " shift >> "
|
||||||
<< unsigned((sizeof(unsigned)*CHAR_BIT) - nBits * offset)
|
<< unsigned((sizeof(unsigned)*CHAR_BIT) - Width * offset)
|
||||||
<< nl;
|
<< nl;
|
||||||
|
|
||||||
hex(Info);
|
hex(Info);
|
||||||
Info<< " maskLower: "
|
Info<< " maskLower: "
|
||||||
<< PackedList<nBits>::mask_lower(PackedList<nBits>::elem_per_block)
|
<< PackedList<Width>::mask_lower(PackedList<Width>::elem_per_block)
|
||||||
<< nl
|
<< nl
|
||||||
<< " useSHL: " << useSHL << nl
|
<< " useSHL: " << useSHL << nl
|
||||||
<< " useSHR: " << useSHR << nl;
|
<< " useSHR: " << useSHR << nl;
|
||||||
|
|||||||
@ -118,6 +118,18 @@ int main(int argc, char *argv[])
|
|||||||
list1.set(14, 2);
|
list1.set(14, 2);
|
||||||
report(list1);
|
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";
|
Info<< "\ntest operator== between references\n";
|
||||||
if (list1[1] == list1[8])
|
if (list1[1] == list1[8])
|
||||||
{
|
{
|
||||||
|
|||||||
@ -83,14 +83,34 @@ bool Foam::PackedList<Width>::uniform() const
|
|||||||
template<unsigned Width>
|
template<unsigned Width>
|
||||||
Foam::labelList Foam::PackedList<Width>::values() const
|
Foam::labelList Foam::PackedList<Width>::values() const
|
||||||
{
|
{
|
||||||
if (size() < 2 || uniform())
|
return this->unpack<label>();
|
||||||
{
|
|
||||||
const label val = (size() ? get(0) : 0);
|
|
||||||
|
|
||||||
return labelList(size(), val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
labelList output(size());
|
|
||||||
|
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 IntType val = (size() ? get(0) : 0);
|
||||||
|
|
||||||
|
return List<IntType>(size(), val);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IntType> output(size());
|
||||||
label outi = 0;
|
label outi = 0;
|
||||||
|
|
||||||
// Process n-1 complete blocks
|
// 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)
|
for (unsigned nget = elem_per_block; nget; --nget, ++outi)
|
||||||
{
|
{
|
||||||
output[outi] = label(blockval & max_value);
|
output[outi] = IntType(blockval & max_value);
|
||||||
blockval >>= Width;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -294,6 +294,22 @@ public:
|
|||||||
//- Return the values as a list of labels
|
//- Return the values as a list of labels
|
||||||
labelList values() const;
|
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
|
// Edit
|
||||||
|
|
||||||
|
|||||||
@ -248,6 +248,7 @@ public:
|
|||||||
inline labelList sortedToc() const;
|
inline labelList sortedToc() const;
|
||||||
|
|
||||||
//- Return the bitset values as a boolList.
|
//- Return the bitset values as a boolList.
|
||||||
|
// When the output is a bool, this is more efficient than unpack()
|
||||||
List<bool> values() const;
|
List<bool> values() const;
|
||||||
|
|
||||||
|
|
||||||
@ -522,17 +523,18 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Housekeeping
|
// Housekeeping
|
||||||
|
|
||||||
//- Identical to toc()
|
//- Identical to toc()
|
||||||
// \deprecated compatibility method for PackedBoolList (APR-2018)
|
// \deprecated compatibility name for PackedBoolList (APR-2018)
|
||||||
inline labelList used() const { return toc(); }
|
inline labelList used() const { return toc(); }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Global Operators
|
// Global Operators
|
||||||
//
|
|
||||||
Ostream& operator<<(Ostream& os, const InfoProxy<bitSet>& info);
|
Ostream& operator<<(Ostream& os, const InfoProxy<bitSet>& info);
|
||||||
Ostream& operator<<(Ostream& os, const bitSet& bitset);
|
Ostream& operator<<(Ostream& os, const bitSet& bitset);
|
||||||
|
|
||||||
|
|||||||
@ -552,36 +552,36 @@ public:
|
|||||||
|
|
||||||
// PackedList versions
|
// PackedList versions
|
||||||
|
|
||||||
template<unsigned nBits, class CombineOp>
|
template<unsigned Width, class CombineOp>
|
||||||
static void syncFaceList
|
static void syncFaceList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& faceValues,
|
PackedList<Width>& faceValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const bool parRun = Pstream::parRun()
|
const bool parRun = Pstream::parRun()
|
||||||
);
|
);
|
||||||
|
|
||||||
template<unsigned nBits>
|
template<unsigned Width>
|
||||||
static void swapFaceList
|
static void swapFaceList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& faceValues
|
PackedList<Width>& faceValues
|
||||||
);
|
);
|
||||||
|
|
||||||
template<unsigned nBits, class CombineOp>
|
template<unsigned Width, class CombineOp>
|
||||||
static void syncPointList
|
static void syncPointList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& pointValues,
|
PackedList<Width>& pointValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const unsigned int nullValue
|
const unsigned int nullValue
|
||||||
);
|
);
|
||||||
|
|
||||||
template<unsigned nBits, class CombineOp>
|
template<unsigned Width, class CombineOp>
|
||||||
static void syncEdgeList
|
static void syncEdgeList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& edgeValues,
|
PackedList<Width>& edgeValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const unsigned int nullValue
|
const unsigned int nullValue
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1413,11 +1413,11 @@ void Foam::syncTools::syncBoundaryFaceList
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<unsigned nBits, class CombineOp>
|
template<unsigned Width, class CombineOp>
|
||||||
void Foam::syncTools::syncFaceList
|
void Foam::syncTools::syncFaceList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& faceValues,
|
PackedList<Width>& faceValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const bool parRun
|
const bool parRun
|
||||||
)
|
)
|
||||||
@ -1564,22 +1564,22 @@ void Foam::syncTools::swapBoundaryCellList
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<unsigned nBits>
|
template<unsigned Width>
|
||||||
void Foam::syncTools::swapFaceList
|
void Foam::syncTools::swapFaceList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& faceValues
|
PackedList<Width>& faceValues
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
syncFaceList(mesh, faceValues, eqOp<unsigned int>());
|
syncFaceList(mesh, faceValues, eqOp<unsigned int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<unsigned nBits, class CombineOp>
|
template<unsigned Width, class CombineOp>
|
||||||
void Foam::syncTools::syncPointList
|
void Foam::syncTools::syncPointList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& pointValues,
|
PackedList<Width>& pointValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const unsigned int nullValue
|
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
|
void Foam::syncTools::syncEdgeList
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
PackedList<nBits>& edgeValues,
|
PackedList<Width>& edgeValues,
|
||||||
const CombineOp& cop,
|
const CombineOp& cop,
|
||||||
const unsigned int nullValue
|
const unsigned int nullValue
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user