Skip to content
Snippets Groups Projects
Commit ff8f19a6 authored by Tomáš Oberhuber's avatar Tomáš Oberhuber Committed by Jakub Klinkovský
Browse files

Reimplementing StaticArray using StaticFor, deleting StaticArray specialization by Size.

parent 82b95fa5
No related branches found
No related tags found
1 merge request!35Static vector
...@@ -55,7 +55,7 @@ class StaticArray ...@@ -55,7 +55,7 @@ class StaticArray
// reference: https://stackoverflow.com/q/4610503 // reference: https://stackoverflow.com/q/4610503
template< typename _unused = void > template< typename _unused = void >
__cuda_callable__ __cuda_callable__
inline StaticArray( const Value v[ Size ] ); StaticArray( const Value v[ Size ] );
/** /**
* \brief Constructor that sets all array components to value \e v. * \brief Constructor that sets all array components to value \e v.
......
...@@ -13,11 +13,86 @@ ...@@ -13,11 +13,86 @@
#include <TNL/param-types.h> #include <TNL/param-types.h>
#include <TNL/Math.h> #include <TNL/Math.h>
#include <TNL/Containers/StaticArray.h> #include <TNL/Containers/StaticArray.h>
#include <TNL/TemplateStaticFor.h> #include <TNL/StaticFor.h>
namespace TNL { namespace TNL {
namespace Containers { namespace Containers {
namespace Detail {
////
// Lambdas used together with StaticFor for static loop unrolling in the
// implementation of the StaticArray
template< typename LeftValue, typename RightValue = LeftValue >
auto assignArrayLambda = [] __cuda_callable__ ( int i, LeftValue* data, const RightValue* v ) { data[ i ] = v[ i ]; };
template< typename LeftValue, typename RightValue = LeftValue >
auto assignValueLambda = [] __cuda_callable__ ( int i, LeftValue* data, const RightValue v ) { data[ i ] = v; };
////
// StaticArrayComparator does static loop unrolling of array comparison
template< int Size, typename LeftValue, typename RightValue, int Index >
struct StaticArrayComparator
{
__cuda_callable__
static bool EQ( const StaticArray< Size, LeftValue >& left,
const StaticArray< Size, RightValue >& right )
{
if( left[ Index ] == right[ Index ] )
return StaticArrayComparator< Size, LeftValue, RightValue, Index + 1 >::EQ( left, right );
return false;
}
};
template< int Size, typename LeftValue, typename RightValue >
struct StaticArrayComparator< Size, LeftValue, RightValue, Size >
{
__cuda_callable__
static bool EQ( const StaticArray< Size, LeftValue >& left,
const StaticArray< Size, RightValue >& right )
{
return true;
}
};
////
// Static array sort does static loop unrolling of array sort.
// It performs static variant of bubble sort as follows:
//
// for( int k = Size - 1; k > 0; k--)
// for( int i = 0; i < k; i++ )
// if( data[ i ] > data[ i+1 ] )
// swap( data[ i ], data[ i+1 ] );
template< int k, int i, typename Value >
struct StaticArraySort
{
__cuda_callable__
static void exec( Value* data ) {
if( data[ i ] > data[ i + 1 ] )
swap( data[ i ], data[ i+1 ] );
StaticArraySort< k, i + 1, Value >::exec( data );
}
};
template< int k, typename Value >
struct StaticArraySort< k, k, Value >
{
__cuda_callable__
static void exec( Value* data ) {
StaticArraySort< k - 1, 0, Value >::exec( data );
}
};
template< typename Value >
struct StaticArraySort< 0, 0, Value >
{
__cuda_callable__
static void exec( Value* data ) {}
};
} //namespace Detail
template< int Size, typename Value > template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
constexpr int StaticArray< Size, Value >::getSize() constexpr int StaticArray< Size, Value >::getSize()
...@@ -31,29 +106,27 @@ inline StaticArray< Size, Value >::StaticArray() ...@@ -31,29 +106,27 @@ inline StaticArray< Size, Value >::StaticArray()
{ {
}; };
template< int Size, typename Value > template< int Size, typename Value >
template< typename _unused > template< typename _unused >
__cuda_callable__ __cuda_callable__
inline StaticArray< Size, Value >::StaticArray( const Value v[ Size ] ) StaticArray< Size, Value >::StaticArray( const Value v[ Size ] )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignArrayLambda< Value >, data, v );
data[ i ] = v[ i ];
} }
template< int Size, typename Value > template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline StaticArray< Size, Value >::StaticArray( const Value& v ) inline StaticArray< Size, Value >::StaticArray( const Value& v )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignValueLambda< Value >, data, v );
data[ i ] = v;
} }
template< int Size, typename Value > template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline StaticArray< Size, Value >::StaticArray( const StaticArray< Size, Value >& v ) inline StaticArray< Size, Value >::StaticArray( const StaticArray< Size, Value >& v )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignArrayLambda< Value >, data, v.getData() );
data[ i ] = v[ i ];
} }
template< int Size, typename Value > template< int Size, typename Value >
...@@ -174,8 +247,7 @@ template< int Size, typename Value > ...@@ -174,8 +247,7 @@ template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline StaticArray< Size, Value >& StaticArray< Size, Value >::operator = ( const StaticArray< Size, Value >& array ) inline StaticArray< Size, Value >& StaticArray< Size, Value >::operator = ( const StaticArray< Size, Value >& array )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignArrayLambda< Value >, data, array.getData() );
data[ i ] = array[ i ];
return *this; return *this;
} }
...@@ -184,8 +256,7 @@ template< int Size, typename Value > ...@@ -184,8 +256,7 @@ template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline StaticArray< Size, Value >& StaticArray< Size, Value >::operator = ( const Array& array ) inline StaticArray< Size, Value >& StaticArray< Size, Value >::operator = ( const Array& array )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignArrayLambda< Value, typename Array::ValueType >, data, array.getData() );
data[ i ] = array[ i ];
return *this; return *this;
} }
...@@ -194,12 +265,7 @@ template< int Size, typename Value > ...@@ -194,12 +265,7 @@ template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline bool StaticArray< Size, Value >::operator == ( const Array& array ) const inline bool StaticArray< Size, Value >::operator == ( const Array& array ) const
{ {
if( ( int ) Size != ( int ) Array::getSize() ) return Detail::StaticArrayComparator< Size, Value, typename Array::ValueType, 0 >::EQ( *this, array );
return false;
for( int i = 0; i < Size; i++ )
if( data[ i ] != array[ i ] )
return false;
return true;
} }
template< int Size, typename Value > template< int Size, typename Value >
...@@ -217,8 +283,7 @@ StaticArray< Size, Value >:: ...@@ -217,8 +283,7 @@ StaticArray< Size, Value >::
operator StaticArray< Size, OtherValue >() const operator StaticArray< Size, OtherValue >() const
{ {
StaticArray< Size, OtherValue > aux; StaticArray< Size, OtherValue > aux;
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignArrayLambda< OtherValue, Value >, aux.getData(), data );
aux[ i ] = data[ i ];
return aux; return aux;
} }
...@@ -226,8 +291,7 @@ template< int Size, typename Value > ...@@ -226,8 +291,7 @@ template< int Size, typename Value >
__cuda_callable__ __cuda_callable__
inline void StaticArray< Size, Value >::setValue( const ValueType& val ) inline void StaticArray< Size, Value >::setValue( const ValueType& val )
{ {
for( int i = 0; i < Size; i++ ) StaticFor< 0, Size >::exec( Detail::assignValueLambda< Value >, data, val );
data[ i ] = val;
} }
template< int Size, typename Value > template< int Size, typename Value >
...@@ -247,14 +311,7 @@ bool StaticArray< Size, Value >::load( File& file) ...@@ -247,14 +311,7 @@ bool StaticArray< Size, Value >::load( File& file)
template< int Size, typename Value > template< int Size, typename Value >
void StaticArray< Size, Value >::sort() void StaticArray< Size, Value >::sort()
{ {
/**** Detail::StaticArraySort< Size - 1, 0, Value >::exec( data );
* We assume that the array data is small and so
* may sort it with the bubble sort.
*/
for( int k = Size - 1; k > 0; k--)
for( int i = 0; i < k; i++ )
if( data[ i ] > data[ i+1 ] )
swap( data[ i ], data[ i+1 ] );
} }
template< int Size, typename Value > template< int Size, typename Value >
...@@ -266,7 +323,6 @@ std::ostream& StaticArray< Size, Value >::write( std::ostream& str, const char* ...@@ -266,7 +323,6 @@ std::ostream& StaticArray< Size, Value >::write( std::ostream& str, const char*
return str; return str;
} }
template< int Size, typename Value > template< int Size, typename Value >
std::ostream& operator << ( std::ostream& str, const StaticArray< Size, Value >& a ) std::ostream& operator << ( std::ostream& str, const StaticArray< Size, Value >& a )
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment