/* Function to partition a given number of processors nprocs into a processor grid nprocs=px*py*pz ..., such that: px*weights[0] + py*weights[1] + ... is minimized. Use -DTEST to compile the test code. The function can be called from a Fortran program, e.g.: PARAMETER (NDIM=3) INTEGER NP(NDIM) DOUBLE PRECISION WEIGHTS(NDIM) DATA WEIGHTS/1.,1.,1./ ... ... CALL PARTITION(32,NP,WEIGHTS,NDIM) (or IERR=PARTITION(32,NP,WEIGHTS,NDIM) ) ... ... By ZLB. */ #ifdef VERBOSE # define TEST #endif #include #include #include #include #define MAXFACTORS 16 int partition_(int *n, int *np, double *weights, int *ndim); static int compare(double sum, int *npwork, double best_sum, int *np); /* the functions with a "stack" argument are recursive */ static void next_factor(int facno, int prod, int dimen); static void next_dimension(int dimen); #ifdef TEST void main(void) { int i, n, dim, *np; double *weights; fprintf(stderr,"Enter dimension: "); scanf("%d",&dim); np=malloc(dim*sizeof(*np)); weights=malloc(dim*sizeof(*weights)); if (np==NULL || weights==NULL) { fprintf(stderr,"Memory allocation error!\n"); exit(1); } for (n=0; n=numfac) { npwork[dimen++]=prod; next_dimension(dimen); return; } p=powers[facno]; f=factors[facno]; for (i=0; i<=p; i++, powers[facno]--) { next_factor(facno+1,prod,dimen); prod*=f; } powers[facno]=p; return; } static void next_dimension(int dimen) { static int i, prod; static double sum; if (dimen>=ndim-1) { prod=1; for (i=0; ibest_sum) return 0; for (i=0; inp[i]) return 0; } return 0; }