diff --git a/src/TNL/Containers/Segments/CSR.h b/src/TNL/Containers/Segments/CSR.h index f140605590934619a644f556ad2c212daab6f2e5..ddf56b67d5594413d8f61e2c053b480734b30741 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 61720869caa418d189d105ce6f0769e0690d9b35..16e8a7763ebf2f3f62ce9c4971d7ce116cbd43c7 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 0000000000000000000000000000000000000000..3ab5ef9d2eb1afde64321a7741dc33cd54c4dcb8 --- /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 4917df9e8ea1044763136bfd2a2b644e5452ff67..3af5798f740ebc715cd0292ee2f050544802d6dd 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 dd4c434ba079030df67ca7912931b7543fb506e9..0135c8c6810dea0e36292c32915fa32e63dceaac 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 8cb430b6a4a57bf8c7733b7972a5af7b286af0f4..0ecae8e7d3e70cb2c04497b4e25b98481b1472ad 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 97d30d3147ecf266f334f9bddc0219a423d89a23..762d314dd659ea83dff076daa8d9aca3a616da7c 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 0000000000000000000000000000000000000000..7a1638e3fe82fed958f00f30c82f3d7309b0657d --- /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 6c6926be92f8cfc593fb7090dddb48acf2a6034d..185321adb2ec720b63dff65539d7745da776f7ce 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 d124633ff68f1d64230d754a6d81dd87a6fc0117..914d30a2e9a30147bae0f311398756022fadb2c6 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 946c9b642c5102248043625618fc7085303cfd73..8c01e8a28672d3ab5a1a055ac280327aec7068fb 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 c9c1d85608ec33d8a92352cda72f820e8f2fee13..1f647970415845a328b5ba29461d2fc35a50b26c 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 adcf9ef5a090dca45e052733420dcecd17e1b3b5..890814b8195dec8ddccf2fbf34a289fd8342abeb 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 66cfce19527e8453112d881b489c90b693488119..45e33b236dc46128b15b87ebb3dc8852def48071 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 558cbb5b1028a9ced91cb10324ef25d5ddb9f1e6..46c02dfb0d3ed69e9880661a983bc5ef27437989 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 8af68bd4dc02615667054a0d237e70d83e262133..3f26c95cae73c4bc3b65873c0d9a049c8be1ec64 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 0000000000000000000000000000000000000000..c6d0468f99f7ea9f6db616ea24d6fd969ad3ddf5 --- /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 0000000000000000000000000000000000000000..364bb8e2eb4e6a7780d57b16422c5544c21232a5 --- /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 847c21dd5fc6c94bf7b1109c12fae77e48bdab76..a674ee807054c7cbaa207e109c364e7bdcfb3c76 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 ffcba43dce57309f03118b95e5ea9ad75c1e31a4..3f97431248d19f06b6a8ede31683b8b0d9de117b 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,