"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/mpi2.c" (19 Aug 2010, 3862 Bytes) of package /linux/privat/old/NetPIPE-3.7.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mpi2.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.x_vs_3.7.2.

    1 /* Netpipe module for mpi-2 one-sided communications by Adam Oline */
    2 #define USE_VOLATILE_RPTR
    3 #include "netpipe.h"
    4 #include <mpi.h>
    5 
    6 MPI_Win win;
    7 
    8 void Init(ArgStruct *p, int* pargc, char*** pargv)
    9 {
   10   p->prot.use_get = 0;  /* Default to put   */
   11   p->prot.no_fence = 0; /* Default to fence */
   12 
   13   MPI_Init(pargc, pargv);
   14 }
   15 
   16 void Setup(ArgStruct *p)
   17 {
   18   int nprocs;
   19 
   20   MPI_Comm_rank(MPI_COMM_WORLD, &p->prot.iproc);
   21 
   22   MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
   23 
   24   if ( nprocs < 2 )
   25     {
   26       printf("Need at least 2 processes, we have %d\n", nprocs);
   27       exit(-2);
   28     }
   29 
   30   {
   31     char s[255], *ptr;
   32     gethostname(s,253);
   33     if( s[0] != '.' ) {                 /* just print the base name */
   34       ptr = strchr( s, '.');
   35       if( ptr != NULL ) *ptr = '\0';
   36     }
   37     printf("%d: %s\n",p->prot.iproc,s);
   38     fflush(stdout);
   39   }
   40 
   41   /* TODO: Finish changing netpipe such that it can run with > 2 procs */
   42   /* 0 <--> (nprocs - 1)
   43    * 1 <--> (nprocs - 2)
   44    * ...
   45    */
   46  
   47   p->tr = p->rcv = 0;
   48   if (p->prot.iproc == 0) {
   49     p->tr = 1;
   50     p->prot.nbor = nprocs-1;
   51   } else if( p->prot.iproc == nprocs-1 ) {
   52     p->rcv = 1;
   53     p->prot.nbor = 0;
   54   }
   55 }
   56 
   57 void Sync(ArgStruct *p)
   58 {
   59   MPI_Win_fence(0, win);
   60 }
   61 
   62 void PrepareToReceive(ArgStruct *p)
   63 {
   64 
   65 }
   66 
   67 void SendData(ArgStruct *p)
   68 {
   69   int buf_offset = 0;
   70 
   71   /* If we're limiting cache effects, then we need to calculate the offset
   72    * from the beginning of the memory pool
   73    */
   74   if( !p->cache )
   75     buf_offset = p->s_ptr - p->s_buff;
   76 
   77   if( p->prot.use_get )
   78     MPI_Get(p->s_ptr, p->bufflen, MPI_BYTE, p->prot.nbor, buf_offset, 
   79             p->bufflen, MPI_BYTE, win);
   80   else
   81     MPI_Put(p->s_ptr, p->bufflen, MPI_BYTE, p->prot.nbor, buf_offset, 
   82             p->bufflen, MPI_BYTE, win);
   83 
   84   if (p->prot.no_fence == 0)
   85     MPI_Win_fence(0, win);
   86 
   87 }
   88 
   89 void RecvData(ArgStruct *p)
   90 {
   91   /* If user specified 'no fence' option on cmd line, then we try to bypass
   92    * the fence call by waiting for the last byte to arrive.  The MPI-2
   93    * standard does not require any data to be written locally until a
   94    * synchronization call (such as fence) occurs, however, so this may
   95    * hang, depending on the MPI-2 implementation.  Currently works with
   96    * MP_Lite .
   97    */
   98      
   99   if( p->prot.no_fence ) {
  100     
  101     /* The conditional in the comparison below is necessary because we are
  102      * always waiting for a 'b' to arrive if in no-cache mode, but in cache
  103      * mode the character we are waiting for depends on whether we are the
  104      * transmitter or receiver.  Adding a little complexity here helps
  105      * us avoid more complexity elsewhere with regard to the no-cache code.
  106      * We cannot use the same character all the time with cache mode due
  107      * to timing issues.
  108      */
  109     while(p->r_ptr[p->bufflen-1] != 'a' + (p->cache ? 1 - p->tr : 1) )
  110       sched_yield(); /* Since we made r_ptr volatile, we don't necessarily
  111                       * need to call a function here encourage the compiler
  112                       * to reload it */
  113     
  114     p->r_ptr[p->bufflen-1] = 'a' + (p->cache ? p->tr : 0);
  115 
  116   } else {
  117 
  118     MPI_Win_fence(0, win);
  119 
  120   }
  121 
  122 }
  123 
  124 void SendTime(ArgStruct *p, double *t)
  125 {
  126   MPI_Send(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD);
  127 }
  128 
  129 void RecvTime(ArgStruct *p, double *t)
  130 {
  131   MPI_Status status;
  132   
  133   MPI_Recv(t, 1, MPI_DOUBLE, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
  134 }
  135 
  136 void SendRepeat(ArgStruct *p, int rpt)
  137 {
  138   MPI_Send(&rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD);
  139 }
  140 
  141 void RecvRepeat(ArgStruct *p, int *rpt)
  142 {
  143   MPI_Status status;
  144   
  145   MPI_Recv(rpt, 1, MPI_INT, p->prot.nbor, 2, MPI_COMM_WORLD, &status);
  146 }
  147 
  148 void CleanUp(ArgStruct *p)
  149 {
  150   MPI_Finalize();
  151 }
  152 
  153 void Reset(ArgStruct *p)
  154 {
  155 
  156 }
  157 
  158 void AfterAlignmentInit(ArgStruct *p)
  159 {
  160   /* After mallocs and alignment, we need to create MPI Window */
  161 
  162   MPI_Win_create(p->r_buff, p->bufflen, 1, NULL, MPI_COMM_WORLD, &win);
  163 }
  164