aboutsummaryrefslogtreecommitdiff
path: root/src/SetupPGV.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/SetupPGV.c')
-rw-r--r--src/SetupPGV.c105
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