Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fixed bugs in SMPI_MPI_Comm_split and added back SMPI_MPI_Wait
[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 *colors = xbt_new(int, comm->size);
226                 int *keys   = 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 *keystmp  = xbt_new(int, comm->size);
232                 int *rankstmp = xbt_new(int, comm->size);
233                 int tmpval;
234                 int indextmp;
235
236                 colors[0] = color;
237                 keys[0]   = key;
238
239                 // FIXME: not efficient
240                 for (i = 1; i < comm->size; i++) {
241                         retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE, rank, MPI_ANY_TAG, comm, &request);
242                         smpi_mpi_irecv(request);
243                         smpi_mpi_wait(request, &status);
244                         colors[status.MPI_SOURCE] = colorkey[0];
245                         keys[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 == colors[i]) {
251                                 continue;
252                         }
253                         colortmp = colors[i];
254                         keycount = 0;
255                         for (j = i; j < comm->size; j++) {
256                                 if(colortmp == colors[j]) {
257                                         colors[j] = -1;
258                                         keystmp[keycount] = keys[j];
259                                         rankstmp[keycount] = j;
260                                         keycount++;
261                                 }
262                         }
263                         // FIXME: yes, mock me, bubble sort...
264                         for (j = 0; j < keycount; j++) {
265                                 for (k = j; k < keycount - 1; k++) {
266                                         if (keystmp[k] > keystmp[k + 1]) {
267                                                 tmpval          = keystmp[k];
268                                                 keystmp[k]      = keystmp[k + 1];
269                                                 keystmp[k + 1]  = tmpval;
270
271                                                 tmpval          = rankstmp[k];
272                                                 rankstmp[k]     = rankstmp[k + 1];
273                                                 rankstmp[k + 1] = tmpval;
274                                         }
275                                 }
276                         }
277                         tempcomm                    = xbt_new(s_smpi_mpi_communicator_t, 1);
278                         tempcomm->barrier_count     = 0;
279                         tempcomm->size              = keycount;
280                         tempcomm->barrier_mutex     = SIMIX_mutex_init();
281                         tempcomm->barrier_cond      = SIMIX_cond_init();
282                         tempcomm->rank_to_index_map = xbt_new(int, keycount);
283                         tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
284                         for (j = 0; j < smpi_global->host_count; j++) {
285                                 tempcomm->index_to_rank_map[j] = -1;
286                         }
287                         for (j = 0; j < keycount; j++) {
288                                 indextmp = comm->rank_to_index_map[rankstmp[j]];
289                                 tempcomm->rank_to_index_map[j]        = indextmp;
290                                 tempcomm->index_to_rank_map[indextmp] = j;
291                         }
292                         for (j = 0; j < keycount; j++) {
293                                 if (rankstmp[j]) {
294                                         retval = smpi_create_request(&j, 1, MPI_INT, 0, rankstmp[j], 0, comm, &request);
295                                         request->data = tempcomm;
296                                         smpi_mpi_isend(request);
297                                         smpi_mpi_wait(request, &status);
298                                         xbt_mallocator_release(smpi_global->request_mallocator, request);
299                                 } else {
300                                         *comm_out = tempcomm;
301                                 }
302                         }
303                 }
304         } else {
305                 colorkey[0] = color;
306                 colorkey[1] = key;
307                 retval = smpi_create_request(colorkey, 2, MPI_INT, rank, 0, 0, comm, &request);
308                 smpi_mpi_isend(request);
309                 smpi_mpi_wait(request, &status);
310                 xbt_mallocator_release(smpi_global->request_mallocator, request);
311                 retval = smpi_create_request(colorkey, 1, MPI_INT, 0, rank, 0, comm, &request);
312                 smpi_mpi_irecv(request);
313                 smpi_mpi_wait(request, &status);
314                 *comm_out = request->data;
315         }
316
317         smpi_bench_begin();
318
319         return retval;
320 }