Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
added very crufy hacked together broadcast and split.
[simgrid.git] / src / smpi / smpi_mpi.c
1 // FIXME: remove
2 #include <stdio.h>
3 #include "private.h"
4
5 int MPI_Init(int *argc, char ***argv)
6 {
7         smpi_mpi_init();
8         smpi_bench_begin();
9         return MPI_SUCCESS;
10 }
11
12 int 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 MPI_Abort(MPI_Comm comm, int errorcode)
22 {
23         smpi_exit(errorcode);
24         return 0;
25 }
26
27 int 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 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 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 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 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         if (NULL == request) {
108                 retval = MPI_ERR_ARG;
109         } else {
110                 int dst = 0;
111                 retval = smpi_create_request(buf, count, datatype, src, dst, tag, comm, request);
112                 if (NULL != *request && MPI_SUCCESS == retval) {
113                         retval = smpi_mpi_irecv(*request);
114                 }
115         }
116
117         smpi_bench_begin();
118
119         return retval;
120 }
121
122 int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm, MPI_Status *status)
123 {
124         int retval = MPI_SUCCESS;
125         int dst = 0;
126         smpi_mpi_request_t request;
127
128         smpi_bench_end();
129
130         retval = smpi_create_request(buf, count, datatype, src, dst, tag, comm, &request);
131         if (NULL != request && MPI_SUCCESS == retval) {
132                 retval = smpi_mpi_irecv(request);
133                 if (MPI_SUCCESS == retval) {
134                         retval = smpi_mpi_wait(request, status);
135                 }
136                 xbt_mallocator_release(smpi_global->request_mallocator, request);
137         }
138
139         smpi_bench_begin();
140
141         return retval;
142 }
143
144 int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm, MPI_Request *request)
145 {
146         int retval = MPI_SUCCESS;
147
148         smpi_bench_end();
149
150         if (NULL == request) {
151                 retval = MPI_ERR_ARG;
152         } else {
153                 int src = 0;
154                 retval = smpi_create_request(buf, count, datatype, src, dst, tag, comm, request);
155                 if (NULL != *request && MPI_SUCCESS == retval) {
156                         retval = smpi_mpi_isend(*request);
157                 }
158         }
159
160         smpi_bench_begin();
161
162         return retval;
163 }
164
165 int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm)
166 {
167         int retval = MPI_SUCCESS;
168         int src = 0;
169         smpi_mpi_request_t request;
170
171         smpi_bench_end();
172
173         retval = smpi_create_request(buf, count, datatype, src, dst, tag, comm, &request);
174         if (NULL != request && MPI_SUCCESS == retval) {
175                 retval = smpi_mpi_isend(request);
176                 if (MPI_SUCCESS == retval) {
177                         smpi_mpi_wait(request, MPI_STATUS_IGNORE);
178                 }
179                 xbt_mallocator_release(smpi_global->request_mallocator, request);
180         }
181
182         smpi_bench_begin();
183
184         return retval;
185 }
186
187 // FIXME: overly simplistic
188 int MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm) {
189
190         int retval = MPI_SUCCESS;
191         int rank;
192
193         smpi_bench_end();
194
195         rank = smpi_mpi_comm_rank(comm);
196
197         if (rank == root) {
198                 int i;
199                 smpi_mpi_request_t *requests = xbt_new(smpi_mpi_request_t, comm->size - 1);
200                 for (i = 1; i < comm->size; i++) {
201                         retval = smpi_create_request(buf, count, datatype, root, (root + i) % comm->size, 0, comm, requests + i - 1);
202                         smpi_mpi_isend(requests[i - 1]);
203                 }
204                 for (i = 0; i < comm->size - 1; i++) {
205                         smpi_mpi_wait(requests[i], MPI_STATUS_IGNORE);
206                         xbt_mallocator_release(smpi_global->request_mallocator, requests[i]);
207                 }
208                 xbt_free(requests);
209         } else {
210                 smpi_mpi_request_t request;
211                 retval = smpi_create_request(buf, count, datatype, root, rank, 0, comm, &request);
212                 smpi_mpi_irecv(request);
213                 smpi_mpi_wait(request, MPI_STATUS_IGNORE);
214                 xbt_mallocator_release(smpi_global->request_mallocator, request);
215         }
216
217         smpi_bench_begin();
218
219         return retval;
220 }
221
222 // FIXME: needs to return null in event of MPI_UNDEFINED color...
223 // FIXME: seriously, this isn't pretty
224 int 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 *colors = xbt_new(int, comm->size);
242                 int *keys   = xbt_new(int, comm->size);
243                 int i, j, k;
244                 smpi_mpi_communicator_t tempcomm = NULL;
245                 int colortmp;
246                 int keycount;
247                 int *keystmp  = xbt_new(int, comm->size);
248                 int *rankstmp = xbt_new(int, comm->size);
249                 int tmpval;
250                 int indextmp;
251
252                 colors[0] = color;
253                 keys[0]   = key;
254
255                 // FIXME: not efficient
256                 for (i = 1; i < comm->size; i++) {
257                         retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE, rank, MPI_ANY_TAG, comm, &request);
258                         smpi_mpi_irecv(request);
259                         smpi_mpi_wait(request, &status);
260                         xbt_mallocator_release(smpi_global->request_mallocator, request);
261                         colors[i] = colorkey[0];
262                         keys[i]   = colorkey[1];
263                 }
264
265                 for (i = 0; i < comm->size; i++) {
266                         if (-1 == colors[i]) {
267                                 continue;
268                         }
269                         colortmp = colors[i];
270                         keycount = 0;
271                         for (j = i; j < comm->size; j++) {
272                                 if(colortmp == colors[j]) {
273                                         colors[j] = -1;
274                                         keystmp[keycount] = keys[j];
275                                         rankstmp[keycount] = j;
276                                         keycount++;
277                                 }
278                         }
279                         if (0 < keycount) {
280                                 // FIXME: yes, mock me, bubble sort...
281                                 for (j = 0; j < keycount; j++) {
282                                         for (k = keycount - 1; k > j; k--) {
283                                                 if (keystmp[k] < keystmp[k - 1]) {
284                                                         tmpval          = keystmp[k];
285                                                         keystmp[k]      = keystmp[k - 1];
286                                                         keystmp[k - 1]  = tmpval;
287
288                                                         tmpval          = rankstmp[k];
289                                                         rankstmp[k]     = rankstmp[k - 1];
290                                                         rankstmp[k - 1] = tmpval;
291                                                 }
292                                         }
293                                 }
294                                 tempcomm                    = xbt_new(s_smpi_mpi_communicator_t, 1);
295                                 tempcomm->barrier_count     = 0;
296                                 tempcomm->barrier_mutex     = SIMIX_mutex_init();
297                                 tempcomm->barrier_cond      = SIMIX_cond_init();
298                                 tempcomm->rank_to_index_map = xbt_new(int, keycount);
299                                 tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
300                                 for (j = 0; j < smpi_global->host_count; j++) {
301                                         tempcomm->index_to_rank_map[j] = -1;
302                                 }
303                                 for (j = 0; j < keycount; j++) {
304                                         indextmp = comm->rank_to_index_map[rankstmp[j]];
305                                         tempcomm->rank_to_index_map[j]        = indextmp;
306                                         tempcomm->index_to_rank_map[indextmp] = j;
307                                 }
308                                 for (j = 0; j < keycount; j++) {
309                                         retval = smpi_create_request(&j, 1, MPI_INT, 0, rankstmp[j], 0, comm, &request);
310                                         request->data = tempcomm;
311                                         smpi_mpi_isend(request);
312                                         smpi_mpi_wait(request, &status);
313                                         xbt_mallocator_release(smpi_global->request_mallocator, request);
314                                 }
315                         }
316                 }
317         } else {
318                 colorkey[0] = color;
319                 colorkey[1] = key;
320                 retval = smpi_create_request(colorkey, 2, MPI_INT, rank, 0, 0, comm, &request);
321                 smpi_mpi_isend(request);
322                 smpi_mpi_wait(request, &status);
323                 xbt_mallocator_release(smpi_global->request_mallocator, request);
324                 retval = smpi_create_request(colorkey, 1, MPI_INT, 0, rank, 0, comm, &request);
325                 smpi_mpi_irecv(request);
326                 smpi_mpi_wait(request, &status);
327                 *comm_out = request->data;
328         }
329
330         smpi_bench_begin();
331
332         return retval;
333 }