1 /*
2 * Copyright (C) by Argonne National Laboratory
3 * See COPYRIGHT in top-level directory
4 */
5
6 #ifndef CH4R_RECV_H_INCLUDED
7 #define CH4R_RECV_H_INCLUDED
8
9 #include "ch4_impl.h"
10
MPIDIG_reply_ssend(MPIR_Request * rreq)11 MPL_STATIC_INLINE_PREFIX int MPIDIG_reply_ssend(MPIR_Request * rreq)
12 {
13 int mpi_errno = MPI_SUCCESS;
14 MPIDIG_ssend_ack_msg_t ack_msg;
15 MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDIG_REPLY_SSEND);
16 MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDIG_REPLY_SSEND);
17 ack_msg.sreq_ptr = MPIDIG_REQUEST(rreq, req->rreq.peer_req_ptr);
18
19 #ifndef MPIDI_CH4_DIRECT_NETMOD
20 if (MPIDI_REQUEST(rreq, is_local))
21 mpi_errno =
22 MPIDI_SHM_am_send_hdr_reply(MPIDIG_REQUEST(rreq, context_id),
23 MPIDIG_REQUEST(rreq, rank), MPIDIG_SSEND_ACK, &ack_msg,
24 sizeof(ack_msg));
25 else
26 #endif
27 {
28 mpi_errno =
29 MPIDI_NM_am_send_hdr_reply(MPIDIG_REQUEST(rreq, context_id),
30 MPIDIG_REQUEST(rreq, rank), MPIDIG_SSEND_ACK, &ack_msg,
31 sizeof(ack_msg));
32 }
33
34 MPIR_ERR_CHECK(mpi_errno);
35 fn_exit:
36 MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDIG_REPLY_SSEND);
37 return mpi_errno;
38 fn_fail:
39 goto fn_exit;
40 }
41
42
MPIDIG_handle_unexp_mrecv(MPIR_Request * rreq)43 MPL_STATIC_INLINE_PREFIX int MPIDIG_handle_unexp_mrecv(MPIR_Request * rreq)
44 {
45 int mpi_errno = MPI_SUCCESS;
46 size_t message_sz;
47 int dt_contig;
48 MPI_Aint dt_true_lb;
49 MPIR_Datatype *dt_ptr;
50 size_t data_sz ATTRIBUTE((unused)), dt_sz, nbytes;
51 void *buf;
52 MPI_Aint count;
53 MPI_Datatype datatype;
54
55 MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPIDIG_HANDLE_UNEXP_MRECV);
56 MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPIDIG_HANDLE_UNEXP_MRECV);
57
58 rreq->status.MPI_SOURCE = MPIDIG_REQUEST(rreq, rank);
59 rreq->status.MPI_TAG = MPIDIG_REQUEST(rreq, tag);
60
61 buf = MPIDIG_REQUEST(rreq, req->rreq.mrcv_buffer);
62 count = MPIDIG_REQUEST(rreq, req->rreq.mrcv_count);
63 datatype = MPIDIG_REQUEST(rreq, req->rreq.mrcv_datatype);
64
65 message_sz = MPIDIG_REQUEST(rreq, count);
66 MPIR_Datatype_get_size_macro(datatype, dt_sz);
67
68 if (message_sz > count * dt_sz) {
69 rreq->status.MPI_ERROR = MPIR_Err_create_code(rreq->status.MPI_ERROR,
70 MPIR_ERR_RECOVERABLE, __FUNCTION__, __LINE__,
71 MPI_ERR_TRUNCATE, "**truncate",
72 "**truncate %d %d %d %d",
73 rreq->status.MPI_SOURCE, rreq->status.MPI_TAG,
74 dt_sz * count, message_sz);
75 nbytes = dt_sz * count;
76 } else {
77 nbytes = message_sz;
78 }
79
80 MPIR_STATUS_SET_COUNT(rreq->status, nbytes);
81 MPIDI_Datatype_get_info(count, datatype, dt_contig, data_sz, dt_ptr, dt_true_lb);
82
83 if (!dt_contig) {
84 MPI_Aint actual_unpack_bytes;
85 mpi_errno = MPIR_Typerep_unpack(MPIDIG_REQUEST(rreq, buffer), nbytes, buf,
86 count, datatype, 0, &actual_unpack_bytes);
87 MPIR_ERR_CHECK(mpi_errno);
88
89 if (actual_unpack_bytes != (MPI_Aint) nbytes) {
90 mpi_errno = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
91 __FUNCTION__, __LINE__,
92 MPI_ERR_TYPE, "**dtypemismatch", 0);
93 rreq->status.MPI_ERROR = mpi_errno;
94 }
95 } else {
96 MPIR_Typerep_copy((char *) buf + dt_true_lb, MPIDIG_REQUEST(rreq, buffer), nbytes);
97 }
98
99 MPIDU_genq_private_pool_free_cell(MPIDI_global.unexp_pack_buf_pool,
100 MPIDIG_REQUEST(rreq, buffer));
101 rreq->kind = MPIR_REQUEST_KIND__RECV;
102
103 if (MPIDIG_REQUEST(rreq, req->status) & MPIDIG_REQ_PEER_SSEND) {
104 mpi_errno = MPIDIG_reply_ssend(rreq);
105 MPIR_ERR_CHECK(mpi_errno);
106 }
107 MPIR_Datatype_release_if_not_builtin(datatype);
108 MPID_Request_complete(rreq);
109
110 fn_exit:
111 MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPIDIG_HANDLE_UNEXP_MRECV);
112 return mpi_errno;
113 fn_fail:
114 goto fn_exit;
115 }
116 #endif /* CH4R_RECV_H_INCLUDED */
117