PerformanceLogger.h 7.08 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//======================================================================================================================
//
//  This file is part of waLBerla. waLBerla is free software: you can
//  redistribute it and/or modify it under the terms of the GNU General Public
//  License as published by the Free Software Foundation, either version 3 of
//  the License, or (at your option) any later version.
//
//  waLBerla is distributed in the hope that it will be useful, but WITHOUT
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
//  for more details.
//
//  You should have received a copy of the GNU General Public License along
//  with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file PerformanceLogger.h
//! \ingroup lbm
//! \author Christian Godenschwager <christian.godenschwager@fau.de>
//
//======================================================================================================================

#pragma once

#include "PerformanceEvaluation.h"

#include "core/DataTypes.h"
#include "core/Set.h"
#include "core/uid/SUID.h"
#include "core/timing/Timer.h"

#include "domain_decomposition/BlockDataID.h"
#include "domain_decomposition/StructuredBlockStorage.h"

#include "field/FlagUID.h"

36
37
#include "timeloop/ITimeloop.h"

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <limits>

namespace walberla {
namespace lbm {

//**********************************************************************************************************************
/*!
*   \brief Class for using the PerformanceEvaluation in a timeloop
*
*   Providing a measurement interval, this class will regularly (every <interval> time steps) measure and report the
*   LBM performance. At the end of the simulation logOverallResults() may be called to output minimum, maximum and
*   average performance during the simulation run.   
*/
//**********************************************************************************************************************
template< typename FlagField_T >
class PerformanceLogger
{
public:
   PerformanceLogger( const shared_ptr< StructuredBlockStorage > & blocks,
                      const ConstBlockDataID & flagFieldId, const Set< FlagUID > & fluid,
                      const uint_t interval,
                      const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
                      const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() );

62
63
64
65
66
67
68
   PerformanceLogger( const shared_ptr< StructuredBlockStorage > & blocks,
                      const ConstBlockDataID & flagFieldId, const Set< FlagUID > & fluid,
                      const timeloop::ITimeloop * const timeloop,
                      const uint_t interval,
                      const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
                      const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() );

69
70
71
   void operator()();
   void logOverallResultsOnRoot() const;

72
73
74
75
76
77
78
   void enableRefreshCellCountOnCall()  { refreshCellCountOnCall_ = true;  }
   void disableRefreshCellCountOnCall() { refreshCellCountOnCall_ = false; }

   void getBestResultsForSQLOnRoot( std::map< std::string, int > &         integerProperties,
                                    std::map< std::string, double > &      realProperties,
                                    std::map< std::string, std::string > & stringProperties );

79
80
81
82
83
84
85
86
private:
   enum Mode { MIN, MAX, AVG, LAST };
   real_t getTiming( Mode mode ) const;

   PerformanceEvaluation<FlagField_T> performanceEvaluation_;
   uint_t interval_;
   uint_t timestep_;
   WcTimer timer_;
87
88
   bool refreshCellCountOnCall_;
   const timeloop::ITimeloop * timeloop_;
89
90
91
92
93
94
95
96
97
98
99

}; // class PerformanceLogger


template< typename FlagField_T >
PerformanceLogger<FlagField_T>::PerformanceLogger( const shared_ptr< StructuredBlockStorage > & blocks,
                   const ConstBlockDataID & flagFieldId, const Set< FlagUID > & fluid,
                   const uint_t interval,
                   const Set<SUID> & requiredSelectors /*= Set<SUID>::emptySet()*/,
                   const Set<SUID> & incompatibleSelectors /*= Set<SUID>::emptySet()*/ )
                   : performanceEvaluation_( blocks, flagFieldId, fluid, requiredSelectors, incompatibleSelectors ),
100
101
102
103
104
105
106
107
108
109
110
111
112
                     interval_(interval), timestep_(1), refreshCellCountOnCall_(false), timeloop_(NULL)
{
}

template< typename FlagField_T >
PerformanceLogger<FlagField_T>::PerformanceLogger( const shared_ptr< StructuredBlockStorage > & blocks,
                                                   const ConstBlockDataID & flagFieldId, const Set< FlagUID > & fluid,
                                                   const timeloop::ITimeloop * const timeloop,
                                                   const uint_t interval,
                                                   const Set<SUID> & requiredSelectors /*= Set<SUID>::emptySet()*/,
                                                   const Set<SUID> & incompatibleSelectors /*= Set<SUID>::emptySet()*/ )
   : performanceEvaluation_( blocks, flagFieldId, fluid, requiredSelectors, incompatibleSelectors ),
     interval_( interval ), timestep_( 1 ), refreshCellCountOnCall_( false ), timeloop_( timeloop )
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
{
}


template< typename FlagField_T >
real_t PerformanceLogger<FlagField_T>::getTiming( Mode mode ) const
{
   switch( mode )
   {
   case MIN:
      return timer_.max();
   case MAX:
      return timer_.min();
   case AVG:
      return timer_.average();
   case LAST:
      return timer_.last();
   default:
      WALBERLA_ASSERT( false );
      return std::numeric_limits< real_t >::signaling_NaN();
   }
}

template< typename FlagField_T >
void PerformanceLogger<FlagField_T>::operator()()
{
139
140
141
142
   if( timeloop_ )
      timestep_ = timeloop_->getCurrentTimeStep() + uint_t(1);

   if( timestep_ % interval_ == 0 )
143
144
145
   {
      WALBERLA_MPI_BARRIER();
      timer_.end();
146
147
148
149
      
      if( refreshCellCountOnCall_ )
         performanceEvaluation_.refresh();

150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
      performanceEvaluation_.logResultOnRoot( interval_, getTiming( LAST ) );
      timer_.start();
   }

   ++timestep_;
}

template< typename FlagField_T >
void PerformanceLogger<FlagField_T>::logOverallResultsOnRoot() const
{
   WALBERLA_LOG_RESULT_ON_ROOT( "Min Performance:\n" << performanceEvaluation_.loggingString( interval_, getTiming( MIN ) ); );
   WALBERLA_LOG_RESULT_ON_ROOT( "Max Performance:\n" << performanceEvaluation_.loggingString( interval_, getTiming( MAX ) ); );
   WALBERLA_LOG_RESULT_ON_ROOT( "Avg Performance:\n" << performanceEvaluation_.loggingString( interval_, getTiming( AVG ) ); );
}

165
166
167
168
169
170
171
172
template< typename FlagField_T >
void PerformanceLogger<FlagField_T>::getBestResultsForSQLOnRoot( std::map< std::string, int > &         integerProperties,
                                                                 std::map< std::string, double > &      realProperties,
                                                                 std::map< std::string, std::string > & stringProperties )
{
   performanceEvaluation_.getResultsForSQLOnRoot( integerProperties, realProperties, stringProperties, interval_, getTiming( MAX ) );
}

173
174
175

} // namespace lbm
} // namespace walberla