From b20418121b70638c87ce82851777105c29e9e464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com> Date: Mon, 13 Jan 2020 21:39:52 +0100 Subject: [PATCH] Debugging multidiagonal matrix. --- src/TNL/Matrices/Matrix.h | 4 +- src/TNL/Matrices/MatrixView.h | 4 +- src/TNL/Matrices/Multidiagonal.h | 10 +- src/TNL/Matrices/Multidiagonal.hpp | 19 +- src/TNL/Matrices/MultidiagonalMatrixRowView.h | 11 +- .../Matrices/MultidiagonalMatrixRowView.hpp | 35 +- src/TNL/Matrices/MultidiagonalMatrixView.h | 7 +- src/TNL/Matrices/MultidiagonalMatrixView.hpp | 172 +++-- src/TNL/Matrices/Tridiagonal.h | 4 +- src/TNL/Matrices/Tridiagonal.hpp | 17 +- src/TNL/Matrices/TridiagonalMatrixView.h | 4 +- src/TNL/Matrices/TridiagonalMatrixView.hpp | 10 +- .../details/MultidiagonalMatrixIndexer.h | 3 + .../Matrices/MultidiagonalMatrixTest.h | 666 ++++++++---------- 14 files changed, 453 insertions(+), 513 deletions(-) diff --git a/src/TNL/Matrices/Matrix.h b/src/TNL/Matrices/Matrix.h index 7813fa9625..ebe7ccc21f 100644 --- a/src/TNL/Matrices/Matrix.h +++ b/src/TNL/Matrices/Matrix.h @@ -76,11 +76,11 @@ public: __cuda_callable__ IndexType getColumns() const; - virtual bool setElement( const IndexType row, + virtual void setElement( const IndexType row, const IndexType column, const RealType& value ) = 0; - virtual bool addElement( const IndexType row, + virtual void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ) = 0; diff --git a/src/TNL/Matrices/MatrixView.h b/src/TNL/Matrices/MatrixView.h index 467d023496..2a6429df58 100644 --- a/src/TNL/Matrices/MatrixView.h +++ b/src/TNL/Matrices/MatrixView.h @@ -73,11 +73,11 @@ public: * in the future and it does not slow down, declare them as virtual here. */ - virtual bool setElement( const IndexType row, + virtual void setElement( const IndexType row, const IndexType column, const RealType& value ) = 0; - virtual bool addElement( const IndexType row, + virtual void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ) = 0; diff --git a/src/TNL/Matrices/Multidiagonal.h b/src/TNL/Matrices/Multidiagonal.h index 5d23cd960e..1741c0c75f 100644 --- a/src/TNL/Matrices/Multidiagonal.h +++ b/src/TNL/Matrices/Multidiagonal.h @@ -38,12 +38,12 @@ class Multidiagonal : public Matrix< Real, Device, Index, RealAllocator > using ValuesType = typename BaseType::ValuesVector; using ValuesViewType = typename ValuesType::ViewType; using IndexerType = details::MultidiagonalMatrixIndexer< IndexType, RowMajorOrder >; - using RowView = MultidiagonalMatrixRowView< ValuesViewType, IndexerType >; + using DiagonalsShiftsType = Containers::Vector< IndexType, DeviceType, IndexType, IndexAllocatorType >; + using DiagonalsShiftsView = typename DiagonalsShiftsType::ViewType; + using RowView = MultidiagonalMatrixRowView< ValuesViewType, IndexerType, DiagonalsShiftsView >; using ViewType = MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >; using ConstViewType = MultidiagonalMatrixView< typename std::add_const< Real >::type, Device, Index, RowMajorOrder >; - using DiagonalsShiftsType = Containers::Vector< IndexType, DeviceType, IndexType, IndexAllocatorType >; - using DiagonalsShiftsView = typename DiagonalsShiftsType::ViewType; using HostDiagonalsShiftsType = Containers::Vector< IndexType, Devices::Host, IndexType >; using HostDiagonalsShiftsView = typename HostDiagonalsShiftsType::ViewType; @@ -119,11 +119,11 @@ class Multidiagonal : public Matrix< Real, Device, Index, RealAllocator > void setValue( const RealType& v ); - bool setElement( const IndexType row, + void setElement( const IndexType row, const IndexType column, const RealType& value ); - bool addElement( const IndexType row, + void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); diff --git a/src/TNL/Matrices/Multidiagonal.hpp b/src/TNL/Matrices/Multidiagonal.hpp index 95f6667c1c..53e3c7f2f4 100644 --- a/src/TNL/Matrices/Multidiagonal.hpp +++ b/src/TNL/Matrices/Multidiagonal.hpp @@ -44,6 +44,7 @@ Multidiagonal( const IndexType rows, const IndexType columns, const Vector& diagonalsShifts ) { + TNL_ASSERT_GT( diagonalsShifts.getSize(), 0, "Cannot construct mutltidiagonal matrix with no diagonals shifts." ); this->setDimensions( rows, columns, diagonalsShifts ); } @@ -60,6 +61,7 @@ getView() const -> ViewType // TODO: fix when getConstView works return ViewType( const_cast< Multidiagonal* >( this )->values.getView(), const_cast< Multidiagonal* >( this )->diagonalsShifts.getView(), + const_cast< Multidiagonal* >( this )->hostDiagonalsShifts.getView(), indexer ); } @@ -358,11 +360,11 @@ template< typename Real, bool RowMajorOrder, typename RealAllocator, typename IndexAllocator > -bool +void Multidiagonal< Real, Device, Index, RowMajorOrder, RealAllocator, IndexAllocator >:: setElement( const IndexType row, const IndexType column, const RealType& value ) { - return this->view.setElement( row, column, value ); + this->view.setElement( row, column, value ); } template< typename Real, @@ -371,14 +373,14 @@ template< typename Real, bool RowMajorOrder, typename RealAllocator, typename IndexAllocator > -bool +void Multidiagonal< Real, Device, Index, RowMajorOrder, RealAllocator, IndexAllocator >:: addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator ) { - return this->view.addElement( row, column, value, thisElementMultiplicator ); + this->view.addElement( row, column, value, thisElementMultiplicator ); } template< typename Real, @@ -745,14 +747,7 @@ void Multidiagonal< Real, Device, Index, RowMajorOrder, RealAllocator, IndexAllocator >:: print( std::ostream& str ) const { - for( IndexType row = 0; row < this->getRows(); row++ ) - { - str <<"Row: " << row << " -> "; - for( IndexType column = row - 1; column < row + 2; column++ ) - if( column >= 0 && column < this->columns ) - str << " Col:" << column << "->" << this->getElement( row, column ) << "\t"; - str << std::endl; - } + this->view.print( str ); } template< typename Real, diff --git a/src/TNL/Matrices/MultidiagonalMatrixRowView.h b/src/TNL/Matrices/MultidiagonalMatrixRowView.h index 68b5be55c1..0825d6fb36 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixRowView.h +++ b/src/TNL/Matrices/MultidiagonalMatrixRowView.h @@ -14,7 +14,8 @@ namespace TNL { namespace Matrices { template< typename ValuesView, - typename Indexer > + typename Indexer, + typename DiagonalsShiftsView_ > class MultidiagonalMatrixRowView { public: @@ -23,11 +24,13 @@ class MultidiagonalMatrixRowView using IndexType = typename ValuesView::IndexType; using ValuesViewType = ValuesView; using IndexerType = Indexer; + using DiagonalsShiftsView = DiagonalsShiftsView_; __cuda_callable__ MultidiagonalMatrixRowView( const IndexType rowIdx, - const ValuesViewType& values, - const IndexerType& indexer ); + const DiagonalsShiftsView& diagonalsShifts, + const ValuesViewType& values, + const IndexerType& indexer); __cuda_callable__ IndexType getSize() const; @@ -48,6 +51,8 @@ class MultidiagonalMatrixRowView IndexType rowIdx; + DiagonalsShiftsView diagonalsShifts; + ValuesViewType values; Indexer indexer; diff --git a/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp b/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp index 349fbe8ea3..88aae3f150 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp +++ b/src/TNL/Matrices/MultidiagonalMatrixRowView.hpp @@ -13,58 +13,59 @@ namespace TNL { namespace Matrices { -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: MultidiagonalMatrixRowView( const IndexType rowIdx, - const ValuesViewType& values, - const IndexerType& indexer ) -: rowIdx( rowIdx ), values( values ), indexer( indexer ) + const DiagonalsShiftsView& diagonalsShifts, + const ValuesViewType& values, + const IndexerType& indexer ) +: rowIdx( rowIdx ), diagonalsShifts( diagonalsShifts ), values( values ), indexer( indexer ) { } -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ auto -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: getSize() const -> IndexType { return indexer.getRowSize(); } -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ auto -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: getColumnIndex( const IndexType localIdx ) const -> const IndexType { TNL_ASSERT_GE( localIdx, 0, "" ); - TNL_ASSERT_LT( localIdx, 3, "" ); - return rowIdx + localIdx - 1; + TNL_ASSERT_LT( localIdx, indexer.getDiagonals(), "" ); + return rowIdx + diagonalsShifts[ localIdx ]; } -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ auto -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: getValue( const IndexType localIdx ) const -> const RealType& { return this->values[ this->indexer.getGlobalIndex( rowIdx, localIdx ) ]; } -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ auto -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: getValue( const IndexType localIdx ) -> RealType& { return this->values[ this->indexer.getGlobalIndex( rowIdx, localIdx ) ]; } -template< typename ValuesView, typename Indexer > +template< typename ValuesView, typename Indexer, typename DiagonalsShiftsView > __cuda_callable__ void -MultidiagonalMatrixRowView< ValuesView, Indexer >:: +MultidiagonalMatrixRowView< ValuesView, Indexer, DiagonalsShiftsView >:: setElement( const IndexType localIdx, const RealType& value ) { diff --git a/src/TNL/Matrices/MultidiagonalMatrixView.h b/src/TNL/Matrices/MultidiagonalMatrixView.h index addeb18b34..3d33ac0aea 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixView.h +++ b/src/TNL/Matrices/MultidiagonalMatrixView.h @@ -38,7 +38,7 @@ class MultidiagonalMatrixView : public MatrixView< Real, Device, Index > using ValuesViewType = typename BaseType::ValuesView; using ViewType = MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >; using ConstViewType = MultidiagonalMatrixView< typename std::add_const< Real >::type, Device, Index, RowMajorOrder >; - using RowView = MultidiagonalMatrixRowView< ValuesViewType, IndexerType >; + using RowView = MultidiagonalMatrixRowView< ValuesViewType, IndexerType, DiagonalsShiftsView >; // TODO: remove this - it is here only for compatibility with original matrix implementation typedef Containers::Vector< IndexType, DeviceType, IndexType > CompressedRowLengthsVector; @@ -55,6 +55,7 @@ class MultidiagonalMatrixView : public MatrixView< Real, Device, Index > MultidiagonalMatrixView( const ValuesViewType& values, const DiagonalsShiftsView& diagonalsShifts, + const HostDiagonalsShiftsView& hostDiagonalsShifts, const IndexerType& indexer ); ViewType getView(); @@ -92,11 +93,11 @@ class MultidiagonalMatrixView : public MatrixView< Real, Device, Index > void setValue( const RealType& v ); - bool setElement( const IndexType row, + void setElement( const IndexType row, const IndexType column, const RealType& value ); - bool addElement( const IndexType row, + void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); diff --git a/src/TNL/Matrices/MultidiagonalMatrixView.hpp b/src/TNL/Matrices/MultidiagonalMatrixView.hpp index 3d9b0237f9..1ba8dc34d0 100644 --- a/src/TNL/Matrices/MultidiagonalMatrixView.hpp +++ b/src/TNL/Matrices/MultidiagonalMatrixView.hpp @@ -33,9 +33,11 @@ template< typename Real, MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: MultidiagonalMatrixView( const ValuesViewType& values, const DiagonalsShiftsView& diagonalsShifts, + const HostDiagonalsShiftsView& hostDiagonalsShifts, const IndexerType& indexer ) : MatrixView< Real, Device, Index >( indexer.getRows(), indexer.getColumns(), values ), diagonalsShifts( diagonalsShifts ), + hostDiagonalsShifts( hostDiagonalsShifts ), indexer( indexer ) { } @@ -48,7 +50,10 @@ auto MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: getView() -> ViewType { - return ViewType( this->values.getView(), indexer ); + return ViewType( const_cast< MultidiagonalMatrixView* >( this )->values.getView(), + const_cast< MultidiagonalMatrixView* >( this )->diagonalsShifts.getView(), + const_cast< MultidiagonalMatrixView* >( this )->hostDiagonalsShifts.getView(), + indexer ); } template< typename Real, @@ -59,7 +64,10 @@ auto MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: getConstView() const -> ConstViewType { - return ConstViewType( this->values.getConstView(), indexer ); + return ConstViewType( this->values.getConstView(), + this->diagonalsShifts.getConstView(), + this->hostDiagonalsShifts.getConstView(), + indexer ); } template< typename Real, @@ -208,7 +216,11 @@ void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: setValue( const RealType& v ) { - this->values = v; + const RealType newValue = v; + auto f = [=] __cuda_callable__ ( const IndexType& rowIdx, const IndexType& localIdx, const IndexType columnIdx, RealType& value ) mutable { + value = newValue; + }; + this->forAllRows( f ); } template< typename Real, @@ -220,7 +232,7 @@ auto MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: getRow( const IndexType& rowIdx ) const -> const RowView { - return RowView( rowIdx, this->values.getView(), this->indexer ); + return RowView( rowIdx, this->diagonalsShifts.getView(), this->values.getView(), this->indexer ); } template< typename Real, @@ -232,14 +244,14 @@ auto MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: getRow( const IndexType& rowIdx ) -> RowView { - return RowView( rowIdx, this->values.getView(), this->indexer ); + return RowView( rowIdx, this->diagonalsShifts.getView(), this->values.getView(), this->indexer ); } template< typename Real, typename Device, typename Index, bool RowMajorOrder > -bool +void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: setElement( const IndexType row, const IndexType column, const RealType& value ) { @@ -247,21 +259,26 @@ setElement( const IndexType row, const IndexType column, const RealType& value ) TNL_ASSERT_LT( row, this->getRows(), "" ); TNL_ASSERT_GE( column, 0, "" ); TNL_ASSERT_LT( column, this->getColumns(), "" ); - if( abs( row - column ) > 1 ) + + for( IndexType i = 0; i < hostDiagonalsShifts.getSize(); i++ ) + if( row + hostDiagonalsShifts[ i ] == column ) + { + this->values.setElement( this->getElementIndex( row, i ), value ); + return; + } + if( value != 0.0 ) { std::stringstream msg; - msg << "Wrong matrix element coordinates ( " << row << ", " << column << " ) in tridiagonal matrix."; + msg << "Wrong matrix element coordinates ( " << row << ", " << column << " ) in multidiagonal matrix."; throw std::logic_error( msg.str() ); } - this->values.setElement( this->getElementIndex( row, column ), value ); - return true; } template< typename Real, typename Device, typename Index, bool RowMajorOrder > -bool +void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: addElement( const IndexType row, const IndexType column, @@ -272,15 +289,20 @@ addElement( const IndexType row, TNL_ASSERT_LT( row, this->getRows(), "" ); TNL_ASSERT_GE( column, 0, "" ); TNL_ASSERT_LT( column, this->getColumns(), "" ); - if( abs( row - column ) > 1 ) + + for( IndexType i = 0; i < hostDiagonalsShifts.getSize(); i++ ) + if( row + hostDiagonalsShifts[ i ] == column ) + { + const Index idx = this->getElementIndex( row, i ); + this->values.setElement( idx, thisElementMultiplicator * this->values.getElement( idx ) + value ); + return; + } + if( value != 0.0 ) { std::stringstream msg; - msg << "Wrong matrix element coordinates ( " << row << ", " << column << " ) in tridiagonal matrix."; + msg << "Wrong matrix element coordinates ( " << row << ", " << column << " ) in multidiagonal matrix."; throw std::logic_error( msg.str() ); } - const Index i = this->getElementIndex( row, column ); - this->values.setElement( i, thisElementMultiplicator * this->values.getElement( i ) + value ); - return true; } template< typename Real, @@ -296,9 +318,10 @@ getElement( const IndexType row, const IndexType column ) const TNL_ASSERT_GE( column, 0, "" ); TNL_ASSERT_LT( column, this->getColumns(), "" ); - if( abs( column - row ) > 1 ) - return 0.0; - return this->values.getElement( this->getElementIndex( row, column ) ); + for( IndexType i = 0; i < hostDiagonalsShifts.getSize(); i++ ) + if( row + hostDiagonalsShifts[ i ] == column ) + return this->values.getElement( this->getElementIndex( row, i ) ); + return 0.0; } template< typename Real, @@ -326,35 +349,20 @@ rowsReduction( IndexType first, IndexType last, Fetch& fetch, Reduce& reduce, Ke { using Real_ = decltype( fetch( IndexType(), IndexType(), RealType() ) ); const auto values_view = this->values.getConstView(); + const auto diagonalsShifts_view = this->diagonalsShifts.getConstView(); + const IndexType diagonalsCount = this->diagonalsShifts.getSize(); + const IndexType columns = this->getColumns(); const auto indexer = this->indexer; const auto zero = zero_; auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { Real_ sum( zero ); - if( rowIdx == 0 ) - { - reduce( sum, fetch( 0, 0, values_view[ indexer.getGlobalIndex( 0, 0 ) ] ) ); - reduce( sum, fetch( 0, 1, values_view[ indexer.getGlobalIndex( 0, 1 ) ] ) ); - keep( 0, sum ); - return; - } - if( rowIdx + 1 < indexer.getColumns() ) - { - reduce( sum, fetch( rowIdx, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ) ); - reduce( sum, fetch( rowIdx, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ) ); - reduce( sum, fetch( rowIdx, rowIdx + 1, values_view[ indexer.getGlobalIndex( rowIdx, 2 ) ] ) ); - keep( rowIdx, sum ); - return; - } - if( rowIdx < indexer.getColumns() ) + for( IndexType localIdx = 0; localIdx < diagonalsCount; localIdx++ ) { - reduce( sum, fetch( rowIdx, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ) ); - reduce( sum, fetch( rowIdx, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ) ); - keep( rowIdx, sum ); - } - else - { - keep( rowIdx, fetch( rowIdx, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ) ); + const IndexType columnIdx = rowIdx + diagonalsShifts_view[ localIdx ]; + if( columnIdx >= 0 && columnIdx < columns ) + reduce( sum, fetch( rowIdx, columnIdx, values_view[ indexer.getGlobalIndex( rowIdx, localIdx ) ] ) ); } + keep( rowIdx, sum ); }; Algorithms::ParallelFor< DeviceType >::exec( first, last, f ); } @@ -368,7 +376,7 @@ void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: allRowsReduction( Fetch& fetch, Reduce& reduce, Keep& keep, const FetchReal& zero ) const { - this->rowsReduction( 0, this->indexer.getNonEmptyRowsCount(), fetch, reduce, keep, zero ); + this->rowsReduction( 0, this->indexer.getNonemptyRowsCount(), fetch, reduce, keep, zero ); } template< typename Real, @@ -381,26 +389,17 @@ MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: forRows( IndexType first, IndexType last, Function& function ) const { const auto values_view = this->values.getConstView(); + const auto diagonalsShifts_view = this->diagonalsShifts.getConstView(); + const IndexType diagonalsCount = this->diagonalsShifts.getSize(); + const IndexType columns = this->getColumns(); const auto indexer = this->indexer; auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { - if( rowIdx == 0 ) + for( IndexType localIdx = 0; localIdx < diagonalsCount; localIdx++ ) { - function( 0, 0, 0, values_view[ indexer.getGlobalIndex( 0, 0 ) ] ); - function( 0, 1, 1, values_view[ indexer.getGlobalIndex( 0, 1 ) ] ); - } - else if( rowIdx + 1 < indexer.getColumns() ) - { - function( rowIdx, 0, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); - function( rowIdx, 1, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ); - function( rowIdx, 2, rowIdx + 1, values_view[ indexer.getGlobalIndex( rowIdx, 2 ) ] ); + const IndexType columnIdx = rowIdx + diagonalsShifts_view[ localIdx ]; + if( columnIdx >= 0 && columnIdx < columns ) + function( rowIdx, localIdx, columnIdx, values_view[ indexer.getGlobalIndex( rowIdx, localIdx, 0 ) ] ); } - else if( rowIdx < indexer.getColumns() ) - { - function( rowIdx, 0, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); - function( rowIdx, 1, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ); - } - else - function( rowIdx, 0, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); }; Algorithms::ParallelFor< DeviceType >::exec( first, last, f ); } @@ -415,26 +414,17 @@ MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: forRows( IndexType first, IndexType last, Function& function ) { auto values_view = this->values.getView(); + const auto diagonalsShifts_view = this->diagonalsShifts.getConstView(); + const IndexType diagonalsCount = this->diagonalsShifts.getSize(); + const IndexType columns = this->getColumns(); const auto indexer = this->indexer; auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { - if( rowIdx == 0 ) - { - function( 0, 0, 0, values_view[ indexer.getGlobalIndex( 0, 0 ) ] ); - function( 0, 1, 1, values_view[ indexer.getGlobalIndex( 0, 1 ) ] ); - } - else if( rowIdx + 1 < indexer.getColumns() ) - { - function( rowIdx, 0, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); - function( rowIdx, 1, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ); - function( rowIdx, 2, rowIdx + 1, values_view[ indexer.getGlobalIndex( rowIdx, 2 ) ] ); - } - else if( rowIdx < indexer.getColumns() ) + for( IndexType localIdx = 0; localIdx < diagonalsCount; localIdx++ ) { - function( rowIdx, 0, rowIdx - 1, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); - function( rowIdx, 1, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 1 ) ] ); + const IndexType columnIdx = rowIdx + diagonalsShifts_view[ localIdx ]; + if( columnIdx >= 0 && columnIdx < columns ) + function( rowIdx, localIdx, columnIdx, values_view[ indexer.getGlobalIndex( rowIdx, localIdx ) ] ); } - else - function( rowIdx, 0, rowIdx, values_view[ indexer.getGlobalIndex( rowIdx, 0 ) ] ); }; Algorithms::ParallelFor< DeviceType >::exec( first, last, f ); } @@ -460,7 +450,7 @@ void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: forAllRows( Function& function ) { - this->forRows( 0, this->indexer.getNonEmptyRowsCount(), function ); + this->forRows( 0, this->indexer.getNonemptyRowsCount(), function ); } template< typename Real, @@ -517,7 +507,7 @@ addMatrix( const MultidiagonalMatrixView< Real_, Device_, Index_, RowMajorOrder_ TNL_ASSERT_EQ( this->getRows(), matrix.getRows(), "Matrices rows are not equal." ); TNL_ASSERT_EQ( this->getColumns(), matrix.getColumns(), "Matrices columns are not equal." ); - if( RowMajorOrder == RowMajorOrder_ ) + /*if( RowMajorOrder == RowMajorOrder_ ) { if( thisMatrixMultiplicator == 1.0 ) this->values += matrixMultiplicator * matrix.getValues(); @@ -544,7 +534,7 @@ addMatrix( const MultidiagonalMatrixView< Real_, Device_, Index_, RowMajorOrder_ this->forAllRows( add1 ); else this->forAllRows( addGen ); - } + }*/ } #ifdef HAVE_CUDA @@ -673,12 +663,19 @@ template< typename Real, bool RowMajorOrder > void MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >::print( std::ostream& str ) const { - for( IndexType row = 0; row < this->getRows(); row++ ) + for( IndexType rowIdx = 0; rowIdx < this->getRows(); rowIdx++ ) { - str <<"Row: " << row << " -> "; - for( IndexType column = row - 1; column < row + 2; column++ ) - if( column >= 0 && column < this->columns ) - str << " Col:" << column << "->" << this->getElement( row, column ) << "\t"; + str <<"Row: " << rowIdx << " -> "; + for( IndexType localIdx = 0; localIdx < this->hostDiagonalsShifts.getSize(); localIdx++ ) + { + const IndexType columnIdx = rowIdx + this->hostDiagonalsShifts[ localIdx ]; + if( columnIdx >= 0 && columnIdx < this->columns ) + { + auto v = this->values.getElement( this->indexer.getGlobalIndex( rowIdx, localIdx ) ); + if( v ) + str << " Col:" << columnIdx << "->" << v << "\t"; + } + } str << std::endl; } } @@ -713,15 +710,8 @@ template< typename Real, bool RowMajorOrder > __cuda_callable__ Index MultidiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: -getElementIndex( const IndexType row, const IndexType column ) const +getElementIndex( const IndexType row, const IndexType localIdx ) const { - IndexType localIdx = column - row; - if( row > 0 ) - localIdx++; - - TNL_ASSERT_GE( localIdx, 0, "" ); - TNL_ASSERT_LT( localIdx, 3, "" ); - return this->indexer.getGlobalIndex( row, localIdx ); } diff --git a/src/TNL/Matrices/Tridiagonal.h b/src/TNL/Matrices/Tridiagonal.h index e7e3ab6b27..82549e7445 100644 --- a/src/TNL/Matrices/Tridiagonal.h +++ b/src/TNL/Matrices/Tridiagonal.h @@ -97,11 +97,11 @@ class Tridiagonal : public Matrix< Real, Device, Index, RealAllocator > void setValue( const RealType& v ); - bool setElement( const IndexType row, + void setElement( const IndexType row, const IndexType column, const RealType& value ); - bool addElement( const IndexType row, + void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); diff --git a/src/TNL/Matrices/Tridiagonal.hpp b/src/TNL/Matrices/Tridiagonal.hpp index 6c09238ff0..41d722c6a7 100644 --- a/src/TNL/Matrices/Tridiagonal.hpp +++ b/src/TNL/Matrices/Tridiagonal.hpp @@ -285,11 +285,11 @@ template< typename Real, typename Index, bool RowMajorOrder, typename RealAllocator > -bool +void Tridiagonal< Real, Device, Index, RowMajorOrder, RealAllocator >:: setElement( const IndexType row, const IndexType column, const RealType& value ) { - return this->view.setElement( row, column, value ); + this->view.setElement( row, column, value ); } template< typename Real, @@ -297,14 +297,14 @@ template< typename Real, typename Index, bool RowMajorOrder, typename RealAllocator > -bool +void Tridiagonal< Real, Device, Index, RowMajorOrder, RealAllocator >:: addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator ) { - return this->view.addElement( row, column, value, thisElementMultiplicator ); + this->view.addElement( row, column, value, thisElementMultiplicator ); } template< typename Real, @@ -645,14 +645,7 @@ void Tridiagonal< Real, Device, Index, RowMajorOrder, RealAllocator >:: print( std::ostream& str ) const { - for( IndexType row = 0; row < this->getRows(); row++ ) - { - str <<"Row: " << row << " -> "; - for( IndexType column = row - 1; column < row + 2; column++ ) - if( column >= 0 && column < this->columns ) - str << " Col:" << column << "->" << this->getElement( row, column ) << "\t"; - str << std::endl; - } + this->view.print( str ); } template< typename Real, diff --git a/src/TNL/Matrices/TridiagonalMatrixView.h b/src/TNL/Matrices/TridiagonalMatrixView.h index 128b484947..7db517cbd3 100644 --- a/src/TNL/Matrices/TridiagonalMatrixView.h +++ b/src/TNL/Matrices/TridiagonalMatrixView.h @@ -81,11 +81,11 @@ class TridiagonalMatrixView : public MatrixView< Real, Device, Index > void setValue( const RealType& v ); - bool setElement( const IndexType row, + void setElement( const IndexType row, const IndexType column, const RealType& value ); - bool addElement( const IndexType row, + void addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); diff --git a/src/TNL/Matrices/TridiagonalMatrixView.hpp b/src/TNL/Matrices/TridiagonalMatrixView.hpp index 4d4950c4e9..e851d2a1f9 100644 --- a/src/TNL/Matrices/TridiagonalMatrixView.hpp +++ b/src/TNL/Matrices/TridiagonalMatrixView.hpp @@ -213,7 +213,7 @@ template< typename Real, typename Device, typename Index, bool RowMajorOrder > -bool +void TridiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: setElement( const IndexType row, const IndexType column, const RealType& value ) { @@ -235,7 +235,7 @@ template< typename Real, typename Device, typename Index, bool RowMajorOrder > -bool +void TridiagonalMatrixView< Real, Device, Index, RowMajorOrder >:: addElement( const IndexType row, const IndexType column, @@ -638,7 +638,11 @@ void TridiagonalMatrixView< Real, Device, Index, RowMajorOrder >::print( std::os str <<"Row: " << row << " -> "; for( IndexType column = row - 1; column < row + 2; column++ ) if( column >= 0 && column < this->columns ) - str << " Col:" << column << "->" << this->getElement( row, column ) << "\t"; + { + auto v = this->getElement( row, column ); + if( v ) + str << " Col:" << column << "->" << v << "\t"; + } str << std::endl; } } diff --git a/src/TNL/Matrices/details/MultidiagonalMatrixIndexer.h b/src/TNL/Matrices/details/MultidiagonalMatrixIndexer.h index 0f0436d748..3597c30f7d 100644 --- a/src/TNL/Matrices/details/MultidiagonalMatrixIndexer.h +++ b/src/TNL/Matrices/details/MultidiagonalMatrixIndexer.h @@ -77,6 +77,9 @@ class MultidiagonalMatrixIndexer __cuda_callable__ const IndexType& getColumns() const { return this->columns; }; + __cuda_callable__ + const IndexType& getDiagonals() const { return this->diagonals; }; + __cuda_callable__ const IndexType& getNonemptyRowsCount() const { return this->nonemptyRows; }; diff --git a/src/UnitTests/Matrices/MultidiagonalMatrixTest.h b/src/UnitTests/Matrices/MultidiagonalMatrixTest.h index cb9916e4c9..514ea39e0e 100644 --- a/src/UnitTests/Matrices/MultidiagonalMatrixTest.h +++ b/src/UnitTests/Matrices/MultidiagonalMatrixTest.h @@ -137,7 +137,6 @@ void test_GetNonemptyRowsCount() Matrix m3( 8, 5, DiagonalsShiftsType({ -2, 0, 3, 5 }) ); m3.setValue( 1.0 ); EXPECT_EQ( m3.getNonemptyRowsCount(), 7 ); - } template< typename Matrix > @@ -148,87 +147,53 @@ void test_GetCompressedRowLengths() using IndexType = typename Matrix::IndexType; using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; - 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 < 2; i++ ) // 0th row -> 2 elements - m.setElement( 0, i, value++ ); - - for( IndexType i = 0; i < 3; i++ ) // 1st row -> 3 elements - m.setElement( 1, i, value++ ); - - for( IndexType i = 1; i < 3; i++ ) // 2nd row -> 2 elements - m.setElement( 2, i, value++ ); - - for( IndexType i = 2; i < 5; i++ ) // 3rd row -> 3 elements - m.setElement( 3, i, value++ ); - - for( IndexType i = 3; i < 6; i++ ) // 4th row -> 3 elements - m.setElement( 4, i, value++ ); - - for( IndexType i = 4; i < 6; i++ ) // 5th row -> 2 elements - m.setElement( 5, i, value++ ); - - for( IndexType i = 5; i < 8; i++ ) // 6th row -> 3 elements - m.setElement( 6, i, value++ ); - - for( IndexType i = 6; i < 8; i++ ) // 7th row -> 2 elements - m.setElement( 7, i, value++ ); - - for( IndexType i = 7; i < 10; i++ ) // 8th row -> 3 elements - m.setElement( 8, i, value++ ); + /* + * Sets up the following 8x8 matrix: + * + * / 0 0 0 1 0 1 0 0 \ -> 2 + * | 0 1 0 0 1 0 1 0 | -> 3 + * | 1 0 1 0 0 1 0 1 | -> 4 + * | 0 1 0 1 0 0 1 0 | -> 3 + * | 0 0 1 0 1 0 0 1 | -> 3 + * | 0 0 0 1 0 1 0 0 | -> 2 + * | 0 0 0 0 1 0 1 0 | -> 2 + * \ 0 0 0 0 0 1 0 0 / -> 1 + */ + + const IndexType rows = 8; + const IndexType cols = 8; - for( IndexType i = 8; i < 11; i++ ) // 9th row -> 3 elements - m.setElement( 9, i, value++ ); + Matrix m( rows, cols, DiagonalsShiftsType({ -2, 0, 3, 5 }) ); + m.setValue( 1.0 ); + m.setElement( 0, 0, 0.0 ); + m.setElement( 7, 7, 0.0 ); typename Matrix::CompressedRowLengthsVector rowLengths( rows ); rowLengths = 0; m.getCompressedRowLengths( rowLengths ); - typename Matrix::CompressedRowLengthsVector correctRowLengths{ 2, 3, 2, 3, 3, 2, 3, 2, 3, 3 }; + typename Matrix::CompressedRowLengthsVector correctRowLengths{ 2, 3, 4, 3, 3, 2, 2, 1 }; 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; - using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; - - const IndexType rows = 8; - const IndexType cols = 7; - - Matrix m( rows, cols ); - - EXPECT_EQ( m.getRowLength( 0 ), 2 ); - EXPECT_EQ( m.getRowLength( 1 ), 3 ); - EXPECT_EQ( m.getRowLength( 2 ), 3 ); - EXPECT_EQ( m.getRowLength( 3 ), 3 ); - EXPECT_EQ( m.getRowLength( 4 ), 3 ); - EXPECT_EQ( m.getRowLength( 5 ), 3 ); - EXPECT_EQ( m.getRowLength( 6 ), 2 ); - EXPECT_EQ( m.getRowLength( 7 ), 1 ); -} - template< typename Matrix > void test_GetAllocatedElementsCount() { using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; const IndexType rows = 7; const IndexType cols = 6; - Matrix m( rows, cols ); + Matrix m1( 7, 6, DiagonalsShiftsType( { -2, 0, 3, 5 } ) ); + EXPECT_EQ( m1.getAllocatedElementsCount(), 28 ); + + Matrix m2( 8, 6, DiagonalsShiftsType( { -2, 0, 3, 5 } ) ); + EXPECT_EQ( m2.getAllocatedElementsCount(), 32 ); - EXPECT_EQ( m.getAllocatedElementsCount(), 21 ); + Matrix m3( 9, 6, DiagonalsShiftsType( { -2, 0, 3, 5 } ) ); + EXPECT_EQ( m3.getAllocatedElementsCount(), 32 ); } template< typename Matrix > @@ -237,29 +202,27 @@ void test_GetNumberOfNonzeroMatrixElements() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* * Sets up the following 7x6 matrix: * - * / 0 1 0 0 0 0 \ - * | 2 3 4 0 0 0 | - * | 0 5 6 7 0 0 | - * | 0 0 8 9 10 0 | - * | 0 0 0 11 12 13 | - * | 0 0 0 0 14 0 | - * \ 0 0 0 0 0 16 / + * / 0 0 1 0 1 0 \ -> 2 + * | 0 1 0 1 0 1 | -> 3 + * | 0 0 1 0 1 0 | -> 2 + * | 1 0 0 1 0 1 | -> 3 + * | 0 1 0 0 1 0 | -> 2 + * | 0 0 1 0 0 1 | -> 2 + * \ 0 0 0 1 0 0 / -> 1 + * ---- + * 15 */ const IndexType rows = 7; const IndexType cols = 6; - Matrix m( rows, cols ); - - RealType value = 0; - for( IndexType i = 0; i < rows; i++ ) - for( IndexType j = TNL::max( 0, i - 1 ); j < TNL::min( cols, i + 2 ); j++ ) - m.setElement( i, j, value++ ); - - m.setElement( 5, 5, 0); + Matrix m( rows, cols, DiagonalsShiftsType( { -3, 0, 2, 4 } ) ); + m.setValue( 1.0 ); + m.setElement( 0, 0, 0.0 ); EXPECT_EQ( m.getNumberOfNonzeroMatrixElements(), 15 ); } @@ -270,6 +233,7 @@ void test_Reset() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* * Sets up the following 5x4 matrix: @@ -283,8 +247,7 @@ void test_Reset() const IndexType rows = 5; const IndexType cols = 4; - Matrix m( rows, cols ); - + Matrix m( rows, cols, DiagonalsShiftsType( { 0, 1, 2, 4 } ) ); m.reset(); EXPECT_EQ( m.getRows(), 0 ); @@ -297,130 +260,73 @@ void test_SetValue() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* * Sets up the following 7x6 matrix: * - * / 0 1 0 0 0 0 \ - * | 2 3 4 0 0 0 | - * | 0 5 6 7 0 0 | - * | 0 0 8 9 10 0 | - * | 0 0 0 11 12 13 | - * | 0 0 0 0 14 0 | - * \ 0 0 0 0 0 16 / + * / 1 0 1 0 1 0 \ + * | 0 1 0 1 0 1 | + * | 0 0 1 0 1 0 | + * | 1 0 0 1 0 1 | + * | 0 1 0 0 1 0 | + * | 0 0 1 0 0 1 | + * \ 0 0 0 1 0 0 / */ const IndexType rows = 7; const IndexType cols = 6; - Matrix m( rows, cols ); - - RealType value = 0; - for( IndexType i = 0; i < rows; i++ ) - for( IndexType j = TNL::max( 0, i - 1 ); j < TNL::min( cols, i + 2 ); j++ ) - m.setElement( i, j, value++ ); - - m.setElement( 5, 5, 0); - - EXPECT_EQ( m.getElement( 0, 0 ), 0 ); - EXPECT_EQ( m.getElement( 0, 1 ), 1 ); - EXPECT_EQ( m.getElement( 0, 2 ), 0 ); - EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); - EXPECT_EQ( m.getElement( 0, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 1, 0 ), 2 ); - EXPECT_EQ( m.getElement( 1, 1 ), 3 ); - EXPECT_EQ( m.getElement( 1, 2 ), 4 ); - EXPECT_EQ( m.getElement( 1, 3 ), 0 ); - EXPECT_EQ( m.getElement( 1, 4 ), 0 ); - EXPECT_EQ( m.getElement( 1, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 5 ); - EXPECT_EQ( m.getElement( 2, 2 ), 6 ); - EXPECT_EQ( m.getElement( 2, 3 ), 7 ); - EXPECT_EQ( m.getElement( 2, 4 ), 0 ); - EXPECT_EQ( m.getElement( 2, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 3, 0 ), 0 ); - EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 8 ); - EXPECT_EQ( m.getElement( 3, 3 ), 9 ); - EXPECT_EQ( m.getElement( 3, 4 ), 10 ); - EXPECT_EQ( m.getElement( 3, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 4, 0 ), 0 ); - EXPECT_EQ( m.getElement( 4, 1 ), 0 ); - EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 11 ); - EXPECT_EQ( m.getElement( 4, 4 ), 12 ); - EXPECT_EQ( m.getElement( 4, 5 ), 13 ); - - EXPECT_EQ( m.getElement( 5, 0 ), 0 ); - EXPECT_EQ( m.getElement( 5, 1 ), 0 ); - EXPECT_EQ( m.getElement( 5, 2 ), 0 ); - EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - EXPECT_EQ( m.getElement( 5, 4 ), 14 ); - EXPECT_EQ( m.getElement( 5, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 6, 0 ), 0 ); - EXPECT_EQ( m.getElement( 6, 1 ), 0 ); - EXPECT_EQ( m.getElement( 6, 2 ), 0 ); - EXPECT_EQ( m.getElement( 6, 3 ), 0 ); - EXPECT_EQ( m.getElement( 6, 4 ), 0 ); - EXPECT_EQ( m.getElement( 6, 5 ), 16 ); - - // 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 ), 0 ); - EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); - EXPECT_EQ( m.getElement( 0, 5 ), 0 ); - - 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 ), 0 ); - EXPECT_EQ( m.getElement( 1, 4 ), 0 ); - EXPECT_EQ( m.getElement( 1, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - 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 ), 0 ); - EXPECT_EQ( m.getElement( 2, 5 ), 0 ); - - EXPECT_EQ( m.getElement( 3, 0 ), 0 ); - EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - 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 ), 0 ); - - EXPECT_EQ( m.getElement( 4, 0 ), 0 ); - EXPECT_EQ( m.getElement( 4, 1 ), 0 ); - EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - 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 ), 0 ); - EXPECT_EQ( m.getElement( 5, 1 ), 0 ); - EXPECT_EQ( m.getElement( 5, 2 ), 0 ); - EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - EXPECT_EQ( m.getElement( 5, 4 ), 42 ); - EXPECT_EQ( m.getElement( 5, 5 ), 42 ); - - EXPECT_EQ( m.getElement( 6, 0 ), 0 ); - EXPECT_EQ( m.getElement( 6, 1 ), 0 ); - EXPECT_EQ( m.getElement( 6, 2 ), 0 ); - EXPECT_EQ( m.getElement( 6, 3 ), 0 ); - EXPECT_EQ( m.getElement( 6, 4 ), 0 ); - EXPECT_EQ( m.getElement( 6, 5 ), 42 ); + Matrix m( rows, cols, DiagonalsShiftsType( { -3, 0, 2, 4 } ) ); + m.setValue( 1.0 ); + + EXPECT_EQ( m.getElement( 0, 0 ), 1 ); + EXPECT_EQ( m.getElement( 0, 1 ), 0 ); + EXPECT_EQ( m.getElement( 0, 2 ), 1 ); + EXPECT_EQ( m.getElement( 0, 3 ), 0 ); + EXPECT_EQ( m.getElement( 0, 4 ), 1 ); + EXPECT_EQ( m.getElement( 0, 5 ), 0 ); + + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); + EXPECT_EQ( m.getElement( 1, 1 ), 1 ); + EXPECT_EQ( m.getElement( 1, 2 ), 0 ); + EXPECT_EQ( m.getElement( 1, 3 ), 1 ); + EXPECT_EQ( m.getElement( 1, 4 ), 0 ); + EXPECT_EQ( m.getElement( 1, 5 ), 1 ); + + EXPECT_EQ( m.getElement( 2, 0 ), 0 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); + EXPECT_EQ( m.getElement( 2, 2 ), 1 ); + EXPECT_EQ( m.getElement( 2, 3 ), 0 ); + EXPECT_EQ( m.getElement( 2, 4 ), 1 ); + EXPECT_EQ( m.getElement( 2, 5 ), 0 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 1 ); + EXPECT_EQ( m.getElement( 3, 1 ), 0 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); + EXPECT_EQ( m.getElement( 3, 3 ), 1 ); + EXPECT_EQ( m.getElement( 3, 4 ), 0 ); + EXPECT_EQ( m.getElement( 3, 5 ), 1 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 0 ); + EXPECT_EQ( m.getElement( 4, 1 ), 1 ); + EXPECT_EQ( m.getElement( 4, 2 ), 0 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); + EXPECT_EQ( m.getElement( 4, 4 ), 1 ); + EXPECT_EQ( m.getElement( 4, 5 ), 0 ); + + EXPECT_EQ( m.getElement( 5, 0 ), 0 ); + EXPECT_EQ( m.getElement( 5, 1 ), 0 ); + EXPECT_EQ( m.getElement( 5, 2 ), 1 ); + EXPECT_EQ( m.getElement( 5, 3 ), 0 ); + EXPECT_EQ( m.getElement( 5, 4 ), 0 ); + EXPECT_EQ( m.getElement( 5, 5 ), 1 ); + + EXPECT_EQ( m.getElement( 6, 0 ), 0 ); + EXPECT_EQ( m.getElement( 6, 1 ), 0 ); + EXPECT_EQ( m.getElement( 6, 2 ), 0 ); + EXPECT_EQ( m.getElement( 6, 3 ), 1 ); + EXPECT_EQ( m.getElement( 6, 4 ), 0 ); + EXPECT_EQ( m.getElement( 6, 5 ), 0 ); } template< typename Matrix > @@ -429,61 +335,70 @@ void test_SetElement() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* * Sets up the following 5x5 matrix: * - * / 1 2 0 0 0 \ - * | 6 7 8 0 0 | - * | 0 12 13 14 0 | - * | 0 0 18 19 20 | - * \ 0 0 0 24 25 / + * / 1 2 0 0 5 \ + * | 0 7 8 0 0 | + * | 0 0 13 14 0 | + * | 16 0 0 19 20 | + * \ 0 22 0 0 25 / */ const IndexType rows = 5; const IndexType cols = 5; - - Matrix m( rows, cols ); + DiagonalsShiftsType diagonals{-3, 0, 1, 4 }; + Matrix m( rows, cols, diagonals ); RealType value = 1; for( IndexType i = 0; i < rows; i++ ) for( IndexType j = 0; j < cols; j++ ) { - if( abs( i - j ) > 1 ) + bool found( false ); + for( IndexType k = 0; k < diagonals.getSize(); k++ ) + { + if( i + diagonals[ k ] == j ) + { + m.setElement( i, j, value++ ); + found = true; + break; + } + } + if( ! found ) { EXPECT_THROW( m.setElement( i, j, value++ ), std::logic_error ); } - else - 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 ), 0 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); - EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); EXPECT_EQ( m.getElement( 1, 1 ), 7 ); EXPECT_EQ( m.getElement( 1, 2 ), 8 ); EXPECT_EQ( m.getElement( 1, 3 ), 0 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); EXPECT_EQ( m.getElement( 2, 2 ), 13 ); EXPECT_EQ( m.getElement( 2, 3 ), 14 ); EXPECT_EQ( m.getElement( 2, 4 ), 0 ); - EXPECT_EQ( m.getElement( 3, 0 ), 0 ); + EXPECT_EQ( m.getElement( 3, 0 ), 16 ); EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); EXPECT_EQ( m.getElement( 3, 3 ), 19 ); EXPECT_EQ( m.getElement( 3, 4 ), 20 ); EXPECT_EQ( m.getElement( 4, 0 ), 0 ); - EXPECT_EQ( m.getElement( 4, 1 ), 0 ); + EXPECT_EQ( m.getElement( 4, 1 ), 22 ); EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); EXPECT_EQ( m.getElement( 4, 4 ), 25 ); } @@ -493,123 +408,137 @@ void test_AddElement() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* - * Sets up the following 6x5 matrix: + * Sets up the following 5x5 matrix: * - * / 1 2 0 0 0 \ - * | 6 7 8 0 0 | - * | 0 12 13 14 0 | - * | 0 0 18 19 20 | - * | 0 0 0 24 25 | - * \ 0 0 0 0 30 / + * / 1 2 0 0 5 \ + * | 0 7 8 0 0 | + * | 0 0 13 14 0 | + * | 0 0 0 19 20 | + * \ 0 0 0 0 25 / */ - - const IndexType rows = 6; + const IndexType rows = 5; const IndexType cols = 5; + DiagonalsShiftsType diagonals{-3, 0, 1, 4 }; + Matrix m( rows, cols, diagonals ); - Matrix m( rows, cols ); - - RealType value = 1; - for( IndexType i = 0; i < rows; i++ ) - for( IndexType j = 0; j < cols; j++ ) - { - if( abs( i - j ) <= 1 ) - m.setElement( i, j, value ); - value++; - } + RealType value = 1; + for( IndexType i = 0; i < rows; i++ ) + for( IndexType j = 0; j < cols; j++ ) + { + bool found( false ); + for( IndexType k = 0; k < diagonals.getSize(); k++ ) + { + if( i + diagonals[ k ] == j ) + { + if( j >= i ) + m.setElement( i, j, value++ ); + else value++; + found = true; + break; + } + } + if( ! found ) + { + EXPECT_THROW( m.setElement( i, j, value++ ), std::logic_error ); + } + } // Check the added elements EXPECT_EQ( m.getElement( 0, 0 ), 1 ); EXPECT_EQ( m.getElement( 0, 1 ), 2 ); EXPECT_EQ( m.getElement( 0, 2 ), 0 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); + EXPECT_EQ( m.getElement( 0, 4 ), 5 ); - EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); EXPECT_EQ( m.getElement( 1, 1 ), 7 ); EXPECT_EQ( m.getElement( 1, 2 ), 8 ); EXPECT_EQ( m.getElement( 1, 3 ), 0 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); EXPECT_EQ( m.getElement( 2, 2 ), 13 ); EXPECT_EQ( m.getElement( 2, 3 ), 14 ); EXPECT_EQ( m.getElement( 2, 4 ), 0 ); EXPECT_EQ( m.getElement( 3, 0 ), 0 ); EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); EXPECT_EQ( m.getElement( 3, 3 ), 19 ); EXPECT_EQ( m.getElement( 3, 4 ), 20 ); EXPECT_EQ( m.getElement( 4, 0 ), 0 ); EXPECT_EQ( m.getElement( 4, 1 ), 0 ); EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); EXPECT_EQ( m.getElement( 4, 4 ), 25 ); - EXPECT_EQ( m.getElement( 5, 0 ), 0 ); - EXPECT_EQ( m.getElement( 5, 1 ), 0 ); - EXPECT_EQ( m.getElement( 5, 2 ), 0 ); - EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - 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 matrix: * - * / 1 2 0 0 0 \ / 1 2 0 0 0 \ / 3 6 0 0 0 \ - * | 6 7 8 0 0 | | 3 4 5 0 0 | | 15 18 21 0 0 | - * 2 * | 0 12 13 14 0 | + | 0 6 7 8 0 | = | 0 30 33 36 0 | - * | 0 0 18 19 20 | | 0 0 9 10 11 | | 0 0 45 48 51 | - * | 0 0 0 24 25 | | 0 0 0 12 13 | | 0 0 0 60 63 | - * \ 0 0 0 0 30 / \ 0 0 0 0 14 / \ 0 0 0 0 74 / + * / 1 2 0 0 5 \ / 1 2 0 0 5 \ / 3 6 0 0 15 \ + * | 0 7 8 0 0 | | 0 7 8 0 0 | | 0 21 24 0 0 | + * 2 * | 0 0 13 14 0 | + | 0 0 13 14 0 | = | 0 0 39 42 0 | + * | 0 0 0 19 20 | | 16 0 0 19 20 | | 16 0 0 57 60 | + * \ 0 0 0 0 25 / \ 0 22 0 0 25 / \ 0 22 0 0 75 / + * */ - RealType newValue = 1; + value = 1; RealType multiplicator = 2; for( IndexType i = 0; i < rows; i++ ) for( IndexType j = 0; j < cols; j++ ) - if( abs( i - j ) <= 1 ) - m.addElement( i, j, newValue++, multiplicator ); + { + bool found( false ); + for( IndexType k = 0; k < diagonals.getSize(); k++ ) + { + if( i + diagonals[ k ] == j ) + { + m.addElement( i, j, value++, multiplicator ); + found = true; + break; + } + } + if( ! found ) + { + EXPECT_THROW( m.addElement( i, j, value++, multiplicator ), std::logic_error ); + } + } EXPECT_EQ( m.getElement( 0, 0 ), 3 ); EXPECT_EQ( m.getElement( 0, 1 ), 6 ); EXPECT_EQ( m.getElement( 0, 2 ), 0 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); + EXPECT_EQ( m.getElement( 0, 4 ), 15 ); - EXPECT_EQ( m.getElement( 1, 0 ), 15 ); - EXPECT_EQ( m.getElement( 1, 1 ), 18 ); - EXPECT_EQ( m.getElement( 1, 2 ), 21 ); + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); + EXPECT_EQ( m.getElement( 1, 1 ), 21 ); + EXPECT_EQ( m.getElement( 1, 2 ), 24 ); EXPECT_EQ( m.getElement( 1, 3 ), 0 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 30 ); - EXPECT_EQ( m.getElement( 2, 2 ), 33 ); - EXPECT_EQ( m.getElement( 2, 3 ), 36 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); + EXPECT_EQ( m.getElement( 2, 2 ), 39 ); + EXPECT_EQ( m.getElement( 2, 3 ), 42 ); EXPECT_EQ( m.getElement( 2, 4 ), 0 ); - EXPECT_EQ( m.getElement( 3, 0 ), 0 ); + EXPECT_EQ( m.getElement( 3, 0 ), 16 ); EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 45 ); - EXPECT_EQ( m.getElement( 3, 3 ), 48 ); - EXPECT_EQ( m.getElement( 3, 4 ), 51 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); + EXPECT_EQ( m.getElement( 3, 3 ), 57 ); + EXPECT_EQ( m.getElement( 3, 4 ), 60 ); EXPECT_EQ( m.getElement( 4, 0 ), 0 ); - EXPECT_EQ( m.getElement( 4, 1 ), 0 ); + EXPECT_EQ( m.getElement( 4, 1 ), 22 ); EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 60 ); - EXPECT_EQ( m.getElement( 4, 4 ), 63 ); - - EXPECT_EQ( m.getElement( 5, 0 ), 0 ); - EXPECT_EQ( m.getElement( 5, 1 ), 0 ); - EXPECT_EQ( m.getElement( 5, 2 ), 0 ); - EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - EXPECT_EQ( m.getElement( 5, 4 ), 74 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); + EXPECT_EQ( m.getElement( 4, 4 ), 75 ); } template< typename Matrix > @@ -618,58 +547,75 @@ void test_SetRow() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* - * Sets up the following 3x7 matrix: + * Sets up the following 5x7 matrix: * - * / 1 2 0 0 0 0 0 \ - * | 8 9 10 0 0 0 0 | - * \ 0 16 17 18 0 0 0 / + * / 1 0 2 0 3 0 0 \ + * | 4 5 0 6 0 7 0 | + * | 0 8 9 0 10 0 11 | + * | 0 0 12 13 0 14 0 | + * \ 0 0 0 15 16 0 17 / */ - const IndexType rows = 3; + const IndexType rows = 5; const IndexType cols = 7; - Matrix m( rows, cols ); + Matrix m( rows, cols, DiagonalsShiftsType({ -1, 0, 2, 4 }) ); auto matrix_view = m.getView(); auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { - RealType values[ 3 ][ 3 ] { - { 1, 2, 0 }, - { 8, 9, 10 }, - { 16, 17, 18 } }; + RealType values[ 5 ][ 4 ] { + { 0, 1, 2, 3 }, + { 4, 5, 6, 7 }, + { 8, 9, 10, 11 }, + { 12, 13, 14, 0 }, + { 15, 16, 17, 0 } }; auto row = matrix_view.getRow( rowIdx ); - for( IndexType i = 0; i < 3; i++ ) - { - if( rowIdx == 0 && i > 1 ) - break; + for( IndexType i = 0; i < 4; i++ ) row.setElement( i, values[ rowIdx ][ i ] ); - } }; - TNL::Algorithms::ParallelFor< DeviceType >::exec( 0, 3, f ); + TNL::Algorithms::ParallelFor< DeviceType >::exec( ( IndexType) 0, rows, f ); EXPECT_EQ( m.getElement( 0, 0 ), 1 ); - EXPECT_EQ( m.getElement( 0, 1 ), 2 ); - EXPECT_EQ( m.getElement( 0, 2 ), 0 ); + EXPECT_EQ( m.getElement( 0, 1 ), 0 ); + EXPECT_EQ( m.getElement( 0, 2 ), 2 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); - EXPECT_EQ( m.getElement( 0, 4 ), 0 ); + EXPECT_EQ( m.getElement( 0, 4 ), 3 ); EXPECT_EQ( m.getElement( 0, 5 ), 0 ); EXPECT_EQ( m.getElement( 0, 6 ), 0 ); - EXPECT_EQ( m.getElement( 1, 0 ), 8 ); - EXPECT_EQ( m.getElement( 1, 1 ), 9 ); - EXPECT_EQ( m.getElement( 1, 2 ), 10 ); - EXPECT_EQ( m.getElement( 1, 3 ), 0 ); + EXPECT_EQ( m.getElement( 1, 0 ), 4 ); + EXPECT_EQ( m.getElement( 1, 1 ), 5 ); + EXPECT_EQ( m.getElement( 1, 2 ), 0 ); + EXPECT_EQ( m.getElement( 1, 3 ), 6 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); - EXPECT_EQ( m.getElement( 1, 5 ), 0 ); + EXPECT_EQ( m.getElement( 1, 5 ), 7 ); EXPECT_EQ( m.getElement( 1, 6 ), 0 ); EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 16 ); - EXPECT_EQ( m.getElement( 2, 2 ), 17 ); - EXPECT_EQ( m.getElement( 2, 3 ), 18 ); - EXPECT_EQ( m.getElement( 2, 4 ), 0 ); + EXPECT_EQ( m.getElement( 2, 1 ), 8 ); + EXPECT_EQ( m.getElement( 2, 2 ), 9 ); + EXPECT_EQ( m.getElement( 2, 3 ), 0 ); + EXPECT_EQ( m.getElement( 2, 4 ), 10 ); EXPECT_EQ( m.getElement( 2, 5 ), 0 ); - EXPECT_EQ( m.getElement( 2, 6 ), 0 ); + EXPECT_EQ( m.getElement( 2, 6 ), 11 ); + + EXPECT_EQ( m.getElement( 3, 0 ), 0 ); + EXPECT_EQ( m.getElement( 3, 1 ), 0 ); + EXPECT_EQ( m.getElement( 3, 2 ), 12 ); + EXPECT_EQ( m.getElement( 3, 3 ), 13 ); + EXPECT_EQ( m.getElement( 3, 4 ), 0 ); + EXPECT_EQ( m.getElement( 3, 5 ), 14 ); + EXPECT_EQ( m.getElement( 3, 6 ), 0 ); + + EXPECT_EQ( m.getElement( 4, 0 ), 0 ); + EXPECT_EQ( m.getElement( 4, 1 ), 0 ); + EXPECT_EQ( m.getElement( 4, 2 ), 0 ); + EXPECT_EQ( m.getElement( 4, 3 ), 15 ); + EXPECT_EQ( m.getElement( 4, 4 ), 16 ); + EXPECT_EQ( m.getElement( 4, 5 ), 0 ); + EXPECT_EQ( m.getElement( 4, 6 ), 17 ); } template< typename Matrix > @@ -678,27 +624,31 @@ void test_AddRow() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; + /* * Sets up the following 6x5 matrix: * - * / 1 2 0 0 0 \ - * | 6 7 8 0 0 | - * | 0 12 13 14 0 | - * | 0 0 18 19 20 | - * | 0 0 0 24 25 | - * \ 0 0 0 0 30 / + * / 1 2 3 0 0 \ + * | 0 7 8 9 0 | + * | 0 0 13 14 15 | + * | 0 0 0 19 20 | + * | 0 0 0 0 25 | + * \ 0 0 0 0 0 / */ const IndexType rows = 6; const IndexType cols = 5; + DiagonalsShiftsType diagonals( { -2, 0, 1, 2 } ); - Matrix m( rows, cols ); + Matrix m( rows, cols, diagonals ); RealType value = 1; for( IndexType i = 0; i < rows; i++ ) for( IndexType j = 0; j < cols; j++ ) { - if( abs( i - j ) <= 1 ) + IndexType offset = j - i; + if( diagonals.containsValue( offset ) && offset >= 0) m.setElement( i, j, value ); value++; } @@ -706,63 +656,63 @@ void test_AddRow() // Check the added elements EXPECT_EQ( m.getElement( 0, 0 ), 1 ); EXPECT_EQ( m.getElement( 0, 1 ), 2 ); - EXPECT_EQ( m.getElement( 0, 2 ), 0 ); + EXPECT_EQ( m.getElement( 0, 2 ), 3 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); EXPECT_EQ( m.getElement( 0, 4 ), 0 ); - EXPECT_EQ( m.getElement( 1, 0 ), 6 ); + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); EXPECT_EQ( m.getElement( 1, 1 ), 7 ); EXPECT_EQ( m.getElement( 1, 2 ), 8 ); - EXPECT_EQ( m.getElement( 1, 3 ), 0 ); + EXPECT_EQ( m.getElement( 1, 3 ), 9 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 12 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); EXPECT_EQ( m.getElement( 2, 2 ), 13 ); EXPECT_EQ( m.getElement( 2, 3 ), 14 ); - EXPECT_EQ( m.getElement( 2, 4 ), 0 ); + EXPECT_EQ( m.getElement( 2, 4 ), 15 ); EXPECT_EQ( m.getElement( 3, 0 ), 0 ); EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 18 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); EXPECT_EQ( m.getElement( 3, 3 ), 19 ); EXPECT_EQ( m.getElement( 3, 4 ), 20 ); EXPECT_EQ( m.getElement( 4, 0 ), 0 ); EXPECT_EQ( m.getElement( 4, 1 ), 0 ); EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 24 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); EXPECT_EQ( m.getElement( 4, 4 ), 25 ); EXPECT_EQ( m.getElement( 5, 0 ), 0 ); EXPECT_EQ( m.getElement( 5, 1 ), 0 ); EXPECT_EQ( m.getElement( 5, 2 ), 0 ); EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - EXPECT_EQ( m.getElement( 5, 4 ), 30 ); + EXPECT_EQ( m.getElement( 5, 4 ), 0 ); // 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: * - * / 0 0 0 0 0 0 \ / 1 2 0 0 0 \ / 11 11 0 0 0 \ / 11 11 0 0 0 \ - * | 0 1 0 0 0 0 | | 6 7 8 0 0 | | 22 22 22 0 0 | | 28 29 30 0 0 | - * | 0 0 2 0 0 0 | * | 0 12 13 14 0 | + | 0 33 33 33 0 | = | 0 57 59 61 0 | - * | 0 0 0 3 0 0 | | 0 0 18 19 20 | | 0 0 44 44 44 | | 0 0 98 101 104 | - * | 0 0 0 0 4 0 | | 0 0 0 24 25 | | 0 0 0 55 55 | | 0 0 0 151 155 | - * \ 0 0 0 0 0 5 / \ 0 0 0 0 30 / \ 0 0 0 0 66 / \ 0 0 0 0 216 / + * / 0 0 0 0 0 0 \ / 1 2 3 0 0 \ / 11 0 0 0 0 \ / 11 0 0 0 0 \ + * | 0 1 0 0 0 0 | | 0 7 8 9 0 | | 0 22 0 0 0 | | 0 29 8 9 0 | + * | 0 0 2 0 0 0 | * | 0 0 13 14 15 | + | 33 0 33 0 0 | = | 33 0 59 28 30 | + * | 0 0 0 3 0 0 | | 0 0 0 19 20 | | 0 44 0 44 0 | | 0 44 0 101 60 | + * | 0 0 0 0 4 0 | | 0 0 0 0 25 | | 0 0 55 0 55 | | 0 0 55 0 155 | + * \ 0 0 0 0 0 5 / \ 0 0 0 0 0 / \ 0 0 0 66 0 / \ 0 0 0 66 0 / */ auto matrix_view = m.getView(); auto f = [=] __cuda_callable__ ( IndexType rowIdx ) mutable { - RealType values[ 6 ][ 3 ] { - { 11, 11, 0 }, - { 22, 22, 22 }, - { 33, 33, 33 }, - { 44, 44, 44 }, - { 55, 55, 55 }, - { 66, 66, 66 } }; + RealType values[ 6 ][ 4 ] { + { 0, 11, 0, 0 }, + { 0, 22, 0, 0 }, + { 33, 33, 0, 0 }, + { 44, 44, 0, 0 }, + { 55, 55, 0, 0 }, + { 66, 0, 0, 0 } }; auto row = matrix_view.getRow( rowIdx ); - for( IndexType i = 0; i < 3; i++ ) + for( IndexType i = 0; i < 4; i++ ) { RealType& val = row.getValue( i ); val = rowIdx * val + values[ rowIdx ][ i ]; @@ -770,42 +720,41 @@ void test_AddRow() }; 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, 1 ), 0 ); EXPECT_EQ( m.getElement( 0, 2 ), 0 ); EXPECT_EQ( m.getElement( 0, 3 ), 0 ); EXPECT_EQ( m.getElement( 0, 4 ), 0 ); - EXPECT_EQ( m.getElement( 1, 0 ), 28 ); + EXPECT_EQ( m.getElement( 1, 0 ), 0 ); EXPECT_EQ( m.getElement( 1, 1 ), 29 ); - EXPECT_EQ( m.getElement( 1, 2 ), 30 ); - EXPECT_EQ( m.getElement( 1, 3 ), 0 ); + EXPECT_EQ( m.getElement( 1, 2 ), 8 ); + EXPECT_EQ( m.getElement( 1, 3 ), 9 ); EXPECT_EQ( m.getElement( 1, 4 ), 0 ); - EXPECT_EQ( m.getElement( 2, 0 ), 0 ); - EXPECT_EQ( m.getElement( 2, 1 ), 57 ); + EXPECT_EQ( m.getElement( 2, 0 ), 33 ); + EXPECT_EQ( m.getElement( 2, 1 ), 0 ); EXPECT_EQ( m.getElement( 2, 2 ), 59 ); - EXPECT_EQ( m.getElement( 2, 3 ), 61 ); - EXPECT_EQ( m.getElement( 2, 4 ), 0 ); + EXPECT_EQ( m.getElement( 2, 3 ), 28 ); + EXPECT_EQ( m.getElement( 2, 4 ), 30 ); EXPECT_EQ( m.getElement( 3, 0 ), 0 ); - EXPECT_EQ( m.getElement( 3, 1 ), 0 ); - EXPECT_EQ( m.getElement( 3, 2 ), 98 ); + EXPECT_EQ( m.getElement( 3, 1 ), 44 ); + EXPECT_EQ( m.getElement( 3, 2 ), 0 ); EXPECT_EQ( m.getElement( 3, 3 ), 101 ); - EXPECT_EQ( m.getElement( 3, 4 ), 104 ); + EXPECT_EQ( m.getElement( 3, 4 ), 60 ); EXPECT_EQ( m.getElement( 4, 0 ), 0 ); EXPECT_EQ( m.getElement( 4, 1 ), 0 ); - EXPECT_EQ( m.getElement( 4, 2 ), 0 ); - EXPECT_EQ( m.getElement( 4, 3 ), 151 ); + EXPECT_EQ( m.getElement( 4, 2 ), 55 ); + EXPECT_EQ( m.getElement( 4, 3 ), 0 ); EXPECT_EQ( m.getElement( 4, 4 ), 155 ); EXPECT_EQ( m.getElement( 5, 0 ), 0 ); EXPECT_EQ( m.getElement( 5, 1 ), 0 ); EXPECT_EQ( m.getElement( 5, 2 ), 0 ); - EXPECT_EQ( m.getElement( 5, 3 ), 0 ); - EXPECT_EQ( m.getElement( 5, 4 ), 216 ); + EXPECT_EQ( m.getElement( 5, 3 ), 66 ); + EXPECT_EQ( m.getElement( 5, 4 ), 0 ); } template< typename Matrix > @@ -814,6 +763,7 @@ void test_VectorProduct() using RealType = typename Matrix::RealType; using DeviceType = typename Matrix::DeviceType; using IndexType = typename Matrix::IndexType; + using DiagonalsShiftsType = typename Matrix::DiagonalsShiftsType; /* * Sets up the following 5x4 matrix: @@ -826,8 +776,9 @@ void test_VectorProduct() */ const IndexType rows = 5; const IndexType cols = 4; + DiagonalsShiftsType diagonals{ -1, 0, 1 }; - Matrix m( rows, cols ); + Matrix m( rows, cols, diagonals ); RealType value = 1; for( IndexType i = 0; i < rows; i++ ) @@ -861,6 +812,8 @@ void test_AddMatrix() using RealType = typename Matrix1::RealType; using DeviceType = typename Matrix1::DeviceType; using IndexType = typename Matrix1::IndexType; + using DiagonalsShiftsType1 = typename Matrix1::DiagonalsShiftsType; + using DiagonalsShiftsType2 = typename Matrix2::DiagonalsShiftsType; /* * Sets up the following 5x4 matrix: @@ -873,8 +826,10 @@ void test_AddMatrix() */ const IndexType rows = 5; const IndexType cols = 4; + DiagonalsShiftsType1 diagonals1; + DiagonalsShiftsType2 diagonals2; - Matrix1 m( rows, cols ); + Matrix1 m( rows, cols, diagonals1 ); RealType value = 1; for( IndexType i = 0; i < rows; i++ ) @@ -894,7 +849,7 @@ void test_AddMatrix() * | 0 0 9 10 | * \ 0 0 0 11 / */ - Matrix2 m2( rows, cols ); + Matrix2 m2( rows, cols, diagonals2 ); RealType newValue = 1; for( IndexType i = 0; i < rows; i++ ) @@ -1457,7 +1412,7 @@ TYPED_TEST( MatrixTest, getNonemptyRowsCountTest ) test_GetNonemptyRowsCount< MatrixType >(); } -/* + TYPED_TEST( MatrixTest, getCompressedRowLengthTest ) { using MatrixType = typename TestFixture::MatrixType; @@ -1465,13 +1420,6 @@ TYPED_TEST( MatrixTest, getCompressedRowLengthTest ) test_GetCompressedRowLengths< MatrixType >(); } -TYPED_TEST( MatrixTest, getRowLengthTest ) -{ - using MatrixType = typename TestFixture::MatrixType; - - test_GetRowLength< MatrixType >(); -} - TYPED_TEST( MatrixTest, getAllocatedElementsCountTest ) { using MatrixType = typename TestFixture::MatrixType; @@ -1535,7 +1483,7 @@ TYPED_TEST( MatrixTest, vectorProductTest ) test_VectorProduct< MatrixType >(); } -TYPED_TEST( MatrixTest, addMatrixTest ) +/*TYPED_TEST( MatrixTest, addMatrixTest ) { using MatrixType = typename TestFixture::MatrixType; -- GitLab