-:    0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/ch3u_buffer.c
        -:    0:Graph:ch3u_buffer.gcno
        -:    0:Data:ch3u_buffer.gcda
        -:    0:Runs:3459
        -:    0:Programs:899
        -:    1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
        -:    2:/*
        -:    3: *  (C) 2001 by Argonne National Laboratory.
        -:    4: *      See COPYRIGHT in top-level directory.
        -:    5: */
        -:    6:
        -:    7:#include "mpidimpl.h"
        -:    8:
        -:    9:/* FIXME: Explain the contents of this file */
        -:   10:/*
        -:   11: * A first guess.  This file contains routines to manage memory-to-memory
        -:   12: * copies of buffers described by MPI datatypes
        -:   13: */
        -:   14:
        -:   15:/* MPIDI_COPY_BUFFER_SZ is the size of the buffer that is allocated when 
        -:   16:   copying from one non-contiguous buffer to another.  In this case, an 
        -:   17:   intermediate contiguous buffer is used of this size */
        -:   18:#if !defined(MPIDI_COPY_BUFFER_SZ)
        -:   19:#define MPIDI_COPY_BUFFER_SZ 16384
        -:   20:#endif
        -:   21:
        -:   22:/* FIXME: Explain this routine .
        -:   23:Used indirectly by mpid_irecv, mpid_recv (through MPIDI_CH3_RecvFromSelf) and 
        -:   24: in mpidi_isend_self.c */
        -:   25:
        -:   26:/* This routine appears to handle copying data from one buffer (described by
        -:   27: the usual MPI triple (buf,count,datatype) to another, as is needed in send 
        -:   28: and receive from self.  We may want to put all of the "from self" routines
        -:   29: into a single file, and make MPIDI_CH3U_Buffer_copy static to this file. */
        -:   30:
        -:   31:#undef FUNCNAME
        -:   32:#define FUNCNAME MPIDI_CH3U_Buffer_copy
        -:   33:#undef FCNAME
        -:   34:#define FCNAME MPIDI_QUOTE(FUNCNAME)
        -:   35:void MPIDI_CH3U_Buffer_copy(
        -:   36:    const void * const sbuf, int scount, MPI_Datatype sdt, int * smpi_errno,
        -:   37:    void * const rbuf, int rcount, MPI_Datatype rdt, MPIDI_msg_sz_t * rsz,
        -:   38:    int * rmpi_errno)
    17290:   39:{
        -:   40:    int sdt_contig;
        -:   41:    int rdt_contig;
        -:   42:    MPI_Aint sdt_true_lb, rdt_true_lb;
        -:   43:    MPIDI_msg_sz_t sdata_sz;
        -:   44:    MPIDI_msg_sz_t rdata_sz;
        -:   45:    MPID_Datatype * sdt_ptr;
        -:   46:    MPID_Datatype * rdt_ptr;
        -:   47:    MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_BUFFER_COPY);
        -:   48:    MPIDI_STATE_DECL(MPID_STATE_MEMCPY);
        -:   49:
        -:   50:    MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_BUFFER_COPY);
    17290:   51:    *smpi_errno = MPI_SUCCESS;
    17290:   52:    *rmpi_errno = MPI_SUCCESS;
        -:   53:
    17290:   54:    MPIDI_Datatype_get_info(scount, sdt, sdt_contig, sdata_sz, sdt_ptr, sdt_true_lb);
    17290:   55:    MPIDI_Datatype_get_info(rcount, rdt, rdt_contig, rdata_sz, rdt_ptr, rdt_true_lb);
        -:   56:
        -:   57:    /* --BEGIN ERROR HANDLING-- */
    17290:   58:    if (sdata_sz > rdata_sz)
        -:   59:    {
        -:   60:	MPIU_DBG_MSG_FMT(CH3_OTHER,TYPICAL,(MPIU_DBG_FDEST,
        -:   61:	    "message truncated, sdata_sz=" MPIDI_MSG_SZ_FMT " rdata_sz=" MPIDI_MSG_SZ_FMT,
        -:   62:			  sdata_sz, rdata_sz));
    #####:   63:	sdata_sz = rdata_sz;
    #####:   64:	*rmpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TRUNCATE, "**truncate", "**truncate %d %d", sdata_sz, rdata_sz );
        -:   65:    }
        -:   66:    /* --END ERROR HANDLING-- */
        -:   67:    
    17290:   68:    if (sdata_sz == 0)
        -:   69:    {
      742:   70:	*rsz = 0;
      742:   71:	goto fn_exit;
        -:   72:    }
        -:   73:    
    16548:   74:    if (sdt_contig && rdt_contig)
        -:   75:    {
        -:   76:	MPIDI_FUNC_ENTER(MPID_STATE_MEMCPY);
    13857:   77:	MPIU_Memcpy((char *)rbuf + rdt_true_lb, (const char *)sbuf + sdt_true_lb, sdata_sz);
        -:   78:	MPIDI_FUNC_EXIT(MPID_STATE_MEMCPY);
    13857:   79:	*rsz = sdata_sz;
        -:   80:    }
     2691:   81:    else if (sdt_contig)
        -:   82:    {
        -:   83:	MPID_Segment seg;
        -:   84:	MPI_Aint last;
        -:   85:
     1938:   86:	MPID_Segment_init(rbuf, rcount, rdt, &seg, 0);
     1938:   87:	last = sdata_sz;
        -:   88:	MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST, 
        -:   89:                          "pre-unpack last=" MPIDI_MSG_SZ_FMT, last ));
     1938:   90:	MPID_Segment_unpack(&seg, 0, &last, (char*)sbuf + sdt_true_lb);
        -:   91:	MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:   92:			 "pre-unpack last=" MPIDI_MSG_SZ_FMT, last ));
        -:   93:	/* --BEGIN ERROR HANDLING-- */
     1938:   94:	if (last != sdata_sz)
        -:   95:	{
    #####:   96:	    *rmpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE, "**dtypemismatch", 0);
        -:   97:	}
        -:   98:	/* --END ERROR HANDLING-- */
        -:   99:
     1938:  100:	*rsz = last;
        -:  101:    }
      753:  102:    else if (rdt_contig)
        -:  103:    {
        -:  104:	MPID_Segment seg;
        -:  105:	MPI_Aint last;
        -:  106:
      157:  107:	MPID_Segment_init(sbuf, scount, sdt, &seg, 0);
      157:  108:	last = sdata_sz;
        -:  109:	MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  110:			       "pre-pack last=" MPIDI_MSG_SZ_FMT, last ));
      157:  111:	MPID_Segment_pack(&seg, 0, &last, (char*)rbuf + rdt_true_lb);
        -:  112:	MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  113:			    "post-pack last=" MPIDI_MSG_SZ_FMT, last ));
        -:  114:	/* --BEGIN ERROR HANDLING-- */
      157:  115:	if (last != sdata_sz)
        -:  116:	{
    #####:  117:	    *rmpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE, "**dtypemismatch", 0);
        -:  118:	}
        -:  119:	/* --END ERROR HANDLING-- */
        -:  120:
      157:  121:	*rsz = last;
        -:  122:    }
        -:  123:    else
        -:  124:    {
        -:  125:	char * buf;
        -:  126:	MPIDI_msg_sz_t buf_off;
        -:  127:	MPID_Segment sseg;
        -:  128:	MPIDI_msg_sz_t sfirst;
        -:  129:	MPID_Segment rseg;
        -:  130:	MPIDI_msg_sz_t rfirst;
        -:  131:
      596:  132:	buf = MPIU_Malloc(MPIDI_COPY_BUFFER_SZ);
        -:  133:	/* --BEGIN ERROR HANDLING-- */
      596:  134:	if (buf == NULL)
        -:  135:	{
        -:  136:	    MPIU_DBG_MSG(CH3_OTHER,TYPICAL,"SRBuf allocation failure");
    #####:  137:	    *smpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);
    #####:  138:	    *rmpi_errno = *smpi_errno;
    #####:  139:	    *rsz = 0;
    #####:  140:	    goto fn_exit;
        -:  141:	}
        -:  142:	/* --END ERROR HANDLING-- */
        -:  143:
      596:  144:	MPID_Segment_init(sbuf, scount, sdt, &sseg, 0);
      596:  145:	MPID_Segment_init(rbuf, rcount, rdt, &rseg, 0);
        -:  146:
      596:  147:	sfirst = 0;
      596:  148:	rfirst = 0;
      596:  149:	buf_off = 0;
        -:  150:	
        -:  151:	for(;;)
        -:  152:	{
        -:  153:	    MPI_Aint last;
        -:  154:	    char * buf_end;
        -:  155:
      612:  156:	    if (sdata_sz - sfirst > MPIDI_COPY_BUFFER_SZ - buf_off)
        -:  157:	    {
       16:  158:		last = sfirst + (MPIDI_COPY_BUFFER_SZ - buf_off);
        -:  159:	    }
        -:  160:	    else
        -:  161:	    {
      596:  162:		last = sdata_sz;
        -:  163:	    }
        -:  164:	    
        -:  165:	    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  166:               "pre-pack first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT, 
        -:  167:						sfirst, last ));
      612:  168:	    MPID_Segment_pack(&sseg, sfirst, &last, buf + buf_off);
        -:  169:	    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  170:               "post-pack first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT, 
        -:  171:               sfirst, last ));
        -:  172:	    /* --BEGIN ERROR HANDLING-- */
      612:  173:	    MPIU_Assert(last > sfirst);
        -:  174:	    /* --END ERROR HANDLING-- */
        -:  175:	    
      612:  176:	    buf_end = buf + buf_off + (last - sfirst);
      612:  177:	    sfirst = last;
        -:  178:	    
        -:  179:	    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  180:             "pre-unpack first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT, 
        -:  181:						rfirst, last ));
      612:  182:	    MPID_Segment_unpack(&rseg, rfirst, &last, buf);
        -:  183:	    MPIU_DBG_MSG_FMT(CH3_OTHER,VERBOSE,(MPIU_DBG_FDEST,
        -:  184:             "post-unpack first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT, 
        -:  185:						rfirst, last ));
        -:  186:	    /* --BEGIN ERROR HANDLING-- */
      612:  187:	    MPIU_Assert(last > rfirst);
        -:  188:	    /* --END ERROR HANDLING-- */
        -:  189:
      612:  190:	    rfirst = last;
        -:  191:
      612:  192:	    if (rfirst == sdata_sz)
        -:  193:	    {
        -:  194:		/* successful completion */
      596:  195:		break;
        -:  196:	    }
        -:  197:
        -:  198:	    /* --BEGIN ERROR HANDLING-- */
       16:  199:	    if (sfirst == sdata_sz)
        -:  200:	    {
        -:  201:		/* datatype mismatch -- remaining bytes could not be unpacked */
    #####:  202:		*rmpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE, "**dtypemismatch", 0);
    #####:  203:		break;
        -:  204:	    }
        -:  205:	    /* --END ERROR HANDLING-- */
        -:  206:
       16:  207:	    buf_off = sfirst - rfirst;
       16:  208:	    if (buf_off > 0)
        -:  209:	    {
        -:  210:		MPIU_DBG_MSG_FMT(CH3_OTHER, VERBOSE, (MPIU_DBG_FDEST,
        -:  211:                  "moved " MPIDI_MSG_SZ_FMT " bytes to the beginning of the tmp buffer", buf_off));
    #####:  212:		memmove(buf, buf_end - buf_off, buf_off);
        -:  213:	    }
        -:  214:	}
        -:  215:
      596:  216:	*rsz = rfirst;
      596:  217:	MPIU_Free(buf);
        -:  218:    }
        -:  219:
    17290:  220:  fn_exit:
        -:  221:    MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_BUFFER_COPY);
    17290:  222:}
        -:  223:
        -:  224:
        -:  225:/*
        -:  226: * This routine is called by mpid_recv and mpid_irecv when a request
        -:  227: * matches a send-to-self message 
        -:  228: */
        -:  229:int MPIDI_CH3_RecvFromSelf( MPID_Request *rreq, void *buf, int count, 
        -:  230:			    MPI_Datatype datatype )
     9020:  231:{
     9020:  232:    MPID_Request * const sreq = rreq->partner_request;
        -:  233:
     9020:  234:    if (sreq != NULL)
        -:  235:    {
        -:  236:	MPIDI_msg_sz_t data_sz;
        -:  237:	
     9020:  238:	MPIDI_CH3U_Buffer_copy(sreq->dev.user_buf, sreq->dev.user_count,
        -:  239:			       sreq->dev.datatype, &sreq->status.MPI_ERROR,
        -:  240:			       buf, count, datatype, &data_sz, 
        -:  241:			       &rreq->status.MPI_ERROR);
     9020:  242:	rreq->status.count = (int)data_sz;
     9020:  243:	MPID_REQUEST_SET_COMPLETED(sreq);
     9020:  244:	MPID_Request_release(sreq);
        -:  245:    }
        -:  246:    else
        -:  247:    {
        -:  248:	/* The sreq is missing which means an error occurred.  
        -:  249:	   rreq->status.MPI_ERROR should have been set when the
        -:  250:	   error was detected. */
        -:  251:    }
        -:  252:    
        -:  253:    /* no other thread can possibly be waiting on rreq, so it is safe to 
        -:  254:       reset ref_count and cc */
     9020:  255:    rreq->cc = 0;
     9020:  256:    MPIU_Object_set_ref(rreq, 1);
        -:  257:
     9020:  258:    return MPI_SUCCESS;
        -:  259:}