mpidi_isend_self.c 4.37 KB
Newer Older
1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

#include "mpidimpl.h"

/* FIXME: Explain this function */

/* FIXME: should there be a simpler version of this for short messages, 
   particularly contiguous ones?  See also the FIXME about buffering
   short messages */

#undef FUNCNAME
#define FUNCNAME MPIDI_Isend_self
#undef FCNAME
#define FCNAME MPIDI_QUOTE(FUNCNAME)
int MPIDI_Isend_self(const void * buf, int count, MPI_Datatype datatype, int rank, int tag, MPID_Comm * comm, int context_offset,
		     int type, MPID_Request ** request)
{
    MPIDI_Message_match match;
    MPID_Request * sreq;
    MPID_Request * rreq;
    MPIDI_VC_t * vc;
#if defined(MPID_USE_SEQUENCE_NUMBERS)
    MPID_Seqnum_t seqnum;
#endif    
    int found;
    int mpi_errno = MPI_SUCCESS;
	
    MPIU_DBG_MSG(CH3_OTHER,VERBOSE,"sending message to self");
	
    MPIDI_Request_create_sreq(sreq, mpi_errno, goto fn_exit);
    MPIDI_Request_set_type(sreq, type);
    MPIDI_Request_set_msg_type(sreq, MPIDI_REQUEST_SELF_MSG);
    
38
39
40
    match.parts.rank = rank;
    match.parts.tag = tag;
    match.parts.context_id = comm->context_id + context_offset;
41
42
43

    MPIU_THREAD_CS_ENTER(MSGQUEUE,);

44
45
46
47
48
49
50
    rreq = MPIDI_CH3U_Recvq_FDP_or_AEU(&match, &found);
    /* --BEGIN ERROR HANDLING-- */
    if (rreq == NULL)
    {
	MPIU_Object_set_ref(sreq, 0);
	MPIDI_CH3_Request_destroy(sreq);
	sreq = NULL;
51
52
        MPIU_ERR_SET1(mpi_errno, MPI_ERR_OTHER, "**nomem", 
		      "**nomemuereq %d", MPIDI_CH3U_Recvq_count_unexp());
53
54
55
56
	goto fn_exit;
    }
    /* --END ERROR HANDLING-- */

57
    MPIDI_Comm_get_vc_set_active(comm, rank, &vc);
58
59
60
61
62
63
64
65
66
67
68
    MPIDI_VC_FAI_send_seqnum(vc, seqnum);
    MPIDI_Request_set_seqnum(sreq, seqnum);
    MPIDI_Request_set_seqnum(rreq, seqnum);
    
    rreq->status.MPI_SOURCE = rank;
    rreq->status.MPI_TAG = tag;
    
    if (found)
    {
	MPIDI_msg_sz_t data_sz;
	
69
70
71
        /* we found a posted req, which we now own, so we can release the CS */
        MPIU_THREAD_CS_EXIT(MSGQUEUE,);

72
73
74
75
76
	MPIU_DBG_MSG(CH3_OTHER,VERBOSE,
		     "found posted receive request; copying data");
	    
	MPIDI_CH3U_Buffer_copy(buf, count, datatype, &sreq->status.MPI_ERROR,
			       rreq->dev.user_buf, rreq->dev.user_count, rreq->dev.datatype, &data_sz, &rreq->status.MPI_ERROR);
77
	MPIR_STATUS_SET_COUNT(rreq->status, data_sz);
78
79
80
81
	MPID_REQUEST_SET_COMPLETED(rreq);
	MPID_Request_release(rreq);
	/* sreq has never been seen by the user or outside this thread, so it is safe to reset ref_count and cc */
	MPIU_Object_set_ref(sreq, 1);
82
        MPID_cc_set(&sreq->cc, 0);
83
84
85
86
87
    }
    else
    {
	if (type != MPIDI_REQUEST_TYPE_RSEND)
	{
88
	    MPI_Aint dt_sz;
89
90
91
92
93
94
95
96
97
98
99
100
101
	
	    /* FIXME: Insert code here to buffer small sends in a temporary buffer? */

	    MPIU_DBG_MSG(CH3_OTHER,VERBOSE,
          "added receive request to unexpected queue; attaching send request");
	    if (HANDLE_GET_KIND(datatype) != HANDLE_KIND_BUILTIN)
	    {
		MPID_Datatype_get_ptr(datatype, sreq->dev.datatype_ptr);
		MPID_Datatype_add_ref(sreq->dev.datatype_ptr);
	    }
	    rreq->partner_request = sreq;
	    rreq->dev.sender_req_id = sreq->handle;
	    MPID_Datatype_get_size_macro(datatype, dt_sz);
Pavan Balaji's avatar
Pavan Balaji committed
102
	    MPIR_STATUS_SET_COUNT(rreq->status, count * dt_sz);
103
104
105
106
107
108
109
110
111
112
113
114
	}
	else
	{
	    /* --BEGIN ERROR HANDLING-- */
	    MPIU_DBG_MSG(CH3_OTHER,TYPICAL,
			 "ready send unable to find matching recv req");
	    sreq->status.MPI_ERROR = MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, FCNAME, __LINE__, MPI_ERR_OTHER,
							  "**rsendnomatch", "**rsendnomatch %d %d", rank, tag);
	    rreq->status.MPI_ERROR = sreq->status.MPI_ERROR;
	    
	    rreq->partner_request = NULL;
	    rreq->dev.sender_req_id = MPI_REQUEST_NULL;
Pavan Balaji's avatar
Pavan Balaji committed
115
	    MPIR_STATUS_SET_COUNT(rreq->status, 0);
116
117
118
	    
	    /* sreq has never been seen by the user or outside this thread, so it is safe to reset ref_count and cc */
	    MPIU_Object_set_ref(sreq, 1);
119
            MPID_cc_set(&sreq->cc, 0);
120
121
122
123
	    /* --END ERROR HANDLING-- */
	}
	    
	MPIDI_Request_set_msg_type(rreq, MPIDI_REQUEST_SELF_MSG);
124

125
126
127
        /* can release now that we've set fields in the unexpected request */
        MPIU_THREAD_CS_EXIT(MSGQUEUE,);

128
129
        /* kick the progress engine in case another thread that is performing a
           blocking recv or probe is waiting in the progress engine */
130
131
132
133
134
	MPIDI_CH3_Progress_signal_completion();
    }

  fn_exit:
    *request = sreq;
135

136
137
    return mpi_errno;
}