/* parallelpascalstriangle.c */ /* © Copyright 2003 Dauger Research, Inc. Our lawyers made us say this: DISCLAIMER: We provide the following on an "AS IS" basis. Use it at your own risk. */ #include /* standard I/O routines */ #include /* standard library routines, such as memory */ #include /* math libraries */ #include "mpi.h" /* MPI library */ #define myType unsigned long /* Routines performing elemental work. */ void addright(myType *inputArray, long size); void addright(myType *inputArray, long size) { if (inputArray) { long i=size-1; while (i--) inputArray[i+1]+=inputArray[i]; } } void addleft(myType *inputArray, long size); void addleft(myType *inputArray, long size) { if (inputArray) { long i; for(i=0; i0) { long index; long leftIDProc=idproc-1, rightIDProc=idproc+1; MPI_Request request; MPI_Status status; /* get to know my (processor's) neighbors */ if (leftIDProc<0) leftIDProc=nproc-1; if (rightIDProc>=nproc) rightIDProc=0; /* loop over indicies */ for(index=0; index>1)/(arraySize-1))) myArray[(binomialExponent>>1)-idproc*(arraySize-1)]=1; /* propagate */ iterationloop(myArray, arraySize, binomialExponent, 2, idproc, nproc); /* proc 0's has a bigger array so we can gather all the data at the end */ {myType *bigArray=idproc?NULL:malloc(sizeof(myType)*(binomialExponent+nproc)); /* gathers the data from the other arrays ... */ MPI_Gather(myArray, arraySize-1, MPI_LONG, bigArray, arraySize-1, MPI_LONG, /* ... to proc 0 */ 0, MPI_COMM_WORLD); if (!idproc) { free(myArray); myArray=bigArray; } } } /* return the array */ *theArray=myArray; } int ppinit(int argc, char *argv[], int *idproc, int *nproc); void ppexit(void); /* BinomialExponent specifies how far to propagate */ #define BinomialExponent 30L int main(int argc, char *argv[]) { /* main copies of the sum and the array */ myType *theArray=NULL; int idproc, nproc, ierr; /* initialize parallel processing */ ierr = ppinit(argc, argv, &idproc, &nproc); if (ierr) return ierr; /* stop right there if there's a problem */ printf("I'm processor #%d in a %d-processor cluster.\n", idproc, nproc); printf("Beginning computation...\n"); computeloop(&theArray, BinomialExponent, idproc, nproc); if (theArray) {/* error checking */ if (!idproc) {/* only processor 0 */ FILE *fp; /* save the array into a data file */ fp=fopen("output", "w"); if (fp) { printf("writing array...\n"); fwrite(theArray, sizeof(myType), BinomialExponent+1, fp); fclose(fp); } } if (1) {long i; for(i=0; i #endif int ppinit(int argc, char *argv[], int *idproc, int *nproc) { /* this subroutine initializes parallel processing idproc = processor id nproc = number of real or virtual processors obtained */ int ierr; *nproc=0; /* initialize the MPI execution environment */ ierr = MPI_Init(&argc, &argv); if (!ierr) { /* determine the rank of the calling process in the communicator */ ierr = MPI_Comm_rank(MPI_COMM_WORLD, idproc); /* determine the size of the group associated with a communicator */ ierr = MPI_Comm_size(MPI_COMM_WORLD, nproc); #ifdef __MWERKS__ /* only for Metrowerks CodeWarrior */ SIOUXSettings.asktosaveonclose=0; SIOUXSettings.autocloseonquit=1; #endif } return ierr; } void ppexit(void) { /* this subroutine terminates parallel processing */ int ierr; /* waits until everybody gets here */ ierr = MPI_Barrier(MPI_COMM_WORLD); /* terminate MPI execution environment */ ierr = MPI_Finalize(); }