SweepTimeloop.cpp 6.31 KB
Newer Older
1
2
//======================================================================================================================
//
3
//  This file is part of waLBerla. waLBerla is free software: you can
4
//  redistribute it and/or modify it under the terms of the GNU General Public
5
//  License as published by the Free Software Foundation, either version 3 of
6
//  the License, or (at your option) any later version.
7
8
9
10
//
//  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
11
//  for more details.
12
//
13
14
15
16
17
18
//  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 SweepTimeloop.cpp
//! \ingroup timeloop
//! \author Martin Bauer <martin.bauer@fau.de>
19
//! \author Christoph Schwarzmeier <christoph.schwarzmeier@fau.de>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
//======================================================================================================================

#include "SweepTimeloop.h"
#include "core/Abort.h"


namespace walberla {
namespace timeloop {


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////   Execution of Timeloop  ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void SweepTimeloop::doTimeStep(const Set<SUID> &selectors)
{
   removeForDeletionMarkedSweeps();
   //iterate over all registered sweeps
   for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
   {
      SweepAdder & s = * ( sweepIt->second );

      //select and execute before functions
      for( size_t j=0; j < s.beforeFuncs.size(); ++j )
         executeSelectable(s.beforeFuncs[j].selectableFunc_,selectors,"Pre-Sweep Function");

      // Loop over all blocks
      for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
      {
51
         // ensure that at least one sweep has been registered (regardless of its selector)
52
53
54
55
56
57
         if( s.sweep.empty() )
         {
            WALBERLA_ABORT("Selecting Sweep " << sweepIt->first << ": " <<
                           "No sweep has been registered! Did you only register a BeforeFunction or AfterFunction?" );
         }

58
59
         // ensure that exactly one sweep has been registered that matches the specified selectors
         size_t numSweeps = s.sweep.getNumberOfMatching(selectors + bi->getState());
60
61

         if (numSweeps == size_t(0)) {
Markus Holzer's avatar
Markus Holzer committed
62
            continue;
63
64
65
66
67
68
         } else {
            if (numSweeps > size_t(1)) {
               WALBERLA_ABORT("Only one sweep must be added to a single SweepAdder object. This error might be caused "
                              "by e.g. \"timeloop.add() << Sweep(A) << Sweep(B);\".")
            }
         }
69

70
71
         Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState() );

72
73
74
75
76
77
78
         WALBERLA_LOG_PROGRESS_SECTION()
         {
            std::string sweepName;
            s.sweep.getUnique( selectors + bi->getState(), sweepName );
            WALBERLA_LOG_PROGRESS("Running sweep \"" << sweepName << "\" on block " << bi->getId() );
         }

79
         (selectedSweep->function_)( bi.get() );
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
      }

      // select and execute after functions
      for( size_t j=0; j < s.afterFuncs.size(); ++j )
         executeSelectable(s.afterFuncs[j].selectableFunc_,selectors,"Post-Sweep Function");
   }
}

void SweepTimeloop::doTimeStep(const Set<SUID> &selectors, WcTimingPool &timing)
{
   removeForDeletionMarkedSweeps();
   // On first run we extract all possible names of sweeps, independent of selectors
   // to register timer for them. Since all timingPools have to have the same entries on
   // all processes otherwise a timingPool.reduce() does not work
   // see test SweepTimeloopTimerReduction.cpp
   if ( firstRun_ || timing.empty() )
   {

      for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
      {
         SweepAdder & s = * ( sweepIt->second );
101
         // loop over all possibilities in selectable object
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
         for( auto it = s.sweep.begin(); it != s.sweep.end(); ++it )
            timing.registerTimer( it.identifier() );
      }
      firstRun_ = false;
   }


   //iterate over all registered sweeps
   for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
   {
      SweepAdder & s = * ( sweepIt->second );

      //select and execute before functions
      for( size_t j=0; j < s.beforeFuncs.size(); ++j )
         executeSelectable( s.beforeFuncs[j].selectableFunc_, selectors, "Pre-Sweep Function", timing );

      for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
      {
120
121
122
123
124
125
126
127
128
         // ensure that at least one sweep has been registered (regardless of its selector)
         if( s.sweep.empty() )
         {
            WALBERLA_ABORT("Selecting Sweep " << sweepIt->first << ": " <<
                           "No sweep has been registered! Did you only register a BeforeFunction or AfterFunction?" );
         }

         // ensure that exactly one sweep has been registered that matches the specified selectors
         size_t numSweeps = s.sweep.getNumberOfMatching(selectors + bi->getState());
129

130
         if (numSweeps == size_t(0)) {
Markus Holzer's avatar
Markus Holzer committed
131
            continue;
132
133
134
135
136
137
         } else {
            if (numSweeps > size_t(1)) {
               WALBERLA_ABORT("Only one sweep must be added to a single SweepAdder object. This error might be caused "
                              "by e.g. \"timeloop.add() << Sweep(A) << Sweep(B);\".")
            }
         }
138

139
140
141
         std::string sweepName;
         Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState(), sweepName );

142
143
144
145
         WALBERLA_LOG_PROGRESS("Running sweep \"" << sweepName << "\" on block " << bi->getId() );

         // loop over all blocks
         timing[sweepName].start();
146
         (selectedSweep->function_)( bi.get() );
147
148
149
150
151
152
153
154
155
156
157
158
159
160
         timing[sweepName].end();
      }

      // select and execute after functions
      for( size_t j=0; j < s.afterFuncs.size(); ++j )
         executeSelectable(s.afterFuncs[j].selectableFunc_,selectors,"Post-Sweep Function", timing );
   }
}



} // namespace timeloop
} // namespace walberla