diff options
Diffstat (limited to 'src/SetupPGV.c')
-rw-r--r-- | src/SetupPGV.c | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/src/SetupPGV.c b/src/SetupPGV.c index b01403b..93a2d56 100644 --- a/src/SetupPGV.c +++ b/src/SetupPGV.c @@ -180,9 +180,12 @@ void PUGH_DestroyPGExtras(pGExtras **PGExtras) @@*/ pConnectivity *PUGH_SetupConnectivity(int dim, int total_procs, + const int *nsize, + const int *nghostzones, int *nprocs, int *perme) { + DECLARE_CCTK_PARAMETERS pConnectivity *this; int i; @@ -238,7 +241,15 @@ pConnectivity *PUGH_SetupConnectivity(int dim, this->neighbours[i] = this->neighbours[0]+(2*dim*i); } - PUGH_GenerateTopology(dim, total_procs, this->nprocs); + if (CCTK_EQUALS(processor_topology, "automatic")) + { + PUGH_GenerateAlternativeTopology(dim, total_procs, nsize, nghostzones, + this->nprocs); + } + else + { + PUGH_GenerateTopology(dim, total_procs, this->nprocs); + } PUGH_GenerateNeighbours(dim, total_procs, this->nprocs, this->neighbours, this->perme); } @@ -382,6 +393,98 @@ int PUGH_GenerateTopology(int dim, int total_procs, int *nprocs) return retval; } + + + /*@@ + @routine PUGH_GenerateAlternativeTopology + @date Thu Feb 02 17:39:21 2005 + @author Frank Loeffler + @desc + Generate the appropriate processor topology for this processor + decomposition. + This routine tries to decompose using the information about the actual + grid size. It can fail in certain situations in which it falls back + gracefully to the traditional decomposition giving a warning. + It also does not support manually set topologies and falls back in this + case. + @enddesc + @history + @endhistory +@@*/ +int PUGH_GenerateAlternativeTopology(int dim, + int total_procs, const int *nsize, + const int *nghostzones, int *nprocs) +{ + int i; + int max_dir, max_length; + int free_procs = total_procs-1; + int used_procs = 1; + + + /* Nothing to decompose here */ + if (dim == 0) + { + return PUGH_GenerateTopology(dim, total_procs, nprocs); + } + /* If there are numbers already set up or we have funny grid sizes, + fall back */ + for (i = 0; i < dim; i++) + { + if (nprocs[i] || (nsize[i]<1)) + { + return PUGH_GenerateTopology(dim, total_procs, nprocs); + } + } + /* start with a single domain */ + for (i = 0; i < dim; i++) + { + nprocs[i] = 1; + } + /* divide as long as there are processors left */ + while (free_procs) + { + used_procs = total_procs - free_procs; + /* find the direction with the longest length, which is allowed */ + max_dir = -1; + max_length = 0; + for (i = 0; i < dim; i++) + { + /* is one part larger than the max? (then it might be a new max) */ + if ((nsize[i] / nprocs[i] > max_length) && + /* would there be at least one real point if we divide? */ + (nsize[i] > 2*nghostzones[i]+nprocs[i]) && + /* do we have enough processors left to divide in this direction? */ + (used_procs/nprocs[i] <= free_procs)) + { + max_length = nsize[i] / nprocs[i]; + max_dir = i; + } + } + /* if no such direction is found: fall back giving a warning */ + if (max_dir == -1) + { + for (i = 0; i < dim; i++) + { + nprocs[i] = 0; + } + CCTK_WARN(CCTK_WARN_COMPLAIN, + "Falling back to the old PUGH topology method, overwriting " + "eventually set manual topologies"); + return PUGH_GenerateTopology(dim, total_procs, nprocs); + } + /* count the new direction and go on */ + /* note: this is garanteed to decrement at least by one, since the number + of used processors is naturally always >= the number of processors used + for one dimension */ + free_procs -= used_procs/nprocs[max_dir]; + nprocs[max_dir]++; + } + /* success */ + return 0; +} + + + /*@@ @routine PUGH_GenerateNeighbours @date Mon Nov 8 08:15:08 1999 |