Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
just changed some comments.
[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 // used by comm_split to sort ranks based on key values
207 int smpi_compare_rankkeys(const void *a, const void *b);
208 int smpi_compare_rankkeys(const void *a, const void *b) {
209     int *x = (int *)a;
210     int *y = (int *)b;
211
212     if (x[1] < y[1]) return -1;
213
214     if (x[1] == y[1]) {
215         if (x[0] < y[0]) return -1;
216         if (x[0] == y[0]) return 0;
217         return 1;
218     }
219
220     return 1;
221 }
222
223 // FIXME: needs to return null in event of MPI_UNDEFINED color...
224 int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
225 {
226         int retval = MPI_SUCCESS;
227
228         int index, rank;
229         smpi_mpi_request_t request;
230         int colorkey[2];
231         smpi_mpi_status_t status;
232
233         smpi_bench_end();
234
235         // FIXME: need to test parameters
236
237         index = smpi_host_index();
238         rank  = comm->index_to_rank_map[index];
239
240         if (0 == rank) {
241                 int colormap[comm->size];
242         int keymap[comm->size];
243         int rankkeymap[comm->size * 2];
244                 int i, j;
245                 smpi_mpi_communicator_t tempcomm = NULL;
246                 int colortmp;
247                 int keycount;
248                 int indextmp;
249
250                 colormap[0] = color;
251         keymap[0]   = key;
252
253                 // FIXME: use scatter/gather or similar instead of individual comms
254                 for (i = 1; i < comm->size; i++) {
255                         retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE,
256                     rank, MPI_ANY_TAG, comm, &request);
257                         smpi_mpi_irecv(request);
258                         smpi_mpi_wait(request, &status);
259                         colormap[status.MPI_SOURCE] = colorkey[0];
260                         keymap[status.MPI_SOURCE]   = colorkey[1];
261                         xbt_mallocator_release(smpi_global->request_mallocator, request);
262                 }
263
264                 for (i = 0; i < comm->size; i++) {
265                         if (-1 == colormap[i]) {
266                                 continue;
267                         }
268                         colortmp = colormap[i];
269                         keycount = 0;
270                         for (j = i; j < comm->size; j++) {
271                                 if(colortmp == colormap[j]) {
272                                         colormap[j] = -1;
273                                         rankkeymap[keycount * 2]     = j;
274                                         rankkeymap[keycount * 2 + 1] = keymap[j];
275                                         keycount++;
276                                 }
277                         }
278             qsort(rankkeymap, keycount, sizeof(int) * 2, &smpi_compare_rankkeys);
279                         tempcomm                    = xbt_new(s_smpi_mpi_communicator_t, 1);
280                         tempcomm->barrier_count     = 0;
281                         tempcomm->size              = keycount;
282                         tempcomm->barrier_mutex     = SIMIX_mutex_init();
283                         tempcomm->barrier_cond      = SIMIX_cond_init();
284                         tempcomm->rank_to_index_map = xbt_new(int, keycount);
285                         tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
286                         for (j = 0; j < smpi_global->host_count; j++) {
287                                 tempcomm->index_to_rank_map[j] = -1;
288                         }
289                         for (j = 0; j < keycount; j++) {
290                                 indextmp = comm->rank_to_index_map[rankkeymap[j*2]];
291                                 tempcomm->rank_to_index_map[j]        = indextmp;
292                                 tempcomm->index_to_rank_map[indextmp] = j;
293                         }
294                         for (j = 0; j < keycount; j++) {
295                                 if (rankkeymap[j*2]) {
296                                         retval = smpi_create_request(&j, 1, MPI_INT, 0,
297                         rankkeymap[j*2], 0, comm, &request);
298                                         request->data = tempcomm;
299                                         smpi_mpi_isend(request);
300                                         smpi_mpi_wait(request, &status);
301                                         xbt_mallocator_release(smpi_global->request_mallocator,
302                         request);
303                                 } else {
304                                         *comm_out = tempcomm;
305                                 }
306                         }
307                 }
308         } else {
309                 colorkey[0] = color;
310                 colorkey[1] = key;
311                 retval = smpi_create_request(colorkey, 2, MPI_INT, rank, 0, 0, comm,
312             &request);
313                 smpi_mpi_isend(request);
314                 smpi_mpi_wait(request, &status);
315                 xbt_mallocator_release(smpi_global->request_mallocator, request);
316                 retval = smpi_create_request(colorkey, 1, MPI_INT, 0, rank, 0, comm,
317             &request);
318                 smpi_mpi_irecv(request);
319                 smpi_mpi_wait(request, &status);
320                 *comm_out = request->data;
321         }
322
323         smpi_bench_begin();
324
325         return retval;
326 }