Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c213d455fbbbbeab80f6a2ba78060834144cce44
[simgrid.git] / src / smpi / smpi_mpi.c
1 #include "private.h"
2
3 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi, smpi, "Logging specific to SMPI (mpi)");
4
5 int SMPI_MPI_Init(int *argc, char ***argv)
6 {
7         smpi_mpi_init();
8         smpi_bench_begin();
9         return MPI_SUCCESS;
10 }
11
12 int SMPI_MPI_Finalize()
13 {
14         smpi_bench_end();
15         smpi_mpi_finalize();
16         return MPI_SUCCESS;
17 }
18
19 // right now this just exits the current node, should send abort signal to all
20 // hosts in the communicator;
21 int SMPI_MPI_Abort(MPI_Comm comm, int errorcode)
22 {
23         smpi_exit(errorcode);
24         return 0;
25 }
26
27 int SMPI_MPI_Comm_size(MPI_Comm comm, int *size)
28 {
29         int retval = MPI_SUCCESS;
30
31         smpi_bench_end();
32
33         if (NULL == comm) {
34                 retval = MPI_ERR_COMM;
35         } else if (NULL == size) {
36                 retval = MPI_ERR_ARG;
37         } else {
38                 *size = comm->size;
39         }
40
41         smpi_bench_begin();
42
43         return retval;
44 }
45
46 int SMPI_MPI_Comm_rank(MPI_Comm comm, int *rank)
47 {
48         int retval = MPI_SUCCESS;
49
50         smpi_bench_end();
51
52         if (NULL == comm) {
53                 retval = MPI_ERR_COMM;
54         } else if (NULL == rank) {
55                 retval = MPI_ERR_ARG;
56         } else {
57                 *rank = smpi_mpi_comm_rank(comm);
58         }
59
60         smpi_bench_begin();
61
62         return retval;
63 }
64
65 int SMPI_MPI_Type_size(MPI_Datatype datatype, size_t *size)
66 {
67         int retval = MPI_SUCCESS;
68
69         smpi_bench_end();
70
71         if (NULL == datatype) {
72                 retval = MPI_ERR_TYPE;
73         } else if (NULL == size) {
74                 retval = MPI_ERR_ARG;
75         } else {
76                 *size = datatype->size;
77         }
78
79         smpi_bench_begin();
80
81         return retval;
82 }
83
84 int SMPI_MPI_Barrier(MPI_Comm comm)
85 {
86         int retval = MPI_SUCCESS;
87
88         smpi_bench_end();
89
90         if (NULL == comm) {
91                 retval = MPI_ERR_COMM;
92         } else {
93                 retval = smpi_mpi_barrier(comm);
94         }
95
96         smpi_bench_begin();
97
98         return retval;
99 }
100
101 int SMPI_MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Request *request)
102 {
103         int retval = MPI_SUCCESS;
104
105         smpi_bench_end();
106
107         retval = smpi_create_request(buf, count, datatype, src, 0, tag, comm, request);
108         if (NULL != *request && MPI_SUCCESS == retval) {
109                 retval = smpi_mpi_irecv(*request);
110         }
111
112         smpi_bench_begin();
113
114         return retval;
115 }
116
117 int SMPI_MPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status)
118 {
119         int retval = MPI_SUCCESS;
120         smpi_mpi_request_t request;
121
122         smpi_bench_end();
123
124         retval = smpi_create_request(buf, count, datatype, src, 0, tag, comm, &request);
125         if (NULL != request && MPI_SUCCESS == retval) {
126                 retval = smpi_mpi_irecv(request);
127                 if (MPI_SUCCESS == retval) {
128                         retval = smpi_mpi_wait(request, status);
129                 }
130                 xbt_mallocator_release(smpi_global->request_mallocator, request);
131         }
132
133         smpi_bench_begin();
134
135         return retval;
136 }
137
138 int SMPI_MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request *request)
139 {
140         int retval = MPI_SUCCESS;
141
142         smpi_bench_end();
143
144         retval = smpi_create_request(buf, count, datatype, 0, dst, tag, comm, request);
145         if (NULL != *request && MPI_SUCCESS == retval) {
146                 retval = smpi_mpi_isend(*request);
147         }
148
149         smpi_bench_begin();
150
151         return retval;
152 }
153
154 int SMPI_MPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
155 {
156         int retval = MPI_SUCCESS;
157         smpi_mpi_request_t request;
158
159         smpi_bench_end();
160
161         retval = smpi_create_request(buf, count, datatype, 0, dst, tag, comm, &request);
162         if (NULL != request && MPI_SUCCESS == retval) {
163                 retval = smpi_mpi_isend(request);
164                 if (MPI_SUCCESS == retval) {
165                         smpi_mpi_wait(request, MPI_STATUS_IGNORE);
166                 }
167                 xbt_mallocator_release(smpi_global->request_mallocator, request);
168         }
169
170         smpi_bench_begin();
171
172         return retval;
173 }
174
175 int SMPI_MPI_Wait(MPI_Request *request, MPI_Status *status) {
176         return smpi_mpi_wait(*request, status);
177 }
178
179 int SMPI_MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
180
181         int retval = MPI_SUCCESS;
182         int rank;
183         smpi_mpi_request_t request;
184
185         smpi_bench_end();
186
187         rank = smpi_mpi_comm_rank(comm);
188
189         if (rank == root) {
190                 retval = smpi_create_request(buf, count, datatype, root, (root + 1) % comm->size, 0, comm, &request);
191                 request->forward = comm->size - 1;
192                 smpi_mpi_isend(request);
193         } else {
194                 retval = smpi_create_request(buf, count, datatype, MPI_ANY_SOURCE, rank, 0, comm, &request);
195                 smpi_mpi_irecv(request);
196         }
197
198         smpi_mpi_wait(request, MPI_STATUS_IGNORE);
199         xbt_mallocator_release(smpi_global->request_mallocator, request);
200
201         smpi_bench_begin();
202
203         return retval;
204 }
205
206 // FIXME: needs to return null in event of MPI_UNDEFINED color...
207 // FIXME: seriously, this isn't pretty
208 int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
209 {
210         int retval = MPI_SUCCESS;
211
212         int index, rank;
213         smpi_mpi_request_t request;
214         int colorkey[2];
215         smpi_mpi_status_t status;
216
217         smpi_bench_end();
218
219         // FIXME: need to test parameters
220
221         index = smpi_host_index();
222         rank  = comm->index_to_rank_map[index];
223
224         if (0 == rank) {
225                 int *color = xbt_new(int, comm->size);
226                 int *key   = xbt_new(int, comm->size);
227                 int i, j, k;
228                 smpi_mpi_communicator_t tempcomm = NULL;
229                 int colortmp;
230                 int keycount;
231                 int *rankmap = xbt_new(int, comm->size);
232                 int tmpval;
233                 int indextmp;
234
235                 color[0] = color;
236                 key[0]   = key;
237
238                 // FIXME: use scatter/gather or similar instead of individual comms
239                 for (i = 1; i < comm->size; i++) {
240                         retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE,
241                     rank, MPI_ANY_TAG, comm, &request);
242                         smpi_mpi_irecv(request);
243                         smpi_mpi_wait(request, &status);
244                         color[status.MPI_SOURCE] = colorkey[0];
245                         key[status.MPI_SOURCE]   = colorkey[1];
246                         xbt_mallocator_release(smpi_global->request_mallocator, request);
247                 }
248
249                 for (i = 0; i < comm->size; i++) {
250                         if (-1 == color[i]) {
251                                 continue;
252                         }
253                         colortmp = color[i];
254                         keycount = 0;
255                         for (j = i; j < comm->size; j++) {
256                                 if(colortmp == color[j]) {
257                                         color[j] = -1;
258                                         rankmap[keycount] = j;
259                                         keycount++;
260                                 }
261                         }
262                         // FIXME: yes, mock me, bubble sort...
263                         for (j = 0; j < keycount; j++) {
264                                 for (k = j; k < keycount - 1; k++) {
265                                         if (key[rankmap[k]] > key[rankmap[k + 1]]) {
266                                                 tmpval          = rankmap[k];
267                                                 rankmap[k]     = rankmap[k + 1];
268                                                 rankmap[k + 1] = tmpval;
269                                         }
270                                 }
271                         }
272                         tempcomm                    = xbt_new(s_smpi_mpi_communicator_t, 1);
273                         tempcomm->barrier_count     = 0;
274                         tempcomm->size              = keycount;
275                         tempcomm->barrier_mutex     = SIMIX_mutex_init();
276                         tempcomm->barrier_cond      = SIMIX_cond_init();
277                         tempcomm->rank_to_index_map = xbt_new(int, keycount);
278                         tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
279                         for (j = 0; j < smpi_global->host_count; j++) {
280                                 tempcomm->index_to_rank_map[j] = -1;
281                         }
282                         for (j = 0; j < keycount; j++) {
283                                 indextmp = comm->rank_to_index_map[rankmap[j]];
284                                 tempcomm->rank_to_index_map[j]        = indextmp;
285                                 tempcomm->index_to_rank_map[indextmp] = j;
286                         }
287                         for (j = 0; j < keycount; j++) {
288                                 if (rankmap[j]) {
289                                         retval = smpi_create_request(&j, 1, MPI_INT, 0, rankmap[j], 0, comm, &request);
290                                         request->data = tempcomm;
291                                         smpi_mpi_isend(request);
292                                         smpi_mpi_wait(request, &status);
293                                         xbt_mallocator_release(smpi_global->request_mallocator, request);
294                                 } else {
295                                         *comm_out = tempcomm;
296                                 }
297                         }
298                 }
299         } else {
300                 colorkey[0] = color;
301                 colorkey[1] = key;
302                 retval = smpi_create_request(colorkey, 2, MPI_INT, rank, 0, 0, comm, &request);
303                 smpi_mpi_isend(request);
304                 smpi_mpi_wait(request, &status);
305                 xbt_mallocator_release(smpi_global->request_mallocator, request);
306                 retval = smpi_create_request(colorkey, 1, MPI_INT, 0, rank, 0, comm, &request);
307                 smpi_mpi_irecv(request);
308                 smpi_mpi_wait(request, &status);
309                 *comm_out = request->data;
310         }
311
312         smpi_bench_begin();
313
314         return retval;
315 }