Skip to content
Snippets Groups Projects
SweepTimeloop.cpp 6.31 KiB
Newer Older
//======================================================================================================================
//
//  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
//  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>
//! \author Christoph Schwarzmeier <christoph.schwarzmeier@fau.de>
//
//======================================================================================================================

#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 )
      {
         // 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());
Markus Holzer's avatar
Markus Holzer committed
            continue;
         } 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);\".")
            }
         }
         Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState() );

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

         (selectedSweep->function_)( bi.get() );
      }

      // 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 );
         // loop over all possibilities in selectable object
         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 )
      {
         // 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());
Markus Holzer's avatar
Markus Holzer committed
            continue;
         } 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);\".")
            }
         }
         std::string sweepName;
         Sweep * selectedSweep = s.sweep.getUnique( selectors + bi->getState(), sweepName );

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

         // loop over all blocks
         timing[sweepName].start();
         (selectedSweep->function_)( bi.get() );
         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