diff options
Diffstat (limited to 'Carpet/Carpet/src/Recompose.cc')
-rw-r--r-- | Carpet/Carpet/src/Recompose.cc | 1037 |
1 files changed, 657 insertions, 380 deletions
diff --git a/Carpet/Carpet/src/Recompose.cc b/Carpet/Carpet/src/Recompose.cc index 958a5d058..f1f0b8834 100644 --- a/Carpet/Carpet/src/Recompose.cc +++ b/Carpet/Carpet/src/Recompose.cc @@ -15,21 +15,25 @@ #include <sys/stat.h> #include <sys/types.h> -#include "cctk.h" -#include "cctk_Parameters.h" +#include <mpi.h> -#include "bbox.hh" -#include "bboxset.hh" -#include "defs.hh" -#include "dh.hh" -#include "gh.hh" -#include "region.hh" -#include "vect.hh" +#include <cctk.h> +#include <cctk_Parameters.h> -#include "carpet.hh" -#include "modes.hh" +#include <loopcontrol.h> -#define DEBUG false // false or true +#include <bbox.hh> +#include <bboxset.hh> +#include <defs.hh> +#include <dh.hh> +#include <gh.hh> +#include <region.hh> +#include <vect.hh> + +#include <carpet.hh> +#include <modes.hh> +#include <variables.hh> +#include <Timers.hh> @@ -61,6 +65,11 @@ namespace Carpet { static void + ClassifyPoints (cGH const * cctkGH, int rl); + + + + static void SplitRegionsMaps_Automatic_Recursively (bvect const & dims, int const firstproc, int const nprocs, @@ -76,57 +85,68 @@ namespace Carpet { void CheckRegions (gh::mregs const & regsss) { + char const * const where = "Carpet::CheckRegions"; + static Timer timer (where); + timer.start(); + // At least one multigrid level if (regsss.size() == 0) { CCTK_WARN (0, "I cannot set up a grid hierarchy with zero multigrid levels."); } assert (regsss.size() > 0); // At least one refinement level - if (regsss.at(0).size() == 0) { + if (regsss.AT(0).size() == 0) { CCTK_WARN (0, "I cannot set up a grid hierarchy with zero refinement levels."); } - assert (regsss.at(0).size() > 0); + assert (regsss.AT(0).size() > 0); // At most maxreflevels levels - if ((int)regsss.at(0).size() > maxreflevels) { + if ((int)regsss.AT(0).size() > maxreflevels) { CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "I cannot set up a grid hierarchy with more than Carpet::max_refinement_levels refinement levels. I found Carpet::max_refinement_levels=%d, while %d levels were requested.", - (int)maxreflevels, (int)regsss.at(0).size()); + (int)maxreflevels, (int)regsss.AT(0).size()); } - assert ((int)regsss.at(0).size() <= maxreflevels); + assert ((int)regsss.AT(0).size() <= maxreflevels); for (int ml=0; ml<(int)regsss.size(); ++ml) { int num_regions = 0; - for (int rl=0; rl<(int)regsss.at(0).size(); ++rl) { + for (int rl=0; rl<(int)regsss.AT(0).size(); ++rl) { // No empty levels // (but allow some empty maps) - // assert (regsss.at(ml).at(rl).size() > 0); - num_regions += regsss.at(ml).at(rl).size(); - for (int c=0; c<(int)regsss.at(ml).at(rl).size(); ++c) { + // assert (regsss.AT(ml).AT(rl).size() > 0); + num_regions += regsss.AT(ml).AT(rl).size(); + for (int c=0; c<(int)regsss.AT(ml).AT(rl).size(); ++c) { // Check sizes // (but allow processors with zero grid points) - // assert (all(regsss.at(rl).at(c).at(ml).extent.lower() <= - // regsss.at(rl).at(c).at(ml).extent.upper())); + // assert (all(regsss.AT(rl).AT(c).AT(ml).extent.lower() <= + // regsss.AT(rl).AT(c).AT(ml).extent.upper())); // Check strides ivect const str = - (maxspacereflevelfact / spacereffacts.at(rl) * ipow(mgfact, ml)); - assert (all(regsss.at(ml).at(rl).at(c).extent.stride() % str == 0)); + (maxspacereflevelfact / spacereffacts.AT(rl) * ipow(mgfact, ml)); + assert (all(regsss.AT(ml).AT(rl).AT(c).extent.stride() % str == 0)); // Check alignments - assert (all(regsss.at(ml).at(rl).at(c).extent.lower() % str == 0)); - assert (all(regsss.at(ml).at(rl).at(c).extent.upper() % str == 0)); + assert (all(regsss.AT(ml).AT(rl).AT(c).extent.lower() % str == 0)); + assert (all(regsss.AT(ml).AT(rl).AT(c).extent.upper() % str == 0)); } } // No empty levels assert (num_regions > 0); } + + timer.stop(); } bool Regrid (cGH const * const cctkGH, - bool const force_recompose) + bool const force_recompose, + bool const do_init) { DECLARE_CCTK_PARAMETERS; + char const * const where = "Carpet::Regrid"; + static Timer timer (where); + timer.start(); + Checkpoint ("Regridding level %d...", reflevel); assert (is_level_mode()); @@ -141,6 +161,7 @@ namespace Carpet { CCTK_WARN (2, "The regridding routine Carpet_Regrid has not been provided. There will be no regridding. Maybe you forgot to activate a regridding thorn?"); didtell = true; } + timer.stop(); return false; } @@ -150,7 +171,7 @@ namespace Carpet { CCTK_WARN (2, "The regridding routine Carpet_RegridMaps has not been provided. Regridding will be performed in singlemap mode instead of level mode."); didtell = true; } - } + } @@ -160,7 +181,7 @@ namespace Carpet { BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { - gh::rregs superregss = vhh.at(map)->superregions; + gh::rregs superregss = vhh.AT(map)->superregions; gh::mregs regsss; // Check whether to recompose @@ -170,7 +191,7 @@ namespace Carpet { did_change = did_change or do_recompose; if (do_recompose) { - RegridMap (cctkGH, map, superregss, regsss); + RegridMap (cctkGH, map, superregss, regsss, do_init); } } END_MAP_LOOP; @@ -180,20 +201,28 @@ namespace Carpet { vector<gh::rregs> superregsss (maps); vector<gh::mregs> regssss (maps); BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { - superregsss.at(map) = vhh.at(map)->superregions; + superregsss.AT(map) = vhh.AT(map)->superregions; } END_MAP_LOOP; // Check whether to recompose CCTK_INT const do_recompose = Carpet_RegridMaps (cctkGH, & superregsss, & regssss, force_recompose); assert (do_recompose >= 0); +#warning "TODO" +#if 1 // #ifdef CARPET_DEBUG + { + int ival = do_recompose; + MPI_Bcast (& ival, 1, MPI_INT, 0, dist::comm()); + assert (ival == do_recompose); + } +#endif did_change = did_change or do_recompose; if (do_recompose) { BEGIN_MAP_LOOP(cctkGH, CCTK_GF) { - gh::rregs const & superregss = superregsss.at(map); - gh::mregs const & regsss = regssss.at(map); - RegridMap (cctkGH, map, superregss, regsss); + gh::rregs const & superregss = superregsss.AT(map); + gh::mregs const & regsss = regssss.AT(map); + RegridMap (cctkGH, map, superregss, regsss, do_init); } END_MAP_LOOP; } @@ -208,6 +237,14 @@ namespace Carpet { } // if did change + + timer.stop(); + + if (enable_no_storage) { + CCTK_WARN (CCTK_WARN_ALERT, + "Carpet completed its internal setup, and would now normally go on to allocate memory. Since the parameter Carpet::enable_no_storage has been set, Carpet will exit instead."); + CCTK_Exit (cctkGH, 0); + } return did_change; } @@ -218,12 +255,16 @@ namespace Carpet { RegridMap (cGH const * const cctkGH, int const m, gh::rregs const & superregss, - gh::mregs const & regsss) + gh::mregs const & regsss, + bool const do_init) { DECLARE_CCTK_PARAMETERS; + char const * const where = "Carpet::RegridMap"; + static Timer timer (where); + timer.start(); + Waypoint ("Regridding map %d...", m); - #warning "TODO: keep levels fixed here" #if 0 @@ -239,15 +280,15 @@ namespace Carpet { int const do_every = use_tapered_grids ? - maxtimereflevelfact / timereffacts.at(max(0,rl-1)): - maxtimereflevelfact / timereffacts.at( rl ); + maxtimereflevelfact / timereffacts.AT(max(0,rl-1)): + maxtimereflevelfact / timereffacts.AT( rl ); bool const regrid_this_level = (cctkGH->cctk_iteration - 1) % do_every == 0; if (not regrid_this_level) { // Set regions from current grid structure - regions.at(rl) = ...; + regions.AT(rl) = ...; } } #endif @@ -258,18 +299,18 @@ namespace Carpet { // not change // Regrid - vhh.at(m)->regrid (superregss, regsss); + vhh.AT(m)->regrid (superregss, regsss, do_init); + + // Output grid structure to screen + OutputSuperregions (cctkGH, m, * vhh.AT(m), superregss); + OutputGrids (cctkGH, m, * vhh.AT(m), * vdd.AT(m)); // Write grid structure to file OutputGridStructure (cctkGH, m, regsss); OutputGridCoordinates (cctkGH, m, regsss); -#warning "TODO: output superregss" - - if (verbose or veryverbose) { - OutputGrids (cctkGH, m, * vhh.at(m), * vdd.at(m)); - } Waypoint ("Done regridding map %d.", m); + timer.stop(); } @@ -279,13 +320,27 @@ namespace Carpet { { DECLARE_CCTK_PARAMETERS; + char const * const where = "Carpet::PostRegrid"; + static Timer timer (where); + timer.start(); + // Calculate new number of levels int const oldreflevels = reflevels; - reflevels = vhh.at(0)->reflevels(); + reflevels = vhh.AT(0)->reflevels(); for (int m=0; m<maps; ++m) { - assert (vhh.at(m)->reflevels() == reflevels); + assert (vhh.AT(m)->reflevels() == reflevels); } +#warning "TODO" +#if 1 // #ifdef CARPET_DEBUG + { + // All processes must use the same number of levels + int ival = reflevels; + MPI_Bcast (& ival, 1, MPI_INT, 0, dist::comm()); + assert (ival == reflevels); + } +#endif + // One cannot switch off the current level assert (reflevels > reflevel); @@ -294,19 +349,23 @@ namespace Carpet { int const grouptype = CCTK_GroupTypeI (n); if (grouptype == CCTK_GF) { for (int ml=0; ml<mglevels; ++ml) { - groupdata.at(n).activetimelevels.at(ml).resize - (reflevels, groupdata.at(n).activetimelevels.at(ml).at(0)); + groupdata.AT(n).activetimelevels.AT(ml).resize + (reflevels, groupdata.AT(n).activetimelevels.AT(ml).AT(0)); } } } // Set new level times for (int ml=0; ml<mglevels; ++ml) { - leveltimes.at(ml).resize - (reflevels, leveltimes.at(ml).at(oldreflevels-1)); + leveltimes.AT(ml).resize + (reflevels, leveltimes.AT(ml).AT(oldreflevels-1)); } + ++ regridding_epoch; + OutputGridStatistics (cctkGH); + + timer.stop(); } @@ -316,200 +375,291 @@ namespace Carpet { int const rl, bool const do_init) { + char const * const where = "Carpet::Recompose"; + static Timer timer (where); + timer.start(); + bool did_recompose = false; for (int m=0; m<maps; ++m) { Waypoint ("Recomposing the grid hierarchy for map %d level %d...", m, rl); - assert (rl>=0 and rl<vhh.at(m)->reflevels()); - did_recompose |= vhh.at(m)->recompose (rl, do_init); + assert (rl>=0 and rl<vhh.AT(m)->reflevels()); + did_recompose |= vhh.AT(m)->recompose (rl, do_init); Waypoint ("Done recomposing the grid hierarchy for map %d level %d.", m, rl); } + + ClassifyPoints (cctkGH, rl); + + timer.stop(); return did_recompose; } void - OutputGrids (cGH const * const cctkGH, - int const m, - gh const & hh, - dh const & dd) + RegridFree (cGH const * const cctkGH, + bool const do_init) { - CCTK_INFO ("Grid structure (grid points):"); - for (int ml=0; ml<hh.mglevels(); ++ml) { - for (int rl=0; rl<hh.reflevels(); ++rl) { - for (int c=0; c<hh.components(rl); ++c) { - const int convfact = ipow(mgfact, ml); - const ivect levfact = spacereffacts.at(rl); - const ibbox ext = hh.extent(ml,rl,c); - const ivect & lower = ext.lower(); - const ivect & upper = ext.upper(); - const ivect & stride = ext.stride(); - assert (all(lower * levfact % maxspacereflevelfact == 0)); - assert (all(upper * levfact % maxspacereflevelfact == 0)); - assert (all(((upper - lower) * levfact / maxspacereflevelfact) - % convfact == 0)); - cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" - << " exterior: " - << "proc " - << hh.processor(rl,c) - << " " - << lower / stride - << " : " - << upper / stride - << " (" - << (upper - lower) / stride + 1 - << ") " - << prod ((upper - lower) / stride + 1) - << endl; - } - } + char const * const where = "Carpet::RegridFree"; + static Timer timer (where); + timer.start(); + + Checkpoint ("Freeing after regridding level %d...", reflevel); + + assert (is_level_mode()); + + // Free old grid structure + for (int m=0; m<maps; ++m) { + vhh.AT(m)->regrid_free (do_init); } - CCTK_INFO ("Grid structure (boundaries):"); - for (int rl=0; rl<hh.reflevels(); ++rl) { - for (int c=0; c<hh.components(rl); ++c) { + timer.stop(); + } + + + + void + OutputSuperregions (cGH const * const cctkGH, + int const m, + gh const & hh, + gh::rregs const & superregss) + { + CCTK_INFO ("Grid structure (superregions, grid points):"); + for (int rl=0; rl<(int)superregss.size(); ++rl) { + assert (rl < hh.reflevels()); + for (int c=0; c<(int)superregss.AT(rl).size(); ++c) { + const ivect & levfact = spacereffacts.AT(rl); + const ibbox & ext = superregss.AT(rl).AT(c).extent; + const ivect & lower = ext.lower(); + const ivect & upper = ext.upper(); + const ivect & stride = ext.stride(); + assert (all(lower * levfact % maxspacereflevelfact == 0)); + assert (all(upper * levfact % maxspacereflevelfact == 0)); cout << " [" << rl << "][" << m << "][" << c << "]" - << " bbox: " - << hh.outer_boundaries(rl,c) - << endl; + << " exterior: " + << lower / stride + << " : " + << upper / stride + << " (" + << (upper - lower) / stride + 1 + << ") " + << prod ((upper - lower) / stride + 1) + << eol; } } - CCTK_INFO ("Grid structure (coordinates):"); - for (int ml=0; ml<hh.mglevels(); ++ml) { - for (int rl=0; rl<hh.reflevels(); ++rl) { - for (int c=0; c<hh.components(rl); ++c) { - const rvect origin = domainspecs.at(m).exterior_min; - const rvect delta = (domainspecs.at(m).exterior_max - domainspecs.at(m).exterior_min) / rvect (domainspecs.at(m).npoints - 1); - const ibbox ext = hh.extent(ml,rl,c); - const ivect & lower = ext.lower(); - const ivect & upper = ext.upper(); - const int convfact = ipow(mgfact, ml); - const ivect levfact = spacereffacts.at(rl); - cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" - << " exterior: " - << origin + delta * rvect(lower) / rvect(maxspacereflevelfact) - << " : " - << origin + delta * rvect(upper) / rvect(maxspacereflevelfact) - << " : " - << delta * rvect(convfact) / rvect(levfact) << endl; - } + CCTK_INFO ("Grid structure (superregions, coordinates):"); + for (int rl=0; rl<(int)superregss.size(); ++rl) { + assert (rl < hh.reflevels()); + for (int c=0; c<(int)superregss.AT(rl).size(); ++c) { + const rvect origin = domainspecs.AT(m).exterior_min; + const rvect delta = (domainspecs.AT(m).exterior_max - domainspecs.AT(m).exterior_min) / rvect (domainspecs.AT(m).npoints - 1); + const ibbox & ext = superregss.AT(rl).AT(c).extent; + const ivect & lower = ext.lower(); + const ivect & upper = ext.upper(); + const ivect & levfact = spacereffacts.AT(rl); + cout << " [" << rl << "][" << m << "][" << c << "]" + << " exterior: " + << origin + delta * rvect(lower) / rvect(maxspacereflevelfact) + << " : " + << origin + delta * rvect(upper) / rvect(maxspacereflevelfact) + << " : " + << delta / rvect(levfact) << eol; } } - CCTK_INFO ("Grid structure (coordinates, including ghosts):"); - for (int ml=0; ml<hh.mglevels(); ++ml) { - for (int rl=0; rl<hh.reflevels(); ++rl) { - for (int c=0; c<hh.components(rl); ++c) { - const rvect origin = domainspecs.at(m).exterior_min; - const rvect delta = (domainspecs.at(m).exterior_max - domainspecs.at(m).exterior_min) / rvect (domainspecs.at(m).npoints - 1); - const ivect lower = dd.boxes.at(ml).at(rl).at(c).exterior.lower(); - const ivect upper = dd.boxes.at(ml).at(rl).at(c).exterior.upper(); - const int convfact = ipow(mgfact, ml); - const ivect levfact = spacereffacts.at(rl); - cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" - << " exterior: " - << origin + delta * rvect(lower) / rvect(maxspacereflevelfact) - << " : " - << origin + delta * rvect(upper) / rvect(maxspacereflevelfact) - << " : " - << delta * rvect(convfact) / rvect(levfact) << endl; + fflush (stdout); + } + + + + void + OutputGrids (cGH const * const cctkGH, + int const m, + gh const & hh, + dh const & dd) + { + DECLARE_CCTK_PARAMETERS; + + if (verbose or veryverbose) { + + CCTK_INFO ("Grid structure (grid points):"); + for (int ml=0; ml<hh.mglevels(); ++ml) { + for (int rl=0; rl<hh.reflevels(); ++rl) { + for (int c=0; c<hh.components(rl); ++c) { + const int convfact = ipow(mgfact, ml); + const ivect levfact = spacereffacts.AT(rl); + const ibbox ext = hh.extent(ml,rl,c); + const ivect & lower = ext.lower(); + const ivect & upper = ext.upper(); + const ivect & stride = ext.stride(); + assert (all(lower * levfact % maxspacereflevelfact == 0)); + assert (all(upper * levfact % maxspacereflevelfact == 0)); + assert (all(((upper - lower) * levfact / maxspacereflevelfact) + % convfact == 0)); + cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" + << " exterior: " + << "proc " + << hh.processor(rl,c) + << " " + << lower / stride + << " : " + << upper / stride + << " (" + << (upper - lower) / stride + 1 + << ") " + << prod ((upper - lower) / stride + 1) + << eol; + } } } - } - - CCTK_INFO ("Grid statistics:"); - const int oldprecision = cout.precision(); - const ios_base::fmtflags oldflags = cout.flags(); - cout.setf (ios::fixed); - for (int ml=0; ml<hh.mglevels(); ++ml) { - CCTK_REAL coarsevolume = 0; + + CCTK_INFO ("Grid structure (boundaries):"); for (int rl=0; rl<hh.reflevels(); ++rl) { - - const CCTK_REAL basevolume = hh.baseextents.AT(0).AT(0).size(); - CCTK_REAL countvolume = 0; - CCTK_REAL totalvolume = 0; - CCTK_REAL totalvolume2 = 0; - for (int c=0; c<hh.components(rl); ++c) { - const CCTK_REAL volume = hh.extent(ml,rl,c).size(); - ++ countvolume; - totalvolume += volume; - totalvolume2 += ipow(volume, 2); + cout << " [" << rl << "][" << m << "][" << c << "]" + << " bbox: " + << hh.outer_boundaries(rl,c) + << eol; } - - const CCTK_REAL avgvolume = totalvolume / countvolume; - const CCTK_REAL stddevvolume - = sqrt (max (CCTK_REAL(0), - totalvolume2 / countvolume - ipow (avgvolume, 2))); - - for (int c=0; c<hh.components(rl); ++c) { - const CCTK_REAL volume = hh.extent(ml,rl,c).size(); - cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" - << " volume: " << setprecision(0) << volume - << " of parent: " << setprecision(1) << 100 * volume / totalvolume << "%" - << " of domain: " << setprecision(1) << 100 * volume / basevolume << "%" - << endl; + } + + CCTK_INFO ("Grid structure (coordinates):"); + for (int ml=0; ml<hh.mglevels(); ++ml) { + for (int rl=0; rl<hh.reflevels(); ++rl) { + for (int c=0; c<hh.components(rl); ++c) { + const rvect origin = domainspecs.AT(m).exterior_min; + const rvect delta = (domainspecs.AT(m).exterior_max - domainspecs.AT(m).exterior_min) / rvect (domainspecs.AT(m).npoints - 1); + const ibbox ext = hh.extent(ml,rl,c); + const ivect & lower = ext.lower(); + const ivect & upper = ext.upper(); + const int convfact = ipow(mgfact, ml); + const ivect levfact = spacereffacts.AT(rl); + cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" + << " exterior: " + << origin + delta * rvect(lower) / rvect(maxspacereflevelfact) + << " : " + << origin + delta * rvect(upper) / rvect(maxspacereflevelfact) + << " : " + << delta * rvect(convfact) / rvect(levfact) << eol; + } } - - cout << " [" << ml << "][" << rl << "][" << m << "]" - << " average volume: " << setprecision(0) << avgvolume - << " of parent: " << setprecision(1) << 100 * avgvolume / totalvolume << "%" - << " of domain: " << setprecision(1) << 100 * avgvolume / basevolume << "%" - << endl; - cout << " [" << ml << "][" << rl << "][" << m << "]" - << " standard deviation: " << setprecision(0) << stddevvolume - << " of parent: " << setprecision(1) << 100 * stddevvolume / totalvolume << "%" - << " of domain: " << setprecision(1) << 100 * stddevvolume / basevolume << "%" - << endl; - - // TODO: ghost points vs. interior points (and boundary - // points) - - CCTK_REAL countquadrupole = 0; - CCTK_REAL minquadrupole = 1; - CCTK_REAL totalquadrupole = 0; - CCTK_REAL totalquadrupole2 = 0; - - for (int c=0; c<hh.components(rl); ++c) { - const ibbox ext = hh.extent(ml,rl,c); - const ivect shape = ext.shape(); - const ivect stride = ext.stride(); - const CCTK_REAL minlength = minval (rvect (shape) / rvect (stride)); - const CCTK_REAL maxlength = maxval (rvect (shape) / rvect (stride)); - const CCTK_REAL quadrupole = minlength / maxlength; - ++ countquadrupole; - minquadrupole = min (minquadrupole, quadrupole); - totalquadrupole += quadrupole; - totalquadrupole2 += ipow (quadrupole, 2); - cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" - << " length ratio: " << setprecision(3) << quadrupole - << endl; + } + + CCTK_INFO ("Grid structure (coordinates, including ghosts):"); + for (int ml=0; ml<hh.mglevels(); ++ml) { + for (int rl=0; rl<hh.reflevels(); ++rl) { + for (int c=0; c<hh.components(rl); ++c) { + const rvect origin = domainspecs.AT(m).exterior_min; + const rvect delta = (domainspecs.AT(m).exterior_max - domainspecs.AT(m).exterior_min) / rvect (domainspecs.AT(m).npoints - 1); + const ivect lower = dd.boxes.AT(ml).AT(rl).AT(c).exterior.lower(); + const ivect upper = dd.boxes.AT(ml).AT(rl).AT(c).exterior.upper(); + const int convfact = ipow(mgfact, ml); + const ivect levfact = spacereffacts.AT(rl); + cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" + << " exterior: " + << origin + delta * rvect(lower) / rvect(maxspacereflevelfact) + << " : " + << origin + delta * rvect(upper) / rvect(maxspacereflevelfact) + << " : " + << delta * rvect(convfact) / rvect(levfact) << eol; + } + } + } + + CCTK_INFO ("Grid statistics:"); + const int oldprecision = cout.precision(); + const ios_base::fmtflags oldflags = cout.flags(); + cout.setf (ios::fixed); + for (int ml=0; ml<hh.mglevels(); ++ml) { + CCTK_REAL coarsevolume = 0; + for (int rl=0; rl<hh.reflevels(); ++rl) { + + const CCTK_REAL basevolume = hh.baseextents.AT(0).AT(0).size(); + CCTK_REAL countvolume = 0; + CCTK_REAL totalvolume = 0; + CCTK_REAL totalvolume2 = 0; + + for (int c=0; c<hh.components(rl); ++c) { + const CCTK_REAL volume = hh.extent(ml,rl,c).size(); + ++ countvolume; + totalvolume += volume; + totalvolume2 += ipow(volume, 2); + } + + const CCTK_REAL avgvolume = totalvolume / countvolume; + const CCTK_REAL stddevvolume + = sqrt (max (CCTK_REAL(0), + totalvolume2 / countvolume - ipow (avgvolume, 2))); + + for (int c=0; c<hh.components(rl); ++c) { + const CCTK_REAL volume = hh.extent(ml,rl,c).size(); + cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" + << " volume: " << setprecision(0) << volume + << " of parent: " << setprecision(1) << 100 * volume / totalvolume << "%" + << " of domain: " << setprecision(1) << 100 * volume / basevolume << "%" + << eol; + } + + cout << " [" << ml << "][" << rl << "][" << m << "]" + << " average volume: " << setprecision(0) << avgvolume + << " of parent: " << setprecision(1) << 100 * avgvolume / totalvolume << "%" + << " of domain: " << setprecision(1) << 100 * avgvolume / basevolume << "%" + << eol; + cout << " [" << ml << "][" << rl << "][" << m << "]" + << " standard deviation: " << setprecision(0) << stddevvolume + << " of parent: " << setprecision(1) << 100 * stddevvolume / totalvolume << "%" + << " of domain: " << setprecision(1) << 100 * stddevvolume / basevolume << "%" + << eol; + + // TODO: ghost points vs. interior points (and boundary + // points) + + CCTK_REAL countquadrupole = 0; + CCTK_REAL minquadrupole = 1; + CCTK_REAL totalquadrupole = 0; + CCTK_REAL totalquadrupole2 = 0; + + for (int c=0; c<hh.components(rl); ++c) { + const ibbox ext = hh.extent(ml,rl,c); + const ivect shape = ext.shape(); + const ivect stride = ext.stride(); + const CCTK_REAL minlength = minval (rvect (shape) / rvect (stride)); + const CCTK_REAL maxlength = maxval (rvect (shape) / rvect (stride)); + const CCTK_REAL quadrupole = minlength / maxlength; + ++ countquadrupole; + minquadrupole = min (minquadrupole, quadrupole); + totalquadrupole += quadrupole; + totalquadrupole2 += ipow (quadrupole, 2); + cout << " [" << ml << "][" << rl << "][" << m << "][" << c << "]" + << " length ratio: " << setprecision(3) << quadrupole + << eol; + } + + const CCTK_REAL avgquadrupole = totalquadrupole / countquadrupole; + const CCTK_REAL stddevquadrupole + = sqrt (max (CCTK_REAL(0), + (totalquadrupole2 / countquadrupole + - ipow (avgquadrupole, 2)))); + + cout << " [" << ml << "][" << rl << "][" << m << "]" + << " average length ratio: " << setprecision(3) << avgquadrupole + << " standard deviation: " << setprecision(3) << stddevquadrupole + << eol; + + // TODO: processor distribution, average load, std deviation + + coarsevolume = totalvolume * prod (rvect (spacereflevelfact)); } - - const CCTK_REAL avgquadrupole = totalquadrupole / countquadrupole; - const CCTK_REAL stddevquadrupole - = sqrt (max (CCTK_REAL(0), - (totalquadrupole2 / countquadrupole - - ipow (avgquadrupole, 2)))); - - cout << " [" << ml << "][" << rl << "][" << m << "]" - << " average length ratio: " << setprecision(3) << avgquadrupole - << " standard deviation: " << setprecision(3) << stddevquadrupole - << endl; - - // TODO: processor distribution, average load, std deviation - - coarsevolume = totalvolume * prod (rvect (spacereflevelfact)); } + cout.precision (oldprecision); + cout.setf (oldflags); + + fflush (stdout); } - cout.precision (oldprecision); - cout.setf (oldflags); - } @@ -561,14 +711,14 @@ namespace Carpet { file << "maps " << maps << eol; file << m << " mglevels " << regsss.size() << eol; for (int ml=0; ml<(int)regsss.size(); ++ml) { - file << m << " " << ml << " reflevels " << regsss.at(ml).size() << eol; - for (int rl=0; rl<(int)regsss.at(ml).size(); ++rl) { - file << m << " " << ml << " " << rl << " components " << regsss.at(ml).at(rl).size() << eol; - for (int c=0; c<(int)regsss.at(ml).at(rl).size(); ++c) { + file << m << " " << ml << " reflevels " << regsss.AT(ml).size() << eol; + for (int rl=0; rl<(int)regsss.AT(ml).size(); ++rl) { + file << m << " " << ml << " " << rl << " components " << regsss.AT(ml).AT(rl).size() << eol; + for (int c=0; c<(int)regsss.AT(ml).AT(rl).size(); ++c) { file << m << " " << ml << " " << rl << " " << c << " " - << regsss.at(ml).at(rl).at(c).processor << " " - << regsss.at(ml).at(rl).at(c).extent << " " - << regsss.at(ml).at(rl).at(c).outer_boundaries << eol; + << regsss.AT(ml).AT(rl).AT(c).processor << " " + << regsss.AT(ml).AT(rl).AT(c).extent << " " + << regsss.AT(ml).AT(rl).AT(c).outer_boundaries << eol; } } } @@ -668,7 +818,7 @@ namespace Carpet { // Affine transformation between index space and coordinate space rvect const origin = exterior_lower; rvect const scale = - rvect (vhh.at(m)->baseextents.at(0).at(0).stride()) / spacing; + rvect (vhh.AT(m)->baseextents.AT(0).AT(0).stride()) / spacing; @@ -676,11 +826,11 @@ namespace Carpet { file << "maps " << maps << eol; file << m << " mglevels " << regsss.size() << eol; for (int ml=0; ml<(int)regsss.size(); ++ml) { - file << m << " " << ml << " reflevels " << regsss.at(ml).size() << eol; - for (int rl=0; rl<(int)regsss.at(ml).size(); ++rl) { + file << m << " " << ml << " reflevels " << regsss.AT(ml).size() << eol; + for (int rl=0; rl<(int)regsss.AT(ml).size(); ++rl) { ibset extents; - for (int c=0; c<(int)regsss.at(ml).at(rl).size(); ++c) { - extents += regsss.at(ml).at(rl).at(c).extent; + for (int c=0; c<(int)regsss.AT(ml).AT(rl).size(); ++c) { + extents += regsss.AT(ml).AT(rl).AT(c).extent; } extents.normalize(); file << m << " " << ml << " " << rl << " regions " << extents.setsize() << eol; @@ -690,12 +840,12 @@ namespace Carpet { { #if 0 ibbox const & ext = * bi; - ibbox const & baseext = vhh.at(m)->baseextents.at(ml).at(rl); - ibbox const & coarseext = vhh.at(m)->baseextents.at(ml).at(0 ); + ibbox const & baseext = vhh.AT(m)->baseextents.AT(ml).AT(rl); + ibbox const & coarseext = vhh.AT(m)->baseextents.AT(ml).AT(0 ); // This is nice, but is wrong since CartGrid3D has not yet // initialised the coordinates - ivect const cctk_levfac = spacereffacts.at(rl); + ivect const cctk_levfac = spacereffacts.AT(rl); ivect const cctk_levoff = baseext.lower() - coarseext.lower(); ivect const cctk_levoffdenom = baseext.stride(); @@ -705,9 +855,9 @@ namespace Carpet { (ext.upper() - baseext.lower()) / ext.stride(); rvect const cctk_origin_space = - origin_space.at(m).at(ml); + origin_space.AT(m).AT(ml); rvect const cctk_delta_space = - delta_space.at(m) * rvect (ipow (mgfact, ml)); + delta_space.AT(m) * rvect (ipow (mgfact, ml)); rvect const CCTK_ORIGIN_SPACE = cctk_origin_space + @@ -773,28 +923,35 @@ namespace Carpet { OutputGridStatistics (cGH const * const cctkGH) { // Grid array statistics - int num_gfs = 0; int num_arrays = 0; + int num_gfs = 0; + int size_gfs = 0; CCTK_REAL num_active_array_points = 0; CCTK_REAL num_total_array_points = 0; + CCTK_REAL size_total_array_points = 0; for (int g=0; g<CCTK_NumGroups(); ++g) { + cGroup gdata; + check (not CCTK_GroupData (g, &gdata)); int const num_tl = CCTK_ActiveTimeLevelsGI (cctkGH, g); - switch (CCTK_GroupTypeI(g)) { + int const num_vars = gdata.numvars; + int const size_vars = gdata.numvars * CCTK_VarTypeSize (gdata.vartype); + switch (gdata.grouptype) { case CCTK_SCALAR: case CCTK_ARRAY: { - int const num_vars = CCTK_NumVarsInGroupI (g); num_arrays += num_tl * num_vars; gh const * const hh = arrdata.AT(g).AT(0).hh; dh const * const dd = arrdata.AT(g).AT(0).dd; for (int c=0; c<hh->components(0); ++c) { dh::dboxes const & b = dd->boxes.AT(0).AT(0).AT(c); - num_active_array_points += num_tl * num_vars * b.active.size(); - num_total_array_points += num_tl * num_vars * b.exterior.size(); + num_active_array_points += num_tl * num_vars * b.active_size; + num_total_array_points += num_tl * num_vars * b.exterior_size; + size_total_array_points += num_tl * size_vars * b.exterior_size; } break; } case CCTK_GF: - num_gfs += num_tl; + num_gfs += num_tl * num_vars; + size_gfs += num_tl * size_vars; break; default: assert (0); @@ -807,6 +964,7 @@ namespace Carpet { CCTK_REAL num_active_mem_points = 0; CCTK_REAL num_owned_mem_points = 0; CCTK_REAL num_total_mem_points = 0; + CCTK_REAL size_total_mem_points = 0; CCTK_REAL num_active_cpu_points = 0; CCTK_REAL num_owned_cpu_points = 0; CCTK_REAL num_total_cpu_points = 0; @@ -822,12 +980,13 @@ namespace Carpet { for (int c=0; c<hh->components(rl); ++c) { ++ num_comps; dh::dboxes const & b = dd->boxes.AT(ml).AT(rl).AT(c); - num_active_mem_points += num_gfs * b.active.size(); - num_owned_mem_points += num_gfs * b.owned.size(); - num_total_mem_points += num_gfs * b.exterior.size(); - num_active_cpu_points += trf * b.active.size(); - num_owned_cpu_points += trf * b.owned.size(); - num_total_cpu_points += trf * b.exterior.size(); + num_active_mem_points += num_gfs * b.active_size; + num_owned_mem_points += num_gfs * b.owned_size; + num_total_mem_points += num_gfs * b.exterior_size; + size_total_mem_points += size_gfs * b.exterior_size; + num_active_cpu_points += trf * b.active_size; + num_owned_cpu_points += trf * b.owned_size; + num_total_cpu_points += trf * b.exterior_size; } } } @@ -841,27 +1000,30 @@ namespace Carpet { "Grid structure statistics:"); CCTK_VInfo (CCTK_THORNSTRING, "GF: rhs: %.0fk active, %.0fk owned (+%.0f%%), %.0fk total (+%.0f%%), %.3g steps/time", - double (num_active_cpu_points / 1000), - double (num_owned_cpu_points / 1000), + double (num_active_cpu_points / 1e+3), + double (num_owned_cpu_points / 1e+3), double (num_owned_cpu_points / num_active_cpu_points * 100 - 100), - double (num_total_cpu_points / 1000), + double (num_total_cpu_points / 1e+3), double (num_total_cpu_points / num_owned_cpu_points * 100 - 100), double (num_steps / delta_time)); CCTK_VInfo (CCTK_THORNSTRING, "GF: vars: %d, pts: %.0fM active, %.0fM owned (+%.0f%%), %.0fM total (+%.0f%%), %.1f comp/proc", num_gfs, - double (num_active_mem_points / 1000000), - double (num_owned_mem_points / 1000000), + double (num_active_mem_points / 1e+6), + double (num_owned_mem_points / 1e+6), double (num_owned_mem_points / num_active_mem_points * 100 - 100), - double (num_total_mem_points / 1000000), + double (num_total_mem_points / 1e+6), double (num_total_mem_points / num_owned_mem_points * 100 - 100), double (num_comps / (reflevels * CCTK_nProcs (cctkGH)))); CCTK_VInfo (CCTK_THORNSTRING, "GA: vars: %d, pts: %.0fM active, %.0fM total (+%.0f%%)", num_arrays, - double (num_active_array_points / 1000000), - double (num_total_array_points / 1000000), + double (num_active_array_points / 1e+6), + double (num_total_array_points / 1e+6), double (num_total_array_points / num_active_array_points * 100 - 100)); + CCTK_VInfo (CCTK_THORNSTRING, + "Total required memory: %.3f GByte (for GAs and currently active GFs)", + double ((size_total_array_points + size_total_mem_points) / 1e+9)); // After this, we will begin to allocate memory for the grid // structure. If we run out of memory, ensure that this output @@ -902,16 +1064,16 @@ namespace Carpet { regs = superregs; if (nprocs == 1) { - regs.at(0).processor = 0; - pseudoregion_t const preg (regs.at(0).extent, regs.at(0).processor); - assert (superregs.at(0).processors == NULL); - superregs.at(0).processors = new ipfulltree (preg); + regs.AT(0).processor = 0; + pseudoregion_t const preg (regs.AT(0).extent, regs.AT(0).processor); + assert (superregs.AT(0).processors == NULL); + superregs.AT(0).processors = new ipfulltree (preg); return; } assert (dir>=0 and dir<dim); - region_t const & reg0 = regs.at(0); + region_t const & reg0 = regs.AT(0); const ivect rstr0 = reg0.extent.stride(); const ivect rlb0 = reg0.extent.lower(); const ivect rub0 = reg0.extent.upper() + rstr0; @@ -933,7 +1095,7 @@ namespace Carpet { if (cub[dir] > rub0[dir]) cub[dir] = rub0[dir]; assert (clb[dir] <= cub[dir]); assert (cub[dir] <= rub0[dir]); - region_t & reg = regs.at(c); + region_t & reg = regs.AT(c); ibbox & ext = reg.extent; b2vect & obnd = reg.outer_boundaries; int & proc = reg.processor; @@ -943,16 +1105,16 @@ namespace Carpet { obnd[1][dir] &= cub[dir] == rub0[dir]; proc = c; pseudoregion_t const preg (reg.extent, c); - bounds.at(c) = reg.extent.lower()[dir]; - subtrees.at(c) = new ipfulltree (preg); + bounds.AT(c) = reg.extent.lower()[dir]; + subtrees.AT(c) = new ipfulltree (preg); } - bounds.at(nprocs) = rub0[dir] + rstr0[dir]; + bounds.AT(nprocs) = rub0[dir] + rstr0[dir]; - assert (superregs.at(0).processors == NULL); - superregs.at(0).processors = new ipfulltree (dir, bounds, subtrees); + assert (superregs.AT(0).processors == NULL); + superregs.AT(0).processors = new ipfulltree (dir, bounds, subtrees); for (int c=0; c<(int)regs.size(); ++c) { - assert (regs.at(c).processor == c); + assert (regs.AT(c).processor == c); } } @@ -968,9 +1130,9 @@ namespace Carpet { vector<vector<region_t> > regss (1); SplitRegionsMaps_Automatic (cctkGH, superregss, regss); assert (superregss.size() == 1); - superregs = regss.at(0); + superregs = superregss.AT(0); assert (regss.size() == 1); - regs = regss.at(0); + regs = regss.AT(0); } @@ -993,7 +1155,7 @@ namespace Carpet { assert (superregs.size() == 1); - region_t const & reg0 = superregs.at(0); + region_t const & reg0 = superregs.AT(0); const ivect rstr0 = reg0.extent.stride(); const ivect rlb0 = reg0.extent.lower(); const ivect rub0 = reg0.extent.upper() + rstr0; @@ -1052,7 +1214,7 @@ namespace Carpet { assert (all (cub <= rub0)); assert (all (not (ipos==0) or clb==rlb0)); assert (all (not (ipos==nprocs_dir-1) or cub==rub0)); - region_t & reg = regs.at(c); + region_t & reg = regs.AT(c); ibbox & ext = reg.extent; b2vect & obnd = reg.outer_boundaries; int & proc = reg.processor; @@ -1063,21 +1225,21 @@ namespace Carpet { proc = c; pseudoregion_t preg (reg.extent, c); - subtreesx.at(i) = new ipfulltree (preg); + subtreesx.AT(i) = new ipfulltree (preg); } - boundsx.at(nprocs_dir[0]) = rub0[0] + rstr0[0]; - subtreesy.at(j) = new ipfulltree (0, boundsx, subtreesx); + boundsx.AT(nprocs_dir[0]) = rub0[0] + rstr0[0]; + subtreesy.AT(j) = new ipfulltree (0, boundsx, subtreesx); } - boundsy.at(nprocs_dir[1]) = rub0[1] + rstr0[1]; - subtreesz.at(k) = new ipfulltree (1, boundsy, subtreesy); + boundsy.AT(nprocs_dir[1]) = rub0[1] + rstr0[1]; + subtreesz.AT(k) = new ipfulltree (1, boundsy, subtreesy); } - boundsz.at(nprocs_dir[2]) = rub0[2] + rstr0[2]; + boundsz.AT(nprocs_dir[2]) = rub0[2] + rstr0[2]; - assert (superregs.at(0).processors == NULL); - superregs.at(0).processors = new ipfulltree (2, boundsz, subtreesz); + assert (superregs.AT(0).processors == NULL); + superregs.AT(0).processors = new ipfulltree (2, boundsz, subtreesz); for (int c=0; c<(int)regs.size(); ++c) { - assert (regs.at(c).processor == c); + assert (regs.AT(c).processor == c); } } @@ -1121,7 +1283,9 @@ namespace Carpet { region_t & superreg, vector<region_t> & newregs) { - if (DEBUG) cout << "SRMAR enter" << endl; + DECLARE_CCTK_PARAMETERS; + + if (recompose_verbose) cout << "SRMAR enter" << endl; // Check preconditions assert (nprocs >= 1); @@ -1130,7 +1294,7 @@ namespace Carpet { // Are we done? if (all(dims)) { - if (DEBUG) cout << "SRMAR bottom" << endl; + if (recompose_verbose) cout << "SRMAR bottom" << endl; // Check precondition assert (nprocs == 1); @@ -1145,30 +1309,57 @@ namespace Carpet { // Check postcondition assert (newregs.size() == oldsize + nprocs); - if (DEBUG) cout << "SRMAR exit" << endl; + if (recompose_verbose) cout << "SRMAR exit" << endl; return; } // Special case if (superreg.extent.empty()) { - if (DEBUG) cout << "SRMAR empty" << endl; + if (recompose_verbose) cout << "SRMAR empty" << endl; + + // Choose a direction + int mydim = -1; + for (int d=0; d<dim; ++d) { + if (not dims[d]) { + mydim = d; + break; + } + } + assert (mydim>=0 and mydim<dim); // Create a new region region_t newreg (superreg); newreg.outer_boundaries = b2vect(false); - if (DEBUG) cout << "SRMAR newreg " << newreg << endl; + if (recompose_verbose) cout << "SRMAR newreg " << newreg << endl; +#if 0 // Store for (int p=0; p<nprocs; ++p) { newreg.processor = firstproc + p; newregs.push_back (newreg); } + assert (superreg.processors == NULL); superreg.processors = new ipfulltree (); +#endif + + // Store + vector<int> bounds (nprocs+1); + vector<ipfulltree *> subtrees (nprocs); + for (int p=0; p<nprocs; ++p) { + newreg.processor = firstproc + p; + newregs.push_back (newreg); + bounds.AT(p) = newreg.extent.lower()[mydim]; + pseudoregion_t const preg (newreg.extent, newreg.processor); + subtrees.AT(p) = new ipfulltree (preg); + } + bounds.AT(nprocs) = newreg.extent.lower()[mydim]; + assert (superreg.processors == NULL); + superreg.processors = new ipfulltree (mydim, bounds, subtrees); // Check postcondition assert (newregs.size() == oldsize + nprocs); - if (DEBUG) cout << "SRMAR exit" << endl; + if (recompose_verbose) cout << "SRMAR exit" << endl; return; } @@ -1177,7 +1368,7 @@ namespace Carpet { CCTK_REAL const rfact = pow (nprocs / prod(rcost), CCTK_REAL(1)/dim); rcost *= rfact; assert (abs (prod (rcost) - nprocs) <= 1.0e-6); - if (DEBUG) cout << "SRMA shapes " << rcost << endl; + if (recompose_verbose) cout << "SRMA shapes " << rcost << endl; // Choose a direction int mydim = -1; @@ -1198,22 +1389,20 @@ namespace Carpet { } assert (mydim>=0 and mydim<dim); assert (mycost>=0); - if (DEBUG) cout << "SRMAR mydim " << mydim << endl; - if (DEBUG) cout << "SRMAR mycost " << mycost << endl; + if (recompose_verbose) cout << "SRMAR mydim " << mydim << endl; + if (recompose_verbose) cout << "SRMAR mycost " << mycost << endl; // Mark this direction as done assert (not dims[mydim]); bvect const newdims = dims.replace(mydim, true); // Choose a number of slices for this direction - int const nslices - = min (nprocs, - int (floor (mycost * pow(nprocs / totalcost, - CCTK_REAL(1) / alldims) + - CCTK_REAL(0.5)))); + CCTK_REAL const mycost1 = + mycost * pow(nprocs / totalcost, CCTK_REAL(1) / alldims); + int const nslices = min (nprocs, int (floor (mycost1 + CCTK_REAL(0.5)))); assert (nslices <= nprocs); - if (DEBUG) cout << "SRMAR " << mydim << " nprocs " << nprocs << endl; - if (DEBUG) cout << "SRMAR " << mydim << " nslices " << nslices << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " nprocs " << nprocs << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " nslices " << nslices << endl; // Split the remaining processors vector<int> mynprocs(nslices); @@ -1221,11 +1410,11 @@ namespace Carpet { int const mynprocs_left = nprocs - nslices * mynprocs_base; int sum_mynprocs = 0; for (int n=0; n<nslices; ++n) { - mynprocs.at(n) = mynprocs_base + int (n < mynprocs_left); - sum_mynprocs += mynprocs.at(n); + mynprocs.AT(n) = mynprocs_base + int (n < mynprocs_left); + sum_mynprocs += mynprocs.AT(n); } assert (sum_mynprocs == nprocs); - if (DEBUG) cout << "SRMAR " << mydim << " mynprocs " << mynprocs << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " mynprocs " << mynprocs << endl; // Split the region vector<int> mynpoints(nslices); @@ -1237,20 +1426,22 @@ namespace Carpet { int npoints_left = npoints; int nprocs_left = nprocs; for (int n=0; n<nslices; ++n) { - mynpoints.at(n) = int (floor (CCTK_REAL(1) * npoints_left * mynprocs.at(n) - / nprocs_left + CCTK_REAL(0.5))); - assert (mynprocs .at(n) > 0); - npoints_left -= mynpoints.at(n); - nprocs_left -= mynprocs.at(n); + assert (nprocs_left > 0); + CCTK_REAL const npoints1 = + CCTK_REAL(1) * npoints_left * mynprocs.AT(n) / nprocs_left; + mynpoints.AT(n) = int (floor (npoints1 + CCTK_REAL(0.5))); + assert (mynpoints.AT(n) >= 0 and mynpoints.AT(n) <= npoints_left); + npoints_left -= mynpoints.AT(n); + nprocs_left -= mynprocs.AT(n); assert (npoints_left >= 0); assert (nprocs_left >= 0); } assert (npoints_left == 0); assert (nprocs_left == 0); - if (DEBUG) cout << "SRMAR " << mydim << " mynpoints " << mynpoints << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " mynpoints " << mynpoints << endl; // Create the regions and recurse - if (DEBUG) cout << "SRMAR " << mydim << ": create bboxes" << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << ": create bboxes" << endl; ivect lo = superreg.extent.lower(); ivect up = superreg.extent.upper(); ivect const str = superreg.extent.stride(); @@ -1258,41 +1449,41 @@ namespace Carpet { vector<int> bounds (nslices+1); vector<ipfulltree *> subtrees (nslices); for (int n=0; n<nslices; ++n) { - if (DEBUG) cout << "SRMAR " << mydim << " n " << n << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " n " << n << endl; // Create a new region - up[mydim] = lo[mydim] + (mynpoints.at(n) - 1) * str[mydim]; + up[mydim] = lo[mydim] + (mynpoints.AT(n) - 1) * str[mydim]; b2vect newob (superreg.outer_boundaries); if (n > 0) { newob[0][mydim] = false; } if (n < nslices-1) { - up[mydim] = lo[mydim] + (mynpoints.at(n) - 1) * str[mydim]; + up[mydim] = lo[mydim] + (mynpoints.AT(n) - 1) * str[mydim]; newob[1][mydim] = false; } region_t newreg (superreg); newreg.extent = ibbox(lo, up, str); newreg.outer_boundaries = newob; - if (DEBUG) cout << "SRMAR " << mydim << " newreg " << newreg << endl; + if (recompose_verbose) cout << "SRMAR " << mydim << " newreg " << newreg << endl; // Recurse - bounds.at(n) = lo[mydim]; + bounds.AT(n) = lo[mydim]; SplitRegionsMaps_Automatic_Recursively - (newdims, p, mynprocs.at(n), newreg, newregs); - if (DEBUG) cout << "SRMAR " << mydim << " newregs " << newregs << endl; + (newdims, p, mynprocs.AT(n), newreg, newregs); + if (recompose_verbose) cout << "SRMAR " << mydim << " newregs " << newregs << endl; assert (newreg.processors != NULL); - subtrees.at(n) = newreg.processors; + subtrees.AT(n) = newreg.processors; newreg.processors = NULL; newreg.processor = p; // Next slice lo[mydim] = up[mydim] + str[mydim]; - p += mynprocs.at(n); + p += mynprocs.AT(n); } assert (up[mydim] == superreg.extent.upper()[mydim]); assert (p == firstproc + nprocs); - bounds.at(nslices) = up[mydim] + str[mydim]; + bounds.AT(nslices) = up[mydim] + str[mydim]; // Create tree assert (superreg.processors == NULL); @@ -1301,7 +1492,7 @@ namespace Carpet { // Check postcondition assert (newregs.size() == oldsize + nprocs); - if (DEBUG) cout << "SRMAR exit" << endl; + if (recompose_verbose) cout << "SRMAR exit" << endl; } @@ -1313,20 +1504,20 @@ namespace Carpet { { DECLARE_CCTK_PARAMETERS; - if (DEBUG) cout << "SRMA enter" << endl; + if (recompose_verbose) cout << "SRMA enter" << endl; int const nmaps = superregss.size(); int minmap = 1000000000; for (int m=0; m<nmaps; ++m) { - for (int r=0; r<int(superregss.at(m).size()); ++r) { - minmap = min (minmap, superregss.at(m).at(r).map); + for (int r=0; r<int(superregss.AT(m).size()); ++r) { + minmap = min (minmap, superregss.AT(m).AT(r).map); } } int nregs = 0; for (int m=0; m<nmaps; ++m) { - nregs += superregss.at(m).size(); + nregs += superregss.AT(m).size(); } - if (DEBUG) cout << "SRMA nregs " << nregs << endl; + if (recompose_verbose) cout << "SRMA nregs " << nregs << endl; // Something to do? if (nregs == 0) { @@ -1337,7 +1528,7 @@ namespace Carpet { vector<region_t> superregs; { for (int m=0; m<nmaps; ++m) { - combine_regions (superregss.at(m), superregs); + combine_regions (superregss.AT(m), superregs); } nregs = superregs.size(); @@ -1351,14 +1542,13 @@ namespace Carpet { reg.extent = ibbox (ivect (0), ivect (-1), ivect (1)); reg.outer_boundaries = b2vect (bvect (true), bvect (true)); reg.map = 0; - reg.processor = -1; superregs.push_back (reg); nregs = superregs.size(); } } int const real_nprocs = CCTK_nProcs (cctkGH); - if (DEBUG) cout << "SRMA real_nprocs " << real_nprocs << endl; + if (recompose_verbose) cout << "SRMA real_nprocs " << real_nprocs << endl; // Deactivate some processors if there are too many int nprocs; @@ -1367,109 +1557,155 @@ namespace Carpet { } else { CCTK_REAL mycost = 0; for (int r=0; r<nregs; ++r) { - mycost += prod (cost (superregs.at(r))); + mycost += prod (cost (superregs.AT(r))); } int const goodnprocs = int (floor (mycost / min_points_per_proc)); nprocs = max (1, min (real_nprocs, goodnprocs)); } - if (DEBUG) cout << "SRMA nprocs " << nprocs << endl; + if (recompose_verbose) cout << "SRMA nprocs " << nprocs << endl; // ncomps: number of components per processor int const ncomps = (nregs + nprocs - 1) / nprocs; - if (DEBUG) cout << "SRMA ncomps " << ncomps << endl; + if (recompose_verbose) cout << "SRMA ncomps " << ncomps << endl; assert (ncomps > 0); int const newnregs = nprocs * ncomps; - if (DEBUG) cout << "SRMA newnregs " << newnregs << endl; + if (recompose_verbose) cout << "SRMA newnregs " << newnregs << endl; - if (DEBUG) cout << "SRMA: distributing processors to regions" << endl; + if (recompose_verbose) cout << "SRMA: distributing processors to regions" << endl; vector<CCTK_REAL> mycosts(nregs); for (int r=0; r<nregs; ++r) { - mycosts.at(r) = prod (cost (superregs.at(r))); + mycosts.AT(r) = prod (cost (superregs.AT(r))); } int nregs_left = newnregs; vector<int> mynprocs(nregs); for (int r=0; r<nregs; ++r) { - mynprocs.at(r) = 1; + mynprocs.AT(r) = 1; -- nregs_left; } #warning "TODO: split regions if necessary" while (nregs_left > 0) { - if (DEBUG) cout << "SRMA nregs_left " << nregs_left << endl; + if (recompose_verbose) cout << "SRMA nregs_left " << nregs_left << endl; int maxr = -1; CCTK_REAL maxratio = -1; for (int r=0; r<nregs; ++r) { - CCTK_REAL const ratio = mycosts.at(r) / mynprocs.at(r); + CCTK_REAL const ratio = mycosts.AT(r) / mynprocs.AT(r); if (ratio > maxratio) { maxr=r; maxratio=ratio; } } assert (maxr>=0 and maxr<nregs); - ++ mynprocs.at(maxr); - if (DEBUG) cout << "SRMA maxr " << maxr << endl; - if (DEBUG) cout << "SRMA mynprocs[maxr] " << mynprocs.at(maxr) << endl; + ++ mynprocs.AT(maxr); + if (recompose_verbose) cout << "SRMA maxr " << maxr << endl; + if (recompose_verbose) cout << "SRMA mynprocs[maxr] " << mynprocs.AT(maxr) << endl; -- nregs_left; } assert (nregs_left == 0); int sum_nprocs = 0; for (int r=0; r<nregs; ++r) { - sum_nprocs += mynprocs.at(r); + sum_nprocs += mynprocs.AT(r); } assert (sum_nprocs == newnregs); - if (DEBUG) cout << "SRMA mynprocs " << mynprocs << endl; + if (recompose_verbose) cout << "SRMA mynprocs " << mynprocs << endl; - if (DEBUG) cout << "SRMA: splitting work units" << endl; + if (recompose_verbose) cout << "SRMA: splitting work units" << endl; #warning "TODO: rename newregs to regs" #warning "TODO: rename nregs to nsuperregs" #warning "TODO: rename newnregs to nregs" vector<region_t> newregs; newregs.reserve (newnregs); - for (int r=0, p=0; r<nregs; p+=mynprocs.at(r), ++r) { - if (DEBUG) cout << "SRMA superreg[" << r << "] " << superregs.at(r) << endl; + for (int r=0, p=0; r<nregs; p+=mynprocs.AT(r), ++r) { + if (recompose_verbose) cout << "SRMA superreg[" << r << "] " << superregs.AT(r) << endl; bvect const dims = false; SplitRegionsMaps_Automatic_Recursively - (dims, p, mynprocs.at(r), superregs.at(r), newregs); + (dims, p, mynprocs.AT(r), superregs.AT(r), newregs); } // for r - if (DEBUG) cout << "SRMA newregs " << newregs << endl; + if (recompose_verbose) cout << "SRMA newregs " << newregs << endl; assert (int(newregs.size()) == newnregs); // Count components per map vector<int> myncomps(nmaps, 0); +#if 0 vector<int> empty_comps(nmaps, 0); +#endif for (int r=0; r<newnregs; ++r) { - int const m = newregs.at(r).map - minmap; + int const m = newregs.AT(r).map - minmap; assert (m>=0 and m<nmaps); - if (not newregs.at(r).extent.empty()) { +#if 0 + if (not newregs.AT(r).extent.empty()) { // Ignore empty regions, which may come from empty grid arrays - ++ myncomps.at(m); + ++ myncomps.AT(m); } else { - ++ empty_comps.at(m); + ++ empty_comps.AT(m); } +#endif + ++ myncomps.AT(m); } vector<int> mynregs(nmaps, 0); +#if 0 + vector<int> empty_regs(nmaps, 0); +#endif for (int r=0; r<nregs; ++r) { - int const m = superregs.at(r).map - minmap; + int const m = superregs.AT(r).map - minmap; assert (m>=0 and m<nmaps); - ++ mynregs.at(m); + ++ mynregs.AT(m); +#if 0 + if (not superregs.AT(r).extent.empty()) { + // Ignore empty regions, which may come from empty grid arrays + ++ mynregs.AT(m); + } else { + ++ empty_regs.AT(m); + } +#endif } // Convert virtual to real processors for (int r=0; r<newnregs; ++r) { - newregs.at(r).processor /= ncomps; - assert (newregs.at(r).processor >= 0 and - newregs.at(r).processor < nprocs); + newregs.AT(r).processor /= ncomps; + assert (newregs.AT(r).processor >= 0 and + newregs.AT(r).processor < nprocs); } { vector<int> tmpncomps(nmaps, 0); for (int r=0; r<nregs; ++r) { - int const m = superregs.at(r).map - minmap; - ipfulltree * const regf = superregs.at(r).processors; + int const m = superregs.AT(r).map - minmap; + ipfulltree * const regf = superregs.AT(r).processors; assert (regf != NULL); for (ipfulltree::iterator fti (* regf); not fti.done(); ++ fti) { pseudoregion_t & preg = (* fti).payload(); - preg.component = tmpncomps.at(m)++; + preg.component = tmpncomps.AT(m)++; } } for (int m=0; m<nmaps; ++m) { - assert (tmpncomps.at(m) == myncomps.at(m)); +#warning "TODO" + if (not (tmpncomps.AT(m) == myncomps.AT(m))) { + cout << "Recompose.cc" << endl + << "superregss=" << superregss << endl + << "regss=" << regss << endl + << "nregs=" << nregs << endl + << "newregs=" << newregs << endl + << "newnregs=" << newnregs << endl + << "m=" << m << endl + << "tmpncomps.AT(m)=" << tmpncomps.AT(m) << endl + << "myncomps.AT(m)=" << myncomps.AT(m) << endl; + cout << "newregs:" << endl; + for (int r=0; r<newnregs; ++r) { + int const m = newregs.AT(r).map - minmap; + assert (m>=0 and m<nmaps); + cout << "r=" << r << endl + << "newregs=" << newregs.at(r) << endl + << "newregs.extent.size()=" << newregs.at(r).extent.size() << endl + << "newregs.extent.empty()=" << newregs.at(r).extent.empty() << endl; + } + cout << "*regf:" << endl; + for (int r=0; r<nregs; ++r) { + int const m = superregs.AT(r).map - minmap; + ipfulltree * const regf = superregs.AT(r).processors; + cout << "r=" << r << endl + << "m=" << m << endl; + cout << "*regf=" << *regf << endl; + } + cout.flush(); + } + assert (tmpncomps.AT(m) == myncomps.AT(m)); } } @@ -1477,34 +1713,37 @@ namespace Carpet { // Allocate regions assert ((int)regss.size() == nmaps); for (int m=0; m<nmaps; ++m) { - assert (regss.at(m).empty()); - regss.at(m).reserve (myncomps.at(m)); - superregss.at(m).clear(); - superregss.at(m).reserve (mynregs.at(m)); + assert (regss.AT(m).empty()); + regss.AT(m).reserve (myncomps.AT(m)); + superregss.AT(m).clear(); + superregss.AT(m).reserve (mynregs.AT(m)); } // Assign regions for (int r=0; r<newnregs; ++r) { - int const m = newregs.at(r).map - minmap; + int const m = newregs.AT(r).map - minmap; assert (m>=0 and m<nmaps); - regss.at(m).push_back (newregs.at(r)); + regss.AT(m).push_back (newregs.AT(r)); } for (int r=0; r<nregs; ++r) { - int const m = superregs.at(r).map - minmap; + int const m = superregs.AT(r).map - minmap; assert (m>=0 and m<nmaps); - superregss.at(m).push_back (superregs.at(r)); + superregss.AT(m).push_back (superregs.AT(r)); } // Output regions - if (DEBUG) { + if (recompose_verbose) { cout << "SRMA superregss " << superregss << endl; cout << "SRMA regss " << regss << endl; } // Check sizes for (int m=0; m<nmaps; ++m) { - assert (int(regss.at(m).size()) == myncomps.at(m) + empty_comps.at(m)); - assert (int(superregss.at(m).size()) == mynregs.at(m)); +#if 0 + assert (int(regss.AT(m).size()) == myncomps.AT(m) + empty_comps.AT(m)); +#endif + assert (int(regss.AT(m).size()) == myncomps.AT(m)); + assert (int(superregss.AT(m).size()) == mynregs.AT(m)); } - if (DEBUG) cout << "SRMA exit" << endl; + if (recompose_verbose) cout << "SRMA exit" << endl; } @@ -1547,30 +1786,30 @@ namespace Carpet { } } vector<ibbox> bases(mglevels); - bases.at(0) = base; + bases.AT(0) = base; for (int ml=1; ml<mglevels; ++ml) { // next finer base - ivect const fbaselo = bases.at(ml-1).lower(); - ivect const fbasehi = bases.at(ml-1).upper(); - ivect const fbasestr = bases.at(ml-1).stride(); + ivect const fbaselo = bases.AT(ml-1).lower(); + ivect const fbasehi = bases.AT(ml-1).upper(); + ivect const fbasestr = bases.AT(ml-1).stride(); // this base ivect const basestr = fbasestr * mgfact; ivect const baselo = fbaselo + (xpose(offset)[0] - ivect(mgfact) * xpose(offset)[0]) * fbasestr; ivect const basehi = fbasehi + (xpose(offset)[1] - ivect(mgfact) * xpose(offset)[1]) * fbasestr; ivect const baselo1 = baselo; ivect const basehi1 = baselo1 + (basehi - baselo1) / basestr * basestr; - bases.at(ml) = ibbox(baselo1, basehi1, basestr); + bases.AT(ml) = ibbox(baselo1, basehi1, basestr); // next finer grid - ivect const flo = regs.at(ml-1).extent.lower(); - ivect const fhi = regs.at(ml-1).extent.upper(); - ivect const fstr = regs.at(ml-1).extent.stride(); + ivect const flo = regs.AT(ml-1).extent.lower(); + ivect const fhi = regs.AT(ml-1).extent.upper(); + ivect const fstr = regs.AT(ml-1).extent.stride(); // this grid ivect const str = fstr * mgfact; ivect const lo = flo + either (reg.outer_boundaries[0], (xpose(offset)[0] - ivect(mgfact) * xpose(offset)[0]) * fstr, ivect(0)); ivect const hi = fhi + either (reg.outer_boundaries[1], - (xpose(offset)[1] - ivect(mgfact) * xpose(offset)[1]) * fstr, ivect(0)); ivect const lo1 = baselo1 + (lo - baselo1 + str - 1) / str * str; ivect const hi1 = lo1 + (hi - lo1) / str * str; - regs.at(ml).extent = ibbox(lo1, hi1, str); + regs.AT(ml).extent = ibbox(lo1, hi1, str); } } } @@ -1583,25 +1822,25 @@ namespace Carpet { { regsss.resize (mglevels); for (int ml=0; ml<mglevels; ++ml) { - regsss.at(ml).resize (regss.size()); + regsss.AT(ml).resize (regss.size()); for (int rl=0; rl<(int)regss.size(); ++rl) { - regsss.at(ml).at(rl).resize (regss.at(rl).size()); + regsss.AT(ml).AT(rl).resize (regss.AT(rl).size()); } } for (int rl=0; rl<(int)regss.size(); ++rl) { ibbox base; - for (int c=0; c<(int)regss.at(rl).size(); ++c) { - base = base.expanded_containing(regss.at(rl).at(c).extent); + for (int c=0; c<(int)regss.AT(rl).size(); ++c) { + base = base.expanded_containing(regss.AT(rl).AT(c).extent); } - for (int c=0; c<(int)regss.at(rl).size(); ++c) { + for (int c=0; c<(int)regss.AT(rl).size(); ++c) { vector<region_t> mg_regs; - MakeMultigridBoxes (cctkGH, m, base, regss.at(rl).at(c), mg_regs); + MakeMultigridBoxes (cctkGH, m, base, regss.AT(rl).AT(c), mg_regs); assert ((int)mg_regs.size() == mglevels); for (int ml=0; ml<mglevels; ++ml) { - regsss.at(ml).at(rl).at(c) = mg_regs.at(ml); + regsss.AT(ml).AT(rl).AT(c) = mg_regs.AT(ml); } } // for c @@ -1615,8 +1854,46 @@ namespace Carpet { vector<vector<vector<vector<region_t> > > > & regssss) { for (int m = 0; m < maps; ++m) { - MakeMultigridBoxes (cctkGH, m, regsss.at(m), regssss.at(m)); + MakeMultigridBoxes (cctkGH, m, regsss.AT(m), regssss.AT(m)); } // for m } + + + static + void + ClassifyPoints (cGH const * const cctkGH, int const rl) + { + // negative: needs to be set explicitly (e.g. boundary) + // zero: unused (e.g. ghost) + // positive: needs to be evolved + // -1: boundary point (needs to be set explicitly) + // 0: unused (e.g. ghost point, or restriction target) + // n=1..N: evolved, used for integrator substeps i<=n + // (i=N..1, counting backwards; see MoL documentation) + // i.e.: n=1: used between time steps (i.e., should be visualised) + // n>1: used only while time stepping (e.g. buffer zones) + + BEGIN_META_MODE(cctkGH) { + BEGIN_MGLEVEL_LOOP (cctkGH) { + ENTER_LEVEL_MODE (cctkGH, rl) { + BEGIN_LOCAL_MAP_LOOP(cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP(cctkGH, CCTK_GF) { + DECLARE_CCTK_ARGUMENTS; +#pragma omp parallel + LC_LOOP3 (CarpetClassifyPoints, + i,j,k, + 0,0,0, cctk_lsh[0],cctk_lsh[1],cctk_lsh[2], + cctk_lsh[0],cctk_lsh[1],cctk_lsh[2]) + { + int const ind = CCTK_GFINDEX3D (cctkGH, i, j, k); + point_class[ind] = 1; + } LC_ENDLOOP3(CarpetClassifyPoints); + } END_LOCAL_COMPONENT_LOOP; + } END_LOCAL_MAP_LOOP; + } LEAVE_LEVEL_MODE; + } END_MGLEVEL_LOOP; + } END_META_MODE; + } + } // namespace Carpet |