/*******************************************************************/ /* 25/09/2004 - Gerard Torrent - gerard@fobos.generacio.com */ /* initial release */ /* 04/10/2004 - Gerard Torrent - gerard@fobos.generacio.com */ /* simplified struct chunk (added status/numops) */ /* send/receive type MPI_LONG's, not structs */ /* added compile directive -O3 (optimize speed) */ /* */ /* Description: Perform cluster megaflops measurement */ /* */ /* Note1: Master node don't work (no FOPS). If you need compute */ /* the real megaflops of cluster, add 1 cpu to master */ /* machine in lam-bhost.def file. */ /* */ /* Note2: compile using -> mpicc -O3 -o mflops mflops.c */ /* run it using -> mpirun C mflops */ /* */ /*******************************************************************/ /* =============================================================== */ /* headers */ /* =============================================================== */ #include #include #include #include #include /* =============================================================== */ /* defines */ /* =============================================================== */ #define WORKTAG 1 #define DIETAG 2 #define MAX_TASKS 10000L #define DEFAULT_NUMOPS 1000000L /* =============================================================== */ /* structs definitions */ /* =============================================================== */ struct chunk { int status; /* WORKTAG=working, DIETAG=finish */ long numchunks; /* number of chuncks procesed */ double t_numops; /* total numops realized */ double t_microseconds; /* total microseconds elapsed */ }; /* =============================================================== */ /* function definitions */ /* =============================================================== */ static int master(void); static int slave(void); static long getElapsedTime(struct timeval *tv0, struct timeval *tv1); static struct chunk * initializeTasks(int n); static int saveChunk(long nummicroseconds, struct chunk *chunklist, int lastpos) ; static int isTasksCompleted(struct chunk *chunklist, int lastpos); static void showReport(struct chunk *chunklist, int size); /* =============================================================== */ /* main function */ /* =============================================================== */ int main(int argc, char* argv[]) { int ret, size, rank, child; /* Initialize MPI */ MPI_Init(&argc, &argv); /* Determine rank process */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* bifurcation flow */ if (rank == 0) { ret = master(); } else { ret = slave(); } /* finalize and exit */ MPI_Finalize(); return(ret); } /* =============================================================== */ /* master function */ /* =============================================================== */ static int master(void) { int i, size; MPI_Status status; struct chunk *tasks; int numtasks=0; int completed = 0; long numops=DEFAULT_NUMOPS, nummicroseconds; /* Determine the number of processes */ MPI_Comm_size(MPI_COMM_WORLD, &size); /* tasks initialization */ tasks = initializeTasks(size); /* initial work dispatching */ for (i=1;i= MAX_TASKS) { tasks[status.MPI_SOURCE].status = DIETAG; MPI_Send(0, 0, MPI_INT, status.MPI_SOURCE, DIETAG, MPI_COMM_WORLD); if (isTasksCompleted(tasks, size)) { completed = 1; } } else { MPI_Send(&numops, 1, MPI_LONG, status.MPI_SOURCE, WORKTAG, MPI_COMM_WORLD); numtasks++; } } /* megaflops report */ showReport(tasks, size); /* memory management */ free(tasks); } /* =============================================================== */ /* slave function */ /* =============================================================== */ static int slave(void) { MPI_Status status; struct timeval tv0, tv1; struct timezone tz0, tz1; long numops, nummicroseconds, counter; double val=2.0, M_PI=3.14159265358979323846; /* awaiting begining order */ MPI_Recv(&numops, 1, MPI_LONG, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); /* slave loop. Make FOPS and send results to master */ while(status.MPI_TAG == WORKTAG) { /* setting start time */ if (gettimeofday(&tv0, &tz0) != 0) { MPI_Finalize(); return(1); } /* numops FLoating OPerationS computation */ for (counter=0; countertv_sec - tv0->tv_sec) * 1000000L; ret += tv1->tv_usec - tv0->tv_usec; return ret; } /* =============================================================== */ /* initializeTasks */ /* =============================================================== */ struct chunk * initializeTasks(int n) { struct chunk *tasks; int i; tasks = (struct chunk *) calloc(n, sizeof(struct chunk)); for (i=0;i