Exemplo n.º 1
0
/*\ initialize lapi
\*/
void lapi_initialize()
{

     int myid, numtasks,rc;

     bzero(&lapi_info,sizeof(lapi_info)); /* needed under Mohonk */
     rc = LAPI_Init(&lapi_handle, &lapi_info);
     if(rc) Error("lapi_init failed",rc);
     
     rc=LAPI_Qenv(lapi_handle, TASK_ID, &myid);
     if(rc) Error("lapi_qenv failed",rc);
     rc=LAPI_Qenv(lapi_handle, NUM_TASKS, &numtasks);
     if(rc) Error("lapi_qenv failed 2",rc);

     TCGMSG_nodeid = (Integer)myid;
     TCGMSG_nnodes = (Integer)numtasks;

     /* disable LAPI internal error checking */
     LAPI_Senv(lapi_handle, ERROR_CHK, 0);

     rc = LAPI_Setcntr(lapi_handle, &req_cnt, 0);
     if(rc)Error("lapi_initialize: setcntr failed",rc);

#ifdef DEBUG
     printf("me=%d initialized %d processes\n", myid, numtasks);
#endif
     fflush(stdout);
}
Exemplo n.º 2
0
Arquivo: lapi.c Projeto: bcernohous/ga
/* tag contains address of receive buffer guarded by cntr at process p */
void armci_lapi_send(msg_tag_t tag, void* data, int len, int p)
{
    int rc;
    lapi_cntr_t org_cntr;
    void *buf = tag.buf;
    lapi_cntr_t *cntr = tag.cntr;
    if(!buf)ERROR("armci_lapi_send: NULL tag(buf) error",0);
    if(!cntr)ERROR("armci_lapi_send:  NULL tag(cntr) error",0);

    rc=LAPI_Setcntr(lapi_handle, &org_cntr, 0);
    if(rc) ERROR("armci_lapi_send:setcntr failed",rc);
    rc=LAPI_Put(lapi_handle, (uint)p, (uint)len, buf, data, 
            cntr, &org_cntr, NULL);
    if(rc) ERROR("armci_lapi_send:put failed",rc);
    rc+=LAPI_Waitcntr(lapi_handle, &org_cntr, 1, NULL);
    if(rc) ERROR("armci_lapi_send:waitcntr failed",rc);
}
Exemplo n.º 3
0
Arquivo: lapi.c Projeto: bcernohous/ga
void armci_completion_handler(lapi_handle_t *t_hndl, void *save)
{
    lapi_handle_t hndl = *t_hndl;
    int need_data;
    void *message;
    int whofrom, msglen;
    request_header_t *msginfo = (request_header_t *)save;
    char *descr= (char*)(msginfo+1), *buf=MessageRcvBuffer;
    int buflen=MSG_BUFLEN;
#if ARMCI_ENABLE_GPC_CALLS
    extern pthread_t data_server;
    data_server = pthread_self();
#endif

    if(DEBUG_)
        fprintf(stderr,"%d:CH:op=%d from=%d datalen=%d dscrlen=%d\n", armci_me,
                msginfo->operation, msginfo->from,msginfo->datalen,msginfo->dscrlen);

    /*** assure that descriptor and data are in the right format and place ***/
    if(  msginfo->dscrlen < 0 || msginfo->datalen <0 ){
        /* for large put/acc/scatter need to get the data */
        int rc;
        lapi_cntr_t req_cntr;    
        int bytes=0;
        char *origin_ptr = msginfo->tag.buf;

        if (msginfo->dscrlen<0) {
            descr =MessageRcvBuffer;
            msginfo->dscrlen = -msginfo->dscrlen;
            buf = descr + msginfo->dscrlen;
            buflen += msginfo->dscrlen;
            bytes += msginfo->dscrlen;

        }
        if (msginfo->datalen <0){
            msginfo->datalen = -msginfo->datalen;
            bytes += msginfo->datalen;
        }

        if(rc=LAPI_Setcntr(hndl, &req_cntr, 0)) ERROR("CH:setcntr failed",rc);
        if(rc=LAPI_Get(hndl, (uint)msginfo->from, bytes,
                    origin_ptr, MessageRcvBuffer,
                    msginfo->tag.cntr,&req_cntr))ERROR("CH:LAPI_Get failed",rc);

        if(rc=LAPI_Waitcntr(hndl, &req_cntr,1,NULL))ERROR("CH:Waitcntr failed",rc);


    } else{

        /* desc is in save, data could be but not for GET */
        if(msginfo->operation !=GET)buf = descr + msginfo->dscrlen;
        buflen = MSG_BUFLEN;
    }

    /*   fprintf(stderr,"CH: val=%lf\n",*(double*)(buf+msginfo->datalen -8));*/


    /*** dispatch request to the appropriate handler function ***/
    switch(msginfo->operation){
        case LOCK:   armci_server_lock(msginfo); 
                     break;
        case UNLOCK: armci_server_unlock(msginfo, descr); 
                     break;
        default:
                     if(msginfo->format == STRIDED)
                         armci_server(msginfo, descr, buf, buflen);
                     else
                         armci_server_vector(msginfo, descr, buf, buflen);
    }

    free(msginfo);
#ifdef LINUX
    (void)fetch_and_add(&num_malloc, (long)-1);
#else
    (void)fetch_and_addlp(&num_malloc, (long)-1);
#endif
}
Exemplo n.º 4
0
Arquivo: lapi.c Projeto: bcernohous/ga
/*\ initialization of LAPI related data structures
  \*/
void armci_init_lapi()
{
    int rc, p;
    int lapi_max_uhdr_sz;
    lapi_cmpl_t *pcntr;
    lapi_remote_cxt_t util_cxt;  /* For call to obtain rCxt */

#ifndef TCGMSG
    rc = LAPI_Init(&lapi_handle, &lapi_info);
    if(rc) ERROR("lapi_init failed",rc);
#endif

    /* set the max limit for AM header data length */
    rc = LAPI_Qenv(lapi_handle,MAX_UHDR_SZ, &lapi_max_uhdr_sz);
    if(rc) ERROR("armci_init_lapi:  LAPI_Qenv failed", rc); 

    /*     fprintf(stderr,"max header size = %d\n",lapi_max_uhdr_sz);*/

    /* how much data can fit into AM header ? */
    lapi_max_uhdr_data_sz = lapi_max_uhdr_sz - sizeof(request_header_t);

    /* allocate memory for completion state array */
    cmpl_arr = (lapi_cmpl_t*)malloc(armci_nproc*sizeof(lapi_cmpl_t));
    if(cmpl_arr==NULL) ERROR("armci_init_lapi:malloc for cmpl_arr failed",0);

    /* allocate memory for ack and get counters, 1 if not thread safe */
#ifdef THREAD_SAFE
    ack_cntr = calloc(armci_user_threads.max, sizeof(lapi_cmpl_t));
    get_cntr = calloc(armci_user_threads.max, sizeof(lapi_cmpl_t));
#else
    ack_cntr = calloc(1, sizeof(lapi_cmpl_t));
    get_cntr = calloc(1, sizeof(lapi_cmpl_t));
#endif
    if (!(ack_cntr && get_cntr))
        ERROR("armci_init_lapi:calloc for ack or get counters failed",0);

    /* initialize completion state array */
    for(p = 0; p< armci_nproc; p++){
        rc = LAPI_Setcntr(lapi_handle, &cmpl_arr[p].cntr, 0);
        if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (arr)",rc);
        cmpl_arr[p].oper = -1;
        cmpl_arr[p].val = 0;
    }

    /* initialize ack/buf/hdr counters */
#ifdef THREAD_SAFE
#   define N armci_user_threads.max
#else
#   define N 1
#endif
    for (p = 0; p < N; p++) {
        rc = LAPI_Setcntr(lapi_handle, &(ack_cntr[p].cntr), 0);
        if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (ack)",rc);
        ack_cntr[p].val = 0;

        rc = LAPI_Setcntr(lapi_handle, &(get_cntr[p].cntr), 0);
        if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (get)",rc);
        get_cntr[p].val = 0;
    }
    rc = LAPI_Setcntr(lapi_handle, &hdr_cntr.cntr, 0);
    if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (hdr)",rc);
    hdr_cntr.val = 0;
    rc = LAPI_Setcntr(lapi_handle, &buf_cntr.cntr, 0);
    if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (buf)",rc);
    buf_cntr.val = 0;
#if 0
    pcntr = (lapi_cmpl_t*)MessageSndBuffer;
    rc = LAPI_Setcntr(lapi_handle, &pcntr->cntr, 0);
    if(rc) ERROR("armci_init_lapi: LAPI_Setcntr failed (bufcntr)",rc);
    pcntr->val = 0;
#endif

#ifdef LAPI_RDMA
    /* allocate rCxt */
    lapi_remote_cxt = (lapi_user_cxt_t*)malloc(armci_nproc *
            sizeof(lapi_user_cxt_t));
    if(lapi_remote_cxt==NULL) ERROR("armci_init_lapi: rCxt malloc failed",0);

    /* obtain remote context "rCxt" for RDMA Operation of all procs */
    for(p = 0; p< armci_nproc; p++){
        if(p==armci_me) continue;
        util_cxt.Util_type   = LAPI_REMOTE_RCXT;
        util_cxt.operation   = LAPI_RDMA_ACQUIRE;
        util_cxt.dest        = p;
        CHECK(LAPI_Util(lapi_handle, (lapi_util_t *) &util_cxt));
        lapi_remote_cxt[p]   =  util_cxt.usr_rcxt;
    }
#endif

#if  !defined(LAPI2)

    /* for high performance, disable LAPI internal error checking */
    LAPI_Senv(lapi_handle, ERROR_CHK, 0);

#endif

    /* make sure that interrupt mode is on */
    LAPI_Senv(lapi_handle, INTERRUPT_SET, 1);

    /* initialize buffer managment module */
    _armci_buf_init();

#ifdef LAPI_RDMA
    CHECK((LAPI_Gfence(lapi_handle)));
#endif
#if ARMCI_ENABLE_GPC_CALLS
    gpc_req = (gpc_buf_t *)malloc(sizeof(gpc_buf_t)*MAX_GPC_REQ);
    if(gpc_req==NULL)armci_die("malloc for gpc failed",sizeof(gpc_buf_t));
    gpc_init();
#endif
}
Exemplo n.º 5
0
/* ---------------------------------------------------------- *\
   DDI_GDLBNext(counter)
   ====================
   [OUT] counter - value of the load balance counter returned
                   to the calling process.

   An atomic operation that sets the value of counter to the
   value of the global load-balance counter, then increments
   the global counter.
\* --------------------------------------------------------- */
   void DDI_GDLBNext(size_t *counter) {
      int np,me,nn,my,tmp_scope,remote_id=0;
      DDI_Patch Patch;
      
    # if defined DDI_LAPI
      lapi_cntr_t org_cntr;
      uint tgt          = gv(lapi_map)[0];
      int *tgt_var      = gv(lapi_gdlb_cntr_addr)[tgt];
      int  in_val       = 1;
      int  prev_tgt_val = -1;
    # endif

# if defined DDI_ARMCI
      DDI_ARMCI_GDLBNext(counter);
      return;
# endif
    
      DDI_NProc(&np,&me);

      if(me == 0) {
      /* ---------------------------------- *\
         We need to work in the world scope
      \* ---------------------------------- */
         tmp_scope = DDI_WORKING_COMM;
         gv(ddi_working_comm) = DDI_COMM_WORLD;
   
         DDI_NProc(&np,&me);
         DDI_NNode(&nn,&my);

       # if FULL_SMP
       # if defined DDI_LAPI
         if(LAPI_Setcntr(gv(lapi_hnd),&org_cntr,0) != LAPI_SUCCESS) {
            fprintf(stdout,"%s: LAPI_Setcntr failed in DDI_GDLBNext.\n",DDI_Id());
            Fatal_error(911);
         }
         
         if(LAPI_Rmw(gv(lapi_hnd),FETCH_AND_ADD,tgt,tgt_var,&in_val,
                       &prev_tgt_val,&org_cntr) != LAPI_SUCCESS) {
            fprintf(stdout,"%s: LAPI_Rmw failed in DDI_GDLBNext.\n",DDI_Id());
            Fatal_error(911);
         }
         
         if(LAPI_Waitcntr(gv(lapi_hnd),&org_cntr,1,NULL) != LAPI_SUCCESS) {
            fprintf(stdout,"%s: LAPI_Waitcntr failed in DDI_GDLBNext.\n",DDI_Id());
            Fatal_error(911);
         }
         
         if(prev_tgt_val == -1) {
            fprintf(stdout,"%s: LAPI version of DDI_GDLBNext is not working correctly.\n",DDI_Id());
            Fatal_error(911);
         } else {
            *counter = (size_t) prev_tgt_val;
         }
       # else
         if(my == 0) {
            DDI_GDLBNext_local(counter);
         } else {
            Patch.oper = DDI_GDLBNEXT;
            DDI_Send_request(&Patch,&remote_id,NULL);
            DDI_Recv(counter,sizeof(size_t),remote_id);
         }
       # endif
       # else
         Patch.oper = DDI_GDLBNEXT;
         DDI_Send_request(&Patch,&remote_id,NULL);
         DDI_Recv(counter,sizeof(size_t),remote_id);
       # endif
   
      /* --------------------------- *\
         Return to the working scope
      \* --------------------------- */
         gv(ddi_working_comm) = tmp_scope;
      }

      DDI_BCast(counter,sizeof(size_t),0);
   }
Exemplo n.º 6
0
   void DDI_GetAcc_lapi_server(DDI_Patch *patch, void *buffer) {

   /* --------------- *\
      Local Variables 
   \* --------------- */
      lapi_handle_t hndl;
      uint tgt;
      ulong len;
      void *tgt_addr,*org_addr;
      lapi_cntr_t *tgt_cntr,*org_cntr,*cmpl_cntr;
      lapi_cntr_t local_cntr;

      STD_DEBUG((stdout,"%s: Entering DDI_GetAcc_lapi_server.\n",DDI_Id()))

   /* ----------------------------------------- *\
      Set up the calling arguments for LAPI_Get 
   \* ----------------------------------------- */
      hndl      = gv(lapi_hnd);                        /* LAPI Handle */
      tgt       = patch->cp_lapi_id;                   /* Target for the LAPI_Get */
      len       = (ulong) patch->size;                 /* Amount of data to get */
      tgt_addr  = patch->cp_buffer_addr;               /* Addr at target to get */
      org_addr  = buffer;                              /* Local Addr for data that is got */
      tgt_cntr  = (lapi_cntr_t *) patch->cp_lapi_cntr; /* Target counter */ 
      org_cntr  = &local_cntr;                         /* Local counter -> incremented once
                                                          the LAPI_Get is completed */
      cmpl_cntr = NULL;
                                                  
      ULTRA_DEBUG((stdout,"%s: DDI_Patch -> ilo=%i ihi=%i jlo=%i jhi=%i size=%lu.\n",
                   DDI_Id(),patch->ilo,patch->ihi,patch->jlo,patch->jhi,patch->size))
      ULTRA_DEBUG((stdout,"%s: org buffer_addr=%x cntr_addr=%x.\n",DDI_Id(),org_addr,org_cntr))
      ULTRA_DEBUG((stdout,"%s: tgt id=%i buffer_addr=%x cntr_addr=%x.\n",DDI_Id(),tgt,tgt_addr,tgt_cntr))


   /* -------------------------------------------------------------------------- *\
      We are interested in when the LAPI_Get is finished, zero the local counter
   \* -------------------------------------------------------------------------- */
      if(LAPI_Setcntr(hndl,org_cntr,0) != LAPI_SUCCESS) {
         fprintf(stdout,"%s: LAPI_Setcntr failed in DDI_GetAcc_lapi_server.\n",DDI_Id());
         Fatal_error(911);
      }
      ULTRA_DEBUG((stdout,"%s: Initializing local LAPI counter.\n",DDI_Id()))


   /* --------------------------------------------------- *\
      Execute the LAPI_Get.  This is a non-blocking call.
   \* --------------------------------------------------- */
      if(LAPI_Get(hndl,tgt,len,tgt_addr,org_addr,tgt_cntr,org_cntr) != LAPI_SUCCESS) {
         fprintf(stdout,"%s: LAPI_Get failed in DDI_GetAcc_lapi_server.\n",DDI_Id());
         Fatal_error(911);
      }
      MAX_DEBUG((stdout,"%s: Executing LAPI_Get from %i.\n",DDI_Id(),tgt))


   /* ------------------------------------------------------------------------ *\
      Wait here until the local counter is incremented ==> LAPI_Get completed.
   \* ------------------------------------------------------------------------ */
      if(LAPI_Waitcntr(hndl,org_cntr,1,NULL) != LAPI_SUCCESS) {
         fprintf(stdout,"%s: LAPI_Waitcntr failed in DDI_GetAcc_lapi_server.\n",DDI_Id());
         Fatal_error(911);
      }
      MAX_DEBUG((stdout,"%s: LAPI_Get from %i completed.\n",DDI_Id(),tgt))
      

   /* -------------------------------------------------------------- *\
      Place the data (now local) into the shared-memory of the node.
   \* -------------------------------------------------------------- */
      MAX_DEBUG((stdout,"%s: LAPI handler calling DDI_GetAcc_local.\n",DDI_Id()))
      DDI_GetAcc_local(patch,buffer);
      MAX_DEBUG((stdout,"%s: LAPI handler completed DDI_GetAcc_local.\n",DDI_Id()))
      STD_DEBUG((stdout,"%s: Exiting DDI_GetAcc_lapi_server.\n",DDI_Id()))


   /* --------------------------------------------------- *\
      Execute the LAPI_Put.  This is a non-blocking call.
   \* --------------------------------------------------- */
      if(LAPI_Put(hndl,tgt,len,tgt_addr,org_addr,tgt_cntr,org_cntr,cmpl_cntr) != LAPI_SUCCESS) {
         fprintf(stdout,"%s: LAPI_Get failed in DDI_GetAcc_lapi_server.\n",DDI_Id());
         Fatal_error(911);
      }
      MAX_DEBUG((stdout,"%s: Executing LAPI_Put from %i.\n",DDI_Id(),tgt))


   /* ------------------------------------------------------------------------- *\
      Wait here until the local counter is incremented ==> LAPI_Put has copied.
   \* ------------------------------------------------------------------------- */
      if(LAPI_Waitcntr(hndl,org_cntr,1,NULL) != LAPI_SUCCESS) {
         fprintf(stdout,"%s: LAPI_Waitcntr failed in DDI_GetAcc_lapi_server.\n",DDI_Id());
         Fatal_error(911);
      }
      MAX_DEBUG((stdout,"%s: LAPI_Put copied data enroute to %i.\n",DDI_Id(),tgt))

   }
Exemplo n.º 7
0
/* -------------------------------------------------------------- *\
   DDI_GetAccP(handle,patch,buff)
   ============================
   [IN] handle - Handle of the distributed array to be accessed.
   [IN] patch  - structure containing ilo, ihi, jlo, jhi, etc.
   [IN] buff   - Data segment to be operated on.
\* -------------------------------------------------------------- */
   void DDI_GetAccP(int handle,DDI_Patch *patch,void *buff) {
   
   /* --------------- *\
      Local Variables
   \* --------------- */
      char ack=57;
      int i,np,me,nn,my,remote_id,nsubp;
      int ranks[MAX_NODES];
      DDI_Patch subp[MAX_NODES];
      char *working_buffer = (char *) buff;

    # if defined DDI_LAPI
      DDI_Patch *local_patch = NULL;
      lapi_cntr_t cntr[MAX_NODES];
    # endif
    
      STD_DEBUG((stdout,"%s: Entering DDI_GetAccP.\n",DDI_Id()))

   /* -------------------- *\
      Process OR Node Rank
   \* -------------------- */
      DDI_NProc(&np,&me);
      DDI_NNode(&nn,&my);


   /* ------------------------------------- *\
      Ensure the patch has the correct info
   \* ------------------------------------- */
      patch->oper   = DDI_GETACC;
      patch->handle = handle;


   /* ---------------------------------- *\
      Check calling arguments for errors
   \* ---------------------------------- */
    # if defined DDI_CHECK_ARGS
      if(handle < 0 || handle >= gv(ndda)) {
         fprintf(stdout,"%s: Invalid handle [%i] in DDI_GetAcc.\n",DDI_Id(),handle);
         Fatal_error(911);
      }
      
      if(patch->ilo > patch->ihi || patch->ilo < 0 || patch->ihi >= gv(nrow)[handle]) {
         fprintf(stdout,"%s: Invalid row dimensions during DDI_GetAcc => ilo=%i ihi=%i.\n",DDI_Id(),patch->ilo,patch->ihi);
         Fatal_error(911);
      }
      
      if(patch->jlo > patch->jhi || patch->jlo < 0 || patch->jhi >= gv(ncol)[handle]) {
         fprintf(stdout,"%s: Invalid colum dimensions during DDI_GetAcc => jlo=%i jhi=%i.\n",DDI_Id(),patch->jlo,patch->jhi);
         Fatal_error(911);
      }
    # endif


   /* ------------------------------ *\
      Log some simple profiling info
   \* ------------------------------ */
    # if defined DDI_COUNTERS
      gv(acc_profile).ncalls++;
      gv(acc_profile).nbytes += DDI_Patch_sizeof(patch);
    # endif


   /* ------------------------------------------------------- *\
      Determine where the pieces of the requested patch exist
   \* ------------------------------------------------------- */
      DDI_Subpatch(handle,patch,&nsubp,ranks,subp);
      MAX_DEBUG((stdout,"%s: %i subpatches.\n",DDI_Id(),nsubp))

      
   /* ------------------------------------------------------------------- *\
      Send data requests for all non-local pieces of the requested patch.
      Operate immediately to GetAcc a local portion of the patch.
   \* ------------------------------------------------------------------- */
      for(i=0; i<nsubp; i++) {
         ULTRA_DEBUG((stdout,"%s: GetAccumulating subpatch %i.\n",DDI_Id(),i))

      /* ------------------------------------------------------------- *\
         Using SysV, take advantage of shared-memory for a local patch
      \* ------------------------------------------------------------- */
       # if defined USE_SYSV

      /* ------------------------------------------------ *\
         Determine if the ith patch is local to 'my' node
      \* ------------------------------------------------ */
         if(ranks[i] == my) {
            MAX_DEBUG((stdout,"%s: Subpatch %i is local.\n",DDI_Id(),i))

         /* ---------------------------------------------------- *\
            Using LAPI, perform the local Getacc after all the data
            requests have been sent ==> maximize concurrency.
         \* ---------------------------------------------------- */
          # if defined DDI_LAPI
            local_patch = &subp[i];
            local_patch->cp_buffer_addr = working_buffer;
          # else
         /* --------------------------------------------- *\
            Otherwise, perform the local Getacc immediately.
         \* --------------------------------------------- */
            DDI_GetAcc_local(&subp[i],working_buffer);
          # endif

         /* ------------------------------------------------------- *\
            Move the working buffer to the next patch and continue.
         \* ------------------------------------------------------- */
            working_buffer += subp[i].size;
            continue;
         }
       # endif


      /* --------------------------------- *\
         If the current patch is NOT local 
      \* --------------------------------- */
         remote_id = ranks[i];


      /* ----------------------------------------------- *\
         Using LAPI, then include some extra information
      \* ----------------------------------------------- */
       # if defined DDI_LAPI
         subp[i].cp_lapi_id     = gv(lapi_map)[me];
         subp[i].cp_lapi_cntr   = (void *) &cntr[i];
         subp[i].cp_buffer_addr = (void *) working_buffer;
         LAPI_Setcntr(gv(lapi_hnd),&cntr[i],0);

         ULTRA_DEBUG((stdout,"%s: cp_lapi_id=%i.\n",DDI_Id(),gv(lapi_map)[me]))
         ULTRA_DEBUG((stdout,"%s: cp_lapi_cntr=%x.\n",DDI_Id(),&cntr[i]))
         ULTRA_DEBUG((stdout,"%s: cp_buffer_addr=%x.\n",DDI_Id(),working_buffer))
       # endif
      
      /* -------------------------------- *\
         Send data request for subpatch i
      \* -------------------------------- */
         MAX_DEBUG((stdout,"%s: Sending data request to node %i.\n",DDI_Id(),remote_id))
         DDI_Send_request(&subp[i],&remote_id,NULL);
         MAX_DEBUG((stdout,"%s: data request sent to global process %i.\n",DDI_Id(),remote_id))


      /* ------------------------------------------------------------ *\
         Receive an acknowledgement that the data server has raised
         a fence that will protect the distributed array from get or
         put access until all accumulates have finished.  This block-
         ing receive ensures that the current process executing this
         accumulate can *NOT* finish, until the fence has been raised 
      \* ------------------------------------------------------------ */
       # if !defined DDI_LAPI
       # if defined USE_SYSV
         MAX_DEBUG((stdout,"%s: Receiving remote fence ACK.\n",DDI_Id()))
         DDI_Recv(&ack,1,remote_id);
       # endif


      /* ---------------------------- *\
         Recv subpatch from remote_id
      \* ---------------------------- */
         MAX_DEBUG((stdout,"%s: Sending subpatch %i to %i.\n",DDI_Id(),i,remote_id))
         DDI_Send(working_buffer,subp[i].size,remote_id);
         DDI_Recv(working_buffer,subp[i].size,remote_id);
       # endif

      
      /* ------------ *\
         Shift buffer 
      \* ------------ */
         working_buffer += subp[i].size;
      }

   /* ----------------------------------------------------------- *\
      Using LAPI, perform the local Getaccumulate (if needed) as the
      remote processes are getting the data to Getaccumulate on the
      target processes.  Then wait for all the data to be copied
      out of the buffer before returning.
   \* ----------------------------------------------------------- */
    # if defined DDI_LAPI

   /* ------------------------------------ *\
      GetAccumulating local patch (if exists)
   \* ------------------------------------ */
      if(local_patch) DDI_GetAcc_local(local_patch,local_patch->cp_buffer_addr);

   /* ---------------------------------------------------------- *\
      Wait for all remote LAPI_Gets to finish copying local data
   \* ---------------------------------------------------------- */
      for(i=0; i<nsubp; i++) {
         if(subp[i].cp_lapi_cntr) {
            ULTRA_DEBUG((stdout,"%s: Wait for subpatch %i to be copied.\n",DDI_Id(),i))
            LAPI_Waitcntr(gv(lapi_hnd),&cntr[i],3,NULL);
            ULTRA_DEBUG((stdout,"%s: Subpatch %i copy completed.\n",DDI_Id(),i))
         }
      }
Exemplo n.º 8
0
void lapi_adr_exchg()
{
     long node, tgt;
     int rc;
     void **table;
     int i;
   
     table = (void **)malloc(TCGMSG_nnodes * sizeof(void *));
     if (!table) Error(" lapi_adr_exchg: malloc failed", 0);

     /* allocate and initialize send buffers */
     sendbuf_arr = (sendbuf_t*)malloc(SENDBUF_NUM*sizeof(sendbuf_t));
     if(!sendbuf_arr) Error(" lapi_adr_exchg:malloc 2 failed", 0);
/*
     bzero(sendbuf_arr,SENDBUF_NUM*sizeof(sendbuf_t));
*/

     for(i=0; i< SENDBUF_NUM; i++){
         LAPI_Setcntr(lapi_handle,&sendbuf_arr[i].cntr, 1);
         sendbuf_arr[i].next = sendbuf_arr+i+1;
     }
     sendbuf_arr[SENDBUF_NUM-1].next = sendbuf_arr;
     localbuf = sendbuf_arr;
     if(sizeof(ShmemBuf) < sizeof(sendbuf_t))
        Error("lapi_adr_exchg: buffer size problem",0);

     /* exchange addresses */
     for(node = 0; node < TCGMSG_nnodes; node++){

         /* Lapi does not like NULL address for buffer that we have 
            for sending msg to itself - use some invalid address */
         if (node == TCGMSG_nodeid) 
             TCGMSG_proc_info[node].recvbuf = (ShmemBuf *)1; 
         else
             if(LAPI_Setcntr(lapi_handle,
                &(TCGMSG_proc_info[node].recvbuf->cntr),0))
                Error("lapi_adr_exchg: setcntr failed",-1);

         rc = LAPI_Address_init(lapi_handle, TCGMSG_proc_info[node].recvbuf, 
                                                                     table); 
         if(rc) Error(" lapi_adr_exchg: address_init failed", node);

         if(rc) Error(" lapi_adr_exchg: cntr init failed", node);

         if(TCGMSG_nodeid == node)
            for(tgt=0; tgt<TCGMSG_nnodes; tgt++){ 
/*
#ifdef DEBUG
                printf("%ld org=%lx final=%lx\n", TCGMSG_nodeid, TCGMSG_proc_info[tgt].sendbuf, table[tgt]);
                fflush(stdout);
#endif
*/
                TCGMSG_proc_info[tgt].sendbuf = (ShmemBuf *)table[tgt];
            }
     }
     free(table);
#ifdef DEBUG
     printf("%ld: bufarray: (%lx, %lx) %ld bytes\n", TCGMSG_nodeid, 
           TCGMSG_receive_buffer, TCGMSG_receive_buffer + MAX_PROC,
           sizeof(ShmemBuf)*MAX_PROC);
     fflush(stdout);
#endif
}