diff options
-rw-r--r-- | src/Comm.c | 1266 | ||||
-rw-r--r-- | src/Evolve.c | 2 | ||||
-rw-r--r-- | src/FinishReceiveGA.c | 239 | ||||
-rw-r--r-- | src/GHExtension.c | 15 | ||||
-rw-r--r-- | src/LoadAware.c | 1 | ||||
-rw-r--r-- | src/PostReceiveGA.c | 130 | ||||
-rw-r--r-- | src/PostSendGA.c | 341 | ||||
-rw-r--r-- | src/Reduction.c | 83 | ||||
-rw-r--r-- | src/SetupGroup.c | 121 | ||||
-rw-r--r-- | src/SetupPGH.c | 91 | ||||
-rw-r--r-- | src/SetupPGV.c | 559 | ||||
-rw-r--r-- | src/Startup.c | 10 | ||||
-rw-r--r-- | src/Storage.c | 561 | ||||
-rw-r--r-- | src/include/pGH.h | 19 | ||||
-rw-r--r-- | src/include/pGV.h | 42 | ||||
-rw-r--r-- | src/include/pugh.h | 49 | ||||
-rw-r--r-- | src/include/pughi.h | 90 | ||||
-rw-r--r-- | src/make.code.defn | 6 | ||||
-rw-r--r-- | src/pugh_extension.h | 2 |
19 files changed, 1866 insertions, 1761 deletions
@@ -14,15 +14,11 @@ #include <stdio.h> #include <stdarg.h> #include <string.h> -#include <assert.h> - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif #include "cctk.h" #include "pugh.h" +#include "pughi.h" #include "pugh_Comm.h" #include "cctk_Parameters.h" @@ -30,41 +26,23 @@ static char *rcsid="$Header$"; CCTK_FILEVERSION(CactusPUGH_PUGH_Comm_c) -static int totalstorage=0; /* Storage for GAs in Bytes */ -static int totalnumber=0; /* Number of stored GAs */ - -/* index into GH->extensions[] to get the PUGH extension handle */ -extern int pugh_GHExtension; /* local function prototypes */ +static int PUGH_EnableGArrayGroupComm(pGH *pughGH, + int first_var, + int commflag); +static int PUGH_DisableGArrayGroupComm(pGH *pughGH, + int first_var); +static int PUGH_EnableComm(pGH *pughGH, + pComm *comm, + int commflag); +static int PUGH_DisableComm(pGH *pughGH, + pComm *comm); +static int PUGH_SyncGArrayGroup(pGH *pughGH, + int first_var); +static int PUGH_Sync(pGH *pughGH, + pComm *comm); -int PUGH_SyncGroupGA (cGH *GH, - int group, - int vtype, - int n_vars, - int timelevel); -int PUGH_SyncGAs(pGH *pughGH, - int dim, - int first_var, - int n_vars, - int timelevel); -int PUGH_EnableArrayGroupStorage(cGH *GH, - int group, - int vtype, - int dim, - int n_variables, - int n_timelevels); -int PUGH_EnablePGAStorage(pGA *GA, - int this_proc, - int zero_memory, - int padding_active, - int padding_cacheline_bits, - int padding_size, - int padding_address_spacing); -void FinishReceiveGA(pGH *GH, pGA *GA, int dir); -void PostReceiveGA(pGH *GH, pGA *GA, int dir); -void PostSendGA(pGH *GH, pGA *GA, int dir); -int PUGH_GAComm(pGA *GA, int docomm); /*@@ @routine PUGH_SyncGroup @@ -75,7 +53,7 @@ int PUGH_GAComm(pGA *GA, int docomm); Only groups of type GROUP_ARRAY and GROUP_GF can be synchronized. @enddesc @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN - PUGH_SyncGroupArray PUGH_SyncGroupGF + PUGH_SyncGArrayGroup @history @endhistory @@ -91,66 +69,48 @@ int PUGH_GAComm(pGA *GA, int docomm); @endvar @@*/ -int PUGH_SyncGroup (cGH *GH, const char *groupname) +int PUGH_SyncGroup(cGH *GH, const char *groupname) { - cGroup pgroup; /* pointer to group information */ + cGroup pgroup; /* group information */ int group; /* group index */ - int timelevel; /* timelevel to be synchronized */ int rc; /* return code */ - group = CCTK_GroupIndex(groupname); +#ifdef DEBUG_PUGH + printf (" PUGH_SyncGroup: request for group '%s'\n", groupname); + fflush (stdout); +#endif /* get the group info from its index */ - CCTK_GroupData (group,&pgroup); + group = CCTK_GroupIndex(groupname); + CCTK_GroupData(group, &pgroup); -#if 0 - /* Compute the timelevel to synchronize */ - if (pgroup.numtimelevels > 1) + if (pgroup.grouptype == CCTK_SCALAR) { - timelevel = pgroup.numtimelevels - 2; + rc = 0; + CCTK_WARN(4, "Synchronising a scalar in PUGH"); } - else + else if (pgroup.grouptype == CCTK_GF || pgroup.grouptype == CCTK_ARRAY) { - timelevel = pgroup.numtimelevels - 1; + rc = PUGH_SyncGArrayGroup(PUGH_pGH(GH), CCTK_FirstVarIndexI(group)); } -#endif - - timelevel = pgroup.numtimelevels - 1; - - /* branch to synchronization function according to group type */ - switch (pgroup.grouptype) + else { - case GROUP_SCALAR : - rc = 0; - CCTK_WARN(4,"Synchronising a scalar in PUGH"); - break; - - case GROUP_ARRAY : - case GROUP_GF : - rc = PUGH_SyncGroupGA (GH, - group, - pgroup.vartype, - pgroup.numvars, - timelevel); - break; - - default : - CCTK_WARN (1, "Unknown group type in PUGH_SyncGroup"); - rc = 0; - break; + CCTK_WARN(1, "Unknown group type in PUGH_SyncGroup"); + rc = 0; } return (rc); } + /*@@ - @routine PUGH_ArrayGroupSize - @author Gabrielle Allen - @date 11 Apr 1999 + @routine PUGH_EnableGroupComm + @author Thomas Radke + @date 30 Mar 1999 @desc - Returns size of arrays in a group, in a given direction + Enables communication for all variables in the group indicated by groupname. @enddesc - @calls + @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN @history @endhistory @@ -163,109 +123,52 @@ int PUGH_SyncGroup (cGH *GH, const char *groupname) @vdesc name of the group to be synchronized @vtype const char * @vio in - @vcomment either index or groupname must be present @endvar - @var group - @vdesc index of group - @vtype int - @vio in - @vcomment either index or groupname must be given - @endvar - @var dir - @vdesc direction - @vtype int - @vio in @@*/ -const int *PUGH_ArrayGroupSize (cGH *GH, int dir, int group, const char *groupname) +int PUGH_EnableGroupComm(cGH *GH, const char *groupname) { - int first; - int *sizep=NULL; - pGH *pughGH; - pGA *pughGA; - - if (groupname) - { - group = CCTK_GroupIndex(groupname); - } + int group; /* group index */ + cGroup pgroup; /* group information */ + int rc; /* return code */ - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; +#ifdef DEBUG_PUGH + printf(" PUGH_EnableGroupComm: request for group '%s'\n", groupname); + fflush(stdout); +#endif - /* get first variable in group */ - first = CCTK_FirstVarIndexI(group); + /* get the group info from its index */ + group = CCTK_GroupIndex(groupname); + CCTK_GroupData(group, &pgroup); - if (CCTK_GroupTypeI(group)==GROUP_GF) + if (pgroup.grouptype == CCTK_SCALAR) { - /* get pointer to pGF for a timelevel of this variable */ - pughGA = (pGA *)(pughGH->variables[first][0]); - - if (pughGA->storage == PUGH_STORAGE) - { - switch (dir) - { - case 0: - sizep = &pughGH->GFExtras[pughGH->dim-1]->lnsize[0]; - break; - case 1: - sizep = &pughGH->GFExtras[pughGH->dim-1]->lnsize[1]; - break; - case 2: - sizep = &pughGH->GFExtras[pughGH->dim-1]->lnsize[2]; - break; - default : - sizep = NULL; - printf("Wrong value for dir in PUGH_ArrayGroupSize\n"); - break; - } - } - else - { - sizep = &_cctk_one; - } + rc = 1; } - else if (CCTK_GroupTypeI(group)==GROUP_ARRAY) + else if (pgroup.grouptype == CCTK_GF || pgroup.grouptype == CCTK_ARRAY) { - /* get pointer to pGA for a timelevel of this variable */ - pughGA = (pGA *)(pughGH->variables[first][0]); - - if (pughGA->storage == PUGH_STORAGE) - { - switch (dir) - { - case 0: - sizep = &pughGA->extras->lnsize[0]; - break; - case 1: - sizep = &pughGA->extras->lnsize[1]; - break; - case 2: - sizep = &pughGA->extras->lnsize[2]; - break; - default : - sizep = NULL; - CCTK_WARN(1,"Wrong value for dir in PUGH_ArrayGroupSize"); - break; - } - } - else - { - sizep = &_cctk_one; - } + rc = PUGH_EnableGArrayGroupComm(PUGH_pGH(GH), + CCTK_FirstVarIndexI(group), + PUGH_ALLCOMM); + } + else + { + CCTK_WARN(1, "Unknown group type in PUGH_EnableGroupComm"); + rc = 0; } - return (sizep); + return (rc); } /*@@ - @routine PUGH_QueryGroupStorage - @author Gabrielle Allen - @date 13 Apr 1999 + @routine PUGH_DisableGroupComm + @author Thomas Radke + @date 30 Mar 1999 @desc - Returns true if group has storage assigned, false otherwise + Disables communication for all variables in the group indicated by groupname. @enddesc - @calls CCTK_DecomposeName + @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN @history @endhistory @@ -275,595 +178,523 @@ const int *PUGH_ArrayGroupSize (cGH *GH, int dir, int group, const char *groupna @vio in @endvar @var groupname - @vdesc name of the group to be queried + @vdesc name of the group to be synchronized @vtype const char * @vio in - @vcomment either index or groupname must be present @endvar - @var group - @vdesc index of group - @vtype int - @vio in - @vcomment either index or groupname must be given - @endvar @@*/ -int PUGH_QueryGroupStorage(cGH *GH, int group, const char *groupname) +int PUGH_DisableGroupComm(cGH *GH, const char *groupname) { + int group; /* group index */ + cGroup pgroup; /* pointer to group information */ + int rc; /* return code */ - int first; - int storage=PUGH_UNDEFINEDSTORAGE; - int retval; - int grouptype; - pGH *pughGH; - - if (groupname) - { - group = CCTK_GroupIndex(groupname); - } - - /* get first variable in group */ - first = CCTK_FirstVarIndexI(group); - if (first < 0) - { - CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, - "Invalid group ID %d in PUGH_QueryGroupStorage", group); - } - - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; - - grouptype = CCTK_GroupTypeI(group); +#ifdef DEBUG_PUGH + printf(" PUGH_DisableGroupComm: request for group '%s'\n", groupname); + fflush(stdout); +#endif - if (grouptype == CCTK_SCALAR) - { - storage = PUGH_STORAGE; - } - else if (grouptype == CCTK_GF) - { - storage = ((pGA *)(pughGH->variables[first][0]))->storage; - } - else if (grouptype == CCTK_ARRAY) - { - storage = ((pGA *)(pughGH->variables[first][0]))->storage; - } - else - { - CCTK_WARN(0,"Unknown group type in PUGH_QueryGroupStorage"); - } + /* get the group info from its index */ + group = CCTK_GroupIndex(groupname); + CCTK_GroupData(group, &pgroup); - if (storage == PUGH_STORAGE) + if (pgroup.grouptype == CCTK_SCALAR) { - retval = 1; + rc = 1; } - else if (storage == PUGH_NOSTORAGE) + else if (pgroup.grouptype == CCTK_GF || pgroup.grouptype == CCTK_ARRAY) { - retval = 0; + rc = PUGH_DisableGArrayGroupComm(PUGH_pGH(GH), CCTK_FirstVarIndexI(group)); } else { - CCTK_WARN(0,"Inconsistency in PUGH_QueryGroupStorage"); - retval = PUGH_ERROR; + CCTK_WARN(1, "Unknown group type in PUGH_DisableGroupComm"); + rc = 0; } - return (retval); + return (rc); } -/*@@ - @routine PUGH_EnableGroupStorage - @author Tom Goodale - @date 30 Mar 1999 - @desc - Enables storage for all variables in the group indicated by groupname. - @enddesc - @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN - PUGH_EnableArrayGroupStorage - @history - - @endhistory - @var GH - @vdesc Pointer to CCTK grid hierarchy - @vtype cGH - @vio in - @endvar - @var groupname - @vdesc name of the group to be synchronized - @vtype const char * - @vio in - @endvar - @@*/ - -int PUGH_EnableGroupStorage(cGH *GH, const char *groupname) + /*@@ + @routine PUGH_EnableGArrayComm + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Enables communication for a single array. + @enddesc + @history + @endhistory +@@*/ +int PUGH_EnableGArrayComm(pGA *GA, + int commflag) { - DECLARE_CCTK_PARAMETERS - - int group; /* group index */ - cGroup pgroup; /* pointer to group information */ - int rc; /* return code */ - pGH *pughGH; - int first_var; - #ifdef DEBUG_PUGH - printf(" PUGH_EnableGroupStorage: request for group -%s-\n",groupname); + printf(" PUGH_EnableGArrayComm: request for var '%s' commflag %d\n", + GA->name, commflag); fflush(stdout); #endif - group = CCTK_GroupIndex(groupname); - - /* get the group info from its index */ - CCTK_GroupData (group, &pgroup); - - /* branch to "enable storage" function according to group type */ - switch (pgroup.grouptype) - { - case CCTK_SCALAR : - rc = 1; - break; - - case CCTK_ARRAY : - case CCTK_GF : - rc = PUGH_EnableArrayGroupStorage (GH, - group, - pgroup.vartype, - pgroup.dim, - pgroup.numvars, - pgroup.numtimelevels); - break; - - default : - CCTK_WARN (1, "Unknown group type in PUGH_EnableGroupStorage"); - rc = 0; - break; - } - - /* Report on memory usage */ - if (storage_verbose) - { - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; + return (PUGH_EnableComm((pGH *) GA->parent, GA->comm, commflag)); +} - /* get global index of first variable in group */ - first_var = CCTK_FirstVarIndexI (group); - if (rc == 0) - { - /* Memory toggled */ - totalnumber = totalnumber + pgroup.numvars; - totalstorage = totalstorage + - ((pGA ***)pughGH->variables)[first_var][0]->extras->npoints - *CCTK_VarTypeSize(pgroup.vartype) - *pgroup.numtimelevels - *pgroup.numvars; - printf("Switched memory on for %s \n [Num Arrays: %d Total Size: %d]\n", - groupname,totalnumber,totalstorage); - } - else if (rc == 1) - { - /* Memory already on */ - printf("Memory already on for %s\n",groupname); - } - } + /*@@ + @routine PUGH_DisableGArrayComm + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Disables communication for a single array. + @enddesc + @history + @endhistory +@@*/ +int PUGH_DisableGArrayComm(pGA *GA) +{ - return (rc); +#ifdef DEBUG_PUGH + printf(" PUGH_DisableGArrayComm: request for var '%s'\n", GA->name); + fflush(stdout); +#endif + return (PUGH_DisableComm((pGH *) GA->parent, GA->comm)); } -/*@@ - @routine PUGH_DisableGroupStorage - @author Tom Goodale - @date 30 Mar 1999 - @desc - Disables storage for all variables in the group indicated by groupname. - @enddesc - @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN - @history - - @endhistory - @var GH - @vdesc Pointer to CCTK grid hierarchy - @vtype cGH - @vio in - @endvar - @var groupname - @vdesc name of the group to be synchronized - @vtype const char * - @vio in - @endvar - @@*/ - -int PUGH_DisableGroupStorage(cGH *GH, const char *groupname) + /*@@ + @routine PUGH_SyncGArrayGroup + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Synchronizes a group of arrays + given the first variable within this group. + @enddesc + @history + @endhistory +@@*/ +int PUGH_SyncGArrayGroup(pGH *pughGH, + int first_var) { - DECLARE_CCTK_PARAMETERS + pGA *firstGA; + + + firstGA = (pGA *) pughGH->variables [first_var][0]; - int group; /* group index */ - cGroup pgroup; /* pointer to group information */ - int rc; /* return code */ - pGH *pughGH; /* PUGH extension reference */ - int level; - int first_var,var; - int unchanged; /* count how many aren't toggled */ - int PUGH_DisableGADataStorage(pGA *GA); - - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; - #ifdef DEBUG_PUGH - printf(" PUGH_DisableGroupStorage: request for group -%s-\n",groupname); + printf(" PUGH_SyncGArrayGroup: request for group with first var '%s'\n", + firstGA->name); fflush(stdout); #endif - group = CCTK_GroupIndex(groupname); + return (PUGH_Sync(pughGH, firstGA->groupcomm)); +} - /* get global index of first variable in group */ - first_var = CCTK_FirstVarIndexI (group); - /* get the group info from its index */ - CCTK_GroupData (group,&pgroup); + /*@@ + @routine PUGH_SyncGArray + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Synchronizes a single array variable given the GA structure + of this variable. + @enddesc + @history + @endhistory +@@*/ +int PUGH_SyncGArray(pGA *GA) +{ - unchanged = 0; - switch (pgroup.grouptype) - { - case GROUP_SCALAR : - rc = 1; - break; +#ifdef DEBUG_PUGH + printf(" PUGH_SyncGArray: request for var '%s'\n", GA->name); + fflush(stdout); +#endif - case GROUP_ARRAY : - case GROUP_GF : - for (var = first_var; var < first_var+pgroup.numvars; var++) - { - for (level = 0; level < pgroup.numtimelevels; level++) - { - unchanged = unchanged + - PUGH_DisableGADataStorage ((pGA *)(pughGH->variables[var][level])); - } - } - rc = 1; - break; + return (PUGH_Sync((pGH *) GA->parent, GA->comm)); +} - default : - CCTK_WARN (1, "Unknown group type in PUGH_DisableGroupStorage"); - rc = 0; - break; - } - /* Report on memory usage */ - if (storage_verbose) - { - if (unchanged == 0) - { - /* Memory toggled */ - totalnumber = totalnumber - pgroup.numvars; - totalstorage = totalstorage - - ((pGA ***)pughGH->variables)[first_var][0]->extras->npoints - *CCTK_VarTypeSize(pgroup.vartype) - *pgroup.numtimelevels - *pgroup.numvars; - printf("Switched memory off for %s \n [Num Arrays: %d Total Size: %d]\n", - groupname,totalnumber,totalstorage); - } - else if (unchanged == pgroup.numvars) - { - /* Memory already off */ - printf("Memory already off for %s\n",groupname); - } - else - { - CCTK_WARN(1,"Inconsistency in group memory assignment"); - } - } +int PUGH_Barrier(cGH *GH) +{ +#ifdef CCTK_MPI + CACTUS_MPI_ERROR(MPI_Barrier(PUGH_pGH(GH)->PUGH_COMM_WORLD)); +#endif - return (rc); + return 0; } -/*@@ - @routine PUGH_EnableGroupComm - @author Thomas Radke - @date 30 Mar 1999 - @desc - Enables communication for all variables in the group indicated by groupname. - @enddesc - @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN - @history - - @endhistory - @var GH - @vdesc Pointer to CCTK grid hierarchy - @vtype cGH - @vio in - @endvar - @var groupname - @vdesc name of the group to be synchronized - @vtype const char * - @vio in - @endvar - @@*/ +/*****************************************************************************/ +/* local functions */ +/*****************************************************************************/ -int PUGH_EnableGroupComm (cGH *GH, const char *groupname) + /*@@ + @routine PUGH_EnableGArrayGroupComm + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Enables communication for a group of arrays + given the first variable within this group. + @enddesc + @history + @endhistory +@@*/ +static int PUGH_EnableGArrayGroupComm(pGH *pughGH, + int first_var, + int commflag) { - cGroup pgroup; /* pointer to group information */ - int group; /* group index */ - pGH *pughGH; /* PUGH extension reference */ - int var, level; /* loop variables */ - int first_var; /* global index of first variable in group */ - int rc; /* return code */ + pGA *GA; /* first variable in group */ - group = CCTK_GroupIndex(groupname); - /* get the group info from its index */ - CCTK_GroupData (group,&pgroup); + GA = pughGH->variables [first_var][0]; - /* get global index of first variable in group */ - first_var = CCTK_FirstVarIndexI (group); +#ifdef DEBUG_PUGH + printf(" PUGH_EnableGArrayGroupComm: request for group " + "with first var '%s', commflag %d\n", GA->name, commflag); + fflush(stdout); +#endif - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; + return (PUGH_EnableComm(pughGH, GA->groupcomm, commflag)); +} - /* branch to "enable comm" function according to group type */ - switch (pgroup.grouptype) - { - case GROUP_SCALAR : - rc = 1; - break; - case GROUP_ARRAY : - case GROUP_GF : - for (var = first_var; var < first_var+pgroup.numvars; var++) - { - for (level = 0; level < pgroup.numtimelevels; level++) - { - PUGH_GAComm ((pGA *)(pughGH->variables[var][level]), - PUGH_ALLCOMM); - } - } - rc = 1; - break; + /*@@ + @routine PUGH_DisableGArrayGroupComm + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Disables communication for a group of arrays + given the first variable within this group. + @enddesc + @history + @endhistory +@@*/ +static int PUGH_DisableGArrayGroupComm(pGH *pughGH, + int first_var) +{ + pGA *GA; /* first variable in group */ - default : - CCTK_WARN (1, "Unknown group type in PUGH_EnableGroupComm"); - rc = 0; - break; - } - return (rc); -} + GA = pughGH->variables [first_var][0]; +#ifdef DEBUG_PUGH + printf(" PUGH_DisableGArrayGroupComm: request for group " + "with first var '%s'\n", GA->name); + fflush(stdout); +#endif -/*@@ - @routine PUGH_DisableGroupComm - @author Thomas Radke - @date 30 Mar 1999 - @desc - Disables communication for all variables in the group indicated by groupname. - @enddesc - @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN - @history - - @endhistory - @var GH - @vdesc Pointer to CCTK grid hierarchy - @vtype cGH - @vio in - @endvar - @var groupname - @vdesc name of the group to be synchronized - @vtype const char * - @vio in - @endvar - @@*/ + return (PUGH_DisableComm(pughGH, GA->groupcomm)); +} -int PUGH_DisableGroupComm(cGH *GH, const char *groupname) + + /*@@ + @routine PUGH_EnableComm + @date Sun Jan 23 12:46:23 2000 + @author Gabrielle Allen + @desc + This sets the docomm[2*dim] array of the GA based + on the setting of the comm flag and allocates the comm buffers. + @enddesc + @history + @date Mon Jun 05 2000 @author Thomas Radke + Moved buffer allocation from PUGH_EnableGArrayDataStorage + @endhistory +@@*/ +static int PUGH_EnableComm(pGH *pughGH, + pComm *comm, + int commflag) { - int group; /* group index */ - cGroup pgroup; /* pointer to group information */ - pGH *pughGH; /* PUGH extension reference */ - int var, level; /* loop variables */ - int first_var; /* global index of first variable in group */ - int rc; /* return code */ + int retval; /* return value */ +#ifdef CCTK_MPI + pGA *GA; /* GA structure the pComm belongs to */ + int i, idir; /* loopers */ + int dir; /* direction */ + int sz; /* buffer size */ +#endif - group = CCTK_GroupIndex(groupname); - /* get the group info from its index */ - CCTK_GroupData (group,&pgroup); + retval = 1; - /* get global index of first variable in group */ - first_var = CCTK_FirstVarIndexI (group); +#ifdef CCTK_MPI + /* check whether this comm buffer is already set up */ + if (comm->commflag == commflag) + { + return (retval); + } - /* get PUGH extension handle */ - pughGH = (pGH *) GH->extensions [pugh_GHExtension]; + /* get the GA structure the comm structure belongs to + For a group comm structure this GA is the first one within the group. */ + GA = (pGA *) pughGH->variables [comm->first_var][comm->sync_timelevel]; - /* branch to "disable comm" function according to group type */ - switch (pgroup.grouptype) + if (comm->commflag == PUGH_NOCOMM) { - case GROUP_SCALAR : - rc = 1; - break; - - case GROUP_ARRAY : - case GROUP_GF : - for (var = first_var; var < first_var+pgroup.numvars; var++) - for (level = 0; level < pgroup.numtimelevels; level++) + +#ifdef DEBUG_PUGH + printf (" PUGH_EnableComm: allocating comm buffer for %d vars starting " + "with %d '%s'\n", comm->n_vars, comm->first_var, GA->name); + fflush (stdout); +#endif + + /* allocate memory for communication buffers: 2 faces per direction */ + for (i = 0; i < 2 * GA->extras->dim; i++) + { + if (GA->connectivity->neighbours[pughGH->myproc][i] >= 0) + { + dir = i/2; + + /* no ghostzones -> no comm buffers */ + sz = comm->n_vars * GA->extras->nghostzones[dir]; + if (sz > 0) { - PUGH_GAComm ((pGA *)(pughGH->variables[var][level]), PUGH_NOCOMM); + for (idir = 0; idir < GA->extras->dim; idir++) + { + if (idir != dir) + { + sz *= GA->extras->lnsize[idir]; + } + } + comm->buffer_sz[i] = sz; + comm->send_buffer[i] = malloc(sz * GA->varsize); + comm->recv_buffer[i] = malloc(sz * GA->varsize); + + if (! (comm->send_buffer[i] && comm->recv_buffer[i])) + { + for (; i >=0 ; i--) + { + if (comm->send_buffer[i]) + { + free(comm->send_buffer[i]); + } + if (comm->recv_buffer[i]) + { + free(comm->recv_buffer[i]); + } + comm->buffer_sz[i] = 0; + } + + CCTK_WARN(1, "Out of memory !"); + retval = -1; + break; + } } - rc = 1; - break; - - default : - CCTK_WARN (1, "Unknown group type in PUGH_DisableGroupComm"); - rc = 0; - break; + else + { + comm->buffer_sz[i] = 0; + comm->send_buffer[i] = NULL; + comm->recv_buffer[i] = NULL; + } + } + else + { + comm->buffer_sz[i] = 0; + comm->send_buffer[i] = NULL; + comm->recv_buffer[i] = NULL; + } + } } - return (rc); -} + /* set up comm flags for each face */ + if (retval >= 0) + { + /* Copy commflag */ + comm->commflag = commflag; + /* First set all communcation off */ + for (idir = 0; idir < 2 * GA->extras->dim; idir++) + comm->docomm[idir] = 0; -int PUGH_Barrier(cGH *GH) -{ -#ifdef CCTK_MPI - pGH *pughGH; + if (commflag == PUGH_ALLCOMM) + { + for (idir = 0; idir < 2 * GA->extras->dim; idir++) + { + comm->docomm[idir] = 1; + } + } + else if (commflag == PUGH_PLUSFACESCOMM) + { + for (idir = 0; idir < GA->extras->dim; idir++) + { + comm->docomm[2*idir+1] = 1; + } + } + else if (commflag == PUGH_MINUSFACESCOMM) + { + for (idir = 0; idir < GA->extras->dim; idir++) + { + comm->docomm[2*idir] = 1; + } + } + else + { + for (idir = 0; idir < GA->extras->dim; idir++) + { + if (commflag == PUGH_COMM(idir)) + { + comm->docomm[2*idir] = 1; + comm->docomm[2*idir+1] = 1; + } + } + } - pughGH = PUGH_pGH(GH); + /* FIXME Add back the check that you have a valid COMM model: Gab */ - CACTUS_MPI_ERROR (MPI_Barrier (pughGH->PUGH_COMM_WORLD)); -#endif + /* Handle nsize = 1 type cases. This is only important for one + processor MPI periodic boundaries */ - return 0; -} + for (idir = 0; idir < GA->extras->dim; idir++) + { + if (GA->extras->nsize[idir] == 1) + { + comm->docomm[2*idir] = 0; + comm->docomm[2*idir+1] = 0; + } + } + } +#endif /* CCTK_MPI */ -/* -int PUGH_Reduce(cGH *GH, - const char *operation, - int n_infields, - int n_outfields, - int out_type, - void **outarray, - ...) -{ - return 0; + return retval; } -*/ -int PUGH_Interp(cGH *GH, - const char *operation, - int n_coords, - int n_infields, - int n_outfields, - int n_points, - int type, - ...) + /*@@ + @routine PUGH_DisableComm + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + This frees the communication buffers + of a given comm structure. + @enddesc + @history + Separated from routine PUGH_DisableGArrayDataStorage() + @endhistory +@@*/ +static int PUGH_DisableComm(pGH *pughGH, + pComm *comm) { - return 0; -} +#ifdef CCTK_MPI + int i; /* looper */ + pGA *GA; /* GA structure the comm structure belongs to */ -int PUGH_ParallelInit(cGH *GH) -{ - return 0; -} + /* get the GA to which the comm structure belongs to + For a comm structure this is the first variable within this group. */ + GA = (pGA *) pughGH->variables [comm->first_var][comm->sync_timelevel]; -int PUGH_Exit(int retval, cGH *GH) -{ -#ifdef CCTK_MPI - CACTUS_MPI_ERROR(MPI_Finalize()); +#ifdef DEBUG_PUGH + printf (" PUGH_DisableComm: freeing comm buffer for group of %d vars and " + "first var '%s'\n", comm->n_vars, GA->name); + fflush (stdout); #endif - exit(retval); - return(retval); -} - -int PUGH_Abort(cGH *GH) -{ - assert(0); - exit(0); - return(0); -} - - -/*****************************************************************************/ -/* local functions */ -/*****************************************************************************/ - + /* free memory for communication buffers: 2 faces per direction */ + for (i = 0; i < 2 * GA->extras->dim; i++) + { + if (comm->send_buffer[i]) + { + if (comm->sreq[i] != MPI_REQUEST_NULL) + { + CACTUS_MPI_ERROR(MPI_Request_free(&comm->sreq[i])); + } + free(comm->send_buffer[i]); + comm->send_buffer[i] = NULL; + } -int PUGH_SyncGroupGA (cGH *GH, - int group, - int vtype, - int n_vars, - int timelevel) -{ + if (comm->recv_buffer[i]) + { + free(comm->recv_buffer[i]); + comm->recv_buffer[i] = NULL; + } - pGH *pughGH; + comm->buffer_sz[i] = 0; + } - pughGH = PUGH_pGH(GH); + comm->commflag = PUGH_NOCOMM; +#endif /* CCTK_MPI */ - return PUGH_SyncGAs(pughGH, - CCTK_GroupDimI(group), - CCTK_FirstVarIndexI(group), - n_vars, - timelevel); + return (1); } -int PUGH_SyncGAs(pGH *pughGH, - int dim, - int first_var, - int n_vars, - int timelevel) + /*@@ + @routine PUGH_Sync + @date Mon Jun 05 2000 + @author Thomas Radke + @desc + Finally synchronizes a variable or group of variables + according to a given comm structure. + @enddesc + @history + @endhistory +@@*/ +static int PUGH_Sync(pGH *pughGH, + pComm *comm) { #ifdef CCTK_MPI - int Dir; + int dir; pGA *GA; -#ifdef COMM_TIMING - double t1,t2; -#endif - MPI_Request *sr = NULL; MPI_Status mss; +#ifdef PUGH_WITH_DERIVED_DATATYPES + int i; + MPI_Request *sr; +#endif +#ifdef COMM_TIMING + double t1, t2; #endif - /* start the timer for communication time */ + #if 0 - CactusStartTimer (&pughGH->comm_time); + /* start the timer for communication time */ + CCTK_TimerStartI(pughGH->comm_time); #endif -#ifdef CCTK_MPI +#ifdef PUGH_WITH_DERIVED_DATATYPES if (pughGH->commmodel == PUGH_DERIVEDTYPES) { - int i; /* 2 faces, send and receive is the 2 * 2 */ - sr = (MPI_Request *)malloc(n_vars * 2 * 2 * sizeof(MPI_Request)); - for (i=0;i<n_vars * 2 * 2; i++) - sr[i] = MPI_REQUEST_NULL; + sr = (MPI_Request *) malloc(comm->n_vars * 2 * 2 * sizeof(MPI_Request)); } +#endif + + GA = (pGA *) pughGH->variables [comm->first_var][comm->sync_timelevel]; + +#ifdef DEBUG_PUGH + printf (" PUGH_Sync: syncing group of %d vars with first var '%s'\n", + comm->n_vars, GA->name); + fflush (stdout); +#endif - for (Dir = 0; Dir < dim; Dir ++) + for (dir = 0; dir < GA->extras->dim; dir ++) { - int i; #ifdef COMM_TIMING t1 = MPI_Wtime(); #endif - for (i = first_var; i < first_var + n_vars; i++) - { - GA = (pGA *) (pughGH->variables [i][timelevel]); - PostReceiveGA(pughGH, GA, 2*Dir); - PostReceiveGA(pughGH, GA, 2*Dir+1); - } + PostReceiveGA(pughGH, 2*dir, comm); + PostReceiveGA(pughGH, 2*dir+1, comm); #ifdef COMM_TIMING t2 = MPI_Wtime(); - printf ("PR : %lf\n",t2-t1); + printf("PR : %f\n",t2-t1); #endif - if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) + + /* For allocated buffers: wait for the last send. + Since these will be null if they + are not used, this is always safe. + */ + if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) { - for (i = first_var; i < first_var + n_vars; i++) - { - GA = (pGA *) (pughGH->variables [i][timelevel]); - /* Wait for the last send. Since these will be null if they - are not used, this is always safe. - */ - MPI_Wait(&(GA->sreq[2*Dir]),&mss); - PostSendGA(pughGH, GA, 2*Dir); - MPI_Wait(&(GA->sreq[2*Dir+1]),&mss); - PostSendGA(pughGH, GA, 2*Dir+1); - } - } - else + MPI_Wait(&comm->sreq[2*dir], &mss); + } + PostSendGA(pughGH, 2*dir, comm); + if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) { - for (i = first_var; i < first_var + n_vars; i++) - { - GA = (pGA *) (pughGH->variables [i][timelevel]); - PostSendGA(pughGH, GA, 2*Dir); - PostSendGA(pughGH, GA, 2*Dir+1); - } + MPI_Wait(&comm->sreq[2*dir+1], &mss); } + PostSendGA(pughGH, 2*dir+1, comm); #ifdef COMM_TIMING t1 = MPI_Wtime(); - printf ("PS : %lf\n",t1-t2); + printf("PS : %f\n",t1-t2); #endif /* Now comes the big difference between derived types and @@ -878,40 +709,37 @@ int PUGH_SyncGAs(pGH *pughGH, if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) { /* Do a wait any on the receives */ - for (i = first_var; i < first_var + n_vars; i++) - { - GA = (pGA *) (pughGH->variables [i][timelevel]); - MPI_Wait(&(GA->rreq[2*Dir]),&mss); - FinishReceiveGA(pughGH, GA, 2*Dir); - MPI_Wait(&(GA->rreq[2*Dir+1]),&mss); - FinishReceiveGA(pughGH, GA, 2*Dir+1); - } - } - - if (pughGH->commmodel == PUGH_DERIVEDTYPES) + MPI_Wait(&comm->rreq[2*dir], &mss); + FinishReceiveGA(pughGH, 2*dir, comm); + MPI_Wait(&comm->rreq[2*dir+1], &mss); + FinishReceiveGA(pughGH, 2*dir+1, comm); + } +#ifdef PUGH_WITH_DERIVED_DATATYPES + else if (pughGH->commmodel == PUGH_DERIVEDTYPES) { /* Load up the thing for the waitall */ - for (i=0;i<n_vars;i++) + for (i = 0; i < comm->n_vars; i++) { - int id = i*4; - GA = (pGA *) (pughGH->variables [i][timelevel]); - if (GA->docomm[2*Dir] && + int id = i * 2 * 2; + pGA *GA = (pGA *) pughGH->variables [i][comm->sync_timelevel]; + + if (GA->comm->docomm[2*dir] && GA->storage) { - sr[id] = GA->sreq[2*Dir]; - sr[id+1] = GA->rreq[2*Dir]; + sr[id] = GA->comm->sreq[2*dir]; + sr[id+1] = GA->comm->rreq[2*dir]; } else { sr[id] = MPI_REQUEST_NULL; sr[id+1] = MPI_REQUEST_NULL; } - - if (GA->docomm[2*Dir+1] && + + if (GA->comm->docomm[2*dir+1] && GA->storage) { - sr[id+2] = GA->sreq[2*Dir+1]; - sr[id+3] = GA->rreq[2*Dir+1]; + sr[id+2] = GA->comm->sreq[2*dir+1]; + sr[id+3] = GA->comm->rreq[2*dir+1]; } else { @@ -920,144 +748,26 @@ int PUGH_SyncGAs(pGH *pughGH, } } /* Now do a waitall */ - MPI_Waitall(4*n_vars,sr,&mss); - + MPI_Waitall(4*comm->n_vars, sr, &mss); } +#endif - if (sr) - free(sr); #ifdef COMM_TIMING t2 = MPI_Wtime(); - printf ("FR : %lf\n",t2-t1); + printf("FR : %f\n",t2-t1); #endif } -#endif /* MPI */ - - /* get the time spent in communication */ - -#if 0 - CactusStopTimer (&pughGH->comm_time); -#endif - - return (1); -} - - -int PUGH_EnableArrayGroupStorage(cGH *GH, - int group, - int vtype, - int dim, - int n_variables, - int n_timelevels) -{ - int nstorage; /* Number of Arrays for which storage was set */ - int nnostorage; /* Number of Arrays for which no storage was set */ - int retval; - int first_var; - int var; - pGH *mypGH; - pGA *GA; - int level; - /* FIXME: This should come from a parameter */ - int zero_memory=1; - int padding_active=0; - int padding_cacheline_bits=0; - int padding_size=0; - int padding_address_spacing=0; - - nstorage = 0; - nnostorage = 0; - - mypGH = PUGH_pGH(GH); - first_var = CCTK_FirstVarIndexI(group); - - for(var = first_var; var < first_var+n_variables; var++) - { - for(level = 0; level < n_timelevels; level++) - { - GA = (pGA *)(mypGH->variables[var][level]); - - if(!GA->storage) - { -#ifdef DEBUG_PUGH - { - const char *name; - name = CCTK_FullName(var); - printf("Storage on in PUGH_EnableArrayGroupStorage for %s\n",name); - } +#ifdef PUGH_WITH_DERIVED_DATATYPES + free(sr); #endif - PUGH_EnablePGAStorage(GA, - mypGH->myproc, - zero_memory, - padding_active, - padding_cacheline_bits, - padding_size, - padding_address_spacing); - - GH->data[var][level] = GA->data; - - nnostorage++; - } - else - { - GH->data[var][level] = GA->data; - nstorage++; - } - } - } - if (nstorage > 0 && nnostorage > 0) - { - CCTK_WARN(0,"Group storage violation in PUGH_EnableArrayGroupStorage"); - retval = -1; - } - else if (nstorage > 0) - { - retval = 1; - } - else if (nnostorage > 0) - { - retval = 0; - } - else - { - CCTK_WARN(0,"Problem in PUGH_EnableArrayGroupStorage"); - retval = -1; - } - - return retval; - -} - - -int PUGH_MyProc(cGH *GH) -{ - int myproc; - -#ifdef CCTK_MPI - pGH *pughGH; - pughGH = PUGH_pGH(GH); - CACTUS_MPI_ERROR(MPI_Comm_rank(pughGH->PUGH_COMM_WORLD, &myproc)); -#else - myproc=0; +#if 0 + /* get the time spent in communication */ + CCTK_TimerStopI(pughGH->comm_time); #endif - return myproc; -} - - -int PUGH_nProcs(cGH *GH) -{ - int nprocs; - -#ifdef CCTK_MPI - pGH *pughGH; - pughGH = PUGH_pGH(GH); - CACTUS_MPI_ERROR(MPI_Comm_size(pughGH->PUGH_COMM_WORLD, &nprocs)); -#else - nprocs=1; -#endif +#endif /* CCTK_MPI */ - return nprocs; + return (0); } diff --git a/src/Evolve.c b/src/Evolve.c index 3a1e9d9..e5b100b 100644 --- a/src/Evolve.c +++ b/src/Evolve.c @@ -49,8 +49,6 @@ static int DoneMainLoop (CCTK_REAL cctk_time, int iteration); static int StepGH(cGH *GH); static void RotateTimeLevelsGH(cGH *cgh); -extern int pugh_GHExtension; - /* the iteration counter used in the evolution loop */ static int iteration = 0; diff --git a/src/FinishReceiveGA.c b/src/FinishReceiveGA.c index d1689da..df4154c 100644 --- a/src/FinishReceiveGA.c +++ b/src/FinishReceiveGA.c @@ -3,9 +3,8 @@ @date Wed Feb 2 11:37:28 1997 @author Gabrielle Allen @desc - The routine which finalize the MPI recieves for a grid - function. Critically linked with @seefile pGA_PostRecv.c - and @seefile pGA_PostSend.c + The routine which finalize the MPI recieves for a communication. + Critically linked with @seefile PostRecvGA.c and @seefile PostSendGA.c @enddesc @version $Header$ @@*/ @@ -17,221 +16,129 @@ #include "cctk.h" #include "pugh.h" -void FinishReceiveGA3(pGH *GH, pGA *GA, int dir); -void FinishReceiveGA1(pGH *GH, pGA *GA, int dir); - static char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusPUGH_PUGH_FinishReceiveGA_c) + +#ifdef CCTK_MPI + /*@@ @routine FinishReceiveGA @date Thu Apr 3 11:38:07 1997 @author Paul Walker @desc This routine finalizes the MPI communication through a face. - It is crucially linked with @seeroutine pGA_PostRecv and - @seeroutine pGA_PostSend. + It is crucially linked with @seeroutine PostRecvGA and + @seeroutine PostSendGA. <p> <b>Important!</b> This routine does <b>not</b> wait on the recieves. Before it is called, you must do the MPI_Wait or else you will not get the right answer. for an - example of this, see @seeroutine SyncGroupGA or - @seeroutine SyncGroupGA + example of this, see @seeroutine PUGH_DisableArrayGroupComm or + @seeroutine PUGH_Sync @enddesc - @calledby SyncGroupGA + @calledby PUGH_Sync @history @hdate Nov 4 1998 @hauthor Gabrielle Allen @hdesc Allow for forced synchronization of all GAs with storage @endhistory @@*/ -void FinishReceiveGA(pGH *GH, pGA *GA, int dir) +void FinishReceiveGA(pGH *pughGH, int dir, pComm *comm) { -#ifdef CCTK_MPI + pGA *GA; + int i, dim, copy_bytes, offset; + char *copy_from, *copy_to; + int *istart, *iend, *iterator; + + + GA = (pGA *) pughGH->variables[comm->first_var][0]; /* Return if GA has no storage */ - if (!(GA->storage)) + if (! GA->storage) { return; } /* Return if communication not required and no forced synchronisation */ - if (!(GH->forceSync || GA->docomm[dir])) + if (! (pughGH->forceSync || comm->docomm[dir])) { return; } - if (GA->connectivity->neighbours[GH->myproc][dir] >= 0) + if (GA->connectivity->neighbours[pughGH->myproc][dir] < 0) { + return; + } - /* Here wait one at a time, so the others can arrive while - we copy the data back in... */ + /* Here wait one at a time, so the others can arrive while + we copy the data back in... */ #ifdef DEBUG_PUGH - printf ("FINISHRECV: GA %s Side %d Proc %d request %d\n", - GA->name,dir,GH->myproc,GA->rreq[dir]); + printf ("FinishReceiveGA: into direction %d from proc %d for %d vars " + "starting with '%s'\n", + dir, GA->connectivity->neighbours[pughGH->myproc][dir], + comm->n_vars, GA->name); #endif - if (GA->extras->dim == 3) - { - FinishReceiveGA3(GH,GA,dir); - } - else if (GA->extras->dim == 1) - { - FinishReceiveGA1(GH,GA,dir); - } - else - { - CCTK_WARN(0,"PUGH does not support this dimension grid"); - } + istart = GA->extras->ghosts[GA->stagger][0][dir]; + iend = GA->extras->ghosts[GA->stagger][1][dir]; + iterator = GA->extras->iterator; + /* set iterator to the start vector */ + for(dim = 0; dim < GA->extras->dim; dim++) + { + iterator[dim] = istart[dim]; } -#endif -} + /* get the source and the number of bytes to copy in the lowest dimension */ + copy_from = comm->recv_buffer[dir]; + copy_bytes = (iend[0] - istart[0]) * GA->varsize; -void FinishReceiveGA3(pGH *GH,pGA *GA,int dir) -{ - int istart,iend,jstart,jend,kstart,kend; - int ii,jj,kk,xx; - CCTK_CHAR *char_data; - CCTK_INT *int_data; - CCTK_REAL *real_data; - CCTK_COMPLEX *complex_data; - - /* Copy buffer onto GA Storage */ - istart = GA->extras->ghosts[GA->stagger][0][dir][0]; - iend = GA->extras->ghosts[GA->stagger][1][dir][0]; - jstart = GA->extras->ghosts[GA->stagger][0][dir][1]; - jend = GA->extras->ghosts[GA->stagger][1][dir][1]; - kstart = GA->extras->ghosts[GA->stagger][0][dir][2]; - kend = GA->extras->ghosts[GA->stagger][1][dir][2]; - - /* Great now copy. Note ordering is just link in PostSend */ - xx=0; - switch (GA->vtype) + /* now do the nested loops starting with the innermost */ + dim = 1; + while (1) { - case CCTK_VARIABLE_CHAR: - char_data = (CCTK_CHAR *) GA->data; - for (kk=kstart; kk<kend; kk++) - { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - char_data [DATINDEX (GA->extras,ii,jj,kk)] = - ((CCTK_CHAR *) GA->recv_buffer[dir]) [xx++]; - } - } - } - break; - - case CCTK_VARIABLE_INT: - int_data = (CCTK_INT *) GA->data; - for (kk=kstart; kk<kend; kk++) + /* check for end of current loop */ + if (GA->extras->dim > 1 && iterator[dim] >= iend[dim]) + { + /* increment outermost loopers */ + for (dim++; dim < GA->extras->dim; dim++) { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - int_data [DATINDEX (GA->extras,ii,jj,kk)] = - ((CCTK_INT *) GA->recv_buffer[dir]) [xx++]; - } - } + iterator[dim]++; + if (iterator[dim] < iend[dim]) + break; } - break; - case CCTK_VARIABLE_REAL: - real_data = (CCTK_REAL *) GA->data; - for (kk=kstart; kk<kend; kk++) - { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - real_data [DATINDEX (GA->extras,ii,jj,kk)] = - ((CCTK_REAL *) GA->recv_buffer[dir]) [xx++]; - } - } - } - break; - - case CCTK_VARIABLE_COMPLEX: - complex_data = (CCTK_COMPLEX *) GA->data; - for (kk=kstart; kk<kend; kk++) - { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - complex_data [DATINDEX (GA->extras,ii,jj,kk)] = - ((CCTK_COMPLEX *) GA->recv_buffer[dir]) [xx++]; - } - } - } - break; + /* done if beyond outermost loop */ + if (dim >= GA->extras->dim) + break; - default: - CCTK_WARN (1, "Unsupported variable type in FinishReceiveGA3"); - return; - } -} + /* reset innermost loopers */ + for (dim--; dim > 0; dim--) + iterator[dim] = istart[dim]; + dim = 1; + } + /* get the linear offset */ + offset = istart[0] * GA->varsize; + for (i = 1; i < GA->extras->dim; i++) + offset += iterator[i] * GA->extras->hyper_volume[i]; + /* copy the data in dimension 0 */ + for (i = comm->first_var; i < comm->first_var + comm->n_vars; i++) + { + copy_to = ((pGA *) pughGH->variables[i][comm->sync_timelevel])->data; + memcpy (copy_to + offset, copy_from, copy_bytes); + copy_from += copy_bytes; + } -void FinishReceiveGA1(pGH *GH,pGA *GA,int dir) -{ - int istart,iend; - int ii,xx; - CCTK_CHAR *char_data; - CCTK_INT *int_data; - CCTK_REAL *real_data; - CCTK_COMPLEX *complex_data; - - /* Copy buffer onto GA Storage */ - istart = GA->extras->ghosts[GA->stagger][0][dir][0]; - iend = GA->extras->ghosts[GA->stagger][1][dir][0]; - - /* Great now copy. Note ordering is just link in PostSend */ - xx=0; - switch (GA->vtype) - { - case CCTK_VARIABLE_CHAR: - char_data = (CCTK_CHAR *) GA->data; - for (ii=istart; ii<iend; ii++) - { - char_data [ii] = ((CCTK_CHAR *)GA->recv_buffer[dir])[xx++]; - } - break; - - case CCTK_VARIABLE_INT: - int_data = (CCTK_INT *) GA->data; - for (ii=istart; ii<iend; ii++) - { - int_data [ii] = ((CCTK_INT *)GA->recv_buffer[dir])[xx++]; - } - break; + /* increment current looper */ + iterator[dim]++; - case CCTK_VARIABLE_REAL: - real_data = (CCTK_REAL *) GA->data; - for (ii=istart; ii<iend; ii++) - { - real_data [ii] = ((CCTK_REAL *)GA->recv_buffer[dir])[xx++]; - } - break; - - case CCTK_VARIABLE_COMPLEX: - complex_data = (CCTK_COMPLEX *) GA->data; - for (ii=istart; ii<iend; ii++) - { - complex_data [ii] = ((CCTK_COMPLEX *)GA->recv_buffer[dir])[xx++]; - } - break; + } /* end of nested loops over all dimensions */ - default: - CCTK_WARN (1, "Unsupported variable type in FinishReceiveGA3"); - return; - } } +#endif /* CCTK_MPI */ diff --git a/src/GHExtension.c b/src/GHExtension.c index 7d9bfcc..23627ff 100644 --- a/src/GHExtension.c +++ b/src/GHExtension.c @@ -80,13 +80,8 @@ void *PUGH_SetupGH(tFleshConfig *config, CCTK_WARN(0,"Failed to allocate memory for a pGH"); } - /* Set the identity for this pGH. */ - - /* FIXME : should be a dynamically allocated string. - * If you change this, please change the line in pugh.h. - */ - - strcpy(newGH->identity_string, ""); + /* Set the identity for this pGH. For now this is an empty string. */ + newGH->identity_string = (char *) calloc (1, sizeof (char *)); /* Set up groups on the GH */ @@ -186,7 +181,7 @@ static void PUGH_InitGHBasics (cGH *GH) pGH *mypGH; pGExtras *GFExtras; - mypGH = (pGH *)GH->extensions[pugh_GHExtension]; + mypGH = PUGH_pGH(GH); GFExtras = mypGH->GFExtras[GH->cctk_dim-1]; GH->cctk_convlevel = 0; @@ -207,7 +202,7 @@ static void PUGH_InitGHBasics (cGH *GH) { GH->cctk_lssh[CCTK_LSSH_IDX(istag,idir)] = GH->cctk_lsh[idir]; if ((GH->cctk_bbox[2*idir+1]==1) && (istag>0)) - GH->cctk_lssh[CCTK_LSSH_IDX(istag,idir)]--; + GH->cctk_lssh[CCTK_LSSH_IDX(istag,idir)]--; } } } @@ -236,7 +231,7 @@ static void PUGH_InitGHVariables (cGH *GH) pGH *mypGH; - mypGH = (pGH *)GH->extensions[pugh_GHExtension]; + mypGH = PUGH_pGH(GH); for(var = 0; var < mypGH->nvariables; var++) { diff --git a/src/LoadAware.c b/src/LoadAware.c index 94c2d17..4a5ce80 100644 --- a/src/LoadAware.c +++ b/src/LoadAware.c @@ -9,6 +9,7 @@ @@*/ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <ctype.h> #include "pugh.h" diff --git a/src/PostReceiveGA.c b/src/PostReceiveGA.c index 3a7864b..caacff0 100644 --- a/src/PostReceiveGA.c +++ b/src/PostReceiveGA.c @@ -3,9 +3,9 @@ @date Wed Feb 2 11:28:06 1997 @author Gabrielle Allen @desc - Routines which post all the IRecv commands for a GA. These - allow the asyncronous model proposed in, for example, - @seeroutine SyncGA to go! + Routines which post all the IRecv commands for a single sync. + These allow the asyncronous model proposed in, for example, + @seeroutine PUGH_Sync to go! @enddesc @version $Header$ @@*/ @@ -21,6 +21,8 @@ CCTK_FILEVERSION(CactusPUGH_PUGH_PostReceiveGA_c) /*#define DEBUG_PUGH*/ +#ifdef CCTK_MPI + /*@@ @routine PostReceiveGA @date Thu Apr 3 12:10:46 1997 @@ -28,8 +30,8 @@ CCTK_FILEVERSION(CactusPUGH_PUGH_PostReceiveGA_c) @desc This routine posts a recieve (MPI_Irecv) of the buffer we want to get the send from another processor, which - will be sent by @seeroutine pGA_PostSend and then - finalized by @seeroutoine pGA_FinishRecv. + will be sent by @seeroutine PostSendGA and then + finalized by @seeroutoine FinishRecvGA. <p> Aside from a silly calculation to get a unique tag based on neigbors and processors, this is a very @@ -41,83 +43,95 @@ CCTK_FILEVERSION(CactusPUGH_PUGH_PostReceiveGA_c) @endhistory @@*/ -void PostReceiveGA(pGH *GH, pGA *GA, int dir) +void PostReceiveGA(pGH *pughGH, int dir, pComm *comm) { -#ifdef CCTK_MPI + pGA *GA; int rtag; - MPI_Datatype mpi_type; - MPI_Datatype *recv_dt; + int neighbour; - if (!(GA->storage)) + GA = (pGA *) pughGH->variables[comm->first_var][0]; + + /* return if no storage assigned */ + if (! GA->storage) { CCTK_VWarn(2, __LINE__, __FILE__, CCTK_THORNSTRING, "Trying to synchronize variable '%s' with no storage", GA->name); return; } - /* Return if communication not required and no forced synchronisation */ - if (!(GH->forceSync || GA->docomm[dir])) + /* return if communication not required and no forced synchronisation */ + if (! (pughGH->forceSync || comm->docomm[dir])) { return; } - if (GA->connectivity->neighbours[GH->myproc][dir] < 0) + /* return if there is no neighbour in the given direction */ + neighbour = GA->connectivity->neighbours[pughGH->myproc][dir]; + if (neighbour < 0) { return; } - switch (GA->vtype) - { - case CCTK_VARIABLE_CHAR: - mpi_type = PUGH_MPI_CHAR; - recv_dt = GH->recv_char_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_INT: - mpi_type = PUGH_MPI_INT; - recv_dt = GH->recv_int_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_REAL: - mpi_type = PUGH_MPI_REAL; - recv_dt = GH->recv_real_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_COMPLEX: - mpi_type = GH->PUGH_mpi_complex; - recv_dt = GH->recv_complex_dt [GA->stagger]; - break; - - default: - CCTK_WARN (1, "Unknown variable type in PostReceiveGA"); - return; - } - - rtag = 1000 + dir + 2 * (GH->myproc + GH->nprocs * GA->id); + /* note this is the complement of the stag set in PostSendGA */ + rtag = 1000 + dir + 2 * (pughGH->myproc + pughGH->nprocs * GA->id); /* mod the tag to force MPI compliance */ rtag = rtag % 32768; + #ifdef DEBUG_PUGH - printf ("RECV GA %s Side %d Proc %d rtag %d size %d from proc %d\n", - GA->name, - dir, - GH->myproc, - rtag, - GA->buffer_sz[dir], - GA->connectivity->neighbours[GH->myproc][dir]); + printf ("PostReceiveGA: into direction %d from proc %d with rtag %d size %d " + "for %d vars starting from '%s'\n", + dir, neighbour, rtag, comm->buffer_sz[dir], comm->n_vars, GA->name); #endif - if (GH->commmodel == PUGH_ALLOCATEDBUFFERS) + + if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) { - CACTUS_MPI_ERROR (MPI_Irecv (GA->recv_buffer [dir], - GA->buffer_sz [dir], mpi_type, - GA->connectivity->neighbours [GH->myproc][dir], rtag, - GH->PUGH_COMM_WORLD, &(GA->rreq [dir]))); + CACTUS_MPI_ERROR (MPI_Irecv (comm->recv_buffer[dir], + comm->buffer_sz[dir], comm->mpi_type, + neighbour, rtag, + pughGH->PUGH_COMM_WORLD, &comm->rreq[dir])); } - if (GH->commmodel == PUGH_DERIVEDTYPES) +#ifdef PUGH_WITH_DERIVED_DATATYPES + else if (pughGH->commmodel == PUGH_DERIVEDTYPES) { - CACTUS_MPI_ERROR (MPI_Irecv (GA->data, - 1, recv_dt [dir], - GA->connectivity->neighbours [GH->myproc][dir], rtag, - GH->PUGH_COMM_WORLD, &(GA->rreq [dir]))); + int var; + MPI_Datatype *recv_dt; + + + switch (GA->vtype) + { + case CCTK_VARIABLE_CHAR: + recv_dt = pughGH->recv_char_dt[GA->stagger]; + break; + + case CCTK_VARIABLE_INT: + recv_dt = pughGH->recv_int_dt[GA->stagger]; + break; + + case CCTK_VARIABLE_REAL: + recv_dt = pughGH->recv_real_dt[GA->stagger]; + break; + + case CCTK_VARIABLE_COMPLEX: + recv_dt = pughGH->recv_complex_dt[GA->stagger]; + break; + + default: + CCTK_WARN (1, "Unknown variable type in PostReceiveGA"); + return; + } + + for (var = comm->first_var; var < comm->first_var + comm->n_vars; var++) + { + pGA *GA = (pGA *) pughGH->variables[var][comm->sync_timelevel]; + + + CACTUS_MPI_ERROR (MPI_Irecv (GA->data, + 1, recv_dt[dir], + neighbour, (rtag + var) % 32768, + pughGH->PUGH_COMM_WORLD, + &GA->comm->rreq[dir])); + } } #endif } +#endif /* CCTK_MPI */ diff --git a/src/PostSendGA.c b/src/PostSendGA.c index 1ef6640..ccaff91 100644 --- a/src/PostSendGA.c +++ b/src/PostSendGA.c @@ -20,11 +20,12 @@ static char *rcsid = "$Header$"; CCTK_FILEVERSION(CactusPUGH_PUGH_PostSendGA_c) -void PostSendGA1(pGH *GH, pGA *GA, int dir); -void PostSendGA3(pGH *GH, pGA *GA, int dir); - /*#define DEBUG_PUGH*/ + +#ifdef CCTK_MPI + + /*@@ @routine PostSendGA @date Thu Apr 3 11:58:59 1997 @@ -32,277 +33,183 @@ void PostSendGA3(pGH *GH, pGA *GA, int dir); @desc This routine posts an asyncronous MPI send of a buffer for a face (MPI_Isend). It does this by first packing up - a send buffer (allocated in @seeroutine SetupPGF) then + a send buffer (allocated in @seeroutine PUGH_SetupGroupComm) then sending it out on the pipe. <p> Since this is an asynchronous communications model we assume that a recieve has been posted for the send. thus the correct calling order for this is as in - @seeroutine SyncGF, eg, after a Recv. + @seeroutine PUGH_Sync, eg, after a Recv. <p> Note this does <b>not</b> wait on the send buffer from previous communications. It is the users responsibility to wait on that buffer. @enddesc - @calledby SyncGroupGF + @calledby PUGH_Sync @history @hdate Nov 4 1998 @hauthor Gabrielle Allen @hdesc Allow for forced synchronization of all GFs with storage @endhistory @@*/ -void PostSendGA(pGH *GH, pGA *GA, int dir) +void PostSendGA(pGH *pughGH, int dir, pComm *comm) { - -#ifdef CCTK_MPI + pGA *GA; int stag, dircomp; - double ts, tw, tp; - MPI_Datatype mpi_type; - MPI_Datatype *send_dt; + int neighbour; + int i, dim, copy_bytes, offset; + char *copy_from, *copy_to; + int *istart, *iend, *iterator; - if (!(GA->storage)) - { - return; - } - - if (!(GH->forceSync || GA->docomm[dir])) + + GA = (pGA *) pughGH->variables[comm->first_var][0]; + + /* return if no storage assigned */ + if (! GA->storage) { return; } - if (GA->connectivity->neighbours[GH->myproc][dir] < 0) + /* return if communication not required and no forced synchronisation */ + if (! (pughGH->forceSync || comm->docomm[dir])) { return; } - switch (GA->vtype) + /* return if there is no neighbour in the given direction */ + neighbour = GA->connectivity->neighbours[pughGH->myproc][dir]; + if (neighbour < 0) { - - case CCTK_VARIABLE_CHAR: - mpi_type = PUGH_MPI_CHAR; - send_dt = GH->send_char_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_INT: - mpi_type = PUGH_MPI_INT; - send_dt = GH->send_int_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_REAL: - mpi_type = PUGH_MPI_REAL; - send_dt = GH->send_real_dt [GA->stagger]; - break; - - case CCTK_VARIABLE_COMPLEX: - mpi_type = GH->PUGH_mpi_complex; - send_dt = GH->send_complex_dt [GA->stagger]; - break; - - default: - CCTK_WARN (1, "Unknown variable type in PostSendGA"); - return; - + return; } - ts = MPI_Wtime(); dircomp = dir+1; /* Complementary direction */ - if (dircomp %2 == 0) + if (dircomp % 2 == 0) { dircomp = dir-1; } - /* Note this is the complement of the rtag set in PostReceive */ - stag = 1000 + dircomp + 2 * - (GA->connectivity->neighbours[GH->myproc][dir] + - GH->nprocs * GA->id); - + /* note this is the complement of the rtag set in PostReceiveGA */ + stag = 1000 + dircomp + 2 * (neighbour + pughGH->nprocs * GA->id); /* mod the tag to force MPI compliance */ stag = stag % 32768; #ifdef DEBUG_PUGH - printf ("SEND: GA %s Side %d Proc %d stag %d Size %d to %d\n", - GA->name, - dir, - GH->myproc, - stag, - GA->buffer_sz[dir], - GA->connectivity->neighbours[GH->myproc][dir]); + printf ("PostSendGA: into direction %d to proc %d with stag %d size %d for " + "%d vars staring with '%s'\n", + dir, neighbour, stag, comm->buffer_sz[dir], comm->n_vars, GA->name); #endif - if (GH->commmodel == PUGH_DERIVEDTYPES) + if (pughGH->commmodel == PUGH_ALLOCATEDBUFFERS) { - CACTUS_MPI_ERROR (MPI_Isend (GA->data, - 1, send_dt [dir], - GA->connectivity->neighbours [GH->myproc][dir], stag, - GH->PUGH_COMM_WORLD, &(GA->sreq [dir]))); - } - if (GH->commmodel == PUGH_ALLOCATEDBUFFERS) - { - if (GA->connectivity->dim == 3) - { - PostSendGA3(GH,GA,dir); - } - else if (GA->connectivity->dim == 1) - { - PostSendGA1(GH,GA,dir); - } - else + istart = GA->extras->overlap[GA->stagger][0][dir]; + iend = GA->extras->overlap[GA->stagger][1][dir]; + iterator = GA->extras->iterator; + + /* set iterator to the start vector */ + for(dim = 0; dim < GA->extras->dim; dim++) { - CCTK_WARN(0,"PUGH does not yet support this dimension"); + iterator[dim] = istart[dim]; } - tp = MPI_Wtime(); - - /* post send */ - CACTUS_MPI_ERROR (MPI_Isend (GA->send_buffer [dir], - GA->buffer_sz [dir], mpi_type, - GA->connectivity->neighbours [GH->myproc][dir], stag, - GH->PUGH_COMM_WORLD, &(GA->sreq [dir]))); - tw = MPI_Wtime(); -#ifdef COMM_TIMING - printf ("GA %s Dir %d Time %f\n", GA->name, dir, tw-ts); -#endif - } -#endif -} + /* get the source and the number of bytes to copy in the lowest dimension */ + copy_to = comm->send_buffer[dir]; + copy_bytes = (iend[0] - istart[0]) * GA->varsize; -void PostSendGA3(pGH *GH, pGA *GA, int dir) -{ - - int ii,jj,kk,xx; - int istart, iend; - int jstart, jend; - int kstart, kend; - CCTK_CHAR *char_data; - CCTK_INT *int_data; - CCTK_REAL *real_data; - CCTK_COMPLEX *complex_data; - - /* Copy my information into the send buffer */ - istart = GA->extras->overlap[GA->stagger][0][dir][0]; - iend = GA->extras->overlap[GA->stagger][1][dir][0]; - jstart = GA->extras->overlap[GA->stagger][0][dir][1]; - jend = GA->extras->overlap[GA->stagger][1][dir][1]; - kstart = GA->extras->overlap[GA->stagger][0][dir][2]; - kend = GA->extras->overlap[GA->stagger][1][dir][2]; - - /* Great now copy */ - xx = 0; - switch (GA->vtype) - { - case CCTK_VARIABLE_CHAR: - char_data = (CCTK_CHAR *) GA->send_buffer [dir]; - for (kk=kstart; kk<kend; kk++) - { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - char_data [xx++] = - ((CCTK_CHAR *) GA->data) [DATINDEX (GA->extras,ii,jj,kk)]; - } - } - } - break; - - case CCTK_VARIABLE_INT: - int_data = (CCTK_INT *) GA->send_buffer [dir]; - for (kk=kstart; kk<kend; kk++) + /* now do the nested loops starting with the innermost */ + dim = 1; + while (1) + { + /* check for end of current loop */ + if (GA->extras->dim > 1 && iterator[dim] >= iend[dim]) { - for (jj=jstart; jj<jend; jj++) + /* increment outermost loopers */ + for (dim++; dim < GA->extras->dim; dim++) { - for (ii=istart; ii<iend; ii++) - { - int_data [xx++] = - ((CCTK_INT *) GA->data) [DATINDEX (GA->extras,ii,jj,kk)]; - } - } - } - break; - - case CCTK_VARIABLE_REAL: - real_data = (CCTK_REAL *) GA->send_buffer [dir]; - for (kk=kstart; kk<kend; kk++) - { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - real_data [xx++] = - ((CCTK_REAL *) GA->data) [DATINDEX (GA->extras,ii,jj,kk)]; - } + iterator[dim]++; + if (iterator[dim] < iend[dim]) + break; } + + /* done if beyond outermost loop */ + if (dim >= GA->extras->dim) + break; + + /* reset innermost loopers */ + for (dim--; dim > 0; dim--) + iterator[dim] = istart[dim]; + dim = 1; } - break; - - case CCTK_VARIABLE_COMPLEX: - complex_data = (CCTK_COMPLEX *) GA->send_buffer [dir]; - for (kk=kstart; kk<kend; kk++) + + /* get the linear offset */ + offset = istart[0] * GA->varsize; + for (i = 1; i < GA->extras->dim; i++) + offset += iterator[i] * GA->extras->hyper_volume[i]; + + /* copy the data in dimension 0 */ + for (i = comm->first_var; i < comm->first_var + comm->n_vars; i++) { - for (jj=jstart; jj<jend; jj++) - { - for (ii=istart; ii<iend; ii++) - { - complex_data [xx++] = - ((CCTK_COMPLEX *) GA->data) [DATINDEX (GA->extras,ii,jj,kk)]; - } - } + copy_from = ((pGA *) pughGH->variables[i][comm->sync_timelevel])->data; + memcpy (copy_to, copy_from + offset, copy_bytes); + copy_to += copy_bytes; } - break; + + /* increment current looper */ + iterator[dim]++; + + } /* end of nested loops over all dimensions */ + + /* now post send */ + CACTUS_MPI_ERROR (MPI_Isend (comm->send_buffer[dir], + comm->buffer_sz[dir], comm->mpi_type, + neighbour, stag, + pughGH->PUGH_COMM_WORLD, &comm->sreq[dir])); } -} +#ifdef PUGH_WITH_DERIVED_DATATYPES + else if (pughGH->commmodel == PUGH_DERIVEDTYPES) + { + int var; + MPI_Datatype *send_dt; + switch (GA->vtype) + { -void PostSendGA1(pGH *GH, pGA *GA, int dir) -{ + case CCTK_VARIABLE_CHAR: + send_dt = pughGH->send_char_dt[GA->stagger]; + break; - int ii,xx; - int istart, iend; - CCTK_CHAR *char_data; - CCTK_INT *int_data; - CCTK_REAL *real_data; - CCTK_COMPLEX *complex_data; - - /* Copy my information into the send buffer */ - istart = GA->extras->overlap[GA->stagger][0][dir][0]; - iend = GA->extras->overlap[GA->stagger][1][dir][0]; - - /* Great now copy */ - xx = 0; - switch (GA->vtype) - { - case CCTK_VARIABLE_CHAR: - char_data = (CCTK_CHAR *) GA->send_buffer [dir]; - for (ii=istart; ii<iend; ii++) - { - char_data [xx++] = ((CCTK_CHAR *) GA->data) [ii]; - } - break; - - case CCTK_VARIABLE_INT: - int_data = (CCTK_INT *) GA->send_buffer [dir]; - for (ii=istart; ii<iend; ii++) - { - int_data [xx++] = ((CCTK_INT *) GA->data) [ii]; - } - break; - - case CCTK_VARIABLE_REAL: - real_data = (CCTK_REAL *) GA->send_buffer [dir]; - for (ii=istart; ii<iend; ii++) - { - real_data [xx++] = ((CCTK_REAL *) GA->data) [ii]; - } - break; - - case CCTK_VARIABLE_COMPLEX: - complex_data = (CCTK_COMPLEX *) GA->send_buffer [dir]; - for (ii=istart; ii<iend; ii++) - { - complex_data [xx++] = ((CCTK_COMPLEX *) GA->data) [ii]; - } - break; + case CCTK_VARIABLE_INT: + send_dt = pughGH->send_int_dt[GA->stagger]; + break; + + case CCTK_VARIABLE_REAL: + send_dt = pughGH->send_real_dt[GA->stagger]; + break; + + case CCTK_VARIABLE_COMPLEX: + send_dt = pughGH->send_complex_dt[GA->stagger]; + break; + + default: + CCTK_WARN (1, "Unknown variable type in PostSendGA"); + return; + + } + + for (var = comm->first_var; var < comm->first_var + comm->n_vars; var++) + { + pGA *GA = (pGA *) pughGH->variables[var][comm->sync_timelevel]; + + + CACTUS_MPI_ERROR (MPI_Isend (GA->data, + 1, send_dt[dir], + neighbour, (stag + var) % 32768, + pughGH->PUGH_COMM_WORLD, + &GA->comm->sreq[dir])); + } } +#endif } +#endif /* CCTK_MPI */ diff --git a/src/Reduction.c b/src/Reduction.c index a9243ab..a91d469 100644 --- a/src/Reduction.c +++ b/src/Reduction.c @@ -37,9 +37,6 @@ CCTK_FILEVERSION(CactusPUGH_PUGH_Reduction_c) #define SQR(x) ((x) * (x)) -/* index into GH->extensions[] to get the PUGH extension handle */ -extern int pugh_GHExtension; - /* local function prototypes */ int PUGH_Norm1_GF (cGH *GH, int index, int proc, CCTK_REAL *outVal); int PUGH_Norm2_GF (cGH *GH, int index, int proc, CCTK_REAL *outVal); @@ -142,12 +139,10 @@ void PUGH_ReduceArrayMinVal (cGH *GH, int proc, int nDims, int dims [], { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceArrayMinVal: don't know how to reduce a " - "%d-dimensional array with %d elements to an output " - "array of %d elements", nDims, nPoints, nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a %d-dimensional array with " + "%d elements to an output array of %d elements", + nDims, nPoints, nOutVals); return; } nPoints = 1; @@ -265,12 +260,10 @@ void PUGH_ReduceArrayMaxVal (cGH *GH, int proc, int nDims, int dims [], { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceArrayMaxVal: don't know how to reduce a " - "%d-dimensional array with %d elements to an output " - "array of %d elements", nDims, nPoints, nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a %d-dimensional array " + "with %d elements to an output array of %d elements", + nDims, nPoints, nOutVals); return; } nPoints = 1; @@ -386,12 +379,10 @@ void PUGH_ReduceArraySum (cGH *GH, int proc, int nDims, int dims [], { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceArraySum: don't know how to reduce a " - "%d-dimensional array with %d elements to an output " - "array of %d elements", nDims, nPoints, nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a %d-dimensional array with " + "%d elements to an output array of %d elements", + nDims, nPoints, nOutVals); return; } nPoints = 1; @@ -511,12 +502,10 @@ void PUGH_ReduceArrayNorm1 (cGH *GH, int proc, int nDims, int dims [], { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceArrayNorm1: don't know how to reduce a " - "%d-dimensional array with %d elements to an output " - "array of %d elements", nDims, nPoints, nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a %d-dimensional array with " + "%d elements to an output array of %d elements", + nDims, nPoints, nOutVals); return; } nPoints = 1; @@ -636,12 +625,10 @@ void PUGH_ReduceArrayNorm2 (cGH *GH, int proc, int nDims, int dims [], { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceArrayNorm2: don't know how to reduce a " - "%d-dimensional array with %d elements to an output " - "array of %d elements", nDims, nPoints, nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a %d-dimensional array with " + "%d elements to an output array of %d elements", + nDims, nPoints, nOutVals); return; } nPoints = 1; @@ -725,12 +712,12 @@ void PUGH_ReduceArrayNorm2 (cGH *GH, int proc, int nDims, int dims [], @endvar @@*/ void PUGH_ReduceMinVal (cGH *GH, - int proc, - int nOutVals, + int proc, + int nOutVals, int outType, - void *outVals, - int numinvars, - int *varlist) + void *outVals, + int numinvars, + int *varlist) { int i; @@ -750,11 +737,9 @@ void PUGH_ReduceMinVal (cGH *GH, { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceMinVal: don't know how to reduce a GF " - "to an output array of %d elements", nOutVals); - CCTK_WARN (1, msg); + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a GF to an output array " + "of %d elements", nOutVals); return; } nPoints = 1; @@ -884,12 +869,9 @@ void PUGH_ReduceMaxVal (cGH *GH, int proc, int nOutVals, { if (nOutVals != nPoints) { - char msg [200]; - - sprintf (msg, "PUGH_ReduceMaxVal: don't know how to reduce a GF " - "to an output array of %d elements", nOutVals); - CCTK_WARN (1, msg); - return; + CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, + "Don't know how to reduce a GF to an output array " + "of %d elements", nOutVals); } nPoints = 1; } @@ -2118,9 +2100,6 @@ int PUGH_Norm2_GF (cGH *GH, int index, int proc, CCTK_REAL *outVal) CCTK_INT np; CCTK_REAL local_result; #endif - int dim; - - dim = GH->cctk_dim; timelevel = CCTK_NumTimeLevelsFromVarI (index) - 1; if (timelevel > 0) diff --git a/src/SetupGroup.c b/src/SetupGroup.c index 812aae4..7bba580 100644 --- a/src/SetupGroup.c +++ b/src/SetupGroup.c @@ -36,13 +36,10 @@ CCTK_FILEVERSION (CactusPUGH_PUGH_SetupGroup_c) @@*/ -int PUGH_SetupScalarGroup - ( - pGH *newGH, - int vtype, - int n_variables, - int n_timelevels - ) +int PUGH_SetupScalarGroup(pGH *newGH, + int vtype, + int n_variables, + int n_timelevels) { int retval=PUGH_SUCCESS; int variable; @@ -67,7 +64,7 @@ int PUGH_SetupScalarGroup for(level = 0; level < n_timelevels; level++) { newGH->variables[newGH->nvariables][level] = - (void *)malloc(var_size); + (void *)malloc(var_size); } newGH->nvariables++; } @@ -105,16 +102,14 @@ int PUGH_SetupScalarGroup @@*/ int PUGH_SetupArrayGroup(pGH *newGH, - int *nsize, - int *ghostsize, - int vtype, - int dim, - int n_variables, - int staggercode, - int n_timelevels) + int *nsize, + int *ghostsize, + int vtype, + int dim, + int n_variables, + int staggercode, + int n_timelevels) { - - int i; int variable; int var_size = CCTK_VarTypeSize(vtype); int retval = PUGH_SUCCESS; @@ -122,34 +117,16 @@ int PUGH_SetupArrayGroup(pGH *newGH, void ***temp; pConnectivity *connectivity; pGExtras *extras; + pComm *groupcomm; int *perme; int *nprocs; - /* Arrays can't (yet) have periodicity */ - perme = (int *) malloc(dim*sizeof(int)); - if (perme) - { - for (i=0;i<dim;i++) - { - perme[i]=0; - } - } - else - { - CCTK_WARN(0,"Memory error in PUGH"); - } - - /* Arrays can't (yet) have manual set up */ - nprocs = (int *) malloc(dim*sizeof(int)); - if (nprocs) - { - for (i=0;i<dim;i++) - { - nprocs[i]=0; - } - } - else + /* Arrays can't (yet) have periodicity and manual setup, + so initialize them to zero */ + perme = (int *) calloc(dim, sizeof(int)); + nprocs = (int *) calloc(dim, sizeof(int)); + if (! (perme && nprocs)) { CCTK_WARN(0,"Memory error in PUGH"); } @@ -168,6 +145,23 @@ int PUGH_SetupArrayGroup(pGH *newGH, free(nprocs); free(perme); + /* Set up the communication buffer used for all variables within this group. + Note: only with allocated buffers we can have group communication. */ + if(newGH->commmodel == PUGH_ALLOCATEDBUFFERS) + { + groupcomm = PUGH_SetupGArrayGroupComm(newGH, + dim, + newGH->nvariables, + n_variables, + n_timelevels - 1, + vtype, + extras); + } + else + { + groupcomm = NULL; + } + temp = (void ***)realloc (newGH->variables,(newGH->nvariables+n_variables)*sizeof(void **)); @@ -185,14 +179,15 @@ int PUGH_SetupArrayGroup(pGH *newGH, for(level = 0; level < n_timelevels; level++) { newGH->variables[newGH->nvariables][level] = - PUGH_SetupPGA(newGH, - extras, - connectivity, - CCTK_VarName(newGH->nvariables), - newGH->nvariables, - var_size, - vtype, - staggercode); + PUGH_SetupGArray(newGH, + extras, + connectivity, + groupcomm, + CCTK_VarName(newGH->nvariables), + newGH->nvariables, + var_size, + vtype, + staggercode); } newGH->nvariables++; } @@ -241,6 +236,15 @@ int PUGH_SetupGFGroup(pGH *newGH, int retval=PUGH_SUCCESS; int level; void ***temp; + pComm *groupcomm; + + groupcomm = PUGH_SetupGArrayGroupComm(newGH, + dim, + newGH->nvariables, + n_variables, + n_timelevels - 1, + vtype, + newGH->GFExtras[dim-1]); temp = (void ***)realloc(newGH->variables, (newGH->nvariables+n_variables)*sizeof(void **)); @@ -258,15 +262,16 @@ int PUGH_SetupGFGroup(pGH *newGH, { for(level = 0; level < n_timelevels; level++) { - newGH->variables[newGH->nvariables][level] = - PUGH_SetupPGA(newGH, - newGH->GFExtras[dim-1], - newGH->Connectivity[dim-1], - CCTK_VarName(newGH->nvariables), - newGH->nvariables, - var_size, - vtype, - staggercode); + newGH->variables[newGH->nvariables][level] = + PUGH_SetupGArray(newGH, + newGH->GFExtras[dim-1], + newGH->Connectivity[dim-1], + groupcomm, + CCTK_VarName(newGH->nvariables), + newGH->nvariables, + var_size, + vtype, + staggercode); } newGH->nvariables++; } diff --git a/src/SetupPGH.c b/src/SetupPGH.c index 441ed59..3d4b1b0 100644 --- a/src/SetupPGH.c +++ b/src/SetupPGH.c @@ -13,6 +13,11 @@ #include <stdio.h> #include <stdlib.h> #include <math.h> +#include <assert.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #include "cctk.h" #include "pugh.h" @@ -46,7 +51,7 @@ pGH *PUGH_SetupPGH(void *callerid, int *nsize, int *nghostzones, int staggertype, - int *perme) + int *perme) { DECLARE_CCTK_PARAMETERS @@ -77,28 +82,34 @@ pGH *PUGH_SetupPGH(void *callerid, GH->Connectivity[idim-1]= PUGH_SetupConnectivity(idim, - GH->nprocs, - nprocs, - perme); + GH->nprocs, + nprocs, + perme); free(nprocs); GH->GFExtras[idim-1]= PUGH_SetupPGExtras(idim, - perme, - staggertype, - nsize, - nghostzones, - GH->nprocs, - ((pConnectivity **)GH->Connectivity)[idim-1]->nprocs, - GH->myproc); + perme, + staggertype, + nsize, + nghostzones, + GH->nprocs, + ((pConnectivity **)GH->Connectivity)[idim-1]->nprocs, + GH->myproc); } GH->active = 1; GH->commmodel = PUGH_ALLOCATEDBUFFERS; + #if 0 - CactusResetTimer (&GH->comm_time); + /* create the timer for communication time */ + if(comm_verbose) + { + GH->comm_time = CCTK_TimerCreateI (); + } #endif + /* set staggering flag */ /*GH->stagger = staggertype; */ GH->level = 0; @@ -201,7 +212,8 @@ void PUGH_DestroyPGH(pGH **GHin) { #ifdef DEBUG_PUGH - printf("Calling Destroying Group %s \n",CCTK_GroupName(group)); + printf("Calling Destroying Group %s\n", CCTK_GroupName(group)); + fflush(stdout); #endif CCTK_GroupData(group,&pgroup); @@ -214,7 +226,7 @@ void PUGH_DestroyPGH(pGH **GHin) { case GROUP_GF: case CCTK_ARRAY: - PUGH_DestroyPGA(&(((pGA ***)GH->variables)[variable][i])); + PUGH_DestroyGArray(&(((pGA ***)GH->variables)[variable][i])); break; case GROUP_SCALAR: free(GH->variables[variable][i]); @@ -231,13 +243,12 @@ void PUGH_DestroyPGH(pGH **GHin) PUGH_DestroyPGExtras(&GH->GFExtras[i-1]); } + free(GH->identity_string); free(GH->Connectivity); free(GH->GFExtras); free(GH->variables); free(GH); *GHin = NULL; - - fflush(stdout); } void pGH_DumpInfo(pGH *GH) @@ -323,3 +334,51 @@ int PUGH_SetupDefaultTopology(int dim, int *nprocs) return retval; } + +int PUGH_ParallelInit(cGH *GH) +{ + return 0; +} + +int PUGH_Exit(int retval, cGH *GH) +{ +#ifdef CCTK_MPI + CACTUS_MPI_ERROR(MPI_Finalize()); +#endif + exit(retval); + return(retval); +} +int PUGH_Abort(cGH *GH) +{ + assert(0); + exit(0); + return(0); +} + + +int PUGH_MyProc(cGH *GH) +{ + int myproc; + +#ifdef CCTK_MPI + CACTUS_MPI_ERROR(MPI_Comm_rank(PUGH_pGH(GH)->PUGH_COMM_WORLD, &myproc)); +#else + myproc = 0; +#endif + + return myproc; +} + + +int PUGH_nProcs(cGH *GH) +{ + int nprocs; + +#ifdef CCTK_MPI + CACTUS_MPI_ERROR(MPI_Comm_size(PUGH_pGH(GH)->PUGH_COMM_WORLD, &nprocs)); +#else + nprocs = 1; +#endif + + return nprocs; +} diff --git a/src/SetupPGV.c b/src/SetupPGV.c index 171aa7c..d27ace0 100644 --- a/src/SetupPGV.c +++ b/src/SetupPGV.c @@ -69,12 +69,12 @@ pGExtras *PUGH_SetupPGExtras(int dim, this->dim = dim; - PUGH_SetupPGExtrasSizes (dim, perme, stagger, sh, nghosts, - total_procs, nprocs, this_proc,this); + PUGH_SetupPGExtrasSizes(dim, perme, stagger, sh, nghosts, + total_procs, nprocs, this_proc,this); PUGH_SetupPGExtrasOwnership(dim, perme, stagger, sh, nghosts, - total_procs, nprocs, this_proc, this); + total_procs, nprocs, this_proc, this); PUGH_SetupPGExtrasStaggering(dim, perme, stagger, sh, nghosts, - total_procs, nprocs, this_proc, this); + total_procs, nprocs, this_proc, this); } } @@ -124,6 +124,8 @@ void PUGH_DestroyPGExtras(pGExtras **PGExtras) free((*PGExtras)->nghostzones); free((*PGExtras)->nsize); free((*PGExtras)->lnsize); + free((*PGExtras)->iterator); + free((*PGExtras)->hyper_volume); free(*PGExtras); *PGExtras = NULL; @@ -552,9 +554,11 @@ int PUGH_SetupPGExtrasMemory(int dim, this->rnpoints = (int *) malloc(total_procs*sizeof(int)); /* Things just depending on dimension */ - this->nghostzones = (int *)malloc(dim*sizeof(int)); - this->nsize = (int *)malloc(dim*sizeof(int)); - this->lnsize = (int *)malloc(dim*sizeof(int)); + this->nghostzones = (int *)malloc(dim*sizeof(int)); + this->nsize = (int *)malloc(dim*sizeof(int)); + this->lnsize = (int *)malloc(dim*sizeof(int)); + this->iterator = (int *)malloc(dim*sizeof(int)); + this->hyper_volume = (int *)malloc(dim*sizeof(int)); /* Check all the above succeeded and then get memory for * arrays hanging off the above. @@ -565,7 +569,9 @@ int PUGH_SetupPGExtrasMemory(int dim, this->rnpoints && this->nghostzones && this->nsize && - this->lnsize) + this->lnsize && + this->iterator && + this->hyper_volume) { this->lb[0] = (int *)malloc(total_procs *dim*sizeof(int)); this->ub[0] = (int *)malloc(total_procs *dim*sizeof(int)); @@ -607,6 +613,10 @@ int PUGH_SetupPGExtrasMemory(int dim, this->nsize = NULL; free(this->lnsize); this->lnsize = NULL; + free(this->iterator); + this->iterator = NULL; + free(this->hyper_volume); + this->hyper_volume = NULL; } } else @@ -626,6 +636,10 @@ int PUGH_SetupPGExtrasMemory(int dim, this->nsize = NULL; free(this->lnsize); this->lnsize = NULL; + free(this->iterator); + this->iterator = NULL; + free(this->hyper_volume); + this->hyper_volume = NULL; } @@ -635,7 +649,9 @@ int PUGH_SetupPGExtrasMemory(int dim, this->rnpoints && this->nghostzones && this->nsize && - this->lnsize) + this->lnsize && + this->iterator && + this->hyper_volume) { retcode = 0; for (i = 0 ; i < PUGH_NSTAGGER; i++) @@ -735,6 +751,10 @@ int PUGH_SetupPGExtrasMemory(int dim, this->nsize = NULL; free(this->lnsize); this->lnsize = NULL; + free(this->iterator); + this->iterator = NULL; + free(this->hyper_volume); + this->hyper_volume = NULL; } } } @@ -853,14 +873,14 @@ int PUGH_SetupPGExtrasSizes(int dim, @@*/ int PUGH_SetupPGExtrasOwnership(int dim, - int *perme, - int stagger, - int *sh, - int *nghosts, - int total_procs, - int *nprocs, - int this_proc, - pGExtras *this) + int *perme, + int stagger, + int *sh, + int *nghosts, + int total_procs, + int *nprocs, + int this_proc, + pGExtras *this) { int tmp; int dir, idir; @@ -1180,394 +1200,307 @@ int PUGH_SetupRemoteSizes(int dim, return 0; } + /*@@ - @routine PUGH_SetupPGA - @date Mon Nov 8 16:29:34 1999 - @author Tom Goodale + @routine PUGH_SetupGArrayGroupComm + @date Tue 06 Jun 2000 + @author Thomas Radke @desc - Sets up a new pGA. + Sets up a communication buffer for a group of GAs. @enddesc @calls @calledby @history @endhistory - @@*/ -pGA *PUGH_SetupPGA(void *parent, - pGExtras *extras, - pConnectivity *connectivity, - const char *name, - int id, - int varsize, - int vtype, - int stagger) +pComm *PUGH_SetupGArrayGroupComm(pGH *pughGH, + int dim, + int first_var, + int n_vars, + int sync_timelevel, + int vartype, + pGExtras *extras) { - pGA *this; int i; - this = (pGA *)malloc(sizeof(pGA)); + pComm *this; - if(this) - { - this->extras = extras; - this->connectivity = connectivity; - this->parent = parent; - this->varsize = varsize; - this->vtype = vtype; - this->stagger = stagger; - this->id = id; - this->storage = PUGH_NOSTORAGE; - this->commflag = PUGH_NOCOMM; + this = (pComm *) malloc (sizeof (pComm)); - this->name = (char *) malloc((strlen(name)+1)*sizeof(char)); - this->buffer_sz = (int *) malloc(2*extras->dim*sizeof(int)); - this->send_buffer = (void **)malloc(2*extras->dim*sizeof(void *)); - this->recv_buffer = (void **)malloc(2*extras->dim*sizeof(void *)); - this->docomm = (int *) malloc(2*extras->dim*sizeof(int)); - this->padddata = (void *) calloc(1, varsize); - this->data = this->padddata; - + if (this) + { + this->buffer_sz = (int *) malloc (2 * dim * sizeof (int)); + this->send_buffer = (void **) malloc (2 * dim * sizeof (void *)); + this->recv_buffer = (void **) malloc (2 * dim * sizeof (void *)); #ifdef CCTK_MPI - this->sreq = (MPI_Request *)malloc(2*extras->dim*sizeof(MPI_Request)); - this->rreq = (MPI_Request *)malloc(2*extras->dim*sizeof(MPI_Request)); + this->sreq = (MPI_Request *) malloc (2 * dim * sizeof (MPI_Request)); + this->rreq = (MPI_Request *) malloc (2 * dim * sizeof (MPI_Request)); #endif + this->docomm = (int *) malloc (2 * dim * sizeof (int)); - if(this->name && - this->buffer_sz && + if(this->buffer_sz && this->send_buffer && this->recv_buffer && - this->docomm && #ifdef CCTK_MPI this->sreq && this->rreq && #endif - this->padddata) + this->docomm) { - strcpy(this->name, name); + this->commflag = PUGH_NOCOMM; + this->first_var = first_var; + this->n_vars = n_vars; + this->sync_timelevel = sync_timelevel; - for(i = 0; i < 2*extras->dim; i++) +#ifdef CCTK_MPI + switch (vartype) + { + case CCTK_VARIABLE_CHAR: + this->mpi_type = PUGH_MPI_CHAR; break; + case CCTK_VARIABLE_INT4: + this->mpi_type = PUGH_MPI_INT4; break; + case CCTK_VARIABLE_INT: + this->mpi_type = PUGH_MPI_INT; break; + case CCTK_VARIABLE_REAL4: + this->mpi_type = PUGH_MPI_REAL4; break; + case CCTK_VARIABLE_REAL: + this->mpi_type = PUGH_MPI_REAL; break; + case CCTK_VARIABLE_COMPLEX: + this->mpi_type = pughGH->PUGH_mpi_complex; break; + + default: + CCTK_WARN (1, "Unsupported variable type for PUGH communication"); + break; + } +#endif + + for (i = 0; i < 2 * dim; i++) { this->buffer_sz[i] = 0; this->send_buffer[i] = NULL; this->recv_buffer[i] = NULL; - this->docomm[i] = 0; #ifdef CCTK_MPI /* Null my send and receive requests */ - this->sreq[i] = MPI_REQUEST_NULL; - this->rreq[i] = MPI_REQUEST_NULL; + this->sreq[i] = MPI_REQUEST_NULL; + this->rreq[i] = MPI_REQUEST_NULL; #endif + this->docomm[i] = PUGH_NOCOMM; } } else { - free(this->name); - free(this->buffer_sz); - free(this->send_buffer); - free(this->recv_buffer); - free(this->docomm); - free(this->padddata); - + if (this->buffer_sz) + { + free (this->buffer_sz); + } + if (this->send_buffer) + { + free (this->send_buffer); + } + if (this->recv_buffer) + { + free (this->recv_buffer); + } #ifdef CCTK_MPI - free(this->sreq); - free(this->rreq); + if (this->sreq) + { + free (this->sreq); + } + if (this->rreq) + { + free (this->rreq); + } #endif - free(this); + if (this->docomm) + { + free (this->docomm); + } + + free (this); this = NULL; } } + /* Now set the hyper_volume vector in the extras structure + which is used to copy the ghostzones from/to the comm buffers. + NOTE: Sizes are already in bytes here. hyper_volume[0] is unused. + */ + if(this) + { + extras->hyper_volume[0] = CCTK_VarTypeSize(vartype); + for (i = 1; i < extras->dim; i++) + { + extras->hyper_volume[i] = extras->hyper_volume[i-1] * extras->lnsize[i-1]; + } + } + return this; } + /*@@ - @routine PUGH_DestroyPGA - @date Mar 12 2000 + @routine PUGH_SetupGArrayComm + @date Tue 06 Jun 2000 @author Thomas Radke @desc - Destroys a pGA object. + Sets up a communication buffer for a GA. @enddesc @calls @calledby @history @endhistory - @@*/ -void PUGH_DestroyPGA(pGA **GA) +pComm *PUGH_SetupGArrayComm(pGH *pughGH, + int dim, + int var, + int sync_timelevel, + int vartype, + pGExtras *extras) { - if(GA && *GA) - { - if((*GA)->storage != PUGH_NOSTORAGE) - { - PUGH_DisableGADataStorage(*GA); - } - free((*GA)->name); - free((*GA)->buffer_sz); - free((*GA)->send_buffer); - free((*GA)->recv_buffer); - free((*GA)->docomm); - free((*GA)->padddata); - -#ifdef CCTK_MPI - free((*GA)->sreq); - free((*GA)->rreq); -#endif - free(*GA); - *GA = NULL; - } + return PUGH_SetupGArrayGroupComm(pughGH, + dim, + var, + 1, + sync_timelevel, + vartype, + extras); } -int PUGH_EnablePGAStorage(pGA *GA, - int this_proc, - int zero_memory, - int padding_active, - int padding_cacheline_bits, - int padding_size, - int padding_address_spacing) + + /*@@ + @routine PUGH_DestroyComm + @date Tue 06 Jun 2000 + @author Thomas Radke + @desc + Destroys a communication buffer. + @enddesc + @calls + @calledby + @history + + @endhistory +@@*/ +void PUGH_DestroyComm(pComm **comm) { - int retval; - int i; - int dir; - int sz; - int ldir; - char *temp_byte; -#if 0 - int special_pad, cache_size; - long start; + free ((*comm)->buffer_sz); + free ((*comm)->send_buffer); + free ((*comm)->recv_buffer); +#ifdef CCTK_MPI + free ((*comm)->sreq); + free ((*comm)->rreq); #endif + free ((*comm)->docomm); + free (*comm); - retval = 0; - if(GA->storage == PUGH_NOSTORAGE) - { - /* Allocate memory for communication buffers */ - for(i = 0; i < 2*GA->extras->dim; i++) - { - dir = i/2; - - sz = GA->extras->nghostzones[dir]; - for(ldir = 0; ldir < GA->extras->dim; ldir++) - { - sz *= GA->extras->lnsize[ldir]; - } - - sz /= GA->extras->lnsize[dir]; - - if(GA->connectivity->neighbours[this_proc][i] >= 0) - { - GA->buffer_sz[i] = sz; - GA->send_buffer[i] = malloc(sz * GA->varsize); - GA->recv_buffer[i] = malloc(sz * GA->varsize); - - if(!(GA->send_buffer[i] - && GA->recv_buffer[i])) - { - retval = -1; - break; - } - } - else - { - GA->buffer_sz[i] = 0; - GA->send_buffer[i] = NULL; - GA->recv_buffer[i] = NULL; - } - } - - if(retval) - { - for(; i >=0 ; i--) - { - free(GA->send_buffer[i]); - free(GA->recv_buffer[i]); - GA->buffer_sz[i] = 0; - } - } - - /* Now assign memory for the variable itself */ - if(!retval) - { - if(GA->padddata) - { - free(GA->padddata); - } + *comm = NULL; +} - if(!padding_active) - { - /* Easy case. */ - if(zero_memory) - { - GA->padddata = calloc(GA->extras->npoints, GA->varsize); - } - else - { - GA->padddata = malloc(GA->extras->npoints * GA->varsize); - } - GA->data = GA->padddata; - } - else - { + /*@@ + @routine PUGH_SetupGArray + @date Mon Nov 8 16:29:34 1999 + @author Tom Goodale + @desc + Sets up a new pGA. + @enddesc + @calls + @calledby + @history + + @endhistory - /* Use the Cactus Cache alignment function */ - GA->data = Util_CacheMalloc(GA->id, - GA->extras->npoints * GA->varsize, - &(GA->padddata)); - - /* Zero the memory if desired. */ - if(GA->data && zero_memory) - { - for(temp_byte = (char *)GA->data; - temp_byte < ((char *)GA->data)+GA->extras->npoints * GA->varsize; - temp_byte++) - { - *temp_byte = 0; - } - } +@@*/ +pGA *PUGH_SetupGArray(void *parent, + pGExtras *extras, + pConnectivity *connectivity, + pComm *groupcomm, + const char *name, + int id, + int varsize, + int vtype, + int stagger) +{ + pGA *this; - } - } - } + this = (pGA *)malloc(sizeof(pGA)); - if (!GA->padddata) + if(this) { - CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, - "FATAL ERROR: Cannot allocate data for %s [%d]\n", - GA->name, GA->id); - } - - GA->storage = PUGH_STORAGE; - - return retval; - -} + this->extras = extras; + this->connectivity = connectivity; + this->comm = NULL; + this->groupcomm = groupcomm; + this->parent = parent; + this->varsize = varsize; + this->vtype = vtype; + this->stagger = stagger; + this->id = id; -int PUGH_DisableGADataStorage(pGA *GA) -{ - int retval; - int i; + this->storage = PUGH_NOSTORAGE; - if (GA->storage == PUGH_STORAGE) - { - if (GA->padddata) + this->name = (char *) malloc((strlen(name)+1)*sizeof(char)); + this->padddata = (void *) calloc(1, varsize); + this->data = this->padddata; + + if(this->name && this->padddata) { - free(GA->padddata); - GA->padddata = NULL; - GA->data = NULL; + strcpy(this->name, name); } - - for (i = 0; i < 2*GA->extras->dim; i++) + else { - if (GA->send_buffer[i]) + if(this->name) { -#ifdef CCTK_MPI - if(GA->sreq[i] != MPI_REQUEST_NULL) - { - CACTUS_MPI_ERROR(MPI_Request_free(&(GA->sreq[i]))); - } -#endif - free(GA->send_buffer[i]); - GA->send_buffer[i] = NULL; + free(this->name); } - } - - for (i = 0; i < 2*GA->extras->dim; i++) - { - if (GA->recv_buffer[i]) + if(this->padddata) { - free(GA->recv_buffer[i]); - GA->recv_buffer[i] = NULL; + free(this->padddata); } + free(this); + this = NULL; } - - GA->padddata = calloc(1, GA->varsize); - GA->data = GA->padddata; - - GA->storage = PUGH_NOSTORAGE; - retval = 0; - } - else - { - retval = 1; } - return retval; + return this; } - /*@@ - @routine PUGH_GAComm - @date Sun Jan 23 12:46:23 2000 - @author Gabrielle Allen + @routine PUGH_DestroyGArray + @date Mar 12 2000 + @author Thomas Radke @desc - This sets the docomm[2*dim] array of the GA based - on the setting of the comm flag. + Destroys a pGA object. @enddesc -@@*/ - + @calls + @calledby + @history + + @endhistory -void PUGH_GAComm(pGA *GA, int docomm) +@@*/ +void PUGH_DestroyGArray(pGA **GA) { - int idir; - int dim = GA->extras->dim; - - /* Copy docomm */ - GA->commflag = docomm; - - /* First set all communcation off */ - for (idir=0;idir<2*dim;idir++) - GA->docomm[idir] = 0; - - if (docomm == PUGH_NOCOMM) - { - for (idir=0;idir<2*dim;idir++) - GA->docomm[idir] = 0; - } - else if (docomm == PUGH_ALLCOMM) - { - for (idir=0;idir<2*dim;idir++) - { - GA->docomm[idir] = 1; - } - } - else if (docomm == PUGH_PLUSFACESCOMM) - { - for (idir=0;idir<dim;idir++) - { - GA->docomm[2*idir+1] = 1; - } - } - else if (docomm == PUGH_MINUSFACESCOMM) + if(GA && *GA) { - for (idir=0;idir<dim;idir++) + if((*GA)->storage != PUGH_NOSTORAGE) { - GA->docomm[2*idir] = 1; + PUGH_DisableGArrayDataStorage(*GA); } - } - else - { - for (idir=0;idir<dim;idir++) + /* destroy group comm buffers only once per group */ + if((*GA)->groupcomm && (*GA)->groupcomm->first_var == (*GA)->id) { - if (docomm == PUGH_COMM(idir)) - { - GA->docomm[2*idir] = 1; - GA->docomm[2*idir+1] = 1; - } + PUGH_DestroyComm(&(*GA)->groupcomm); } - } - - /* FIXME Add back the check that you have a valid COMM model: Gab */ - - /* Handle nsize = 1 type cases. This is only important for one - processor MPI periodic boundaries */ - - for (idir=0;idir<dim;idir++) - { - if (GA->extras->nsize[idir] == 1) + if((*GA)->comm) { - GA->docomm[2*idir] = 0; - GA->docomm[2*idir+1] = 0; + PUGH_DestroyComm(&(*GA)->comm); } + free((*GA)->name); + free((*GA)->padddata); + + free(*GA); + *GA = NULL; } - } diff --git a/src/Startup.c b/src/Startup.c index fb5a51a..10a0740 100644 --- a/src/Startup.c +++ b/src/Startup.c @@ -17,15 +17,10 @@ #include "pugh_Comm.h" #include "pugh_reductions.h" -static char *WhatIsPugh(void); - static char *rcsid="$Header$"; CCTK_FILEVERSION(CactusPUGH_PUGH_Startup_c) -/* Store the handle in a global variable for the moment. */ -int pugh_GHExtension; - /*@@ @routine PUGH_Startup @@ -43,6 +38,7 @@ int pugh_GHExtension; @@*/ int PUGH_Startup(void) { + int pugh_GHExtension; char *banner; /* Register the stuff in the GH extension. */ @@ -94,7 +90,7 @@ int PUGH_Startup(void) } - +#if 0 /*@@ @routine WhatIsPugh @date Mon Apr 14 22:13:12 1997 @@ -140,4 +136,4 @@ static char *WhatIsPugh(void) return (pughnames[which]); } - +#endif diff --git a/src/Storage.c b/src/Storage.c new file mode 100644 index 0000000..801f1a4 --- /dev/null +++ b/src/Storage.c @@ -0,0 +1,561 @@ + /*@@ + @file Storage.c + @date Tue Jun 13 2000 + @author Thomas Radke + @desc + Pugh storage functions + @enddesc + @version $Header$ + @@*/ + +/*#define DEBUG_PUGH*/ + +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "cctk.h" +#include "cctk_Parameters.h" + +#include "pugh.h" +#include "pughi.h" + +static char *rcsid="$Header$"; + +CCTK_FILEVERSION(CactusPUGH_PUGH_Storage_c) + +static int totalstorage = 0; /* Storage for GAs in Bytes */ +static int totalnumber = 0; /* Number of stored GAs */ + + +/*@@ + @routine PUGH_ArrayGroupSize + @author Gabrielle Allen + @date 11 Apr 1999 + @desc + Returns size of arrays in a group, in a given direction + @enddesc + @calls + @history + + @endhistory + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH + @vio in + @endvar + @var groupname + @vdesc name of the group to be synchronized + @vtype const char * + @vio in + @vcomment either index or groupname must be present + @endvar + @var group + @vdesc index of group + @vtype int + @vio in + @vcomment either index or groupname must be given + @endvar + @var dir + @vdesc direction + @vtype int + @vio in + @@*/ + +const int *PUGH_ArrayGroupSize(cGH *GH, int dir, int group, const char *groupname) +{ + int *sizep; + pGA *GA; + + if (groupname) + { + group = CCTK_GroupIndex(groupname); + } + + /* get pointer to pGA for a timelevel of first variable in this group */ + GA = (pGA *) PUGH_pGH(GH)->variables[CCTK_FirstVarIndexI(group)][0]; + + if (GA->storage == PUGH_STORAGE) + { + if (dir >= 0 && dir < GA->extras->dim) + { + sizep = &GA->extras->lnsize[dir]; + } + else + { + sizep = NULL; + CCTK_WARN(1, "Wrong value for dir"); + } + } + else + { + sizep = &_cctk_one; + } + + return (sizep); +} + + +/*@@ + @routine PUGH_QueryGroupStorage + @author Gabrielle Allen + @date 13 Apr 1999 + @desc + Returns true if group has storage assigned, false otherwise + @enddesc + @calls CCTK_DecomposeName + @history + + @endhistory + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH + @vio in + @endvar + @var groupname + @vdesc name of the group to be queried + @vtype const char * + @vio in + @vcomment either index or groupname must be present + @endvar + @var group + @vdesc index of group + @vtype int + @vio in + @vcomment either index or groupname must be given + @endvar + @@*/ + +int PUGH_QueryGroupStorage(cGH *GH, int group, const char *groupname) +{ + + int first; + int storage=PUGH_UNDEFINEDSTORAGE; + int retval; + int grouptype; + + if (groupname) + { + group = CCTK_GroupIndex(groupname); + } + + /* get first variable in group */ + first = CCTK_FirstVarIndexI(group); + if (first < 0) + { + CCTK_VWarn(0, __LINE__, __FILE__, CCTK_THORNSTRING, + "Invalid group ID %d in PUGH_QueryGroupStorage", group); + } + + grouptype = CCTK_GroupTypeI(group); + + if (grouptype == CCTK_SCALAR) + { + storage = PUGH_STORAGE; + } + else if (grouptype == CCTK_GF || grouptype == CCTK_ARRAY) + { + storage = ((pGA *) PUGH_pGH(GH)->variables[first][0])->storage; + } + else + { + CCTK_WARN(0,"Unknown group type in PUGH_QueryGroupStorage"); + } + + if (storage == PUGH_STORAGE) + { + retval = 1; + } + else if (storage == PUGH_NOSTORAGE) + { + retval = 0; + } + else + { + CCTK_WARN(0,"Inconsistency in PUGH_QueryGroupStorage"); + retval = PUGH_ERROR; + } + + return (retval); +} + + +/*@@ + @routine PUGH_EnableGroupStorage + @author Tom Goodale + @date 30 Mar 1999 + @desc + Enables storage for all variables in the group indicated by groupname. + @enddesc + @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN + PUGH_EnableGArrayGroupStorage + @history + + @endhistory + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH + @vio in + @endvar + @var groupname + @vdesc name of the group to be synchronized + @vtype const char * + @vio in + @endvar + @@*/ + +int PUGH_EnableGroupStorage(cGH *GH, const char *groupname) +{ + + DECLARE_CCTK_PARAMETERS + + int group; /* group index */ + int first_var; /* first variable's index */ + cGroup pgroup; /* group information */ + int rc; /* return code */ + pGA *GA; + pGH *pughGH; + +#ifdef DEBUG_PUGH + printf(" PUGH_EnableGroupStorage: request for group '%s'\n", groupname); + fflush(stdout); +#endif + + pughGH = PUGH_pGH(GH); + group = CCTK_GroupIndex(groupname); + first_var = CCTK_FirstVarIndexI(group); + + /* get the group info from its index */ + CCTK_GroupData(group, &pgroup); + + /* SCALAR types have always switched on memory */ + if (pgroup.grouptype == CCTK_SCALAR) + { + rc = 1; + } + else if (pgroup.grouptype == CCTK_GF || pgroup.grouptype == CCTK_ARRAY) + { + rc = PUGH_EnableGArrayGroupStorage(pughGH, + first_var, + pgroup.numvars, + pgroup.numtimelevels); + } + else + { + CCTK_WARN(1, "Unknown group type in PUGH_EnableGroupStorage"); + rc = -1; + } + + /* Report on memory usage */ + if (storage_verbose) + { + if (rc == 0) + { + /* get GA pointer of first var in group */ + GA = (pGA *) pughGH->variables[first_var][0]; + + /* Memory toggled */ + totalnumber += pgroup.numvars; + totalstorage += GA->extras->npoints * GA->varsize * + pgroup.numtimelevels * pgroup.numvars; + printf("Switched memory on for %s \n [Num Arrays: %d Total Size: %d]\n", + groupname,totalnumber,totalstorage); + } + else if (rc == 1) + { + /* Memory already on */ + printf("Memory already on for %s\n",groupname); + } + } + + return (rc); + +} + + +/*@@ + @routine PUGH_DisableGroupStorage + @author Tom Goodale + @date 30 Mar 1999 + @desc + Disables storage for all variables in the group indicated by groupname. + @enddesc + @calls CCTK_DecomposeName CCTK_GroupIndex CCTK_GroupData CCTK_WARN + @history + + @endhistory + @var GH + @vdesc Pointer to CCTK grid hierarchy + @vtype cGH + @vio in + @endvar + @var groupname + @vdesc name of the group to be synchronized + @vtype const char * + @vio in + @endvar + @@*/ + +int PUGH_DisableGroupStorage(cGH *GH, const char *groupname) +{ + DECLARE_CCTK_PARAMETERS + + int group; /* group index */ + cGroup pgroup; /* group information */ + int rc; /* return code */ + pGH *pughGH; /* PUGH extension reference */ + pGA *GA; + int level; + int first_var,var; + int unchanged; /* count how many aren't toggled */ + + /* get PUGH extension handle */ + pughGH = PUGH_pGH(GH); + +#ifdef DEBUG_PUGH + printf(" PUGH_DisableGroupStorage: request for group '%s'\n", groupname); + fflush(stdout); +#endif + + /* get the group info from its index */ + group = CCTK_GroupIndex(groupname); + CCTK_GroupData(group, &pgroup); + + /* get global index of first variable in group */ + first_var = CCTK_FirstVarIndexI(group); + + unchanged = 0; + + if (pgroup.grouptype == CCTK_SCALAR) + { + rc = 1; + } + else if (pgroup.grouptype == CCTK_GF || pgroup.grouptype == CCTK_ARRAY) + { + for (var = first_var; var < first_var+pgroup.numvars; var++) + { + for (level = 0; level < pgroup.numtimelevels; level++) + { + unchanged = unchanged + + PUGH_DisableGArrayDataStorage((pGA *)(pughGH->variables[var][level])); + } + } + + rc = 1; + } + else + { + CCTK_WARN(1, "Unknown group type in PUGH_DisableGroupStorage"); + rc = 0; + } + + /* Report on memory usage */ + if (storage_verbose) + { + if (unchanged == 0) + { + GA = (pGA *) pughGH->variables[first_var][0]; + + /* Memory toggled */ + totalnumber -= pgroup.numvars; + totalstorage -= GA->extras->npoints * GA->varsize * + pgroup.numtimelevels * pgroup.numvars; + printf("Switched memory off for %s \n [Num Arrays: %d Total Size: %d]\n", + groupname,totalnumber,totalstorage); + } + else if (unchanged == pgroup.numvars) + { + /* Memory already off */ + printf("Memory already off for %s\n",groupname); + } + else + { + CCTK_WARN(1,"Inconsistency in group memory assignment"); + } + } + + return (rc); +} + + +/*****************************************************************************/ +/* local functions */ +/*****************************************************************************/ + +int PUGH_EnableGArrayGroupStorage(pGH *pughGH, + int first_var, + int n_variables, + int n_timelevels) +{ + DECLARE_CCTK_PARAMETERS + int nstorage; /* Number of Arrays for which storage was set */ + int nnostorage; /* Number of Arrays for which no storage was set */ + int retval; + int var; + pGA *GA; + int level; + + nstorage = 0; + nnostorage = 0; + + for (var = first_var; var < first_var + n_variables; var++) + { + for (level = 0; level < n_timelevels; level++) + { + GA = (pGA *) pughGH->variables[var][level]; + + if (! GA->storage) + { +#ifdef DEBUG_PUGH + printf(" PUGH_EnableGArrayGroupStorage: request for var '%s' " + "timelevel %d\n", GA->name, level); + fflush(stdout); +#endif + PUGH_EnableGArrayDataStorage(GA, + pughGH->myproc, + zero_memory, + padding_active, + padding_cacheline_bits, + padding_size, + padding_address_spacing); + + ((cGH *) pughGH->callerid)->data[var][level] = GA->data; + + nnostorage++; + } + else + { + ((cGH *) pughGH->callerid)->data[var][level] = GA->data; + nstorage++; + } + } + } + + if (nstorage > 0 && nnostorage > 0) + { + CCTK_WARN(0, "Group storage violation in PUGH_EnableGArrayGroupStorage"); + retval = -1; + } + else if (nstorage > 0) + { + retval = 1; + } + else if (nnostorage > 0) + { + retval = 0; + } + else + { + CCTK_WARN(0, "Problem in PUGH_EnableGArrayGroupStorage"); + retval = -1; + } + + return retval; + +} + + +int PUGH_EnableGArrayDataStorage(pGA *GA, + int this_proc, + int zero_memory, + int padding_active, + int padding_cacheline_bits, + int padding_size, + int padding_address_spacing) +{ + + if(GA->storage == PUGH_NOSTORAGE) + { +#ifdef DEBUG_PUGH + printf(" PUGH_EnableGArrayDataStorage: allocating storage " + "for var '%s'\n", GA->name); + fflush(stdout); +#endif + + /* Now assign memory for the variable itself */ + if(GA->padddata) + { + free(GA->padddata); + } + + if(!padding_active) + { + /* Easy case. */ + if(zero_memory) + { + GA->padddata = calloc(GA->extras->npoints, GA->varsize); + } + else + { + GA->padddata = malloc(GA->extras->npoints * GA->varsize); + } + + GA->data = GA->padddata; + } + else + { + + /* Use the Cactus Cache alignment function */ + GA->data = Util_CacheMalloc(GA->id, + GA->extras->npoints * GA->varsize, + &(GA->padddata)); + + /* Zero the memory if desired. */ + if(GA->data && zero_memory) + { + memset(GA->data, 0, GA->extras->npoints * GA->varsize); + } + + } + } + + if (!GA->padddata) + { + CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, + "FATAL ERROR: Cannot allocate data for %s [%d]\n", + GA->name, GA->id); + } + + GA->storage = PUGH_STORAGE; + + return 0; + +} + + +int PUGH_DisableGArrayDataStorage(pGA *GA) +{ + int retval; + + if (GA->storage == PUGH_STORAGE) + { +#ifdef DEBUG_PUGH + printf(" PUGH_DisableGArrayDataStorage: freeing storage for var '%s'\n", + GA->name); + fflush(stdout); +#endif + if (GA->padddata) + { + free(GA->padddata); + GA->padddata = NULL; + GA->data = NULL; + } + + GA->padddata = calloc(1, GA->varsize); + GA->data = GA->padddata; + + GA->storage = PUGH_NOSTORAGE; + retval = 0; + } + else + { + retval = 1; + } + + return retval; +} diff --git a/src/include/pGH.h b/src/include/pGH.h index 9fe17e7..d5139d9 100644 --- a/src/include/pGH.h +++ b/src/include/pGH.h @@ -13,10 +13,6 @@ typedef struct PGH { -#ifdef CCTK_MPI - MPI_Comm PUGH_COMM_WORLD; /* A MPIcommunicator */ -#endif - /* pGH identifier */ void *callerid; int dim; /* The dimension of the GH */ @@ -55,12 +51,16 @@ typedef struct PGH /* 0 -> GH is skipped for conv.test */ /* is used in NanCheckGH.c */ +#if 1 /* FIXME */ double comm_time; /* time spent in communication */ +#endif #ifdef CCTK_MPI - /* the complex datatype defined in SetupPGH.c */ - MPI_Datatype PUGH_mpi_complex; + MPI_Datatype PUGH_mpi_complex;/* the MPI datatype for COMPLEX types */ + MPI_Comm PUGH_COMM_WORLD; /* the MPI communicator */ + +#ifdef PUGH_WITH_DERIVED_DATATYPES /* Derived data types for communication */ MPI_Datatype send_char_dt [PUGH_NSTAGGER][6]; MPI_Datatype recv_char_dt [PUGH_NSTAGGER][6]; @@ -71,15 +71,14 @@ typedef struct PGH MPI_Datatype send_complex_dt [PUGH_NSTAGGER][6]; MPI_Datatype recv_complex_dt [PUGH_NSTAGGER][6]; #endif +#endif /* Used for all grid functions */ pGExtras **GFExtras; /* [dim] stagger ? */ pConnectivity **Connectivity; /* [dim] */ - /* FIXME : should be a dynamically allocated string. - * If you change this, please change the line in PUGH_SetupGH. - */ - char identity_string[20]; + char *identity_string; /* identifier for this pGH */ + } pGH; #define XDP 1 diff --git a/src/include/pGV.h b/src/include/pGV.h index 841ecb0..e86afb1 100644 --- a/src/include/pGV.h +++ b/src/include/pGV.h @@ -49,6 +49,10 @@ typedef struct PGExtras int *rnpoints; /* Number of points on each proc */ int **rnsize; /* [#points on a proc][in each dir] */ + /* Copying ghostzones to/from comm buffers */ + int *iterator; /* Iterator for copying ghostzones [dim] */ + int *hyper_volume; /* Points per subcube dimension [dim] */ + /* Ghosts and overlaps. */ int *nghostzones; /* Width of ghost zone */ int *ownership[PUGH_NSTAGGER][2]; @@ -65,19 +69,34 @@ typedef struct PGExtras } pGExtras; +typedef struct PComm +{ + /* buffer_sz[2*dim] */ + int *buffer_sz; /* Size of the face ghost zones */ + void **send_buffer; /* Storage for buffered Comm if */ + void **recv_buffer; /* we don't use derived types */ + int commflag; /* What is the comm flag set to? */ + /* do_comm[2*dim] */ + int *docomm; /* Do we do comm or not? */ + + int first_var; /* first variable to be synced */ + int n_vars; /* number of variables to be synced */ + int sync_timelevel; /* the timelevel to be synced */ + +#ifdef CCTK_MPI + MPI_Request *sreq, *rreq; /* Comm requests and statuses. */ + MPI_Status ms; + MPI_Datatype mpi_type; /* MPI datatype to use for communication */ +#endif + +} pComm; + typedef struct PGA { char *name; /* The name of the grid function */ int id; /* My ID number in my GH parent. */ void *padddata; /* Storage for the data. */ void *data; /* See the note above. */ - /* buffer_sz[2*dim] */ - int *buffer_sz; /* Size of the face ghost zones */ - void **send_buffer; /* Storage for buffered Comm if */ - void **recv_buffer; /* we don't use derived types */ - int commflag; /* What is the comm flag set to? */ - /* do_comm[2*dim] */ - int *docomm; /* Do we do comm or not? */ int storage; /* Do we have storage or not? */ int stagger; /* Only Vertex Centered now... */ @@ -92,13 +111,12 @@ typedef struct PGA int varsize; /* The size of the data */ int vtype; /* The type of the data */ -#ifdef CCTK_MPI - MPI_Request *sreq, *rreq; /* Comm requests and statuses. */ - MPI_Status ms; -#endif - pGExtras *extras; pConnectivity *connectivity; + + pComm *comm; /* comm buffer for single variable */ + pComm *groupcomm; /* comm buffer for a variable group */ + } pGA; typedef struct PGV diff --git a/src/include/pugh.h b/src/include/pugh.h index ce8c89b..7408c0f 100644 --- a/src/include/pugh.h +++ b/src/include/pugh.h @@ -72,18 +72,21 @@ #ifdef CCTK_MPI -#define CACTUS_MPI_ERROR(xf) do {int errcode; \ - if((errcode = xf) != MPI_SUCCESS) \ - { \ - char mpi_error_string[MPI_MAX_ERROR_STRING+1]; \ - int resultlen; \ - MPI_Error_string(errcode, mpi_error_string, &resultlen);\ - fprintf(stderr, "MPI Call %s returned error code %d (%s)\n", \ - #xf, errcode, mpi_error_string); \ - fprintf(stderr, "At line %d of file %s\n", \ - __LINE__, __FILE__); \ - } \ - } while (0) +#define CACTUS_MPI_ERROR(fn_call) \ + do { \ + int errcode; \ + \ + if ((errcode = fn_call) != MPI_SUCCESS) \ + { \ + char mpi_error_string[MPI_MAX_ERROR_STRING+1]; \ + int resultlen; \ + \ + MPI_Error_string (errcode, mpi_error_string, &resultlen); \ + fprintf (stderr, "MPI call '%s' returned error code %d (%s)\n", \ + #fn_call, errcode, mpi_error_string); \ + fprintf(stderr, "At line %d of file %s\n", __LINE__, __FILE__); \ + } \ + } while (0) #endif #ifdef _cplusplus @@ -93,21 +96,21 @@ extern "C" int PUGH_SetupGroup(pGH *newGH, - int *nsize, - int *nghostsize, - int gtype, - int vtype, - int dim, - int n_variables, - int staggertype, - int n_timelevels); + int *nsize, + int *nghostsize, + int gtype, + int vtype, + int dim, + int n_variables, + int staggertype, + int n_timelevels); pGH *PUGH_SetupPGH(void *callerid, int dim, int *nsize, int *nghostzones, - int staggertype, - int *perme); + int staggertype, + int *perme); int PUGH_GFSize(int dim, int *nsize); @@ -115,7 +118,7 @@ int PUGH_GFSize(int dim, int PUGH_GFGhostsize(int dim, int *ghostsize); int PUGH_GFPeriodic(int dim, - int *perme); + int *perme); pGH *PUGH_pGH(cGH *GH); diff --git a/src/include/pughi.h b/src/include/pughi.h index 8defba7..f6fdf1c 100644 --- a/src/include/pughi.h +++ b/src/include/pughi.h @@ -30,22 +30,22 @@ pGExtras *PUGH_SetupPGExtras(int dim, int *nprocs, int this_proc); -pGA *SetupPGA(void *parent, - pGExtras *extras, - pConnectivity *connectivity, - const char *name, - int id, - int varsize, - int vtype, - int stagger); - - -void pGH_DumpInfo(pGH *GH); +pComm *PUGH_SetupGArrayGroupComm(pGH *pughGH, + int dim, + int first_var, + int n_vars, + int sync_timelevel, + int vartype, + pGExtras *extras); + +void pGH_DumpInfo(pGH *pughGH); int PUGH_SetupDefaultTopology(int dim, int *nprocs); -int pGH_SetupnProcs(pGH *GH,int dim); -void PUGH_DestroyPGA(pGA **GA); +int pGH_SetupnProcs(pGH *pughGH,int dim); +void PUGH_DestroyGArray(pGA **GA); +void PUGH_DestroyComm(pComm **comm); void PUGH_DestroyConnectivity(pConnectivity **conn); void PUGH_DestroyPGExtras(pGExtras **PGExtras); +void PUGH_DestroyPGH(pGH **pughGH); int PUGH_GenerateTopology(int dim, int total_procs, int *nprocs); @@ -104,25 +104,6 @@ int PUGH_SetupRemoteSizes(int dim, int *nprocs, pGExtras *this); -pGA *PUGH_SetupPGA(void *parent, - pGExtras *extras, - pConnectivity *connectivity, - const char *name, - int id, - int varsize, - int vtype, - int stagger); - -int PUGH_EnablePGAStorage(pGA *GA, - int this_proc, - int zero_memory, - int padding_active, - int padding_cacheline_bits, - int padding_size, - int padding_address_spacing); - -int PUGH_DisableGADataStorage(pGA *GA); - int PUGH_SetupPGExtrasStaggering(int dim, int *perme, int stagger, @@ -133,6 +114,51 @@ int PUGH_SetupPGExtrasStaggering(int dim, int this_proc, pGExtras *this); +pGA *PUGH_SetupGArray(void *parent, + pGExtras *extras, + pConnectivity *connectivity, + pComm *comm, + const char *name, + int id, + int varsize, + int vtype, + int stagger); + +pComm *PUGH_SetupGArrayComm(pGH *pughGH, + int dim, + int var, + int sync_timelevel, + int vartype, + pGExtras *extras); + +int PUGH_EnableGArrayGroupStorage(pGH *pughGH, + int first_var, + int n_variables, + int n_timelevels); + +int PUGH_EnableGArrayDataStorage(pGA *GA, + int this_proc, + int zero_memory, + int padding_active, + int padding_cacheline_bits, + int padding_size, + int padding_address_spacing); + +int PUGH_DisableGArrayDataStorage(pGA *GA); + +int PUGH_EnableGArrayComm(pGA *GA, + int commflag); + +int PUGH_DisableGArrayComm(pGA *GA); + +int PUGH_SyncGArray(pGA *GA); + +#ifdef CCTK_MPI +void PostSendGA (pGH *pughGH, int dir, pComm *comm); +void PostReceiveGA (pGH *pughGH, int dir, pComm *comm); +void FinishReceiveGA(pGH *pughGH, int dir, pComm *comm); +#endif + #ifdef _cplusplus } #endif diff --git a/src/make.code.defn b/src/make.code.defn index d28f187..f5cda42 100644 --- a/src/make.code.defn +++ b/src/make.code.defn @@ -1,8 +1,4 @@ # Main make.code.defn file for thorn pugh # : /usr/users/cactus/CCTK/lib/make/new_thorn.pl,v 1.1 1999/02/03 17:00:50 goodale Exp n # Source files in this directory -SRCS = Evolve.c Startup.c GHExtension.c Comm.c SetupPGH.c SetupGroup.c Reduction.c PughUtils.c SetupPGV.c PostSendGA.c PostReceiveGA.c FinishReceiveGA.c LoadAware.c - -# Subdirectories containing source files -SUBDIRS = - +SRCS = Evolve.c Startup.c GHExtension.c Comm.c Storage.c SetupPGH.c SetupGroup.c Reduction.c PughUtils.c SetupPGV.c PostSendGA.c PostReceiveGA.c FinishReceiveGA.c LoadAware.c diff --git a/src/pugh_extension.h b/src/pugh_extension.h index b2b2b1b..62cf29b 100644 --- a/src/pugh_extension.h +++ b/src/pugh_extension.h @@ -11,8 +11,6 @@ #ifndef _PUGH_EXTENSION_H_ #define _PUGH_EXTENSION_H_ 1 -extern int pugh_GHExtension; - #ifdef _cplusplus extern "C" { |