From b99bbe77f3be6f9fd5c1a572148d2946263bec3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Oberhuber?= <oberhuber.tomas@gmail.com>
Date: Mon, 1 Feb 2021 16:44:44 +0100
Subject: [PATCH] Refactoring SpMV benchmark.

---
 .../SpMV/ReferenceFormats/cusparseCSRMatrix.h | 15 ++---
 src/Benchmarks/SpMV/spmv-legacy.h             | 61 +++++++++++--------
 src/Benchmarks/SpMV/tnl-benchmark-spmv.h      |  9 ++-
 3 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/src/Benchmarks/SpMV/ReferenceFormats/cusparseCSRMatrix.h b/src/Benchmarks/SpMV/ReferenceFormats/cusparseCSRMatrix.h
index b331ac7ad1..7d96fbc84e 100644
--- a/src/Benchmarks/SpMV/ReferenceFormats/cusparseCSRMatrix.h
+++ b/src/Benchmarks/SpMV/ReferenceFormats/cusparseCSRMatrix.h
@@ -10,6 +10,7 @@
 
 #include <TNL/Assert.h>
 #include <TNL/Devices/Cuda.h>
+#include <TNL/Matrices/SparseMatrix.h>
 #ifdef HAVE_CUDA
 #include <cusparse.h>
 #endif
@@ -20,9 +21,9 @@ template< typename Real >
 class CusparseCSRBase
 {
    public:
-      typedef Real RealType;
-      typedef Devices::Cuda DeviceType;
-      typedef Benchmarks::SpMV::ReferenceFormats::Legacy::CSR< RealType, Devices::Cuda, int > MatrixType;
+      using RealType = Real;
+      using DeviceType = TNL::Devices::Cuda;
+      using MatrixType = TNL::Matrices::SparseMatrix< Real, TNL::Devices::Cuda, int >;
 
       CusparseCSRBase()
       : matrix( 0 )
@@ -51,7 +52,7 @@ class CusparseCSRBase
 
       int getNumberOfMatrixElements() const
       {
-         return matrix->getNumberOfMatrixElements();
+         return matrix->getAllocatedElementsCount();
       }
 
 
@@ -73,7 +74,7 @@ class CusparseCSRBase
                          1.0,
                          this->matrixDescriptor,
                          this->matrix->values.getData(),
-                         this->matrix->rowPointers.getData(),
+                         this->matrix->getSegments().getOffsets().getData(),
                          this->matrix->columnIndexes.getData(),
                          inVector.getData(),
                          1.0,
@@ -122,7 +123,7 @@ class CusparseCSR< double > : public CusparseCSRBase< double >
                          alpha,
                          this->matrixDescriptor,
                          this->matrix->getValues().getData(),
-                         this->matrix->getRowPointers().getData(),
+                         this->matrix->getSegments().getOffsets().getData(),
                          this->matrix->getColumnIndexes().getData(),
                          inVector.getData(),
                          alpha,
@@ -157,7 +158,7 @@ class CusparseCSR< float > : public CusparseCSRBase< float >
                          alpha,
                          this->matrixDescriptor,
                          this->matrix->getValues().getData(),
-                         this->matrix->getRowPointers().getData(),
+                         this->matrix->getSegments().getOffsets().getData(),
                          this->matrix->getColumnIndexes().getData(),
                          inVector.getData(),
                          alpha,
diff --git a/src/Benchmarks/SpMV/spmv-legacy.h b/src/Benchmarks/SpMV/spmv-legacy.h
index 7d58d17b5a..191b313628 100644
--- a/src/Benchmarks/SpMV/spmv-legacy.h
+++ b/src/Benchmarks/SpMV/spmv-legacy.h
@@ -168,10 +168,10 @@ template< typename Real,
           template< typename, typename, typename > class Matrix,
           template< typename, typename, typename, typename > class Vector = Containers::Vector >
 void
-benchmarkSpMV( Benchmark& benchmark,
-               const TNL::Containers::Vector< Real, Devices::Host, int >& csrResultVector,
-               const String& inputFileName,
-               bool verboseMR )
+benchmarkSpMVLegacy( Benchmark& benchmark,
+                     const TNL::Containers::Vector< Real, Devices::Host, int >& csrResultVector,
+                     const String& inputFileName,
+                     bool verboseMR )
 {
    using HostMatrix = Matrix< Real, Devices::Host, int >;
    using CudaMatrix = Matrix< Real, Devices::Cuda, int >;
@@ -237,10 +237,12 @@ template< typename Real = double,
 void
 benchmarkSpmvSynthetic( Benchmark& benchmark,
                         const String& inputFileName,
+                        const Config::ParameterContainer& parameters,
                         bool verboseMR )
 {
-   using CSRHostMatrix = Benchmarks::SpMV::ReferenceFormats::Legacy::CSR< Real, Devices::Host, int >;
-   using CSRCudaMatrix = Benchmarks::SpMV::ReferenceFormats::Legacy::CSR< Real, Devices::Cuda, int >;
+   // Here we use 'int' instead of 'Index' because of compatibility with cusparse.
+   using CSRHostMatrix = TNL::Matrices::SparseMatrix< Real, TNL::Devices::Host, int >;
+   using CSRCudaMatrix = TNL::Matrices::SparseMatrix< Real, TNL::Devices::Cuda, int >;
    using HostVector = Containers::Vector< Real, Devices::Host, int >;
    using CudaVector = Containers::Vector< Real, Devices::Cuda, int >;
 
@@ -251,7 +253,7 @@ benchmarkSpmvSynthetic( Benchmark& benchmark,
    // Set-up benchmark datasize
    //
    MatrixReader< CSRHostMatrix >::readMtx( inputFileName, csrHostMatrix, verboseMR );
-   const int elements = csrHostMatrix.getNumberOfNonzeroMatrixElements();
+   const int elements = csrHostMatrix.getNonzeroElementsCount();
    const double datasetSize = (double) elements * ( 2 * sizeof( Real ) + sizeof( int ) ) / oneGB;
    benchmark.setOperation( datasetSize );
 
@@ -318,30 +320,41 @@ benchmarkSpmvSynthetic( Benchmark& benchmark,
    benchmark.time< Devices::Cuda >( resetCusparseVectors, "GPU", spmvCusparse, cusparseBenchmarkResults );
 #endif
 
-   using namespace Benchmarks::SpMV::ReferenceFormats;
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Scalar             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Vector             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light              >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light2             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light3             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light4             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light5             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Light6             >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_Adaptive           >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_MultiVector        >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrixLegacy_CSR_LightWithoutAtomic >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrix_CSR_Scalar                   >( benchmark, hostOutVector, inputFileName, verboseMR );
+   /////
+   // Benchmarking TNL formats
+   /*benchmarkSpMV< Real, SparseMatrix_CSR_Scalar                   >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_CSR_Vector                   >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_CSR_Hybrid                   >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_CSR_Adaptive                 >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, Legacy::Ellpack                           >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_Ellpack                      >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SlicedEllpackAlias                        >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_SlicedEllpack                >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, Legacy::ChunkedEllpack                    >( benchmark, hostOutVector, inputFileName, verboseMR );
    benchmarkSpMV< Real, SparseMatrix_ChunkedEllpack               >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, Legacy::BiEllpack                         >( benchmark, hostOutVector, inputFileName, verboseMR );
-   benchmarkSpMV< Real, SparseMatrix_BiEllpack                    >( benchmark, hostOutVector, inputFileName, verboseMR );
+   benchmarkSpMV< Real, SparseMatrix_BiEllpack                    >( benchmark, hostOutVector, inputFileName, verboseMR );*/
+
+
+   const bool withSymmetricMatrices = parameters.getParameter< bool >("with-symmetric-matrices");
+
+   /////
+   // Benchmarking of TNL legacy formats
+   if( parameters.getParameter< bool >("with-legacy-matrices") )
+   {
+      using namespace Benchmarks::SpMV::ReferenceFormats;
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Scalar             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Vector             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light              >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light2             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light3             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light4             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light5             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Light6             >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_Adaptive           >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_MultiVector        >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, SparseMatrixLegacy_CSR_LightWithoutAtomic >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, Legacy::Ellpack                           >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, Legacy::ChunkedEllpack                    >( benchmark, hostOutVector, inputFileName, verboseMR );
+      benchmarkSpMVLegacy< Real, Legacy::BiEllpack                         >( benchmark, hostOutVector, inputFileName, verboseMR );
+   }
    /* AdEllpack is broken
    benchmarkSpMV< Real, Matrices::AdEllpack              >( benchmark, hostOutVector, inputFileName, verboseMR );
     */
diff --git a/src/Benchmarks/SpMV/tnl-benchmark-spmv.h b/src/Benchmarks/SpMV/tnl-benchmark-spmv.h
index 7897073d96..82d0e083c6 100644
--- a/src/Benchmarks/SpMV/tnl-benchmark-spmv.h
+++ b/src/Benchmarks/SpMV/tnl-benchmark-spmv.h
@@ -36,6 +36,7 @@ void
 runSpMVBenchmarks( Benchmark & benchmark,
                    Benchmark::MetadataMap metadata,
                    const String & inputFileName,
+                   const Config::ParameterContainer& parameters,
                    bool verboseMR = false )
 {
    const String precision = getType< Real >();
@@ -46,7 +47,7 @@ runSpMVBenchmarks( Benchmark & benchmark,
                            metadata );
    // Start the actual benchmark in spmv.h
    try {
-      SpMVLegacy::benchmarkSpmvSynthetic< Real >( benchmark, inputFileName, verboseMR );
+      SpMVLegacy::benchmarkSpmvSynthetic< Real >( benchmark, inputFileName, parameters, verboseMR );
    }
    catch( const std::exception& ex ) {
       std::cerr << ex.what() << std::endl;
@@ -71,6 +72,8 @@ setupConfig( Config::ConfigDescription & config )
 {
    config.addDelimiter( "Benchmark settings:" );
    config.addRequiredEntry< String >( "input-file", "Input file name." );
+   config.addEntry< bool >( "with-symmetric-matrices", "Perform benchmark even for symmetric matrix formats.", true );
+   config.addEntry< bool >( "with-legacy-matrices", "Perform benchmark even for legacy TNL matrix formats.", true );
    config.addEntry< String >( "log-file", "Log file name.", "tnl-benchmark-spmv::" + getCurrDateTime() + ".log");
    config.addEntry< String >( "output-mode", "Mode for opening the log file.", "overwrite" );
    config.addEntryEnum( "append" );
@@ -135,9 +138,9 @@ main( int argc, char* argv[] )
 
    // Initiate setup of benchmarks
    if( precision == "all" || precision == "float" )
-      runSpMVBenchmarks< float >( benchmark, metadata, inputFileName, verboseMR );
+      runSpMVBenchmarks< float >( benchmark, metadata, inputFileName, parameters, verboseMR );
    if( precision == "all" || precision == "double" )
-      runSpMVBenchmarks< double >( benchmark, metadata, inputFileName, verboseMR );
+      runSpMVBenchmarks< double >( benchmark, metadata, inputFileName, parameters, verboseMR );
 
    if( ! benchmark.save( logFile ) ) {
       std::cerr << "Failed to write the benchmark results to file '" << parameters.getParameter< String >( "log-file" ) << "'." << std::endl;
-- 
GitLab