Commit 4fbfbb48 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Benchmarks: refactoring to avoid useless templates on BenchmarkResult

parent a6544303
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -185,7 +185,7 @@ main( int argc, char* argv[] )
   Benchmark<> benchmark( loops, verbose );

   // prepare global metadata
   Benchmark<>::MetadataMap metadata = getHardwareMetadata< Logging >();
   Logging::MetadataMap metadata = getHardwareMetadata();

   if( precision == "all" || precision == "float" )
      runBlasBenchmarks< float >( benchmark, metadata, minSize, maxSize, sizeStepFactor, elementsPerRow );
+4 −4
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ Benchmark< Logger >::
time( ResetFunction reset,
      const String & performer,
      ComputeFunction & compute,
      BenchmarkResult< Logger > & result )
      BenchmarkResult & result )
{
   result.time = std::numeric_limits<double>::quiet_NaN();
   result.stddev = std::numeric_limits<double>::quiet_NaN();
@@ -210,7 +210,7 @@ time( ResetFunction reset,
      const String& performer,
      ComputeFunction& compute )
{
   BenchmarkResult< Logger > result;
   BenchmarkResult result;
   return time< Device, ResetFunction, ComputeFunction >( reset, performer, compute, result );
}

@@ -221,7 +221,7 @@ double
Benchmark< Logger >::
time( const String & performer,
      ComputeFunction & compute,
      BenchmarkResult< Logger > & result )
      BenchmarkResult & result )
{
   result.time = std::numeric_limits<double>::quiet_NaN();
   result.stddev = std::numeric_limits<double>::quiet_NaN();
@@ -259,7 +259,7 @@ Benchmark< Logger >::
time( const String & performer,
      ComputeFunction & compute )
{
   BenchmarkResult< Logger > result;
   BenchmarkResult result;
   return time< Device, ComputeFunction >( performer, compute, result );
}

+9 −11
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@

#pragma once

#include "Logging.h"
#include "CustomLogging.h"

#include <limits>

@@ -32,11 +32,10 @@ namespace Benchmarks {
const double oneGB = 1024.0 * 1024.0 * 1024.0;


template< typename Logger = Logging >
struct BenchmarkResult
{
   using HeaderElements = typename Logger::HeaderElements;
   using RowElements = typename Logger::RowElements;
   using HeaderElements = typename Logging::HeaderElements;
   using RowElements = typename Logging::RowElements;

   double time = std::numeric_limits<double>::quiet_NaN();
   double stddev = std::numeric_limits<double>::quiet_NaN();
@@ -65,7 +64,7 @@ struct BenchmarkResult
   }
};

template< typename Logger = Logging >
template< typename Logger = CustomLogging >
class Benchmark
: protected Logger
{
@@ -139,7 +138,7 @@ class Benchmark
      double time( ResetFunction reset,
                  const String & performer,
                  ComputeFunction & compute,
                  BenchmarkResult< Logger > & result );
                  BenchmarkResult & result );

      template< typename Device,
               typename ResetFunction,
@@ -148,7 +147,7 @@ class Benchmark
                        const String & performer,
                        ComputeFunction & compute );
      /*{
         BenchmarkResult< Logger > result;
         BenchmarkResult result;
         return time< Device, ResetFunction, ComputeFunction >( reset, performer, compute, result );
      }*/

@@ -159,7 +158,7 @@ class Benchmark
               typename ComputeFunction >
      double time( const String & performer,
                  ComputeFunction & compute,
                  BenchmarkResult< Logger > & result );
                  BenchmarkResult & result );

      template< typename Device,
               typename ComputeFunction >
@@ -195,8 +194,7 @@ class Benchmark
};


template< typename Logger >
inline typename Benchmark< Logger >::MetadataMap getHardwareMetadata()
inline typename Logging::MetadataMap getHardwareMetadata()
{
   const int cpu_id = 0;
   const CacheSizes cacheSizes = SystemInfo::getCPUCacheSizes( cpu_id );
@@ -218,7 +216,7 @@ inline typename Benchmark< Logger >::MetadataMap getHardwareMetadata()
      nproc = TNL::MPI::GetSize();
#endif

   typename Benchmark< Logger >::MetadataMap metadata {
   typename Logging::MetadataMap metadata {
       { "host name", SystemInfo::getHostname() },
       { "architecture", SystemInfo::getArchitecture() },
       { "system", SystemInfo::getSystemName() },
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ set( headers
         Benchmark.hpp
         FunctionTimer.h
         Logging.h
         CustomLogging.h
         JsonLogging.h
)

+229 −0
Original line number Diff line number Diff line
/***************************************************************************
                          CustomLogging.h  -  description
                             -------------------
    begin                : May 11, 2021
    copyright            : (C) 2021 by Tomas Oberhuber et al.
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

// Implemented by: Jakub Klinkovsky,
//                 Tomas Oberhuber

#pragma once

#include "Logging.h"

namespace TNL {
namespace Benchmarks {

class CustomLogging
: public Logging
{
public:
   CustomLogging( int verbose = true,
                  String outputMode = "",
                  bool logFileAppend = false )
   : Logging(verbose), outputMode( outputMode )
   {}

   virtual void
   writeTitle( const String & title ) override
   {
      if( verbose )
         std::cout << std::endl << "== " << title << " ==" << std::endl << std::endl;
      log << ": title = " << title << std::endl;
   }

   virtual void addCommonLogs( const CommonLogs& logs ) override
   {
      for( auto log : logs )
      {
         if( verbose )
            std::cout << log.first << " = " << log.second << std::endl;
      }
   };

   virtual void
   writeMetadata( const MetadataMap & metadata ) override
   {
      if( verbose )
         std::cout << "properties:" << std::endl;

      for( auto & it : metadata ) {
         if( verbose )
            std::cout << "   " << it.first << " = " << it.second << std::endl;
         log << ": " << it.first << " = " << it.second << std::endl;
      }
      if( verbose )
         std::cout << std::endl;
   }

   virtual void
   writeTableHeader( const String & spanningElement,
                     const HeaderElements & subElements ) override
   {
      if( verbose && header_changed ) {
         for( auto & it : metadataColumns ) {
            std::cout << std::setw( 20 ) << it.first;
         }

         // spanning element is printed as usual column to stdout,
         // but is excluded from header
         std::cout << std::setw( 15 ) << "";

         for( auto & it : subElements ) {
            std::cout << std::setw( 15 ) << it;
         }
         std::cout << std::endl;

         header_changed = false;
      }

      // initial indent string
      header_indent = "!";
      log << std::endl;
      for( auto & it : metadataColumns ) {
         log << header_indent << " " << it.first << std::endl;
      }

      // dump stacked spanning columns
      if( horizontalGroups.size() > 0 )
         while( horizontalGroups.back().second <= 0 ) {
            horizontalGroups.pop_back();
            header_indent.pop_back();
         }
      for( size_t i = 0; i < horizontalGroups.size(); i++ ) {
         if( horizontalGroups[ i ].second > 0 ) {
            log << header_indent << " " << horizontalGroups[ i ].first << std::endl;
            header_indent += "!";
         }
      }

      log << header_indent << " " << spanningElement << std::endl;
      for( auto & it : subElements ) {
         log << header_indent << "! " << it << std::endl;
      }

      if( horizontalGroups.size() > 0 ) {
         horizontalGroups.back().second--;
         header_indent.pop_back();
      }
   }

   virtual void
   writeTableRow( const String & spanningElement,
                  const RowElements & subElements ) override
   {
      if( verbose ) {
         for( auto & it : metadataColumns ) {
            std::cout << std::setw( 20 ) << it.second;
         }
         // spanning element is printed as usual column to stdout
         std::cout << std::setw( 15 ) << spanningElement;
         for( auto & it : subElements ) {
            std::cout << std::setw( 15 ) << it;
         }
         std::cout << std::endl;
      }

      // only when changed (the header has been already adjusted)
      // print each element on separate line
      for( auto & it : metadataColumns ) {
         log << it.second << std::endl;
      }

      // benchmark data are indented
      const String indent = "    ";
      for( auto & it : subElements ) {
         log << indent << it << std::endl;
      }
   }

   virtual void
   writeErrorMessage( const char* msg,
                      int colspan = 1 ) override
   {
      // initial indent string
      header_indent = "!";
      log << std::endl;
      for( auto & it : metadataColumns ) {
         log << header_indent << " " << it.first << std::endl;
      }

      // make sure there is a header column for the message
      if( horizontalGroups.size() == 0 )
         horizontalGroups.push_back( {"", 1} );

      // dump stacked spanning columns
      while( horizontalGroups.back().second <= 0 ) {
         horizontalGroups.pop_back();
         header_indent.pop_back();
      }
      for( size_t i = 0; i < horizontalGroups.size(); i++ ) {
         if( horizontalGroups[ i ].second > 0 ) {
            log << header_indent << " " << horizontalGroups[ i ].first << std::endl;
            header_indent += "!";
         }
      }
      if( horizontalGroups.size() > 0 ) {
         horizontalGroups.back().second -= colspan;
         header_indent.pop_back();
      }

      // only when changed (the header has been already adjusted)
      // print each element on separate line
      for( auto & it : metadataColumns ) {
         log << it.second << std::endl;
      }
      log << msg << std::endl;
   }

   virtual void
   closeTable() override
   {
      log << std::endl;
      header_indent = body_indent = "";
      header_changed = true;
      horizontalGroups.clear();
   }

   virtual bool save( std::ostream & logFile ) override
   {
      closeTable();
      logFile << log.str();
      if( logFile.good() ) {
         log.str() = "";
         return true;
      }
      return false;
   }

protected:
   // manual double -> String conversion with fixed precision
   static String
   _to_string( double num, int precision = 0, bool fixed = false )
   {
      std::stringstream str;
      if( fixed )
         str << std::fixed;
      if( precision )
         str << std::setprecision( precision );
      str << num;
      return String( str.str().data() );
   }

   std::stringstream log;
   std::string header_indent;
   std::string body_indent;

   MetadataColumns metadataColumns;
   bool header_changed = true;
   std::vector< std::pair< String, int > > horizontalGroups;

   String outputMode;
};

} // namespace Benchmarks
} // namespace TNL
Loading