source: XIOS/dev/branch_yushan_merged/extern/src_ep_dev/ep_send.cpp @ 1160

Last change on this file since 1160 was 1147, checked in by yushan, 7 years ago

bug fixed in MPI_Gather(v)

File size: 9.8 KB
Line 
1/*!
2   \file ep_send.hpp
3   \since 2 may 2016
4
5   \brief Definitions of MPI send functions: MPI_Send, MPI_Ssend, MPI_Isend, MPI_Issend
6 */
7
8#include "ep_lib.hpp"
9#include <mpi.h>
10#include "ep_declaration.hpp"
11
12
13namespace ep_lib {
14
15
16  int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
17  {
18    if(!comm.is_ep)
19    {
20      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
21      ::MPI_Send(buf, count, static_cast< ::MPI_Datatype>(datatype), dest, tag, mpi_comm);
22      return 0;
23    }
24
25    MPI_Request request;
26    MPI_Status status;
27    MPI_Isend(buf, count, datatype, dest, tag, comm, &request);
28    MPI_Wait(&request, &status);
29
30    //check_sum_send(buf, count, datatype, dest, tag, comm);
31
32    return 0;
33  }
34
35
36  int MPI_Ssend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
37  {
38    if(!comm.is_ep)
39    {
40      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
41      ::MPI_Ssend(buf, count, static_cast< ::MPI_Datatype>(datatype), dest, tag, mpi_comm);
42      return 0;
43    }
44
45    MPI_Request request;
46    MPI_Status status;
47    MPI_Issend(buf, count, datatype, dest, tag, comm, &request);
48    MPI_Wait(&request, &status);
49    //check_sum_send(buf, count, datatype, dest, tag, comm);
50    return 0;
51  }
52
53
54
55  int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
56  {
57    Debug("\nMPI_Isend with EP\n");
58    int src_rank;
59    MPI_Comm_rank(comm, &src_rank);
60
61   
62
63    if(!comm.is_ep)
64    {
65      ::MPI_Request mpi_request;
66      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
67      ::MPI_Isend(buf, count, static_cast< ::MPI_Datatype> (datatype), dest, tag, mpi_comm, &mpi_request);
68
69      request->mpi_request = mpi_request;
70
71      request->ep_src = src_rank;
72      request->ep_tag = tag;
73      request->ep_datatype = datatype;
74      request->type = 1;
75      request->comm = comm;
76
77      return 0;
78    }
79
80    if(comm.is_intercomm) return MPI_Isend_intercomm(buf, count, datatype, dest, tag, comm, request);
81
82    // EP intracomm
83
84    //check_sum_send(buf, count, datatype, dest, tag, comm, 1);
85
86    int ep_src_loc = comm.ep_comm_ptr->size_rank_info[1].first;
87    int ep_dest_loc = comm.ep_comm_ptr->comm_list->rank_map->at(dest).first;
88    int mpi_tag                 = tag_combine(tag, ep_src_loc, ep_dest_loc);
89    int mpi_dest        = comm.ep_comm_ptr->comm_list->rank_map->at(dest).second;
90
91    request->ep_src  = src_rank;
92    request->ep_tag  = tag;
93    request->ep_datatype = datatype;
94
95    ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm> (comm.mpi_comm);
96    ::MPI_Request mpi_request;
97
98    ::MPI_Isend(buf, count, static_cast< ::MPI_Datatype>(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
99
100    request->mpi_request = mpi_request;
101    request->type = 1;          // used in wait
102    request->comm = comm;
103
104    Message_Check(comm);
105
106    return 0;
107  }
108
109
110
111
112  int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
113  {
114    Debug("\nMPI_Issend with EP\n");
115
116    int src_rank;
117    MPI_Comm_rank(comm, &src_rank);
118
119   
120
121    if(!comm.is_ep)
122    {
123      ::MPI_Request mpi_request;
124      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
125      ::MPI_Issend(buf, count, static_cast< ::MPI_Datatype> (datatype), dest, tag, mpi_comm, &mpi_request);
126
127      request->mpi_request = mpi_request;
128      request->ep_src = src_rank;
129      request->ep_tag = tag;
130      request->ep_datatype = datatype;
131      request->type = 1;
132      request->comm = comm;
133
134      return 0;
135    }
136
137    if(comm.is_intercomm) return MPI_Issend_intercomm(buf, count, datatype, dest, tag, comm, request);
138
139    // EP intracomm
140
141    //check_sum_send(buf, count, datatype, dest, tag, comm, 1);
142
143    int ep_src_loc = comm.ep_comm_ptr->size_rank_info[1].first;
144    int ep_dest_loc = comm.ep_comm_ptr->comm_list->rank_map->at(dest).first;
145    int mpi_tag                 = tag_combine(tag, ep_src_loc, ep_dest_loc);
146    int mpi_dest        = comm.ep_comm_ptr->comm_list->rank_map->at(dest).second;
147   
148    request->ep_src = src_rank;
149    request->ep_tag = tag;
150    request->ep_datatype = datatype;
151
152    ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm> (comm.mpi_comm);
153    ::MPI_Request mpi_request;
154
155    ::MPI_Issend(buf, count, static_cast< ::MPI_Datatype>(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
156
157    request->mpi_request = mpi_request;
158    request->type = 1;          // used in wait
159    request->comm = comm;
160    request->buf = NULL;
161   
162
163    //Message_Check(comm);
164
165    return 0;
166  }
167
168
169
170  int MPI_Isend_intercomm(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
171  {
172    Debug("MPI_Isend with intercomm\n");
173
174    //check_sum_send(buf, count, datatype, dest, tag, comm, 1);
175
176    int dest_remote_ep_rank    = comm.ep_comm_ptr->intercomm->remote_rank_map->at(dest).first;
177    int dest_remote_comm_label = comm.ep_comm_ptr->intercomm->remote_rank_map->at(dest).second;
178
179    int src_ep_rank    = comm.ep_comm_ptr->intercomm->size_rank_info[0].first;
180    int src_comm_label;
181
182    for(int i=0; i<comm.ep_comm_ptr->intercomm->local_rank_map->size(); i++)
183    {
184      if(comm.ep_comm_ptr->intercomm->local_rank_map->at(i).first == src_ep_rank)
185      {
186        src_comm_label = comm.ep_comm_ptr->intercomm->local_rank_map->at(i).second;
187        break;
188      }
189    }
190
191    Message_Check(comm);
192
193
194    if(dest_remote_comm_label == src_comm_label)       // mpi_dest differs
195    {
196      int inter_src = comm.ep_comm_ptr->intercomm->local_rank_map->at(src_ep_rank).first;
197      int ep_src_loc = comm.rank_map->at(inter_src).first;
198      int ep_dest_loc = comm.rank_map->at(dest_remote_ep_rank).first;
199      int mpi_dest    = comm.rank_map->at(dest_remote_ep_rank).second;
200      int mpi_tag = tag_combine(tag, ep_src_loc, ep_dest_loc);
201
202      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
203      ::MPI_Request mpi_request;
204 
205      ::MPI_Isend(buf, count, static_cast< ::MPI_Datatype >(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
206
207      request->mpi_request = mpi_request;
208      request->type = 1;                // used in wait
209      request->comm = comm;
210
211      request->ep_src = src_ep_rank;
212      request->ep_tag = tag;
213      request->ep_datatype = datatype;
214    }
215
216    else   // dest_remote_comm_label != src_comm_label
217    { 
218      int inter_src = comm.ep_comm_ptr->intercomm->local_rank_map->at(src_ep_rank).first;
219      int ep_src_loc = comm.rank_map->at(inter_src).first;
220      int ep_dest_loc = comm.ep_comm_ptr->intercomm->intercomm_rank_map->at(dest_remote_ep_rank).first;
221      int mpi_dest    = comm.ep_comm_ptr->intercomm->intercomm_rank_map->at(dest_remote_ep_rank).second;
222      int mpi_tag = tag_combine(tag, ep_src_loc, ep_dest_loc);
223
224      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm >(comm.ep_comm_ptr->intercomm->mpi_inter_comm);
225      ::MPI_Request mpi_request;
226
227      ::MPI_Isend(buf, count, static_cast< ::MPI_Datatype >(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
228
229      request->mpi_request = mpi_request;
230      request->type = 1;                // used in wait
231      request->comm = comm;
232   
233      request->ep_src = src_ep_rank;
234      request->ep_tag = tag;
235      request->ep_datatype = datatype;
236    }
237
238    return 0;
239
240  }
241
242
243  int MPI_Issend_intercomm(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
244  {
245    Debug("MPI_Issend with intercomm\n");
246
247    //check_sum_send(buf, count, datatype, dest, tag, comm, 1);
248
249    int dest_remote_ep_rank    = comm.ep_comm_ptr->intercomm->remote_rank_map->at(dest).first;
250    int dest_remote_comm_label = comm.ep_comm_ptr->intercomm->remote_rank_map->at(dest).second;
251
252    int src_ep_rank    = comm.ep_comm_ptr->intercomm->size_rank_info[0].first;
253    int src_comm_label;
254
255    for(int i=0; i<comm.ep_comm_ptr->intercomm->local_rank_map->size(); i++)
256    {
257      if(comm.ep_comm_ptr->intercomm->local_rank_map->at(i).first == src_ep_rank)
258      {
259        src_comm_label = comm.ep_comm_ptr->intercomm->local_rank_map->at(i).second;
260        break;
261      }
262    }
263
264    Message_Check(comm);
265
266
267    if(dest_remote_comm_label == src_comm_label)       // dest rank (loc, mpi) differs
268    {
269      int inter_src = comm.ep_comm_ptr->intercomm->local_rank_map->at(src_ep_rank).first;
270      int ep_src_loc = comm.rank_map->at(inter_src).first;
271      int ep_dest_loc = comm.rank_map->at(dest_remote_ep_rank).first;
272      int mpi_dest    = comm.rank_map->at(dest_remote_ep_rank).second;
273      int mpi_tag = tag_combine(tag, ep_src_loc, ep_dest_loc);
274
275      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm > (comm.mpi_comm);
276      ::MPI_Request mpi_request;
277 
278      ::MPI_Issend(buf, count, static_cast< ::MPI_Datatype >(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
279
280      request->mpi_request = mpi_request;
281      request->type = 1;                // used in wait
282      request->comm = comm;
283
284      request->ep_src = src_ep_rank;
285      request->ep_tag = tag;
286      request->ep_datatype = datatype;
287    }
288
289    else   // dest_remote_comm_label != src_comm_label
290    { 
291      int inter_src = comm.ep_comm_ptr->intercomm->local_rank_map->at(src_ep_rank).first;
292      int ep_src_loc = comm.rank_map->at(inter_src).first;
293      int ep_dest_loc = comm.ep_comm_ptr->intercomm->intercomm_rank_map->at(dest_remote_ep_rank).first;
294      int mpi_dest    = comm.ep_comm_ptr->intercomm->intercomm_rank_map->at(dest_remote_ep_rank).second;
295      int mpi_tag = tag_combine(tag, ep_src_loc, ep_dest_loc);
296
297      ::MPI_Comm mpi_comm = static_cast< ::MPI_Comm >(comm.ep_comm_ptr->intercomm->mpi_inter_comm);
298      ::MPI_Request mpi_request;
299
300      ::MPI_Issend(buf, count, static_cast< ::MPI_Datatype >(datatype), mpi_dest, mpi_tag, mpi_comm, &mpi_request);
301
302      request->mpi_request = mpi_request;
303      request->type = 1;                // used in wait
304      request->comm = comm;
305   
306      request->ep_src = src_ep_rank;
307      request->ep_tag = tag;
308      request->ep_datatype = datatype;
309    }
310
311    return 0;
312
313  }
314}
315
316
317
318
319
Note: See TracBrowser for help on using the repository browser.