Commit 1ac668ec authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Refactoring SparseMatrixTest.

parent 3b631afc
Loading
Loading
Loading
Loading
+925 −1315
Original line number Diff line number Diff line
/***************************************************************************
                          SparseMatrixTest_impl.h -  description
                          SparseMatrixTest.h -  description
                             -------------------
    begin                : Nov 22, 2018
    copyright            : (C) 2018 by Tomas Oberhuber et al.
@@ -13,11 +13,7 @@
#include <TNL/Math.h>
#include <TNL/Algorithms/ParallelFor.h>
#include <iostream>

// Temporary, until test_OperatorEquals doesn't work for all formats.
#include <TNL/Matrices/Legacy/ChunkedEllpack.h>
#include <TNL/Matrices/Legacy/AdEllpack.h>
#include <TNL/Matrices/Legacy/BiEllpack.h>
#include <sstream>

#ifdef HAVE_GTEST
#include <gtest/gtest.h>
@@ -67,12 +63,10 @@ void test_SetCompressedRowLengths()
   const IndexType rows = 10;
   const IndexType cols = 11;

    Matrix m;
    m.reset();
    m.setDimensions( rows, cols );
   Matrix m( rows, cols );
   typename Matrix::CompressedRowLengthsVector rowLengths;
   rowLengths.setSize( rows );
    rowLengths.setValue( 3 );
   rowLengths = 3;

   IndexType rowLength = 1;
   for( IndexType i = 2; i < rows; i++ )
@@ -129,17 +123,11 @@ void test_SetLike()
   const IndexType rows = 8;
   const IndexType cols = 7;

    Matrix1 m1;
    m1.reset();
    m1.setDimensions( rows + 1, cols + 2 );

    Matrix2 m2;
    m2.reset();
    m2.setDimensions( rows, cols );
   Matrix1 m1( rows + 1, cols + 2 );
   Matrix2 m2( rows, cols );

   m1.setLike( m2 );


   EXPECT_EQ( m1.getRows(), m2.getRows() );
   EXPECT_EQ( m1.getColumns(), m2.getColumns() );
}
@@ -169,23 +157,9 @@ void test_GetNumberOfNonzeroMatrixElements()
   const IndexType rows = 10;
   const IndexType cols = 10;

   Matrix m;
   m.reset();

   m.setDimensions( rows, cols );
   Matrix m( rows, cols );

   typename Matrix::CompressedRowLengthsVector rowLengths;
   rowLengths.setSize( rows );
   rowLengths.setElement( 0, 4 );
   rowLengths.setElement( 1, 3 );
   rowLengths.setElement( 2, 8 );
   rowLengths.setElement( 3, 2 );
   for( IndexType i = 4; i < rows - 2; i++ )
   {
      rowLengths.setElement( i, 1 );
   }
   rowLengths.setElement( 8, 10 );
   rowLengths.setElement( 9, 10 );
   typename Matrix::CompressedRowLengthsVector rowLengths{ 4, 3, 8, 2, 1, 1, 1, 1, 10, 10 };
   m.setCompressedRowLengths( rowLengths );

   RealType value = 1;
@@ -205,10 +179,8 @@ void test_GetNumberOfNonzeroMatrixElements()
      m.setElement( i, 0, value++ );

   for( IndexType j = 8; j < rows; j++)
   {
      for( IndexType i = 0; i < cols; i++ )
         m.setElement( j, i, value++ );
   }

   EXPECT_EQ( m.getNumberOfNonzeroMatrixElements(), 41 );
}
@@ -233,12 +205,9 @@ void test_Reset()
   const IndexType rows = 5;
   const IndexType cols = 4;

    Matrix m;
    m.setDimensions( rows, cols );

   Matrix m( rows, cols );
   m.reset();


   EXPECT_EQ( m.getRows(), 0 );
   EXPECT_EQ( m.getColumns(), 0 );
}
@@ -270,18 +239,7 @@ void test_GetRow()

   Matrix m( rows, cols );

    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( rows );
    rowLengths.setElement( 0, 4 );
    rowLengths.setElement( 1, 3 );
    rowLengths.setElement( 2, 8 );
    rowLengths.setElement( 3, 2 );
    for( IndexType i = 4; i < rows - 2; i++ )
    {
        rowLengths.setElement( i, 1 );
    }
    rowLengths.setElement( 8, 10 );
    rowLengths.setElement( 9, 10 );
   typename Matrix::CompressedRowLengthsVector rowLengths{ 4, 3, 8, 2, 1, 1, 1, 1, 10, 10 };
   m.setCompressedRowLengths( rowLengths );

   auto matrixView = m.getView();
@@ -478,18 +436,7 @@ void test_SetElement()

   m.setDimensions( rows, cols );

    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( rows );
    rowLengths.setElement( 0, 4 );
    rowLengths.setElement( 1, 3 );
    rowLengths.setElement( 2, 8 );
    rowLengths.setElement( 3, 2 );
    for( IndexType i = 4; i < rows - 2; i++ )
    {
        rowLengths.setElement( i, 1 );
    }
    rowLengths.setElement( 8, 10 );
    rowLengths.setElement( 9, 10 );
   typename Matrix::CompressedRowLengthsVector rowLengths { 4, 3, 8, 2, 1, 1, 1, 1, 10, 10 };
   m.setCompressedRowLengths( rowLengths );

   RealType value = 1;
@@ -509,10 +456,8 @@ void test_SetElement()
      m.setElement( i, 0, value++ );

   for( IndexType j = 8; j < rows; j++)
    {
      for( IndexType i = 0; i < cols; i++ )
         m.setElement( j, i, value++ );
    }

   EXPECT_EQ( m.getElement( 0, 0 ),  1 );
   EXPECT_EQ( m.getElement( 0, 1 ),  0 );
@@ -646,12 +591,9 @@ void test_AddElement()
   const IndexType rows = 6;
   const IndexType cols = 5;

    Matrix m;
    m.reset();
    m.setDimensions( rows, cols );
    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( rows );
    rowLengths.setValue( 3 );
   Matrix m( rows, cols );
   typename Matrix::CompressedRowLengthsVector rowLengths( rows );
   rowLengths = 3;
   m.setCompressedRowLengths( rowLengths );

   RealType value = 1;
@@ -709,18 +651,6 @@ void test_AddElement()
   EXPECT_EQ( m.getElement( 5, 4 ),  0 );

   // Add new elements to the old elements with a multiplying factor applied to the old elements.

/*
 * Sets up the following 6x5 sparse matrix:
 *
 *    /  1  2  3  0  0 \
 *    |  0  4  5  6  0 |
 *    |  0  0  7  8  9 |
 *    | 10  0  0  0  0 |
 *    |  0 11  0  0  0 |
 *    \  0  0  0 12  0 /
 */

   /*
    * The following setup results in the following 6x5 sparse matrix:
    *
@@ -849,7 +779,6 @@ void test_VectorProduct()
   EXPECT_EQ( outVector_1.getElement( 2 ),  8 );
   EXPECT_EQ( outVector_1.getElement( 3 ), 10 );


   /*
    * Sets up the following 4x4 sparse matrix:
    *
@@ -862,14 +791,11 @@ void test_VectorProduct()
   const IndexType m_rows_2 = 4;
   const IndexType m_cols_2 = 4;

    Matrix m_2;
    m_2.reset();
    m_2.setDimensions( m_rows_2, m_cols_2 );
    typename Matrix::CompressedRowLengthsVector rowLengths_2;
    rowLengths_2.setSize( m_rows_2 );
    rowLengths_2.setValue( 3 );
   Matrix m_2( m_rows_2, m_cols_2 );
   typename Matrix::CompressedRowLengthsVector rowLengths_2{ 3, 1, 3, 1 };
   /*rowLengths_2 = 3;
   rowLengths_2.setElement( 1, 1 );
    rowLengths_2.setElement( 3, 1 );
   rowLengths_2.setElement( 3, 1 );*/
   m_2.setCompressedRowLengths( rowLengths_2 );

   RealType value_2 = 1;
@@ -894,16 +820,13 @@ void test_VectorProduct()
   for( IndexType j = 0; j < outVector_2.getSize(); j++ )
      outVector_2.setElement( j, 0 );


   m_2.vectorProduct( inVector_2, outVector_2 );


   EXPECT_EQ( outVector_2.getElement( 0 ), 12 );
   EXPECT_EQ( outVector_2.getElement( 1 ),  8 );
   EXPECT_EQ( outVector_2.getElement( 2 ), 36 );
   EXPECT_EQ( outVector_2.getElement( 3 ), 16 );


   /*
    * Sets up the following 4x4 sparse matrix:
    *
@@ -916,12 +839,8 @@ void test_VectorProduct()
   const IndexType m_rows_3 = 4;
   const IndexType m_cols_3 = 4;

    Matrix m_3;
    m_3.reset();
    m_3.setDimensions( m_rows_3, m_cols_3 );
    typename Matrix::CompressedRowLengthsVector rowLengths_3;
    rowLengths_3.setSize( m_rows_3 );
    rowLengths_3.setValue( 3 );
   Matrix m_3( m_rows_3, m_cols_3 );
   typename Matrix::CompressedRowLengthsVector rowLengths_3{ 3, 3, 3, 3 };
   m_3.setCompressedRowLengths( rowLengths_3 );

   RealType value_3 = 1;
@@ -947,16 +866,13 @@ void test_VectorProduct()
   for( IndexType j = 0; j < outVector_3.getSize(); j++ )
      outVector_3.setElement( j, 0 );


   m_3.vectorProduct( inVector_3, outVector_3 );


   EXPECT_EQ( outVector_3.getElement( 0 ), 12 );
   EXPECT_EQ( outVector_3.getElement( 1 ), 30 );
   EXPECT_EQ( outVector_3.getElement( 2 ), 48 );
   EXPECT_EQ( outVector_3.getElement( 3 ), 66 );


   /*
    * Sets up the following 8x8 sparse matrix:
    *
@@ -973,15 +889,13 @@ void test_VectorProduct()
   const IndexType m_rows_4 = 8;
   const IndexType m_cols_4 = 8;

    Matrix m_4;
    m_4.reset();
    m_4.setDimensions( m_rows_4, m_cols_4 );
    typename Matrix::CompressedRowLengthsVector rowLengths_4;
    rowLengths_4.setSize( m_rows_4 );
   Matrix m_4( m_rows_4, m_cols_4 );
   typename Matrix::CompressedRowLengthsVector rowLengths_4{ 4, 4, 5, 4, 4, 4, 5, 5 };
   /*rowLengths_4.setSize( m_rows_4 );
   rowLengths_4.setValue( 4 );
   rowLengths_4.setElement( 2, 5 );
   rowLengths_4.setElement( 6, 5 );
    rowLengths_4.setElement( 7, 5 );
   rowLengths_4.setElement( 7, 5 );*/
   m_4.setCompressedRowLengths( rowLengths_4 );

   RealType value_4 = 1;
@@ -1021,10 +935,8 @@ void test_VectorProduct()
   for( IndexType j = 0; j < outVector_4.getSize(); j++ )
      outVector_4.setElement( j, 0 );


   m_4.vectorProduct( inVector_4, outVector_4 );


   EXPECT_EQ( outVector_4.getElement( 0 ),  20 );
   EXPECT_EQ( outVector_4.getElement( 1 ),  52 );
   EXPECT_EQ( outVector_4.getElement( 2 ), 110 );
@@ -1051,19 +963,8 @@ void test_VectorProduct()
   const IndexType m_rows_5 = 8;
   const IndexType m_cols_5 = 8;

    Matrix m_5;
    m_5.reset();
    m_5.setDimensions( m_rows_5, m_cols_5 );
    typename Matrix::CompressedRowLengthsVector rowLengths_5;
    rowLengths_5.setSize( m_rows_5 );
    rowLengths_5.setElement(0, 6);
    rowLengths_5.setElement(1, 3);
    rowLengths_5.setElement(2, 4);
    rowLengths_5.setElement(3, 5);
    rowLengths_5.setElement(4, 2);
    rowLengths_5.setElement(5, 7);
    rowLengths_5.setElement(6, 8);
    rowLengths_5.setElement(7, 8);
   Matrix m_5( m_rows_5, m_cols_5 );
   typename Matrix::CompressedRowLengthsVector rowLengths_5{ 6, 3, 4, 5, 2, 7, 8, 8 };
   m_5.setCompressedRowLengths( rowLengths_5 );

   RealType value_5 = 1;
@@ -1145,16 +1046,7 @@ void test_RowsReduction()

   Matrix m;
   m.setDimensions( rows, cols );
   typename Matrix::RowsCapacitiesType rowsCapacities( rows );
   //rowLengths.setSize( rows );
   rowsCapacities.setElement(0, 6);
   rowsCapacities.setElement(1, 3);
   rowsCapacities.setElement(2, 4);
   rowsCapacities.setElement(3, 5);
   rowsCapacities.setElement(4, 2);
   rowsCapacities.setElement(5, 7);
   rowsCapacities.setElement(6, 8);
   rowsCapacities.setElement(7, 8);
   typename Matrix::RowsCapacitiesType rowsCapacities{ 6, 3, 4, 5, 2, 7, 8, 8 };
   m.setCompressedRowLengths( rowsCapacities );

   RealType value = 1;
@@ -1244,12 +1136,9 @@ void test_PerformSORIteration()
   const IndexType m_rows = 4;
   const IndexType m_cols = 4;

    Matrix m;
    m.reset();
    m.setDimensions( m_rows, m_cols );
    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( m_rows );
    rowLengths.setValue( 3 );
   Matrix m( m_rows, m_cols );
   typename Matrix::CompressedRowLengthsVector rowLengths( m_rows );
   rowLengths = 3;
   m.setCompressedRowLengths( rowLengths );

   m.setElement( 0, 0, 4.0 );        // 0th row
@@ -1272,7 +1161,6 @@ void test_PerformSORIteration()
   IndexType row = 0;
   RealType omega = 1;


   m.performSORIteration( bVector, row++, xVector, omega);

   EXPECT_EQ( xVector[ 0 ], 0.0 );
@@ -1280,7 +1168,6 @@ void test_PerformSORIteration()
   EXPECT_EQ( xVector[ 2 ], 1.0 );
   EXPECT_EQ( xVector[ 3 ], 1.0 );


   m.performSORIteration( bVector, row++, xVector, omega);

   EXPECT_EQ( xVector[ 0 ], 0.0 );
@@ -1288,7 +1175,6 @@ void test_PerformSORIteration()
   EXPECT_EQ( xVector[ 2 ], 1.0 );
   EXPECT_EQ( xVector[ 3 ], 1.0 );


   m.performSORIteration( bVector, row++, xVector, omega);

   EXPECT_EQ( xVector[ 0 ], 0.0 );
@@ -1296,7 +1182,6 @@ void test_PerformSORIteration()
   EXPECT_EQ( xVector[ 2 ], 0.0 );
   EXPECT_EQ( xVector[ 3 ], 1.0 );


   m.performSORIteration( bVector, row++, xVector, omega);

   EXPECT_EQ( xVector[ 0 ], 0.0 );
@@ -1305,268 +1190,6 @@ void test_PerformSORIteration()
   EXPECT_EQ( xVector[ 3 ], 0.25 );
}

// This test is only for AdEllpack
template< typename Matrix >
void test_OperatorEquals()
{
   using RealType = typename Matrix::RealType;
   using DeviceType = typename Matrix::DeviceType;
   using IndexType = typename Matrix::IndexType;

   if( std::is_same< DeviceType, TNL::Devices::Cuda >::value )
       return;
   else
   {
       using AdELL_host = TNL::Matrices::AdEllpack< RealType, TNL::Devices::Host, IndexType >;
       using AdELL_cuda = TNL::Matrices::AdEllpack< RealType, TNL::Devices::Cuda, IndexType >;

       /*
        * Sets up the following 8x8 sparse matrix:
        *
        *    /  1  2  3  0  4  5  0  1 \   6
        *    |  0  6  0  7  0  0  0  1 |   3
        *    |  0  8  9  0 10  0  0  1 |   4
        *    |  0 11 12 13 14  0  0  1 |   5
        *    |  0 15  0  0  0  0  0  1 |   2
        *    |  0 16 17 18 19 20 21  1 |   7
        *    | 22 23 24 25 26 27 28  1 |   8
        *    \ 29 30 31 32 33 34 35 36 /   8
        */

        const IndexType m_rows = 8;
        const IndexType m_cols = 8;

        AdELL_host m_host;

        m_host.reset();
        m_host.setDimensions( m_rows, m_cols );
        typename AdELL_host::CompressedRowLengthsVector rowLengths;
        rowLengths.setSize( m_rows );
        rowLengths.setElement(0, 6);
        rowLengths.setElement(1, 3);
        rowLengths.setElement(2, 4);
        rowLengths.setElement(3, 5);
        rowLengths.setElement(4, 2);
        rowLengths.setElement(5, 7);
        rowLengths.setElement(6, 8);
        rowLengths.setElement(7, 8);
        m_host.setCompressedRowLengths( rowLengths );

        RealType value = 1;
        for( IndexType i = 0; i < 3; i++ )   // 0th row
            m_host.setElement( 0, i, value++ );

        m_host.setElement( 0, 4, value++ );           // 0th row
        m_host.setElement( 0, 5, value++ );

        m_host.setElement( 1, 1, value++ );           // 1st row
        m_host.setElement( 1, 3, value++ );

        for( IndexType i = 1; i < 3; i++ )            // 2nd row
            m_host.setElement( 2, i, value++ );

        m_host.setElement( 2, 4, value++ );           // 2nd row


        for( IndexType i = 1; i < 5; i++ )            // 3rd row
            m_host.setElement( 3, i, value++ );

        m_host.setElement( 4, 1, value++ );           // 4th row

        for( IndexType i = 1; i < 7; i++ )            // 5th row
            m_host.setElement( 5, i, value++ );

        for( IndexType i = 0; i < 7; i++ )            // 6th row
            m_host.setElement( 6, i, value++ );

        for( IndexType i = 0; i < 8; i++ )            // 7th row
            m_host.setElement( 7, i, value++ );

        for( IndexType i = 0; i < 7; i++ )            // 1s at the end or rows: 5, 6
            m_host.setElement( i, 7, 1);

        EXPECT_EQ( m_host.getElement( 0, 0 ),  1 );
        EXPECT_EQ( m_host.getElement( 0, 1 ),  2 );
        EXPECT_EQ( m_host.getElement( 0, 2 ),  3 );
        EXPECT_EQ( m_host.getElement( 0, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 0, 4 ),  4 );
        EXPECT_EQ( m_host.getElement( 0, 5 ),  5 );
        EXPECT_EQ( m_host.getElement( 0, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 0, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 1, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 1 ),  6 );
        EXPECT_EQ( m_host.getElement( 1, 2 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 3 ),  7 );
        EXPECT_EQ( m_host.getElement( 1, 4 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 2, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 1 ),  8 );
        EXPECT_EQ( m_host.getElement( 2, 2 ),  9 );
        EXPECT_EQ( m_host.getElement( 2, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 4 ), 10 );
        EXPECT_EQ( m_host.getElement( 2, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 3, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 1 ), 11 );
        EXPECT_EQ( m_host.getElement( 3, 2 ), 12 );
        EXPECT_EQ( m_host.getElement( 3, 3 ), 13 );
        EXPECT_EQ( m_host.getElement( 3, 4 ), 14 );
        EXPECT_EQ( m_host.getElement( 3, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 4, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 1 ), 15 );
        EXPECT_EQ( m_host.getElement( 4, 2 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 4 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 5, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 5, 1 ), 16 );
        EXPECT_EQ( m_host.getElement( 5, 2 ), 17 );
        EXPECT_EQ( m_host.getElement( 5, 3 ), 18 );
        EXPECT_EQ( m_host.getElement( 5, 4 ), 19 );
        EXPECT_EQ( m_host.getElement( 5, 5 ), 20 );
        EXPECT_EQ( m_host.getElement( 5, 6 ), 21 );
        EXPECT_EQ( m_host.getElement( 5, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 6, 0 ), 22 );
        EXPECT_EQ( m_host.getElement( 6, 1 ), 23 );
        EXPECT_EQ( m_host.getElement( 6, 2 ), 24 );
        EXPECT_EQ( m_host.getElement( 6, 3 ), 25 );
        EXPECT_EQ( m_host.getElement( 6, 4 ), 26 );
        EXPECT_EQ( m_host.getElement( 6, 5 ), 27 );
        EXPECT_EQ( m_host.getElement( 6, 6 ), 28 );
        EXPECT_EQ( m_host.getElement( 6, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 7, 0 ), 29 );
        EXPECT_EQ( m_host.getElement( 7, 1 ), 30 );
        EXPECT_EQ( m_host.getElement( 7, 2 ), 31 );
        EXPECT_EQ( m_host.getElement( 7, 3 ), 32 );
        EXPECT_EQ( m_host.getElement( 7, 4 ), 33 );
        EXPECT_EQ( m_host.getElement( 7, 5 ), 34 );
        EXPECT_EQ( m_host.getElement( 7, 6 ), 35 );
        EXPECT_EQ( m_host.getElement( 7, 7 ), 36 );

        AdELL_cuda m_cuda;

        // Copy the host matrix into the cuda matrix
        m_cuda = m_host;

        // Reset the host matrix
        m_host.reset();

        // Copy the cuda matrix back into the host matrix
        m_host = m_cuda;

        // Check the newly created double-copy host matrix
        EXPECT_EQ( m_host.getElement( 0, 0 ),  1 );
        EXPECT_EQ( m_host.getElement( 0, 1 ),  2 );
        EXPECT_EQ( m_host.getElement( 0, 2 ),  3 );
        EXPECT_EQ( m_host.getElement( 0, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 0, 4 ),  4 );
        EXPECT_EQ( m_host.getElement( 0, 5 ),  5 );
        EXPECT_EQ( m_host.getElement( 0, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 0, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 1, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 1 ),  6 );
        EXPECT_EQ( m_host.getElement( 1, 2 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 3 ),  7 );
        EXPECT_EQ( m_host.getElement( 1, 4 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 1, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 2, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 1 ),  8 );
        EXPECT_EQ( m_host.getElement( 2, 2 ),  9 );
        EXPECT_EQ( m_host.getElement( 2, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 4 ), 10 );
        EXPECT_EQ( m_host.getElement( 2, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 2, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 3, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 1 ), 11 );
        EXPECT_EQ( m_host.getElement( 3, 2 ), 12 );
        EXPECT_EQ( m_host.getElement( 3, 3 ), 13 );
        EXPECT_EQ( m_host.getElement( 3, 4 ), 14 );
        EXPECT_EQ( m_host.getElement( 3, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 3, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 4, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 1 ), 15 );
        EXPECT_EQ( m_host.getElement( 4, 2 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 3 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 4 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 5 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 6 ),  0 );
        EXPECT_EQ( m_host.getElement( 4, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 5, 0 ),  0 );
        EXPECT_EQ( m_host.getElement( 5, 1 ), 16 );
        EXPECT_EQ( m_host.getElement( 5, 2 ), 17 );
        EXPECT_EQ( m_host.getElement( 5, 3 ), 18 );
        EXPECT_EQ( m_host.getElement( 5, 4 ), 19 );
        EXPECT_EQ( m_host.getElement( 5, 5 ), 20 );
        EXPECT_EQ( m_host.getElement( 5, 6 ), 21 );
        EXPECT_EQ( m_host.getElement( 5, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 6, 0 ), 22 );
        EXPECT_EQ( m_host.getElement( 6, 1 ), 23 );
        EXPECT_EQ( m_host.getElement( 6, 2 ), 24 );
        EXPECT_EQ( m_host.getElement( 6, 3 ), 25 );
        EXPECT_EQ( m_host.getElement( 6, 4 ), 26 );
        EXPECT_EQ( m_host.getElement( 6, 5 ), 27 );
        EXPECT_EQ( m_host.getElement( 6, 6 ), 28 );
        EXPECT_EQ( m_host.getElement( 6, 7 ),  1 );

        EXPECT_EQ( m_host.getElement( 7, 0 ), 29 );
        EXPECT_EQ( m_host.getElement( 7, 1 ), 30 );
        EXPECT_EQ( m_host.getElement( 7, 2 ), 31 );
        EXPECT_EQ( m_host.getElement( 7, 3 ), 32 );
        EXPECT_EQ( m_host.getElement( 7, 4 ), 33 );
        EXPECT_EQ( m_host.getElement( 7, 5 ), 34 );
        EXPECT_EQ( m_host.getElement( 7, 6 ), 35 );
        EXPECT_EQ( m_host.getElement( 7, 7 ), 36 );

        // Try vectorProduct with copied cuda matrix to see if it works correctly.
        using VectorType = TNL::Containers::Vector< RealType, TNL::Devices::Cuda, IndexType >;

        VectorType inVector;
        inVector.setSize( m_cols );
        for( IndexType i = 0; i < inVector.getSize(); i++ )
            inVector.setElement( i, 2 );

        VectorType outVector;
        outVector.setSize( m_rows );
        for( IndexType j = 0; j < outVector.getSize(); j++ )
            outVector.setElement( j, 0 );

        m_cuda.vectorProduct( inVector, outVector );

        EXPECT_EQ( outVector.getElement( 0 ),  32 );
        EXPECT_EQ( outVector.getElement( 1 ),  28 );
        EXPECT_EQ( outVector.getElement( 2 ),  56 );
        EXPECT_EQ( outVector.getElement( 3 ), 102 );
        EXPECT_EQ( outVector.getElement( 4 ),  32 );
        EXPECT_EQ( outVector.getElement( 5 ), 224 );
        EXPECT_EQ( outVector.getElement( 6 ), 352 );
        EXPECT_EQ( outVector.getElement( 7 ), 520 );
   }
}

template< typename Matrix >
void test_SaveAndLoad( const char* filename )
{
@@ -1586,12 +1209,9 @@ void test_SaveAndLoad( const char* filename )
   const IndexType m_rows = 4;
   const IndexType m_cols = 4;

    Matrix savedMatrix;
    savedMatrix.reset();
    savedMatrix.setDimensions( m_rows, m_cols );
    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( m_rows );
    rowLengths.setValue( 3 );
   Matrix savedMatrix( m_rows, m_cols );
   typename Matrix::CompressedRowLengthsVector rowLengths( m_rows );
   rowLengths = 3;
   savedMatrix.setCompressedRowLengths( rowLengths );

   RealType value = 1;
@@ -1609,18 +1229,13 @@ void test_SaveAndLoad( const char* filename )

   ASSERT_NO_THROW( savedMatrix.save( filename ) );

    Matrix loadedMatrix;
    loadedMatrix.reset();
    loadedMatrix.setDimensions( m_rows, m_cols );
    typename Matrix::CompressedRowLengthsVector rowLengths2;
    rowLengths2.setSize( m_rows );
    rowLengths2.setValue( 3 );
   Matrix loadedMatrix( m_rows, m_cols );
   typename Matrix::CompressedRowLengthsVector rowLengths2( m_rows );
   rowLengths2 = 3;
   loadedMatrix.setCompressedRowLengths( rowLengths2 );


   ASSERT_NO_THROW( loadedMatrix.load( filename ) );


   EXPECT_EQ( savedMatrix.getElement( 0, 0 ), loadedMatrix.getElement( 0, 0 ) );
   EXPECT_EQ( savedMatrix.getElement( 0, 1 ), loadedMatrix.getElement( 0, 1 ) );
   EXPECT_EQ( savedMatrix.getElement( 0, 2 ), loadedMatrix.getElement( 0, 2 ) );
@@ -1684,12 +1299,9 @@ void test_Print()
   const IndexType m_rows = 5;
   const IndexType m_cols = 4;

    Matrix m;
    m.reset();
    m.setDimensions( m_rows, m_cols );
    typename Matrix::CompressedRowLengthsVector rowLengths;
    rowLengths.setSize( m_rows );
    rowLengths.setValue( 3 );
   Matrix m( m_rows, m_cols );
   typename Matrix::CompressedRowLengthsVector rowLengths( m_rows );
   rowLengths = 3;
   m.setCompressedRowLengths( rowLengths );

   RealType value = 1;
@@ -1707,7 +1319,6 @@ void test_Print()
   for( IndexType i = 2; i < m_cols; i++ )       // 4th row
      m.setElement( 4, i, value++ );

    #include <sstream>
   std::stringstream printed;
   std::stringstream couted;

@@ -1724,7 +1335,6 @@ void test_Print()
             "Row: 3 ->  Col:1->8	 Col:2->9	 Col:3->10\t\n"
             "Row: 4 ->  Col:2->11	 Col:3->12\t\n";


   EXPECT_EQ( printed.str(), couted.str() );
}