From 2cc4680c7564f2f062781eef3d4775368b98b5d1 Mon Sep 17 00:00:00 2001 From: Tomas Oberhuber <tomas.oberhuber@fjfi.cvut.cz> Date: Wed, 8 Jan 2020 17:38:17 +0100 Subject: [PATCH] Fixed Matrices::Dense::getSerializationType unit test. --- src/TNL/Matrices/Dense.hpp | 2 +- src/UnitTests/Matrices/DenseMatrixTest.h | 31 +- .../Matrices/TridiagonalMatrixTest.cpp | 11 + .../Matrices/TridiagonalMatrixTest.cu | 11 + .../Matrices/TridiagonalMatrixTest.h | 1614 +++++++++++++++++ 5 files changed, 1651 insertions(+), 18 deletions(-) create mode 100644 src/UnitTests/Matrices/TridiagonalMatrixTest.cpp create mode 100644 src/UnitTests/Matrices/TridiagonalMatrixTest.cu create mode 100644 src/UnitTests/Matrices/TridiagonalMatrixTest.h diff --git a/src/TNL/Matrices/Dense.hpp b/src/TNL/Matrices/Dense.hpp index 49e218c779..c4deeb6fa4 100644 --- a/src/TNL/Matrices/Dense.hpp +++ b/src/TNL/Matrices/Dense.hpp @@ -78,7 +78,7 @@ getSerializationType() { return String( "Matrices::Dense< " ) + TNL::getSerializationType< RealType >() + ", [any_device], " + - TNL::getSerializationType< IndexType >() + + TNL::getSerializationType< IndexType >() + ", " + ( RowMajorOrder ? "true" : "false" ) + ", [any_allocator] >"; } diff --git a/src/UnitTests/Matrices/DenseMatrixTest.h b/src/UnitTests/Matrices/DenseMatrixTest.h index 8c3132caf8..183783ea3e 100644 --- a/src/UnitTests/Matrices/DenseMatrixTest.h +++ b/src/UnitTests/Matrices/DenseMatrixTest.h @@ -31,24 +31,16 @@ static const char* TEST_FILE_NAME = "test_DenseMatrixTest.tnl"; #include <gtest/gtest.h> -template< typename MatrixHostFloat, typename MatrixHostInt > -void host_test_GetType() +void test_GetSerializationType() { - MatrixHostFloat mtrxHostFloat; - MatrixHostInt mtrxHostInt; - - EXPECT_EQ( mtrxHostFloat.getType(), TNL::String( "Matrices::Dense< float, Devices::Host, int >" ) ); - EXPECT_EQ( mtrxHostInt.getType(), TNL::String( "Matrices::Dense< int, Devices::Host, int >" ) ); -} - -template< typename MatrixCudaFloat, typename MatrixCudaInt > -void cuda_test_GetType() -{ - MatrixCudaFloat mtrxCudaFloat; - MatrixCudaInt mtrxCudaInt; - - EXPECT_EQ( mtrxCudaFloat.getType(), TNL::String( "Matrices::Dense< float, Devices::Cuda, int >" ) ); - EXPECT_EQ( mtrxCudaInt.getType(), TNL::String( "Matrices::Dense< int, Devices::Cuda, int >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< float, TNL::Devices::Host, int, true >::getSerializationType() ), TNL::String( "Matrices::Dense< float, [any_device], int, true, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< int, TNL::Devices::Host, int, true >::getSerializationType() ), TNL::String( "Matrices::Dense< int, [any_device], int, true, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< float, TNL::Devices::Cuda, int, true >::getSerializationType() ), TNL::String( "Matrices::Dense< float, [any_device], int, true, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< int, TNL::Devices::Cuda, int, true >::getSerializationType() ), TNL::String( "Matrices::Dense< int, [any_device], int, true, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< float, TNL::Devices::Host, int, false >::getSerializationType() ), TNL::String( "Matrices::Dense< float, [any_device], int, false, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< int, TNL::Devices::Host, int, false >::getSerializationType() ), TNL::String( "Matrices::Dense< int, [any_device], int, false, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< float, TNL::Devices::Cuda, int, false >::getSerializationType() ), TNL::String( "Matrices::Dense< float, [any_device], int, false, [any_allocator] >" ) ); + EXPECT_EQ( ( TNL::Matrices::Dense< int, TNL::Devices::Cuda, int, false >::getSerializationType() ), TNL::String( "Matrices::Dense< int, [any_device], int, false, [any_allocator] >" ) ); } template< typename Matrix > @@ -1377,6 +1369,11 @@ using MatrixTypes = ::testing::Types TYPED_TEST_SUITE( MatrixTest, MatrixTypes ); +TYPED_TEST( MatrixTest, getSerializationType ) +{ + test_GetSerializationType(); +} + TYPED_TEST( MatrixTest, setDimensionsTest ) { using MatrixType = typename TestFixture::MatrixType; diff --git a/src/UnitTests/Matrices/TridiagonalMatrixTest.cpp b/src/UnitTests/Matrices/TridiagonalMatrixTest.cpp new file mode 100644 index 0000000000..a56349360a --- /dev/null +++ b/src/UnitTests/Matrices/TridiagonalMatrixTest.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + DenseMatrixTest.cpp - description + ------------------- + begin : Nov 10, 2018 + copyright : (C) 2018 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include "DenseMatrixTest.h" \ No newline at end of file diff --git a/src/UnitTests/Matrices/TridiagonalMatrixTest.cu b/src/UnitTests/Matrices/TridiagonalMatrixTest.cu new file mode 100644 index 0000000000..11d45efdb5 --- /dev/null +++ b/src/UnitTests/Matrices/TridiagonalMatrixTest.cu @@ -0,0 +1,11 @@ +/*************************************************************************** + DenseMatrixTest.cu - description + ------------------- + begin : Nov 10, 2018 + copyright : (C) 2018 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include "DenseMatrixTest.h" \ No newline at end of file diff --git a/src/UnitTests/Matrices/TridiagonalMatrixTest.h b/src/UnitTests/Matrices/TridiagonalMatrixTest.h new file mode 100644 index 0000000000..8c3132caf8 --- /dev/null +++ b/src/UnitTests/Matrices/TridiagonalMatrixTest.h @@ -0,0 +1,1614 @@ +/*************************************************************************** + DenseMatrixTest.h - description + ------------------- + begin : Nov 10, 2018 + copyright : (C) 2018 by Tomas Oberhuber et al. + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include <TNL/Devices/Host.h> +#include <TNL/Matrices/Matrix.h> +#include <TNL/Matrices/Dense.h> +#include <TNL/Containers/Array.h> + +#include <TNL/Containers/Vector.h> +#include <TNL/Containers/VectorView.h> +#include <TNL/Math.h> +#include <iostream> + +using Dense_host_float = TNL::Matrices::Dense< float, TNL::Devices::Host, int >; +using Dense_host_int = TNL::Matrices::Dense< int, TNL::Devices::Host, int >; + +using Dense_cuda_float = TNL::Matrices::Dense< float, TNL::Devices::Cuda, int >; +using Dense_cuda_int = TNL::Matrices::Dense< int, TNL::Devices::Cuda, int >; + +static const char* TEST_FILE_NAME = "test_DenseMatrixTest.tnl"; + +#ifdef HAVE_GTEST +#include <type_traits> + +#include <gtest/gtest.h> + +template< typename MatrixHostFloat, typename MatrixHostInt > +void host_test_GetType() +{ + MatrixHostFloat mtrxHostFloat; + MatrixHostInt mtrxHostInt; + + EXPECT_EQ( mtrxHostFloat.getType(), TNL::String( "Matrices::Dense< float, Devices::Host, int >" ) ); + EXPECT_EQ( mtrxHostInt.getType(), TNL::String( "Matrices::Dense< int, Devices::Host, int >" ) ); +} + +template< typename MatrixCudaFloat, typename MatrixCudaInt > +void cuda_test_GetType() +{ + MatrixCudaFloat mtrxCudaFloat; + MatrixCudaInt mtrxCudaInt; + + EXPECT_EQ( mtrxCudaFloat.getType(), TNL::String( "Matrices::Dense< float, Devices::Cuda, int >" ) ); + EXPECT_EQ( mtrxCudaInt.getType(), TNL::String( "Matrices::Dense< int, Devices::Cuda, int >" ) ); +} + +template< typename Matrix > +void test_SetDimensions() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + const IndexType rows = 9; + const IndexType cols = 8; + + Matrix m; + m.setDimensions( rows, cols ); + + EXPECT_EQ( m.getRows(), 9 ); + EXPECT_EQ( m.getColumns(), 8 ); +} + +template< typename Matrix1, typename Matrix2 > +void test_SetLike() +{ + using RealType = typename Matrix1::RealType; + using DeviceType = typename Matrix1::DeviceType; + using IndexType = typename Matrix1::IndexType; + + const IndexType rows = 8; + const IndexType cols = 7; + + Matrix1 m1; + m1.reset(); + m1.setDimensions( rows + 1, cols + 2 ); + + Matrix2 m2; + m2.reset(); + m2.setDimensions( rows, cols ); + + m1.setLike( m2 ); + + EXPECT_EQ( m1.getRows(), m2.getRows() ); + EXPECT_EQ( m1.getColumns(), m2.getColumns() ); +} + +template< typename Matrix > +void test_GetCompressedRowLengths() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + const IndexType rows = 10; + const IndexType cols = 11; + + Matrix m( rows, cols ); + + // Insert values into the rows. + RealType value = 1; + + for( IndexType i = 0; i < 3; i++ ) // 0th row + m.setElement( 0, i, value++ ); + + for( IndexType i = 0; i < 3; i++ ) // 1st row + m.setElement( 1, i, value++ ); + + for( IndexType i = 0; i < 1; i++ ) // 2nd row + m.setElement( 2, i, value++ ); + + for( IndexType i = 0; i < 2; i++ ) // 3rd row + m.setElement( 3, i, value++ ); + + for( IndexType i = 0; i < 3; i++ ) // 4th row + m.setElement( 4, i, value++ ); + + for( IndexType i = 0; i < 4; i++ ) // 5th row + m.setElement( 5, i, value++ ); + + for( IndexType i = 0; i < 5; i++ ) // 6th row + m.setElement( 6, i, value++ ); + + for( IndexType i = 0; i < 6; i++ ) // 7th row + m.setElement( 7, i, value++ ); + + for( IndexType i = 0; i < 7; i++ ) // 8th row + m.setElement( 8, i, value++ ); + + for( IndexType i = 0; i < 8; i++ ) // 9th row + m.setElement( 9, i, value++ ); + + typename Matrix::CompressedRowLengthsVector rowLengths; + rowLengths = 0; + m.getCompressedRowLengths( rowLengths ); + typename Matrix::CompressedRowLengthsVector correctRowLengths{ 3, 3, 1, 2, 3, 4, 5, 6, 7, 8 }; + EXPECT_EQ( rowLengths, correctRowLengths ); +} + +template< typename Matrix > +void test_GetRowLength() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + const IndexType rows = 8; + const IndexType cols = 7; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + EXPECT_EQ( m.getRowLength( 0 ), 7 ); + EXPECT_EQ( m.getRowLength( 1 ), 7 ); + EXPECT_EQ( m.getRowLength( 2 ), 7 ); + EXPECT_EQ( m.getRowLength( 3 ), 7 ); + EXPECT_EQ( m.getRowLength( 4 ), 7 ); + EXPECT_EQ( m.getRowLength( 5 ), 7 ); + EXPECT_EQ( m.getRowLength( 6 ), 7 ); + EXPECT_EQ( m.getRowLength( 7 ), 7 ); +} + +template< typename Matrix > +void test_GetNumberOfMatrixElements() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + const IndexType rows = 7; + const IndexType cols = 6; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + EXPECT_EQ( m.getNumberOfMatrixElements(), 42 ); +} + +template< typename Matrix > +void test_GetNumberOfNonzeroMatrixElements() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + +/* + * Sets up the following 7x6 dense matrix: + * + * / 0 2 3 4 5 6 \ + * | 7 8 9 10 11 12 | + * | 13 14 15 16 17 18 | + * | 19 20 21 22 23 24 | + * | 25 26 27 28 29 30 | + * | 31 32 33 34 35 36 | + * \ 37 38 39 40 41 0 / + */ + const IndexType rows = 7; + const IndexType cols = 6; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + m.setElement( 0, 0, 0); // Set the first element of the diagonal to 0. + m.setElement( 6, 5, 0); // Set the last element of the diagonal to 0. + + EXPECT_EQ( m.getNumberOfNonzeroMatrixElements(), 40 ); +} + +template< typename Matrix > +void test_Reset() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + +/* + * Sets up the following 5x4 dense matrix: + * + * / 0 0 0 0 \ + * | 0 0 0 0 | + * | 0 0 0 0 | + * | 0 0 0 0 | + * \ 0 0 0 0 / + */ + const IndexType rows = 5; + const IndexType cols = 4; + + Matrix m; + m.setDimensions( rows, cols ); + + m.reset(); + + EXPECT_EQ( m.getRows(), 0 ); + EXPECT_EQ( m.getColumns(), 0 ); +} + +template< typename Matrix > +void test_SetValue() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 7x6 dense matrix: + * + * / 1 2 3 4 5 6 \ + * | 7 8 9 10 11 12 | + * | 13 14 15 16 17 18 | + * | 19 20 21 22 23 24 | + * | 25 26 27 28 29 30 | + * | 31 32 33 34 35 36 | + * \ 37 38 39 40 41 42 / + */ + const IndexType rows = 7; + const IndexType cols = 6; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + EXPECT_EQ( m.getElement( 0, 0 ), 1 ); + EXPECT_EQ( m.getElement( 0, 1 ), 2 ); + EXPECT_EQ( m.getElement( 0, 2 ), 3 ); + EXPECT_EQ( m.getElement( 0, 3 ), 4 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); + EXPECT_EQ( m.getElement( 0, 5 ), 6 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 7 ); + EXPECT_EQ( m.getElement( 1, 1 ), 8 ); + EXPECT_EQ( m.getElement( 1, 2 ), 9 ); + EXPECT_EQ( m.getElement( 1, 3 ), 10 ); + EXPECT_EQ( m.getElement( 1, 4 ), 11 ); + EXPECT_EQ( m.getElement( 1, 5 ), 12 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 13 ); + EXPECT_EQ( m.getElement( 2, 1 ), 14 ); + EXPECT_EQ( m.getElement( 2, 2 ), 15 ); + EXPECT_EQ( m.getElement( 2, 3 ), 16 ); + EXPECT_EQ( m.getElement( 2, 4 ), 17 ); + EXPECT_EQ( m.getElement( 2, 5 ), 18 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 19 ); + EXPECT_EQ( m.getElement( 3, 1 ), 20 ); + EXPECT_EQ( m.getElement( 3, 2 ), 21 ); + EXPECT_EQ( m.getElement( 3, 3 ), 22 ); + EXPECT_EQ( m.getElement( 3, 4 ), 23 ); + EXPECT_EQ( m.getElement( 3, 5 ), 24 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 25 ); + EXPECT_EQ( m.getElement( 4, 1 ), 26 ); + EXPECT_EQ( m.getElement( 4, 2 ), 27 ); + EXPECT_EQ( m.getElement( 4, 3 ), 28 ); + EXPECT_EQ( m.getElement( 4, 4 ), 29 ); + EXPECT_EQ( m.getElement( 4, 5 ), 30 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 31 ); + EXPECT_EQ( m.getElement( 5, 1 ), 32 ); + EXPECT_EQ( m.getElement( 5, 2 ), 33 ); + EXPECT_EQ( m.getElement( 5, 3 ), 34 ); + EXPECT_EQ( m.getElement( 5, 4 ), 35 ); + EXPECT_EQ( m.getElement( 5, 5 ), 36 ); + + EXPECT_EQ( m.getElement( 6, 0 ), 37 ); + EXPECT_EQ( m.getElement( 6, 1 ), 38 ); + EXPECT_EQ( m.getElement( 6, 2 ), 39 ); + EXPECT_EQ( m.getElement( 6, 3 ), 40 ); + EXPECT_EQ( m.getElement( 6, 4 ), 41 ); + EXPECT_EQ( m.getElement( 6, 5 ), 42 ); + + // Set the values of all elements to a certain number + m.setValue( 42 ); + + EXPECT_EQ( m.getElement( 0, 0 ), 42 ); + EXPECT_EQ( m.getElement( 0, 1 ), 42 ); + EXPECT_EQ( m.getElement( 0, 2 ), 42 ); + EXPECT_EQ( m.getElement( 0, 3 ), 42 ); + EXPECT_EQ( m.getElement( 0, 4 ), 42 ); + EXPECT_EQ( m.getElement( 0, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 42 ); + EXPECT_EQ( m.getElement( 1, 1 ), 42 ); + EXPECT_EQ( m.getElement( 1, 2 ), 42 ); + EXPECT_EQ( m.getElement( 1, 3 ), 42 ); + EXPECT_EQ( m.getElement( 1, 4 ), 42 ); + EXPECT_EQ( m.getElement( 1, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 42 ); + EXPECT_EQ( m.getElement( 2, 1 ), 42 ); + EXPECT_EQ( m.getElement( 2, 2 ), 42 ); + EXPECT_EQ( m.getElement( 2, 3 ), 42 ); + EXPECT_EQ( m.getElement( 2, 4 ), 42 ); + EXPECT_EQ( m.getElement( 2, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 42 ); + EXPECT_EQ( m.getElement( 3, 1 ), 42 ); + EXPECT_EQ( m.getElement( 3, 2 ), 42 ); + EXPECT_EQ( m.getElement( 3, 3 ), 42 ); + EXPECT_EQ( m.getElement( 3, 4 ), 42 ); + EXPECT_EQ( m.getElement( 3, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 42 ); + EXPECT_EQ( m.getElement( 4, 1 ), 42 ); + EXPECT_EQ( m.getElement( 4, 2 ), 42 ); + EXPECT_EQ( m.getElement( 4, 3 ), 42 ); + EXPECT_EQ( m.getElement( 4, 4 ), 42 ); + EXPECT_EQ( m.getElement( 4, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 42 ); + EXPECT_EQ( m.getElement( 5, 1 ), 42 ); + EXPECT_EQ( m.getElement( 5, 2 ), 42 ); + EXPECT_EQ( m.getElement( 5, 3 ), 42 ); + EXPECT_EQ( m.getElement( 5, 4 ), 42 ); + EXPECT_EQ( m.getElement( 5, 5 ), 42 ); + + EXPECT_EQ( m.getElement( 6, 0 ), 42 ); + EXPECT_EQ( m.getElement( 6, 1 ), 42 ); + EXPECT_EQ( m.getElement( 6, 2 ), 42 ); + EXPECT_EQ( m.getElement( 6, 3 ), 42 ); + EXPECT_EQ( m.getElement( 6, 4 ), 42 ); + EXPECT_EQ( m.getElement( 6, 5 ), 42 ); +} + +template< typename Matrix > +void test_SetElement() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 5x5 dense matrix: + * + * / 1 2 3 4 5 \ + * | 6 7 8 9 10 | + * | 11 12 13 14 15 | + * | 16 17 18 19 20 | + * \ 21 22 23 24 25 / + */ + const IndexType rows = 5; + const IndexType cols = 5; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + EXPECT_EQ( m.getElement( 0, 0 ), 1 ); + EXPECT_EQ( m.getElement( 0, 1 ), 2 ); + EXPECT_EQ( m.getElement( 0, 2 ), 3 ); + EXPECT_EQ( m.getElement( 0, 3 ), 4 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 1 ), 7 ); + EXPECT_EQ( m.getElement( 1, 2 ), 8 ); + EXPECT_EQ( m.getElement( 1, 3 ), 9 ); + EXPECT_EQ( m.getElement( 1, 4 ), 10 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 11 ); + EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 2 ), 13 ); + EXPECT_EQ( m.getElement( 2, 3 ), 14 ); + EXPECT_EQ( m.getElement( 2, 4 ), 15 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 16 ); + EXPECT_EQ( m.getElement( 3, 1 ), 17 ); + EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 3 ), 19 ); + EXPECT_EQ( m.getElement( 3, 4 ), 20 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 21 ); + EXPECT_EQ( m.getElement( 4, 1 ), 22 ); + EXPECT_EQ( m.getElement( 4, 2 ), 23 ); + EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 4 ), 25 ); +} + +template< typename Matrix > +void test_AddElement() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 6x5 dense matrix: + * + * / 1 2 3 4 5 \ + * | 6 7 8 9 10 | + * | 11 12 13 14 15 | + * | 16 17 18 19 20 | + * | 21 22 23 24 25 | + * \ 26 27 28 29 30 / + */ + const IndexType rows = 6; + const IndexType cols = 5; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + // Check the added elements + EXPECT_EQ( m.getElement( 0, 0 ), 1 ); + EXPECT_EQ( m.getElement( 0, 1 ), 2 ); + EXPECT_EQ( m.getElement( 0, 2 ), 3 ); + EXPECT_EQ( m.getElement( 0, 3 ), 4 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 1 ), 7 ); + EXPECT_EQ( m.getElement( 1, 2 ), 8 ); + EXPECT_EQ( m.getElement( 1, 3 ), 9 ); + EXPECT_EQ( m.getElement( 1, 4 ), 10 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 11 ); + EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 2 ), 13 ); + EXPECT_EQ( m.getElement( 2, 3 ), 14 ); + EXPECT_EQ( m.getElement( 2, 4 ), 15 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 16 ); + EXPECT_EQ( m.getElement( 3, 1 ), 17 ); + EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 3 ), 19 ); + EXPECT_EQ( m.getElement( 3, 4 ), 20 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 21 ); + EXPECT_EQ( m.getElement( 4, 1 ), 22 ); + EXPECT_EQ( m.getElement( 4, 2 ), 23 ); + EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 4 ), 25 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 26 ); + EXPECT_EQ( m.getElement( 5, 1 ), 27 ); + EXPECT_EQ( m.getElement( 5, 2 ), 28 ); + EXPECT_EQ( m.getElement( 5, 3 ), 29 ); + EXPECT_EQ( m.getElement( 5, 4 ), 30 ); + + // Add new elements to the old elements with a multiplying factor applied to the old elements. +/* + * The following setup results in the following 6x5 dense matrix: + * + * / 3 6 9 12 15 \ + * | 18 21 24 27 30 | + * | 33 36 39 42 45 | + * | 48 51 54 57 60 | + * | 63 66 69 72 75 | + * \ 78 81 84 87 90 / + */ + RealType newValue = 1; + RealType multiplicator = 2; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.addElement( i, j, newValue++, multiplicator ); + + EXPECT_EQ( m.getElement( 0, 0 ), 3 ); + EXPECT_EQ( m.getElement( 0, 1 ), 6 ); + EXPECT_EQ( m.getElement( 0, 2 ), 9 ); + EXPECT_EQ( m.getElement( 0, 3 ), 12 ); + EXPECT_EQ( m.getElement( 0, 4 ), 15 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 18 ); + EXPECT_EQ( m.getElement( 1, 1 ), 21 ); + EXPECT_EQ( m.getElement( 1, 2 ), 24 ); + EXPECT_EQ( m.getElement( 1, 3 ), 27 ); + EXPECT_EQ( m.getElement( 1, 4 ), 30 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 33 ); + EXPECT_EQ( m.getElement( 2, 1 ), 36 ); + EXPECT_EQ( m.getElement( 2, 2 ), 39 ); + EXPECT_EQ( m.getElement( 2, 3 ), 42 ); + EXPECT_EQ( m.getElement( 2, 4 ), 45 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 48 ); + EXPECT_EQ( m.getElement( 3, 1 ), 51 ); + EXPECT_EQ( m.getElement( 3, 2 ), 54 ); + EXPECT_EQ( m.getElement( 3, 3 ), 57 ); + EXPECT_EQ( m.getElement( 3, 4 ), 60 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 63 ); + EXPECT_EQ( m.getElement( 4, 1 ), 66 ); + EXPECT_EQ( m.getElement( 4, 2 ), 69 ); + EXPECT_EQ( m.getElement( 4, 3 ), 72 ); + EXPECT_EQ( m.getElement( 4, 4 ), 75 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 78 ); + EXPECT_EQ( m.getElement( 5, 1 ), 81 ); + EXPECT_EQ( m.getElement( 5, 2 ), 84 ); + EXPECT_EQ( m.getElement( 5, 3 ), 87 ); + EXPECT_EQ( m.getElement( 5, 4 ), 90 ); +} + +template< typename Matrix > +void test_SetRow() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + /* + * Sets up the following 3x7 dense matrix: + * + * / 1 2 3 4 5 6 7 \ + * | 8 9 10 11 12 13 14 | + * \ 15 16 17 18 19 20 21 / + */ + const IndexType rows = 3; + const IndexType cols = 7; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + auto matrix_view = m.getView(); + auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { + RealType values[ 3 ][ 5 ] { + { 11, 11, 11, 11, 11 }, + { 22, 22, 22, 22, 22 }, + { 33, 33, 33, 33, 33 } }; + IndexType columnIndexes[ 3 ][ 5 ] { + { 0, 1, 2, 3, 4 }, + { 0, 1, 2, 3, 4 }, + { 2, 3, 4, 5, 6 } }; + auto row = matrix_view.getRow( rowIdx ); + for( IndexType i = 0; i < 5; i++ ) + row.setElement( columnIndexes[ rowIdx ][ i ], values[ rowIdx ][ i ] ); + }; + TNL::Algorithms::ParallelFor< DeviceType >::exec( 0, 3, f ); + + EXPECT_EQ( m.getElement( 0, 0 ), 11 ); + EXPECT_EQ( m.getElement( 0, 1 ), 11 ); + EXPECT_EQ( m.getElement( 0, 2 ), 11 ); + EXPECT_EQ( m.getElement( 0, 3 ), 11 ); + EXPECT_EQ( m.getElement( 0, 4 ), 11 ); + EXPECT_EQ( m.getElement( 0, 5 ), 6 ); + EXPECT_EQ( m.getElement( 0, 6 ), 7 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 22 ); + EXPECT_EQ( m.getElement( 1, 1 ), 22 ); + EXPECT_EQ( m.getElement( 1, 2 ), 22 ); + EXPECT_EQ( m.getElement( 1, 3 ), 22 ); + EXPECT_EQ( m.getElement( 1, 4 ), 22 ); + EXPECT_EQ( m.getElement( 1, 5 ), 13 ); + EXPECT_EQ( m.getElement( 1, 6 ), 14 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 15 ); + EXPECT_EQ( m.getElement( 2, 1 ), 16 ); + EXPECT_EQ( m.getElement( 2, 2 ), 33 ); + EXPECT_EQ( m.getElement( 2, 3 ), 33 ); + EXPECT_EQ( m.getElement( 2, 4 ), 33 ); + EXPECT_EQ( m.getElement( 2, 5 ), 33 ); + EXPECT_EQ( m.getElement( 2, 6 ), 33 ); +} + +template< typename Matrix > +void test_AddRow() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + /* + * Sets up the following 6x5 dense matrix: + * + * / 1 2 3 4 5 \ + * | 6 7 8 9 10 | + * | 11 12 13 14 15 | + * | 16 17 18 19 20 | + * | 21 22 23 24 25 | + * \ 26 27 28 29 30 / + */ + + const IndexType rows = 6; + const IndexType cols = 5; + + Matrix m( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + // Check the added elements + EXPECT_EQ( m.getElement( 0, 0 ), 1 ); + EXPECT_EQ( m.getElement( 0, 1 ), 2 ); + EXPECT_EQ( m.getElement( 0, 2 ), 3 ); + EXPECT_EQ( m.getElement( 0, 3 ), 4 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 1 ), 7 ); + EXPECT_EQ( m.getElement( 1, 2 ), 8 ); + EXPECT_EQ( m.getElement( 1, 3 ), 9 ); + EXPECT_EQ( m.getElement( 1, 4 ), 10 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 11 ); + EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 2 ), 13 ); + EXPECT_EQ( m.getElement( 2, 3 ), 14 ); + EXPECT_EQ( m.getElement( 2, 4 ), 15 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 16 ); + EXPECT_EQ( m.getElement( 3, 1 ), 17 ); + EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 3 ), 19 ); + EXPECT_EQ( m.getElement( 3, 4 ), 20 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 21 ); + EXPECT_EQ( m.getElement( 4, 1 ), 22 ); + EXPECT_EQ( m.getElement( 4, 2 ), 23 ); + EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 4 ), 25 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 26 ); + EXPECT_EQ( m.getElement( 5, 1 ), 27 ); + EXPECT_EQ( m.getElement( 5, 2 ), 28 ); + EXPECT_EQ( m.getElement( 5, 3 ), 29 ); + EXPECT_EQ( m.getElement( 5, 4 ), 30 ); + + // Add new elements to the old elements with a multiplying factor applied to the old elements. + /* + * The following setup results in the following 6x5 sparse matrix: + * + * / 3 6 9 12 15 \ + * | 18 21 24 27 30 | + * | 33 36 39 42 45 | + * | 48 51 54 57 60 | + * | 63 66 69 72 75 | + * \ 78 81 84 87 90 / + */ + + auto matrix_view = m.getView(); + auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { + RealType values[ 6 ][ 5 ] { + { 11, 11, 11, 11, 0 }, + { 22, 22, 22, 22, 0 }, + { 33, 33, 33, 33, 0 }, + { 44, 44, 44, 44, 0 }, + { 55, 55, 55, 55, 0 }, + { 66, 66, 66, 66, 0 } }; + auto row = matrix_view.getRow( rowIdx ); + for( IndexType i = 0; i < 5; i++ ) + { + RealType& val = row.getValue( i ); + val = rowIdx * val + values[ rowIdx ][ i ]; + } + }; + TNL::Algorithms::ParallelFor< DeviceType >::exec( 0, 6, f ); + + + EXPECT_EQ( m.getElement( 0, 0 ), 11 ); + EXPECT_EQ( m.getElement( 0, 1 ), 11 ); + EXPECT_EQ( m.getElement( 0, 2 ), 11 ); + EXPECT_EQ( m.getElement( 0, 3 ), 11 ); + EXPECT_EQ( m.getElement( 0, 4 ), 0 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 28 ); + EXPECT_EQ( m.getElement( 1, 1 ), 29 ); + EXPECT_EQ( m.getElement( 1, 2 ), 30 ); + EXPECT_EQ( m.getElement( 1, 3 ), 31 ); + EXPECT_EQ( m.getElement( 1, 4 ), 10 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 55 ); + EXPECT_EQ( m.getElement( 2, 1 ), 57 ); + EXPECT_EQ( m.getElement( 2, 2 ), 59 ); + EXPECT_EQ( m.getElement( 2, 3 ), 61 ); + EXPECT_EQ( m.getElement( 2, 4 ), 30 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 92 ); + EXPECT_EQ( m.getElement( 3, 1 ), 95 ); + EXPECT_EQ( m.getElement( 3, 2 ), 98 ); + EXPECT_EQ( m.getElement( 3, 3 ), 101 ); + EXPECT_EQ( m.getElement( 3, 4 ), 60 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 139 ); + EXPECT_EQ( m.getElement( 4, 1 ), 143 ); + EXPECT_EQ( m.getElement( 4, 2 ), 147 ); + EXPECT_EQ( m.getElement( 4, 3 ), 151 ); + EXPECT_EQ( m.getElement( 4, 4 ), 100 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 196 ); + EXPECT_EQ( m.getElement( 5, 1 ), 201 ); + EXPECT_EQ( m.getElement( 5, 2 ), 206 ); + EXPECT_EQ( m.getElement( 5, 3 ), 211 ); + EXPECT_EQ( m.getElement( 5, 4 ), 150 ); +} + +template< typename Matrix > +void test_VectorProduct() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 5x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + const IndexType rows = 5; + const IndexType cols = 4; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++) + m.setElement( i, j, value++ ); + + using VectorType = TNL::Containers::Vector< RealType, DeviceType, IndexType >; + + VectorType inVector; + inVector.setSize( 4 ); + for( IndexType i = 0; i < inVector.getSize(); i++ ) + inVector.setElement( i, 2 ); + + VectorType outVector; + outVector.setSize( 5 ); + for( IndexType j = 0; j < outVector.getSize(); j++ ) + outVector.setElement( j, 0 ); + + + m.vectorProduct( inVector, outVector); + + EXPECT_EQ( outVector.getElement( 0 ), 20 ); + EXPECT_EQ( outVector.getElement( 1 ), 52 ); + EXPECT_EQ( outVector.getElement( 2 ), 84 ); + EXPECT_EQ( outVector.getElement( 3 ), 116 ); + EXPECT_EQ( outVector.getElement( 4 ), 148 ); +} + +template< typename Matrix > +void test_AddMatrix() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 5x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + const IndexType rows = 5; + const IndexType cols = 4; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++) + m.setElement( i, j, value++ ); + +/* + * Sets up the following 5x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + + Matrix m2; + m2.reset(); + m2.setDimensions( rows, cols ); + + RealType newValue = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++) + m2.setElement( i, j, newValue++ ); + + /* + * Sets up the following 5x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + + Matrix mResult; + mResult.reset(); + mResult.setDimensions( rows, cols ); + + mResult = m; + + RealType matrixMultiplicator = 2; + RealType thisMatrixMultiplicator = 1; + + mResult.addMatrix( m2, matrixMultiplicator, thisMatrixMultiplicator ); + + EXPECT_EQ( mResult.getElement( 0, 0 ), matrixMultiplicator * m2.getElement( 0, 0 ) + thisMatrixMultiplicator * m.getElement( 0, 0 ) ); + EXPECT_EQ( mResult.getElement( 0, 1 ), matrixMultiplicator * m2.getElement( 0, 1 ) + thisMatrixMultiplicator * m.getElement( 0, 1 ) ); + EXPECT_EQ( mResult.getElement( 0, 2 ), matrixMultiplicator * m2.getElement( 0, 2 ) + thisMatrixMultiplicator * m.getElement( 0, 2 ) ); + EXPECT_EQ( mResult.getElement( 0, 3 ), matrixMultiplicator * m2.getElement( 0, 3 ) + thisMatrixMultiplicator * m.getElement( 0, 3 ) ); + + EXPECT_EQ( mResult.getElement( 1, 0 ), matrixMultiplicator * m2.getElement( 1, 0 ) + thisMatrixMultiplicator * m.getElement( 1, 0 ) ); + EXPECT_EQ( mResult.getElement( 1, 1 ), matrixMultiplicator * m2.getElement( 1, 1 ) + thisMatrixMultiplicator * m.getElement( 1, 1 ) ); + EXPECT_EQ( mResult.getElement( 1, 2 ), matrixMultiplicator * m2.getElement( 1, 2 ) + thisMatrixMultiplicator * m.getElement( 1, 2 ) ); + EXPECT_EQ( mResult.getElement( 1, 3 ), matrixMultiplicator * m2.getElement( 1, 3 ) + thisMatrixMultiplicator * m.getElement( 1, 3 ) ); + + EXPECT_EQ( mResult.getElement( 2, 0 ), matrixMultiplicator * m2.getElement( 2, 0 ) + thisMatrixMultiplicator * m.getElement( 2, 0 ) ); + EXPECT_EQ( mResult.getElement( 2, 1 ), matrixMultiplicator * m2.getElement( 2, 1 ) + thisMatrixMultiplicator * m.getElement( 2, 1 ) ); + EXPECT_EQ( mResult.getElement( 2, 2 ), matrixMultiplicator * m2.getElement( 2, 2 ) + thisMatrixMultiplicator * m.getElement( 2, 2 ) ); + EXPECT_EQ( mResult.getElement( 2, 3 ), matrixMultiplicator * m2.getElement( 2, 3 ) + thisMatrixMultiplicator * m.getElement( 2, 3 ) ); + + EXPECT_EQ( mResult.getElement( 3, 0 ), matrixMultiplicator * m2.getElement( 3, 0 ) + thisMatrixMultiplicator * m.getElement( 3, 0 ) ); + EXPECT_EQ( mResult.getElement( 3, 1 ), matrixMultiplicator * m2.getElement( 3, 1 ) + thisMatrixMultiplicator * m.getElement( 3, 1 ) ); + EXPECT_EQ( mResult.getElement( 3, 2 ), matrixMultiplicator * m2.getElement( 3, 2 ) + thisMatrixMultiplicator * m.getElement( 3, 2 ) ); + EXPECT_EQ( mResult.getElement( 3, 3 ), matrixMultiplicator * m2.getElement( 3, 3 ) + thisMatrixMultiplicator * m.getElement( 3, 3 ) ); + + EXPECT_EQ( mResult.getElement( 4, 0 ), matrixMultiplicator * m2.getElement( 4, 0 ) + thisMatrixMultiplicator * m.getElement( 4, 0 ) ); + EXPECT_EQ( mResult.getElement( 4, 1 ), matrixMultiplicator * m2.getElement( 4, 1 ) + thisMatrixMultiplicator * m.getElement( 4, 1 ) ); + EXPECT_EQ( mResult.getElement( 4, 2 ), matrixMultiplicator * m2.getElement( 4, 2 ) + thisMatrixMultiplicator * m.getElement( 4, 2 ) ); + EXPECT_EQ( mResult.getElement( 4, 3 ), matrixMultiplicator * m2.getElement( 4, 3 ) + thisMatrixMultiplicator * m.getElement( 4, 3 ) ); + + EXPECT_EQ( mResult.getElement( 0, 0 ), 3 ); + EXPECT_EQ( mResult.getElement( 0, 1 ), 6 ); + EXPECT_EQ( mResult.getElement( 0, 2 ), 9 ); + EXPECT_EQ( mResult.getElement( 0, 3 ), 12 ); + + EXPECT_EQ( mResult.getElement( 1, 0 ), 15 ); + EXPECT_EQ( mResult.getElement( 1, 1 ), 18 ); + EXPECT_EQ( mResult.getElement( 1, 2 ), 21 ); + EXPECT_EQ( mResult.getElement( 1, 3 ), 24 ); + + EXPECT_EQ( mResult.getElement( 2, 0 ), 27 ); + EXPECT_EQ( mResult.getElement( 2, 1 ), 30 ); + EXPECT_EQ( mResult.getElement( 2, 2 ), 33 ); + EXPECT_EQ( mResult.getElement( 2, 3 ), 36 ); + + EXPECT_EQ( mResult.getElement( 3, 0 ), 39 ); + EXPECT_EQ( mResult.getElement( 3, 1 ), 42 ); + EXPECT_EQ( mResult.getElement( 3, 2 ), 45 ); + EXPECT_EQ( mResult.getElement( 3, 3 ), 48 ); + + EXPECT_EQ( mResult.getElement( 4, 0 ), 51 ); + EXPECT_EQ( mResult.getElement( 4, 1 ), 54 ); + EXPECT_EQ( mResult.getElement( 4, 2 ), 57 ); + EXPECT_EQ( mResult.getElement( 4, 3 ), 60 ); +} + +template< typename Matrix > +void test_GetMatrixProduct() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 5x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + const IndexType leftRows = 5; + const IndexType leftCols = 4; + + Matrix leftMatrix; + leftMatrix.reset(); + leftMatrix.setDimensions( leftRows, leftCols ); + + RealType value = 1; + for( IndexType i = 0; i < leftRows; i++ ) + for( IndexType j = 0; j < leftCols; j++) + leftMatrix.setElement( i, j, value++ ); + +/* + * Sets up the following 4x5 dense matrix: + * + * / 1 2 3 4 5 \ + * | 6 7 8 9 10 | + * | 11 12 13 14 15 | + * \ 16 17 18 19 20 / + */ + const IndexType rightRows = 4; + const IndexType rightCols = 5; + + Matrix rightMatrix; + rightMatrix.reset(); + rightMatrix.setDimensions( rightRows, rightCols ); + + RealType newValue = 1; + for( IndexType i = 0; i < rightRows; i++ ) + for( IndexType j = 0; j < rightCols; j++) + rightMatrix.setElement( i, j, newValue++ ); + +/* + * Sets up the following 5x5 resulting dense matrix: + * + * / 0 0 0 0 \ + * | 0 0 0 0 | + * | 0 0 0 0 | + * | 0 0 0 0 | + * \ 0 0 0 0 / + */ + + Matrix mResult; + mResult.reset(); + mResult.setDimensions( leftRows, rightCols ); + mResult.setValue( 0 ); + + RealType leftMatrixMultiplicator = 1; + RealType rightMatrixMultiplicator = 2; +/* + * / 1 2 3 4 \ / 220 240 260 280 300 \ + * | 5 6 7 8 | / 1 2 3 4 5 \ | 492 544 596 648 700 | + * 1 * | 9 10 11 12 | * 2 * | 6 7 8 9 10 | = | 764 848 932 1016 1100 | + * | 13 14 15 16 | | 11 12 13 14 15 | | 1036 1152 1268 1384 1500 | + * \ 17 18 19 20 / \ 16 17 18 19 20 / \ 1308 1456 1604 1752 1900 / + */ + + mResult.getMatrixProduct( leftMatrix, rightMatrix, leftMatrixMultiplicator, rightMatrixMultiplicator ); + + EXPECT_EQ( mResult.getElement( 0, 0 ), 220 ); + EXPECT_EQ( mResult.getElement( 0, 1 ), 240 ); + EXPECT_EQ( mResult.getElement( 0, 2 ), 260 ); + EXPECT_EQ( mResult.getElement( 0, 3 ), 280 ); + EXPECT_EQ( mResult.getElement( 0, 4 ), 300 ); + + EXPECT_EQ( mResult.getElement( 1, 0 ), 492 ); + EXPECT_EQ( mResult.getElement( 1, 1 ), 544 ); + EXPECT_EQ( mResult.getElement( 1, 2 ), 596 ); + EXPECT_EQ( mResult.getElement( 1, 3 ), 648 ); + EXPECT_EQ( mResult.getElement( 1, 4 ), 700 ); + + EXPECT_EQ( mResult.getElement( 2, 0 ), 764 ); + EXPECT_EQ( mResult.getElement( 2, 1 ), 848 ); + EXPECT_EQ( mResult.getElement( 2, 2 ), 932 ); + EXPECT_EQ( mResult.getElement( 2, 3 ), 1016 ); + EXPECT_EQ( mResult.getElement( 2, 4 ), 1100 ); + + EXPECT_EQ( mResult.getElement( 3, 0 ), 1036 ); + EXPECT_EQ( mResult.getElement( 3, 1 ), 1152 ); + EXPECT_EQ( mResult.getElement( 3, 2 ), 1268 ); + EXPECT_EQ( mResult.getElement( 3, 3 ), 1384 ); + EXPECT_EQ( mResult.getElement( 3, 4 ), 1500 ); + + EXPECT_EQ( mResult.getElement( 4, 0 ), 1308 ); + EXPECT_EQ( mResult.getElement( 4, 1 ), 1456 ); + EXPECT_EQ( mResult.getElement( 4, 2 ), 1604 ); + EXPECT_EQ( mResult.getElement( 4, 3 ), 1752 ); + EXPECT_EQ( mResult.getElement( 4, 4 ), 1900 ); +} + +template< typename Matrix > +void test_GetTransposition() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 3x2 dense matrix: + * + * / 1 2 \ + * | 3 4 | + * \ 5 6 / + */ + const IndexType rows = 3; + const IndexType cols = 2; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + m.setElement( i, j, value++ ); + + m.print( std::cout ); + +/* + * Sets up the following 2x3 dense matrix: + * + * / 0 0 0 \ + * \ 0 0 0 / + */ + Matrix mTransposed; + mTransposed.reset(); + mTransposed.setDimensions( cols, rows ); + + mTransposed.print( std::cout ); + + RealType matrixMultiplicator = 1; + + mTransposed.getTransposition( m, matrixMultiplicator ); + + mTransposed.print( std::cout ); + +/* + * Should result in the following 2x3 dense matrix: + * + * / 1 3 5 \ + * \ 2 4 6 / + */ + + EXPECT_EQ( mTransposed.getElement( 0, 0 ), 1 ); + EXPECT_EQ( mTransposed.getElement( 0, 1 ), 3 ); + EXPECT_EQ( mTransposed.getElement( 0, 2 ), 5 ); + + EXPECT_EQ( mTransposed.getElement( 1, 0 ), 2 ); + EXPECT_EQ( mTransposed.getElement( 1, 1 ), 4 ); + EXPECT_EQ( mTransposed.getElement( 1, 2 ), 6 ); +} + + +template< typename Matrix > +void test_PerformSORIteration() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 4x4 dense matrix: + * + * / 4 1 1 1 \ + * | 1 4 1 1 | + * | 1 1 4 1 | + * \ 1 1 1 4 / + */ + const IndexType rows = 4; + const IndexType cols = 4; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + m.setElement( 0, 0, 4.0 ); // 0th row + m.setElement( 0, 1, 1.0 ); + m.setElement( 0, 2, 1.0 ); + m.setElement( 0, 3, 1.0 ); + + m.setElement( 1, 0, 1.0 ); // 1st row + m.setElement( 1, 1, 4.0 ); + m.setElement( 1, 2, 1.0 ); + m.setElement( 1, 3, 1.0 ); + + m.setElement( 2, 0, 1.0 ); + m.setElement( 2, 1, 1.0 ); // 2nd row + m.setElement( 2, 2, 4.0 ); + m.setElement( 2, 3, 1.0 ); + + m.setElement( 3, 0, 1.0 ); // 3rd row + m.setElement( 3, 1, 1.0 ); + m.setElement( 3, 2, 1.0 ); + m.setElement( 3, 3, 4.0 ); + + RealType bVector [ 4 ] = { 1.0, 1.0, 1.0, 1.0 }; + RealType xVector [ 4 ] = { 1.0, 1.0, 1.0, 1.0 }; + + IndexType row = 0; + RealType omega = 1; + + m.performSORIteration( bVector, row++, xVector, omega); + + EXPECT_EQ( xVector[ 0 ], -0.5 ); + EXPECT_EQ( xVector[ 1 ], 1.0 ); + EXPECT_EQ( xVector[ 2 ], 1.0 ); + EXPECT_EQ( xVector[ 3 ], 1.0 ); + + m.performSORIteration( bVector, row++, xVector, omega); + + EXPECT_EQ( xVector[ 0 ], -0.5 ); + EXPECT_EQ( xVector[ 1 ], -0.125 ); + EXPECT_EQ( xVector[ 2 ], 1.0 ); + EXPECT_EQ( xVector[ 3 ], 1.0 ); + + m.performSORIteration( bVector, row++, xVector, omega); + + EXPECT_EQ( xVector[ 0 ], -0.5 ); + EXPECT_EQ( xVector[ 1 ], -0.125 ); + EXPECT_EQ( xVector[ 2 ], 0.15625 ); + EXPECT_EQ( xVector[ 3 ], 1.0 ); + + m.performSORIteration( bVector, row++, xVector, omega); + + EXPECT_EQ( xVector[ 0 ], -0.5 ); + EXPECT_EQ( xVector[ 1 ], -0.125 ); + EXPECT_EQ( xVector[ 2 ], 0.15625 ); + EXPECT_EQ( xVector[ 3 ], 0.3671875 ); +} + +template< typename Matrix > +void test_AssignmentOperator() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + using DenseHost = TNL::Matrices::Dense< RealType, TNL::Devices::Host, IndexType >; + using DenseCuda = TNL::Matrices::Dense< RealType, TNL::Devices::Cuda, IndexType >; + + const IndexType rows( 10 ), columns( 10 ); + DenseHost hostMatrix( rows, columns ); + for( IndexType i = 0; i < columns; i++ ) + for( IndexType j = 0; j <= i; j++ ) + hostMatrix( i, j ) = i + j; + + Matrix matrix( rows, columns ); + matrix.getValues() = 0.0; + matrix = hostMatrix; + for( IndexType i = 0; i < columns; i++ ) + for( IndexType j = 0; j < rows; j++ ) + { + if( j > i ) + EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); + else + EXPECT_EQ( matrix.getElement( i, j ), i + j ); + } + +#ifdef HAVE_CUDA + DenseCuda cudaMatrix( rows, columns ); + for( IndexType i = 0; i < columns; i++ ) + for( IndexType j = 0; j <= i; j++ ) + cudaMatrix.setElement( i, j, i + j ); + + matrix.getValues() = 0.0; + matrix = cudaMatrix; + for( IndexType i = 0; i < columns; i++ ) + for( IndexType j = 0; j < rows; j++ ) + { + if( j > i ) + EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); + else + EXPECT_EQ( matrix.getElement( i, j ), i + j ); + } +#endif +} + + +template< typename Matrix > +void test_SaveAndLoad() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 4x4 dense matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * \ 13 14 15 16 / + */ + const IndexType rows = 4; + const IndexType cols = 4; + + Matrix savedMatrix; + savedMatrix.reset(); + savedMatrix.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + savedMatrix.setElement( i, j, value++ ); + + ASSERT_NO_THROW( savedMatrix.save( TEST_FILE_NAME ) ); + + Matrix loadedMatrix; + loadedMatrix.reset(); + loadedMatrix.setDimensions( rows, cols ); + + ASSERT_NO_THROW( loadedMatrix.load( TEST_FILE_NAME ) ); + + EXPECT_EQ( savedMatrix.getElement( 0, 0 ), loadedMatrix.getElement( 0, 0 ) ); + EXPECT_EQ( savedMatrix.getElement( 0, 1 ), loadedMatrix.getElement( 0, 1 ) ); + EXPECT_EQ( savedMatrix.getElement( 0, 2 ), loadedMatrix.getElement( 0, 2 ) ); + EXPECT_EQ( savedMatrix.getElement( 0, 3 ), loadedMatrix.getElement( 0, 3 ) ); + + EXPECT_EQ( savedMatrix.getElement( 1, 0 ), loadedMatrix.getElement( 1, 0 ) ); + EXPECT_EQ( savedMatrix.getElement( 1, 1 ), loadedMatrix.getElement( 1, 1 ) ); + EXPECT_EQ( savedMatrix.getElement( 1, 2 ), loadedMatrix.getElement( 1, 2 ) ); + EXPECT_EQ( savedMatrix.getElement( 1, 3 ), loadedMatrix.getElement( 1, 3 ) ); + + EXPECT_EQ( savedMatrix.getElement( 2, 0 ), loadedMatrix.getElement( 2, 0 ) ); + EXPECT_EQ( savedMatrix.getElement( 2, 1 ), loadedMatrix.getElement( 2, 1 ) ); + EXPECT_EQ( savedMatrix.getElement( 2, 2 ), loadedMatrix.getElement( 2, 2 ) ); + EXPECT_EQ( savedMatrix.getElement( 2, 3 ), loadedMatrix.getElement( 2, 3 ) ); + + EXPECT_EQ( savedMatrix.getElement( 3, 0 ), loadedMatrix.getElement( 3, 0 ) ); + EXPECT_EQ( savedMatrix.getElement( 3, 1 ), loadedMatrix.getElement( 3, 1 ) ); + EXPECT_EQ( savedMatrix.getElement( 3, 2 ), loadedMatrix.getElement( 3, 2 ) ); + EXPECT_EQ( savedMatrix.getElement( 3, 3 ), loadedMatrix.getElement( 3, 3 ) ); + + EXPECT_EQ( savedMatrix.getElement( 0, 0 ), 1 ); + EXPECT_EQ( savedMatrix.getElement( 0, 1 ), 2 ); + EXPECT_EQ( savedMatrix.getElement( 0, 2 ), 3 ); + EXPECT_EQ( savedMatrix.getElement( 0, 3 ), 4 ); + + EXPECT_EQ( savedMatrix.getElement( 1, 0 ), 5 ); + EXPECT_EQ( savedMatrix.getElement( 1, 1 ), 6 ); + EXPECT_EQ( savedMatrix.getElement( 1, 2 ), 7 ); + EXPECT_EQ( savedMatrix.getElement( 1, 3 ), 8 ); + + EXPECT_EQ( savedMatrix.getElement( 2, 0 ), 9 ); + EXPECT_EQ( savedMatrix.getElement( 2, 1 ), 10 ); + EXPECT_EQ( savedMatrix.getElement( 2, 2 ), 11 ); + EXPECT_EQ( savedMatrix.getElement( 2, 3 ), 12 ); + + EXPECT_EQ( savedMatrix.getElement( 3, 0 ), 13 ); + EXPECT_EQ( savedMatrix.getElement( 3, 1 ), 14 ); + EXPECT_EQ( savedMatrix.getElement( 3, 2 ), 15 ); + EXPECT_EQ( savedMatrix.getElement( 3, 3 ), 16 ); +} + +template< typename Matrix > +void test_Print() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; +/* + * Sets up the following 5x4 sparse matrix: + * + * / 1 2 3 4 \ + * | 5 6 7 8 | + * | 9 10 11 12 | + * | 13 14 15 16 | + * \ 17 18 19 20 / + */ + const IndexType rows = 5; + const IndexType cols = 4; + + Matrix m; + m.reset(); + m.setDimensions( rows, cols ); + + RealType value = 1; + for( IndexType i = 0; i < rows; i++) + for( IndexType j = 0; j < cols; j++) + m.setElement( i, j, value++ ); + + #include <sstream> + std::stringstream printed; + std::stringstream couted; + + //change the underlying buffer and save the old buffer + auto old_buf = std::cout.rdbuf(printed.rdbuf()); + + m.print( std::cout ); //all the std::cout goes to ss + + std::cout.rdbuf(old_buf); //reset + + couted << "Row: 0 -> Col:0->1 Col:1->2 Col:2->3 Col:3->4\t\n" + "Row: 1 -> Col:0->5 Col:1->6 Col:2->7 Col:3->8\t\n" + "Row: 2 -> Col:0->9 Col:1->10 Col:2->11 Col:3->12\t\n" + "Row: 3 -> Col:0->13 Col:1->14 Col:2->15 Col:3->16\t\n" + "Row: 4 -> Col:0->17 Col:1->18 Col:2->19 Col:3->20\t\n"; + + EXPECT_EQ( printed.str(), couted.str() ); +} + +// test fixture for typed tests +template< typename Matrix > +class MatrixTest : public ::testing::Test +{ +protected: + using MatrixType = Matrix; +}; + +// types for which MatrixTest is instantiated +using MatrixTypes = ::testing::Types +< + TNL::Matrices::Dense< int, TNL::Devices::Host, short >, + TNL::Matrices::Dense< long, TNL::Devices::Host, short >, + TNL::Matrices::Dense< float, TNL::Devices::Host, short >, + TNL::Matrices::Dense< double, TNL::Devices::Host, short >, + TNL::Matrices::Dense< int, TNL::Devices::Host, int >, + TNL::Matrices::Dense< long, TNL::Devices::Host, int >, + TNL::Matrices::Dense< float, TNL::Devices::Host, int >, + TNL::Matrices::Dense< double, TNL::Devices::Host, int >, + TNL::Matrices::Dense< int, TNL::Devices::Host, long >, + TNL::Matrices::Dense< long, TNL::Devices::Host, long >, + TNL::Matrices::Dense< float, TNL::Devices::Host, long >, + TNL::Matrices::Dense< double, TNL::Devices::Host, long > +#ifdef HAVE_CUDA + ,TNL::Matrices::Dense< int, TNL::Devices::Cuda, short >, + TNL::Matrices::Dense< long, TNL::Devices::Cuda, short >, + TNL::Matrices::Dense< float, TNL::Devices::Cuda, short >, + TNL::Matrices::Dense< double, TNL::Devices::Cuda, short >, + TNL::Matrices::Dense< int, TNL::Devices::Cuda, int >, + TNL::Matrices::Dense< long, TNL::Devices::Cuda, int >, + TNL::Matrices::Dense< float, TNL::Devices::Cuda, int >, + TNL::Matrices::Dense< double, TNL::Devices::Cuda, int >, + TNL::Matrices::Dense< int, TNL::Devices::Cuda, long >, + TNL::Matrices::Dense< long, TNL::Devices::Cuda, long >, + TNL::Matrices::Dense< float, TNL::Devices::Cuda, long >, + TNL::Matrices::Dense< double, TNL::Devices::Cuda, long > +#endif +>; + +TYPED_TEST_SUITE( MatrixTest, MatrixTypes ); + +TYPED_TEST( MatrixTest, setDimensionsTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SetDimensions< MatrixType >(); +} + +TYPED_TEST( MatrixTest, setLikeTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SetLike< MatrixType, MatrixType >(); +} + +TYPED_TEST( MatrixTest, getRowLengthTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_GetRowLength< MatrixType >(); +} + +TYPED_TEST( MatrixTest, getNumberOfMatrixElementsTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_GetNumberOfMatrixElements< MatrixType >(); +} + +TYPED_TEST( MatrixTest, getNumberOfNonzeroMatrixElementsTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_GetNumberOfNonzeroMatrixElements< MatrixType >(); +} + +TYPED_TEST( MatrixTest, resetTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_Reset< MatrixType >(); +} + +TYPED_TEST( MatrixTest, setValueTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SetValue< MatrixType >(); +} + +TYPED_TEST( MatrixTest, setElementTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SetElement< MatrixType >(); +} + +TYPED_TEST( MatrixTest, addElementTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_AddElement< MatrixType >(); +} + +TYPED_TEST( MatrixTest, setRowTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SetRow< MatrixType >(); +} + +TYPED_TEST( MatrixTest, addRowTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_AddRow< MatrixType >(); +} + +TYPED_TEST( MatrixTest, vectorProductTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_VectorProduct< MatrixType >(); +} + +TYPED_TEST( MatrixTest, addMatrixTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_AddMatrix< MatrixType >(); +} + +TYPED_TEST( MatrixTest, assignmentOperatorTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_AssignmentOperator< MatrixType >(); +} + +TYPED_TEST( MatrixTest, saveAndLoadTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_SaveAndLoad< MatrixType >(); +} + +TYPED_TEST( MatrixTest, printTest ) +{ + using MatrixType = typename TestFixture::MatrixType; + + test_Print< MatrixType >(); +} + +//// test_getType is not general enough yet. DO NOT TEST IT YET. + +//TEST( DenseMatrixTest, Dense_GetTypeTest_Host ) +//{ +// host_test_GetType< Dense_host_float, Dense_host_int >(); +//} +// +//#ifdef HAVE_CUDA +//TEST( DenseMatrixTest, Dense_GetTypeTest_Cuda ) +//{ +// cuda_test_GetType< Dense_cuda_float, Dense_cuda_int >(); +//} +//#endif + +/*TEST( DenseMatrixTest, Dense_getMatrixProductTest_Host ) +{ + bool testRan = false; + EXPECT_TRUE( testRan ); + std::cout << "\nTEST DID NOT RUN. NOT WORKING.\n\n"; + std::cout << "If launched on CPU, this test will not build, but will print the following message: \n"; + std::cout << " /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h(609): error: no instance of function template \"TNL::Matrices::DenseMatrixProductKernel\" matches the argument list\n"; + std::cout << " argument types are: (TNL::Matrices::Dense<int, TNL::Devices::Host, int> *, Dense_host_int *, Dense_host_int *, const int, const int, int, int)\n"; + std::cout << " detected during:\n"; + std::cout << " instantiation of \"void TNL::Matrices::Dense<Real, Device, Index>::getMatrixProduct(const Matrix1 &, const Matrix2 &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &) [with Real=int, Device=TNL::Devices::Host, Index=int, Matrix1=Dense_host_int, Matrix2=Dense_host_int, tileDim=32]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(901): here\n"; + std::cout << " instantiation of \"void test_GetMatrixProduct<Matrix>() [with Matrix=Dense_host_int]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(1315): here\n\n"; +} + +#ifdef HAVE_CUDA +TEST( DenseMatrixTest, Dense_getMatrixProductTest_Cuda ) +{ + bool testRan = false; + EXPECT_TRUE( testRan ); + std::cout << "\nTEST DID NOT RUN. NOT WORKING.\n\n"; + std::cout << "If launched on GPU, this test will not build, but will print the following message: \n"; + std::cout << " /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h(510): error: identifier \"tnlCudaMin\" is undefined\n"; + std::cout << " detected during:\n"; + std::cout << " instantiation of \"void TNL::Matrices::DenseMatrixProductKernel<Real,Index,Matrix1,Matrix2,tileDim,tileRowBlockSize>(TNL::Matrices::Dense<Real, TNL::Devices::Cuda, Index> *, const Matrix1 *, const Matrix2 *, Real, Real, Index, Index) [with Real=int, Index=int, Matrix1=Dense_cuda_int, Matrix2=Dense_cuda_int, tileDim=32, tileRowBlockSize=8]\"\n"; + std::cout << " instantiation of \"void TNL::Matrices::Dense<Real, Device, Index>::getMatrixProduct(const Matrix1 &, const Matrix2 &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &) [with Real=int, Device=TNL::Devices::Cuda, Index=int, Matrix1=Dense_cuda_int, Matrix2=Dense_cuda_int, tileDim=32]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(901): here\n"; + std::cout << " instantiation of \"void test_GetMatrixProduct<Matrix>() [with Matrix=Dense_cuda_int]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(1332): here\n\n"; +} +#endif + +TEST( DenseMatrixTest, Dense_getTranspositionTest_Host ) +{ +// test_GetTransposition< Dense_host_int >(); + bool testRan = false; + EXPECT_TRUE( testRan ); + std::cout << "\nTEST DID NOT RUN. NOT WORKING.\n\n"; + std::cout << "If launched on CPU, this test will not build, but will print the following message: \n"; + std::cout << " /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h(836): error: no instance of function template \"TNL::Matrices::DenseTranspositionAlignedKernel\" matches the argument list\n"; + std::cout << " argument types are: (TNL::Matrices::Dense<int, TNL::Devices::Host, int> *, Dense_host_int *, const int, int, int)\n"; + std::cout << " detected during:\n"; + std::cout << " instantiation of \"void TNL::Matrices::Dense<Real, Device, Index>::getTransposition(const Matrix &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &) [with Real=int, Device=TNL::Devices::Host, Index=int, Matrix=Dense_host_int, tileDim=32]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(977): here\n"; + std::cout << " instantiation of \"void test_GetTransposition<Matrix>() [with Matrix=Dense_host_int]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(1420): here\n\n"; + std::cout << "AND this message: \n"; + std::cout << " /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h(852): error: no instance of function template \"TNL::Matrices::DenseTranspositionNonAlignedKernel\" matches the argument list\n"; + std::cout << " argument types are: (TNL::Matrices::Dense<int, TNL::Devices::Host, int> *, Dense_host_int *, const int, int, int)\n"; + std::cout << " detected during:\n"; + std::cout << " instantiation of \"void TNL::Matrices::Dense<Real, Device, Index>::getTransposition(const Matrix &, const TNL::Matrices::Dense<Real, Device, Index>::RealType &) [with Real=int, Device=TNL::Devices::Host, Index=int, Matrix=Dense_host_int, tileDim=32]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(977): here\n"; + std::cout << " instantiation of \"void test_GetTransposition<Matrix>() [with Matrix=Dense_host_int]\"\n"; + std::cout << " /home/lukas/tnl-dev/src/UnitTests/Matrices/DenseMatrixTest.h(1420): here\n\n"; +} + +#ifdef HAVE_CUDA +TEST( DenseMatrixTest, Dense_getTranspositionTest_Cuda ) +{ +// test_GetTransposition< Dense_cuda_int >(); + bool testRan = false; + EXPECT_TRUE( testRan ); + std::cout << "\nTEST DID NOT RUN. NOT WORKING.\n\n"; + std::cout << "If launched on GPU, this test throws the following message: \n"; + std::cout << " Assertion 'row >= 0 && row < this->getRows() && column >= 0 && column < this->getColumns()' failed !!!\n"; + std::cout << " File: /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h \n"; + std::cout << " Line: 329 \n"; + std::cout << " Diagnostics: Not supported with CUDA.\n"; + std::cout << " Assertion 'row >= 0 && row < this->getRows() && column >= 0 && column < this->getColumns()' failed !!! \n"; + std::cout << " File: /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h \n"; + std::cout << " Line: 329 \n"; + std::cout << " Diagnostics: Not supported with CUDA.\n"; + std::cout << " Assertion 'row >= 0 && row < this->getRows() && column >= 0 && column < this->getColumns()' failed !!! \n"; + std::cout << " File: /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h \n"; + std::cout << " Line: 329 \n"; + std::cout << " Diagnostics: Not supported with CUDA.\n"; + std::cout << " Assertion 'row >= 0 && row < this->getRows() && column >= 0 && column < this->getColumns()' failed !!! \n"; + std::cout << " File: /home/lukas/tnl-dev/src/TNL/Matrices/Dense_impl.h \n"; + std::cout << " Line: 329 \n"; + std::cout << " Diagnostics: Not supported with CUDA.\n"; + std::cout << " terminate called after throwing an instance of 'TNL::Exceptions::CudaRuntimeError'\n"; + std::cout << " what(): CUDA ERROR 4 (cudaErrorLaunchFailure): unspecified launch failure.\n"; + std::cout << " Source: line 57 in /home/lukas/tnl-dev/src/TNL/Containers/Algorithms/ArrayOperationsCuda_impl.h: unspecified launch failure\n"; + std::cout << " [1] 4003 abort (core dumped) ./DenseMatrixTest-dbg\n"; +} +#endif + +TEST( DenseMatrixTest, Dense_performSORIterationTest_Host ) +{ + test_PerformSORIteration< Dense_host_float >(); +} + +#ifdef HAVE_CUDA +TEST( DenseMatrixTest, Dense_performSORIterationTest_Cuda ) +{ +// test_PerformSORIteration< Dense_cuda_float >(); + bool testRan = false; + EXPECT_TRUE( testRan ); + std::cout << "\nTEST DID NOT RUN. NOT WORKING.\n\n"; + std::cout << "If launched, this test throws the following message: \n"; + std::cout << " [1] 6992 segmentation fault (core dumped) ./SparseMatrixTest-dbg\n\n"; + std::cout << "\n THIS IS NOT IMPLEMENTED FOR CUDA YET!!\n\n"; +} +#endif + * */ + +#endif // HAVE_GTEST + +#include "../main.h" -- GitLab