#include "mpi.h" #include #include #define NSIZE 1000000 /* size of array */ /* * To run this test program using the lock/unlock protocol, comment out both * defines for USE_MPI_REQUESTS and USE_MPI_FLUSH_LOCAL * * To run this test program using the request-based protocol with Rput, Rget, * uncomment the definition USE_MPI_REQUESTS and comment out the definition * USE_MPI_FLUSH_LOCAL * * To run this test program using the flush_local protocol, uncomment the * definitions for both USE_MPI_FLUSH_LOCAL and USE_MPI_REQUESTS * * The program can be converted to use MPI_Datatypes that are set up using * the command MPI_Type_create_subarray by commenting out the definition * USE_STRUCTS */ /* #define USE_MPI_REQUESTS #define USE_MPI_FLUSH_LOCAL */ #ifdef USE_MPI_FLUSH_LOCAL #define USE_MPI_REQUESTS #endif /* * To run this program using the MPI_Type_create_subarray instead of the * MPI_Type_create_struct routine, comment out the USE_STRUCTS definition */ #define USE_STRUCTS void do_work(MPI_Comm comm, int offset) { int one = 1; int me, nproc, wme; int i, j, iproc; int dims = NSIZE; int lo, hi, mysize; int nval, icnt, jcnt; int *values; int **index; int *ival; int sok, ok; int *local_buf; MPI_Win win; MPI_Comm_size(comm, &nproc); MPI_Comm_rank(comm, &me); MPI_Comm_rank(MPI_COMM_WORLD, &wme); /* Print out which protocol is being used */ if (me==0) { printf("\nRunning test on %d processors\n",nproc); #ifdef USE_MPI_REQUESTS #ifdef USE_MPI_FLUSH_LOCAL printf("\nUsing flush local protocol\n"); #else printf("\nUsing request-based protocol\n"); #endif #else printf("\nUsing lock/unlock protocol\n"); #endif #ifdef USE_STRUCTS printf("\nBuilding data types using stuct command\n"); #else printf("\nBuilding data types using subarray command\n"); #endif } /* this processor will assign every nproc'th value starting at me */ nval = (dims-1-me)/nproc+1; values = (int*)malloc(nval*sizeof(int)); ival = (int*)malloc(nval*sizeof(int)); icnt=0; for (i=me; i= dims) icnt = me; /* create src data type */ MPI_Type_create_struct(jcnt,blocklengths,src_displacements,types,&src_type); /* create destination data type */ MPI_Type_create_struct(jcnt,blocklengths,dst_displacements,types,&dst_type); free(blocklengths); free(dst_displacements); free(types); #else while (icnt <= hi) { /* evaluate value and global index for value in global array */ values[jcnt] = icnt + offset; /* convert global index to displacement */ jcnt++; icnt += nproc; } if (icnt >= dims) icnt = me; /* create src_data type */ array_of_sizes[0] = 1; array_of_sizes[1] = jcnt; array_of_subsizes[0] = 1; array_of_subsizes[1] = jcnt; array_of_starts[0] = 0; array_of_starts[1] = 0; base_type = MPI_INT; MPI_Type_create_subarray(two, array_of_sizes,array_of_subsizes, array_of_starts,MPI_ORDER_FORTRAN,base_type,&src_type); /* create dst_data type */ array_of_sizes[0] = nproc; array_of_sizes[1] = jcnt; array_of_subsizes[0] = 1; array_of_subsizes[1] = jcnt; array_of_starts[0] = (isave-lo)%nproc; array_of_starts[1] = 0; MPI_Type_create_subarray(two, array_of_sizes,array_of_subsizes, array_of_starts,MPI_ORDER_FORTRAN,base_type,&dst_type); #endif /* commit data types and put data on remote processor */ MPI_Type_commit(&src_type); MPI_Type_commit(&dst_type); #ifdef USE_MPI_REQUESTS #ifdef USE_MPI_FLUSH_LOCAL MPI_Put(values, 1, src_type, iproc, 0, 1, dst_type, win); MPI_Win_flush_local(iproc, win); #else MPI_Rput(values, 1, src_type, iproc, 0, 1, dst_type, win, &request); MPI_Wait(&request, &status); #endif #else MPI_Win_lock(MPI_LOCK_SHARED,iproc,0,win); MPI_Put(values, 1, src_type, iproc, 0, 1, dst_type, win); MPI_Win_unlock(iproc,win); #endif MPI_Type_free(&src_type); MPI_Type_free(&dst_type); } if (me==0) printf("\nCompleted scatter operation\n"); /* synchronize communication across all processors */ #ifdef USE_MPI_REQUESTS MPI_Win_flush_all(win); #else MPI_Win_fence(0,win); #endif MPI_Barrier(comm); /* print values in distributed array */ /* for (i=0; i= dims) icnt = (me+1)%nproc; /* create src data type */ MPI_Type_create_struct(jcnt,blocklengths,src_displacements,types,&src_type); /* create destination data type */ MPI_Type_create_struct(jcnt,blocklengths,dst_displacements,types,&dst_type); free(blocklengths); free(dst_displacements); free(src_displacements); free(types); #else while (icnt <= hi) { /* evaluate value and global index for value in global array */ /* convert global index to displacement */ jcnt++; icnt += nproc; } if (icnt >= dims) icnt = (me+1)%nproc; /* create src_data type */ array_of_sizes[0] = nproc; array_of_sizes[1] = jcnt; array_of_subsizes[0] = 1; array_of_subsizes[1] = jcnt; array_of_starts[0] = (isave-lo)%nproc; array_of_starts[1] = 0; base_type = MPI_INT; MPI_Type_create_subarray(two, array_of_sizes,array_of_subsizes, array_of_starts,MPI_ORDER_FORTRAN,base_type,&src_type); /* create dst_data type */ array_of_sizes[0] = 1; array_of_sizes[1] = nval; array_of_subsizes[0] = 1; array_of_subsizes[1] = jcnt; array_of_starts[0] = 0; array_of_starts[1] = jlo; MPI_Type_create_subarray(two, array_of_sizes,array_of_subsizes, array_of_starts,MPI_ORDER_FORTRAN,base_type,&dst_type); #endif /* commit data types and put data on remote processor */ MPI_Type_commit(&src_type); MPI_Type_commit(&dst_type); #ifdef USE_MPI_REQUESTS #ifdef USE_MPI_FLUSH_LOCAL MPI_Get(values, 1, dst_type, iproc, 0, 1, src_type, win); MPI_Win_flush_local(iproc, win); #else MPI_Rget(values, 1, dst_type, iproc, 0, 1, src_type, win, &request); MPI_Wait(&request, &status); #endif #else MPI_Win_lock(MPI_LOCK_SHARED,iproc,0,win); MPI_Get(values, 1, dst_type, iproc, 0, 1, src_type, win); MPI_Win_unlock(iproc,win); #endif MPI_Type_free(&src_type); MPI_Type_free(&dst_type); } if (me==0) printf("\nCompleted gather operation\n"); /* for (i=0; i= nproc) hi = nproc-1; group_size = hi - lo + 1; printf("p[%d] group_size: %d lo: %d hi: %d\n",me,group_size,lo,hi); ranks = (int*)malloc(sizeof(int)*group_size); for (i=0; i