From 733401dcfd44ac508f43d1f5731bfc795226ddf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com> Date: Fri, 17 Jan 2020 22:51:01 +0100 Subject: [PATCH] Fixed tridiagonal to sparse matrix assignment. Debugging multidiagonal to sparse matrix assignment. --- .../Matrices/MultidiagonalMatrixRowView.hpp | 2 +- src/TNL/Matrices/MultidiagonalMatrixView.hpp | 3 +- src/TNL/Matrices/SparseMatrix.hpp | 3 +- src/UnitTests/Matrices/SparseMatrixCopyTest.h | 117 ++++++++++++++---- 4 files changed, 98 insertions(+), 27 deletions(-) diff --git a/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp b/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp index 88aae3f150..855b8463aa 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp +++ b/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp @@ -30,7 +30,7 @@ auto MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: getSize() const -> IndexType { - return indexer.getRowSize(); + return diagonalsShifts.getSize();//indexer.getRowSize( rowIdx ); } template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > diff --git a/src/TNL/Matrices/MultidiagonalMatrixView.hpp b/src/TNL/Matrices/MultidiagonalMatrixView.hpp index 2839c997aa..96312d03cf 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixView.hpp +++ b/src/TNL/Matrices/MultidiagonalMatrixView.hpp @@ -393,12 +393,13 @@ forRows( IndexType first, IndexType last, Function& function ) const const IndexType diagonalsCount = this->diagonalsShifts.getSize(); const IndexType columns = this->getColumns(); const auto indexer = this->indexer; + bool compute( true ); auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { for( IndexType localIdx = 0; localIdx < diagonalsCount; localIdx++ ) { const IndexType columnIdx = rowIdx + diagonalsShifts_view[ localIdx ]; if( columnIdx >= 0 && columnIdx < columns ) - function( rowIdx, localIdx, columnIdx, values_view[ indexer.getGlobalIndex( rowIdx, localIdx ) ] ); + function( rowIdx, localIdx, columnIdx, values_view[ indexer.getGlobalIndex( rowIdx, localIdx ) ], compute ); } }; Algorithms::ParallelFor< DeviceType >::exec( first, last, f ); diff --git a/src/TNL/Matrices/SparseMatrix.hpp b/src/TNL/Matrices/SparseMatrix.hpp index 6d3d9d8b8b..66813a732c 100644 --- a/src/TNL/Matrices/SparseMatrix.hpp +++ b/src/TNL/Matrices/SparseMatrix.hpp @@ -682,7 +682,6 @@ operator=( const RHSMatrix& matrix ) Containers::Vector< IndexType, DeviceType, IndexType > rowLocalIndexes( matrix.getRows() ); rowLocalIndexes = 0; - // TODO: use getConstView when it works const auto matrixView = const_cast< RHSMatrix& >( matrix ).getView(); const IndexType paddingIndex = this->getPaddingIndex(); @@ -697,7 +696,7 @@ operator=( const RHSMatrix& matrix ) auto f = [=] __cuda_callable__ ( RHSIndexType rowIdx, RHSIndexType localIdx_, RHSIndexType columnIndex, const RHSRealType& value, bool& compute ) mutable { RealType inValue( 0.0 ); IndexType localIdx( rowLocalIndexes_view[ rowIdx ] ); - if( columnIndex != paddingIndex ) + if( value != 0.0 && columnIndex != paddingIndex ) { IndexType thisGlobalIdx = segments_view.getGlobalIndex( rowIdx, localIdx++ ); columns_view[ thisGlobalIdx ] = columnIndex; diff --git a/src/UnitTests/Matrices/SparseMatrixCopyTest.h b/src/UnitTests/Matrices/SparseMatrixCopyTest.h index b285f5e058..7f29191b6f 100644 --- a/src/UnitTests/Matrices/SparseMatrixCopyTest.h +++ b/src/UnitTests/Matrices/SparseMatrixCopyTest.h @@ -421,7 +421,6 @@ void testConversion() checkAntiTriDiagMatrix( antiTriDiag1 ); Matrix2 antiTriDiag2; - //TNL::Matrices::copySparseMatrix( antiTriDiag2, antiTriDiag1 ); antiTriDiag2 = antiTriDiag1; checkAntiTriDiagMatrix( antiTriDiag2 ); } @@ -433,7 +432,6 @@ void testConversion() checkUnevenRowSizeMatrix( unevenRowSize1 ); Matrix2 unevenRowSize2; - //TNL::Matrices::copySparseMatrix( unevenRowSize2, unevenRowSize1 ); unevenRowSize2 = unevenRowSize1; checkUnevenRowSizeMatrix( unevenRowSize2 ); } @@ -451,21 +449,19 @@ void tridiagonalMatrixAssignment() const IndexType rows( 10 ), columns( 10 ); TridiagonalHost hostMatrix( rows, columns ); - for( IndexType i = 0; i < columns; i++ ) - for( IndexType j = TNL::max( 0, i - 1 ); j < TNL::min( rows, i + 2 ); j++ ) + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = TNL::max( 0, i - 1 ); j < TNL::min( columns, i + 2 ); j++ ) hostMatrix.setElement( i, j, i + j ); - std::cerr << hostMatrix << std::endl; Matrix matrix; matrix = hostMatrix; - std::cerr << matrix << std::endl; using RowCapacitiesType = typename Matrix::RowsCapacitiesType; RowCapacitiesType rowCapacities; matrix.getCompressedRowLengths( rowCapacities ); - RowCapacitiesType exactRowLengths{ 0, 3, 3, 3, 3, 3, 3, 3, 3, 2 }; + RowCapacitiesType exactRowLengths{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 2 }; EXPECT_EQ( rowCapacities, exactRowLengths ); - for( IndexType i = 0; i < columns; i++ ) - for( IndexType j = 0; j < rows; j++ ) + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < columns; j++ ) { if( abs( i - j ) > 1 ) EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); @@ -476,15 +472,11 @@ void tridiagonalMatrixAssignment() #ifdef HAVE_CUDA TridiagonalCuda cudaMatrix( rows, columns ); cudaMatrix = hostMatrix; - /*for( IndexType i = 0; i < columns; i++ ) - for( IndexType j = TNL::max( 0, i - 1 ); j < TNL::min( row, i + 1 ); j++ ) - cudaMatrix.setElement( i, j, i + j );*/ - matrix = cudaMatrix; matrix.getCompressedRowLengths( rowCapacities ); EXPECT_EQ( rowCapacities, exactRowLengths ); - for( IndexType i = 0; i < columns; i++ ) - for( IndexType j = 0; j < rows; j++ ) + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < columns; j++ ) { if( abs( i - j ) > 1 ) EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); @@ -492,7 +484,58 @@ void tridiagonalMatrixAssignment() EXPECT_EQ( matrix.getElement( i, j ), i + j ); } #endif +} +template< typename Matrix > +void multidiagonalMatrixAssignment() +{ + using RealType = typename Matrix::RealType; + using DeviceType = typename Matrix::DeviceType; + using IndexType = typename Matrix::IndexType; + + using MultidiagonalHost = TNL::Matrices::Multidiagonal< RealType, TNL::Devices::Host, IndexType >; + using MultidiagonalCuda = TNL::Matrices::Multidiagonal< RealType, TNL::Devices::Cuda, IndexType >; + using DiagonalsShiftsType = typename MultidiagonalHost::DiagonalsShiftsType; + DiagonalsShiftsType diagonals{ -4, -2, 0, 1, 3, 5 }; + + const IndexType rows( 10 ), columns( 10 ); + MultidiagonalHost hostMatrix( rows, columns, diagonals ); + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < columns; j++ ) + if( diagonals.containsValue( i - j ) ) + hostMatrix.setElement( i, j, i + j ); + + Matrix matrix; + matrix = hostMatrix; + using RowCapacitiesType = typename Matrix::RowsCapacitiesType; + RowCapacitiesType rowCapacities; + matrix.getCompressedRowLengths( rowCapacities ); + RowCapacitiesType exactRowLengths{ 1, 3, 3, 3, 3, 3, 3, 3, 3, 2 }; + EXPECT_EQ( rowCapacities, exactRowLengths ); + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < columns; j++ ) + { + if( diagonals.containsValue( i - j ) ) + EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); + else + EXPECT_EQ( matrix.getElement( i, j ), i + j ); + } + +#ifdef HAVE_CUDA + MultidiagonalCuda cudaMatrix( rows, columns, diagonals ); + cudaMatrix = hostMatrix; + matrix = cudaMatrix; + matrix.getCompressedRowLengths( rowCapacities ); + EXPECT_EQ( rowCapacities, exactRowLengths ); + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < columns; j++ ) + { + if( diagonals.containsValue( i - j ) > 1 ) + EXPECT_EQ( matrix.getElement( i, j ), 0.0 ); + else + EXPECT_EQ( matrix.getElement( i, j ), i + j ); + } +#endif } template< typename Matrix > @@ -530,10 +573,6 @@ void denseMatrixAssignment() #ifdef HAVE_CUDA DenseCuda cudaMatrix( rows, columns ); cudaMatrix = hostMatrix; - /*for( IndexType i = 0; i < columns; i++ ) - for( IndexType j = 0; j <= i; j++ ) - cudaMatrix.setElement( i, j, i + j );*/ - matrix = cudaMatrix; matrix.getCompressedRowLengths( rowCapacities ); EXPECT_EQ( rowCapacities, exactRowLengths ); @@ -547,7 +586,7 @@ void denseMatrixAssignment() } #endif } -/* + TEST( SparseMatrixCopyTest, CSR_HostToHost ) { testCopyAssignment< CSR_host, CSR_host >(); @@ -616,8 +655,8 @@ TEST( SparseMatrixCopyTest, SlicedEllpack_CudaToCuda ) } #endif - -// test conversion between formats +//// +// Test of conversion between formats TEST( SparseMatrixCopyTest, CSR_to_Ellpack_host ) { testConversion< CSR_host, E_host >(); @@ -679,7 +718,6 @@ TEST( SparseMatrixCopyTest, SlicedEllpack_to_Ellpack_cuda ) testConversion< SE_cuda, E_cuda >(); } #endif -*/ //// // Tridiagonal matrix assignment test @@ -715,8 +753,41 @@ TEST( SparseMatrixCopyTest, TridiagonalMatrixAssignment_to_SlicedEllpack_cuda ) } #endif // HAVE_CUDA +//// +// Multidiagonal matrix assignment test +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_CSR_host ) +{ + multidiagonalMatrixAssignment< CSR_host >(); +} + +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_Ellpack_host ) +{ + multidiagonalMatrixAssignment< E_host >(); +} + +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_SlicedEllpack_host ) +{ + multidiagonalMatrixAssignment< SE_host >(); +} + +#ifdef HAVE_CUDA +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_CSR_cuda ) +{ + multidiagonalMatrixAssignment< CSR_cuda >(); +} + +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_Ellpack_cuda ) +{ + multidiagonalMatrixAssignment< E_cuda >(); +} +TEST( SparseMatrixCopyTest, MultidiagonalMatrixAssignment_to_SlicedEllpack_cuda ) +{ + multidiagonalMatrixAssignment< SE_cuda >(); +} +#endif // HAVE_CUDA +//// // Dense matrix assignment test TEST( SparseMatrixCopyTest, DenseMatrixAssignment_to_CSR_host ) { -- GitLab