#include #include #include "usempi.h" #define MS_PRINT 0 /* flag to print out debugging information to file */ /* Each process gets a unique file */ #ifdef _CRAY /* this is for the mallopt() command below */ #include #endif #define OFFSET 2 /* offset for tags number for normal tasks */ /* 0 quit 1 run mapcouplings */ /* This subroutine initializes the data structures and communication groups used by mpi */ void init_mpi_types(void){ int i; #define SPECIFY_SIZE 11 int len[SPECIFY_SIZE]; MPI_Datatype type[SPECIFY_SIZE]; specify_calculation mx; MPI_Aint disp[SPECIFY_SIZE],base; #if 0 MPI_Group g1,g2; int master[1]={0}; #endif /* make MPI datatype for the structure specify_calculation */ MPI_Address(&mx.type,disp); len[0]=1; type[0]=MPI_INT; MPI_Address(&mx.ht,disp+1); len[1]=HINDEX; type[1]=MPI_INT; MPI_Address(&mx.nptrunc,disp+2); len[2]=1; type[2]=MPI_INT; MPI_Address(&mx.kt,disp+3); len[3]=1; type[3]=MPI_UNSIGNED; MPI_Address(&mx.charge,disp+4); len[4]=1; type[4]=MPI_INT; MPI_Address(&mx.o,disp+5); len[5]=1; type[5]=MPI_INT; MPI_Address(&mx.multi,disp+6); len[6]=1; type[6]=MPI_INT; MPI_Address(&mx.momflag,disp+7); len[7]=1; type[7]=MPI_INTEGER; MPI_Address(&mx.angle,disp+8); len[8]=HINDEX+2; type[8]=MPI_DOUBLE; MPI_Address(&mx.nval,disp+9); len[9]=1; type[9]=MPI_INTEGER; MPI_Address(&mx.vectorflag,disp+10); len[10]=1; type[10]=MPI_INTEGER; /* we find offsets relative to the "base" of the structure, wherever that may be (thus we make no assumptions of order. */ MPI_Address(&mx,&base); for(i=0; i0 /* Initialize the communicator mpiallslaves which is a subgroup consisting of just the slaves. This is used in file "improved.c" */ MPI_Comm_group(MPI_COMM_WORLD,&g1); MPI_Group_excl(g1,1,master,&g2); MPI_Comm_create(MPI_COMM_WORLD,g2,&mpiallslaves); MPI_Group_free(&g1); MPI_Group_free(&g2); #endif } /* This is the slave process used by MPI it is a "stand-alone" subroutine to calculate the lowest eigenvalues for a given basis. It also calculates the basis when necessary. angle contains HINDEX components of transverse momentum, the kmax cutoff for nonzero L and L itself. */ #define MAXBASIS 150 void slave(void){ specify_calculation a; full_basis basis; eigensystem eigen=INITIAL_EIGENSYSTEM; int myrank; element couplings[NPARAMS]; size_mem global_reduced_memory; size_mem global_els_memory; #if MS_PRINT FILE *fp; char out[10]; int i,j; #endif MPI_Status status; MPI_Comm_rank(MPI_COMM_WORLD,&myrank); #if MS_PRINT /* open debugging file with name based on rank */ sprintf(out,"p%i.tmp",myrank); if((fp = fopen(out,"w")) == NULL){ fprintf(stderr,__FILE__": Can't open file %s in usempi.c, exiting\n",out); goto error; } #endif /* on CRAY, be more carefull about memory management. */ #ifdef _CRAY mallopt(M_LOWFIT,1); #endif /* Main loop of program */ for(;;){ MPI_Probe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status); /* Stop program */ if(status.MPI_TAG==0)goto exit; /* Receive coupling constants. */ else if(status.MPI_TAG==1) MPI_Recv(couplings,NPARAMS,MPI_DOUBLE,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status); /* Calculate spectrum */ else { #if MS_PRINT /* diagnostic print to debugging file*/ fprintf(fp,"About to receive Job %i\n",status.MPI_TAG-OFFSET); fflush(fp); #endif MPI_Recv(&a,1,mpi_specify_calculation,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status); #if MS_PRINT /* diagnostic print to debugging file */ fprintf(fp,"Received job %i, nvals=%i\n", status.MPI_TAG-OFFSET,nvals); fprintf(fp," ht=("); for(i=0; i=njob){ fprintf(stderr,__FILE__": Master receiving tag=%i from slave %i, exiting\n", status.MPI_TAG,status.MPI_SOURCE); #if MS_PRINT /* debugging file with name based on rank */ fclose(fp); #endif return 1; } MPI_Recv(vals+whichvals[j],nvals[j], MPI_DOUBLE,MPI_ANY_SOURCE, MPI_ANY_TAG,MPI_COMM_WORLD,&status2); if(base[j].vectorflag){ fprintf(stderr,__FILE__": master(...) not ready to receive vectors!\n"); return 1; } #if 0 /* debugging print: print jobs received */ if(status.MPI_TAG<10){ printf("Master receiving job %i from slave %i offset %i;\n ", status.MPI_TAG,status.MPI_SOURCE,whichvals[status.MPI_TAG]); for(i=0; iht[i]); fprintf(fp,"), np=%i kt=%i cyclic=%i o=%i and multi=%i,\n", base[job][k]->npmax,base[job][k]->kt,base[job][k]->cyclic, base[job][k]->o,base[job][k]->multi); } fprintf(fp," angle="); for(i=0; i