2 This source code file is part of thread_mpi.
3 Written by Sander Pronk, Erik Lindahl, and possibly others.
5 Copyright (c) 2009, Sander Pronk, Erik Lindahl.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10 1) Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 3) Neither the name of the copyright holders nor the
16 names of its contributors may be used to endorse or promote products
17 derived from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY US ''AS IS'' AND ANY
20 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL WE BE LIABLE FOR ANY
23 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 If you want to redistribute modifications, please consider that
31 scientific software is very special. Version control is crucial -
32 bugs must be traceable. We will be happy to consider code for
33 inclusion in the official distribution, but derived work should not
34 be called official thread_mpi. Details are found in the README & COPYING
38 /* this file is included from p2p.c */
41 /* point-to-point communication exported functions */
43 int tMPI_Send(void* buf
, int count
, tMPI_Datatype datatype
, int dest
,
44 int tag
, tMPI_Comm comm
)
47 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
48 struct tmpi_thread
*cur
=tMPI_Get_current();
52 tMPI_Profile_count_start(cur
);
55 tMPI_Trace_print("tMPI_Send(%p, %d, %p, %d, %d, %p)", buf
, count
,
56 datatype
, dest
, tag
, comm
);
60 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
64 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
67 sev
=tMPI_Post_send(cur
, comm
, send_dst
, buf
, count
, datatype
, tag
, FALSE
);
68 tMPI_Req_init(&req
, sev
);
69 tMPI_Wait_single(cur
, &req
);
72 tMPI_Profile_count_stop(cur
,TMPIFN_Send
);
80 int tMPI_Recv(void* buf
, int count
, tMPI_Datatype datatype
, int source
,
81 int tag
, tMPI_Comm comm
, tMPI_Status
*status
)
84 struct tmpi_thread
*recv_src
=0;
85 struct tmpi_thread
*cur
=tMPI_Get_current();
89 tMPI_Profile_count_start(cur
);
92 tMPI_Trace_print("tMPI_Recv(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
93 datatype
, source
, tag
, comm
, status
);
97 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
100 if (source
!=TMPI_ANY_SOURCE
)
102 recv_src
=tMPI_Get_thread(comm
, source
);
105 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
109 rev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, buf
, count
, datatype
, tag
,
111 tMPI_Req_init(&req
, rev
);
112 tMPI_Wait_single(cur
, &req
);
114 tMPI_Set_status(&req
, status
);
116 tMPI_Profile_count_stop(cur
, TMPIFN_Recv
);
125 int tMPI_Sendrecv(void *sendbuf
, int sendcount
, tMPI_Datatype sendtype
,
126 int dest
, int sendtag
, void *recvbuf
, int recvcount
,
127 tMPI_Datatype recvtype
, int source
, int recvtag
,
128 tMPI_Comm comm
, tMPI_Status
*status
)
130 struct envelope
*rev
, *sev
;
131 struct tmpi_thread
*cur
=tMPI_Get_current();
132 struct tmpi_thread
*recv_src
=0;
133 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
134 struct tmpi_req_ sreq
, rreq
;
135 int ret
=TMPI_SUCCESS
;
138 tMPI_Profile_count_start(cur
);
141 tMPI_Trace_print("tMPI_Sendrecv(%p, %d, %p, %d, %d, %p, %d, %p, %d, %d, %p, %p)",
142 sendbuf
, sendcount
, sendtype
, dest
, sendtag
, recvbuf
,
143 recvcount
, recvtype
, source
, recvtag
, comm
, status
);
147 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
151 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
153 if (source
!=TMPI_ANY_SOURCE
)
155 recv_src
=tMPI_Get_thread(comm
, source
);
158 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
162 /* we first prepare to send */
163 sev
=tMPI_Post_send(cur
, comm
, send_dst
, sendbuf
, sendcount
,
164 sendtype
, sendtag
, FALSE
);
165 tMPI_Req_init(&sreq
, sev
);
166 /* the we prepare to receive */
167 rev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, recvbuf
, recvcount
,
168 recvtype
, recvtag
, FALSE
);
169 tMPI_Req_init(&rreq
, rev
);
171 /* fix the pointers */
177 /* and wait for our requests */
180 if (tMPI_Test_multi(cur
, &sreq
, NULL
))
182 tMPI_Wait_process_incoming(cur
);
186 tMPI_Profile_count_stop(cur
, TMPIFN_Sendrecv
);
189 tMPI_Set_status(&rreq
, status
);
191 if (rreq
.error
!= TMPI_SUCCESS
)
203 int tMPI_Isend(void* buf
, int count
, tMPI_Datatype datatype
, int dest
,
204 int tag
, tMPI_Comm comm
, tMPI_Request
*request
)
206 struct tmpi_thread
*cur
=tMPI_Get_current();
207 struct req_list
*rql
=&(cur
->rql
);
208 struct tmpi_req_
*rq
=tMPI_Get_req(rql
);
209 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
213 tMPI_Profile_count_start(cur
);
216 tMPI_Trace_print("tMPI_Isend(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
217 datatype
, dest
, tag
, comm
, request
);
221 tMPI_Return_req(rql
,rq
);
222 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
226 tMPI_Return_req(rql
,rq
);
227 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
229 ev
=tMPI_Post_send(cur
, comm
, send_dst
, buf
, count
, datatype
, tag
, TRUE
);
230 tMPI_Req_init(rq
, ev
);
234 tMPI_Profile_count_stop(cur
, TMPIFN_Isend
);
240 int tMPI_Irecv(void* buf
, int count
, tMPI_Datatype datatype
, int source
,
241 int tag
, tMPI_Comm comm
, tMPI_Request
*request
)
243 struct tmpi_thread
*cur
=tMPI_Get_current();
244 struct req_list
*rql
=&(cur
->rql
);
245 struct tmpi_req_
*rq
=tMPI_Get_req(rql
);
246 struct tmpi_thread
*recv_src
=0;
250 tMPI_Profile_count_start(cur
);
253 tMPI_Trace_print("tMPI_Irecv(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
254 datatype
, source
, tag
, comm
, request
);
258 tMPI_Return_req(rql
,rq
);
259 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
262 if (source
!=TMPI_ANY_SOURCE
)
264 recv_src
=tMPI_Get_thread(comm
, source
);
267 tMPI_Return_req(rql
,rq
);
268 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
271 ev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, buf
, count
, datatype
, tag
,
273 tMPI_Req_init(rq
, ev
);
276 tMPI_Profile_count_stop(cur
, TMPIFN_Irecv
);