Commit 59fa0056 authored by Sebastian Eibl's avatar Sebastian Eibl
Browse files

[API] moved uint utility to core/Uint.h

parent 0c8c717a
......@@ -28,6 +28,7 @@
#include "Types.h"
#include "core/debug/Debug.h"
#include "core/math/Uint.h"
#include "core/timing/TimingPool.h"
#include "domain_decomposition/BlockStorage.h"
......@@ -259,7 +260,7 @@ public:
uint_t getMaxDepth() const
{
#ifdef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
return ( UINT_BITS - treeIdDigits_ ) / uint_t(3);
return ( math::UINT_BITS - treeIdDigits_ ) / uint_t(3);
#else
return std::numeric_limits< uint_t >::max();
#endif
......
......@@ -51,12 +51,12 @@ BlockID::BlockID( const std::vector< uint8_t >& array, const uint_t offset, cons
WALBERLA_ASSERT_UNEQUAL( usedBits_, 0 );
const uint_t blocks = ( usedBits_ / UINT_BITS ) + ( ( (usedBits_ & ( UINT_BITS - 1 )) == 0 ) ? 0 : 1 );
const uint_t blocks = ( usedBits_ / math::UINT_BITS ) + ( ( (usedBits_ & ( math::UINT_BITS - 1 )) == 0 ) ? 0 : 1 );
uint_t b = offset;
for( uint_t i = 0; i != blocks; ++i ) {
blocks_.push_back(0);
for( uint_t j = 0; j != UINT_BYTES && b != offset + bytes; ++j, ++b ) {
for( uint_t j = 0; j != math::UINT_BYTES && b != offset + bytes; ++j, ++b ) {
blocks_.back() |= uint_c( array[b] ) << ( j * 8 );
}
}
......@@ -68,11 +68,11 @@ void BlockID::appendBranchId( const uint_t branchId )
{
WALBERLA_ASSERT( !blocks_.empty() );
WALBERLA_ASSERT_LESS( branchId, 8 );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + math::UINT_BITS * (blocks_.size()-1) );
const uint_t unusedBits = UINT_BITS - ( usedBits_ & ( UINT_BITS - 1 ) );
const uint_t unusedBits = math::UINT_BITS - ( usedBits_ & ( math::UINT_BITS - 1 ) );
if( unusedBits < 3 || unusedBits == UINT_BITS )
if( unusedBits < 3 || unusedBits == math::UINT_BITS )
blocks_.push_back(0);
for( uint_t i = static_cast< uint_t >( blocks_.size() ) - 1; i != 0; --i )
......@@ -81,8 +81,8 @@ void BlockID::appendBranchId( const uint_t branchId )
blocks_[0] = ( blocks_[0] << 3 ) | branchId;
usedBits_ += 3;
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT_GREATER_EQUAL( blocks_.size() * UINT_BITS, usedBits_ );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + math::UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT_GREATER_EQUAL( blocks_.size() * math::UINT_BITS, usedBits_ );
}
......@@ -91,19 +91,19 @@ void BlockID::removeBranchId()
{
WALBERLA_ASSERT( !blocks_.empty() );
WALBERLA_ASSERT_GREATER( usedBits_, 3 );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + math::UINT_BITS * (blocks_.size()-1) );
for( uint_t i = 0; i != static_cast< uint_t >( blocks_.size() ) - 1; ++i )
blocks_[i] = ( blocks_[i] >> 3 ) | ( (blocks_[i+1] & uint_c(7)) << SHIFT );
const uint_t bits = usedBits_ & ( UINT_BITS - 1 );
const uint_t bits = usedBits_ & ( math::UINT_BITS - 1 );
if( 0 < bits && bits < 4 ) blocks_.pop_back();
else blocks_.back() >>= 3;
usedBits_ -= 3;
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_.back() ) + math::UINT_BITS * (blocks_.size()-1) );
WALBERLA_ASSERT( !blocks_.empty() );
}
......@@ -124,7 +124,7 @@ void BlockID::toByteArray( std::vector< uint8_t >& array, const uint_t offset, c
uint_t block = blocks_[i];
for( uint_t j = 0; j != UINT_BYTES && b != offset + bytes; ++j, ++b ) {
for( uint_t j = 0; j != math::UINT_BYTES && b != offset + bytes; ++j, ++b ) {
array[b] = static_cast< uint8_t >( block & uint_c(255) );
block >>= 8;
......
......@@ -25,6 +25,7 @@
#include "Utility.h"
#include "core/debug/Debug.h"
#include "core/math/Uint.h"
#include "core/mpi/RecvBuffer.h"
#include "core/mpi/SendBuffer.h"
......@@ -91,10 +92,10 @@ private:
uint_t usedBits_;
std::vector< uint_t > blocks_;
static const uint_t SHIFT = UINT_BITS - 3;
static const uint_t SHIFT = math::UINT_BITS - 3;
WALBERLA_STATIC_ASSERT( UINT_BITS > 31 );
WALBERLA_STATIC_ASSERT( !(UINT_BITS & (UINT_BITS - 1)) ); // power of two
WALBERLA_STATIC_ASSERT( math::UINT_BITS > 31 );
WALBERLA_STATIC_ASSERT( !(math::UINT_BITS & (math::UINT_BITS - 1)) ); // power of two
}; // class BlockID
......@@ -141,7 +142,7 @@ inline void BlockID::init( const uint_t treeIndex, const uint_t treeIdMarker )
inline uint_t BlockID::getTreeId() const
{
WALBERLA_ASSERT_GREATER( usedBits_, 0 );
WALBERLA_ASSERT_LESS_EQUAL( usedBits_, UINT_BITS );
WALBERLA_ASSERT_LESS_EQUAL( usedBits_, math::UINT_BITS );
WALBERLA_CHECK_EQUAL( blocks_.size(), 1 );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_[0] ) );
......@@ -153,7 +154,7 @@ inline uint_t BlockID::getTreeId() const
inline uint_t BlockID::getTreeIndex() const
{
WALBERLA_ASSERT_GREATER( usedBits_, 0 );
WALBERLA_ASSERT_LESS_EQUAL( usedBits_, UINT_BITS );
WALBERLA_ASSERT_LESS_EQUAL( usedBits_, math::UINT_BITS );
WALBERLA_CHECK_EQUAL( blocks_.size(), 1 );
WALBERLA_ASSERT_EQUAL( usedBits_, uintMSBPosition( blocks_[0] ) );
......@@ -220,7 +221,7 @@ void BlockID::toBuffer( Buffer_T& buffer ) const
uint8_t b(0);
for( uint_t i = 0; i != blocks_.size(); ++i )
for( uint_t j = 0; j != UINT_BYTES && b != bytes; ++j, ++b )
for( uint_t j = 0; j != math::UINT_BYTES && b != bytes; ++j, ++b )
buffer << uint8_c( ( blocks_[i] >> ( uint_c(j) * uint_c(8) ) ) & uint_c(255) );
}
......@@ -232,22 +233,22 @@ void BlockID::fromBuffer( Buffer_T& buffer ) {
uint8_t bytes(0);
buffer >> bytes;
const uint_t blocks = ( bytes / UINT_BYTES ) + ( ( (bytes & ( UINT_BYTES - 1 )) == 0 ) ? 0 : 1 );
const uint_t blocks = ( bytes / math::UINT_BYTES ) + ( ( (bytes & ( math::UINT_BYTES - 1 )) == 0 ) ? 0 : 1 );
uint8_t b(0);
blocks_.clear();
for( uint_t i = 0; i != blocks; ++i ) {
blocks_.push_back(0);
for( uint_t j = 0; j != UINT_BYTES && b != bytes; ++j, ++b ) {
for( uint_t j = 0; j != math::UINT_BYTES && b != bytes; ++j, ++b ) {
uint8_t byte(0);
buffer >> byte;
blocks_.back() |= uint_c( byte ) << ( uint_c(j) * uint_c(8) );
}
}
for( uint_t i = 0; i != UINT_BITS; ++i )
for( uint_t i = 0; i != math::UINT_BITS; ++i )
if( ( blocks_[ blocks-1 ] & ( uint_c(1) << uint_c(i) ) ) != uint_c(0) )
usedBits_ = i + 1 + (blocks-1) * UINT_BITS;
usedBits_ = i + 1 + (blocks-1) * math::UINT_BITS;
}
......@@ -278,7 +279,7 @@ public:
BlockID getSuperId() const { WALBERLA_ASSERT_GREATER_EQUAL( getUsedBits(), uint_c(4) ); return BlockID( id_ >> 3 ); }
BlockID getFatherId() const { return getSuperId(); }
void appendBranchId( const uint_t branchId ) { WALBERLA_ASSERT_LESS_EQUAL( getUsedBits() + 3, UINT_BITS ); WALBERLA_ASSERT_LESS( branchId, 8 ); id_ = (id_ << 3) + branchId; }
void appendBranchId( const uint_t branchId ) { WALBERLA_ASSERT_LESS_EQUAL( getUsedBits() + 3, math::UINT_BITS ); WALBERLA_ASSERT_LESS( branchId, 8 ); id_ = (id_ << 3) + branchId; }
void removeBranchId() { WALBERLA_ASSERT_GREATER_EQUAL( getUsedBits(), uint_c(4) ); id_ >>= 3; }
uint_t getBranchId() const { WALBERLA_ASSERT_GREATER_EQUAL( getUsedBits(), uint_c(4) ); return id_ & uint_c(7); }
......@@ -317,7 +318,7 @@ inline BlockID::BlockID( const uint_t treeIndex, const uint_t treeIdMarker ) : i
inline BlockID::BlockID( const BlockID& id, const uint_t branchId ) : id_( (id.id_ << 3) + branchId )
{
WALBERLA_ASSERT_LESS_EQUAL( id.getUsedBits() + 3, UINT_BITS );
WALBERLA_ASSERT_LESS_EQUAL( id.getUsedBits() + 3, math::UINT_BITS );
WALBERLA_ASSERT_LESS( branchId, 8 );
}
......@@ -366,7 +367,7 @@ void BlockID::fromBuffer( Buffer_T& buffer ) {
uint8_t bytes(0);
buffer >> bytes;
WALBERLA_ASSERT_LESS_EQUAL( bytes, UINT_BYTES );
WALBERLA_ASSERT_LESS_EQUAL( bytes, math::UINT_BYTES );
id_ = uint_c(0);
for( uint8_t i = 0; i != bytes; ++i ) {
......
......@@ -26,6 +26,7 @@
#include "core/debug/CheckFunctions.h"
#include "core/debug/Debug.h"
#include "core/logging/Logging.h"
#include "core/math/Uint.h"
#include "core/mpi/BufferSizeTrait.h"
#include "core/mpi/BufferSystem.h"
#include "core/mpi/MPIManager.h"
......@@ -188,7 +189,7 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
depth_ = blockforest_.getDepth();
#ifdef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
WALBERLA_CHECK_LESS_EQUAL( blockforest_.getTreeIdDigits() + depth_ * uint_t(3), UINT_BITS );
WALBERLA_CHECK_LESS_EQUAL( blockforest_.getTreeIdDigits() + depth_ * uint_t(3), math::UINT_BITS );
#endif
// phantom block neighborhood construction
......
......@@ -24,12 +24,6 @@
namespace walberla {
#ifndef WALBERLA_CXX_COMPILER_IS_MSVC
const uint_t int_ld<1>::exp;
#endif
namespace real_comparison
{
const float Epsilon< float >::value = static_cast< float >(1e-4);
......
......@@ -142,60 +142,6 @@ inline void static_assert_uint_t() {
!std::numeric_limits<UINT>::is_signed, "Unsigned integer type required/expected!" );
}
template< uint_t size > struct uintFromBitWidth;
template<> struct uintFromBitWidth< 8 > { typedef uint8_t type; };
template<> struct uintFromBitWidth< 16 > { typedef uint16_t type; };
template<> struct uintFromBitWidth< 32 > { typedef uint32_t type; };
template<> struct uintFromBitWidth< 64 > { typedef uint64_t type; };
constexpr uint_t leastUnsignedIntegerBitWidth( uint_t width )
{
if ( width <= 8 ) return 8;
if ( width <= 16 ) return 16;
if ( width <= 32 ) return 32;
if ( width <= 64 ) return 64;
return width;
}
/// \brief Provides the smallest unsigned integer type that has at least minSize bits.
///
/// Example:
///
/// leastUnsignedInteger< 5 >::type a; // a is an 8-bit unsigned integer
/// leastUnsignedInteger< 9 >::type b; // b is a 16-bit unsigned integer
///
template< uint_t minSize >
struct leastUnsignedInteger
{
typedef typename uintFromBitWidth< leastUnsignedIntegerBitWidth( minSize ) >::type type;
};
/// \cond internal
static const uint_t UINT_BITS = static_cast< uint_t >( std::numeric_limits< uint_t >::digits );
static const uint_t UINT_BYTES = static_cast< uint_t >( std::numeric_limits< uint_t >::digits ) >> 3;
static_assert( !(UINT_BITS & (UINT_BITS - 1)), "Type \"uint_t\" must consist of 2^x Bits!" ); // power of two
template< int N >
struct int_ld
{
static_assert( N >= 1 && !(N & (N - 1)), "Calculating log_2(N) -> \"N\" must be a power of two!" );
static const uint_t exp = 1 + int_ld< (N >> 1) >::exp;
};
template< int N > const uint_t int_ld<N>::exp;
template<>
struct int_ld<1>
{
static const uint_t exp = 0;
};
static const uint_t UINT_BITS_LD = int_ld< std::numeric_limits< uint_t >::digits >::exp;
/// \endcond
// data structure specific data types
typedef int cell_idx_t;
......
......@@ -23,6 +23,7 @@
#include "DataTypes.h"
#include "core/debug/Debug.h"
#include "core/math/Uint.h"
#include <cmath>
#include <limits>
......@@ -52,7 +53,7 @@ namespace walberla {
inline void uintToByteArray( uint_t value, std::vector< uint8_t >& array, const uint_t offset, const uint_t bytes )
{
WALBERLA_ASSERT_LESS_EQUAL( offset + bytes, array.size() );
WALBERLA_ASSERT_LESS_EQUAL( bytes, UINT_BYTES );
WALBERLA_ASSERT_LESS_EQUAL( bytes, math::UINT_BYTES );
for( uint_t i = 0; i != bytes; ++i ) {
......@@ -79,7 +80,7 @@ inline void uintToByteArray( uint_t value, std::vector< uint8_t >& array, const
inline uint_t byteArrayToUint( const std::vector< uint8_t >& array, const uint_t offset, const uint_t bytes )
{
WALBERLA_ASSERT_LESS_EQUAL( offset + bytes, array.size() );
WALBERLA_ASSERT_LESS_EQUAL( bytes, UINT_BYTES );
WALBERLA_ASSERT_LESS_EQUAL( bytes, math::UINT_BYTES );
uint_t value = 0;
for( uint_t i = 0; i != bytes; ++i )
......
......@@ -25,8 +25,6 @@
namespace walberla {
namespace math {
template<> uint_t uintMSBPosition< uint64_t >( uint64_t value ) { // for the documentation see the header file
uint64_t i;
......@@ -51,7 +49,11 @@ template<> uint_t uintMSBPosition< uint64_t >( uint64_t value ) { // for the doc
return ( i != 0 ) ? (8 + msbLookupTable[i]) : msbLookupTable[value];
}
#ifndef WALBERLA_CXX_COMPILER_IS_MSVC
const uint_t int_ld<1>::exp;
#endif
} // namespace math
} // namespace walberla
......@@ -193,7 +193,57 @@ template<> inline uint_t uintMSBPosition< uint8_t >( uint8_t value ) {
return msbLookupTable[value];
}
template< uint_t size > struct uintFromBitWidth;
template<> struct uintFromBitWidth< 8 > { typedef uint8_t type; };
template<> struct uintFromBitWidth< 16 > { typedef uint16_t type; };
template<> struct uintFromBitWidth< 32 > { typedef uint32_t type; };
template<> struct uintFromBitWidth< 64 > { typedef uint64_t type; };
constexpr uint_t leastUnsignedIntegerBitWidth( uint_t width )
{
if ( width <= 8 ) return 8;
if ( width <= 16 ) return 16;
if ( width <= 32 ) return 32;
if ( width <= 64 ) return 64;
return width;
}
/// \brief Provides the smallest unsigned integer type that has at least minSize bits.
///
/// Example:
///
/// leastUnsignedInteger< 5 >::type a; // a is an 8-bit unsigned integer
/// leastUnsignedInteger< 9 >::type b; // b is a 16-bit unsigned integer
///
template< uint_t minSize >
struct leastUnsignedInteger
{
typedef typename uintFromBitWidth< leastUnsignedIntegerBitWidth( minSize ) >::type type;
};
/// \cond internal
static const uint_t UINT_BITS = static_cast< uint_t >( std::numeric_limits< uint_t >::digits );
static const uint_t UINT_BYTES = static_cast< uint_t >( std::numeric_limits< uint_t >::digits ) >> 3;
static_assert( !(UINT_BITS & (UINT_BITS - 1)), "Type \"uint_t\" must consist of 2^x Bits!" ); // power of two
template< int N >
struct int_ld
{
static_assert( N >= 1 && !(N & (N - 1)), "Calculating log_2(N) -> \"N\" must be a power of two!" );
static const uint_t exp = 1 + int_ld< (N >> 1) >::exp;
};
template< int N > const uint_t int_ld<N>::exp;
template<>
struct int_ld<1>
{
static const uint_t exp = 0;
};
static const uint_t UINT_BITS_LD = int_ld< std::numeric_limits< uint_t >::digits >::exp;
/// \endcond
} // namespace math
} // namespace walberla
......@@ -27,6 +27,7 @@
#include "SendBuffer.h"
#include "core/Conversion.h"
#include "core/DataTypes.h"
#include "core/math/Uint.h"
#include "core/Optional.h"
#include "core/RandomUUID.h"
......@@ -276,7 +277,7 @@ template< typename T, // Element type of SendBuffer
GenericSendBuffer<T,G>& packBoolVectorWithoutSize(GenericSendBuffer<T,G> & buf, const std::vector<bool> & bools )
{
// Use an unsigned type at least as large as the SendBuffer base type as container for the bools
typedef typename leastUnsignedInteger< std::numeric_limits<T>::digits >::type ContainerType;
typedef typename math::leastUnsignedInteger< std::numeric_limits<T>::digits >::type ContainerType;
static const size_t NUM_BITS = std::numeric_limits<ContainerType>::digits;
auto it = bools.begin();
......@@ -297,7 +298,7 @@ template< typename T > // Element type of RecvBuffer
GenericRecvBuffer<T>& unpackBoolVectorWithoutSize(GenericRecvBuffer<T> & buf, std::vector<bool> & bools, size_t size )
{
// Use an unsigned type at least as large as the RecvBuffer base type as container for the bools
typedef typename leastUnsignedInteger<std::numeric_limits<T>::digits>::type ContainerType;
typedef typename math::leastUnsignedInteger<std::numeric_limits<T>::digits>::type ContainerType;
static const size_t NUM_BITS = std::numeric_limits<ContainerType>::digits;
bools.resize(size);
......
......@@ -41,7 +41,7 @@ static void test() {
uint_t bit = 1;
uint_t mask = 0;
for( uint_t i = 0; i != UINT_BITS; ++i ) {
for( uint_t i = 0; i != math::UINT_BITS; ++i ) {
for( uint_t j = 0; j !=10000; ++j ) {
......@@ -50,7 +50,7 @@ static void test() {
#ifndef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
const uint_t branches = walberla::math::intRandom<uint8_t>();
#else
const uint_t branches = walberla::math::intRandom( uint_t(0), uint_c( ( UINT_BITS - i - 1 ) / 3 ) );
const uint_t branches = walberla::math::intRandom( uint_t(0), uint_c( ( math::UINT_BITS - i - 1 ) / 3 ) );
#endif
std::vector< uint_t > branch;
for( uint_t b = 0; b != branches; ++b )
......@@ -102,7 +102,7 @@ static void test() {
#ifndef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
const uint_t branches = walberla::math::intRandom<uint8_t>();
#else
const uint_t branches = walberla::math::intRandom( uint_t(0), uint_c( ( UINT_BITS - i - 1 ) / 3 ) );
const uint_t branches = walberla::math::intRandom( uint_t(0), uint_c( ( math::UINT_BITS - i - 1 ) / 3 ) );
#endif
BlockID id( treeIndex, bit );
for( uint_t b = 0; b != branches; ++b )
......
......@@ -52,8 +52,8 @@ static void refinementSelectionFunctionRandom( SetupBlockForest& forest ) {
#ifndef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
const uint_t maxLevel = 25;
#else
WALBERLA_ASSERT_GREATER_EQUAL( UINT_BITS, 32 );
const uint_t maxLevel = ( UINT_BITS - 14 ) / 3;
WALBERLA_ASSERT_GREATER_EQUAL( math::UINT_BITS, 32 );
const uint_t maxLevel = ( math::UINT_BITS - 14 ) / 3;
#endif
std::vector< SetupBlock* > blocks;
......
......@@ -22,6 +22,7 @@
#include "core/DataTypes.h"
#include "core/debug/Debug.h"
#include "core/debug/TestSubsystem.h"
#include "core/math/Uint.h"
#include <cstdlib>
#include <iostream>
......@@ -39,17 +40,17 @@ int main( int /*argc*/, char** /*argv*/ )
{
debug::enterTestMode();
WALBERLA_CHECK_EQUAL( UINT_BITS_LD, uintBitsLd( UINT_BITS ) );
WALBERLA_CHECK_EQUAL( math::UINT_BITS_LD, uintBitsLd( math::UINT_BITS ) );
WALBERLA_CHECK_EQUAL( int_ld< 2048 >::exp, 11 );
WALBERLA_CHECK_EQUAL( math::int_ld< 2048 >::exp, 11 );
WALBERLA_CHECK_EQUAL( int_ld< 64 >::exp, 6 );
WALBERLA_CHECK_EQUAL( int_ld< 32 >::exp, 5 );
WALBERLA_CHECK_EQUAL( int_ld< 16 >::exp, 4 );
WALBERLA_CHECK_EQUAL( int_ld< 8 >::exp, 3 );
WALBERLA_CHECK_EQUAL( int_ld< 4 >::exp, 2 );
WALBERLA_CHECK_EQUAL( int_ld< 2 >::exp, 1 );
WALBERLA_CHECK_EQUAL( int_ld< 1 >::exp, 0 );
WALBERLA_CHECK_EQUAL( math::int_ld< 64 >::exp, 6 );
WALBERLA_CHECK_EQUAL( math::int_ld< 32 >::exp, 5 );
WALBERLA_CHECK_EQUAL( math::int_ld< 16 >::exp, 4 );
WALBERLA_CHECK_EQUAL( math::int_ld< 8 >::exp, 3 );
WALBERLA_CHECK_EQUAL( math::int_ld< 4 >::exp, 2 );
WALBERLA_CHECK_EQUAL( math::int_ld< 2 >::exp, 1 );
WALBERLA_CHECK_EQUAL( math::int_ld< 1 >::exp, 0 );
return EXIT_SUCCESS;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment