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 #ifdef HAVE_TMPI_CONFIG_H
39 #include "tmpi_config.h"
62 /* point-to-point communication exported functions */
64 int tMPI_Send(void* buf
, int count
, tMPI_Datatype datatype
, int dest
,
65 int tag
, tMPI_Comm comm
)
68 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
69 struct tmpi_thread
*cur
=tMPI_Get_current();
73 tMPI_Profile_count_start(cur
);
76 tMPI_Trace_print("tMPI_Send(%p, %d, %p, %d, %d, %p)", buf
, count
,
77 datatype
, dest
, tag
, comm
);
81 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
85 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
88 sev
=tMPI_Post_send(cur
, comm
, send_dst
, buf
, count
, datatype
, tag
, FALSE
);
89 tMPI_Req_init(&req
, sev
);
90 tMPI_Wait_single(cur
, &req
);
93 tMPI_Profile_count_stop(cur
,TMPIFN_Send
);
101 int tMPI_Recv(void* buf
, int count
, tMPI_Datatype datatype
, int source
,
102 int tag
, tMPI_Comm comm
, tMPI_Status
*status
)
104 struct envelope
*rev
;
105 struct tmpi_thread
*recv_src
=0;
106 struct tmpi_thread
*cur
=tMPI_Get_current();
107 struct tmpi_req_ req
;
110 tMPI_Profile_count_start(cur
);
113 tMPI_Trace_print("tMPI_Recv(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
114 datatype
, source
, tag
, comm
, status
);
118 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
121 if (source
!=TMPI_ANY_SOURCE
)
123 recv_src
=tMPI_Get_thread(comm
, source
);
126 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
130 rev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, buf
, count
, datatype
, tag
,
132 tMPI_Req_init(&req
, rev
);
133 tMPI_Wait_single(cur
, &req
);
135 tMPI_Set_status(&req
, status
);
137 tMPI_Profile_count_stop(cur
, TMPIFN_Recv
);
146 int tMPI_Sendrecv(void *sendbuf
, int sendcount
, tMPI_Datatype sendtype
,
147 int dest
, int sendtag
, void *recvbuf
, int recvcount
,
148 tMPI_Datatype recvtype
, int source
, int recvtag
,
149 tMPI_Comm comm
, tMPI_Status
*status
)
151 struct envelope
*rev
, *sev
;
152 struct tmpi_thread
*cur
=tMPI_Get_current();
153 struct tmpi_thread
*recv_src
=0;
154 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
155 struct tmpi_req_ sreq
, rreq
;
156 int ret
=TMPI_SUCCESS
;
159 tMPI_Profile_count_start(cur
);
162 tMPI_Trace_print("tMPI_Sendrecv(%p, %d, %p, %d, %d, %p, %d, %p, %d, %d, %p, %p)",
163 sendbuf
, sendcount
, sendtype
, dest
, sendtag
, recvbuf
,
164 recvcount
, recvtype
, source
, recvtag
, comm
, status
);
168 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
172 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
174 if (source
!=TMPI_ANY_SOURCE
)
176 recv_src
=tMPI_Get_thread(comm
, source
);
179 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
183 /* we first prepare to send */
184 sev
=tMPI_Post_send(cur
, comm
, send_dst
, sendbuf
, sendcount
,
185 sendtype
, sendtag
, FALSE
);
186 tMPI_Req_init(&sreq
, sev
);
187 /* the we prepare to receive */
188 rev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, recvbuf
, recvcount
,
189 recvtype
, recvtag
, FALSE
);
190 tMPI_Req_init(&rreq
, rev
);
192 /* fix the pointers */
198 /* and wait for our requests */
201 if (tMPI_Test_multi(cur
, &sreq
, NULL
))
203 tMPI_Wait_process_incoming(cur
);
207 tMPI_Profile_count_stop(cur
, TMPIFN_Sendrecv
);
210 tMPI_Set_status(&rreq
, status
);
212 if (rreq
.error
!= TMPI_SUCCESS
)
224 int tMPI_Isend(void* buf
, int count
, tMPI_Datatype datatype
, int dest
,
225 int tag
, tMPI_Comm comm
, tMPI_Request
*request
)
227 struct tmpi_thread
*cur
=tMPI_Get_current();
228 struct req_list
*rql
=&(cur
->rql
);
229 struct tmpi_req_
*rq
=tMPI_Get_req(rql
);
230 struct tmpi_thread
*send_dst
=tMPI_Get_thread(comm
, dest
);
234 tMPI_Profile_count_start(cur
);
237 tMPI_Trace_print("tMPI_Isend(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
238 datatype
, dest
, tag
, comm
, request
);
242 tMPI_Return_req(rql
,rq
);
243 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
247 tMPI_Return_req(rql
,rq
);
248 return tMPI_Error(comm
, TMPI_ERR_SEND_DEST
);
250 ev
=tMPI_Post_send(cur
, comm
, send_dst
, buf
, count
, datatype
, tag
, TRUE
);
251 tMPI_Req_init(rq
, ev
);
255 tMPI_Profile_count_stop(cur
, TMPIFN_Isend
);
261 int tMPI_Irecv(void* buf
, int count
, tMPI_Datatype datatype
, int source
,
262 int tag
, tMPI_Comm comm
, tMPI_Request
*request
)
264 struct tmpi_thread
*cur
=tMPI_Get_current();
265 struct req_list
*rql
=&(cur
->rql
);
266 struct tmpi_req_
*rq
=tMPI_Get_req(rql
);
267 struct tmpi_thread
*recv_src
=0;
271 tMPI_Profile_count_start(cur
);
274 tMPI_Trace_print("tMPI_Irecv(%p, %d, %p, %d, %d, %p, %p)", buf
, count
,
275 datatype
, source
, tag
, comm
, request
);
279 tMPI_Return_req(rql
,rq
);
280 return tMPI_Error(TMPI_COMM_WORLD
, TMPI_ERR_COMM
);
283 if (source
!=TMPI_ANY_SOURCE
)
285 recv_src
=tMPI_Get_thread(comm
, source
);
288 tMPI_Return_req(rql
,rq
);
289 return tMPI_Error(comm
, TMPI_ERR_RECV_SRC
);
292 ev
=tMPI_Post_match_recv(cur
, comm
, recv_src
, buf
, count
, datatype
, tag
,
294 tMPI_Req_init(rq
, ev
);
297 tMPI_Profile_count_stop(cur
, TMPIFN_Irecv
);