From 322b5b5874beb93ddeeec19f4e66ea23a667b632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Klinkovsk=C3=BD?= <klinkjak@fjfi.cvut.cz> Date: Sun, 7 Jul 2019 22:11:31 +0200 Subject: [PATCH] Reordering and optimizing tests in VectorTest to improve the compilation time --- src/UnitTests/Containers/VectorTest-1.h | 264 ++++++++++--- src/UnitTests/Containers/VectorTest-2.h | 358 +++++++++++++----- src/UnitTests/Containers/VectorTest-3.h | 163 +++----- src/UnitTests/Containers/VectorTest-4.h | 474 +++++++----------------- src/UnitTests/Containers/VectorTest-5.h | 204 +++------- src/UnitTests/Containers/VectorTest-6.h | 399 +++----------------- src/UnitTests/Containers/VectorTest-7.h | 427 +++++++++++++++++---- 7 files changed, 1114 insertions(+), 1175 deletions(-) diff --git a/src/UnitTests/Containers/VectorTest-1.h b/src/UnitTests/Containers/VectorTest-1.h index 6ebb6eb212..c1a29f7895 100644 --- a/src/UnitTests/Containers/VectorTest-1.h +++ b/src/UnitTests/Containers/VectorTest-1.h @@ -13,23 +13,9 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - -// should be small enough to have fast tests, but larger than minGPUReductionDataSize -// and large enough to require multiple CUDA blocks for reduction -constexpr int VECTOR_TEST_SIZE = 5000; +constexpr int VECTOR_TEST_SIZE = 100; TYPED_TEST( VectorTest, constructors ) { @@ -91,72 +77,231 @@ TYPED_TEST( VectorTest, constructors ) EXPECT_EQ( a3.getElement( 2 ), 9 ); } -TYPED_TEST( VectorTest, max ) +TEST( VectorSpecialCasesTest, defaultConstructors ) +{ + using ArrayType = Containers::Array< int, Devices::Host >; + using VectorViewType = VectorView< int, Devices::Host >; + using ArrayViewType = ArrayView< int, Devices::Host >; + + ArrayType a( 100 ); + a.setValue( 0 ); + + ArrayViewType a_view; + a_view.bind( a ); + + VectorViewType v_view; + v_view.bind( a ); + EXPECT_EQ( v_view.getData(), a_view.getData() ); +} + +TEST( VectorSpecialCasesTest, assignmentThroughView ) +{ + using VectorType = Containers::Vector< int, Devices::Host >; + using ViewType = VectorView< int, Devices::Host >; + + static_assert( Algorithms::Details::HasSubscriptOperator< VectorType >::value, "Subscript operator detection by SFINAE does not work for Vector." ); + static_assert( Algorithms::Details::HasSubscriptOperator< ViewType >::value, "Subscript operator detection by SFINAE does not work for VectorView." ); + + VectorType u( 100 ), v( 100 ); + ViewType u_view( u ), v_view( v ); + + u.setValue( 42 ); + v.setValue( 0 ); + v_view = u_view; + EXPECT_EQ( u_view.getData(), u.getData() ); + EXPECT_EQ( v_view.getData(), v.getData() ); + for( int i = 0; i < 100; i++ ) + EXPECT_EQ( v_view[ i ], 42 ); + + u.setValue( 42 ); + v.setValue( 0 ); + v_view = u; + EXPECT_EQ( u_view.getData(), u.getData() ); + EXPECT_EQ( v_view.getData(), v.getData() ); + for( int i = 0; i < 100; i++ ) + EXPECT_EQ( v_view[ i ], 42 ); +} + +TEST( VectorSpecialCasesTest, operationsOnConstView ) +{ + using VectorType = Containers::Vector< int, Devices::Host >; + using ViewType = VectorView< const int, Devices::Host >; + + VectorType u( 100 ), v( 100 ); + ViewType u_view( u ), v_view( v ); + + u.setValue( 1 ); + v.setValue( 1 ); + + EXPECT_EQ( u_view.max(), 1 ); + EXPECT_EQ( u_view.min(), 1 ); + EXPECT_EQ( u_view.absMax(), 1 ); + EXPECT_EQ( u_view.absMin(), 1 ); + EXPECT_EQ( u_view.lpNorm( 1 ), 100 ); + EXPECT_EQ( u_view.differenceMax( v_view ), 0 ); + EXPECT_EQ( u_view.differenceMin( v_view ), 0 ); + EXPECT_EQ( u_view.differenceAbsMax( v_view ), 0 ); + EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 ); + EXPECT_EQ( u_view.differenceLpNorm( v_view, 1 ), 0 ); + EXPECT_EQ( u_view.differenceSum( v_view ), 0 ); + EXPECT_EQ( u_view.scalarProduct( v_view ), 100 ); +} + +TEST( VectorSpecialCasesTest, initializationOfVectorViewByArrayView ) +{ + using ArrayType = Containers::Array< int, Devices::Host >; + using VectorViewType = VectorView< const int, Devices::Host >; + using ArrayViewType = ArrayView< int, Devices::Host >; + + ArrayType a( 100 ); + a.setValue( 0 ); + ArrayViewType a_view( a ); + + VectorViewType v_view( a_view ); + EXPECT_EQ( v_view.getData(), a_view.getData() ); + EXPECT_EQ( v_view.sum(), 0 ); +} + +TYPED_TEST( VectorTest, scalarMultiplication ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType v; - v.setSize( size ); - ViewType v_view( v ); - setLinearSequence( v ); + VectorType u( size ); + ViewType u_view( u ); + + typename VectorType::HostType expected; + expected.setSize( size ); + for( int i = 0; i < size; i++ ) + expected[ i ] = 2.0 * i; + + setLinearSequence( u ); + VectorOperations::vectorScalarMultiplication( u, 2.0 ); + EXPECT_EQ( u, expected ); + + setLinearSequence( u ); + u.scalarMultiplication( 2.0 ); + EXPECT_EQ( u, expected ); + + setLinearSequence( u ); + u_view.scalarMultiplication( 2.0 ); + EXPECT_EQ( u, expected ); - EXPECT_EQ( v.max(), size - 1 ); - EXPECT_EQ( v_view.max(), size - 1 ); - EXPECT_EQ( VectorOperations::getVectorMax( v ), size - 1 ); + setLinearSequence( u ); + u *= 2.0; + EXPECT_EQ( u, expected ); + + setLinearSequence( u ); + u_view *= 2.0; + EXPECT_EQ( u, expected ); } -TYPED_TEST( VectorTest, min ) +TYPED_TEST( VectorTest, addVector ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType v; - v.setSize( size ); - ViewType v_view( v ); - setLinearSequence( v ); + VectorType x, y; + x.setSize( size ); + y.setSize( size ); + ViewType x_view( x ), y_view( y ); + + typename VectorType::HostType expected1, expected2; + expected1.setSize( size ); + expected2.setSize( size ); + for( int i = 0; i < size; i++ ) { + expected1[ i ] = 2.0 + 3.0 * i; + expected2[ i ] = 1.0 + 3.0 * i; + } - EXPECT_EQ( v.min(), 0 ); - EXPECT_EQ( v_view.min(), 0 ); - EXPECT_EQ( VectorOperations::getVectorMin( v ), 0 ); + setConstantSequence( x, 1 ); + setLinearSequence( y ); + VectorOperations::addVector( x, y, 3.0, 2.0 ); + EXPECT_EQ( x, expected1 ); + + setConstantSequence( x, 1 ); + setLinearSequence( y ); + x.addVector( y, 3.0, 1.0 ); + EXPECT_EQ( x, expected2 ); + + setConstantSequence( x, 1 ); + setLinearSequence( y ); + x_view.addVector( y_view, 3.0, 1.0 ); + EXPECT_EQ( x, expected2 ); + + // multiplication by floating-point scalars which produces integer values + setConstantSequence( x, 2 ); + setConstantSequence( y, 4 ); + x.addVector( y, 2.5, -1.5 ); + EXPECT_EQ( x.min(), 7 ); + EXPECT_EQ( x.max(), 7 ); } -TYPED_TEST( VectorTest, absMax ) +TYPED_TEST( VectorTest, addVectors ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType v; - v.setSize( size ); - ViewType v_view( v ); - setNegativeLinearSequence( v ); + VectorType x, y, z; + x.setSize( size ); + y.setSize( size ); + z.setSize( size ); + ViewType x_view( x ), y_view( y ), z_view( z ); + + typename VectorType::HostType expected1, expected2; + expected1.setSize( size ); + expected2.setSize( size ); + for( int i = 0; i < size; i++ ) { + expected1[ i ] = 1.0 + 3.0 * i + 2.0; + expected2[ i ] = 2.0 + 3.0 * i + 2.0; + } - EXPECT_EQ( v.absMax(), size - 1 ); - EXPECT_EQ( v_view.absMax(), size - 1 ); - EXPECT_EQ( VectorOperations::getVectorAbsMax( v ), size - 1 ); + setConstantSequence( x, 1 ); + setLinearSequence( y ); + setConstantSequence( z, 2 ); + VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 ); + EXPECT_EQ( x, expected1 ); + + setConstantSequence( x, 1 ); + setLinearSequence( y ); + setConstantSequence( z, 2 ); + x.addVectors( y, 3.0, z, 1.0, 2.0 ); + EXPECT_EQ( x, expected2 ); + + setConstantSequence( x, 1 ); + setLinearSequence( y ); + setConstantSequence( z, 2 ); + x_view.addVectors( y_view, 3.0, z_view, 1.0, 2.0 ); + EXPECT_EQ( x, expected2 ); + + // multiplication by floating-point scalars which produces integer values + setConstantSequence( x, 2 ); + setConstantSequence( y, 4 ); + setConstantSequence( z, 6 ); + x.addVectors( y, 2.5, z, -1.5, -1.5 ); + EXPECT_EQ( x.min(), -2 ); + EXPECT_EQ( x.max(), -2 ); } -TYPED_TEST( VectorTest, absMin ) +TYPED_TEST( VectorTest, abs ) { using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType v; - v.setSize( size ); - ViewType v_view( v ); - setNegativeLinearSequence( v ); + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + u.setElement( i, i ); - EXPECT_EQ( v.absMin(), 0 ); - EXPECT_EQ( v_view.absMin(), 0 ); - EXPECT_EQ( VectorOperations::getVectorAbsMin( v ), 0 ); + v = -u; + EXPECT_TRUE( abs( v ) == u ); } TYPED_TEST( VectorTest, comparison ) @@ -176,7 +321,28 @@ TYPED_TEST( VectorTest, comparison ) EXPECT_TRUE( w + 1.0 < v + 4.0 ); } +TYPED_TEST( VectorTest, horizontalOperations ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + using IndexType = typename VectorType::IndexType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ), _w( size ); + ViewType u( _u ), v( _v ), w( _w ); + EXPECT_EQ( u.getSize(), size ); + u = 0; + v = 1; + w = 2; + + u = u + 4 * TNL::max( v, 0 ); + EXPECT_TRUE( u.containsOnlyValue( 4.0 ) ); + + u = u + 3 * w + 4 * TNL::max( v, 0 ); + EXPECT_TRUE( u.containsOnlyValue( 14.0 ) ); +} #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorTest-2.h b/src/UnitTests/Containers/VectorTest-2.h index bf60389f60..93a15168f5 100644 --- a/src/UnitTests/Containers/VectorTest-2.h +++ b/src/UnitTests/Containers/VectorTest-2.h @@ -13,141 +13,315 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction -constexpr int VECTOR_TEST_SIZE = 5000; +constexpr int VECTOR_TEST_SIZE = 10000; -TYPED_TEST( VectorTest, lpNorm ) +TYPED_TEST( VectorTest, prefixSum ) { using VectorType = typename TestFixture::VectorType; - using RealType = typename VectorType::RealType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + using DeviceType = typename VectorType::DeviceType; + using IndexType = typename VectorType::IndexType; const int size = VECTOR_TEST_SIZE; - const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon(); - VectorType v; - v.setSize( size ); + if( std::is_same< RealType, float >::value || + std::is_same< IndexType, short >::value ) + return; + + VectorType v( size ); ViewType v_view( v ); + typename VectorType::HostType v_host( size ); + + v = 0; + v_host = -1; + v.prefixSum(); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v.prefixSum(); + v_host = v; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i ); + setConstantSequence( v, 1 ); + v_host = -1; + v_view.prefixSum(); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i + 1 ); + + v = 0; + v_host = -1; + v_view.prefixSum(); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v_view.prefixSum(); + v_host = v_view; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i ); + + //// + // With CUDA, perform tests with multiple CUDA grids. + if( std::is_same< DeviceType, Devices::Cuda >::value ) + { +#ifdef HAVE_CUDA + Algorithms::CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::setMaxGridSize( 3 ); + v = 0; + v_host = -1; + v.prefixSum(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v.prefixSum(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i ); + + setConstantSequence( v, 1 ); + v_host = -1; + v_view.prefixSum(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i + 1 ); - const RealType expectedL1norm = size; - const RealType expectedL2norm = std::sqrt( size ); - const RealType expectedL3norm = std::cbrt( size ); - EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm ); - EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm ); - EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon ); - EXPECT_EQ( v_view.lpNorm( 1.0 ), expectedL1norm ); - EXPECT_EQ( v_view.lpNorm( 2.0 ), expectedL2norm ); - EXPECT_NEAR( v_view.lpNorm( 3.0 ), expectedL3norm, epsilon ); - EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 1.0 ), expectedL1norm ); - EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 2.0 ), expectedL2norm ); - EXPECT_NEAR( VectorOperations::getVectorLpNorm( v, 3.0 ), expectedL3norm, epsilon ); + v = 0; + v_host = -1; + v_view.prefixSum(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v_view.prefixSum(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i ); + CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::resetMaxGridSize(); +#endif + } } -TYPED_TEST( VectorTest, sum ) +TYPED_TEST( VectorTest, exclusivePrefixSum ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - // this test expect an even size - const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE; + using RealType = typename VectorType::RealType; + using DeviceType = typename VectorType::DeviceType; + using IndexType = typename VectorType::IndexType; + const int size = VECTOR_TEST_SIZE; + + if( std::is_same< RealType, float >::value || + std::is_same< IndexType, short >::value ) + return; VectorType v; v.setSize( size ); ViewType v_view( v ); + typename VectorType::HostType v_host( size ); setConstantSequence( v, 1 ); - EXPECT_EQ( v.sum(), size ); - EXPECT_EQ( v_view.sum(), size ); - EXPECT_EQ( VectorOperations::getVectorSum( v ), size ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i ); + + v.setValue( 0 ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 ); + + setConstantSequence( v, 1 ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i ); + + v.setValue( 0 ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); setLinearSequence( v ); - EXPECT_EQ( v.sum(), 0.5 * size * ( size - 1 ) ); - EXPECT_EQ( v_view.sum(), 0.5 * size * ( size - 1 ) ); - EXPECT_EQ( VectorOperations::getVectorSum( v ), 0.5 * size * ( size - 1 ) ); - - setNegativeLinearSequence( v ); - EXPECT_EQ( v.sum(), - 0.5 * size * ( size - 1 ) ); - EXPECT_EQ( v_view.sum(), - 0.5 * size * ( size - 1 ) ); - EXPECT_EQ( VectorOperations::getVectorSum( v ), - 0.5 * size * ( size - 1 ) ); - - setOscilatingSequence( v, 1.0 ); - EXPECT_EQ( v.sum(), 0 ); - EXPECT_EQ( v_view.sum(), 0 ); - EXPECT_EQ( VectorOperations::getVectorSum( v ), 0 ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + v_host = v_view; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 ); + + //// + // With CUDA, perform tests with multiple CUDA grids. + if( std::is_same< DeviceType, Devices::Cuda >::value ) + { +#ifdef HAVE_CUDA + CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::setMaxGridSize( 3 ); + + setConstantSequence( v, 1 ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i ); + + v.setValue( 0 ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 ); + + setConstantSequence( v, 1 ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], i ); + + v.setValue( 0 ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_host[ i ], 0 ); + + setLinearSequence( v ); + v_host = -1; + v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); + EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); + v_host = v_view; + for( int i = 1; i < size; i++ ) + EXPECT_EQ( v_host[ i ] - v_host[ i - 1 ], i - 1 ); + CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::resetMaxGridSize(); +#endif + } } -TYPED_TEST( VectorTest, differenceMax ) -{ - using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; - using ViewType = typename TestFixture::ViewType; - const int size = VECTOR_TEST_SIZE; +// TODO: test prefix sum with custom begin and end parameters - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - setLinearSequence( u ); - setConstantSequence( v, size / 2 ); - EXPECT_EQ( u.differenceMax( v ), size - 1 - size / 2 ); - EXPECT_EQ( u_view.differenceMax( v_view ), size - 1 - size / 2 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceMax( u, v ), size - 1 - size / 2 ); +template< typename FlagsView > +void setupFlags( FlagsView& f ) +{ + auto f1 = [] __cuda_callable__ ( typename FlagsView::IndexType i ) { return ( i % 5 ) == 0; }; + f.evaluate( f1 ); } -TYPED_TEST( VectorTest, differenceMin ) +/* +TYPED_TEST( VectorTest, segmentedPrefixSum ) { using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + using DeviceType = typename VectorType::DeviceType; + using IndexType = typename VectorType::IndexType; + using FlagsArrayType = Array< bool, DeviceType, IndexType >; + using FlagsViewType = ArrayView< bool, DeviceType, IndexType >; const int size = VECTOR_TEST_SIZE; - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - setLinearSequence( u ); - setConstantSequence( v, size / 2 ); - - EXPECT_EQ( u.differenceMin( v ), - size / 2 ); - EXPECT_EQ( u_view.differenceMin( v_view ), - size / 2 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceMin( u, v ), - size / 2 ); - EXPECT_EQ( v.differenceMin( u ), size / 2 - size + 1 ); - EXPECT_EQ( v_view.differenceMin( u_view ), size / 2 - size + 1 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceMin( v, u ), size / 2 - size + 1 ); -} + VectorType v( size ); + ViewType v_view( v ); -TYPED_TEST( VectorTest, differenceAbsMax ) -{ - using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; - using ViewType = typename TestFixture::ViewType; - // this test expects an odd size - const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1; + FlagsArrayType flags( size ), flags_copy( size ); + FlagsViewType flags_view( flags ); + //auto f1 = [] __cuda_callable__ ( IndexType i ) { return ( i % 5 ) == 0; }; + //flags_view.evaluate( f1 ); + setupFlags( flags_view ); + flags_copy = flags_view; - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - setNegativeLinearSequence( u ); - setConstantSequence( v, - size / 2 ); + v = 0; + v.computeSegmentedPrefixSum( flags_view ); + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v.getElement( i ), 0 ); + flags_view = flags_copy; - EXPECT_EQ( u.differenceAbsMax( v ), size - 1 - size / 2 ); - EXPECT_EQ( u_view.differenceAbsMax( v_view ), size - 1 - size / 2 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMax( u, v ), size - 1 - size / 2 ); -} + v = 1; + v.computeSegmentedPrefixSum( flags_view ); + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v.getElement( i ), ( i % 5 ) + 1 ); + flags_view = flags_copy; + + setLinearSequence( v ); + v.computeSegmentedPrefixSum( flags_view ); + for( int i = 1; i < size; i++ ) + { + if( flags.getElement( i ) ) + EXPECT_EQ( v.getElement( i ), i ); + else + EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); + } + flags_view = flags_copy; + + v_view = 0; + v_view.computeSegmentedPrefixSum( flags_view ); + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_view.getElement( i ), 0 ); + flags_view = flags_copy; + v_view = 1; + v_view.computeSegmentedPrefixSum( flags_view ); + for( int i = 0; i < size; i++ ) + EXPECT_EQ( v_view.getElement( i ), ( i % 5 ) + 1 ); + flags_view = flags_copy; + + //v_view.evaluate( [] __cuda_callable__ ( IndexType i ) { return i; } ); + setLinearSequence( v ); + v_view.computeSegmentedPrefixSum( flags_view ); + for( int i = 1; i < size; i++ ) + { + if( flags.getElement( i ) ) + EXPECT_EQ( v_view.getElement( i ), i ); + else + EXPECT_EQ( v_view.getElement( i ) - v_view.getElement( i - 1 ), i ); + } +} +*/ #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorTest-3.h b/src/UnitTests/Containers/VectorTest-3.h index 6eae23b844..c857c9edd5 100644 --- a/src/UnitTests/Containers/VectorTest-3.h +++ b/src/UnitTests/Containers/VectorTest-3.h @@ -13,157 +13,106 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction constexpr int VECTOR_TEST_SIZE = 5000; -TYPED_TEST( VectorTest, differenceAbsMin ) +TYPED_TEST( VectorTest, max ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - setNegativeLinearSequence( u ); - setConstantSequence( v, - size / 2 ); - - EXPECT_EQ( u.differenceAbsMin( v ), 0 ); - EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( u, v ), 0 ); - EXPECT_EQ( v.differenceAbsMin( u ), 0 ); - EXPECT_EQ( v_view.differenceAbsMin( u_view ), 0 ); - EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( v, u ), 0 ); + VectorType v; + v.setSize( size ); + ViewType v_view( v ); + setLinearSequence( v ); + + EXPECT_EQ( v.max(), size - 1 ); + EXPECT_EQ( v_view.max(), size - 1 ); + EXPECT_EQ( VectorOperations::getVectorMax( v ), size - 1 ); } -TYPED_TEST( VectorTest, differenceLpNorm ) +TYPED_TEST( VectorTest, min ) { using VectorType = typename TestFixture::VectorType; - using RealType = typename VectorType::RealType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon(); - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - u.setValue( 3.0 ); - v.setValue( 1.0 ); - - const RealType expectedL1norm = 2.0 * size; - const RealType expectedL2norm = std::sqrt( 4.0 * size ); - const RealType expectedL3norm = std::cbrt( 8.0 * size ); - EXPECT_EQ( u.differenceLpNorm( v, 1.0 ), expectedL1norm ); - EXPECT_EQ( u.differenceLpNorm( v, 2.0 ), expectedL2norm ); - EXPECT_NEAR( u.differenceLpNorm( v, 3.0 ), expectedL3norm, epsilon ); - EXPECT_EQ( u_view.differenceLpNorm( v_view, 1.0 ), expectedL1norm ); - EXPECT_EQ( u_view.differenceLpNorm( v_view, 2.0 ), expectedL2norm ); - EXPECT_NEAR( u_view.differenceLpNorm( v_view, 3.0 ), expectedL3norm, epsilon ); - EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 1.0 ), expectedL1norm ); - EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 2.0 ), expectedL2norm ); - EXPECT_NEAR( VectorOperations::getVectorDifferenceLpNorm( u, v, 3.0 ), expectedL3norm, epsilon ); + VectorType v; + v.setSize( size ); + ViewType v_view( v ); + setLinearSequence( v ); + + EXPECT_EQ( v.min(), 0 ); + EXPECT_EQ( v_view.min(), 0 ); + EXPECT_EQ( VectorOperations::getVectorMin( v ), 0 ); } -TYPED_TEST( VectorTest, differenceSum ) +TYPED_TEST( VectorTest, absMax ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - // this test expect an even size - const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE; - - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - v.setValue( 1.0 ); - - setConstantSequence( u, 2 ); - EXPECT_EQ( u.differenceSum( v ), size ); - EXPECT_EQ( u_view.differenceSum( v_view ), size ); - EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), size ); - - setLinearSequence( u ); - EXPECT_EQ( u.differenceSum( v ), 0.5 * size * ( size - 1 ) - size ); - EXPECT_EQ( u_view.differenceSum( v_view ), 0.5 * size * ( size - 1 ) - size ); - EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), 0.5 * size * ( size - 1 ) - size ); - - setNegativeLinearSequence( u ); - EXPECT_EQ( u.differenceSum( v ), - 0.5 * size * ( size - 1 ) - size ); - EXPECT_EQ( u_view.differenceSum( v_view ), - 0.5 * size * ( size - 1 ) - size ); - EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - 0.5 * size * ( size - 1 ) - size ); - - setOscilatingSequence( u, 1.0 ); - EXPECT_EQ( u.differenceSum( v ), - size ); - EXPECT_EQ( u_view.differenceSum( v_view ), - size ); - EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - size ); + const int size = VECTOR_TEST_SIZE; + + VectorType v; + v.setSize( size ); + ViewType v_view( v ); + setNegativeLinearSequence( v ); + + EXPECT_EQ( v.absMax(), size - 1 ); + EXPECT_EQ( v_view.absMax(), size - 1 ); + EXPECT_EQ( VectorOperations::getVectorAbsMax( v ), size - 1 ); } -TYPED_TEST( VectorTest, scalarMultiplication ) +TYPED_TEST( VectorTest, absMin ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - VectorType u( size ); - ViewType u_view( u ); - - typename VectorType::HostType expected; - expected.setSize( size ); - for( int i = 0; i < size; i++ ) - expected[ i ] = 2.0 * i; - - setLinearSequence( u ); - VectorOperations::vectorScalarMultiplication( u, 2.0 ); - EXPECT_EQ( u, expected ); - - setLinearSequence( u ); - u.scalarMultiplication( 2.0 ); - EXPECT_EQ( u, expected ); - - setLinearSequence( u ); - u_view.scalarMultiplication( 2.0 ); - EXPECT_EQ( u, expected ); + VectorType v; + v.setSize( size ); + ViewType v_view( v ); + setNegativeLinearSequence( v ); - setLinearSequence( u ); - u *= 2.0; - EXPECT_EQ( u, expected ); - - setLinearSequence( u ); - u_view *= 2.0; - EXPECT_EQ( u, expected ); + EXPECT_EQ( v.absMin(), 0 ); + EXPECT_EQ( v_view.absMin(), 0 ); + EXPECT_EQ( VectorOperations::getVectorAbsMin( v ), 0 ); } -TYPED_TEST( VectorTest, scalarProduct ) +TYPED_TEST( VectorTest, lpNorm ) { using VectorType = typename TestFixture::VectorType; + using RealType = typename VectorType::RealType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - // this test expects an odd size - const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1; + const int size = VECTOR_TEST_SIZE; + const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon(); - VectorType u( size ), v( size ); - ViewType u_view( u ), v_view( v ); - setOscilatingSequence( u, 1.0 ); + VectorType v; + v.setSize( size ); + ViewType v_view( v ); setConstantSequence( v, 1 ); - EXPECT_EQ( u.scalarProduct( v ), 1.0 ); - EXPECT_EQ( u_view.scalarProduct( v_view ), 1.0 ); - EXPECT_EQ( VectorOperations::getScalarProduct( u, v ), 1.0 ); + const RealType expectedL1norm = size; + const RealType expectedL2norm = std::sqrt( size ); + const RealType expectedL3norm = std::cbrt( size ); + EXPECT_EQ( v.lpNorm( 1.0 ), expectedL1norm ); + EXPECT_EQ( v.lpNorm( 2.0 ), expectedL2norm ); + EXPECT_NEAR( v.lpNorm( 3.0 ), expectedL3norm, epsilon ); + EXPECT_EQ( v_view.lpNorm( 1.0 ), expectedL1norm ); + EXPECT_EQ( v_view.lpNorm( 2.0 ), expectedL2norm ); + EXPECT_NEAR( v_view.lpNorm( 3.0 ), expectedL3norm, epsilon ); + EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 1.0 ), expectedL1norm ); + EXPECT_EQ( VectorOperations::getVectorLpNorm( v, 2.0 ), expectedL2norm ); + EXPECT_NEAR( VectorOperations::getVectorLpNorm( v, 3.0 ), expectedL3norm, epsilon ); } #endif // HAVE_GTEST diff --git a/src/UnitTests/Containers/VectorTest-4.h b/src/UnitTests/Containers/VectorTest-4.h index 20650272e3..950d46ef6a 100644 --- a/src/UnitTests/Containers/VectorTest-4.h +++ b/src/UnitTests/Containers/VectorTest-4.h @@ -13,385 +13,175 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // Should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction. -constexpr int VECTOR_TEST_SIZE = 10000; - -TYPED_TEST( VectorTest, addVector ) -{ - using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; - using ViewType = typename TestFixture::ViewType; - const int size = VECTOR_TEST_SIZE; - - VectorType x, y; - x.setSize( size ); - y.setSize( size ); - ViewType x_view( x ), y_view( y ); - - typename VectorType::HostType expected1, expected2; - expected1.setSize( size ); - expected2.setSize( size ); - for( int i = 0; i < size; i++ ) { - expected1[ i ] = 2.0 + 3.0 * i; - expected2[ i ] = 1.0 + 3.0 * i; - } - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - VectorOperations::addVector( x, y, 3.0, 2.0 ); - EXPECT_EQ( x, expected1 ); - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - x.addVector( y, 3.0, 1.0 ); - EXPECT_EQ( x, expected2 ); - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - x_view.addVector( y_view, 3.0, 1.0 ); - EXPECT_EQ( x, expected2 ); - - // multiplication by floating-point scalars which produces integer values - setConstantSequence( x, 2 ); - setConstantSequence( y, 4 ); - x.addVector( y, 2.5, -1.5 ); - EXPECT_EQ( x.min(), 7 ); - EXPECT_EQ( x.max(), 7 ); -} - -TYPED_TEST( VectorTest, addVectors ) -{ - using VectorType = typename TestFixture::VectorType; - using VectorOperations = typename TestFixture::VectorOperations; - using ViewType = typename TestFixture::ViewType; - const int size = VECTOR_TEST_SIZE; +constexpr int VECTOR_TEST_SIZE = 5000; - VectorType x, y, z; - x.setSize( size ); - y.setSize( size ); - z.setSize( size ); - ViewType x_view( x ), y_view( y ), z_view( z ); - - typename VectorType::HostType expected1, expected2; - expected1.setSize( size ); - expected2.setSize( size ); - for( int i = 0; i < size; i++ ) { - expected1[ i ] = 1.0 + 3.0 * i + 2.0; - expected2[ i ] = 2.0 + 3.0 * i + 2.0; - } - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - setConstantSequence( z, 2 ); - VectorOperations::addVectors( x, y, 3.0, z, 1.0, 1.0 ); - EXPECT_EQ( x, expected1 ); - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - setConstantSequence( z, 2 ); - x.addVectors( y, 3.0, z, 1.0, 2.0 ); - EXPECT_EQ( x, expected2 ); - - setConstantSequence( x, 1 ); - setLinearSequence( y ); - setConstantSequence( z, 2 ); - x_view.addVectors( y_view, 3.0, z_view, 1.0, 2.0 ); - EXPECT_EQ( x, expected2 ); - - // multiplication by floating-point scalars which produces integer values - setConstantSequence( x, 2 ); - setConstantSequence( y, 4 ); - setConstantSequence( z, 6 ); - x.addVectors( y, 2.5, z, -1.5, -1.5 ); - EXPECT_EQ( x.min(), -2 ); - EXPECT_EQ( x.max(), -2 ); -} - -TYPED_TEST( VectorTest, prefixSum ) +TYPED_TEST( VectorTest, sum ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - using DeviceType = typename VectorType::DeviceType; - using IndexType = typename VectorType::IndexType; - const int size = VECTOR_TEST_SIZE; + // this test expect an even size + const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE; - if( std::is_same< RealType, float >::value || - std::is_same< IndexType, short >::value ) - return; - - VectorType v( size ); + VectorType v; + v.setSize( size ); ViewType v_view( v ); - v = 0; - v.prefixSum(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v.prefixSum(); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); - setConstantSequence( v, 1 ); - v_view.prefixSum(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i + 1 ); - - v = 0; - v_view.prefixSum(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); + EXPECT_EQ( v.sum(), size ); + EXPECT_EQ( v_view.sum(), size ); + EXPECT_EQ( VectorOperations::getVectorSum( v ), size ); setLinearSequence( v ); - v_view.prefixSum(); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); - - //// - // With CUDA, perform tests with multiple CUDA grids. - if( std::is_same< DeviceType, Devices::Cuda >::value ) - { -#ifdef HAVE_CUDA - Algorithms::CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::setMaxGridSize( 3 ); - v = 0; - v.prefixSum(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v.prefixSum(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); - - setConstantSequence( v, 1 ); - v_view.prefixSum(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i + 1 ); - - v = 0; - v_view.prefixSum(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); + EXPECT_EQ( v.sum(), 0.5 * size * ( size - 1 ) ); + EXPECT_EQ( v_view.sum(), 0.5 * size * ( size - 1 ) ); + EXPECT_EQ( VectorOperations::getVectorSum( v ), 0.5 * size * ( size - 1 ) ); + + setNegativeLinearSequence( v ); + EXPECT_EQ( v.sum(), - 0.5 * size * ( size - 1 ) ); + EXPECT_EQ( v_view.sum(), - 0.5 * size * ( size - 1 ) ); + EXPECT_EQ( VectorOperations::getVectorSum( v ), - 0.5 * size * ( size - 1 ) ); + + setOscilatingSequence( v, 1.0 ); + EXPECT_EQ( v.sum(), 0 ); + EXPECT_EQ( v_view.sum(), 0 ); + EXPECT_EQ( VectorOperations::getVectorSum( v ), 0 ); +} - setLinearSequence( v ); - v_view.prefixSum(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); - CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Inclusive, RealType, IndexType >::resetMaxGridSize(); -#endif - } +TEST( VectorSpecialCasesTest, sumOfBoolVector ) +{ + using VectorType = Containers::Vector< bool, Devices::Host >; + using ViewType = VectorView< bool, Devices::Host >; + const float epsilon = 64 * std::numeric_limits< float >::epsilon(); + + VectorType v( 512 ), w( 512 ); + ViewType v_view( v ), w_view( w ); + v.setValue( true ); + w.setValue( false ); + + const int sum = v.sum< int >(); + const int l1norm = v.lpNorm< int >( 1.0 ); + const float l2norm = v.lpNorm< float >( 2.0 ); + const float l3norm = v.lpNorm< float >( 3.0 ); + EXPECT_EQ( sum, 512 ); + EXPECT_EQ( l1norm, 512 ); + EXPECT_NEAR( l2norm, std::sqrt( 512 ), epsilon ); + EXPECT_NEAR( l3norm, std::cbrt( 512 ), epsilon ); + + const int diff_sum = v.differenceSum< int >( w ); + const int diff_l1norm = v.differenceLpNorm< int >( w, 1.0 ); + const float diff_l2norm = v.differenceLpNorm< float >( w, 2.0 ); + const float diff_l3norm = v.differenceLpNorm< float >( w, 3.0 ); + EXPECT_EQ( diff_sum, 512 ); + EXPECT_EQ( diff_l1norm, 512 ); + EXPECT_NEAR( diff_l2norm, std::sqrt( 512 ), epsilon ); + EXPECT_NEAR( diff_l3norm, std::cbrt( 512 ), epsilon ); + + // test views + const int sum_view = v_view.sum< int >(); + const int l1norm_view = v_view.lpNorm< int >( 1.0 ); + const float l2norm_view = v_view.lpNorm< float >( 2.0 ); + const float l3norm_view = v_view.lpNorm< float >( 3.0 ); + EXPECT_EQ( sum_view, 512 ); + EXPECT_EQ( l1norm_view, 512 ); + EXPECT_NEAR( l2norm_view, std::sqrt( 512 ), epsilon ); + EXPECT_NEAR( l3norm_view, std::cbrt( 512 ), epsilon ); + + const int diff_sum_view = v_view.differenceSum< int >( w_view ); + const int diff_l1norm_view = v_view.differenceLpNorm< int >( w_view, 1.0 ); + const float diff_l2norm_view = v_view.differenceLpNorm< float >( w_view, 2.0 ); + const float diff_l3norm_view = v_view.differenceLpNorm< float >( w_view, 3.0 ); + EXPECT_EQ( diff_sum_view, 512 ); + EXPECT_EQ( diff_l1norm_view, 512 ); + EXPECT_NEAR( diff_l2norm_view, std::sqrt( 512 ), epsilon ); + EXPECT_NEAR( diff_l3norm_view, std::cbrt( 512 ), epsilon ); } -TYPED_TEST( VectorTest, exclusivePrefixSum ) +TYPED_TEST( VectorTest, scalarProduct ) { using VectorType = typename TestFixture::VectorType; using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - using DeviceType = typename VectorType::DeviceType; - using IndexType = typename VectorType::IndexType; - const int size = VECTOR_TEST_SIZE; - - if( std::is_same< RealType, float >::value || - std::is_same< IndexType, short >::value ) - return; - - VectorType v; - v.setSize( size ); - ViewType v_view( v ); - - setConstantSequence( v, 1 ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i ); - - v.setValue( 0 ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 ); + // this test expects an odd size + const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1; + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + setOscilatingSequence( u, 1.0 ); setConstantSequence( v, 1 ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i ); - - v.setValue( 0 ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 ); - - //// - // With CUDA, perform tests with multiple CUDA grids. - if( std::is_same< DeviceType, Devices::Cuda >::value ) - { -#ifdef HAVE_CUDA - CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::setMaxGridSize( 3 ); - - setConstantSequence( v, 1 ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i ); - v.setValue( 0 ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 ); - - setConstantSequence( v, 1 ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), i ); - - v.setValue( 0 ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - - setLinearSequence( v ); - v_view.template prefixSum< Algorithms::PrefixSumType::Exclusive >(); - EXPECT_GT( ( CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::gridsCount ), 1 ); - for( int i = 1; i < size; i++ ) - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i - 1 ); - CudaPrefixSumKernelLauncher< Algorithms::PrefixSumType::Exclusive, RealType, IndexType >::resetMaxGridSize(); -#endif - } + EXPECT_EQ( u.scalarProduct( v ), 1.0 ); + EXPECT_EQ( u_view.scalarProduct( v_view ), 1.0 ); + EXPECT_EQ( VectorOperations::getScalarProduct( u, v ), 1.0 ); + EXPECT_EQ( (u, v), 1.0 ); + EXPECT_EQ( (u_view, v_view), 1.0 ); } - -template< typename FlagsView > -void setupFlags( FlagsView& f ) -{ - auto f1 = [] __cuda_callable__ ( typename FlagsView::IndexType i ) { return ( i % 5 ) == 0; }; - f.evaluate( f1 ); -} - -/* -TYPED_TEST( VectorTest, segmentedPrefixSum ) +TYPED_TEST( VectorTest, differenceLpNorm ) { using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; using RealType = typename VectorType::RealType; - using DeviceType = typename VectorType::DeviceType; - using IndexType = typename VectorType::IndexType; - using FlagsArrayType = Array< bool, DeviceType, IndexType >; - using FlagsViewType = ArrayView< bool, DeviceType, IndexType >; + using VectorOperations = typename TestFixture::VectorOperations; + using ViewType = typename TestFixture::ViewType; const int size = VECTOR_TEST_SIZE; - - VectorType v( size ); - ViewType v_view( v ); - - FlagsArrayType flags( size ), flags_copy( size ); - FlagsViewType flags_view( flags ); - //auto f1 = [] __cuda_callable__ ( IndexType i ) { return ( i % 5 ) == 0; }; - //flags_view.evaluate( f1 ); - setupFlags( flags_view ); - flags_copy = flags_view; - - v = 0; - v.computeSegmentedPrefixSum( flags_view ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), 0 ); - flags_view = flags_copy; - - v = 1; - v.computeSegmentedPrefixSum( flags_view ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v.getElement( i ), ( i % 5 ) + 1 ); - flags_view = flags_copy; - - setLinearSequence( v ); - v.computeSegmentedPrefixSum( flags_view ); - for( int i = 1; i < size; i++ ) - { - if( flags.getElement( i ) ) - EXPECT_EQ( v.getElement( i ), i ); - else - EXPECT_EQ( v.getElement( i ) - v.getElement( i - 1 ), i ); - } - flags_view = flags_copy; - - v_view = 0; - v_view.computeSegmentedPrefixSum( flags_view ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v_view.getElement( i ), 0 ); - flags_view = flags_copy; - - v_view = 1; - v_view.computeSegmentedPrefixSum( flags_view ); - for( int i = 0; i < size; i++ ) - EXPECT_EQ( v_view.getElement( i ), ( i % 5 ) + 1 ); - flags_view = flags_copy; - - //v_view.evaluate( [] __cuda_callable__ ( IndexType i ) { return i; } ); - setLinearSequence( v ); - v_view.computeSegmentedPrefixSum( flags_view ); - for( int i = 1; i < size; i++ ) - { - if( flags.getElement( i ) ) - EXPECT_EQ( v_view.getElement( i ), i ); - else - EXPECT_EQ( v_view.getElement( i ) - v_view.getElement( i - 1 ), i ); - } + const RealType epsilon = 64 * std::numeric_limits< RealType >::epsilon(); + + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + u.setValue( 3.0 ); + v.setValue( 1.0 ); + + const RealType expectedL1norm = 2.0 * size; + const RealType expectedL2norm = std::sqrt( 4.0 * size ); + const RealType expectedL3norm = std::cbrt( 8.0 * size ); + EXPECT_EQ( u.differenceLpNorm( v, 1.0 ), expectedL1norm ); + EXPECT_EQ( u.differenceLpNorm( v, 2.0 ), expectedL2norm ); + EXPECT_NEAR( u.differenceLpNorm( v, 3.0 ), expectedL3norm, epsilon ); + EXPECT_EQ( u_view.differenceLpNorm( v_view, 1.0 ), expectedL1norm ); + EXPECT_EQ( u_view.differenceLpNorm( v_view, 2.0 ), expectedL2norm ); + EXPECT_NEAR( u_view.differenceLpNorm( v_view, 3.0 ), expectedL3norm, epsilon ); + EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 1.0 ), expectedL1norm ); + EXPECT_EQ( VectorOperations::getVectorDifferenceLpNorm( u, v, 2.0 ), expectedL2norm ); + EXPECT_NEAR( VectorOperations::getVectorDifferenceLpNorm( u, v, 3.0 ), expectedL3norm, epsilon ); } -*/ -TYPED_TEST( VectorTest, abs ) +TYPED_TEST( VectorTest, differenceSum ) { using VectorType = typename TestFixture::VectorType; + using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - u.setElement( i, i ); - - v = -u; - EXPECT_TRUE( abs( v ) == u ); + // this test expect an even size + const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE - 1 : VECTOR_TEST_SIZE; + + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + v.setValue( 1.0 ); + + setConstantSequence( u, 2 ); + EXPECT_EQ( u.differenceSum( v ), size ); + EXPECT_EQ( u_view.differenceSum( v_view ), size ); + EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), size ); + + setLinearSequence( u ); + EXPECT_EQ( u.differenceSum( v ), 0.5 * size * ( size - 1 ) - size ); + EXPECT_EQ( u_view.differenceSum( v_view ), 0.5 * size * ( size - 1 ) - size ); + EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), 0.5 * size * ( size - 1 ) - size ); + + setNegativeLinearSequence( u ); + EXPECT_EQ( u.differenceSum( v ), - 0.5 * size * ( size - 1 ) - size ); + EXPECT_EQ( u_view.differenceSum( v_view ), - 0.5 * size * ( size - 1 ) - size ); + EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - 0.5 * size * ( size - 1 ) - size ); + + setOscilatingSequence( u, 1.0 ); + EXPECT_EQ( u.differenceSum( v ), - size ); + EXPECT_EQ( u_view.differenceSum( v_view ), - size ); + EXPECT_EQ( VectorOperations::getVectorDifferenceSum( u, v ), - size ); } #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorTest-5.h b/src/UnitTests/Containers/VectorTest-5.h index bff4c117bb..f2a53df10e 100644 --- a/src/UnitTests/Containers/VectorTest-5.h +++ b/src/UnitTests/Containers/VectorTest-5.h @@ -13,197 +13,87 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction constexpr int VECTOR_TEST_SIZE = 5000; -TYPED_TEST( VectorTest, sin ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::sin( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( sin( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( sin( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, cos ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::cos( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( cos( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( cos( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, tan ) +TYPED_TEST( VectorTest, differenceMax ) { using VectorType = typename TestFixture::VectorType; + using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; const int size = VECTOR_TEST_SIZE; - const double h = 10.0 / size; - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - const RealType x = -5.0 + i * h; - u.setElement( i, x ); - v.setElement( i, TNL::tan( x ) ); - } - - //EXPECT_EQ( tan( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( tan( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + setLinearSequence( u ); + setConstantSequence( v, size / 2 ); + EXPECT_EQ( u.differenceMax( v ), size - 1 - size / 2 ); + EXPECT_EQ( u_view.differenceMax( v_view ), size - 1 - size / 2 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceMax( u, v ), size - 1 - size / 2 ); } -TYPED_TEST( VectorTest, sqrt ) +TYPED_TEST( VectorTest, differenceMin ) { using VectorType = typename TestFixture::VectorType; + using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; const int size = VECTOR_TEST_SIZE; - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i ); - v.setElement( i, TNL::sqrt( ( RealType ) i ) ); - } - - //EXPECT_EQ( sqrt( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( sqrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); - + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + setLinearSequence( u ); + setConstantSequence( v, size / 2 ); + + EXPECT_EQ( u.differenceMin( v ), - size / 2 ); + EXPECT_EQ( u_view.differenceMin( v_view ), - size / 2 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceMin( u, v ), - size / 2 ); + EXPECT_EQ( v.differenceMin( u ), size / 2 - size + 1 ); + EXPECT_EQ( v_view.differenceMin( u_view ), size / 2 - size + 1 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceMin( v, u ), size / 2 - size + 1 ); } -TYPED_TEST( VectorTest, cbrt ) +TYPED_TEST( VectorTest, differenceAbsMax ) { using VectorType = typename TestFixture::VectorType; + using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i ); - v.setElement( i, TNL::cbrt( ( RealType ) i ) ); - } + // this test expects an odd size + const int size = VECTOR_TEST_SIZE % 2 ? VECTOR_TEST_SIZE : VECTOR_TEST_SIZE - 1; - //EXPECT_EQ( cbrt( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( cbrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + setNegativeLinearSequence( u ); + setConstantSequence( v, - size / 2 ); + EXPECT_EQ( u.differenceAbsMax( v ), size - 1 - size / 2 ); + EXPECT_EQ( u_view.differenceAbsMax( v_view ), size - 1 - size / 2 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMax( u, v ), size - 1 - size / 2 ); } -TYPED_TEST( VectorTest, pow ) +TYPED_TEST( VectorTest, differenceAbsMin ) { using VectorType = typename TestFixture::VectorType; + using VectorOperations = typename TestFixture::VectorOperations; using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; const int size = VECTOR_TEST_SIZE; - VectorType _u( size ), _v( size ), _w( size ); - ViewType u( _u ), v( _v ), w( _w ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 2.0 ) ); - w.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 3.0 ) ); - } - - //EXPECT_EQ( pow( u, 2.0 ), v ); - //EXPECT_EQ( pow( u, 3.0 ), w ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( pow( u, 2.0 ).getElement( i ), v.getElement( i ), 1.0e-6 ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( pow( u, 3.0 ).getElement( i ), w.getElement( i ), 1.0e-6 ); - - -} - -TYPED_TEST( VectorTest, floor ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::floor( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( floor( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( floor( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); - -} - -TYPED_TEST( VectorTest, ceil ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::ceil( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( ceil( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( ceil( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); - + VectorType u( size ), v( size ); + ViewType u_view( u ), v_view( v ); + setNegativeLinearSequence( u ); + setConstantSequence( v, - size / 2 ); + + EXPECT_EQ( u.differenceAbsMin( v ), 0 ); + EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( u, v ), 0 ); + EXPECT_EQ( v.differenceAbsMin( u ), 0 ); + EXPECT_EQ( v_view.differenceAbsMin( u_view ), 0 ); + EXPECT_EQ( VectorOperations::getVectorDifferenceAbsMin( v, u ), 0 ); } #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorTest-6.h b/src/UnitTests/Containers/VectorTest-6.h index c8e9d3d35e..6b04d4083f 100644 --- a/src/UnitTests/Containers/VectorTest-6.h +++ b/src/UnitTests/Containers/VectorTest-6.h @@ -13,367 +13,74 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction -constexpr int VECTOR_TEST_SIZE = 5000; - -TYPED_TEST( VectorTest, acos ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType )( i - size / 2 ) / ( RealType ) size ); - v.setElement( i, TNL::acos( ( RealType )( i - size / 2 ) / ( RealType ) size ) ); - } - - //EXPECT_EQ( acos( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( acos( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, asin ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) ( i - size / 2 ) / ( RealType ) size ); - v.setElement( i, TNL::asin( ( RealType )( i - size / 2 ) / ( RealType ) size ) ); - } +constexpr int VECTOR_TEST_SIZE = 500; - //EXPECT_EQ( asin( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( asin( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, atan ) +TYPED_TEST( VectorTest, verticalOperations ) { using VectorType = typename TestFixture::VectorType; using ViewType = typename TestFixture::ViewType; using RealType = typename VectorType::RealType; + using IndexType = typename VectorType::IndexType; const int size = VECTOR_TEST_SIZE; - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); + VectorType _u( size ), _v( size ), _w( size ); + ViewType u( _u ), v( _v ), w( _w ); + RealType sum_( 0.0 ), absSum( 0.0 ), diffSum( 0.0 ), diffAbsSum( 0.0 ), + absMin( size + 10.0 ), absMax( -size - 10.0 ), + diffMin( 2 * size + 10.0 ), diffMax( - 2.0 * size - 10.0 ), + l2Norm( 0.0 ), l2NormDiff( 0.0 ), argMinValue( size * size ), argMaxValue( -size * size ); + IndexType argMin( 0 ), argMax( 0 ); for( int i = 0; i < size; i++ ) { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::atan( ( RealType ) i - ( RealType ) size / 2 ) ); + const RealType aux = ( RealType )( i - size / 2 ) / ( RealType ) size; + const RealType w_value = aux * aux - 5.0; + u.setElement( i, aux ); + v.setElement( i, -aux ); + w.setElement( i, w_value ); + absMin = TNL::min( absMin, TNL::abs( aux ) ); + absMax = TNL::max( absMax, TNL::abs( aux ) ); + diffMin = TNL::min( diffMin, 2 * aux ); + diffMax = TNL::max( diffMax, 2 * aux ); + sum_ += aux; + absSum += TNL::abs( aux ); + diffSum += 2.0 * aux; + diffAbsSum += TNL::abs( 2.0* aux ); + l2Norm += aux * aux; + l2NormDiff += 4.0 * aux * aux; + if( w_value < argMinValue ) { + argMinValue = w_value; + argMin = i; + } + if( w_value > argMaxValue ) { + argMaxValue = w_value; + argMax = i; + } } - - //EXPECT_EQ( atan( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( atan( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, cosh ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - RealType h = 2.0 / ( RealType ) size; - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, i * h - ( RealType ) 1.0 ); - v.setElement( i, TNL::cosh( i * h - ( RealType ) 1.0 ) ); - } - - // EXPECT_EQ( cosh( u ), v ) does not work here for float, maybe because - // of some fast-math optimization - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( cosh( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, tanh ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::tanh( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( tanh( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( tanh( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, log ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i + 1 ); - v.setElement( i, TNL::log( ( RealType ) i + 1 ) ); - } - - //EXPECT_EQ( log( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( log( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); - -} - -TYPED_TEST( VectorTest, log10 ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i + 1 ); - v.setElement( i, TNL::log10( ( RealType ) i + 1 ) ); - } - - // EXPECT_EQ( log10( u ), v ) does not work here for float, maybe because - // of some fast-math optimization - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( log10( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, log2 ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i + 1 ); - v.setElement( i, TNL::log2( ( RealType ) i + 1 ) ); - } - - //EXPECT_EQ( log2( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( log2( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); - -} - -TYPED_TEST( VectorTest, exp ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - const double h = 10.0 / size; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - const RealType x = -5.0 + i * h; - u.setElement( i, x ); - v.setElement( i, TNL::exp( x ) ); - } - - //EXPECT_EQ( exp( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( exp( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -TYPED_TEST( VectorTest, sign ) -{ - using VectorType = typename TestFixture::VectorType; - using ViewType = typename TestFixture::ViewType; - using RealType = typename VectorType::RealType; - const int size = VECTOR_TEST_SIZE; - - VectorType _u( size ), _v( size ); - ViewType u( _u ), v( _v ); - for( int i = 0; i < size; i++ ) - { - u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); - v.setElement( i, TNL::sign( ( RealType ) i - ( RealType ) size / 2 ) ); - } - - //EXPECT_EQ( sign( u ), v ); - for( int i = 0; i < size; i++ ) - EXPECT_NEAR( sign( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); -} - -// TODO: test prefix sum with custom begin and end parameters - -TEST( VectorSpecialCasesTest, sumOfBoolVector ) -{ - using VectorType = Containers::Vector< bool, Devices::Host >; - using ViewType = VectorView< bool, Devices::Host >; - const float epsilon = 64 * std::numeric_limits< float >::epsilon(); - - VectorType v( 512 ), w( 512 ); - ViewType v_view( v ), w_view( w ); - v.setValue( true ); - w.setValue( false ); - - const int sum = v.sum< int >(); - const int l1norm = v.lpNorm< int >( 1.0 ); - const float l2norm = v.lpNorm< float >( 2.0 ); - const float l3norm = v.lpNorm< float >( 3.0 ); - EXPECT_EQ( sum, 512 ); - EXPECT_EQ( l1norm, 512 ); - EXPECT_NEAR( l2norm, std::sqrt( 512 ), epsilon ); - EXPECT_NEAR( l3norm, std::cbrt( 512 ), epsilon ); - - const int diff_sum = v.differenceSum< int >( w ); - const int diff_l1norm = v.differenceLpNorm< int >( w, 1.0 ); - const float diff_l2norm = v.differenceLpNorm< float >( w, 2.0 ); - const float diff_l3norm = v.differenceLpNorm< float >( w, 3.0 ); - EXPECT_EQ( diff_sum, 512 ); - EXPECT_EQ( diff_l1norm, 512 ); - EXPECT_NEAR( diff_l2norm, std::sqrt( 512 ), epsilon ); - EXPECT_NEAR( diff_l3norm, std::cbrt( 512 ), epsilon ); - - // test views - const int sum_view = v_view.sum< int >(); - const int l1norm_view = v_view.lpNorm< int >( 1.0 ); - const float l2norm_view = v_view.lpNorm< float >( 2.0 ); - const float l3norm_view = v_view.lpNorm< float >( 3.0 ); - EXPECT_EQ( sum_view, 512 ); - EXPECT_EQ( l1norm_view, 512 ); - EXPECT_NEAR( l2norm_view, std::sqrt( 512 ), epsilon ); - EXPECT_NEAR( l3norm_view, std::cbrt( 512 ), epsilon ); - - const int diff_sum_view = v_view.differenceSum< int >( w_view ); - const int diff_l1norm_view = v_view.differenceLpNorm< int >( w_view, 1.0 ); - const float diff_l2norm_view = v_view.differenceLpNorm< float >( w_view, 2.0 ); - const float diff_l3norm_view = v_view.differenceLpNorm< float >( w_view, 3.0 ); - EXPECT_EQ( diff_sum_view, 512 ); - EXPECT_EQ( diff_l1norm_view, 512 ); - EXPECT_NEAR( diff_l2norm_view, std::sqrt( 512 ), epsilon ); - EXPECT_NEAR( diff_l3norm_view, std::cbrt( 512 ), epsilon ); -} - -TEST( VectorSpecialCasesTest, assignmentThroughView ) -{ - using VectorType = Containers::Vector< int, Devices::Host >; - using ViewType = VectorView< int, Devices::Host >; - - static_assert( Algorithms::Details::HasSubscriptOperator< VectorType >::value, "Subscript operator detection by SFINAE does not work for Vector." ); - static_assert( Algorithms::Details::HasSubscriptOperator< ViewType >::value, "Subscript operator detection by SFINAE does not work for VectorView." ); - - VectorType u( 100 ), v( 100 ); - ViewType u_view( u ), v_view( v ); - - u.setValue( 42 ); - v.setValue( 0 ); - v_view = u_view; - EXPECT_EQ( u_view.getData(), u.getData() ); - EXPECT_EQ( v_view.getData(), v.getData() ); - for( int i = 0; i < 100; i++ ) - EXPECT_EQ( v_view[ i ], 42 ); - - u.setValue( 42 ); - v.setValue( 0 ); - v_view = u; - EXPECT_EQ( u_view.getData(), u.getData() ); - EXPECT_EQ( v_view.getData(), v.getData() ); - for( int i = 0; i < 100; i++ ) - EXPECT_EQ( v_view[ i ], 42 ); -} - -TEST( VectorSpecialCasesTest, operationsOnConstView ) -{ - using VectorType = Containers::Vector< int, Devices::Host >; - using ViewType = VectorView< const int, Devices::Host >; - - VectorType u( 100 ), v( 100 ); - ViewType u_view( u ), v_view( v ); - - u.setValue( 1 ); - v.setValue( 1 ); - - EXPECT_EQ( u_view.max(), 1 ); - EXPECT_EQ( u_view.min(), 1 ); - EXPECT_EQ( u_view.absMax(), 1 ); - EXPECT_EQ( u_view.absMin(), 1 ); - EXPECT_EQ( u_view.lpNorm( 1 ), 100 ); - EXPECT_EQ( u_view.differenceMax( v_view ), 0 ); - EXPECT_EQ( u_view.differenceMin( v_view ), 0 ); - EXPECT_EQ( u_view.differenceAbsMax( v_view ), 0 ); - EXPECT_EQ( u_view.differenceAbsMin( v_view ), 0 ); - EXPECT_EQ( u_view.differenceLpNorm( v_view, 1 ), 0 ); - EXPECT_EQ( u_view.differenceSum( v_view ), 0 ); - EXPECT_EQ( u_view.scalarProduct( v_view ), 100 ); -} - -TEST( VectorSpecialCasesTest, initializationOfVectorViewByArrayView ) -{ - using ArrayType = Containers::Array< int, Devices::Host >; - using VectorViewType = VectorView< const int, Devices::Host >; - using ArrayViewType = ArrayView< int, Devices::Host >; - - ArrayType a( 100 ); - a.setValue( 0 ); - ArrayViewType a_view( a ); - - VectorViewType v_view( a_view ); - EXPECT_EQ( v_view.getData(), a_view.getData() ); - EXPECT_EQ( v_view.sum(), 0 ); -} - -TEST( VectorSpecialCasesTest, defaultConstructors ) -{ - using ArrayType = Containers::Array< int, Devices::Host >; - using VectorViewType = VectorView< int, Devices::Host >; - using ArrayViewType = ArrayView< int, Devices::Host >; - - ArrayType a( 100 ); - a.setValue( 0 ); - - ArrayViewType a_view; - a_view.bind( a ); - - VectorViewType v_view; - v_view.bind( a ); - EXPECT_EQ( v_view.getData(), a_view.getData() ); + l2Norm = TNL::sqrt( l2Norm ); + l2NormDiff = TNL::sqrt( l2NormDiff ); + + EXPECT_EQ( min( u ), u.getElement( 0 ) ); + EXPECT_EQ( max( u ), u.getElement( size - 1 ) ); + EXPECT_NEAR( sum( u ), sum_, 2.0e-5 ); + EXPECT_EQ( min( abs( u ) ), absMin ); + EXPECT_EQ( max( abs( u ) ), absMax ); + EXPECT_EQ( min( u - v ), diffMin ); + EXPECT_EQ( max( u - v ), diffMax ); + EXPECT_NEAR( sum( u - v ), diffSum, 2.0e-5 ); + EXPECT_NEAR( sum( abs( u - v ) ), diffAbsSum, 2.0e-5 ); + EXPECT_NEAR( lpNorm( u, 2.0 ), l2Norm, 2.0e-5 ); + EXPECT_NEAR( lpNorm( u - v, 2.0 ), l2NormDiff, 2.0e-5 ); + IndexType wArgMin, wArgMax; + EXPECT_NEAR( TNL::argMin( w, wArgMin ), argMinValue, 2.0e-5 ); + EXPECT_EQ( argMin, wArgMin ); + EXPECT_NEAR( TNL::argMax( w, wArgMax ), argMaxValue, 2.0e-5 ); + EXPECT_EQ( argMax, wArgMax ); } #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorTest-7.h b/src/UnitTests/Containers/VectorTest-7.h index a8a6c145de..ecf6fabbf6 100644 --- a/src/UnitTests/Containers/VectorTest-7.h +++ b/src/UnitTests/Containers/VectorTest-7.h @@ -13,109 +13,144 @@ #pragma once #ifdef HAVE_GTEST -#include <limits> - -#include <TNL/Experimental/Arithmetics/Quad.h> -#include <TNL/Containers/Vector.h> -#include <TNL/Containers/VectorView.h> #include "VectorTestSetup.h" -#include "gtest/gtest.h" - -using namespace TNL; -using namespace TNL::Containers; -using namespace TNL::Containers::Algorithms; -using namespace TNL::Arithmetics; - // should be small enough to have fast tests, but larger than minGPUReductionDataSize // and large enough to require multiple CUDA blocks for reduction -constexpr int VECTOR_TEST_SIZE = 500; +constexpr int VECTOR_TEST_SIZE = 100; -TYPED_TEST( VectorTest, horizontalOperations ) +TYPED_TEST( VectorTest, sin ) { using VectorType = typename TestFixture::VectorType; using ViewType = typename TestFixture::ViewType; using RealType = typename VectorType::RealType; - using IndexType = typename VectorType::IndexType; const int size = VECTOR_TEST_SIZE; - VectorType _u( size ), _v( size ), _w( size ); - ViewType u( _u ), v( _v ), w( _w ); - EXPECT_EQ( u.getSize(), size ); - u = 0; - v = 1; - w = 2; + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::sin( ( RealType ) i - ( RealType ) size / 2 ) ); + } + + //EXPECT_EQ( sin( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( sin( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, cos ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; - u = u + 4 * TNL::max( v, 0 ); - EXPECT_TRUE( u.containsOnlyValue( 4.0 ) ); + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::cos( ( RealType ) i - ( RealType ) size / 2 ) ); + } - u = u + 3 * w + 4 * TNL::max( v, 0 ); - EXPECT_TRUE( u.containsOnlyValue( 14.0 ) ); + //EXPECT_EQ( cos( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( cos( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); } -TYPED_TEST( VectorTest, verticalOperations ) +TYPED_TEST( VectorTest, tan ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + const double h = 10.0 / size; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + const RealType x = -5.0 + i * h; + u.setElement( i, x ); + v.setElement( i, TNL::tan( x ) ); + } + + //EXPECT_EQ( tan( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( tan( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, sqrt ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i ); + v.setElement( i, TNL::sqrt( ( RealType ) i ) ); + } + + //EXPECT_EQ( sqrt( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( sqrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, cbrt ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i ); + v.setElement( i, TNL::cbrt( ( RealType ) i ) ); + } + + //EXPECT_EQ( cbrt( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( cbrt( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, pow ) { using VectorType = typename TestFixture::VectorType; using ViewType = typename TestFixture::ViewType; using RealType = typename VectorType::RealType; - using IndexType = typename VectorType::IndexType; const int size = VECTOR_TEST_SIZE; VectorType _u( size ), _v( size ), _w( size ); ViewType u( _u ), v( _v ), w( _w ); - RealType sum_( 0.0 ), absSum( 0.0 ), diffSum( 0.0 ), diffAbsSum( 0.0 ), - absMin( size + 10.0 ), absMax( -size - 10.0 ), - diffMin( 2 * size + 10.0 ), diffMax( - 2.0 * size - 10.0 ), - l2Norm( 0.0 ), l2NormDiff( 0.0 ), argMinValue( size * size ), argMaxValue( -size * size ); - IndexType argMin( 0 ), argMax( 0 ); for( int i = 0; i < size; i++ ) { - const RealType aux = ( RealType )( i - size / 2 ) / ( RealType ) size; - const RealType w_value = aux * aux - 5.0; - u.setElement( i, aux ); - v.setElement( i, -aux ); - w.setElement( i, w_value ); - absMin = TNL::min( absMin, TNL::abs( aux ) ); - absMax = TNL::max( absMax, TNL::abs( aux ) ); - diffMin = TNL::min( diffMin, 2 * aux ); - diffMax = TNL::max( diffMax, 2 * aux ); - sum_ += aux; - absSum += TNL::abs( aux ); - diffSum += 2.0 * aux; - diffAbsSum += TNL::abs( 2.0* aux ); - l2Norm += aux * aux; - l2NormDiff += 4.0 * aux * aux; - if( w_value < argMinValue ) { - argMinValue = w_value; - argMin = i; - } - if( w_value > argMaxValue ) { - argMaxValue = w_value; - argMax = i; - } + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 2.0 ) ); + w.setElement( i, TNL::pow( ( RealType ) i - ( RealType ) size / 2, 3.0 ) ); } - l2Norm = TNL::sqrt( l2Norm ); - l2NormDiff = TNL::sqrt( l2NormDiff ); - EXPECT_EQ( min( u ), u.getElement( 0 ) ); - EXPECT_EQ( max( u ), u.getElement( size - 1 ) ); - EXPECT_NEAR( sum( u ), sum_, 2.0e-5 ); - EXPECT_EQ( min( abs( u ) ), absMin ); - EXPECT_EQ( max( abs( u ) ), absMax ); - EXPECT_EQ( min( u - v ), diffMin ); - EXPECT_EQ( max( u - v ), diffMax ); - EXPECT_NEAR( sum( u - v ), diffSum, 2.0e-5 ); - EXPECT_NEAR( sum( abs( u - v ) ), diffAbsSum, 2.0e-5 ); - EXPECT_NEAR( lpNorm( u, 2.0 ), l2Norm, 2.0e-5 ); - EXPECT_NEAR( lpNorm( u - v, 2.0 ), l2NormDiff, 2.0e-5 ); - IndexType wArgMin, wArgMax; - EXPECT_NEAR( TNL::argMin( w, wArgMin ), argMinValue, 2.0e-5 ); - EXPECT_EQ( argMin, wArgMin ); - EXPECT_NEAR( TNL::argMax( w, wArgMax ), argMaxValue, 2.0e-5 ); - EXPECT_EQ( argMax, wArgMax ); + //EXPECT_EQ( pow( u, 2.0 ), v ); + //EXPECT_EQ( pow( u, 3.0 ), w ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( pow( u, 2.0 ).getElement( i ), v.getElement( i ), 1.0e-6 ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( pow( u, 3.0 ).getElement( i ), w.getElement( i ), 1.0e-6 ); + + } -TYPED_TEST( VectorTest, scalarProduct ) +TYPED_TEST( VectorTest, floor ) { using VectorType = typename TestFixture::VectorType; using ViewType = typename TestFixture::ViewType; @@ -124,18 +159,246 @@ TYPED_TEST( VectorTest, scalarProduct ) VectorType _u( size ), _v( size ); ViewType u( _u ), v( _v ); - RealType aux( 0.0 ); for( int i = 0; i < size; i++ ) { - const RealType x = i; - const RealType y = size / 2 - i; - u.setElement( i, x ); - v.setElement( i, y ); - aux += x * y; + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::floor( ( RealType ) i - ( RealType ) size / 2 ) ); + } + + //EXPECT_EQ( floor( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( floor( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, ceil ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::ceil( ( RealType ) i - ( RealType ) size / 2 ) ); + } + + //EXPECT_EQ( ceil( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( ceil( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, acos ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType )( i - size / 2 ) / ( RealType ) size ); + v.setElement( i, TNL::acos( ( RealType )( i - size / 2 ) / ( RealType ) size ) ); + } + + //EXPECT_EQ( acos( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( acos( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, asin ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) ( i - size / 2 ) / ( RealType ) size ); + v.setElement( i, TNL::asin( ( RealType )( i - size / 2 ) / ( RealType ) size ) ); + } + + //EXPECT_EQ( asin( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( asin( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, atan ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::atan( ( RealType ) i - ( RealType ) size / 2 ) ); } - EXPECT_NEAR( ( u, v ), aux, 1.0e-5 ); + + //EXPECT_EQ( atan( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( atan( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, cosh ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + RealType h = 2.0 / ( RealType ) size; + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, i * h - ( RealType ) 1.0 ); + v.setElement( i, TNL::cosh( i * h - ( RealType ) 1.0 ) ); + } + + // EXPECT_EQ( cosh( u ), v ) does not work here for float, maybe because + // of some fast-math optimization + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( cosh( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, tanh ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::tanh( ( RealType ) i - ( RealType ) size / 2 ) ); + } + + //EXPECT_EQ( tanh( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( tanh( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, log ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i + 1 ); + v.setElement( i, TNL::log( ( RealType ) i + 1 ) ); + } + + //EXPECT_EQ( log( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( log( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, log10 ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i + 1 ); + v.setElement( i, TNL::log10( ( RealType ) i + 1 ) ); + } + + // EXPECT_EQ( log10( u ), v ) does not work here for float, maybe because + // of some fast-math optimization + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( log10( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, log2 ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i + 1 ); + v.setElement( i, TNL::log2( ( RealType ) i + 1 ) ); + } + + //EXPECT_EQ( log2( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( log2( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); + +} + +TYPED_TEST( VectorTest, exp ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + const double h = 10.0 / size; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + const RealType x = -5.0 + i * h; + u.setElement( i, x ); + v.setElement( i, TNL::exp( x ) ); + } + + //EXPECT_EQ( exp( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( exp( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); +} + +TYPED_TEST( VectorTest, sign ) +{ + using VectorType = typename TestFixture::VectorType; + using ViewType = typename TestFixture::ViewType; + using RealType = typename VectorType::RealType; + const int size = VECTOR_TEST_SIZE; + + VectorType _u( size ), _v( size ); + ViewType u( _u ), v( _v ); + for( int i = 0; i < size; i++ ) + { + u.setElement( i, ( RealType ) i - ( RealType ) size / 2 ); + v.setElement( i, TNL::sign( ( RealType ) i - ( RealType ) size / 2 ) ); + } + + //EXPECT_EQ( sign( u ), v ); + for( int i = 0; i < size; i++ ) + EXPECT_NEAR( sign( u ).getElement( i ), v.getElement( i ), 1.0e-6 ); } #endif // HAVE_GTEST -#include "../main.h" \ No newline at end of file +#include "../main.h" -- GitLab