Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'smpi-topo'
[simgrid.git] / src / smpi / smpi_f77.c
1 /* Copyright (c) 2010-2014. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <limits.h>
8 #include <stdio.h>
9
10 #include "private.h"
11 #include "xbt.h"
12
13 extern int xargc;
14 extern char** xargv;
15
16 static xbt_dict_t comm_lookup = NULL;
17 static xbt_dict_t group_lookup = NULL;
18 static xbt_dict_t request_lookup = NULL;
19 static xbt_dict_t datatype_lookup = NULL;
20 static xbt_dict_t op_lookup = NULL;
21 static int running_processes = 0;
22
23 /* Bindings for MPI special values */
24 union u_smpi_common {
25   struct s_smpi_common {
26     integer _MPI_IN_PLACE;
27     integer _MPI_BOTTOM;
28     integer _MPI_STATUS_IGNORE;
29     integer _MPI_STATUSES_IGNORE;
30   } *f77;                       /* with f2c, remains NULL with gfortran */
31   struct s_smpi_common f90;     /* with gfortran */
32 } smpi_ = { NULL };
33
34 /* Convert between Fortran and C */
35 #define F2C_ADDR(addr, val)                                             \
36   (((void *)(addr) == (void *)(smpi_.f77                                \
37                                ? &smpi_.f77[smpi_current_rank]._ ## val \
38                                : &smpi_.f90._ ## val))                  \
39    ? (val) : (void *)(addr))
40 #define F2C_BOTTOM(addr)          F2C_ADDR(addr, MPI_BOTTOM)
41 #define F2C_IN_PLACE(addr)        F2C_ADDR(addr, MPI_IN_PLACE)
42 #define F2C_STATUS_IGNORE(addr)   F2C_ADDR(addr, MPI_STATUS_IGNORE)
43 #define F2C_STATUSES_IGNORE(addr) F2C_ADDR(addr, MPI_STATUSES_IGNORE)
44
45 #define KEY_SIZE (sizeof(int) * 2 + 1)
46
47
48 static char* get_key(char* key, int id) {
49   snprintf(key, KEY_SIZE, "%x",id);
50   return key;
51 }
52 static char* get_key_id(char* key, int id) {
53   snprintf(key, KEY_SIZE, "%x_%d",id, smpi_process_index());
54   return key;
55 }
56
57 static int new_comm(MPI_Comm comm) {
58   static int comm_id = 0;
59   char key[KEY_SIZE];
60   xbt_dict_set(comm_lookup, comm==MPI_COMM_WORLD? get_key(key, comm_id) : get_key_id(key, comm_id), comm, NULL);
61   comm_id++;
62   return comm_id-1;
63 }
64
65 static void free_comm(int comm) {
66   char key[KEY_SIZE];
67   xbt_dict_remove(comm_lookup, comm==0? get_key(key, comm) : get_key_id(key, comm));
68 }
69
70 static MPI_Comm get_comm(int comm) {
71   if(comm == -2) {
72     return MPI_COMM_SELF;
73   }else if(comm==0){
74     return MPI_COMM_WORLD;
75   }     else if(comm_lookup && comm >= 0) {
76
77       char key[KEY_SIZE];
78       MPI_Comm tmp =  (MPI_Comm)xbt_dict_get_or_null(comm_lookup,get_key_id(key, comm));
79       return tmp != NULL ? tmp : MPI_COMM_NULL ;
80   }
81   return MPI_COMM_NULL;
82 }
83
84 static int new_group(MPI_Group group) {
85   static int group_id = 0;
86   char key[KEY_SIZE];
87   xbt_dict_set(group_lookup, get_key(key, group_id), group, NULL);
88   group_id++;
89   return group_id-1;
90 }
91
92 static MPI_Group get_group(int group) {
93   if(group == -2) {
94     return MPI_GROUP_EMPTY;
95   } else if(group_lookup && group >= 0) {
96     char key[KEY_SIZE];
97     return (MPI_Group)xbt_dict_get_or_null(group_lookup, get_key(key, group));
98   }
99   return MPI_GROUP_NULL;
100 }
101
102 static void free_group(int group) {
103   char key[KEY_SIZE];
104   xbt_dict_remove(group_lookup, get_key(key, group));
105 }
106
107
108
109 static int new_request(MPI_Request req) {
110   static int request_id = INT_MIN;
111   char key[KEY_SIZE];
112   xbt_dict_set(request_lookup, get_key_id(key, request_id), req, NULL);
113   request_id++;
114   return request_id-1;
115 }
116
117 static MPI_Request find_request(int req) {
118   char key[KEY_SIZE];
119   if(req==MPI_FORTRAN_REQUEST_NULL)return MPI_REQUEST_NULL;
120   return (MPI_Request)xbt_dict_get(request_lookup, get_key_id(key, req));
121 }
122
123 static void free_request(int request) {
124   char key[KEY_SIZE];
125   if(request!=MPI_FORTRAN_REQUEST_NULL)
126   xbt_dict_remove(request_lookup, get_key_id(key, request));
127 }
128
129 static int new_datatype(MPI_Datatype datatype) {
130   static int datatype_id = 0;
131   char key[KEY_SIZE];
132   xbt_dict_set(datatype_lookup, get_key(key, datatype_id), datatype, NULL);
133   datatype_id++;
134   return datatype_id-1;
135 }
136
137 static MPI_Datatype get_datatype(int datatype) {
138   char key[KEY_SIZE];
139   return datatype >= 0
140          ? (MPI_Datatype)xbt_dict_get_or_null(datatype_lookup, get_key(key, datatype))
141          : MPI_DATATYPE_NULL;
142 }
143
144 static void free_datatype(int datatype) {
145   char key[KEY_SIZE];
146   xbt_dict_remove(datatype_lookup, get_key(key, datatype));
147 }
148
149 static int new_op(MPI_Op op) {
150   static int op_id = 0;
151   char key[KEY_SIZE];
152   xbt_dict_set(op_lookup, get_key(key, op_id), op, NULL);
153   op_id++;
154   return op_id-1;
155 }
156
157 static MPI_Op get_op(int op) {
158   char key[KEY_SIZE];
159    return op >= 0
160           ? (MPI_Op)xbt_dict_get_or_null(op_lookup,  get_key(key, op))
161           : MPI_OP_NULL;
162 }
163
164 static void free_op(int op) {
165   char key[KEY_SIZE];
166   xbt_dict_remove(op_lookup, get_key(key, op));
167 }
168
169 void mpi_init_(int* ierr) {
170    if(!comm_lookup){
171      comm_lookup = xbt_dict_new_homogeneous(NULL);
172      new_comm(MPI_COMM_WORLD);
173      group_lookup = xbt_dict_new_homogeneous(NULL);
174
175      request_lookup = xbt_dict_new_homogeneous(NULL);
176
177      datatype_lookup = xbt_dict_new_homogeneous(NULL);
178      new_datatype(MPI_BYTE);
179      new_datatype(MPI_CHAR);
180      new_datatype(MPI_INT);
181      new_datatype(MPI_INT);
182      new_datatype(MPI_INT8_T);
183      new_datatype(MPI_INT16_T);
184      new_datatype(MPI_INT32_T);
185      new_datatype(MPI_INT64_T);
186      new_datatype(MPI_FLOAT);
187      new_datatype(MPI_FLOAT);
188      new_datatype(MPI_DOUBLE);
189      new_datatype(MPI_DOUBLE);
190      new_datatype(MPI_C_FLOAT_COMPLEX);
191      new_datatype(MPI_C_DOUBLE_COMPLEX);
192      new_datatype(MPI_2INT);
193      new_datatype(MPI_UINT8_T);
194      new_datatype(MPI_UINT16_T);
195      new_datatype(MPI_UINT32_T);
196      new_datatype(MPI_UINT64_T);
197      new_datatype(MPI_2FLOAT);
198      new_datatype(MPI_2DOUBLE);
199      new_datatype(MPI_DOUBLE);
200      new_datatype(MPI_DOUBLE);
201      new_datatype(MPI_INT);
202      new_datatype(MPI_DATATYPE_NULL);
203      new_datatype(MPI_DATATYPE_NULL);
204      new_datatype(MPI_DATATYPE_NULL);
205      new_datatype(MPI_DATATYPE_NULL);
206      op_lookup = xbt_dict_new_homogeneous(NULL);
207      new_op(MPI_MAX);
208      new_op(MPI_MIN);
209      new_op(MPI_MAXLOC);
210      new_op(MPI_MINLOC);
211      new_op(MPI_SUM);
212      new_op(MPI_PROD);
213      new_op(MPI_LAND);
214      new_op(MPI_LOR);
215      new_op(MPI_LXOR);
216      new_op(MPI_BAND);
217      new_op(MPI_BOR);
218      new_op(MPI_BXOR);
219    }
220    /* smpif2c is responsible for generating a call with the final arguments */
221    *ierr = MPI_Init(NULL, NULL);
222    running_processes++;
223 }
224
225 void mpi_finalize_(int* ierr) {
226    *ierr = MPI_Finalize();
227    running_processes--;
228    if(running_processes==0){
229      xbt_dict_free(&op_lookup);
230      xbt_dict_free(&datatype_lookup);
231      xbt_dict_free(&request_lookup);
232      xbt_dict_free(&group_lookup);
233      xbt_dict_free(&comm_lookup);
234    }
235 }
236
237 void mpi_abort_(int* comm, int* errorcode, int* ierr) {
238   *ierr = MPI_Abort(get_comm(*comm), *errorcode);
239 }
240
241 void mpi_comm_rank_(int* comm, int* rank, int* ierr) {
242    *ierr = MPI_Comm_rank(get_comm(*comm), rank);
243 }
244
245 void mpi_comm_size_(int* comm, int* size, int* ierr) {
246    *ierr = MPI_Comm_size(get_comm(*comm), size);
247 }
248
249 double mpi_wtime_(void) {
250    return MPI_Wtime();
251 }
252
253 double mpi_wtick_(void) {
254   return MPI_Wtick();
255 }
256
257 void mpi_comm_dup_(int* comm, int* newcomm, int* ierr) {
258   MPI_Comm tmp;
259
260   *ierr = MPI_Comm_dup(get_comm(*comm), &tmp);
261   if(*ierr == MPI_SUCCESS) {
262     *newcomm = new_comm(tmp);
263   }
264 }
265
266 void mpi_comm_create_(int* comm, int* group, int* newcomm, int* ierr) {
267   MPI_Comm tmp;
268
269   *ierr = MPI_Comm_create(get_comm(*comm),get_group(*group), &tmp);
270   if(*ierr == MPI_SUCCESS) {
271     *newcomm = new_comm(tmp);
272   }
273 }
274
275
276 void mpi_comm_free_(int* comm, int* ierr) {
277   MPI_Comm tmp = get_comm(*comm);
278
279   *ierr = MPI_Comm_free(&tmp);
280
281   if(*ierr == MPI_SUCCESS) {
282     free_comm(*comm);
283   }
284 }
285
286 void mpi_comm_split_(int* comm, int* color, int* key, int* comm_out, int* ierr) {
287   MPI_Comm tmp;
288
289   *ierr = MPI_Comm_split(get_comm(*comm), *color, *key, &tmp);
290   if(*ierr == MPI_SUCCESS) {
291     *comm_out = new_comm(tmp);
292   }
293 }
294
295 void mpi_group_incl_(int* group, int* n, int* ranks, int* group_out, int* ierr) {
296   MPI_Group tmp;
297
298   *ierr = MPI_Group_incl(get_group(*group), *n, ranks, &tmp);
299   if(*ierr == MPI_SUCCESS) {
300     *group_out = new_group(tmp);
301   }
302 }
303
304 void mpi_comm_group_(int* comm, int* group_out,  int* ierr) {
305   MPI_Group tmp;
306
307   *ierr = MPI_Comm_group(get_comm(*comm), &tmp);
308   if(*ierr == MPI_SUCCESS) {
309     *group_out = new_group(tmp);
310   }
311 }
312
313
314 void mpi_initialized_(int* flag, int* ierr){
315   *ierr = MPI_Initialized(flag);
316 }
317
318 void mpi_send_init_(void *buf, int* count, int* datatype, int* dst, int* tag,
319                      int* comm, int* request, int* ierr) {
320   MPI_Request req;
321
322   *ierr = MPI_Send_init(buf, *count, get_datatype(*datatype), *dst, *tag,
323                         get_comm(*comm), &req);
324   if(*ierr == MPI_SUCCESS) {
325     *request = new_request(req);
326   }
327 }
328
329 void mpi_isend_(void *buf, int* count, int* datatype, int* dst,
330                  int* tag, int* comm, int* request, int* ierr) {
331   MPI_Request req;
332   buf = (char *) F2C_BOTTOM(buf);
333   *ierr = MPI_Isend(buf, *count, get_datatype(*datatype), *dst, *tag,
334                     get_comm(*comm), &req);
335   if(*ierr == MPI_SUCCESS) {
336     *request = new_request(req);
337   }
338 }
339
340 void mpi_irsend_(void *buf, int* count, int* datatype, int* dst,
341                  int* tag, int* comm, int* request, int* ierr) {
342   MPI_Request req;
343   buf = (char *) F2C_BOTTOM(buf);
344   *ierr = MPI_Irsend(buf, *count, get_datatype(*datatype), *dst, *tag,
345                     get_comm(*comm), &req);
346   if(*ierr == MPI_SUCCESS) {
347     *request = new_request(req);
348   }
349 }
350
351 void mpi_send_(void* buf, int* count, int* datatype, int* dst,
352                 int* tag, int* comm, int* ierr) {
353    *ierr = MPI_Send(buf, *count, get_datatype(*datatype), *dst, *tag,
354                     get_comm(*comm));
355 }
356
357 void mpi_rsend_(void* buf, int* count, int* datatype, int* dst,
358                 int* tag, int* comm, int* ierr) {
359    *ierr = MPI_Rsend(buf, *count, get_datatype(*datatype), *dst, *tag,
360                     get_comm(*comm));
361 }
362
363 void mpi_sendrecv_(void* sendbuf, int* sendcount, int* sendtype, int* dst,
364                 int* sendtag, void *recvbuf, int* recvcount,
365                 int* recvtype, int* src, int* recvtag,
366                 int* comm, MPI_Status* status, int* ierr) {
367    *ierr = MPI_Sendrecv(sendbuf, *sendcount, get_datatype(*sendtype), *dst,
368        *sendtag, recvbuf, *recvcount,get_datatype(*recvtype), *src, *recvtag,
369        get_comm(*comm), F2C_STATUS_IGNORE(status));
370 }
371
372 void mpi_recv_init_(void *buf, int* count, int* datatype, int* src, int* tag,
373                      int* comm, int* request, int* ierr) {
374   MPI_Request req;
375
376   *ierr = MPI_Recv_init(buf, *count, get_datatype(*datatype), *src, *tag,
377                         get_comm(*comm), &req);
378   if(*ierr == MPI_SUCCESS) {
379     *request = new_request(req);
380   }
381 }
382
383 void mpi_irecv_(void *buf, int* count, int* datatype, int* src, int* tag,
384                  int* comm, int* request, int* ierr) {
385   MPI_Request req;
386   buf = (char *) F2C_BOTTOM(buf);
387   *ierr = MPI_Irecv(buf, *count, get_datatype(*datatype), *src, *tag,
388                     get_comm(*comm), &req);
389   if(*ierr == MPI_SUCCESS) {
390     *request = new_request(req);
391   }
392 }
393
394 void mpi_recv_(void* buf, int* count, int* datatype, int* src,
395                 int* tag, int* comm, MPI_Status* status, int* ierr) {
396    *ierr = MPI_Recv(buf, *count, get_datatype(*datatype), *src, *tag,
397                     get_comm(*comm), status);
398 }
399
400 void mpi_start_(int* request, int* ierr) {
401   MPI_Request req = find_request(*request);
402
403   *ierr = MPI_Start(&req);
404 }
405
406 void mpi_startall_(int* count, int* requests, int* ierr) {
407   MPI_Request* reqs;
408   int i;
409
410   reqs = xbt_new(MPI_Request, *count);
411   for(i = 0; i < *count; i++) {
412     reqs[i] = find_request(requests[i]);
413   }
414   *ierr = MPI_Startall(*count, reqs);
415   free(reqs);
416 }
417
418 void mpi_wait_(int* request, MPI_Status* status, int* ierr) {
419    MPI_Request req = find_request(*request);
420    
421    *ierr = MPI_Wait(&req, F2C_STATUS_IGNORE(status));
422    if(req==MPI_REQUEST_NULL){
423      free_request(*request);
424      *request=MPI_FORTRAN_REQUEST_NULL;
425    }
426 }
427
428 void mpi_waitany_(int* count, int* requests, int* index, MPI_Status* status, int* ierr) {
429   MPI_Request* reqs;
430   int i;
431
432   reqs = xbt_new(MPI_Request, *count);
433   for(i = 0; i < *count; i++) {
434     reqs[i] = find_request(requests[i]);
435   }
436   *ierr = MPI_Waitany(*count, reqs, index, status);
437   if(reqs[*index]==MPI_REQUEST_NULL){
438       free_request(requests[*index]);
439       requests[*index]=MPI_FORTRAN_REQUEST_NULL;
440   }
441   free(reqs);
442 }
443
444 void mpi_waitall_(int* count, int* requests, MPI_Status* status, int* ierr) {
445   MPI_Request* reqs;
446   int i;
447
448   reqs = xbt_new(MPI_Request, *count);
449   for(i = 0; i < *count; i++) {
450     reqs[i] = find_request(requests[i]);
451   }
452   *ierr = MPI_Waitall(*count, reqs, F2C_STATUSES_IGNORE(status));
453   for(i = 0; i < *count; i++) {
454       if(reqs[i]==MPI_REQUEST_NULL){
455           free_request(requests[i]);
456           requests[i]=MPI_FORTRAN_REQUEST_NULL;
457       }
458   }
459
460   free(reqs);
461 }
462
463 void mpi_barrier_(int* comm, int* ierr) {
464   *ierr = MPI_Barrier(get_comm(*comm));
465 }
466
467 void mpi_bcast_(void *buf, int* count, int* datatype, int* root, int* comm, int* ierr) {
468   *ierr = MPI_Bcast(buf, *count, get_datatype(*datatype), *root, get_comm(*comm));
469 }
470
471 void mpi_reduce_(void* sendbuf, void* recvbuf, int* count,
472                   int* datatype, int* op, int* root, int* comm, int* ierr) {
473   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
474   sendbuf = (char *) F2C_BOTTOM(sendbuf);
475   recvbuf = (char *) F2C_BOTTOM(recvbuf);
476   *ierr = MPI_Reduce(sendbuf, recvbuf, *count,
477                      get_datatype(*datatype), get_op(*op), *root, get_comm(*comm));
478 }
479
480 void mpi_allreduce_(void* sendbuf, void* recvbuf, int* count, int* datatype,
481                      int* op, int* comm, int* ierr) {
482   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
483   *ierr = MPI_Allreduce(sendbuf, recvbuf, *count, get_datatype(*datatype),
484                         get_op(*op), get_comm(*comm));
485 }
486
487 void mpi_reduce_scatter_(void* sendbuf, void* recvbuf, int* recvcounts, int* datatype,
488                      int* op, int* comm, int* ierr) {
489   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
490   *ierr = MPI_Reduce_scatter(sendbuf, recvbuf, recvcounts, get_datatype(*datatype),
491                         get_op(*op), get_comm(*comm));
492 }
493
494 void mpi_scatter_(void* sendbuf, int* sendcount, int* sendtype,
495                    void* recvbuf, int* recvcount, int* recvtype, 
496                    int* root, int* comm, int* ierr) {
497   recvbuf = (char *) F2C_IN_PLACE(recvbuf);
498   *ierr = MPI_Scatter(sendbuf, *sendcount, get_datatype(*sendtype),
499                       recvbuf, *recvcount, get_datatype(*recvtype), *root, get_comm(*comm));
500 }
501
502
503 void mpi_scatterv_(void* sendbuf, int* sendcounts, int* displs, int* sendtype,
504                    void* recvbuf, int* recvcount, int* recvtype,
505                    int* root, int* comm, int* ierr) {
506   recvbuf = (char *) F2C_IN_PLACE(recvbuf);
507   *ierr = MPI_Scatterv(sendbuf, sendcounts, displs, get_datatype(*sendtype),
508                       recvbuf, *recvcount, get_datatype(*recvtype), *root, get_comm(*comm));
509 }
510
511 void mpi_gather_(void* sendbuf, int* sendcount, int* sendtype,
512                   void* recvbuf, int* recvcount, int* recvtype,
513                   int* root, int* comm, int* ierr) {
514   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
515   sendbuf = (char *) F2C_BOTTOM(sendbuf);
516   recvbuf = (char *) F2C_BOTTOM(recvbuf);
517   *ierr = MPI_Gather(sendbuf, *sendcount, get_datatype(*sendtype),
518                      recvbuf, *recvcount, get_datatype(*recvtype), *root, get_comm(*comm));
519 }
520
521 void mpi_gatherv_(void* sendbuf, int* sendcount, int* sendtype,
522                   void* recvbuf, int* recvcounts, int* displs, int* recvtype,
523                   int* root, int* comm, int* ierr) {
524   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
525   sendbuf = (char *) F2C_BOTTOM(sendbuf);
526   recvbuf = (char *) F2C_BOTTOM(recvbuf);
527   *ierr = MPI_Gatherv(sendbuf, *sendcount, get_datatype(*sendtype),
528                      recvbuf, recvcounts, displs, get_datatype(*recvtype), *root, get_comm(*comm));
529 }
530
531 void mpi_allgather_(void* sendbuf, int* sendcount, int* sendtype,
532                      void* recvbuf, int* recvcount, int* recvtype,
533                      int* comm, int* ierr) {
534   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
535   *ierr = MPI_Allgather(sendbuf, *sendcount, get_datatype(*sendtype),
536                         recvbuf, *recvcount, get_datatype(*recvtype), get_comm(*comm));
537 }
538
539 void mpi_allgatherv_(void* sendbuf, int* sendcount, int* sendtype,
540                      void* recvbuf, int* recvcounts,int* displs, int* recvtype,
541                      int* comm, int* ierr) {
542   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
543   *ierr = MPI_Allgatherv(sendbuf, *sendcount, get_datatype(*sendtype),
544                         recvbuf, recvcounts, displs, get_datatype(*recvtype), get_comm(*comm));
545 }
546
547 void mpi_scan_(void* sendbuf, void* recvbuf, int* count, int* datatype,
548                 int* op, int* comm, int* ierr) {
549   *ierr = MPI_Scan(sendbuf, recvbuf, *count, get_datatype(*datatype),
550                    get_op(*op), get_comm(*comm));
551 }
552
553 void mpi_alltoall_(void* sendbuf, int* sendcount, int* sendtype,
554                     void* recvbuf, int* recvcount, int* recvtype, int* comm, int* ierr) {
555   *ierr = MPI_Alltoall(sendbuf, *sendcount, get_datatype(*sendtype),
556                        recvbuf, *recvcount, get_datatype(*recvtype), get_comm(*comm));
557 }
558
559 void mpi_alltoallv_(void* sendbuf, int* sendcounts, int* senddisps, int* sendtype,
560                     void* recvbuf, int* recvcounts, int* recvdisps, int* recvtype, int* comm, int* ierr) {
561   *ierr = MPI_Alltoallv(sendbuf, sendcounts, senddisps, get_datatype(*sendtype),
562                        recvbuf, recvcounts, recvdisps, get_datatype(*recvtype), get_comm(*comm));
563 }
564
565 void mpi_test_ (int * request, int *flag, MPI_Status * status, int* ierr){
566   MPI_Request req = find_request(*request);
567   *ierr= MPI_Test(&req, flag, F2C_STATUS_IGNORE(status));
568   if(req==MPI_REQUEST_NULL){
569       free_request(*request);
570       *request=MPI_FORTRAN_REQUEST_NULL;
571   }
572 }
573
574
575 void mpi_testall_ (int* count, int * requests,  int *flag, MPI_Status * statuses, int* ierr){
576   MPI_Request* reqs;
577   int i;
578   reqs = xbt_new(MPI_Request, *count);
579   for(i = 0; i < *count; i++) {
580     reqs[i] = find_request(requests[i]);
581   }
582   *ierr= MPI_Testall(*count, reqs, flag, F2C_STATUSES_IGNORE(statuses));
583   for(i = 0; i < *count; i++) {
584     if(reqs[i]==MPI_REQUEST_NULL){
585         free_request(requests[i]);
586         requests[i]=MPI_FORTRAN_REQUEST_NULL;
587     }
588   }
589 }
590
591
592 void mpi_get_processor_name_(char *name, int *resultlen, int* ierr){
593   *ierr = MPI_Get_processor_name(name, resultlen);
594 }
595
596 void mpi_get_count_(MPI_Status * status, int* datatype, int *count, int* ierr){
597   *ierr = MPI_Get_count(F2C_STATUS_IGNORE(status), get_datatype(*datatype), count);
598 }
599
600 void mpi_attr_get_(int* comm, int* keyval, void* attr_value, int* flag, int* ierr ){
601   *ierr = MPI_Attr_get(get_comm(*comm), *keyval, attr_value, flag);
602 }
603
604 void mpi_type_extent_(int* datatype, MPI_Aint * extent, int* ierr){
605   *ierr= MPI_Type_extent(get_datatype(*datatype),  extent);
606 }
607
608 void mpi_type_commit_(int* datatype,  int* ierr){
609   MPI_Datatype tmp= get_datatype(*datatype);
610   *ierr= MPI_Type_commit(&tmp);
611 }
612
613 void mpi_type_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr){
614   MPI_Datatype tmp;
615   *ierr= MPI_Type_vector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
616   if(*ierr == MPI_SUCCESS) {
617     *newtype = new_datatype(tmp);
618   }
619 }
620
621 void mpi_type_create_vector_(int* count, int* blocklen, int* stride, int* old_type, int* newtype,  int* ierr){
622   MPI_Datatype tmp;
623   *ierr= MPI_Type_vector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
624   if(*ierr == MPI_SUCCESS) {
625     *newtype = new_datatype(tmp);
626   }
627 }
628
629 void mpi_type_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr){
630   MPI_Datatype tmp;
631   *ierr= MPI_Type_hvector (*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
632   if(*ierr == MPI_SUCCESS) {
633     *newtype = new_datatype(tmp);
634   }
635 }
636
637 void mpi_type_create_hvector_(int* count, int* blocklen, MPI_Aint* stride, int* old_type, int* newtype,  int* ierr){
638   MPI_Datatype tmp;
639   *ierr= MPI_Type_hvector(*count, *blocklen, *stride, get_datatype(*old_type), &tmp);
640   if(*ierr == MPI_SUCCESS) {
641     *newtype = new_datatype(tmp);
642   }
643 }
644
645 void mpi_type_free_(int* datatype, int* ierr){
646   MPI_Datatype tmp= get_datatype(*datatype);
647   *ierr= MPI_Type_free (&tmp);
648   if(*ierr == MPI_SUCCESS) {
649     free_datatype(*datatype);
650   }
651 }
652
653 void mpi_type_ub_(int* datatype, MPI_Aint * disp, int* ierr){
654   *ierr= MPI_Type_ub(get_datatype(*datatype), disp);
655 }
656
657 void mpi_type_lb_(int* datatype, MPI_Aint * extent, int* ierr){
658   *ierr= MPI_Type_extent(get_datatype(*datatype), extent);
659 }
660
661 void mpi_type_size_(int* datatype, int *size, int* ierr)
662 {
663   *ierr = MPI_Type_size(get_datatype(*datatype), size);
664 }
665
666 void mpi_error_string_(int* errorcode, char* string, int* resultlen, int* ierr){
667   *ierr = MPI_Error_string(*errorcode, string, resultlen);
668 }
669
670 void mpi_win_fence_( int* assert,  int* win, int* ierr){
671   *ierr =  MPI_Win_fence(* assert, *(MPI_Win*)win);
672 }
673
674 void mpi_win_free_( int* win, int* ierr){
675   *ierr =  MPI_Win_free(  (MPI_Win*)win);
676 }
677
678 void mpi_win_create_( int *base, MPI_Aint* size, int* disp_unit, int* info, int* comm, int *win, int* ierr){
679   *ierr =  MPI_Win_create( (void*)base, *size, *disp_unit, *(MPI_Info*)info, get_comm(*comm),(MPI_Win*)win);
680 }
681
682 void mpi_info_create_( int *info, int* ierr){
683   *ierr =  MPI_Info_create( (MPI_Info *)info);
684 }
685
686 void mpi_info_set_( int *info, char *key, char *value, int* ierr){
687   *ierr =  MPI_Info_set( *(MPI_Info *)info, key, value);
688 }
689
690 void mpi_info_free_(int* info, int* ierr){
691   *ierr =  MPI_Info_free((MPI_Info *) info);
692 }
693
694 void mpi_get_( int *origin_addr, int* origin_count, int* origin_datatype, int *target_rank,
695     MPI_Aint* target_disp, int *target_count, int* target_datatype, int* win, int* ierr){
696   *ierr =  MPI_Get( (void*)origin_addr,*origin_count, get_datatype(*origin_datatype),*target_rank,
697       *target_disp, *target_count,get_datatype(*target_datatype), *(MPI_Win *)win);
698 }
699
700
701 //following are automatically generated, and have to be checked
702 void mpi_finalized_ (int * flag, int* ierr){
703
704  *ierr = MPI_Finalized(flag);
705 }
706
707 void mpi_init_thread_ (int* required, int *provided, int* ierr){
708   if(!comm_lookup){
709     comm_lookup = xbt_dict_new_homogeneous(NULL);
710     new_comm(MPI_COMM_WORLD);
711     group_lookup = xbt_dict_new_homogeneous(NULL);
712
713     request_lookup = xbt_dict_new_homogeneous(NULL);
714
715     datatype_lookup = xbt_dict_new_homogeneous(NULL);
716     new_datatype(MPI_BYTE);
717     new_datatype(MPI_CHAR);
718     new_datatype(MPI_INT);
719     new_datatype(MPI_INT);
720     new_datatype(MPI_INT8_T);
721     new_datatype(MPI_INT16_T);
722     new_datatype(MPI_INT32_T);
723     new_datatype(MPI_INT64_T);
724     new_datatype(MPI_FLOAT);
725     new_datatype(MPI_FLOAT);
726     new_datatype(MPI_DOUBLE);
727     new_datatype(MPI_DOUBLE);
728     new_datatype(MPI_C_FLOAT_COMPLEX);
729     new_datatype(MPI_C_DOUBLE_COMPLEX);
730     new_datatype(MPI_2INT);
731     new_datatype(MPI_UINT8_T);
732     new_datatype(MPI_UINT16_T);
733     new_datatype(MPI_UINT32_T);
734     new_datatype(MPI_UINT64_T);
735     new_datatype(MPI_2FLOAT);
736     new_datatype(MPI_2DOUBLE);
737
738     op_lookup = xbt_dict_new_homogeneous( NULL);
739     new_op(MPI_MAX);
740     new_op(MPI_MIN);
741     new_op(MPI_MAXLOC);
742     new_op(MPI_MINLOC);
743     new_op(MPI_SUM);
744     new_op(MPI_PROD);
745     new_op(MPI_LAND);
746     new_op(MPI_LOR);
747     new_op(MPI_LXOR);
748     new_op(MPI_BAND);
749     new_op(MPI_BOR);
750     new_op(MPI_BXOR);
751   }
752   /* smpif2c is responsible for generating a call with the final arguments */
753  *ierr = MPI_Init_thread(NULL, NULL,*required, provided);
754 }
755
756 void mpi_query_thread_ (int *provided, int* ierr){
757
758  *ierr = MPI_Query_thread(provided);
759 }
760
761 void mpi_is_thread_main_ (int *flag, int* ierr){
762
763  *ierr = MPI_Is_thread_main(flag);
764 }
765
766 void mpi_address_ (void *location, MPI_Aint * address, int* ierr){
767
768  *ierr = MPI_Address(location, address);
769 }
770
771 void mpi_get_address_ (void *location, MPI_Aint * address, int* ierr){
772
773  *ierr = MPI_Get_address(location, address);
774 }
775
776 void mpi_type_dup_ (int*  datatype, int* newdatatype, int* ierr){
777  MPI_Datatype tmp;
778  *ierr = MPI_Type_dup(get_datatype(*datatype), &tmp);
779  if(*ierr == MPI_SUCCESS) {
780    *newdatatype = new_datatype(tmp);
781  }
782 }
783
784 void mpi_type_set_name_ (int*  datatype, char * name, int* ierr){
785
786  *ierr = MPI_Type_set_name(get_datatype(*datatype), name);
787 }
788
789 void mpi_type_get_name_ (int*  datatype, char * name, int* len, int* ierr){
790
791  *ierr = MPI_Type_get_name(get_datatype(*datatype),name,len);
792 }
793
794 void mpi_type_get_attr_ (int* type, int* type_keyval, void *attribute_val, int* flag, int* ierr){
795
796  *ierr = MPI_Type_get_attr ( get_datatype(*type), *type_keyval, attribute_val,flag);
797 }
798
799 void mpi_type_set_attr_ (int* type, int* type_keyval, void *attribute_val, int* ierr){
800
801  *ierr = MPI_Type_set_attr ( get_datatype(*type), *type_keyval, attribute_val);
802 }
803
804 void mpi_type_delete_attr_ (int* type, int* type_keyval, int* ierr){
805
806  *ierr = MPI_Type_delete_attr ( get_datatype(*type),  *type_keyval);
807 }
808
809 void mpi_type_create_keyval_ (void* copy_fn, void*  delete_fn, int* keyval, void* extra_state, int* ierr){
810
811  *ierr = MPI_Type_create_keyval((MPI_Type_copy_attr_function*)copy_fn, (MPI_Type_delete_attr_function*) delete_fn,  keyval,  extra_state) ;
812 }
813
814 void mpi_type_free_keyval_ (int* keyval, int* ierr) {
815  *ierr = MPI_Type_free_keyval( keyval);
816 }
817
818 void mpi_pcontrol_ (int* level , int* ierr){
819  *ierr = MPI_Pcontrol(*(const int*)level);
820 }
821
822 void mpi_type_get_extent_ (int* datatype, MPI_Aint * lb, MPI_Aint * extent, int* ierr){
823
824  *ierr = MPI_Type_get_extent(get_datatype(*datatype), lb, extent);
825 }
826
827 void mpi_type_get_true_extent_ (int* datatype, MPI_Aint * lb, MPI_Aint * extent, int* ierr){
828
829  *ierr = MPI_Type_get_true_extent(get_datatype(*datatype), lb, extent);
830 }
831
832 void mpi_op_create_ (void * function, int* commute, int* op, int* ierr){
833   MPI_Op tmp;
834  *ierr = MPI_Op_create((MPI_User_function*)function,* commute, &tmp);
835  if(*ierr == MPI_SUCCESS) {
836    *op = new_op(tmp);
837  }
838 }
839
840 void mpi_op_free_ (int* op, int* ierr){
841   MPI_Op tmp=get_op(*op);
842   *ierr = MPI_Op_free(& tmp);
843   if(*ierr == MPI_SUCCESS) {
844     free_op(*op);
845   }
846 }
847
848 void mpi_group_free_ (int* group, int* ierr){
849  MPI_Group tmp=get_group(*group);
850  *ierr = MPI_Group_free(&tmp);
851  if(*ierr == MPI_SUCCESS) {
852    free_group(*group);
853  }
854 }
855
856 void mpi_group_size_ (int* group, int *size, int* ierr){
857
858  *ierr = MPI_Group_size(get_group(*group), size);
859 }
860
861 void mpi_group_rank_ (int* group, int *rank, int* ierr){
862
863  *ierr = MPI_Group_rank(get_group(*group), rank);
864 }
865
866 void mpi_group_translate_ranks_ (int* group1, int* n, int *ranks1, int* group2, int *ranks2, int* ierr)
867 {
868
869  *ierr = MPI_Group_translate_ranks(get_group(*group1), *n, ranks1, get_group(*group2), ranks2);
870 }
871
872 void mpi_group_compare_ (int* group1, int* group2, int *result, int* ierr){
873
874  *ierr = MPI_Group_compare(get_group(*group1), get_group(*group2), result);
875 }
876
877 void mpi_group_union_ (int* group1, int* group2, int* newgroup, int* ierr){
878  MPI_Group tmp;
879  *ierr = MPI_Group_union(get_group(*group1), get_group(*group2), &tmp);
880  if(*ierr == MPI_SUCCESS) {
881    *newgroup = new_group(tmp);
882  }
883 }
884
885 void mpi_group_intersection_ (int* group1, int* group2, int* newgroup, int* ierr){
886  MPI_Group tmp;
887  *ierr = MPI_Group_intersection(get_group(*group1), get_group(*group2), &tmp);
888  if(*ierr == MPI_SUCCESS) {
889    *newgroup = new_group(tmp);
890  }
891 }
892
893 void mpi_group_difference_ (int* group1, int* group2, int* newgroup, int* ierr){
894  MPI_Group tmp;
895  *ierr = MPI_Group_difference(get_group(*group1), get_group(*group2), &tmp);
896  if(*ierr == MPI_SUCCESS) {
897    *newgroup = new_group(tmp);
898  }
899 }
900
901 void mpi_group_excl_ (int* group, int* n, int *ranks, int* newgroup, int* ierr){
902   MPI_Group tmp;
903  *ierr = MPI_Group_excl(get_group(*group), *n, ranks, &tmp);
904  if(*ierr == MPI_SUCCESS) {
905    *newgroup = new_group(tmp);
906  }
907 }
908
909 void mpi_group_range_incl_ (int* group, int* n, int ranges[][3], int* newgroup, int* ierr)
910 {
911   MPI_Group tmp;
912  *ierr = MPI_Group_range_incl(get_group(*group), *n, ranges, &tmp);
913  if(*ierr == MPI_SUCCESS) {
914    *newgroup = new_group(tmp);
915  }
916 }
917
918 void mpi_group_range_excl_ (int* group, int* n, int ranges[][3], int* newgroup, int* ierr)
919 {
920  MPI_Group tmp;
921  *ierr = MPI_Group_range_excl(get_group(*group), *n, ranges, &tmp);
922  if(*ierr == MPI_SUCCESS) {
923    *newgroup = new_group(tmp);
924  }
925 }
926
927 void mpi_comm_get_attr_ (int* comm, int* comm_keyval, void *attribute_val, int *flag, int* ierr){
928
929  *ierr = MPI_Comm_get_attr (get_comm(*comm), *comm_keyval, attribute_val, flag);
930 }
931
932 void mpi_comm_set_attr_ (int* comm, int* comm_keyval, void *attribute_val, int* ierr){
933
934  *ierr = MPI_Comm_set_attr ( get_comm(*comm), *comm_keyval, attribute_val);
935 }
936
937 void mpi_comm_delete_attr_ (int* comm, int* comm_keyval, int* ierr){
938
939  *ierr = MPI_Comm_delete_attr (get_comm(*comm),  *comm_keyval);
940 }
941
942 void mpi_comm_create_keyval_ (void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr){
943
944  *ierr = MPI_Comm_create_keyval((MPI_Comm_copy_attr_function*)copy_fn,  (MPI_Comm_delete_attr_function*)delete_fn,  keyval,  extra_state) ;
945 }
946
947 void mpi_comm_free_keyval_ (int* keyval, int* ierr) {
948  *ierr = MPI_Comm_free_keyval( keyval);
949 }
950
951 void mpi_comm_get_name_ (int* comm, char* name, int* len, int* ierr){
952
953  *ierr = MPI_Comm_get_name(get_comm(*comm), name, len);
954 }
955
956 void mpi_comm_compare_ (int* comm1, int* comm2, int *result, int* ierr){
957
958  *ierr = MPI_Comm_compare(get_comm(*comm1), get_comm(*comm2), result);
959 }
960
961 void mpi_comm_disconnect_ (int* comm, int* ierr){
962  MPI_Comm tmp=get_comm(*comm);
963  *ierr = MPI_Comm_disconnect(&tmp);
964  if(*ierr == MPI_SUCCESS) {
965    free_comm(*comm);
966  }
967 }
968
969 void mpi_request_free_ (int* request, int* ierr){
970   MPI_Request tmp=find_request(*request);
971  *ierr = MPI_Request_free(&tmp);
972  if(*ierr == MPI_SUCCESS) {
973    free_request(*request);
974  }
975 }
976
977 void mpi_sendrecv_replace_ (void *buf, int* count, int* datatype, int* dst, int* sendtag, int* src, int* recvtag,
978  int* comm, MPI_Status* status, int* ierr)
979 {
980
981  *ierr = MPI_Sendrecv_replace(buf, *count, get_datatype(*datatype), *dst, *sendtag, *src,
982  *recvtag, get_comm(*comm), F2C_STATUS_IGNORE(status));
983 }
984
985 void mpi_testany_ (int* count, int* requests, int *index, int *flag, MPI_Status* status, int* ierr)
986 {
987   MPI_Request* reqs;
988   int i;
989
990   reqs = xbt_new(MPI_Request, *count);
991   for(i = 0; i < *count; i++) {
992     reqs[i] = find_request(requests[i]);
993   }
994   *ierr = MPI_Testany(*count, reqs, index, flag, F2C_STATUS_IGNORE(status));
995   if(*index!=MPI_UNDEFINED)
996   if(reqs[*index]==MPI_REQUEST_NULL){
997     free_request(requests[*index]);
998     requests[*index]=MPI_FORTRAN_REQUEST_NULL;
999   }
1000   free(reqs);
1001 }
1002
1003 void mpi_waitsome_ (int* incount, int* requests, int *outcount, int *indices, MPI_Status* status, int* ierr)
1004 {
1005   MPI_Request* reqs;
1006   int i;
1007
1008   reqs = xbt_new(MPI_Request, *incount);
1009   for(i = 0; i < *incount; i++) {
1010     reqs[i] = find_request(requests[i]);
1011   }
1012   *ierr = MPI_Waitsome(*incount, reqs, outcount, indices, status);
1013   for(i=0;i<*outcount;i++){
1014     if(reqs[indices[i]]==MPI_REQUEST_NULL){
1015         free_request(requests[indices[i]]);
1016         requests[indices[i]]=MPI_FORTRAN_REQUEST_NULL;
1017     }
1018   }
1019   free(reqs);
1020 }
1021
1022 void mpi_reduce_local_ (void *inbuf, void *inoutbuf, int* count, int* datatype, int* op, int* ierr){
1023
1024  *ierr = MPI_Reduce_local(inbuf, inoutbuf, *count, get_datatype(*datatype), get_op(*op));
1025 }
1026
1027 void mpi_reduce_scatter_block_ (void *sendbuf, void *recvbuf, int* recvcount, int* datatype, int* op, int* comm, int* ierr)
1028 {
1029   sendbuf = (char *) F2C_IN_PLACE(sendbuf);
1030  *ierr = MPI_Reduce_scatter_block(sendbuf, recvbuf, *recvcount, get_datatype(*datatype), get_op(*op), get_comm(*comm));
1031 }
1032
1033 void mpi_pack_size_ (int* incount, int* datatype, int* comm, int* size, int* ierr) {
1034  *ierr = MPI_Pack_size(*incount, get_datatype(*datatype), get_comm(*comm), size);
1035 }
1036
1037 void mpi_cart_coords_ (int* comm, int* rank, int* maxdims, int* coords, int* ierr) {
1038  *ierr = MPI_Cart_coords(get_comm(*comm), *rank, *maxdims, coords);
1039 }
1040
1041 void mpi_cart_create_ (int* comm_old, int* ndims, int* dims, int* periods, int* reorder, int*  comm_cart, int* ierr) {
1042   MPI_Comm tmp;
1043  *ierr = MPI_Cart_create(get_comm(*comm_old), *ndims, dims, periods, *reorder, &tmp);
1044  if(*ierr == MPI_SUCCESS) {
1045    *comm_cart = new_comm(tmp);
1046  }
1047 }
1048
1049 void mpi_cart_get_ (int* comm, int* maxdims, int* dims, int* periods, int* coords, int* ierr) {
1050  *ierr = MPI_Cart_get(get_comm(*comm), *maxdims, dims, periods, coords);
1051 }
1052
1053 void mpi_cart_map_ (int* comm_old, int* ndims, int* dims, int* periods, int* newrank, int* ierr) {
1054  *ierr = MPI_Cart_map(get_comm(*comm_old), *ndims, dims, periods, newrank);
1055 }
1056
1057 void mpi_cart_rank_ (int* comm, int* coords, int* rank, int* ierr) {
1058  *ierr = MPI_Cart_rank(get_comm(*comm), coords, rank);
1059 }
1060
1061 void mpi_cart_shift_ (int* comm, int* direction, int* displ, int* source, int* dest, int* ierr) {
1062  *ierr = MPI_Cart_shift(get_comm(*comm), *direction, *displ, source, dest);
1063 }
1064
1065 void mpi_cart_sub_ (int* comm, int* remain_dims, int*  comm_new, int* ierr) {
1066  MPI_Comm tmp;
1067  *ierr = MPI_Cart_sub(get_comm(*comm), remain_dims, &tmp);
1068  if(*ierr == MPI_SUCCESS) {
1069    *comm_new = new_comm(tmp);
1070  }
1071 }
1072
1073 void mpi_cartdim_get_ (int* comm, int* ndims, int* ierr) {
1074  *ierr = MPI_Cartdim_get(get_comm(*comm), ndims);
1075 }
1076
1077 void mpi_graph_create_ (int* comm_old, int* nnodes, int* index, int* edges, int* reorder, int*  comm_graph, int* ierr) {
1078   MPI_Comm tmp;
1079  *ierr = MPI_Graph_create(get_comm(*comm_old), *nnodes, index, edges, *reorder, &tmp);
1080  if(*ierr == MPI_SUCCESS) {
1081    *comm_graph = new_comm(tmp);
1082  }
1083 }
1084
1085 void mpi_graph_get_ (int* comm, int* maxindex, int* maxedges, int* index, int* edges, int* ierr) {
1086  *ierr = MPI_Graph_get(get_comm(*comm), *maxindex, *maxedges, index, edges);
1087 }
1088
1089 void mpi_graph_map_ (int* comm_old, int* nnodes, int* index, int* edges, int* newrank, int* ierr) {
1090  *ierr = MPI_Graph_map(get_comm(*comm_old), *nnodes, index, edges, newrank);
1091 }
1092
1093 void mpi_graph_neighbors_ (int* comm, int* rank, int* maxneighbors, int* neighbors, int* ierr) {
1094  *ierr = MPI_Graph_neighbors(get_comm(*comm), *rank, *maxneighbors, neighbors);
1095 }
1096
1097 void mpi_graph_neighbors_count_ (int* comm, int* rank, int* nneighbors, int* ierr) {
1098  *ierr = MPI_Graph_neighbors_count(get_comm(*comm), *rank, nneighbors);
1099 }
1100
1101 void mpi_graphdims_get_ (int* comm, int* nnodes, int* nedges, int* ierr) {
1102  *ierr = MPI_Graphdims_get(get_comm(*comm), nnodes, nedges);
1103 }
1104
1105 void mpi_topo_test_ (int* comm, int* top_type, int* ierr) {
1106  *ierr = MPI_Topo_test(get_comm(*comm), top_type);
1107 }
1108
1109 void mpi_error_class_ (int* errorcode, int* errorclass, int* ierr) {
1110  *ierr = MPI_Error_class(*errorcode, errorclass);
1111 }
1112
1113 void mpi_errhandler_create_ (void* function, void* errhandler, int* ierr) {
1114  *ierr = MPI_Errhandler_create((MPI_Handler_function*)function, (MPI_Errhandler*)errhandler);
1115 }
1116
1117 void mpi_errhandler_free_ (void* errhandler, int* ierr) {
1118  *ierr = MPI_Errhandler_free((MPI_Errhandler*)errhandler);
1119 }
1120
1121 void mpi_errhandler_get_ (int* comm, void* errhandler, int* ierr) {
1122  *ierr = MPI_Errhandler_get(get_comm(*comm), (MPI_Errhandler*) errhandler);
1123 }
1124
1125 void mpi_errhandler_set_ (int* comm, void* errhandler, int* ierr) {
1126  *ierr = MPI_Errhandler_set(get_comm(*comm), *(MPI_Errhandler*)errhandler);
1127 }
1128
1129 void mpi_comm_set_errhandler_ (int* comm, void* errhandler, int* ierr) {
1130  *ierr = MPI_Errhandler_set(get_comm(*comm), *(MPI_Errhandler*)errhandler);
1131 }
1132
1133 void mpi_comm_get_errhandler_ (int* comm, void* errhandler, int* ierr) {
1134  *ierr = MPI_Errhandler_set(get_comm(*comm), (MPI_Errhandler*)errhandler);
1135 }
1136
1137 void mpi_type_contiguous_ (int* count, int* old_type, int*  newtype, int* ierr) {
1138   MPI_Datatype tmp;
1139   *ierr = MPI_Type_contiguous(*count, get_datatype(*old_type), &tmp);
1140   if(*ierr == MPI_SUCCESS) {
1141     *newtype = new_datatype(tmp);
1142   }
1143 }
1144
1145 void mpi_cancel_ (int* request, int* ierr) {
1146   MPI_Request tmp=find_request(*request);
1147  *ierr = MPI_Cancel(&tmp);
1148  if(*ierr == MPI_SUCCESS) {
1149    free_request(*request);
1150  }
1151 }
1152
1153 void mpi_buffer_attach_ (void* buffer, int* size, int* ierr) {
1154  *ierr = MPI_Buffer_attach(buffer, *size);
1155 }
1156
1157 void mpi_buffer_detach_ (void* buffer, int* size, int* ierr) {
1158  *ierr = MPI_Buffer_detach(buffer, size);
1159 }
1160
1161 void mpi_testsome_ (int* incount, int*  requests, int* outcount, int* indices, MPI_Status*  statuses, int* ierr) {
1162   MPI_Request* reqs;
1163   int i;
1164
1165   reqs = xbt_new(MPI_Request, *incount);
1166   for(i = 0; i < *incount; i++) {
1167     reqs[i] = find_request(requests[i]);
1168     indices[i]=0;
1169   }
1170   *ierr = MPI_Testsome(*incount, reqs, outcount, indices, F2C_STATUSES_IGNORE(statuses));
1171   for(i=0;i<*incount;i++){
1172     if(indices[i]){
1173       if(reqs[indices[i]]==MPI_REQUEST_NULL){
1174           free_request(requests[indices[i]]);
1175           requests[indices[i]]=MPI_FORTRAN_REQUEST_NULL;
1176       }
1177     }
1178   }
1179   free(reqs);
1180 }
1181
1182 void mpi_comm_test_inter_ (int* comm, int* flag, int* ierr) {
1183  *ierr = MPI_Comm_test_inter(get_comm(*comm), flag);
1184 }
1185
1186 void mpi_unpack_ (void* inbuf, int* insize, int* position, void* outbuf, int* outcount, int* type, int* comm, int* ierr) {
1187  *ierr = MPI_Unpack(inbuf, *insize, position, outbuf, *outcount, get_datatype(*type), get_comm(*comm));
1188 }
1189
1190 void mpi_pack_external_size_ (char *datarep, int* incount, int* datatype, MPI_Aint *size, int* ierr){
1191  *ierr = MPI_Pack_external_size(datarep, *incount, get_datatype(*datatype), size);
1192 }
1193
1194 void mpi_pack_external_ (char *datarep, void *inbuf, int* incount, int* datatype, void *outbuf, MPI_Aint* outcount, MPI_Aint *position, int* ierr){
1195  *ierr = MPI_Pack_external(datarep, inbuf, *incount, get_datatype(*datatype), outbuf, *outcount, position);
1196 }
1197
1198 void mpi_unpack_external_ ( char *datarep, void *inbuf, MPI_Aint* insize, MPI_Aint *position, void *outbuf, int* outcount, int* datatype, int* ierr){
1199  *ierr = MPI_Unpack_external( datarep, inbuf, *insize, position, outbuf, *outcount, get_datatype(*datatype));
1200 }
1201
1202 void mpi_type_hindexed_ (int* count, int* blocklens, MPI_Aint* indices, int* old_type, int*  newtype, int* ierr) {
1203   MPI_Datatype tmp;
1204   *ierr = MPI_Type_hindexed(*count, blocklens, indices, get_datatype(*old_type), &tmp);
1205   if(*ierr == MPI_SUCCESS) {
1206     *newtype = new_datatype(tmp);
1207   }
1208 }
1209
1210 void mpi_type_create_hindexed_ (int* count, int* blocklens, MPI_Aint* indices, int* old_type, int*  newtype, int* ierr) {
1211   MPI_Datatype tmp;
1212   *ierr = MPI_Type_create_hindexed(*count, blocklens, indices, get_datatype(*old_type), &tmp);
1213   if(*ierr == MPI_SUCCESS) {
1214     *newtype = new_datatype(tmp);
1215   }
1216 }
1217
1218 void mpi_type_create_hindexed_block_ (int* count, int* blocklength, MPI_Aint* indices, int* old_type, int*  newtype, int* ierr) {
1219   MPI_Datatype tmp;
1220   *ierr = MPI_Type_create_hindexed_block(*count, *blocklength, indices, get_datatype(*old_type), &tmp);
1221   if(*ierr == MPI_SUCCESS) {
1222     *newtype = new_datatype(tmp);
1223   }
1224 }
1225
1226 void mpi_type_indexed_ (int* count, int* blocklens, int* indices, int* old_type, int*  newtype, int* ierr) {
1227   MPI_Datatype tmp;
1228   *ierr = MPI_Type_indexed(*count, blocklens, indices, get_datatype(*old_type), &tmp);
1229   if(*ierr == MPI_SUCCESS) {
1230     *newtype = new_datatype(tmp);
1231   }
1232 }
1233
1234 void mpi_type_create_indexed_block_ (int* count, int* blocklength, int* indices,  int* old_type,  int*newtype, int* ierr){
1235   MPI_Datatype tmp;
1236   *ierr = MPI_Type_create_indexed_block(*count, *blocklength, indices, get_datatype(*old_type), &tmp);
1237   if(*ierr == MPI_SUCCESS) {
1238     *newtype = new_datatype(tmp);
1239   }
1240 }
1241
1242 void mpi_type_struct_ (int* count, int* blocklens, MPI_Aint* indices, int* old_types, int*  newtype, int* ierr) {
1243   MPI_Datatype tmp;
1244   *ierr = MPI_Type_struct(*count, blocklens, indices, (MPI_Datatype*)old_types, &tmp);
1245   if(*ierr == MPI_SUCCESS) {
1246     *newtype = new_datatype(tmp);
1247   }
1248 }
1249
1250 void mpi_type_create_struct_ (int* count, int* blocklens, MPI_Aint* indices, int*  old_types, int*  newtype, int* ierr) {
1251   MPI_Datatype tmp;
1252   *ierr = MPI_Type_create_struct(*count, blocklens, indices, (MPI_Datatype*)old_types, &tmp);
1253   if(*ierr == MPI_SUCCESS) {
1254     *newtype = new_datatype(tmp);
1255   }
1256 }
1257
1258 void mpi_ssend_ (void* buf, int* count, int* datatype, int* dest, int* tag, int* comm, int* ierr) {
1259  *ierr = MPI_Ssend(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm));
1260 }
1261
1262 void mpi_ssend_init_ (void* buf, int* count, int* datatype, int* dest, int* tag, int* comm, int* request, int* ierr) {
1263   MPI_Request tmp;
1264  *ierr = MPI_Ssend_init(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm), &tmp);
1265  if(*ierr == MPI_SUCCESS) {
1266    *request = new_request(tmp);
1267  }
1268 }
1269
1270 void mpi_intercomm_create_ (int* local_comm, int *local_leader, int* peer_comm, int* remote_leader, int* tag, int*  comm_out, int* ierr) {
1271   MPI_Comm tmp;
1272   *ierr = MPI_Intercomm_create(get_comm(*local_comm), *local_leader,get_comm(*peer_comm), *remote_leader, *tag, &tmp);
1273   if(*ierr == MPI_SUCCESS) {
1274     *comm_out = new_comm(tmp);
1275   }
1276 }
1277
1278 void mpi_intercomm_merge_ (int* comm, int* high, int*  comm_out, int* ierr) {
1279  MPI_Comm tmp;
1280  *ierr = MPI_Intercomm_merge(get_comm(*comm), *high, &tmp);
1281  if(*ierr == MPI_SUCCESS) {
1282    *comm_out = new_comm(tmp);
1283  }
1284 }
1285
1286 void mpi_bsend_ (void* buf, int* count, int* datatype, int *dest, int* tag, int* comm, int* ierr) {
1287  *ierr = MPI_Bsend(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm));
1288 }
1289
1290 void mpi_bsend_init_ (void* buf, int* count, int* datatype, int *dest, int* tag, int* comm, int*  request, int* ierr) {
1291   MPI_Request tmp;
1292   *ierr = MPI_Bsend_init(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm), &tmp);
1293  if(*ierr == MPI_SUCCESS) {
1294    *request = new_request(tmp);
1295  }
1296 }
1297
1298 void mpi_ibsend_ (void* buf, int* count, int* datatype, int *dest, int* tag, int* comm, int*  request, int* ierr) {
1299   MPI_Request tmp;
1300   *ierr = MPI_Ibsend(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm), &tmp);
1301  if(*ierr == MPI_SUCCESS) {
1302    *request = new_request(tmp);
1303  }
1304 }
1305
1306 void mpi_comm_remote_group_ (int* comm, int*  group, int* ierr) {
1307   MPI_Group tmp;
1308  *ierr = MPI_Comm_remote_group(get_comm(*comm), &tmp);
1309  if(*ierr == MPI_SUCCESS) {
1310    *group = new_group(tmp);
1311  }
1312 }
1313
1314 void mpi_comm_remote_size_ (int* comm, int* size, int* ierr) {
1315  *ierr = MPI_Comm_remote_size(get_comm(*comm), size);
1316 }
1317
1318 void mpi_issend_ (void* buf, int* count, int* datatype, int *dest, int* tag, int* comm, int*  request, int* ierr) {
1319   MPI_Request tmp;
1320   *ierr = MPI_Issend(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm), &tmp);
1321  if(*ierr == MPI_SUCCESS) {
1322    *request = new_request(tmp);
1323  }
1324 }
1325
1326 void mpi_probe_ (int* source, int* tag, int* comm, MPI_Status*  status, int* ierr) {
1327  *ierr = MPI_Probe(*source, *tag, get_comm(*comm), F2C_STATUS_IGNORE(status));
1328 }
1329
1330 void mpi_attr_delete_ (int* comm, int* keyval, int* ierr) {
1331  *ierr = MPI_Attr_delete(get_comm(*comm), *keyval);
1332 }
1333
1334 void mpi_attr_put_ (int* comm, int* keyval, void* attr_value, int* ierr) {
1335  *ierr = MPI_Attr_put(get_comm(*comm), *keyval, attr_value);
1336 }
1337
1338 void mpi_rsend_init_ (void* buf, int* count, int* datatype, int *dest, int* tag, int* comm, int*  request, int* ierr) {
1339   MPI_Request tmp;
1340   *ierr = MPI_Rsend_init(buf, *count, get_datatype(*datatype), *dest, *tag, get_comm(*comm), &tmp);
1341  if(*ierr == MPI_SUCCESS) {
1342    *request = new_request(tmp);
1343  }
1344 }
1345
1346 void mpi_keyval_create_ (void* copy_fn, void* delete_fn, int* keyval, void* extra_state, int* ierr) {
1347  *ierr = MPI_Keyval_create((MPI_Copy_function*)copy_fn, (MPI_Delete_function*)delete_fn, keyval, extra_state);
1348 }
1349
1350 void mpi_keyval_free_ (int* keyval, int* ierr) {
1351  *ierr = MPI_Keyval_free(keyval);
1352 }
1353
1354 void mpi_test_cancelled_ (MPI_Status*  status, int* flag, int* ierr) {
1355  *ierr = MPI_Test_cancelled(status, flag);
1356 }
1357
1358 void mpi_pack_ (void* inbuf, int* incount, int* type, void* outbuf, int* outcount, int* position, int* comm, int* ierr) {
1359  *ierr = MPI_Pack(inbuf, *incount, get_datatype(*type), outbuf, *outcount, position, get_comm(*comm));
1360 }
1361
1362 void mpi_get_elements_ (MPI_Status*  status, int* datatype, int* elements, int* ierr) {
1363  *ierr = MPI_Get_elements(status, get_datatype(*datatype), elements);
1364 }
1365
1366 void mpi_dims_create_ (int* nnodes, int* ndims, int* dims, int* ierr) {
1367  *ierr = MPI_Dims_create(*nnodes, *ndims, dims);
1368 }
1369
1370 void mpi_iprobe_ (int* source, int* tag, int* comm, int* flag, MPI_Status*  status, int* ierr) {
1371  *ierr = MPI_Iprobe(*source, *tag, get_comm(*comm), flag, status);
1372 }
1373
1374 void mpi_type_get_envelope_ ( int* datatype, int *num_integers, int *num_addresses, int *num_datatypes, int *combiner, int* ierr){
1375
1376  *ierr = MPI_Type_get_envelope(  get_datatype(*datatype), num_integers,
1377  num_addresses, num_datatypes, combiner);
1378 }
1379
1380 void mpi_type_get_contents_ (int* datatype, int* max_integers, int* max_addresses, int* max_datatypes, int* array_of_integers, MPI_Aint* array_of_addresses,
1381  int* array_of_datatypes, int* ierr){
1382  *ierr = MPI_Type_get_contents(get_datatype(*datatype), *max_integers, *max_addresses,*max_datatypes, array_of_integers, array_of_addresses, (MPI_Datatype*)array_of_datatypes);
1383 }
1384
1385 void mpi_type_create_darray_ (int* size, int* rank, int* ndims, int* array_of_gsizes, int* array_of_distribs, int* array_of_dargs, int* array_of_psizes,
1386  int* order, int* oldtype, int*newtype, int* ierr) {
1387   MPI_Datatype tmp;
1388   *ierr = MPI_Type_create_darray(*size, *rank, *ndims,  array_of_gsizes,
1389   array_of_distribs,  array_of_dargs,  array_of_psizes,
1390   *order,  get_datatype(*oldtype), &tmp) ;
1391   if(*ierr == MPI_SUCCESS) {
1392     *newtype = new_datatype(tmp);
1393   }
1394 }
1395
1396 void mpi_type_create_resized_ (int* oldtype,MPI_Aint* lb, MPI_Aint* extent, int*newtype, int* ierr){
1397   MPI_Datatype tmp;
1398   *ierr = MPI_Type_create_resized(get_datatype(*oldtype),*lb, *extent, &tmp);
1399   if(*ierr == MPI_SUCCESS) {
1400     *newtype = new_datatype(tmp);
1401   }
1402 }
1403
1404 void mpi_type_create_subarray_ (int* ndims,int *array_of_sizes, int *array_of_subsizes, int *array_of_starts, int* order, int* oldtype, int*newtype, int* ierr){
1405   MPI_Datatype tmp;
1406   *ierr = MPI_Type_create_subarray(*ndims,array_of_sizes, array_of_subsizes, array_of_starts, *order, get_datatype(*oldtype), &tmp);
1407   if(*ierr == MPI_SUCCESS) {
1408     *newtype = new_datatype(tmp);
1409   }
1410 }
1411
1412 void mpi_type_match_size_ (int* typeclass,int* size,int* datatype, int* ierr){
1413   MPI_Datatype tmp;
1414   *ierr = MPI_Type_match_size(*typeclass,*size,&tmp);
1415   if(*ierr == MPI_SUCCESS) {
1416     *datatype = new_datatype(tmp);
1417   }
1418 }
1419
1420 void mpi_alltoallw_ ( void *sendbuf, int *sendcnts, int *sdispls, int* sendtypes, void *recvbuf, int *recvcnts, int *rdispls, int* recvtypes,
1421  int* comm, int* ierr){
1422  *ierr = MPI_Alltoallw( sendbuf, sendcnts, sdispls, (MPI_Datatype*) sendtypes, recvbuf, recvcnts, rdispls, (MPI_Datatype*)recvtypes, get_comm(*comm));
1423 }
1424
1425 void mpi_exscan_ (void *sendbuf, void *recvbuf, int* count, int* datatype, int* op, int* comm, int* ierr){
1426  *ierr = MPI_Exscan(sendbuf, recvbuf, *count, get_datatype(*datatype), get_op(*op), get_comm(*comm));
1427 }
1428
1429 void mpi_comm_set_name_ (int* comm, char* name, int* ierr){
1430  *ierr = MPI_Comm_set_name (get_comm(*comm), name);
1431 }
1432
1433 void mpi_comm_dup_with_info_ (int* comm, int* info, int* newcomm, int* ierr){
1434   MPI_Comm tmp;
1435   *ierr = MPI_Comm_dup_with_info(get_comm(*comm),*(MPI_Info*)info,&tmp);
1436   if(*ierr == MPI_SUCCESS) {
1437     *newcomm = new_comm(tmp);
1438   }
1439 }
1440
1441 void mpi_comm_split_type_ (int* comm, int* split_type, int* key, int* info, int* newcomm, int* ierr){
1442   MPI_Comm tmp;
1443   *ierr = MPI_Comm_split_type(get_comm(*comm), *split_type, *key, *(MPI_Info*)info, &tmp);
1444   if(*ierr == MPI_SUCCESS) {
1445     *newcomm = new_comm(tmp);
1446   }
1447 }
1448
1449 void mpi_comm_set_info_ (int* comm, int* info, int* ierr){
1450  *ierr = MPI_Comm_set_info (get_comm(*comm), *(MPI_Info*)info);
1451 }
1452
1453 void mpi_comm_get_info_ (int* comm, int* info, int* ierr){
1454  *ierr = MPI_Comm_get_info (get_comm(*comm), (MPI_Info*)info);
1455 }
1456
1457 void mpi_info_get_ (int* info,char *key,int* valuelen, char *value, int *flag, int* ierr){
1458  *ierr = MPI_Info_get(*(MPI_Info*)info,key,*valuelen, value, flag);
1459 }
1460
1461 void mpi_comm_create_errhandler_ ( void *function, void *errhandler, int* ierr){
1462  *ierr = MPI_Comm_create_errhandler( (MPI_Comm_errhandler_fn*) function, (MPI_Errhandler*)errhandler);
1463 }
1464
1465 void mpi_add_error_class_ ( int *errorclass, int* ierr){
1466  *ierr = MPI_Add_error_class( errorclass);
1467 }
1468
1469 void mpi_add_error_code_ (  int* errorclass, int *errorcode, int* ierr){
1470  *ierr = MPI_Add_error_code(*errorclass, errorcode);
1471 }
1472
1473 void mpi_add_error_string_ ( int* errorcode, char *string, int* ierr){
1474  *ierr = MPI_Add_error_string(*errorcode, string);
1475 }
1476
1477 void mpi_comm_call_errhandler_ (int* comm,int* errorcode, int* ierr){
1478  *ierr = MPI_Comm_call_errhandler(get_comm(*comm), *errorcode);
1479 }
1480
1481 void mpi_info_dup_ (int* info, int* newinfo, int* ierr){
1482  *ierr = MPI_Info_dup(*(MPI_Info*)info, (MPI_Info*)newinfo);
1483 }
1484
1485 void mpi_info_get_valuelen_ ( int* info, char *key, int *valuelen, int *flag, int* ierr){
1486  *ierr = MPI_Info_get_valuelen( *(MPI_Info*)info, key, valuelen, flag);
1487 }
1488
1489 void mpi_info_delete_ (int* info, char *key, int* ierr){
1490  *ierr = MPI_Info_delete(*(MPI_Info*)info, key);
1491 }
1492
1493 void mpi_info_get_nkeys_ ( int* info, int *nkeys, int* ierr){
1494  *ierr = MPI_Info_get_nkeys(  *(MPI_Info*)info, nkeys);
1495 }
1496
1497 void mpi_info_get_nthkey_ ( int* info, int* n, char *key, int* ierr){
1498  *ierr = MPI_Info_get_nthkey( *(MPI_Info*)info, *n, key);
1499 }
1500
1501 void mpi_get_version_ (int *version,int *subversion, int* ierr){
1502  *ierr = MPI_Get_version (version,subversion);
1503 }
1504
1505 void mpi_get_library_version_ (char *version,int *len, int* ierr){
1506  *ierr = MPI_Get_library_version (version,len);
1507 }
1508
1509 void mpi_request_get_status_ ( int* request, int *flag, MPI_Status* status, int* ierr){
1510  *ierr = MPI_Request_get_status( find_request(*request), flag, status);
1511 }
1512
1513 void mpi_grequest_start_ ( void *query_fn, void *free_fn, void *cancel_fn, void *extra_state, int*request, int* ierr){
1514   MPI_Request tmp;
1515   *ierr = MPI_Grequest_start( (MPI_Grequest_query_function*)query_fn, (MPI_Grequest_free_function*)free_fn, (MPI_Grequest_cancel_function*)cancel_fn, extra_state, &tmp);
1516  if(*ierr == MPI_SUCCESS) {
1517    *request = new_request(tmp);
1518  }
1519 }
1520
1521 void mpi_grequest_complete_ ( int* request, int* ierr){
1522  *ierr = MPI_Grequest_complete( find_request(*request));
1523 }
1524
1525 void mpi_status_set_cancelled_ (MPI_Status* status,int* flag, int* ierr){
1526  *ierr = MPI_Status_set_cancelled(status,*flag);
1527 }
1528
1529 void mpi_status_set_elements_ ( MPI_Status* status, int* datatype, int* count, int* ierr){
1530  *ierr = MPI_Status_set_elements( status, get_datatype(*datatype), *count);
1531 }
1532
1533 void mpi_comm_connect_ ( char *port_name, int* info, int* root, int* comm, int*newcomm, int* ierr){
1534   MPI_Comm tmp;
1535   *ierr = MPI_Comm_connect( port_name, *(MPI_Info*)info, *root, get_comm(*comm), &tmp);
1536   if(*ierr == MPI_SUCCESS) {
1537     *newcomm = new_comm(tmp);
1538   }
1539 }
1540
1541 void mpi_publish_name_ ( char *service_name, int* info, char *port_name, int* ierr){
1542  *ierr = MPI_Publish_name( service_name, *(MPI_Info*)info, port_name);
1543 }
1544
1545 void mpi_unpublish_name_ ( char *service_name, int* info, char *port_name, int* ierr){
1546  *ierr = MPI_Unpublish_name( service_name, *(MPI_Info*)info, port_name);
1547 }
1548
1549 void mpi_lookup_name_ ( char *service_name, int* info, char *port_name, int* ierr){
1550  *ierr = MPI_Lookup_name( service_name, *(MPI_Info*)info, port_name);
1551 }
1552
1553 void mpi_comm_join_ ( int* fd, int* intercomm, int* ierr){
1554   MPI_Comm tmp;
1555   *ierr = MPI_Comm_join( *fd, &tmp);
1556   if(*ierr == MPI_SUCCESS) {
1557     *intercomm = new_comm(tmp);
1558   }
1559 }
1560
1561 void mpi_open_port_ ( int* info, char *port_name, int* ierr){
1562  *ierr = MPI_Open_port( *(MPI_Info*)info,port_name);
1563 }
1564
1565 void mpi_close_port_ ( char *port_name, int* ierr){
1566  *ierr = MPI_Close_port( port_name);
1567 }
1568
1569 void mpi_comm_accept_ ( char *port_name, int* info, int* root, int* comm, int*newcomm, int* ierr){
1570   MPI_Comm tmp;
1571   *ierr = MPI_Comm_accept( port_name, *(MPI_Info*)info, *root, get_comm(*comm), &tmp);
1572   if(*ierr == MPI_SUCCESS) {
1573     *newcomm = new_comm(tmp);
1574   }
1575 }
1576
1577 void mpi_comm_spawn_ ( char *command, char *argv, int* maxprocs, int* info, int* root, int* comm, int* intercomm, int* array_of_errcodes, int* ierr){
1578   MPI_Comm tmp;
1579   *ierr = MPI_Comm_spawn( command, NULL, *maxprocs, *(MPI_Info*)info, *root, get_comm(*comm), &tmp, array_of_errcodes);
1580   if(*ierr == MPI_SUCCESS) {
1581     *intercomm = new_comm(tmp);
1582   }
1583 }
1584
1585 void mpi_comm_spawn_multiple_ ( int* count, char *array_of_commands, char** array_of_argv, int* array_of_maxprocs, int* array_of_info, int* root,
1586  int* comm, int* intercomm, int* array_of_errcodes, int* ierr){
1587  MPI_Comm tmp;
1588  *ierr = MPI_Comm_spawn_multiple(* count, &array_of_commands, &array_of_argv, array_of_maxprocs,
1589  (MPI_Info*)array_of_info, *root, get_comm(*comm), &tmp, array_of_errcodes);
1590  if(*ierr == MPI_SUCCESS) {
1591    *intercomm = new_comm(tmp);
1592  }
1593 }
1594
1595 void mpi_comm_get_parent_ ( int* parent, int* ierr){
1596   MPI_Comm tmp;
1597   *ierr = MPI_Comm_get_parent( &tmp);
1598   if(*ierr == MPI_SUCCESS) {
1599     *parent = new_comm(tmp);
1600   }
1601 }