aboutsummaryrefslogtreecommitdiff
path: root/Carpet/Carpet/src/Comm.cc
diff options
context:
space:
mode:
authorThomas Radke <tradke@aei.mpg.de>2005-03-30 15:28:00 +0000
committerThomas Radke <tradke@aei.mpg.de>2005-03-30 15:28:00 +0000
commit94daef6e66284e4bd9cd44cfe9f554932c7773c7 (patch)
treedf80da062422e5363d871063b9154b3589d7f71b /Carpet/Carpet/src/Comm.cc
parentb6ed81fe31a0a5571ea7433f1e2e2e93a630de16 (diff)
CarpetLib, Carpet: implement and use collective communication buffers
Collective buffers are used to gather all components' data on a processor before it gets send off to other processors in one go. This minimizes the number of outstanding MPI communications down to O(N-1) and thus improves overall efficiency as benchmarks show. Each processor allocates a pair of single send/recv buffers to communicate with all other processors. For this the class (actually, the struct) comm_state was extended by 3 more states: state_get_buffer_sizes: accumulates the sizes for the send/recv buffers state_fill_send_buffers: gathers all the data into the send buffers state_empty_recv_buffers: copies the data from the recv buffer back into the processor's components Send/recv buffers are exchanged during state_fill_send_buffers and state_empty_recv_buffers. The constructor for a comm_state struct now takes an argument <datatype> which denotes the CCTK datatype to use for the attached collective buffers. If a negative value is passed here then it falls back to using the old send/recv/wait communication scheme. The datatype argument has a default value of -1 to maintain backwards compatibility to existing code (which therefore will keep using the old scheme). The new communication scheme is chosen by setting the parameter CarpetLib::use_collective_communication_buffers to "yes". It defaults to "no" meaning that the old send/recv/wait scheme is still used. So far all the comm_state objects in the higher-level routines in thorn Carpet (restriction/prolongation, regridding, synchronization) have been enabled to use collective communication buffers. Other thorns (CarpetInterp, CarpetIO*, CarpetSlab) will follow in separate commits. darcs-hash:20050330152811-776a0-51f426887fea099d1a67b42bd79e4f786979ba91.gz
Diffstat (limited to 'Carpet/Carpet/src/Comm.cc')
-rw-r--r--Carpet/Carpet/src/Comm.cc107
1 files changed, 67 insertions, 40 deletions
diff --git a/Carpet/Carpet/src/Comm.cc b/Carpet/Carpet/src/Comm.cc
index dd50e2140..c71458236 100644
--- a/Carpet/Carpet/src/Comm.cc
+++ b/Carpet/Carpet/src/Comm.cc
@@ -16,10 +16,12 @@ namespace Carpet {
using namespace std;
- static int CheckSyncGroupConsistency ( const cGH* cgh,
- const char *groupname );
- static void ProlongateGroupBoundaries ( const cGH* cgh,
- CCTK_REAL initial_time, int group );
+ static int CheckSyncGroupConsistency (const cGH* cgh,
+ const char *groupname);
+ static void ProlongateGroupBoundaries (const cGH* cgh,
+ CCTK_REAL initial_time, int group,
+ int vartype);
+
int SyncGroup (const cGH* cgh, const char* groupname)
{
@@ -29,6 +31,8 @@ namespace Carpet {
assert (group>=0 and group<CCTK_NumGroups());
assert (group<(int)arrdata.size());
const int grouptype = CCTK_GroupTypeI(group);
+ const int firstvar = CCTK_FirstVarIndexI (group);
+ const int vartype = CCTK_VarTypeI (firstvar);
assert(grouptype == CCTK_GF ||
grouptype == CCTK_SCALAR || grouptype == CCTK_ARRAY);
assert (CCTK_NumVarsInGroupI(group) != 0);
@@ -43,18 +47,21 @@ namespace Carpet {
if (do_prolongate && grouptype == CCTK_GF) {
assert (reflevel>=0 and reflevel<reflevels);
if (reflevel > 0) {
- ProlongateGroupBoundaries ( cgh, cctk_initial_time, group );
+ ProlongateGroupBoundaries (cgh, cctk_initial_time, group, vartype);
}
}
// Sync
- SyncGVGroup ( cgh, group );
+ const vector<int> members(1, group);
+ group_set groups = {vartype, members};
+ SyncGroups (cgh, groups);
}
return retval;
}
- void ProlongateGroupBoundaries ( const cGH* cgh, CCTK_REAL initial_time,
- int group )
+ static void ProlongateGroupBoundaries (const cGH* cgh,
+ CCTK_REAL initial_time, int group,
+ int vartype)
{
DECLARE_CCTK_PARAMETERS;
@@ -62,26 +69,32 @@ namespace Carpet {
const CCTK_REAL time = (cgh->cctk_time - initial_time) / delta_time;
const int tl = 0;
- // make the comm_state loop the innermost
- // in order to minimise the number of outstanding communications
- if (minimise_outstanding_communications) {
- for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
- for (int var=0; var<CCTK_NumVarsInGroupI(group); ++var) {
- for (int c=0; c<vhh.at(m)->components(reflevel); ++c) {
- for (comm_state state; !state.done(); state.step()) {
- arrdata.at(group).at(m).data.at(var)->ref_bnd_prolongate
- (state, tl, reflevel, c, mglevel, time);
+ // Use collective or single-component buffers for communication ?
+ if (! use_collective_communication_buffers) {
+ vartype = -1;
+ }
+
+ if (use_collective_communication_buffers ||
+ ! minimise_outstanding_communications) {
+ for (comm_state state(vartype); ! state.done(); state.step()) {
+ for (int m = 0; m < arrdata.at(group).size(); ++m) {
+ for (int v = 0; v < arrdata.at(group).at(m).data.size(); ++v) {
+ ggf *const gv = arrdata.at(group).at(m).data.at(v);
+ for (int c = 0; c < vhh.at(m)->components(reflevel); ++c) {
+ gv->ref_bnd_prolongate (state, tl, reflevel, c, mglevel, time);
}
}
}
}
} else {
- for (comm_state state; !state.done(); state.step()) {
- for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
- for (int var=0; var<CCTK_NumVarsInGroupI(group); ++var) {
- for (int c=0; c<vhh.at(m)->components(reflevel); ++c) {
- arrdata.at(group).at(m).data.at(var)->ref_bnd_prolongate
- (state, tl, reflevel, c, mglevel, time);
+ // make the comm_state loop the innermost
+ // in order to minimise the number of outstanding communications
+ for (int m = 0; m < arrdata.at(group).size(); ++m) {
+ for (int v = 0; v < arrdata.at(group).at(m).data.size(); ++v) {
+ ggf *const gv = arrdata.at(group).at(m).data.at(v);
+ for (int c = 0; c < vhh.at(m)->components(reflevel); ++c) {
+ for (comm_state state(vartype); ! state.done(); state.step()) {
+ gv->ref_bnd_prolongate (state, tl, reflevel, c, mglevel, time);
}
}
}
@@ -89,31 +102,45 @@ namespace Carpet {
}
}
- void SyncGVGroup ( const cGH* cgh, int group )
+ // synchronises a set of group which all have the same vartype
+ void SyncGroups (const cGH* cgh, group_set& groups)
{
DECLARE_CCTK_PARAMETERS;
const int tl = 0;
- // make the comm_state loop the innermost
- // in order to minimise the number of outstanding communications
- if (minimise_outstanding_communications) {
- for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
- for (int var=0; var<(int)arrdata.at(group).at(m).data.size(); ++var) {
- for (int c=0; c<vhh.at(m)->components(reflevel); ++c) {
- for (comm_state state; ! state.done(); state.step()) {
- arrdata.at(group).at(m).data.at(var)->sync
- (state, tl, reflevel, c, mglevel);
+ assert (groups.members.size() > 0);
+
+ // Use collective or single-component buffers for communication ?
+ const int vartype =
+ use_collective_communication_buffers ? groups.vartype : -1;
+
+ if (use_collective_communication_buffers ||
+ ! minimise_outstanding_communications) {
+ for (comm_state state(vartype); ! state.done(); state.step()) {
+ for (int group = 0; group < groups.members.size(); ++group) {
+ const int g = groups.members.at(group);
+ for (int m = 0; m < arrdata.at(g).size(); ++m) {
+ for (int v = 0; v < arrdata.at(g).at(m).data.size(); ++v) {
+ ggf *const gv = arrdata.at(g).at(m).data.at(v);
+ for (int c = 0; c < vhh.at(m)->components(reflevel); ++c) {
+ gv->sync (state, tl, reflevel, c, mglevel);
+ }
}
}
}
}
} else {
- for (comm_state state; ! state.done(); state.step()) {
- for (int m=0; m<(int)arrdata.at(group).size(); ++m) {
- for (int var=0; var<(int)arrdata.at(group).at(m).data.size(); ++var) {
- for (int c=0; c<vhh.at(m)->components(reflevel); ++c) {
- arrdata.at(group).at(m).data.at(var)->sync
- (state, tl, reflevel, c, mglevel);
+ // make the comm_state loop the innermost
+ // in order to minimise the number of outstanding communications
+ for (int group = 0; group < groups.members.size(); ++group) {
+ const int g = groups.members.at(group);
+ for (int m = 0; m < arrdata.at(g).size(); ++m) {
+ for (int v = 0; v < arrdata.at(g).at(m).data.size(); ++v) {
+ ggf *const gv = arrdata.at(g).at(m).data.at(v);
+ for (int c = 0; c < vhh.at(m)->components(reflevel); ++c) {
+ for (comm_state state(vartype); ! state.done(); state.step()) {
+ gv->sync (state, tl, reflevel, c, mglevel);
+ }
}
}
}
@@ -121,6 +148,7 @@ namespace Carpet {
}
}
+
int CheckSyncGroupConsistency ( const cGH* cgh,const char *groupname )
{
int retval = 0;
@@ -169,7 +197,6 @@ namespace Carpet {
return retval;
}
-
int EnableGroupComm (const cGH* cgh, const char* groupname)
{
// Communication is always enabled