/* $Id: readtest_ng.c,v 1.7 1999/10/21 16:36:55 garner Exp $ */ /* * $Log: readtest_ng.c,v $ * Revision 1.7 1999/10/21 16:36:55 garner * readtest with IBP additions * * Revision 1.6 1999/10/15 15:10:39 garner * Working version without IBP yet. Multi-MPI apps work. * * Revision 1.5 1999/10/06 21:50:50 garner * Working with new server * * Revision 1.4 1999/10/04 18:02:33 garner * *** empty log message *** * */ #include "mpi.h" #include "mpio.h" /* not necessary with MPICH 1.1.1 or HPMPI 1.4 */ #include "client_lib.h" #include #include #include #include #include /* Each process writes to separate files and reads them back. The file name is taken as a command-line argument, and the process rank is appended to it. */ char errbuf[MPI_MAX_ERROR_STRING]; /* * MPIO_Type_set_bounds surround a type with holes (increasing the extent) */ int MPIO_Type_set_bounds( int displacement, /* Displacement from the lower bound */ int ub, /* Set the upper bound */ MPI_Datatype oldtype, /* Old datatype */ MPI_Datatype *newtype) /* New datatype */ { int blocklength[3]; MPI_Datatype type[3]; MPI_Aint disp[3]; blocklength[0] = 1; disp[0] = 0; type[0] = MPI_LB; blocklength[1] = 1; disp[1] = displacement; type[1] = oldtype; blocklength[2] = 1; disp[2] = ub; type[2] = MPI_UB; /* * newtype = * -- (LB, 0), (oldtype, displacement), (UB, ub) */ return MPI_Type_struct(3, blocklength, disp, type, newtype); } /* * MPIO_Type_scatter_gather generate scatter/gather datatype to access data * block in rank order. Blocks are identical in size * and datatype. */ int MPIO_Type_scatter_gather( MPI_Comm comm, /* Communicator group */ MPI_Datatype oldtype, /* Block datatype */ MPI_Datatype *newtype) /* New datatype */ { int size, rank; int extent; MPI_Type_extent(oldtype,&extent); MPI_Comm_size(comm, &size); MPI_Comm_rank(comm, &rank); return MPIO_Type_set_bounds(rank*extent, size*extent, oldtype, newtype); } int main(int argc, char **argv) { int i, rank, ndoubles, len, locallen, flag, numelements; int myappnum, totalapps, localTMPlen, groupsize; double min, max, sum, avg, avgsum; double *minAll, *maxAll, *sumAll, *avgAll; int *numelementsAll, totalElements; int errlen, ierr; MPI_Offset numbytes; char *globalfn, *localfn, *localfnTMP, *tmp; double *buf; MPI_File fh; MPI_Status status; MPI_Datatype filetype; struct stat sbuf; int cc, fsize; MPI_Offset size; char fname[256]; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &groupsize); min = max = sum = avg = 0.0; buf = (double *) malloc(sizeof(double)); /* process 0 takes the file name as a command-line argument and broadcasts it to other processes */ if (argc < 5) { printf("\n*# Usage: readtest_ng globalfn localfn myAppNum totalApps\n\n"); MPI_Abort(MPI_COMM_WORLD, 1); } else { myappnum = atoi(argv[3]); totalapps = atoi(argv[4]); /* Get filename from argv */ len = strlen(argv[1]); globalfn = (char *) malloc(len+10); strcpy(globalfn, argv[1]); locallen = strlen(argv[2]); localfn = (char *) malloc(locallen+10); strcpy(localfn, argv[2]); tmp = (char *) malloc(len+10); strcpy(tmp, localfn); sprintf(localfn, "%s.%d", tmp, myappnum); locallen = strlen(localfn); localTMPlen = locallen; localfnTMP = (char *) malloc(localTMPlen+10); /* strcpy(localfnTMP, localfn); */ sprintf(localfnTMP, "/tmp/%s", localfn); localTMPlen = strlen(localfnTMP); } printf("\nmyrank: %d gfn: %s lfn: %s myapp: %d apps: %d\n", rank, globalfn, localfnTMP, myappnum, totalapps); MPI_Conn_getfile_view(globalfn, localfn, myappnum, totalapps, MPI_DOUBLE, &fsize, MPI_COMM_WORLD); /* open the file and read the data in */ printf("Opening file = %s with size %d \n", localfnTMP, fsize); ierr = MPI_File_open(MPI_COMM_WORLD, localfnTMP, MPI_MODE_RDWR, MPI_INFO_NULL, &fh); if (ierr != MPI_SUCCESS){ printf("Error in MPI_File_open = %d rank = %d\n", ierr, rank); MPI_Error_string(ierr, errbuf, &errlen); printf("%s\n", errbuf); MPI_Abort(MPI_COMM_WORLD, 1); } else { printf("File %s successfully opened by %d\n", localfnTMP, rank); } MPI_File_get_size(fh, &size); printf("file size = %lld bytes\n", size); MPIO_Type_scatter_gather(MPI_COMM_WORLD, MPI_DOUBLE, &filetype); ierr = MPI_File_set_view(fh, 0, MPI_DOUBLE, filetype, "native", MPI_INFO_NULL); if (ierr != MPI_SUCCESS){ printf("Error in MPI_File_set_view = %d rank = %d\n", ierr, rank); MPI_Error_string(ierr, errbuf, &errlen); printf("%s\n", errbuf); } MPI_Barrier(MPI_COMM_WORLD); buf = (double *)malloc(fsize); numelements = (fsize / sizeof(double))/groupsize; MPI_File_read_all(fh, buf, numelements, MPI_DOUBLE, &status); min = buf[0]; max = buf[0]; for (i = 0; i < numelements; i++) { if ( min > buf[i]) min = buf[i]; if ( max < buf[i]) max = buf[i]; sum += buf[i]; } avg = sum / numelements; printf("--- Sub-rank: %d Min: %f Max: %f Sum: %f Avg: %f\n", rank, min, max, sum, avg); if (rank == 0) { minAll = (double *)malloc(groupsize * sizeof(double)); maxAll = (double *)malloc(groupsize * sizeof(double)); sumAll = (double *)malloc(groupsize * sizeof(double)); avgAll = (double *)malloc(groupsize * sizeof(double)); numelementsAll = (int *)malloc(groupsize * sizeof(int)); } MPI_Gather(&min, 1, MPI_DOUBLE, minAll, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Gather(&max, 1, MPI_DOUBLE, maxAll, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Gather(&sum, 1, MPI_DOUBLE, sumAll, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Gather(&avg, 1, MPI_DOUBLE, avgAll, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD); MPI_Gather(&numelements, 1, MPI_INT, numelementsAll, 1, MPI_INT, 0, MPI_COMM_WORLD); sum = 0; avg = 0; avgsum = 0; totalElements = 0; if (rank == 0) { min = minAll[0]; max = maxAll[0]; for (i = 0; i < groupsize; i++) { if ( min > minAll[i]) min = minAll[i]; if ( max < maxAll[i]) max = maxAll[i]; sum += sumAll[i]; avgsum += avgAll[i] * numelementsAll[i]; totalElements += numelementsAll[i]; } avg = avgsum / totalElements; printf("\n--- Rank: %d Min: %f Max: %f Sum: %f Avg: %f\n", rank, min, max, sum, avg); } MPI_File_close(&fh); if (!rank) { /* Root do cleanup here */ printf("Done\n"); } MPI_Finalize(); return 0; }