minor fixes in ditribution files
[gromacs/qmmm-gamess-us.git] / src / gmxlib / thread_mpi / p2p_send_recv.c
blobe044aecc2f0941b00e59ab76b4ac085f9f2ad421
1 /*
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.
6 All rights reserved.
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
35 files.
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)
46 struct envelope *sev;
47 struct tmpi_thread *send_dst=tMPI_Get_thread(comm, dest);
48 struct tmpi_thread *cur=tMPI_Get_current();
49 struct tmpi_req_ req;
51 #ifdef TMPI_PROFILE
52 tMPI_Profile_count_start(cur);
53 #endif
54 #ifdef TMPI_TRACE
55 tMPI_Trace_print("tMPI_Send(%p, %d, %p, %d, %d, %p)", buf, count,
56 datatype, dest, tag, comm);
57 #endif
58 if (!comm)
60 return tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_COMM);
62 if (!send_dst)
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);
71 #ifdef TMPI_PROFILE
72 tMPI_Profile_count_stop(cur,TMPIFN_Send);
73 #endif
74 return req.error;
80 int tMPI_Recv(void* buf, int count, tMPI_Datatype datatype, int source,
81 int tag, tMPI_Comm comm, tMPI_Status *status)
83 struct envelope *rev;
84 struct tmpi_thread *recv_src=0;
85 struct tmpi_thread *cur=tMPI_Get_current();
86 struct tmpi_req_ req;
88 #ifdef TMPI_PROFILE
89 tMPI_Profile_count_start(cur);
90 #endif
91 #ifdef TMPI_TRACE
92 tMPI_Trace_print("tMPI_Recv(%p, %d, %p, %d, %d, %p, %p)", buf, count,
93 datatype, source, tag, comm, status);
94 #endif
95 if (!comm)
97 return tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_COMM);
100 if (source!=TMPI_ANY_SOURCE)
102 recv_src=tMPI_Get_thread(comm, source);
103 if (!recv_src)
105 return tMPI_Error(comm, TMPI_ERR_RECV_SRC);
109 rev=tMPI_Post_match_recv(cur, comm, recv_src, buf, count, datatype, tag,
110 FALSE);
111 tMPI_Req_init(&req, rev);
112 tMPI_Wait_single(cur, &req);
114 tMPI_Set_status(&req, status);
115 #ifdef TMPI_PROFILE
116 tMPI_Profile_count_stop(cur, TMPIFN_Recv);
117 #endif
118 return req.error;
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;
137 #ifdef TMPI_PROFILE
138 tMPI_Profile_count_start(cur);
139 #endif
140 #ifdef TMPI_TRACE
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);
144 #endif
145 if (!comm)
147 return tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_COMM);
149 if (!send_dst)
151 return tMPI_Error(comm, TMPI_ERR_SEND_DEST);
153 if (source!=TMPI_ANY_SOURCE)
155 recv_src=tMPI_Get_thread(comm, source);
156 if (!recv_src)
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 */
172 sreq.next=&rreq;
173 sreq.prev=NULL;
174 rreq.prev=&sreq;
175 rreq.next=NULL;
177 /* and wait for our requests */
180 if (tMPI_Test_multi(cur, &sreq, NULL))
181 break;
182 tMPI_Wait_process_incoming(cur);
183 } while(TRUE);
185 #ifdef TMPI_PROFILE
186 tMPI_Profile_count_stop(cur, TMPIFN_Sendrecv);
187 #endif
189 tMPI_Set_status(&rreq, status);
190 ret=sreq.error;
191 if (rreq.error != TMPI_SUCCESS)
192 ret=rreq.error;
194 return ret;
201 /* async */
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);
210 struct envelope *ev;
212 #ifdef TMPI_PROFILE
213 tMPI_Profile_count_start(cur);
214 #endif
215 #ifdef TMPI_TRACE
216 tMPI_Trace_print("tMPI_Isend(%p, %d, %p, %d, %d, %p, %p)", buf, count,
217 datatype, dest, tag, comm, request);
218 #endif
219 if (!comm)
221 tMPI_Return_req(rql,rq);
222 return tMPI_Error(TMPI_COMM_WORLD, TMPI_ERR_COMM);
224 if (!send_dst)
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);
231 *request=rq;
233 #ifdef TMPI_PROFILE
234 tMPI_Profile_count_stop(cur, TMPIFN_Isend);
235 #endif
236 return ev->error;
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;
247 struct envelope *ev;
249 #ifdef TMPI_PROFILE
250 tMPI_Profile_count_start(cur);
251 #endif
252 #ifdef TMPI_TRACE
253 tMPI_Trace_print("tMPI_Irecv(%p, %d, %p, %d, %d, %p, %p)", buf, count,
254 datatype, source, tag, comm, request);
255 #endif
256 if (!comm)
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);
265 if (!recv_src)
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,
272 TRUE);
273 tMPI_Req_init(rq, ev);
274 *request=rq;
275 #ifdef TMPI_PROFILE
276 tMPI_Profile_count_stop(cur, TMPIFN_Irecv);
277 #endif
278 return ev->error;