Logo AND Algorithmique Numérique Distribuée

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