aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetLib/src/dh.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/CarpetLib/src/dh.cc')
-rw-r--r--Carpet/CarpetLib/src/dh.cc1232
1 files changed, 959 insertions, 273 deletions
diff --git a/Carpet/CarpetLib/src/dh.cc b/Carpet/CarpetLib/src/dh.cc
index 046600c6b..36b3c310f 100644
--- a/Carpet/CarpetLib/src/dh.cc
+++ b/Carpet/CarpetLib/src/dh.cc
@@ -3,6 +3,9 @@
#include "cctk.h"
#include "cctk_Parameters.h"
+#include "CarpetTimers.hh"
+
+#include "mpi_string.hh"
#include "bbox.hh"
#include "bboxset.hh"
#include "defs.hh"
@@ -19,6 +22,10 @@ using namespace CarpetLib;
+list<dh*> dh::alldh;
+
+
+
// Constructors
dh::
dh (gh & h_,
@@ -31,12 +38,14 @@ dh (gh & h_,
assert (all (all (ghost_width >= 0)));
assert (all (all (buffer_width >= 0)));
assert (prolongation_order_space >= 0);
- h.add (this);
+ alldhi = alldh.insert(alldh.end(), this);
+ gh_handle = h.add (this);
CHECKPOINT;
- regrid ();
+ regrid (false);
for (int rl = 0; rl < h.reflevels(); ++ rl) {
recompose (rl, false);
}
+ regrid_free (false);
}
@@ -46,7 +55,8 @@ dh::
~dh ()
{
CHECKPOINT;
- h.remove (this);
+ h.erase (gh_handle);
+ alldh.erase(alldhi);
}
@@ -135,6 +145,15 @@ assert_error (char const * restrict const checkstring,
there_was_an_error = true;
}
+#ifdef CARPET_OPTIMISE
+
+// For highest efficiency, omit all self-checks
+#define ASSERT_rl(check, message)
+#define ASSERT_c(check, message)
+#define ASSERT_cc(check, message)
+
+#else
+
#define ASSERT_rl(check, message) \
do { \
if (not (check)) { \
@@ -156,41 +175,60 @@ assert_error (char const * restrict const checkstring,
} \
} while (false)
+#endif
+
void
dh::
-regrid ()
+regrid (bool const do_init)
{
DECLARE_CCTK_PARAMETERS;
+
+ static Carpet::Timer timer ("CarpetLib::dh::regrid");
+ timer.start();
CHECKPOINT;
- static Timer total ("dh::regrid");
+ static Timer total ("CarpetLib::dh::regrid");
total.start ();
- oldboxes.clear();
+ mboxes oldboxes;
swap (boxes, oldboxes);
- fast_oldboxes.clear();
- swap (fast_boxes, fast_oldboxes);
+
+ full_mboxes full_boxes;
+
+ fast_boxes.clear();
+ // cerr << "QQQ: regrid[1]" << endl;
boxes.resize (h.mglevels());
+ full_boxes.resize (h.mglevels());
fast_boxes.resize (h.mglevels());
for (int ml = 0; ml < h.mglevels(); ++ ml) {
+ // cerr << "QQQ: regrid[2] ml=" << ml << endl;
boxes.AT(ml).resize (h.reflevels());
+ full_boxes.AT(ml).resize (h.reflevels());
fast_boxes.AT(ml).resize (h.reflevels());
for (int rl = 0; rl < h.reflevels(); ++ rl) {
+ // cerr << "QQQ: regrid[3] rl=" << rl << endl;
boxes.AT(ml).AT(rl).resize (h.components(rl));
- fast_boxes.AT(ml).AT(rl).resize (dist::size());
+ full_boxes.AT(ml).AT(rl).resize (h.components(rl));
cboxes & level = boxes.AT(ml).AT(rl);
- fast_cboxes & fast_level = fast_boxes.AT(ml).AT(rl);
+ full_cboxes & full_level = full_boxes.AT(ml).AT(rl);
+ fast_dboxes & fast_level = fast_boxes.AT(ml).AT(rl);
+
+ vector<fast_dboxes> fast_level_otherprocs (dist::size());
// Domain:
+ // cerr << "QQQ: regrid[a]" << endl;
+
+ static Carpet::Timer timer_domain ("CarpetLib::dh::regrid::domain");
+ timer_domain.start();
ibbox const & domain_exterior = h.baseextent(ml,rl);
// Variables may have size zero
@@ -211,17 +249,24 @@ regrid ()
ibset domain_boundary = domain_exterior - domain_active;
domain_boundary.normalize();
+ timer_domain.stop();
+
+ static Carpet::Timer timer_region ("CarpetLib::dh::regrid::region");
+ timer_region.start();
+
+ // cerr << "QQQ: regrid[b]" << endl;
for (int c = 0; c < h.components(rl); ++ c) {
- dboxes & box = boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes & box = full_level.AT(c);
// Interior:
ibbox & intr = box.interior;
+ intr = ibbox::poison();
// The interior of the grid has the extent as specified by the
// regridding thorn
@@ -237,10 +282,12 @@ regrid ()
"The interior must be contained in the domain");
// All interiors must be disjunct
+#ifdef CARPET_DEBUG
for (int cc = 0; cc < c; ++ cc) {
- ASSERT_cc (not intr.intersects (level.AT(cc).interior),
+ ASSERT_cc (not intr.intersects (full_level.AT(cc).interior),
"All interiors must be disjunct");
}
+#endif
@@ -261,6 +308,7 @@ regrid ()
// Exterior:
ibbox & extr = box.exterior;
+ extr = ibbox::poison();
ASSERT_c (all (all (ghost_width >= 0)),
"The gh ghost widths must not be negative");
@@ -280,6 +328,7 @@ regrid ()
// Cactus ghost zones (which include outer boundaries):
ibset & ghosts = box.ghosts;
+ ghosts = ibset::poison();
ghosts = extr - intr;
ghosts.normalize();
@@ -295,6 +344,7 @@ regrid ()
// Communicated region:
ibbox & comm = box.communicated;
+ comm = ibbox::poison();
comm = extr.expand (i2vect (is_outer_boundary) * (- boundary_width));
@@ -313,6 +363,7 @@ regrid ()
// Outer boundary:
ibset & outer_boundaries = box.outer_boundaries;
+ outer_boundaries = ibset::poison();
outer_boundaries = extr - comm;
outer_boundaries.normalize();
@@ -327,6 +378,7 @@ regrid ()
// Owned region:
ibbox & owned = box.owned;
+ owned = ibbox::poison();
owned = intr.expand (i2vect (is_outer_boundary) * (- boundary_width));
@@ -341,10 +393,12 @@ regrid ()
"The owned region must be contained in the active part of the domain");
// All owned regions must be disjunct
+#ifdef CARPET_DEBUG
for (int cc = 0; cc < c; ++ cc) {
- ASSERT_cc (not owned.intersects (level.AT(cc).owned),
+ ASSERT_cc (not owned.intersects (full_level.AT(cc).owned),
"All owned regions must be disjunct");
}
+#endif
@@ -352,6 +406,7 @@ regrid ()
// boundaries):
ibset & boundaries = box.boundaries;
+ boundaries = ibset::poison();
boundaries = comm - owned;
boundaries.normalize();
@@ -365,9 +420,15 @@ regrid ()
} // for c
+ timer_region.stop();
+
// Conjunction of all buffer zones:
+ // cerr << "QQQ: regrid[c]" << endl;
+
+ static Carpet::Timer timer_buffers ("CarpetLib::dh::regrid::buffers");
+ timer_buffers.start();
// Enlarge active part of domain
i2vect const safedist = i2vect (0);
@@ -376,7 +437,7 @@ regrid ()
// All owned regions
ibset allowned;
for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes const & box = full_level.AT(c);
allowned += box.owned;
}
allowned.normalize();
@@ -409,20 +470,13 @@ regrid ()
for (int c = 0; c < h.components(rl); ++ c) {
-
- dboxes & box = boxes.AT(ml).AT(rl).AT(c);
-
-
+ full_dboxes & box = full_level.AT(c);
// Buffer zones:
-
box.buffers = box.owned & allbuffers;
box.buffers.normalize();
-
-
// Active region:
-
box.active = box.owned - box.buffers;
box.active.normalize();
@@ -431,22 +485,29 @@ regrid ()
// The conjunction of all buffer zones must equal allbuffers
+ // cerr << "QQQ: regrid[d]" << endl;
ibset allbuffers1;
for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes const & box = full_level.AT(c);
allbuffers1 += box.buffers;
}
allbuffers1.normalize();
ASSERT_rl (allbuffers1 == allbuffers,
"Buffer zone consistency check");
+ timer_buffers.stop();
+
// Test constituency relations:
+ // cerr << "QQQ: regrid[e]" << endl;
+
+ static Carpet::Timer timer_test ("CarpetLib::dh::regrid::test");
+ timer_test.start();
for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes const & box = full_level.AT(c);
ASSERT_c ((box.active & box.buffers).empty(),
"Consistency check");
@@ -473,24 +534,36 @@ regrid ()
} // for c
+ timer_test.stop();
+
// Communication schedule:
+ // cerr << "QQQ: regrid[4]" << endl;
- for (int c = 0; c < h.components(rl); ++ c) {
+ static Carpet::Timer timer_comm ("CarpetLib::dh::regrid::comm");
+ timer_comm.start();
+
+ for (int lc = 0; lc < h.local_components(rl); ++ lc) {
+ int const c = h.get_component (rl, lc);
+ // cerr << "QQQ: regrid[4a] lc=" << lc << " c=" << c << endl;
- dboxes & box = boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes & box = full_level.AT(c);
// Multigrid restriction:
+ static Carpet::Timer timer_comm_mgrest
+ ("CarpetLib::dh::regrid::comm::mgrest");
+ timer_comm_mgrest.start();
+
if (ml > 0) {
int const oml = ml - 1;
// Multigrid restriction must fill all active points
- dboxes const & obox = boxes.AT(oml).AT(rl).AT(c);
+ full_dboxes const & obox = full_boxes.AT(oml).AT(rl).AT(c);
ibset needrecv = box.active;
@@ -513,11 +586,8 @@ regrid ()
ibbox const send = recv.expanded_for (obox.interior);
ASSERT_c (send <= obox.exterior,
"Multigrid restriction: Send region must be contained in exterior");
- if (on_this_proc (rl, c)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_mg_rest_sendrecv.push_back
- (sendrecv_pseudoregion_t (send, c, recv, c));
- }
+ fast_level.fast_mg_rest_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, c, recv, c));
}
needrecv -= ovlp;
@@ -529,9 +599,16 @@ regrid ()
} // if ml > 0
+ timer_comm_mgrest.stop();
+
// Multigrid prolongation:
+ // cerr << "QQQ: regrid[f]" << endl;
+
+ static Carpet::Timer timer_comm_mgprol
+ ("CarpetLib::dh::regrid::comm::mprol");
+ timer_comm_mgprol.start();
if (ml > 0) {
int const oml = ml - 1;
@@ -539,7 +616,7 @@ regrid ()
// Multigrid prolongation must fill all active points
// (this could probably be relaxed)
- dboxes const & obox = boxes.AT(oml).AT(rl).AT(c);
+ full_dboxes const & obox = full_boxes.AT(oml).AT(rl).AT(c);
ibset oneedrecv = obox.active;
@@ -565,11 +642,8 @@ regrid ()
recv.expanded_for (box.interior).expand (stencil_size);
ASSERT_c (send <= box.exterior,
"Multigrid prolongation: Send region must be contained in exterior");
- if (on_this_proc (rl, c)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_mg_prol_sendrecv.push_back
- (sendrecv_pseudoregion_t (send, c, recv, c));
- }
+ fast_level.fast_mg_prol_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, c, recv, c));
}
oneedrecv -= ovlp;
@@ -581,9 +655,16 @@ regrid ()
} // if ml > 0
+ timer_comm_mgprol.stop();
+
// Refinement prolongation:
+ // cerr << "QQQ: regrid[g]" << endl;
+
+ static Carpet::Timer timer_comm_refprol
+ ("CarpetLib::dh::regrid::comm::refprol");
+ timer_comm_refprol.start();
if (rl > 0) {
int const orl = rl - 1;
@@ -600,7 +681,7 @@ regrid ()
i2vect (h.reffacts.at(rl) / h.reffacts.at(orl));
for (int cc = 0; cc < h.components(orl); ++ cc) {
- dboxes const & obox = boxes.AT(ml).AT(orl).AT(cc);
+ full_dboxes const & obox = full_boxes.AT(ml).AT(orl).AT(cc);
ibset contracted_oactive;
for (ibset::const_iterator
@@ -617,16 +698,19 @@ regrid ()
ovlp.normalize();
for (ibset::const_iterator
- ri =ovlp.begin(); ri != ovlp.end(); ++ ri)
+ ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
{
ibbox const & recv = * ri;
ibbox const send =
recv.expanded_for (obox.interior).expand (stencil_size);
ASSERT_c (send <= obox.exterior,
"Refinement prolongation: Send region must be contained in exterior");
- if (on_this_proc (rl, c) or on_this_proc (orl, cc)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_ref_prol_sendrecv.push_back
+ fast_level.fast_ref_prol_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, cc, recv, c));
+ if (not on_this_proc (orl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(orl, cc));
+ fast_level_otherproc.fast_ref_prol_sendrecv.push_back
(sendrecv_pseudoregion_t (send, cc, recv, c));
}
}
@@ -635,83 +719,120 @@ regrid ()
} // for cc
- needrecv.normalize();
-
// All points must have been received
+ needrecv.normalize();
ASSERT_c (needrecv.empty(),
"Refinement prolongation: All points must have been received");
} // if rl > 0
+ timer_comm_refprol.stop();
+
// Synchronisation:
+ // cerr << "QQQ: regrid[h]" << endl;
- // Synchronisation should fill as many boundary points as
- // possible
+ static Carpet::Timer timer_comm_sync
+ ("CarpetLib::dh::regrid::comm::sync");
+ timer_comm_sync.start();
+ {
+
+ // Synchronisation should fill as many boundary points as
+ // possible
+
#if 0
- // Outer boundaries are not synchronised, since they cannot be
- // filled by boundary prolongation either, and therefore the
- // user code must set them anyway.
- ibset needrecv = box.boundaries;
+ // Outer boundaries are not synchronised, since they cannot
+ // be filled by boundary prolongation either, and therefore
+ // the user code must set them anyway.
+ ibset needrecv = box.boundaries;
#else
- // Outer boundaries are synchronised for backward
- // compatibility.
- ibset needrecv = box.ghosts;
+ // Outer boundaries are synchronised for backward
+ // compatibility.
+ ibset needrecv = box.ghosts;
#endif
-
- ibset & sync = box.sync;
-
- for (int cc = 0; cc < h.components(rl); ++ cc) {
- dboxes const & obox = boxes.AT(ml).AT(rl).AT(cc);
+ ibset const needrecv_orig = needrecv;
+ ibset & sync = box.sync;
+
+ for (int cc = 0; cc < h.components(rl); ++ cc) {
+ full_dboxes const & obox = full_level.AT(cc);
+
#if 0
- ibset ovlp = needrecv & obox.owned;
+ ibset ovlp = needrecv & obox.owned;
#else
- ibset ovlp = needrecv & obox.interior;
+ ibset ovlp = needrecv & obox.interior;
#endif
- ovlp.normalize();
-
- if (cc == c) {
- ASSERT_cc (ovlp.empty(),
- "A region may not synchronise from itself");
- }
-
- for (ibset::const_iterator
- ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
- {
- ibbox const & recv = * ri;
- ibbox const & send = recv;
- if (on_this_proc (rl, c) or on_this_proc (rl, cc)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_sync_sendrecv.push_back
+ ovlp.normalize();
+
+ if (cc == c) {
+ ASSERT_cc (ovlp.empty(),
+ "A region may not synchronise from itself");
+ }
+
+ for (ibset::const_iterator
+ ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
+ {
+ ibbox const & recv = * ri;
+ ibbox const & send = recv;
+ fast_level.fast_sync_sendrecv.push_back
(sendrecv_pseudoregion_t (send, cc, recv, c));
+ if (not on_this_proc (rl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(rl, cc));
+ fast_level_otherproc.fast_sync_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, cc, recv, c));
+ }
}
- }
+
+ needrecv -= ovlp;
+ sync += ovlp;
+
+ } // for cc
- needrecv -= ovlp;
- sync += ovlp;
+ sync.normalize();
- } // for cc
+ }
- needrecv.normalize();
- sync.normalize();
+ timer_comm_sync.stop();
// Boundary prolongation:
+ // cerr << "QQQ: regrid[i]" << endl;
+
+ static Carpet::Timer timer_comm_refbndprol
+ ("CarpetLib::dh::regrid::comm::refbndprol");
+ timer_comm_refbndprol.start();
if (rl > 0) {
int const orl = rl - 1;
+#if 0
+ // Outer boundaries are not synchronised, since they cannot
+ // be filled by boundary prolongation either, and therefore
+ // the user code must set them anyway.
+ ibset needrecv = box.boundaries;
+#else
+ // Outer boundaries are synchronised for backward
+ // compatibility.
+ ibset needrecv = box.ghosts;
+#endif
+
+ // Points which are synchronised need not be boundary
+ // prolongated
+ needrecv -= box.sync;
+
// Outer boundary points cannot be boundary prolongated
needrecv &= box.communicated;
// Prolongation must fill what cannot be synchronised, and
// also all buffer zones
needrecv += box.buffers;
+
needrecv.normalize();
+ ibset const needrecv_orig = needrecv;
ibset & bndref = box.bndref;
@@ -721,9 +842,10 @@ regrid ()
"Refinement factors must be integer multiples of each other");
i2vect const reffact =
i2vect (h.reffacts.at(rl) / h.reffacts.at(orl));
+ ivect const reffact1 = h.reffacts.at(rl) / h.reffacts.at(orl);
for (int cc = 0; cc < h.components(orl); ++ cc) {
- dboxes const & obox = boxes.AT(ml).AT(orl).AT(cc);
+ full_dboxes const & obox = full_boxes.AT(ml).AT(orl).AT(cc);
ibset contracted_oactive;
for (ibset::const_iterator
@@ -747,251 +869,522 @@ regrid ()
recv.expanded_for (obox.interior).expand (stencil_size);
ASSERT_c (send <= obox.exterior,
"Boundary prolongation: Send region must be contained in exterior");
- if (on_this_proc (rl, c) or on_this_proc (orl, cc)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_ref_bnd_prol_sendrecv.push_back
+ fast_level.fast_ref_bnd_prol_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, cc, recv, c));
+ if (not on_this_proc (orl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(orl, cc));
+ fast_level_otherproc.fast_ref_bnd_prol_sendrecv.push_back
(sendrecv_pseudoregion_t (send, cc, recv, c));
}
}
needrecv -= ovlp;
bndref += ovlp;
-
+
} // for cc
- needrecv.normalize();
bndref.normalize();
+ // All points must now have been received, either through
+ // synchronisation or through boundary prolongation
+ needrecv.normalize();
+ ASSERT_c (needrecv.empty(),
+ "Synchronisation and boundary prolongation: All points must have been received");
+
} // if rl > 0
- // All points must now have been received, either through
- // synchronisation or through boundary prolongation
- ASSERT_c (needrecv.empty(),
- "Synchronisation and boundary prolongation: All points must have been received");
+ timer_comm_refbndprol.stop();
- } // for c
+ } // for lc
// Refinement restriction:
+ // cerr << "QQQ: regrid[j]" << endl;
+
+ static Carpet::Timer timer_comm_refrest
+ ("CarpetLib::dh::regrid::comm::refrest");
+ timer_comm_refrest.start();
if (rl > 0) {
int const orl = rl - 1;
- fast_cboxes & fast_olevel = fast_boxes.AT(ml).AT(orl);
-
- ibset needrecv;
- for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
- dboxes const & obox0 = boxes.AT(ml).AT(orl).AT(0);
-
- // Refinement restriction may fill all active points, and
- // must use all active points
-
- for (ibset::const_iterator
- ai = box.active.begin(); ai != box.active.end(); ++ ai)
- {
- ibbox const & active = * ai;
- needrecv += active.contracted_for (obox0.interior);
- }
- needrecv.normalize();
- } // for c
+ fast_dboxes & fast_olevel = fast_boxes.AT(ml).AT(orl);
- for (int cc = 0; cc < h.components(orl); ++ cc) {
- dboxes & obox = boxes.AT(ml).AT(orl).AT(cc);
-
- for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
+ if (h.components(orl) > 0) {
+ for (int lc = 0; lc < h.local_components(rl); ++ lc) {
+ int const c = h.get_component (rl, lc);
+
+ full_dboxes const & box = full_level.AT(c);
+ full_dboxes const & obox0 = full_boxes.AT(ml).AT(orl).AT(0);
+
+ // Refinement restriction may fill all active points, and
+ // must use all active points
- ibset contracted_active;
+ ibset needrecv;
for (ibset::const_iterator
ai = box.active.begin(); ai != box.active.end(); ++ ai)
{
ibbox const & active = * ai;
- contracted_active += active.contracted_for (obox.interior);
+ needrecv += active.contracted_for (obox0.interior);
}
- contracted_active.normalize();
+ needrecv.normalize();
- ibset ovlp = obox.active & contracted_active;
- ovlp.normalize();
-
- for (ibset::const_iterator
- ri =ovlp.begin(); ri != ovlp.end(); ++ ri)
- {
- ibbox const & recv = * ri;
- ibbox const send = recv.expanded_for (box.interior);
- ASSERT_c (send <= box.active,
- "Refinement restriction: Send region must be contained in active part");
- if (on_this_proc (rl, c) or on_this_proc (orl, cc)) {
- int const p = dist::rank();
- fast_olevel.AT(p).fast_ref_rest_sendrecv.push_back
+ for (int cc = 0; cc < h.components(orl); ++ cc) {
+ full_dboxes & obox = full_boxes.AT(ml).AT(orl).AT(cc);
+
+ ibset contracted_active;
+ for (ibset::const_iterator
+ ai = box.active.begin(); ai != box.active.end(); ++ ai)
+ {
+ ibbox const & active = * ai;
+ contracted_active += active.contracted_for (obox0.interior);
+ }
+ contracted_active.normalize();
+
+ ibset ovlp = obox.active & contracted_active;
+ ovlp.normalize();
+
+ for (ibset::const_iterator
+ ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
+ {
+ ibbox const & recv = * ri;
+ ibbox const send = recv.expanded_for (box.interior);
+ ASSERT_c (send <= box.active,
+ "Refinement restriction: Send region must be contained in active part");
+ fast_olevel.fast_ref_rest_sendrecv.push_back
(sendrecv_pseudoregion_t (send, c, recv, cc));
+ if (not on_this_proc (orl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(orl, cc));
+ fast_level_otherproc.fast_ref_rest_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, c, recv, cc));
+ }
}
- }
-
- needrecv -= ovlp;
- } // for c
-
- } // for cc
-
- needrecv.normalize();
-
- // All points must have been received
- ASSERT_rl (needrecv.empty(),
- "Refinement restriction: All points must have been received");
+ needrecv -= ovlp;
+
+ } // for cc
+
+ // All points must have been received
+ needrecv.normalize();
+ ASSERT_rl (needrecv.empty(),
+ "Refinement restriction: All points must have been received");
+
+ } // for lc
+ } // if orl not empty
} // if rl > 0
+ timer_comm_refrest.stop();
+
+ timer_comm.stop();
+
// Regridding schedule:
+ // cerr << "QQQ: regrid[5]" << endl;
- for (int c = 0; c < h.components(rl); ++ c) {
-
- dboxes & box = boxes.AT(ml).AT(rl).AT(c);
-
- ibset needrecv = box.active;
+ fast_level.do_init = do_init;
+ if (do_init) {
+ static Carpet::Timer timer_regrid ("CarpetLib::dh::regrid::regrid");
+ timer_regrid.start();
+ for (int lc = 0; lc < h.local_components(rl); ++ lc) {
+ int const c = h.get_component (rl, lc);
+ // cerr << "QQQ: regrid[5a] lc=" << lc << " c=" << c << endl;
- // Synchronisation:
-
- if (int (oldboxes.size()) > ml and int (oldboxes.AT(ml).size()) > rl) {
+ full_dboxes & box = full_level.AT(c);
- int const oldcomponents = oldboxes.AT(ml).AT(rl).size();
+ ibset needrecv = box.active;
- // Synchronisation copies from the same level of the old
- // grid structure. It should fill as many active points as
- // possible
- for (int cc = 0; cc < oldcomponents; ++ cc) {
- dboxes const & obox = oldboxes.AT(ml).AT(rl).AT(cc);
+
+ // Synchronisation:
+ // cerr << "QQQ: regrid[k]" << endl;
+
+ static Carpet::Timer timer_regrid_sync
+ ("CarpetLib::dh::regrid::regrid::sync");
+ timer_regrid_sync.start();
+
+ if (int (oldboxes.size()) > ml and int (oldboxes.AT(ml).size()) > rl)
+ {
- ibset ovlp = needrecv & obox.owned;
- ovlp.normalize();
+ int const oldcomponents = oldboxes.AT(ml).AT(rl).size();
- for (ibset::const_iterator
- ri =ovlp.begin(); ri != ovlp.end(); ++ ri)
- {
- ibbox const & recv = * ri;
- ibbox const & send = recv;
- if (on_this_proc (rl, c) or on_this_oldproc (rl, cc)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_old2new_sync_sendrecv.push_back
+ // Synchronisation copies from the same level of the old
+ // grid structure. It should fill as many active points
+ // as possible.
+
+ for (int cc = 0; cc < oldcomponents; ++ cc) {
+ dboxes const & obox = oldboxes.AT(ml).AT(rl).AT(cc);
+
+ ibset ovlp = needrecv & obox.owned;
+ ovlp.normalize();
+
+ for (ibset::const_iterator
+ ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
+ {
+ ibbox const & recv = * ri;
+ ibbox const & send = recv;
+ fast_level.fast_old2new_sync_sendrecv.push_back
(sendrecv_pseudoregion_t (send, cc, recv, c));
+ if (not on_this_oldproc (rl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(rl, cc));
+ fast_level_otherproc.fast_old2new_sync_sendrecv.push_back
+ (sendrecv_pseudoregion_t (send, cc, recv, c));
+ }
}
- }
+
+ needrecv -= ovlp;
+
+ } // for cc
- needrecv -= ovlp;
+ needrecv.normalize();
- } // for cc
+ } // if not oldboxes.empty
- needrecv.normalize();
-
- } // if not oldboxes.empty
-
-
-
- // Prolongation:
-
- if (rl > 0) {
- int const orl = rl - 1;
+ timer_regrid_sync.stop();
- // Prolongation interpolates from the next coarser level of
- // the new grid structure. It must fill what cannot be
- // synchronised
-
- i2vect const stencil_size = i2vect (prolongation_stencil_size());
- ASSERT_c (all (h.reffacts.at(rl) % h.reffacts.at(orl) == 0),
- "Refinement factors must be integer multiples of each other");
- i2vect const reffact =
- i2vect (h.reffacts.at(rl) / h.reffacts.at(orl));
- for (int cc = 0; cc < h.components(orl); ++ cc) {
- dboxes const & obox = boxes.AT(ml).AT(orl).AT(cc);
+ // Prolongation:
+ // cerr << "QQQ: regrid[l]" << endl;
+
+ static Carpet::Timer timer_regrid_prolongate
+ ("CarpetLib::dh::regrid::regrid::prolongate");
+ timer_regrid_prolongate.start();
+
+ if (rl > 0) {
+ int const orl = rl - 1;
- ibset contracted_oactive;
- for (ibset::const_iterator
- ai = obox.active.begin(); ai != obox.active.end(); ++ ai)
- {
- ibbox const & oactive = * ai;
- // untested for cell centering
- contracted_oactive +=
- oactive.contracted_for (box.interior).expand (reffact);
- }
- contracted_oactive.normalize();
+ // Prolongation interpolates from the next coarser level
+ // of the new grid structure. It must fill what cannot be
+ // synchronised.
- ibset ovlp = needrecv & contracted_oactive;
- ovlp.normalize();
+ i2vect const stencil_size = i2vect (prolongation_stencil_size());
- for (ibset::const_iterator
- ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
- {
- ibbox const & recv = * ri;
- ibbox const send =
- recv.expanded_for (obox.interior).expand (stencil_size);
- ASSERT_c (send <= obox.exterior,
- "Regridding prolongation: Send region must be contained in exterior");
- if (on_this_proc (rl, c) or on_this_proc (orl, cc)) {
- int const p = dist::rank();
- fast_level.AT(p).fast_old2new_ref_prol_sendrecv.push_back
+ ASSERT_c (all (h.reffacts.at(rl) % h.reffacts.at(orl) == 0),
+ "Refinement factors must be integer multiples of each other");
+ i2vect const reffact =
+ i2vect (h.reffacts.at(rl) / h.reffacts.at(orl));
+
+ for (int cc = 0; cc < h.components(orl); ++ cc) {
+ full_dboxes const & obox = full_boxes.AT(ml).AT(orl).AT(cc);
+
+ ibset contracted_oactive;
+ for (ibset::const_iterator
+ ai = obox.active.begin(); ai != obox.active.end(); ++ ai)
+ {
+ ibbox const & oactive = * ai;
+ // untested for cell centering
+ contracted_oactive +=
+ oactive.contracted_for (box.interior).expand (reffact);
+ }
+ contracted_oactive.normalize();
+
+ ibset ovlp = needrecv & contracted_oactive;
+ ovlp.normalize();
+
+ for (ibset::const_iterator
+ ri = ovlp.begin(); ri != ovlp.end(); ++ ri)
+ {
+ ibbox const & recv = * ri;
+ ibbox const send =
+ recv.expanded_for (obox.interior).expand (stencil_size);
+ ASSERT_c (send <= obox.exterior,
+ "Regridding prolongation: Send region must be contained in exterior");
+ fast_level.fast_old2new_ref_prol_sendrecv.push_back
(sendrecv_pseudoregion_t (send, cc, recv, c));
+ if (not on_this_proc (orl, cc)) {
+ fast_dboxes & fast_level_otherproc =
+ fast_level_otherprocs.AT(this_proc(orl, cc));
+ fast_level_otherproc.fast_old2new_ref_prol_sendrecv.
+ push_back (sendrecv_pseudoregion_t (send, cc, recv, c));
+ }
}
- }
+
+ needrecv -= ovlp;
+
+ } // for cc
- needrecv -= ovlp;
+ needrecv.normalize();
- } // for cc
+ } // if rl > 0
- needrecv.normalize();
+ if (int (oldboxes.size()) > ml and int (oldboxes.AT(ml).size()) > 0) {
+ // All points must now have been received, either through
+ // synchronisation or through prolongation
+ ASSERT_c (needrecv.empty(),
+ "Regridding prolongation: All points must have been received");
+ }
- } // if rl > 0
+ timer_regrid_prolongate.stop();
+
+ } // for lc
- if (int (oldboxes.size()) > ml and int (oldboxes.AT(ml).size()) > 0) {
- // All points must now have been received, either through
- // synchronisation or through prolongation
- ASSERT_c (needrecv.empty(),
- "Regridding prolongation: All points must have been received");
+ timer_regrid.stop();
+
+ } // if do_init
+
+
+
+ // cerr << "QQQ: regrid[6]" << endl;
+ for (int lc = 0; lc < h.local_components(rl); ++ lc) {
+ int const c = h.get_component (rl, lc);
+
+ level.AT(c).exterior = full_level.AT(c).exterior;
+ level.AT(c).owned = full_level.AT(c).owned;
+ level.AT(c).interior = full_level.AT(c).interior;
+
+ level.AT(c).exterior_size = full_level.AT(c).exterior.size();
+ level.AT(c).owned_size = full_level.AT(c).owned.size();
+ level.AT(c).active_size = full_level.AT(c).active.size();
+
+ } // for lc
+
+
+
+ // Broadcast grid structure and communication schedule
+ // cerr << "QQQ: regrid[7]" << endl;
+
+ {
+
+ static Carpet::Timer timer_bcast_boxes
+ ("CarpetLib::dh::regrid::bcast_boxes");
+ timer_bcast_boxes.start();
+
+ int const count_send = h.local_components(rl);
+ vector<dboxes> level_send (count_send);
+ for (int lc = 0; lc < h.local_components(rl); ++ lc) {
+ int const c = h.get_component (rl, lc);
+ level_send.AT(lc) = level.AT(c);
+ }
+ // cerr << "QQQ: regrid[7a]" << endl;
+ vector<vector<dboxes> > const level_recv =
+ allgatherv (dist::comm(), level_send);
+ // cerr << "QQQ: regrid[7b]" << endl;
+ vector<int> count_recv (dist::size(), 0);
+ for (int c = 0; c < h.components(rl); ++ c) {
+ int const p = this_proc (rl, c);
+ if (p != dist::rank()) {
+ level.AT(c) = level_recv.AT(p).AT(count_recv.AT(p));
+ ++ count_recv.AT(p);
+ }
+ }
+ for (int p = 0; p < dist::size(); ++ p) {
+ if (p != dist::rank()) {
+ assert (count_recv.AT(p) == int(level_recv.AT(p).size()));
+ }
}
+ // cerr << "QQQ: regrid[7c]" << endl;
- } // for c
+ timer_bcast_boxes.stop();
+
+ }
- } // for rl
- } // for m
-
-
-
- // Output:
- if (output_bboxes or there_was_an_error) {
-
- for (int ml = 0; ml < h.mglevels(); ++ ml) {
- for (int rl = 0; rl < h.reflevels(); ++ rl) {
+ {
+
+ static Carpet::Timer timer_bcast_comm
+ ("CarpetLib::dh::regrid::bcast_comm");
+ timer_bcast_comm.start();
+
+ static Carpet::Timer timer_bcast_comm_ref_prol
+ ("CarpetLib::dh::regrid::bcast_comm::ref_prol");
+ timer_bcast_comm_ref_prol.start();
+ broadcast_schedule (fast_level_otherprocs, fast_level,
+ & fast_dboxes::fast_ref_prol_sendrecv);
+ timer_bcast_comm_ref_prol.stop();
+
+ static Carpet::Timer timer_bcast_comm_sync
+ ("CarpetLib::dh::regrid::bcast_comm::sync");
+ timer_bcast_comm_sync.start();
+ broadcast_schedule (fast_level_otherprocs, fast_level,
+ & fast_dboxes::fast_sync_sendrecv);
+ timer_bcast_comm_sync.stop();
+
+ static Carpet::Timer timer_bcast_comm_ref_bnd_prol
+ ("CarpetLib::dh::regrid::bcast_comm::ref_bnd_prol");
+ timer_bcast_comm_ref_bnd_prol.start();
+ broadcast_schedule (fast_level_otherprocs, fast_level,
+ & fast_dboxes::fast_ref_bnd_prol_sendrecv);
+ timer_bcast_comm_ref_bnd_prol.stop();
+
+ if (rl > 0) {
+ int const orl = rl - 1;
+ fast_dboxes & fast_olevel = fast_boxes.AT(ml).AT(orl);
+ static Carpet::Timer timer_bcast_comm_ref_rest
+ ("CarpetLib::dh::regrid::bcast_comm::ref_rest");
+ timer_bcast_comm_ref_rest.start();
+ broadcast_schedule (fast_level_otherprocs, fast_olevel,
+ & fast_dboxes::fast_ref_rest_sendrecv);
+ timer_bcast_comm_ref_rest.stop();
+ }
+
+ // TODO: Maybe broadcast old2new schedule only if do_init is
+ // set
+ static Carpet::Timer timer_bcast_comm_old2new_sync
+ ("CarpetLib::dh::regrid::bcast_comm::old2new_sync");
+ timer_bcast_comm_old2new_sync.start();
+ broadcast_schedule (fast_level_otherprocs, fast_level,
+ & fast_dboxes::fast_old2new_sync_sendrecv);
+ timer_bcast_comm_old2new_sync.stop();
+
+ static Carpet::Timer timer_bcast_comm_old2new_ref_prol
+ ("CarpetLib::dh::regrid::bcast_comm::old2new_ref_prol");
+ timer_bcast_comm_old2new_ref_prol.start();
+ broadcast_schedule (fast_level_otherprocs, fast_level,
+ & fast_dboxes::fast_old2new_ref_prol_sendrecv);
+ timer_bcast_comm_old2new_ref_prol.stop();
+
+ timer_bcast_comm.stop();
+
+ }
+
+
+
+ // Output:
+ if (output_bboxes or there_was_an_error) {
+
for (int c = 0; c < h.components(rl); ++ c) {
- dboxes const & box = boxes.AT(ml).AT(rl).AT(c);
- fast_dboxes const & fast_box = fast_boxes.AT(ml).AT(rl).AT(c);
+ full_dboxes const & box = full_boxes.AT(ml).AT(rl).AT(c);
cout << eol;
cout << "ml=" << ml << " rl=" << rl << " c=" << c << eol;
cout << box;
- cout << fast_box;
- cout << endl;
} // for c
- } // for rl
- } // for m
+
+ fast_dboxes const & fast_box = fast_boxes.AT(ml).AT(rl);
+
+ cout << eol;
+ cout << "ml=" << ml << " rl=" << rl << eol;
+ cout << fast_box;
+
+ } // if output_bboxes
+
+
+
+ // Free memory early to save space
+ if (int (oldboxes.size()) > ml and int (oldboxes.AT(ml).size()) > rl) {
+ oldboxes.AT(ml).AT(rl).clear();
+ }
+
+ if (ml > 0) {
+ if (rl > 0) {
+ full_boxes.AT(ml-1).AT(rl-1).clear();
+ }
+ if (rl == h.reflevels()-1) {
+ full_boxes.AT(ml-1).AT(rl).clear();
+ }
+ }
+ if (ml == h.mglevels()-1) {
+ if (rl > 0) {
+ full_boxes.AT(ml).AT(rl-1).clear();
+ }
+ if (rl == h.reflevels()-1) {
+ full_boxes.AT(ml).AT(rl).clear();
+ }
+ }
+
+ } // for rl
+
+ if (ml > 0) {
+ full_boxes.AT(ml-1).clear();
+ }
+ if (ml == h.mglevels()-1) {
+ full_boxes.AT(ml).clear();
+ }
+
+ } // for ml
+
+
+
+ // Output:
+ if (output_bboxes or there_was_an_error) {
+
+ cout << eol;
+ cout << "memoryof(gh)=" << memoryof(h) << eol;
+ cout << "memoryof(dh)=" << memoryof(*this) << eol;
+ cout << "memoryof(dh.boxes)=" << memoryof(boxes) << eol;
+ cout << "memoryof(dh.fast_boxes)=" << memoryof(fast_boxes) << eol;
+ int gfcount = 0;
+ size_t gfmemory = 0;
+ for (list<ggf*>::const_iterator
+ gfi = gfs.begin(); gfi != gfs.end(); ++ gfi)
+ {
+ ++ gfcount;
+ gfmemory += memoryof(**gfi);
+ }
+ cout << "#gfs=" << gfcount << eol;
+ cout << "memoryof(gfs)=" << gfmemory << eol;
} // if output_bboxes
if (there_was_an_error) {
CCTK_WARN (CCTK_WARN_ABORT,
- "The grid structure is inconsistent. "
- "It is impossible to continue.");
+ "The grid structure is inconsistent. It is impossible to continue.");
}
total.stop (0);
+ timer.stop();
+}
+
+
+
+void
+dh::
+broadcast_schedule (vector<fast_dboxes> & fast_level_otherprocs,
+ fast_dboxes & fast_level,
+ srpvect fast_dboxes::* const schedule_item)
+{
+ // cerr << "QQQ: broadcast_schedule[1]" << endl;
+ static Carpet::Timer timer_bs1 ("CarpetLib::dh::bs1");
+ timer_bs1.start();
+ vector <srpvect> send (dist::size());
+ for (int p=0; p<dist::size(); ++p) {
+ swap (send.AT(p), fast_level_otherprocs.AT(p).*schedule_item);
+ }
+ timer_bs1.stop();
+
+ static Carpet::Timer timer_bs2 ("CarpetLib::dh::bs2");
+ timer_bs2.start();
+ srpvect const recv = alltoallv1 (dist::comm(), send);
+ timer_bs2.stop();
+
+ static Carpet::Timer timer_bs3 ("CarpetLib::dh::bs3");
+ timer_bs3.start();
+ (fast_level.*schedule_item).insert
+ ((fast_level.*schedule_item).end(), recv.begin(), recv.end());
+ timer_bs3.stop();
+ // cerr << "QQQ: broadcast_schedule[2]" << endl;
+}
+
+
+
+void
+dh::
+regrid_free (bool const do_init)
+{
+ if (do_init) {
+ for (int ml = 0; ml < h.mglevels(); ++ ml) {
+ for (int rl = 0; rl < h.reflevels(); ++ rl) {
+ fast_boxes.AT(ml).AT(rl).fast_old2new_sync_sendrecv.clear();
+ fast_boxes.AT(ml).AT(rl).fast_old2new_ref_prol_sendrecv.clear();
+ }
+ }
+ } else {
+ for (int ml = 0; ml < h.mglevels(); ++ ml) {
+ for (int rl = 0; rl < h.reflevels(); ++ rl) {
+ assert (fast_boxes.AT(ml).AT(rl).fast_old2new_sync_sendrecv.empty());
+ assert (fast_boxes.AT(ml).AT(rl).fast_old2new_ref_prol_sendrecv.empty());
+ }
+ }
+ }
}
@@ -1004,7 +1397,7 @@ recompose (int const rl, bool const do_prolongate)
assert (rl>=0 and rl<h.reflevels());
- static Timer timer ("dh::recompose");
+ static Carpet::Timer timer ("CarpetLib::dh::recompose");
timer.start ();
for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
@@ -1017,11 +1410,21 @@ recompose (int const rl, bool const do_prolongate)
for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
(*f)->recompose_allocate (rl);
}
+#warning "TODO: If this works, rename do_prolongate to do_init here, and remove the do_prolongate parameter from ggf::recompose_fill"
+#if 0
for (comm_state state; not state.done(); state.step()) {
for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
(*f)->recompose_fill (state, rl, do_prolongate);
}
}
+#endif
+ if (do_prolongate) {
+ for (comm_state state; not state.done(); state.step()) {
+ for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
+ (*f)->recompose_fill (state, rl, true);
+ }
+ }
+ }
for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
(*f)->recompose_free_old (rl);
}
@@ -1030,33 +1433,144 @@ recompose (int const rl, bool const do_prolongate)
// but requires less memory. This is the default.
for (list<ggf*>::iterator f=gfs.begin(); f!=gfs.end(); ++f) {
(*f)->recompose_allocate (rl);
+#if 0
for (comm_state state; not state.done(); state.step()) {
(*f)->recompose_fill (state, rl, do_prolongate);
}
+#endif
+ if (do_prolongate) {
+ for (comm_state state; not state.done(); state.step()) {
+ (*f)->recompose_fill (state, rl, true);
+ }
+ }
(*f)->recompose_free_old (rl);
}
}
- timer.stop (0);
+ timer.stop ();
}
// Grid function management
-void
+dh::ggf_handle
dh::
add (ggf * const f)
{
CHECKPOINT;
- gfs.push_back (f);
+ return gfs.insert (gfs.end(), f);
}
void
dh::
-remove (ggf * const f)
+erase (ggf_handle const fi)
{
CHECKPOINT;
- gfs.remove (f);
+ gfs.erase (fi);
+}
+
+
+
+// Equality
+
+bool
+dh::full_dboxes::
+operator== (full_dboxes const & b) const
+{
+ return
+ exterior == b.exterior and
+ all(all(is_outer_boundary == b.is_outer_boundary)) and
+ outer_boundaries == b.outer_boundaries and
+ communicated == b.communicated and
+ boundaries == b.boundaries and
+ owned == b.owned and
+ buffers == b.buffers and
+ active == b.active and
+ sync == b.sync and
+ bndref == b.bndref and
+ ghosts == b.ghosts and
+ interior == b.interior;
+}
+
+
+
+// MPI datatypes
+
+MPI_Datatype
+mpi_datatype (dh::dboxes const &)
+{
+ static bool initialised = false;
+ static MPI_Datatype newtype;
+ if (not initialised) {
+ static dh::dboxes s;
+#define ENTRY(type, name) \
+ { \
+ sizeof s.name / sizeof(type), /* count elements */ \
+ (char*)&s.name - (char*)&s, /* offsetof doesn't work (why?) */ \
+ dist::mpi_datatype<type>(), /* find MPI datatype */ \
+ STRINGIFY(name), /* field name */ \
+ STRINGIFY(type), /* type name */ \
+ }
+ dist::mpi_struct_descr_t const descr[] = {
+ ENTRY(int, exterior),
+ ENTRY(int, owned),
+ ENTRY(int, interior),
+ ENTRY(dh::dboxes::size_type, exterior_size),
+ ENTRY(dh::dboxes::size_type, owned_size),
+ ENTRY(dh::dboxes::size_type, active_size),
+ {1, sizeof s, MPI_UB, "MPI_UB", "MPI_UB"}
+ };
+#undef ENTRY
+ newtype =
+ dist::create_mpi_datatype (sizeof descr / sizeof descr[0], descr,
+ "dh::dboxes", sizeof s);
+#if 0
+ int type_size;
+ MPI_Type_size (newtype, & type_size);
+ assert (type_size <= sizeof s);
+ MPI_Aint type_lb, type_ub;
+ MPI_Type_lb (newtype, & type_lb);
+ MPI_Type_ub (newtype, & type_ub);
+ assert (type_ub - type_lb == sizeof s);
+#endif
+ initialised = true;
+ }
+ return newtype;
+}
+
+MPI_Datatype
+mpi_datatype (dh::fast_dboxes const &)
+{
+ static bool initialised = false;
+ static MPI_Datatype newtype;
+ if (not initialised) {
+ static dh::fast_dboxes s;
+#define ENTRY(type, name) \
+ { \
+ sizeof s.name / sizeof(type), /* count elements */ \
+ (char*)&s.name - (char*)&s, /* offsetof doesn't work (why?) */ \
+ dist::mpi_datatype<type>(), /* find MPI datatype */ \
+ STRINGIFY(name), /* field name */ \
+ STRINGIFY(type), /* type name */ \
+ }
+ dist::mpi_struct_descr_t const descr[] = {
+ ENTRY (dh::srpvect, fast_mg_rest_sendrecv),
+ ENTRY (dh::srpvect, fast_mg_prol_sendrecv),
+ ENTRY (dh::srpvect, fast_ref_prol_sendrecv),
+ ENTRY (dh::srpvect, fast_ref_rest_sendrecv),
+ ENTRY (dh::srpvect, fast_sync_sendrecv),
+ ENTRY (dh::srpvect, fast_ref_bnd_prol_sendrecv),
+ ENTRY (dh::srpvect, fast_old2new_sync_sendrecv),
+ ENTRY (dh::srpvect, fast_old2new_ref_prol_sendrecv),
+ {1, sizeof s, MPI_UB, "MPI_UB", "MPI_UB"}
+ };
+#undef ENTRY
+ newtype =
+ dist::create_mpi_datatype (sizeof descr / sizeof descr[0], descr,
+ "dh::fast_dboxes", sizeof s);
+ initialised = true;
+ }
+ return newtype;
}
@@ -1069,22 +1583,48 @@ memory ()
const
{
return
+ sizeof alldhi + // memoryof (alldhi) +
+ sizeof & h + // memoryof (& h) +
+ sizeof gh_handle + // memoryof (gh_handle) +
memoryof (ghost_width) +
memoryof (buffer_width) +
memoryof (prolongation_order_space) +
memoryof (boxes) +
memoryof (fast_boxes) +
- memoryof (fast_oldboxes) +
memoryof (gfs);
}
size_t
+dh::
+allmemory ()
+{
+ size_t mem = memoryof(alldh);
+ for (list<dh*>::const_iterator
+ dhi = alldh.begin(); dhi != alldh.end(); ++ dhi)
+ {
+ mem += memoryof(**dhi);
+ }
+ return mem;
+}
+
+size_t
dh::dboxes::
memory ()
const
{
return
memoryof (exterior) +
+ memoryof (owned) +
+ memoryof (interior);
+}
+
+size_t
+dh::full_dboxes::
+memory ()
+ const
+{
+ return
+ memoryof (exterior) +
memoryof (is_outer_boundary) +
memoryof (outer_boundaries) +
memoryof (communicated) +
@@ -1116,6 +1656,135 @@ memory ()
+// Input
+
+istream &
+dh::dboxes::
+input (istream & is)
+{
+ // Regions:
+ try {
+ skipws (is);
+ consume (is, "dh::dboxes:{");
+ skipws (is);
+ consume (is, "exterior:");
+ is >> exterior;
+ exterior_size = exterior.size();
+ skipws (is);
+ consume (is, "owned:");
+ is >> owned;
+ owned_size = owned.size();
+ skipws (is);
+ consume (is, "interior:");
+ is >> interior;
+ skipws (is);
+ consume (is, "active_size:");
+ is >> active_size;
+ skipws (is);
+ consume (is, "}");
+ } catch (input_error & err) {
+ cout << "Input error while reading a dh::full_dboxes" << endl;
+ throw err;
+ }
+ return is;
+}
+
+istream &
+dh::full_dboxes::
+input (istream & is)
+{
+ // Regions:
+ try {
+ skipws (is);
+ consume (is, "dh::full_dboxes:{");
+ skipws (is);
+ consume (is, "exterior:");
+ is >> exterior;
+ skipws (is);
+ consume (is, "is_outer_boundary:");
+ is >> is_outer_boundary;
+ skipws (is);
+ consume (is, "outer_boundaries:");
+ is >> outer_boundaries;
+ skipws (is);
+ consume (is, "communicated:");
+ is >> communicated;
+ skipws (is);
+ consume (is, "boundaries:");
+ is >> boundaries;
+ skipws (is);
+ consume (is, "owned:");
+ is >> owned;
+ skipws (is);
+ consume (is, "buffers:");
+ is >> buffers;
+ skipws (is);
+ consume (is, "active:");
+ is >> active;
+ skipws (is);
+ consume (is, "sync:");
+ is >> sync;
+ skipws (is);
+ consume (is, "bndref:");
+ is >> bndref;
+ skipws (is);
+ consume (is, "ghosts:");
+ is >> ghosts;
+ skipws (is);
+ consume (is, "interior:");
+ is >> interior;
+ skipws (is);
+ consume (is, "}");
+ } catch (input_error & err) {
+ cout << "Input error while reading a dh::full_dboxes" << endl;
+ throw err;
+ }
+ return is;
+}
+
+istream &
+dh::fast_dboxes::
+input (istream & is)
+{
+ // Communication schedule:
+ try {
+ skipws (is);
+ consume (is, "dh::fast_dboxes:{");
+ skipws (is);
+ consume (is, "fast_mg_rest_sendrecv:");
+ is >> fast_mg_rest_sendrecv;
+ skipws (is);
+ consume (is, "fast_mg_prol_sendrecv:");
+ is >> fast_mg_prol_sendrecv;
+ skipws (is);
+ consume (is, "fast_ref_prol_sendrecv:");
+ is >> fast_ref_prol_sendrecv;
+ skipws (is);
+ consume (is, "fast_ref_rest_sendrecv:");
+ is >> fast_ref_rest_sendrecv;
+ skipws (is);
+ consume (is, "fast_sync_sendrecv:");
+ is >> fast_sync_sendrecv;
+ skipws (is);
+ consume (is, "fast_ref_bnd_prol_sendrecv:");
+ is >> fast_ref_bnd_prol_sendrecv;
+ skipws (is);
+ consume (is, "fast_old2new_sync_sendrecv:");
+ is >> fast_old2new_sync_sendrecv;
+ skipws (is);
+ consume (is, "fast_old2new_ref_prol_sendrecv:");
+ is >> fast_old2new_ref_prol_sendrecv;
+ skipws (is);
+ consume (is, "}");
+ } catch (input_error & err) {
+ cout << "Input error while reading a dh::fast_dboxes" << endl;
+ throw err;
+ }
+ return is;
+}
+
+
+
// Output
ostream &
@@ -1149,19 +1818,35 @@ output (ostream & os)
const
{
// Regions:
- os << "dh::dboxes:" << eol;
- os << "exterior:" << exterior << eol;
- os << "is_outer_boundary:" << is_outer_boundary << eol;
- os << "outer_boundaries:" << outer_boundaries << eol;
- os << "communicated:" << communicated << eol;
- os << "boundaries:" << boundaries << eol;
- os << "owned:" << owned << eol;
- os << "buffers:" << buffers << eol;
- os << "active:" << active << eol;
- os << "sync:" << sync << eol;
- os << "bndref:" << bndref << eol;
- os << "ghosts:" << ghosts << eol;
- os << "interior:" << interior << eol;
+ os << "dh::dboxes:{" << eol
+ << " exterior: " << exterior << eol
+ << " owned: " << owned << eol
+ << " interior: " << interior << eol
+ << " active_size: " << active_size << eol
+ << "}" << eol;
+ return os;
+}
+
+ostream &
+dh::full_dboxes::
+output (ostream & os)
+ const
+{
+ // Regions:
+ os << "dh::full_dboxes:{" << eol
+ << " exterior: " << exterior << eol
+ << " is_outer_boundary: " << is_outer_boundary << eol
+ << " outer_boundaries: " << outer_boundaries << eol
+ << " communicated: " << communicated << eol
+ << " boundaries: " << boundaries << eol
+ << " owned: " << owned << eol
+ << " buffers: " << buffers << eol
+ << " active: " << active << eol
+ << " sync: " << sync << eol
+ << " bndref: " << bndref << eol
+ << " ghosts: " << ghosts << eol
+ << " interior: " << interior << eol
+ << "}" << eol;
return os;
}
@@ -1171,14 +1856,15 @@ output (ostream & os)
const
{
// Communication schedule:
- os << "dh::fast_dboxes:" << eol;
- os << "fast_mg_rest_sendrecv: " << fast_mg_rest_sendrecv << eol;
- os << "fast_mg_prol_sendrecv: " << fast_mg_prol_sendrecv << eol;
- os << "fast_ref_prol_sendrecv: " << fast_ref_prol_sendrecv << eol;
- os << "fast_ref_rest_sendrecv: " << fast_ref_rest_sendrecv << eol;
- os << "fast_sync_sendrecv: " << fast_sync_sendrecv << eol;
- os << "fast_ref_bnd_prol_sendrecv: " << fast_ref_bnd_prol_sendrecv << eol;
- os << "fast_old2new_sync_sendrecv:" << fast_old2new_sync_sendrecv << eol;
- os << "fast_old2new_ref_prol_sendrecv:" << fast_old2new_ref_prol_sendrecv << eol;
+ os << "dh::fast_dboxes:{" << eol
+ << " fast_mg_rest_sendrecv: " << fast_mg_rest_sendrecv << eol
+ << " fast_mg_prol_sendrecv: " << fast_mg_prol_sendrecv << eol
+ << " fast_ref_prol_sendrecv: " << fast_ref_prol_sendrecv << eol
+ << " fast_ref_rest_sendrecv: " << fast_ref_rest_sendrecv << eol
+ << " fast_sync_sendrecv: " << fast_sync_sendrecv << eol
+ << " fast_ref_bnd_prol_sendrecv: " << fast_ref_bnd_prol_sendrecv << eol
+ << " fast_old2new_sync_sendrecv: " << fast_old2new_sync_sendrecv << eol
+ << " fast_old2new_ref_prol_sendrecv: " << fast_old2new_ref_prol_sendrecv << eol
+ << "}" << eol;
return os;
}