Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
updated to use branching-tree broadcast instead of for-loop.
[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         smpi_mpi_request_t request;
193
194         smpi_bench_end();
195
196         rank = smpi_mpi_comm_rank(comm);
197
198         if (rank == root) {
199                 retval = smpi_create_request(buf, count, datatype, root, (root + 1) % comm->size, 0, comm, &request);
200                 request->forward = comm->size - 1;
201                 smpi_mpi_isend(request);
202                 smpi_mpi_wait(request, MPI_STATUS_IGNORE);
203                 xbt_mallocator_release(smpi_global->request_mallocator, request);
204         } else {
205                 retval = smpi_create_request(buf, count, datatype, MPI_ANY_SOURCE, rank, 0, comm, &request);
206                 smpi_mpi_irecv(request);
207                 smpi_mpi_wait(request, MPI_STATUS_IGNORE);
208                 xbt_mallocator_release(smpi_global->request_mallocator, request);
209         }
210
211         smpi_bench_begin();
212
213         return retval;
214 }
215
216 // FIXME: needs to return null in event of MPI_UNDEFINED color...
217 // FIXME: seriously, this isn't pretty
218 int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
219 {
220         int retval = MPI_SUCCESS;
221
222         int index, rank;
223         smpi_mpi_request_t request;
224         int colorkey[2];
225         smpi_mpi_status_t status;
226
227         smpi_bench_end();
228
229         // FIXME: need to test parameters
230
231         index = smpi_host_index();
232         rank  = comm->index_to_rank_map[index];
233
234         if (0 == rank) {
235                 int *colors = xbt_new(int, comm->size);
236                 int *keys   = xbt_new(int, comm->size);
237                 int i, j, k;
238                 smpi_mpi_communicator_t tempcomm = NULL;
239                 int colortmp;
240                 int keycount;
241                 int *keystmp  = xbt_new(int, comm->size);
242                 int *rankstmp = xbt_new(int, comm->size);
243                 int tmpval;
244                 int indextmp;
245
246                 colors[0] = color;
247                 keys[0]   = key;
248
249                 // FIXME: not efficient
250                 for (i = 1; i < comm->size; i++) {
251                         retval = smpi_create_request(colorkey, 2, MPI_INT, MPI_ANY_SOURCE, rank, MPI_ANY_TAG, comm, &request);
252                         smpi_mpi_irecv(request);
253                         smpi_mpi_wait(request, &status);
254                         xbt_mallocator_release(smpi_global->request_mallocator, request);
255                         colors[i] = colorkey[0];
256                         keys[i]   = colorkey[1];
257                 }
258
259                 for (i = 0; i < comm->size; i++) {
260                         if (-1 == colors[i]) {
261                                 continue;
262                         }
263                         colortmp = colors[i];
264                         keycount = 0;
265                         for (j = i; j < comm->size; j++) {
266                                 if(colortmp == colors[j]) {
267                                         colors[j] = -1;
268                                         keystmp[keycount] = keys[j];
269                                         rankstmp[keycount] = j;
270                                         keycount++;
271                                 }
272                         }
273                         if (0 < keycount) {
274                                 // FIXME: yes, mock me, bubble sort...
275                                 for (j = 0; j < keycount; j++) {
276                                         for (k = keycount - 1; k > j; k--) {
277                                                 if (keystmp[k] < keystmp[k - 1]) {
278                                                         tmpval          = keystmp[k];
279                                                         keystmp[k]      = keystmp[k - 1];
280                                                         keystmp[k - 1]  = tmpval;
281
282                                                         tmpval          = rankstmp[k];
283                                                         rankstmp[k]     = rankstmp[k - 1];
284                                                         rankstmp[k - 1] = tmpval;
285                                                 }
286                                         }
287                                 }
288                                 tempcomm                    = xbt_new(s_smpi_mpi_communicator_t, 1);
289                                 tempcomm->barrier_count     = 0;
290                                 tempcomm->barrier_mutex     = SIMIX_mutex_init();
291                                 tempcomm->barrier_cond      = SIMIX_cond_init();
292                                 tempcomm->rank_to_index_map = xbt_new(int, keycount);
293                                 tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
294                                 for (j = 0; j < smpi_global->host_count; j++) {
295                                         tempcomm->index_to_rank_map[j] = -1;
296                                 }
297                                 for (j = 0; j < keycount; j++) {
298                                         indextmp = comm->rank_to_index_map[rankstmp[j]];
299                                         tempcomm->rank_to_index_map[j]        = indextmp;
300                                         tempcomm->index_to_rank_map[indextmp] = j;
301                                 }
302                                 for (j = 0; j < keycount; j++) {
303                                         retval = smpi_create_request(&j, 1, MPI_INT, 0, rankstmp[j], 0, comm, &request);
304                                         request->data = tempcomm;
305                                         smpi_mpi_isend(request);
306                                         smpi_mpi_wait(request, &status);
307                                         xbt_mallocator_release(smpi_global->request_mallocator, request);
308                                 }
309                         }
310                 }
311         } else {
312                 colorkey[0] = color;
313                 colorkey[1] = key;
314                 retval = smpi_create_request(colorkey, 2, MPI_INT, rank, 0, 0, comm, &request);
315                 smpi_mpi_isend(request);
316                 smpi_mpi_wait(request, &status);
317                 xbt_mallocator_release(smpi_global->request_mallocator, request);
318                 retval = smpi_create_request(colorkey, 1, MPI_INT, 0, rank, 0, comm, &request);
319                 smpi_mpi_irecv(request);
320                 smpi_mpi_wait(request, &status);
321                 *comm_out = request->data;
322         }
323
324         smpi_bench_begin();
325
326         return retval;
327 }