"Fossies" - the Fresh Open Source Software Archive

Member "NetPIPE-3.7.2/src/armci.c" (19 Aug 2010, 7590 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 "armci.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 /*  This module is basically the rewritten ARMCI module written by Xuehua
    2 */
    3 #include <stdio.h>
    4 #include <netinet/in.h>
    5 #include <netdb.h>
    6 
    7 #include <mpi.h>
    8 #include "armci.h"
    9 #define USE_VOLATILE_RPTR /* need for polling on receive buffer */
   10 #include "netpipe.h"
   11 
   12 extern double *pTime;
   13 extern int    *pNrepeat;
   14 
   15 
   16 int npes, mype;
   17 int nbor_r_buff_offset;
   18 
   19 struct mnode_t {
   20     void *ptrs[2];   /* Will only use 2 pointers */
   21     int nbytes;
   22     struct mnode_t* next;
   23 };
   24 
   25 /* Pointers to first element of the linked list */
   26 struct mnode_t *m_first = 0;
   27 
   28 
   29 void mlink_front(struct mnode_t* node) {
   30     if (m_first != 0) node->next = m_first;
   31     else node->next = 0;
   32     m_first = node;
   33 }
   34 
   35 
   36 struct mnode_t *mfind(void* ptr, struct mnode_t** prev) {
   37     struct mnode_t *p, *n;
   38 
   39     if (m_first != 0) {
   40         if (m_first->ptrs[mype] != ptr) {
   41             for (p=m_first, n=p->next; n != 0; p=n, n=n->next) {
   42                 if (n->ptrs[mype] == ptr) {
   43                    *prev = p;
   44                    return n;
   45                 }
   46             }
   47         }
   48         else {
   49             *prev = 0;
   50             return m_first;
   51         }
   52     }
   53     else {
   54         *prev = 0;
   55         return 0;
   56     }
   57     
   58     ARMCI_Error("Cannot find pointer in linked list", -1);
   59     
   60 }
   61 
   62 
   63 void* munlink(struct mnode_t *node, struct mnode_t *prev) {
   64 
   65     if (node != 0) {
   66         if (prev != 0) prev->next = node->next;
   67         else m_first = node->next;
   68     }
   69 
   70     return node;
   71 }
   72 
   73 
   74 
   75 void* armci_malloc(int nbytes) {
   76     struct mnode_t *node = malloc(sizeof(struct mnode_t));
   77 
   78     if (node == 0) {
   79         ARMCI_Error("Cannot allocate memory", -1);
   80     }
   81 
   82     ARMCI_Malloc(node->ptrs, nbytes);
   83 
   84     node->nbytes = nbytes;
   85     mlink_front(node);
   86 
   87     return node->ptrs[mype];
   88 }
   89 
   90 
   91 void armci_free(void* ptr) {
   92     struct mnode_t *n, *p;
   93 
   94     n = mfind(ptr, &p);
   95     if (n != 0) munlink(n, p);
   96 
   97     /* XXX if n = 0, then we have a problem */
   98 
   99     ARMCI_Free(ptr);
  100 }
  101 
  102 
  103 void* remote_ptr(void* local) {
  104     struct mnode_t *n, *p;
  105 
  106     n = mfind(local, &p);  /* ignore p */
  107     if (n != 0) {
  108         return n->ptrs[1-mype];
  109     }
  110     else {
  111         return 0;
  112     }
  113 }
  114 
  115 /* aro */
  116 int is_host_local(char* hostname)
  117 {
  118   struct hostent* hostinfo;
  119   char* addr;
  120   char buf[1024];
  121   char cmd[80];
  122   FILE* output;
  123 
  124   hostinfo = gethostbyname(hostname);
  125 
  126   if(hostinfo == NULL) {
  127     fprintf(stderr, "Could not resolve hostname [%s] to IP address", hostname);
  128     fprintf(stderr, "Reason: ");
  129 
  130     switch(h_errno)
  131       {
  132       case HOST_NOT_FOUND:
  133         printf("host not found\n");
  134         break;
  135 
  136       case NO_ADDRESS:
  137         printf("no IP address available\n");
  138         break;
  139 
  140       case NO_RECOVERY:
  141         printf("name server error\n");
  142         break;
  143 
  144       case TRY_AGAIN:
  145         printf("temporary error on name server, try again later\n");
  146         break;
  147 
  148       }
  149 
  150     return -1;
  151   }
  152 
  153   addr = (char*)inet_ntoa(*(struct in_addr *)hostinfo->h_addr_list[0]);
  154 
  155   sprintf(cmd, "/sbin/ifconfig | grep %s", addr);
  156 
  157   output = popen(cmd, "r");
  158    
  159   if(output == NULL) {
  160     fprintf(stderr, "running /sbin/ifconfig failed\n");
  161     return -1;
  162   }
  163   
  164   if(fgets(buf, 1024, output) == NULL) {
  165     pclose(output);
  166     return 0;
  167   } else {
  168     pclose(output);
  169     return 1;
  170   } 
  171 }
  172 
  173 void chop(char* s)
  174 {
  175   int i;
  176   for(i=0; s[i]!='\0'; s++)
  177     if(s[i]=='\n')
  178       s[i]='\0';
  179     
  180 }
  181 
  182 void set_armci_hostname()
  183 {
  184   char buf[1024];
  185   FILE* hostfile = fopen("armci_hosts", "r");
  186 
  187   if(hostfile == NULL)
  188     return;
  189 
  190   while(fgets(buf, 1024, hostfile) != NULL) {
  191     chop(buf);/* remove trailing newline */
  192     if(is_host_local(buf)==1) {
  193       fprintf(stderr,"Setting ARMCI_HOSTNAME=%s\n", buf);
  194       if(setenv("ARMCI_HOSTNAME", buf, 1)==-1)
  195       fprintf(stderr, "Insufficient space in environment\n");
  196     }
  197   }
  198 
  199   fclose(hostfile);
  200 
  201 }
  202 
  203 void Init(ArgStruct *p, int* pargc, char*** pargv)
  204 {
  205     MPI_Init(pargc, pargv);
  206 }
  207 
  208 void Setup(ArgStruct *p) {
  209     int e;
  210 
  211     set_armci_hostname(); /* aro */
  212     ARMCI_Init(); /* aro */
  213 
  214     e = MPI_Comm_size(MPI_COMM_WORLD, &npes);
  215     if (e != MPI_SUCCESS) {
  216         ARMCI_Error("Cannot obtain number of PEs", e);
  217     }
  218     else if (npes != 2) {
  219         ARMCI_Error("This program must be run on 2 PEs", -1);
  220     }
  221 
  222     e = MPI_Comm_rank(MPI_COMM_WORLD, &mype);
  223     if (e != MPI_SUCCESS) {
  224         ARMCI_Error("Cannot obtain PE rank", e);
  225     }
  226 
  227     if (npes != 2) {
  228         ARMCI_Error("You must run on 2 nodes", -1);
  229         /* ARMCI_Error terminates everything */
  230     }
  231 
  232     p->prot.flag = armci_malloc(sizeof(int));
  233     pTime = armci_malloc(sizeof(double));
  234     pNrepeat = armci_malloc(sizeof(int));
  235 
  236     p->tr = p->rcv = 0;
  237     if ((p->prot.ipe = mype) == 0) {
  238         p->tr = 1;
  239         p->prot.nbor = 1;
  240         *p->prot.flag = 1;
  241     }
  242     else {
  243         p->rcv = 1;
  244         p->prot.nbor = 0;
  245         *p->prot.flag = 0;
  246     }
  247 }
  248 
  249 
  250 void Sync(ArgStruct *p) {
  251     MPI_Barrier(MPI_COMM_WORLD);
  252 }
  253 
  254 
  255 void PrepareToReceive(ArgStruct *p) {
  256 }
  257 
  258 
  259 void SendData(ArgStruct *p) {
  260     int p_bytes;
  261     void *remote_buff;
  262     int buf_offset=0;
  263 
  264     p_bytes = p->bufflen;
  265 
  266     buf_offset  = nbor_r_buff_offset;
  267     buf_offset += p->s_ptr - p->s_buff;
  268     remote_buff = remote_ptr(p->r_buff_orig) + buf_offset;
  269 
  270     ARMCI_Put(p->s_ptr, remote_buff, p_bytes, p->prot.nbor);
  271     ARMCI_AllFence();  /* may be necessary or not */
  272 }
  273 
  274 
  275 void RecvData(ArgStruct *p) {
  276 
  277     while (p->r_ptr[p->bufflen-1] != 'a' + (p->cache ? 1 - p->tr : 1)) 
  278     {
  279        /* BUSY WAIT */
  280     }
  281 
  282     p->r_ptr[p->bufflen-1] = 'a' + (p->cache ? p->tr : 0);
  283 }
  284 
  285 
  286 void SendTime(ArgStruct *p, double *t) {
  287     int p_bytes;
  288     void *remote_buff;
  289 
  290     *pTime = *t;
  291     
  292     p_bytes = sizeof(double);
  293     remote_buff = remote_ptr(pTime);
  294     ARMCI_Put(pTime, remote_buff, p_bytes, p->prot.nbor);
  295 
  296     p_bytes = sizeof(int);
  297     remote_buff = remote_ptr((void*)p->prot.flag);
  298     ARMCI_Put((void*)p->prot.flag, remote_buff, p_bytes, p->prot.nbor);
  299 }
  300 
  301 
  302 void RecvTime(ArgStruct *p, double *t) {
  303 
  304     while (*p->prot.flag != p->prot.ipe) 
  305     {
  306        /* BUSY WAIT */   
  307     }
  308 
  309     *t = *pTime; 
  310     *p->prot.flag = p->prot.nbor;
  311 }
  312 
  313 
  314 void SendRepeat(ArgStruct *p, int rpt) {
  315     void *remote_buff;
  316     int p_bytes;
  317 
  318     *pNrepeat = rpt;
  319 
  320     p_bytes = sizeof(int);
  321     remote_buff = remote_ptr(pNrepeat);
  322     ARMCI_Put(pNrepeat, remote_buff, p_bytes, p->prot.nbor);
  323 
  324     p_bytes = sizeof(int);
  325     remote_buff = remote_ptr((void*)p->prot.flag);
  326     ARMCI_Put((void*)p->prot.flag, remote_buff, p_bytes, p->prot.nbor);
  327 
  328 }
  329 
  330 
  331 void RecvRepeat(ArgStruct *p, int *rpt) {
  332     void *remote_buff;
  333 
  334     while (*p->prot.flag != p->prot.ipe)
  335     {
  336        /* BUSY WAIT */
  337     }
  338     
  339     *rpt = *pNrepeat;
  340     *p->prot.flag = p->prot.nbor;
  341 }
  342 
  343 
  344 void  CleanUp(ArgStruct *p) {
  345     ARMCI_Finalize();
  346 
  347 }
  348 
  349 
  350 
  351 void Reset(ArgStruct *p)
  352 {
  353 
  354 }
  355 
  356 void AfterAlignmentInit(ArgStruct *p)
  357 {
  358   MPI_Status s;
  359 
  360   /* Calculate difference between malloc'ed buffer and aligned buffer */
  361 
  362   int my_r_buff_offset = p->r_buff - p->r_buff_orig;
  363 
  364   /* Exchange offset data */
  365 
  366   MPI_Send(&my_r_buff_offset, 1, MPI_INT, p->prot.nbor, 0, MPI_COMM_WORLD);
  367 
  368   MPI_Recv(&nbor_r_buff_offset, 1, MPI_INT, p->prot.nbor,0,MPI_COMM_WORLD, &s);
  369   
  370 }
  371 
  372 void MyMalloc(ArgStruct *p, int bufflen, int soffset, int roffset)
  373 {
  374 
  375 /* the MAX() is easier than another if clause and the offsets should be
  376    small enough for this to never matter */
  377 
  378     p->r_buff = armci_malloc(bufflen+MAX(soffset,roffset));
  379 
  380     if(!p->cache)
  381       p->s_buff = armci_malloc(bufflen+soffset);
  382 
  383 }
  384 void FreeBuff(char *buff1, char* buff2)
  385 {
  386 
  387   if(buff1 != NULL)
  388     armci_free(buff1);
  389 
  390   if(buff2 != NULL)
  391     armci_free(buff2);
  392 }
  393