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