From 8a083c49d0c3a8b6499bf53b4229e9445f5f116b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com> Date: Sat, 28 Dec 2019 22:49:57 +0100 Subject: [PATCH] Added SparseMatrixRowView. --- src/TNL/Containers/Segments/CSR.h | 5 + src/TNL/Containers/Segments/CSR.hpp | 11 +++ src/TNL/Containers/Segments/CSRSegmentView.h | 47 ++++++++++ src/TNL/Containers/Segments/CSRView.h | 5 + src/TNL/Containers/Segments/CSRView.hpp | 10 ++ src/TNL/Containers/Segments/Ellpack.h | 5 + src/TNL/Containers/Segments/Ellpack.hpp | 16 ++++ .../Containers/Segments/EllpackSegmentView.h | 49 ++++++++++ src/TNL/Containers/Segments/EllpackView.h | 5 + src/TNL/Containers/Segments/EllpackView.hpp | 15 +++ src/TNL/Containers/Segments/SlicedEllpack.h | 5 + src/TNL/Containers/Segments/SlicedEllpack.hpp | 21 +++++ .../Containers/Segments/SlicedEllpackView.h | 6 +- .../Containers/Segments/SlicedEllpackView.hpp | 20 ++++ src/TNL/Matrices/SparseMatrix.h | 22 ++++- src/TNL/Matrices/SparseMatrix.hpp | 30 ++++++ src/TNL/Matrices/SparseMatrixRowView.h | 64 +++++++++++++ src/TNL/Matrices/SparseMatrixRowView.hpp | 94 +++++++++++++++++++ src/TNL/Matrices/SparseMatrixView.h | 22 +++-- src/TNL/Matrices/SparseMatrixView.hpp | 26 +++++ 20 files changed, 466 insertions(+), 12 deletions(-) create mode 100644 src/TNL/Containers/Segments/CSRSegmentView.h create mode 100644 src/TNL/Containers/Segments/EllpackSegmentView.h create mode 100644 src/TNL/Matrices/SparseMatrixRowView.h create mode 100644 src/TNL/Matrices/SparseMatrixRowView.hpp diff --git a/src/TNL/Containers/Segments/CSR.h b/src/TNL/Containers/Segments/CSR.h index f140605590..ddf56b67d5 100644 --- a/src/TNL/Containers/Segments/CSR.h +++ b/src/TNL/Containers/Segments/CSR.h @@ -14,6 +14,7 @@ #include <TNL/Containers/Vector.h> #include <TNL/Containers/Segments/CSRView.h> +#include <TNL/Containers/Segments/CSRSegmentView.h> namespace TNL { namespace Containers { @@ -34,6 +35,7 @@ class CSR using ViewTemplate = CSRView< Device_, Index_ >; using ViewType = CSRView< Device, Index >; using ConstViewType = CSRView< Device, std::add_const_t< Index > >; + using SegmentView = CSRSegmentView< IndexType >; CSR(); @@ -83,6 +85,9 @@ class CSR __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/CSR.hpp b/src/TNL/Containers/Segments/CSR.hpp index 61720869ca..16e8a7763e 100644 --- a/src/TNL/Containers/Segments/CSR.hpp +++ b/src/TNL/Containers/Segments/CSR.hpp @@ -158,6 +158,17 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index, + typename IndexAllocator > +__cuda_callable__ +auto +CSR< Device, Index, IndexAllocator >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + return SegmentView( offsets[ segmentIdx ], offsets[ segmentIdx + 1 ] - offsets[ segmentIdx ] ); +} + template< typename Device, typename Index, typename IndexAllocator > diff --git a/src/TNL/Containers/Segments/CSRSegmentView.h b/src/TNL/Containers/Segments/CSRSegmentView.h new file mode 100644 index 0000000000..3ab5ef9d2e --- /dev/null +++ b/src/TNL/Containers/Segments/CSRSegmentView.h @@ -0,0 +1,47 @@ +/*************************************************************************** + CSRSegmentView.h - description + ------------------- + begin : Dec 28, 2019 + copyright : (C) 2019 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +namespace TNL { + namespace Containers { + namespace Segments { + +template< typename Index > +class CSRSegmentView +{ + public: + + using IndexType = Index; + + __cuda_callable__ + CSRSegmentView( const IndexType offset, const IndexType size ) + : segmentOffset( offset ), segmentSize( size ){}; + + __cuda_callable__ + IndexType getSize() const + { + return this->segmentSize; + }; + + __cuda_callable__ + IndexType getGlobalIndex( const IndexType localIndex ) const + { + TNL_ASSERT_LT( localIndex, segmentSize, "Local index exceeds segment bounds." ); + return segmentOffset + localIndex; + }; + + protected: + + IndexType segmentOffset, segmentSize; +}; + } //namespace Segments + } //namespace Containers +} //namespace TNL \ No newline at end of file diff --git a/src/TNL/Containers/Segments/CSRView.h b/src/TNL/Containers/Segments/CSRView.h index 4917df9e8e..3af5798f74 100644 --- a/src/TNL/Containers/Segments/CSRView.h +++ b/src/TNL/Containers/Segments/CSRView.h @@ -13,6 +13,7 @@ #include <type_traits> #include <TNL/Containers/Vector.h> +#include <TNL/Containers/Segments/CSRSegmentView.h> namespace TNL { namespace Containers { @@ -32,6 +33,7 @@ class CSRView template< typename Device_, typename Index_ > using ViewTemplate = CSRView< Device_, Index_ >; using ConstViewType = CSRView< Device, std::add_const_t< Index > >; + using SegmentView = CSRSegmentView< IndexType >; __cuda_callable__ CSRView(); @@ -82,6 +84,9 @@ class CSRView __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/CSRView.hpp b/src/TNL/Containers/Segments/CSRView.hpp index dd4c434ba0..0135c8c681 100644 --- a/src/TNL/Containers/Segments/CSRView.hpp +++ b/src/TNL/Containers/Segments/CSRView.hpp @@ -149,6 +149,16 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index > +__cuda_callable__ +auto +CSRView< Device, Index >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + return SegmentView( offsets[ segmentIdx ], offsets[ segmentIdx + 1 ] - offsets[ segmentIdx ] ); +} + template< typename Device, typename Index > template< typename Function, typename... Args > diff --git a/src/TNL/Containers/Segments/Ellpack.h b/src/TNL/Containers/Segments/Ellpack.h index 8cb430b6a4..0ecae8e7d3 100644 --- a/src/TNL/Containers/Segments/Ellpack.h +++ b/src/TNL/Containers/Segments/Ellpack.h @@ -12,6 +12,7 @@ #include <TNL/Containers/Vector.h> #include <TNL/Containers/Segments/EllpackView.h> +#include <TNL/Containers/Segments/EllpackSegmentView.h> namespace TNL { namespace Containers { @@ -36,6 +37,7 @@ class Ellpack using ViewTemplate = EllpackView< Device_, Index_ >; using ViewType = EllpackView< Device, Index, RowMajorOrder, Alignment >; //using ConstViewType = EllpackView< Device, std::add_const_t< Index >, RowMajorOrder, Alignment >; + using SegmentView = EllpackSegmentView< IndexType >; Ellpack(); @@ -80,6 +82,9 @@ class Ellpack __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/Ellpack.hpp b/src/TNL/Containers/Segments/Ellpack.hpp index 97d30d3147..762d314dd6 100644 --- a/src/TNL/Containers/Segments/Ellpack.hpp +++ b/src/TNL/Containers/Segments/Ellpack.hpp @@ -216,6 +216,22 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index, + typename IndexAllocator, + bool RowMajorOrder, + int Alignment > +__cuda_callable__ +auto +Ellpack< Device, Index, IndexAllocator, RowMajorOrder, Alignment >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + if( RowMajorOrder ) + return SegmentView( segmentIdx * this->segmentSize, this->segmentSize, 1 ); + else + return SegmentView( segmentIdx, this->segmentSize, this->alignedSize ); +} + template< typename Device, typename Index, typename IndexAllocator, diff --git a/src/TNL/Containers/Segments/EllpackSegmentView.h b/src/TNL/Containers/Segments/EllpackSegmentView.h new file mode 100644 index 0000000000..7a1638e3fe --- /dev/null +++ b/src/TNL/Containers/Segments/EllpackSegmentView.h @@ -0,0 +1,49 @@ +/*************************************************************************** + EllpackSegmentView.h - description + ------------------- + begin : Dec 28, 2019 + copyright : (C) 2019 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +namespace TNL { + namespace Containers { + namespace Segments { + +template< typename Index > +class EllpackSegmentView +{ + public: + + using IndexType = Index; + + __cuda_callable__ + EllpackSegmentView( const IndexType offset, + const IndexType size, + const IndexType step ) + : segmentOffset( offset ), segmentSize( size ), step( step ){}; + + __cuda_callable__ + IndexType getSize() const + { + return this->segmentSize; + }; + + __cuda_callable__ + IndexType getGlobalIndex( const IndexType localIndex ) const + { + TNL_ASSERT_LT( localIndex, segmentSize, "Local index exceeds segment bounds." ); + return segmentOffset + localIndex * step; + }; + + protected: + + IndexType segmentOffset, segmentSize, step; +}; + } //namespace Segments + } //namespace Containers +} //namespace TNL diff --git a/src/TNL/Containers/Segments/EllpackView.h b/src/TNL/Containers/Segments/EllpackView.h index 6c6926be92..185321adb2 100644 --- a/src/TNL/Containers/Segments/EllpackView.h +++ b/src/TNL/Containers/Segments/EllpackView.h @@ -13,6 +13,7 @@ #include <type_traits> #include <TNL/Containers/Vector.h> +#include <TNL/Containers/Segments/EllpackSegmentView.h> namespace TNL { @@ -37,6 +38,7 @@ class EllpackView using ViewTemplate = EllpackView< Device_, Index_ >; using ViewType = EllpackView; //using ConstViewType = EllpackView< Device, std::add_const_t< Index > >; + using SegmentView = EllpackSegmentView< IndexType >; __cuda_callable__ EllpackView(); @@ -75,6 +77,9 @@ class EllpackView __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/EllpackView.hpp b/src/TNL/Containers/Segments/EllpackView.hpp index d124633ff6..914d30a2e9 100644 --- a/src/TNL/Containers/Segments/EllpackView.hpp +++ b/src/TNL/Containers/Segments/EllpackView.hpp @@ -160,6 +160,21 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index, + bool RowMajorOrder, + int Alignment > +__cuda_callable__ +auto +EllpackView< Device, Index, RowMajorOrder, Alignment >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + if( RowMajorOrder ) + return SegmentView( segmentIdx * this->segmentSize, this->segmentSize, 1 ); + else + return SegmentView( segmentIdx, this->segmentSize, this->alignedSize ); +} + template< typename Device, typename Index, bool RowMajorOrder, diff --git a/src/TNL/Containers/Segments/SlicedEllpack.h b/src/TNL/Containers/Segments/SlicedEllpack.h index 946c9b642c..8c01e8a286 100644 --- a/src/TNL/Containers/Segments/SlicedEllpack.h +++ b/src/TNL/Containers/Segments/SlicedEllpack.h @@ -12,6 +12,7 @@ #include <TNL/Containers/Vector.h> #include <TNL/Containers/Segments/SlicedEllpackView.h> +#include <TNL/Containers/Segments/EllpackSegmentView.h> namespace TNL { namespace Containers { @@ -35,6 +36,7 @@ class SlicedEllpack template< typename Device_, typename Index_ > using ViewTemplate = SlicedEllpackView< Device_, Index_ >; using ConstViewType = SlicedEllpackView< Device, std::add_const_t< Index >, RowMajorOrder, SliceSize >; + using SegmentView = EllpackSegmentView< IndexType >; SlicedEllpack(); @@ -76,6 +78,9 @@ class SlicedEllpack __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/SlicedEllpack.hpp b/src/TNL/Containers/Segments/SlicedEllpack.hpp index c9c1d85608..1f64797041 100644 --- a/src/TNL/Containers/Segments/SlicedEllpack.hpp +++ b/src/TNL/Containers/Segments/SlicedEllpack.hpp @@ -241,6 +241,27 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index, + typename IndexAllocator, + bool RowMajorOrder, + int SliceSize > +__cuda_callable__ +auto +SlicedEllpack< Device, Index, IndexAllocator, RowMajorOrder, SliceSize >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + const IndexType sliceIdx = segmentIdx / SliceSize; + const IndexType segmentInSliceIdx = segmentIdx % SliceSize; + const IndexType& sliceOffset = this->sliceOffsets[ sliceIdx ]; + const IndexType& segmentSize = this->sliceSegmentSizes[ sliceIdx ]; + + if( RowMajorOrder ) + return SegmentView( sliceOffset, segmentSize, 1 ); + else + return SegmentView( sliceOffset + segmentInSliceIdx, segmentSize, SliceSize ); +} + template< typename Device, typename Index, typename IndexAllocator, diff --git a/src/TNL/Containers/Segments/SlicedEllpackView.h b/src/TNL/Containers/Segments/SlicedEllpackView.h index adcf9ef5a0..890814b819 100644 --- a/src/TNL/Containers/Segments/SlicedEllpackView.h +++ b/src/TNL/Containers/Segments/SlicedEllpackView.h @@ -13,6 +13,7 @@ #include <type_traits> #include <TNL/Containers/Vector.h> +#include <TNL/Containers/Segments/EllpackSegmentView.h> namespace TNL { namespace Containers { @@ -35,6 +36,7 @@ class SlicedEllpackView using ViewTemplate = SlicedEllpackView< Device_, Index_ >; using ViewType = SlicedEllpackView; using ConstViewType = SlicedEllpackView< Device, std::add_const_t< Index > >; + using SegmentView = EllpackSegmentView< IndexType >; __cuda_callable__ SlicedEllpackView(); @@ -68,7 +70,6 @@ class SlicedEllpackView __cuda_callable__ IndexType getSize() const; - __cuda_callable__ IndexType getStorageSize() const; @@ -78,6 +79,9 @@ class SlicedEllpackView __cuda_callable__ void getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localIdx ) const; + __cuda_callable__ + SegmentView getSegmentView( const IndexType segmentIdx ) const; + /*** * \brief Go over all segments and for each segment element call * function 'f' with arguments 'args'. The return type of 'f' is bool. diff --git a/src/TNL/Containers/Segments/SlicedEllpackView.hpp b/src/TNL/Containers/Segments/SlicedEllpackView.hpp index 66cfce1952..45e33b236d 100644 --- a/src/TNL/Containers/Segments/SlicedEllpackView.hpp +++ b/src/TNL/Containers/Segments/SlicedEllpackView.hpp @@ -196,6 +196,26 @@ getSegmentAndLocalIndex( const Index globalIdx, Index& segmentIdx, Index& localI { } +template< typename Device, + typename Index, + bool RowMajorOrder, + int SliceSize > +__cuda_callable__ +auto +SlicedEllpackView< Device, Index, RowMajorOrder, SliceSize >:: +getSegmentView( const IndexType segmentIdx ) const -> SegmentView +{ + const IndexType sliceIdx = segmentIdx / SliceSize; + const IndexType segmentInSliceIdx = segmentIdx % SliceSize; + const IndexType& sliceOffset = this->sliceOffsets[ sliceIdx ]; + const IndexType& segmentSize = this->sliceSegmentSizes[ sliceIdx ]; + + if( RowMajorOrder ) + return SegmentView( sliceOffset, segmentSize, 1 ); + else + return SegmentView( sliceOffset + segmentInSliceIdx, segmentSize, SliceSize ); +} + template< typename Device, typename Index, bool RowMajorOrder, diff --git a/src/TNL/Matrices/SparseMatrix.h b/src/TNL/Matrices/SparseMatrix.h index 558cbb5b10..46c02dfb0d 100644 --- a/src/TNL/Matrices/SparseMatrix.h +++ b/src/TNL/Matrices/SparseMatrix.h @@ -15,6 +15,7 @@ #include <TNL/Allocators/Default.h> #include <TNL/Containers/Segments/CSR.h> #include <TNL/Matrices/SparseMatrixView.h> +#include <TNL/Matrices/SparseMatrixRowView.h> namespace TNL { namespace Matrices { @@ -36,6 +37,7 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > using SegmentsType = Segments< Device, Index, IndexAllocator >; template< typename Device_, typename Index_ > using SegmentsViewTemplate = typename SegmentsType::ViewTemplate< Device_, Index >; + using SegmentViewType = typename SegmentsType::ViewType; using DeviceType = Device; using IndexType = Index; using RealAllocatorType = RealAllocator; @@ -47,6 +49,7 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > using ColumnsVectorType = Containers::Vector< IndexType, DeviceType, IndexType, IndexAllocatorType >; using ViewType = SparseMatrixView< Real, Device, Index, MatrixType, SegmentsViewTemplate >; using ConstViewType = SparseMatrixView< typename std::add_const< Real >::type, Device, Index, MatrixType, SegmentsViewTemplate >; + using RowView = SparseMatrixRowView< RealType, SegmentViewType >; // TODO: remove this - it is here only for compatibility with original matrix implementation typedef Containers::Vector< IndexType, DeviceType, IndexType > CompressedRowLengthsVector; @@ -104,6 +107,12 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > void reset(); __cuda_callable__ + const RowView getRow( const IndexType& rowIdx ) const; + + __cuda_callable__ + RowView getRow( const IndexType& rowIdx ); + + [[deprecated("")]] __cuda_callable__ bool setElementFast( const IndexType row, const IndexType column, const RealType& value ); @@ -112,37 +121,40 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > const IndexType column, const RealType& value ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool addElementFast( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); + [[deprecated("")]] bool addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool setRowFast( const IndexType row, const IndexType* columnIndexes, const RealType* values, const IndexType elements ); + [[deprecated("")]] bool setRow( const IndexType row, const IndexType* columnIndexes, const RealType* values, const IndexType elements ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool addRowFast( const IndexType row, const IndexType* columns, const RealType* values, const IndexType numberOfElements, const RealType& thisElementMultiplicator = 1.0 ); + [[deprecated("")]] bool addRow( const IndexType row, const IndexType* columns, const RealType* values, @@ -150,14 +162,14 @@ class SparseMatrix : public Matrix< Real, Device, Index, RealAllocator > const RealType& thisElementMultiplicator = 1.0 ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ RealType getElementFast( const IndexType row, const IndexType column ) const; RealType getElement( const IndexType row, const IndexType column ) const; - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ void getRowFast( const IndexType row, IndexType* columns, RealType* values ) const; diff --git a/src/TNL/Matrices/SparseMatrix.hpp b/src/TNL/Matrices/SparseMatrix.hpp index 8af68bd4dc..3f26c95cae 100644 --- a/src/TNL/Matrices/SparseMatrix.hpp +++ b/src/TNL/Matrices/SparseMatrix.hpp @@ -303,6 +303,36 @@ reset() } +template< typename Real, + typename Device, + typename Index, + typename MatrixType, + template< typename, typename, typename > class Segments, + typename RealAllocator, + typename IndexAllocator > +__cuda_callable__ auto +SparseMatrix< Real, Device, Index, MatrixType, Segments, RealAllocator, IndexAllocator >:: +getRow( const IndexType& rowIdx ) const -> const RowView +{ + TNL_ASSERT_LT( rowIdx, this->getRows(), "Row index is larger than number of matrix rows." ); + return RowView( this->segments.getSegmentView( rowIdx ), this->values.getView(), this->columnIndexes.getView() ); +} + +template< typename Real, + typename Device, + typename Index, + typename MatrixType, + template< typename, typename, typename > class Segments, + typename RealAllocator, + typename IndexAllocator > +__cuda_callable__ auto +SparseMatrix< Real, Device, Index, MatrixType, Segments, RealAllocator, IndexAllocator >:: +getRow( const IndexType& rowIdx ) -> RowView +{ + TNL_ASSERT_LT( rowIdx, this->getRows(), "Row index is larger than number of matrix rows." ); + return RowView( this->segments.getSegmentView( rowIdx ), this->values.getView(), this->columnIndexes.getView() ); +} + template< typename Real, typename Device, typename Index, diff --git a/src/TNL/Matrices/SparseMatrixRowView.h b/src/TNL/Matrices/SparseMatrixRowView.h new file mode 100644 index 0000000000..c6d0468f99 --- /dev/null +++ b/src/TNL/Matrices/SparseMatrixRowView.h @@ -0,0 +1,64 @@ +/*************************************************************************** + SparseMatrixRowView.h - description + ------------------- + begin : Dec 28, 2019 + copyright : (C) 2019 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +namespace TNL { + namespace Matrices { + +template< typename Real, + typename SegmentView > +class SparseMatrixRowView +{ + public: + + using RealType = Real; + using SegmentViewType = SegmentView; + using DeviceType = typename SegmentViewType::DeviceType; + using IndexType = typename SegmentViewType::IndexType; + using ValuesView = Containers::VectorView< RealType, DeviceType, IndexType >; + using ColumnIndexesView = Containers::VectorView< IndexType, DeviceType, IndexType >; + + __cuda_callable__ + SparseMatrixRowView( const SegmentView& segmentView, + const ValuesView& values, + const ColumnIndexesView& columnIndexes ); + + __cuda_callable__ + IndexType getSize() const; + + __cuda_callable__ + const IndexType& getColumnIndex( const IndexType localIdx ) const; + + __cuda_callable__ + IndexType& getColumnIndex( const IndexType localIdx ); + + __cuda_callable__ + const RealType& getValue( const IndexType localIdx ) const; + + __cuda_callable__ + RealType& getValue( const IndexType localIdx ); + + __cuda_callable__ + void setElement( const IndexType localIdx, + const IndexType column, + const RealType& value ); + protected: + + SegmentView segmentView; + + ValuesView values; + + ColumnIndexesView columnIndexes; +}; + } // namespace Matrices +} // namespace TNL + +#include <TNL/Matrices/SparseMatrixRowView.hpp> diff --git a/src/TNL/Matrices/SparseMatrixRowView.hpp b/src/TNL/Matrices/SparseMatrixRowView.hpp new file mode 100644 index 0000000000..364bb8e2eb --- /dev/null +++ b/src/TNL/Matrices/SparseMatrixRowView.hpp @@ -0,0 +1,94 @@ +/*************************************************************************** + SparseMatrixRowView.hpp - description + ------------------- + begin : Dec 28, 2019 + copyright : (C) 2019 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Matrices/SparseMatrixRowView.h> + +namespace TNL { + namespace Matrices { + +template< typename Real, + typename SegmentView > +__cuda_callable__ +SparseMatrixRowView< Real, SegmentView >:: +SparseMatrixRowView( const SegmentView& segmentView, + const ValuesView& values, + const ColumnIndexesView& columnIndexes ) + : segmentView( segmentView ), values( values ), columnIndexes( columnIndexes ) +{ +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ auto +SparseMatrixRowView< Real, SegmentView >:: +getSize() const -> IndexType +{ + return segmentView.getSize(); +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ auto +SparseMatrixRowView< Real, SegmentView >:: +getColumnIndex( const IndexType localIdx ) const -> const IndexType& +{ + TNL_ASSERT_LT( localIdx, this->getSize(), "Local index exceeds matrix row capacity." ); + return columnIndexes[ segmentView.getGlobalIndex( localIdx ) ]; +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ auto +SparseMatrixRowView< Real, SegmentView >:: +getColumnIndex( const IndexType localIdx ) -> IndexType& +{ + TNL_ASSERT_LT( localIdx, this->getSize(), "Local index exceeds matrix row capacity." ); + return columnIndexes[ segmentView.getGlobalIndex( localIdx ) ]; +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ auto +SparseMatrixRowView< Real, SegmentView >:: +getValue( const IndexType localIdx ) const -> const RealType& +{ + TNL_ASSERT_LT( localIdx, this->getSize(), "Local index exceeds matrix row capacity." ); + return values[ segmentView.getGlobalIndex( localIdx ) ]; +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ auto +SparseMatrixRowView< Real, SegmentView >:: +getValue( const IndexType localIdx ) -> RealType& +{ + TNL_ASSERT_LT( localIdx, this->getSize(), "Local index exceeds matrix row capacity." ); + return values[ segmentView.getGlobalIndex( localIdx ) ]; +} + +template< typename Real, + typename SegmentView > +__cuda_callable__ void +SparseMatrixRowView< Real, SegmentView >:: +setElement( const IndexType localIdx, + const IndexType column, + const RealType& value ) +{ + TNL_ASSERT_LT( localIdx, this->getSize(), "Local index exceeds matrix row capacity." ); + const IndexType globalIdx = segmentView.getGlobalIndex( localIdx ); + columnIndexes[ globalIdx ] = column; + values[ globalIdx ] = value; +} + + + } // namespace Matrices +} // namespace TNL diff --git a/src/TNL/Matrices/SparseMatrixView.h b/src/TNL/Matrices/SparseMatrixView.h index 847c21dd5f..a674ee8070 100644 --- a/src/TNL/Matrices/SparseMatrixView.h +++ b/src/TNL/Matrices/SparseMatrixView.h @@ -14,6 +14,7 @@ #include <TNL/Matrices/MatrixType.h> #include <TNL/Allocators/Default.h> #include <TNL/Containers/Segments/CSR.h> +#include <TNL/Matrices/SparseMatrixRowView.h> namespace TNL { namespace Matrices { @@ -39,7 +40,7 @@ class SparseMatrixView : public MatrixView< Real, Device, Index > using ColumnsViewType = Containers::VectorView< IndexType, DeviceType, IndexType >; using ViewType = SparseMatrixView< typename std::remove_const< Real >::type, Device, Index, MatrixType, SegmentsViewTemplate >; using ConstViewType = SparseMatrixView< typename std::add_const< Real >::type, Device, Index, MatrixType, SegmentsViewTemplate >; - + using RowView = SparseMatrixRowView< RealType, SegmentsViewType >; // TODO: remove this - it is here only for compatibility with original matrix implementation typedef Containers::Vector< IndexType, DeviceType, IndexType > CompressedRowLengthsVector; @@ -92,6 +93,12 @@ class SparseMatrixView : public MatrixView< Real, Device, Index > void reset(); __cuda_callable__ + const RowView getRow( const IndexType& rowIdx ) const; + + __cuda_callable__ + RowView getRow( const IndexType& rowIdx ); + + [[deprecated("")]] __cuda_callable__ bool setElementFast( const IndexType row, const IndexType column, const RealType& value ); @@ -100,37 +107,40 @@ class SparseMatrixView : public MatrixView< Real, Device, Index > const IndexType column, const RealType& value ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool addElementFast( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); + [[deprecated("")]] bool addElement( const IndexType row, const IndexType column, const RealType& value, const RealType& thisElementMultiplicator = 1.0 ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool setRowFast( const IndexType row, const IndexType* columnIndexes, const RealType* values, const IndexType elements ); + [[deprecated("")]] bool setRow( const IndexType row, const IndexType* columnIndexes, const RealType* values, const IndexType elements ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ bool addRowFast( const IndexType row, const IndexType* columns, const RealType* values, const IndexType numberOfElements, const RealType& thisElementMultiplicator = 1.0 ); + [[deprecated("")]] bool addRow( const IndexType row, const IndexType* columns, const RealType* values, @@ -138,14 +148,14 @@ class SparseMatrixView : public MatrixView< Real, Device, Index > const RealType& thisElementMultiplicator = 1.0 ); - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ RealType getElementFast( const IndexType row, const IndexType column ) const; RealType getElement( const IndexType row, const IndexType column ) const; - __cuda_callable__ + [[deprecated("")]] __cuda_callable__ void getRowFast( const IndexType row, IndexType* columns, RealType* values ) const; diff --git a/src/TNL/Matrices/SparseMatrixView.hpp b/src/TNL/Matrices/SparseMatrixView.hpp index ffcba43dce..3f97431248 100644 --- a/src/TNL/Matrices/SparseMatrixView.hpp +++ b/src/TNL/Matrices/SparseMatrixView.hpp @@ -211,6 +211,32 @@ reset() } +template< typename Real, + typename Device, + typename Index, + typename MatrixType, + template< typename, typename > class SegmentsView > +__cuda_callable__ auto +SparseMatrixView< Real, Device, Index, MatrixType, SegmentsView >:: +getRow( const IndexType& rowIdx ) const -> const RowView +{ + TNL_ASSERT_LT( rowIdx, this->getRows(), "Row index is larger than number of matrix rows." ); + return RowView( this->segments.getSegmentView( rowIdx ), this->values.getView(), this->columnIndexes.getView() ); +} + +template< typename Real, + typename Device, + typename Index, + typename MatrixType, + template< typename, typename > class SegmentsView > +__cuda_callable__ auto +SparseMatrixView< Real, Device, Index, MatrixType, SegmentsView >:: +getRow( const IndexType& rowIdx ) -> RowView +{ + TNL_ASSERT_LT( rowIdx, this->getRows(), "Row index is larger than number of matrix rows." ); + return RowView( this->segments.getSegmentView( rowIdx ), this->values.getView(), this->columnIndexes.getView() ); +} + template< typename Real, typename Device, typename Index, -- GitLab