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