-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/mpid/ch3/src/ch3u_request.c
-: 0:Graph:ch3u_request.gcno
-: 0:Data:ch3u_request.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:/* This file contains two types of routines associated with requests:
-: 10: * Routines to allocate and free requests
-: 11: * Routines to manage iovs on requests
-: 12: *
-: 13: * Note that there are a number of macros that also manage requests defined
-: 14: * in mpidimpl.h ; these are intended to optimize request creation for
-: 15: * specific types of requests. See the comments in mpidimpl.h for more
-: 16: * details.
-: 17: */
-: 18:
-: 19:/* Routines and data structures for request allocation and deallocation */
-: 20:#ifndef MPID_REQUEST_PREALLOC
-: 21:#define MPID_REQUEST_PREALLOC 8
-: 22:#endif
-: 23:
-: 24:MPID_Request MPID_Request_direct[MPID_REQUEST_PREALLOC] = {{0}};
-: 25:MPIU_Object_alloc_t MPID_Request_mem = {
-: 26: 0, 0, 0, 0, MPID_REQUEST, sizeof(MPID_Request), MPID_Request_direct,
-: 27: MPID_REQUEST_PREALLOC };
-: 28:
-: 29:/* See the comments above about request creation. Some routines will
-: 30: use macros in mpidimpl.h *instead* of this routine */
-: 31:#undef FUNCNAME
-: 32:#define FUNCNAME MPID_Request_create
-: 33:#undef FCNAME
-: 34:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 35:MPID_Request * MPID_Request_create(void)
580657: 36:{
-: 37: MPID_Request * req;
-: 38: MPIDI_STATE_DECL(MPID_STATE_MPID_REQUEST_CREATE);
-: 39:
-: 40: MPIDI_FUNC_ENTER(MPID_STATE_MPID_REQUEST_CREATE);
-: 41:
580657: 42: req = MPIU_Handle_obj_alloc(&MPID_Request_mem);
580657: 43: if (req != NULL)
-: 44: {
-: 45: MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE,
-: 46: "allocated request, handle=0x%08x", req->handle);
-: 47:#ifdef MPICH_DBG_OUTPUT
-: 48: /*MPIU_Assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);*/
-: 49: if (HANDLE_GET_MPI_KIND(req->handle) != MPID_REQUEST)
-: 50: {
-: 51: int mpi_errno;
|
-: 52: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 53: FCNAME, __LINE__, MPI_ERR_OTHER,
-: 54: "**invalid_handle", "**invalid_handle %d", req->handle);
-: 55: MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);
-: 56: }
-: 57:#endif
-: 58: /* FIXME: This makes request creation expensive. We need to trim
-: 59: this to the basics, with additional setup for special-purpose
-: 60: requests (think base class and inheritance). For example, do we
-: 61: *really* want to set the kind to UNDEFINED? And should the RMA
-: 62: values be set only for RMA requests? */
|
580657: 63: MPIU_Object_set_ref(req, 1);
580657: 64: req->kind = MPID_REQUEST_UNDEFINED;
580657: 65: req->cc = 1;
580657: 66: req->cc_ptr = &req->cc;
-: 67: /* FIXME: status fields meaningful only for receive, and even then
-: 68: should not need to be set. */
580657: 69: req->status.MPI_SOURCE = MPI_UNDEFINED;
580657: 70: req->status.MPI_TAG = MPI_UNDEFINED;
580657: 71: req->status.MPI_ERROR = MPI_SUCCESS;
580657: 72: req->status.count = 0;
580657: 73: req->status.cancelled = FALSE;
580657: 74: req->comm = NULL;
580657: 75: req->dev.datatype_ptr = NULL;
580657: 76: req->dev.segment_ptr = NULL;
-: 77: /* Masks and flags for channel device state in an MPID_Request */
580657: 78: req->dev.state = 0;
580657: 79: req->dev.cancel_pending = FALSE;
-: 80: /* FIXME: RMA ops shouldn't need to be set except when creating a
-: 81: request for RMA operations */
580657: 82: req->dev.target_win_handle = MPI_WIN_NULL;
580657: 83: req->dev.source_win_handle = MPI_WIN_NULL;
580657: 84: req->dev.single_op_opt = 0;
580657: 85: req->dev.lock_queue_entry = NULL;
580657: 86: req->dev.dtype_info = NULL;
580657: 87: req->dev.dataloop = NULL;
580657: 88: req->dev.iov_offset = 0;
-: 89:#if 0
-: 90: req->dev.rdma_iov_count = 0;
-: 91: req->dev.rdma_iov_offset = 0;
-: 92:#endif
-: 93:#ifdef MPIDI_CH3_REQUEST_INIT
-: 94: MPIDI_CH3_REQUEST_INIT(req);
-: 95:#endif
-: 96: }
-: 97: else
-: 98: {
-: 99: /* FIXME: This fails to fail if debugging is turned off */
-: 100: MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"unable to allocate a request");
-: 101: }
-: 102:
|
-: 103: MPIDI_FUNC_EXIT(MPID_STATE_MPID_REQUEST_CREATE);
|
580657: 104: return req;
-: 105:}
-: 106:
-: 107:/* FIXME: We need a lighter-weight version of this to avoid all of the
-: 108: extra checks. One posibility would be a single, no special case (no
-: 109: comm, datatype, or srbuf to check) and a more general (check everything)
-: 110: version. */
-: 111:#undef FUNCNAME
-: 112:#define FUNCNAME MPIDI_CH3_Request_destroy
-: 113:#undef FCNAME
-: 114:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 115:void MPIDI_CH3_Request_destroy(MPID_Request * req)
20967117: 116:{
-: 117: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);
-: 118:
-: 119: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);
-: 120: MPIU_DBG_MSG_P(CH3_CHANNEL,VERBOSE,
-: 121: "freeing request, handle=0x%08x", req->handle);
-: 122:
-: 123:#ifdef MPICH_DBG_OUTPUT
-: 124: /*MPIU_Assert(HANDLE_GET_MPI_KIND(req->handle) == MPID_REQUEST);*/
-: 125: if (HANDLE_GET_MPI_KIND(req->handle) != MPID_REQUEST)
-: 126: {
|
-: 127: int mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 128: FCNAME, __LINE__, MPI_ERR_OTHER,
-: 129: "**invalid_handle", "**invalid_handle %d", req->handle);
-: 130: MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);
-: 131: }
-: 132: /* XXX DJG FIXME should we be checking this? */
-: 133: /*MPIU_Assert(req->ref_count == 0);*/
-: 134: if (req->ref_count != 0)
-: 135: {
-: 136: int mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 137: FCNAME, __LINE__, MPI_ERR_OTHER,
-: 138: "**invalid_refcount", "**invalid_refcount %d", req->ref_count);
-: 139: MPID_Abort(MPIR_Process.comm_world, mpi_errno, -1, NULL);
-: 140: }
-: 141:#endif
-: 142:
-: 143: /* FIXME: We need a better way to handle these so that we
-: 144: do not always need to initialize these fields and check them
-: 145: when we destroy a request */
-: 146: /* FIXME: We need a way to call these routines ONLY when the
-: 147: related ref count has become zero. */
|
20967117: 148: if (req->comm != NULL) {
20387127: 149: MPIR_Comm_release(req->comm, 0);
-: 150: }
-: 151:
20967117: 152: if (req->dev.datatype_ptr != NULL) {
448917: 153: MPID_Datatype_release(req->dev.datatype_ptr);
-: 154: }
-: 155:
20967117: 156: if (req->dev.segment_ptr != NULL) {
520991: 157: MPID_Segment_free(req->dev.segment_ptr);
-: 158: }
-: 159:
20967117: 160: if (MPIDI_Request_get_srbuf_flag(req)) {
251345: 161: MPIDI_CH3U_SRBuf_free(req);
-: 162: }
-: 163:
20967117: 164: MPIU_Handle_obj_free(&MPID_Request_mem, req);
-: 165:
|
-: 166: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3_REQUEST_DESTROY);
|
20967117: 167:}
-: 168:
-: 169:
-: 170:/* ------------------------------------------------------------------------- */
-: 171:/* Here are the routines to manipulate the iovs in the requests */
-: 172:/* ------------------------------------------------------------------------- */
-: 173:
-: 174:
-: 175:
-: 176:/*
-: 177: * MPIDI_CH3U_Request_load_send_iov()
-: 178: *
-: 179: * Fill the provided IOV with the next (or remaining) portion of data described
-: 180: * by the segment contained in the request structure.
-: 181: * If the density of IOV is not sufficient, pack the data into a send/receive
-: 182: * buffer and point the IOV at the buffer.
-: 183: *
-: 184: * Expects sreq->dev.OnFinal to be initialized (even if it's NULL).
-: 185: */
-: 186:#undef FUNCNAME
-: 187:#define FUNCNAME MPIDI_CH3U_Request_load_send_iov
-: 188:#undef FCNAME
-: 189:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 190:int MPIDI_CH3U_Request_load_send_iov(MPID_Request * const sreq,
-: 191: MPID_IOV * const iov, int * const iov_n)
388925: 192:{
-: 193: MPI_Aint last;
388925: 194: int mpi_errno = MPI_SUCCESS;
-: 195: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);
-: 196:
-: 197: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);
388925: 198: MPIU_Assert(sreq->dev.segment_ptr != NULL);
388925: 199: last = sreq->dev.segment_size;
-: 200: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 201: "pre-pv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d",
-: 202: sreq->dev.segment_first, last, *iov_n));
388925: 203: MPIU_Assert(sreq->dev.segment_first < last);
388925: 204: MPIU_Assert(last > 0);
388925: 205: MPIU_Assert(*iov_n > 0 && *iov_n <= MPID_IOV_LIMIT);
388925: 206: MPID_Segment_pack_vector(sreq->dev.segment_ptr, sreq->dev.segment_first,
-: 207: &last, iov, iov_n);
-: 208: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 209: "post-pv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d",
-: 210: sreq->dev.segment_first, last, *iov_n));
388925: 211: MPIU_Assert(*iov_n > 0 && *iov_n <= MPID_IOV_LIMIT);
-: 212:
388925: 213: if (last == sreq->dev.segment_size)
-: 214: {
-: 215: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"remaining data loaded into IOV");
214759: 216: sreq->dev.OnDataAvail = sreq->dev.OnFinal;
-: 217: }
174166: 218: else if ((last - sreq->dev.segment_first) / *iov_n >= MPIDI_IOV_DENSITY_MIN)
-: 219: {
-: 220: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"more data loaded into IOV");
2: 221: sreq->dev.segment_first = last;
2: 222: sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV;
-: 223: }
-: 224: else
-: 225: {
-: 226: MPIDI_msg_sz_t data_sz;
-: 227: int i, iov_data_copied;
-: 228:
-: 229: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"low density. using SRBuf.");
-: 230:
174164: 231: data_sz = sreq->dev.segment_size - sreq->dev.segment_first;
174164: 232: if (!MPIDI_Request_get_srbuf_flag(sreq))
-: 233: {
173966: 234: MPIDI_CH3U_SRBuf_alloc(sreq, data_sz);
|
-: 235: /* --BEGIN ERROR HANDLING-- */
173966: 236: if (sreq->dev.tmpbuf_sz == 0)
-: 237: {
-: 238: MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"SRBuf allocation failure");
#####: 239: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 240: FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);
#####: 241: sreq->status.MPI_ERROR = mpi_errno;
#####: 242: goto fn_exit;
-: 243: }
-: 244: /* --END ERROR HANDLING-- */
-: 245: }
-: 246:
|
174164: 247: iov_data_copied = 0;
2786822: 248: for (i = 0; i < *iov_n; i++) {
2612658: 249: MPIU_Memcpy((char*) sreq->dev.tmpbuf + iov_data_copied,
-: 250: iov[i].MPID_IOV_BUF, iov[i].MPID_IOV_LEN);
2612658: 251: iov_data_copied += iov[i].MPID_IOV_LEN;
-: 252: }
174164: 253: sreq->dev.segment_first = last;
-: 254:
174164: 255: last = (data_sz <= sreq->dev.tmpbuf_sz - iov_data_copied) ?
-: 256: sreq->dev.segment_size :
-: 257: sreq->dev.segment_first + sreq->dev.tmpbuf_sz - iov_data_copied;
-: 258: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 259: "pre-pack: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT,
-: 260: sreq->dev.segment_first, last));
174164: 261: MPID_Segment_pack(sreq->dev.segment_ptr, sreq->dev.segment_first,
-: 262: &last, (char*) sreq->dev.tmpbuf + iov_data_copied);
-: 263: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 264: "post-pack: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT,
-: 265: sreq->dev.segment_first, last));
174164: 266: iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)sreq->dev.tmpbuf;
174164: 267: iov[0].MPID_IOV_LEN = last - sreq->dev.segment_first + iov_data_copied;
174164: 268: *iov_n = 1;
174164: 269: if (last == sreq->dev.segment_size)
-: 270: {
-: 271: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"remaining data packed into SRBuf");
173966: 272: sreq->dev.OnDataAvail = sreq->dev.OnFinal;
-: 273: }
-: 274: else
-: 275: {
-: 276: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"more data packed into SRBuf");
198: 277: sreq->dev.segment_first = last;
198: 278: sreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_SendReloadIOV;
-: 279: }
-: 280: }
-: 281:
388925: 282: fn_exit:
|
-: 283: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_SEND_IOV);
|
388925: 284: return mpi_errno;
-: 285:}
-: 286:
-: 287:/*
-: 288: * MPIDI_CH3U_Request_load_recv_iov()
-: 289: *
-: 290: * Fill the request's IOV with the next (or remaining) portion of data
-: 291: * described by the segment (also contained in the request
-: 292: * structure). If the density of IOV is not sufficient, allocate a
-: 293: * send/receive buffer and point the IOV at the buffer.
-: 294: */
-: 295:#undef FUNCNAME
-: 296:#define FUNCNAME MPIDI_CH3U_Request_load_recv_iov
-: 297:#undef FCNAME
-: 298:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 299:int MPIDI_CH3U_Request_load_recv_iov(MPID_Request * const rreq)
209843: 300:{
-: 301: MPI_Aint last;
209843: 302: int mpi_errno = MPI_SUCCESS;
-: 303: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_RECV_IOV);
-: 304:
-: 305: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_RECV_IOV);
209843: 306: if (rreq->dev.segment_first < rreq->dev.segment_size)
-: 307: {
-: 308: /* still reading data that needs to go into the user buffer */
-: 309:
209830: 310: if (MPIDI_Request_get_srbuf_flag(rreq))
-: 311: {
-: 312: MPIDI_msg_sz_t data_sz;
-: 313: MPIDI_msg_sz_t tmpbuf_sz;
-: 314:
-: 315: /* Once a SRBuf is in use, we continue to use it since a small
-: 316: amount of data may already be present at the beginning
-: 317: of the buffer. This data is left over from the previous unpack,
-: 318: most like a result of alignment issues. NOTE: we
-: 319: could force the use of the SRBuf only
-: 320: when (rreq->dev.tmpbuf_off > 0)... */
-: 321:
77579: 322: data_sz = rreq->dev.segment_size - rreq->dev.segment_first -
-: 323: rreq->dev.tmpbuf_off;
77579: 324: MPIU_Assert(data_sz > 0);
77579: 325: tmpbuf_sz = rreq->dev.tmpbuf_sz - rreq->dev.tmpbuf_off;
77579: 326: if (data_sz > tmpbuf_sz)
-: 327: {
213: 328: data_sz = tmpbuf_sz;
-: 329: }
77579: 330: rreq->dev.iov[0].MPID_IOV_BUF =
-: 331: (MPID_IOV_BUF_CAST)((char *) rreq->dev.tmpbuf +
-: 332: rreq->dev.tmpbuf_off);
77579: 333: rreq->dev.iov[0].MPID_IOV_LEN = data_sz;
77579: 334: rreq->dev.iov_offset = 0;
77579: 335: rreq->dev.iov_count = 1;
77579: 336: MPIU_Assert(rreq->dev.segment_first + data_sz +
-: 337: rreq->dev.tmpbuf_off <= rreq->dev.recv_data_sz);
77579: 338: if (rreq->dev.segment_first + data_sz + rreq->dev.tmpbuf_off ==
-: 339: rreq->dev.recv_data_sz)
-: 340: {
-: 341: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 342: "updating rreq to read the remaining data into the SRBuf");
77366: 343: rreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_UnpackSRBufComplete;
-: 344: }
-: 345: else
-: 346: {
-: 347: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 348: "updating rreq to read more data into the SRBuf");
213: 349: rreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_UnpackSRBufReloadIOV;
-: 350: }
-: 351: goto fn_exit;
-: 352: }
-: 353:
132251: 354: last = rreq->dev.segment_size;
132251: 355: rreq->dev.iov_count = MPID_IOV_LIMIT;
132251: 356: rreq->dev.iov_offset = 0;
-: 357: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 358: "pre-upv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d",
-: 359: rreq->dev.segment_first, last, rreq->dev.iov_count));
132251: 360: MPIU_Assert(rreq->dev.segment_first < last);
132251: 361: MPIU_Assert(last > 0);
132251: 362: MPID_Segment_unpack_vector(rreq->dev.segment_ptr,
-: 363: rreq->dev.segment_first,
-: 364: &last, &rreq->dev.iov[0], &rreq->dev.iov_count);
-: 365: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 366: "post-upv: first=" MPIDI_MSG_SZ_FMT ", last=" MPIDI_MSG_SZ_FMT ", iov_n=%d, iov_offset=%d",
-: 367: rreq->dev.segment_first, last, rreq->dev.iov_count, rreq->dev.iov_offset));
132251: 368: MPIU_Assert(rreq->dev.iov_count >= 0 && rreq->dev.iov_count <=
-: 369: MPID_IOV_LIMIT);
-: 370:
|
-: 371: /* --BEGIN ERROR HANDLING-- */
132251: 372: if (rreq->dev.iov_count == 0)
-: 373: {
-: 374: /* If the data can't be unpacked, the we have a mis-match between
-: 375: the datatype and the amount of data received. Adjust
-: 376: the segment info so that the remaining data is received and
-: 377: thrown away. */
1: 378: rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
-: 379: MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE,
-: 380: "**dtypemismatch", 0);
1: 381: rreq->status.count = (int)rreq->dev.segment_first;
1: 382: rreq->dev.segment_size = rreq->dev.segment_first;
1: 383: mpi_errno = MPIDI_CH3U_Request_load_recv_iov(rreq);
1: 384: goto fn_exit;
-: 385: }
-: 386: else
-: 387: {
132250: 388: MPIU_Assert(rreq->dev.iov_offset < rreq->dev.iov_count);
-: 389: }
-: 390: /* --END ERROR HANDLING-- */
-: 391:
|
132250: 392: if (last == rreq->dev.recv_data_sz)
-: 393: {
-: 394: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 395: "updating rreq to read the remaining data directly into the user buffer");
-: 396: /* Eventually, use OnFinal for this instead */
54871: 397: rreq->dev.OnDataAvail = 0;
-: 398: }
77392: 399: else if (last == rreq->dev.segment_size ||
-: 400: (last - rreq->dev.segment_first) / rreq->dev.iov_count >= MPIDI_IOV_DENSITY_MIN)
-: 401: {
-: 402: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 403: "updating rreq to read more data directly into the user buffer");
13: 404: rreq->dev.segment_first = last;
13: 405: rreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_ReloadIOV;
-: 406: }
-: 407: else
-: 408: {
-: 409: /* Too little data would have been received using an IOV.
-: 410: We will start receiving data into a SRBuf and unpacking it
-: 411: later. */
77366: 412: MPIU_Assert(MPIDI_Request_get_srbuf_flag(rreq) == FALSE);
-: 413:
77366: 414: MPIDI_CH3U_SRBuf_alloc(rreq,
-: 415: rreq->dev.segment_size - rreq->dev.segment_first);
77366: 416: rreq->dev.tmpbuf_off = 0;
|
-: 417: /* --BEGIN ERROR HANDLING-- */
77366: 418: if (rreq->dev.tmpbuf_sz == 0)
-: 419: {
-: 420: /* FIXME - we should drain the data off the pipe here, but we
-: 421: don't have a buffer to drain it into. should this be
-: 422: a fatal error? */
-: 423: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,"SRBuf allocation failure");
#####: 424: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 425: FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);
#####: 426: rreq->status.MPI_ERROR = mpi_errno;
#####: 427: goto fn_exit;
-: 428: }
-: 429: /* --END ERROR HANDLING-- */
-: 430:
-: 431: /* fill in the IOV using a recursive call */
|
77366: 432: mpi_errno = MPIDI_CH3U_Request_load_recv_iov(rreq);
-: 433: }
-: 434: }
-: 435: else
-: 436: {
-: 437: /* receive and toss any extra data that does not fit in the user's
-: 438: buffer */
-: 439: MPIDI_msg_sz_t data_sz;
-: 440:
13: 441: data_sz = rreq->dev.recv_data_sz - rreq->dev.segment_first;
13: 442: if (!MPIDI_Request_get_srbuf_flag(rreq))
-: 443: {
13: 444: MPIDI_CH3U_SRBuf_alloc(rreq, data_sz);
|
-: 445: /* --BEGIN ERROR HANDLING-- */
13: 446: if (rreq->dev.tmpbuf_sz == 0)
-: 447: {
-: 448: MPIU_DBG_MSG(CH3_CHANNEL,TYPICAL,"SRBuf allocation failure");
#####: 449: mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL,
-: 450: FCNAME, __LINE__, MPI_ERR_OTHER, "**nomem", 0);
#####: 451: rreq->status.MPI_ERROR = mpi_errno;
#####: 452: goto fn_exit;
-: 453: }
-: 454: /* --END ERROR HANDLING-- */
-: 455: }
-: 456:
|
13: 457: if (data_sz <= rreq->dev.tmpbuf_sz)
-: 458: {
-: 459: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 460: "updating rreq to read overflow data into the SRBuf and complete");
13: 461: rreq->dev.iov[0].MPID_IOV_LEN = data_sz;
13: 462: MPIU_Assert(MPIDI_Request_get_type(rreq) == MPIDI_REQUEST_TYPE_RECV);
-: 463: /* Eventually, use OnFinal for this instead */
13: 464: rreq->dev.OnDataAvail = 0;
-: 465: }
-: 466: else
-: 467: {
-: 468: MPIU_DBG_MSG(CH3_CHANNEL,VERBOSE,
-: 469: "updating rreq to read overflow data into the SRBuf and reload IOV");
|
#####: 470: rreq->dev.iov[0].MPID_IOV_LEN = rreq->dev.tmpbuf_sz;
#####: 471: rreq->dev.segment_first += rreq->dev.tmpbuf_sz;
#####: 472: rreq->dev.OnDataAvail = MPIDI_CH3_ReqHandler_ReloadIOV;
-: 473: }
-: 474:
|
13: 475: rreq->dev.iov[0].MPID_IOV_BUF = (MPID_IOV_BUF_CAST)rreq->dev.tmpbuf;
13: 476: rreq->dev.iov_count = 1;
-: 477: }
-: 478:
209843: 479: fn_exit:
|
-: 480: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_REQUEST_LOAD_RECV_IOV);
|
209843: 481: return mpi_errno;
-: 482:}
-: 483:
-: 484:/*
-: 485: * MPIDI_CH3U_Request_unpack_srbuf
-: 486: *
-: 487: * Unpack data from a send/receive buffer into the user buffer.
-: 488: */
-: 489:#undef FUNCNAME
-: 490:#define FUNCNAME MPIDI_CH3U_Request_unpack_srbuf
-: 491:#undef FCNAME
-: 492:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 493:int MPIDI_CH3U_Request_unpack_srbuf(MPID_Request * rreq)
77579: 494:{
-: 495: MPI_Aint last;
-: 496: int tmpbuf_last;
77579: 497: int mpi_errno = MPI_SUCCESS;
-: 498: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_SRBUF);
-: 499:
-: 500: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_SRBUF);
-: 501:
77579: 502: tmpbuf_last = (int)(rreq->dev.segment_first + rreq->dev.tmpbuf_sz);
77579: 503: if (rreq->dev.segment_size < tmpbuf_last)
-: 504: {
77202: 505: tmpbuf_last = (int)rreq->dev.segment_size;
-: 506: }
77579: 507: last = tmpbuf_last;
77579: 508: MPID_Segment_unpack(rreq->dev.segment_ptr, rreq->dev.segment_first,
-: 509: &last, rreq->dev.tmpbuf);
77579: 510: if (last == 0 || last == rreq->dev.segment_first)
-: 511: {
|
-: 512: /* --BEGIN ERROR HANDLING-- */
-: 513: /* If no data can be unpacked, then we have a datatype processing
-: 514: problem. Adjust the segment info so that the remaining
-: 515: data is received and thrown away. */
#####: 516: rreq->status.count = (int)rreq->dev.segment_first;
#####: 517: rreq->dev.segment_size = rreq->dev.segment_first;
#####: 518: rreq->dev.segment_first += tmpbuf_last;
#####: 519: rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
-: 520: MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE,
-: 521: "**dtypemismatch", 0);
-: 522: /* --END ERROR HANDLING-- */
-: 523: }
|
77579: 524: else if (tmpbuf_last == rreq->dev.segment_size)
-: 525: {
|
-: 526: /* --BEGIN ERROR HANDLING-- */
77366: 527: if (last != tmpbuf_last)
-: 528: {
-: 529: /* received data was not entirely consumed by unpack() because too
-: 530: few bytes remained to fill the next basic datatype.
-: 531: Note: the segment_first field is set to segment_last so that if
-: 532: this is a truncated message, extra data will be read
-: 533: off the pipe. */
#####: 534: rreq->status.count = (int)last;
#####: 535: rreq->dev.segment_size = last;
#####: 536: rreq->dev.segment_first = tmpbuf_last;
#####: 537: rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
-: 538: MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE,
-: 539: "**dtypemismatch", 0);
-: 540: }
-: 541: /* --END ERROR HANDLING-- */
-: 542: }
-: 543: else
-: 544: {
|
213: 545: rreq->dev.tmpbuf_off = (int)(tmpbuf_last - last);
213: 546: if (rreq->dev.tmpbuf_off > 0)
-: 547: {
-: 548: /* move any remaining data to the beginning of the buffer.
-: 549: Note: memmove() is used since the data regions could
-: 550: overlap. */
|
#####: 551: memmove(rreq->dev.tmpbuf, (char *) rreq->dev.tmpbuf +
-: 552: (last - rreq->dev.segment_first), rreq->dev.tmpbuf_off);
-: 553: }
|
213: 554: rreq->dev.segment_first = last;
-: 555: }
-: 556:
|
-: 557: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_SRBUF);
|
77579: 558: return mpi_errno;
-: 559:}
-: 560:
-: 561:/*
-: 562: * MPIDI_CH3U_Request_unpack_uebuf
-: 563: *
-: 564: * Copy/unpack data from an "unexpected eager buffer" into the user buffer.
-: 565: */
-: 566:#undef FUNCNAME
-: 567:#define FUNCNAME MPIDI_CH3U_Request_unpack_uebuf
-: 568:#undef FCNAME
-: 569:#define FCNAME MPIDI_QUOTE(FUNCNAME)
-: 570:int MPIDI_CH3U_Request_unpack_uebuf(MPID_Request * rreq)
1119858: 571:{
-: 572: int dt_contig;
-: 573: MPI_Aint dt_true_lb;
-: 574: MPIDI_msg_sz_t userbuf_sz;
-: 575: MPID_Datatype * dt_ptr;
-: 576: MPIDI_msg_sz_t unpack_sz;
1119858: 577: int mpi_errno = MPI_SUCCESS;
-: 578: MPIDI_STATE_DECL(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_UEBUF);
-: 579: MPIDI_STATE_DECL(MPID_STATE_MEMCPY);
-: 580:
-: 581: MPIDI_FUNC_ENTER(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_UEBUF);
-: 582:
1119858: 583: MPIDI_Datatype_get_info(rreq->dev.user_count, rreq->dev.datatype,
-: 584: dt_contig, userbuf_sz, dt_ptr, dt_true_lb);
-: 585:
1119858: 586: if (rreq->dev.recv_data_sz <= userbuf_sz)
-: 587: {
1119857: 588: unpack_sz = rreq->dev.recv_data_sz;
-: 589: }
-: 590: else
-: 591: {
|
-: 592: /* --BEGIN ERROR HANDLING-- */
-: 593: MPIU_DBG_MSG_FMT(CH3_CHANNEL,VERBOSE,(MPIU_DBG_FDEST,
-: 594: "receive buffer overflow; message truncated, msg_sz=" MPIDI_MSG_SZ_FMT
-: 595: ", buf_sz=" MPIDI_MSG_SZ_FMT,
-: 596: rreq->dev.recv_data_sz, userbuf_sz));
1: 597: unpack_sz = userbuf_sz;
1: 598: rreq->status.count = (int)userbuf_sz;
1: 599: rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
-: 600: MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TRUNCATE,
-: 601: "**truncate", "**truncate %d %d",
-: 602: rreq->dev.recv_data_sz, userbuf_sz);
-: 603: /* --END ERROR HANDLING-- */
-: 604: }
-: 605:
|
1119858: 606: if (unpack_sz > 0)
-: 607: {
1119858: 608: if (dt_contig)
-: 609: {
-: 610: /* TODO - check that amount of data is consistent with datatype.
-: 611: In other words, if we were to use Segment_unpack()
-: 612: would last = unpack? If not we should return an error
-: 613: (unless configured with --enable-fast) */
-: 614: MPIDI_FUNC_ENTER(MPID_STATE_MEMCPY);
1119325: 615: MPIU_Memcpy((char *)rreq->dev.user_buf + dt_true_lb, rreq->dev.tmpbuf,
-: 616: unpack_sz);
|
-: 617: MPIDI_FUNC_EXIT(MPID_STATE_MEMCPY);
-: 618: }
-: 619: else
-: 620: {
-: 621: MPID_Segment seg;
-: 622: MPI_Aint last;
-: 623:
|
533: 624: MPID_Segment_init(rreq->dev.user_buf, rreq->dev.user_count,
-: 625: rreq->dev.datatype, &seg, 0);
533: 626: last = unpack_sz;
533: 627: MPID_Segment_unpack(&seg, 0, &last, rreq->dev.tmpbuf);
533: 628: if (last != unpack_sz)
-: 629: {
|
-: 630: /* --BEGIN ERROR HANDLING-- */
-: 631: /* received data was not entirely consumed by unpack()
-: 632: because too few bytes remained to fill the next basic
-: 633: datatype */
#####: 634: rreq->status.count = (int)last;
#####: 635: rreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS,
-: 636: MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_TYPE,
-: 637: "**dtypemismatch", 0);
-: 638: /* --END ERROR HANDLING-- */
-: 639: }
-: 640: }
-: 641: }
-: 642:
-: 643: MPIDI_FUNC_EXIT(MPID_STATE_MPIDI_CH3U_REQUEST_UNPACK_UEBUF);
|
1119858: 644: return mpi_errno;
-: 645:}
-: 646:
-: 647:/*
-: 648: * Export the function to set a request as completed for use by
-: 649: * the generalized request functions in mpich2/src/pt2pt/greq_complete.c
-: 650: */
-: 651:void MPID_Request_set_completed( MPID_Request *req )
532445: 652:{
532445: 653: MPID_REQUEST_SET_COMPLETED(req);
532445: 654:}
|